Improvements:
Better view : extented vs simple views Modified several views Simplified Stock Mgt: remove stock.move.lot (packing of type delivery) remove mode.lot Chained locations Allows to define menus with parents Support logo in the company bzr revid: fp@tinyerp.com-9dd4d862b64c393dbcc7b6c085e4ff039716d90c
This commit is contained in:
@@ -26,11 +26,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
print '1'
|
||||
import ir
|
||||
print '2'
|
||||
import module
|
||||
print '3'
|
||||
import res
|
||||
print '4'
|
||||
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
<record model="res.groups" id="group_user">
|
||||
<field name="name">user</field>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_no_one">
|
||||
<record model="res.groups" id="group_extended">
|
||||
<field name="name">Extended View</field>
|
||||
</record>
|
||||
<record model="res.groups" id="group_no_one">
|
||||
<field name="name">No One</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record model="res.lang" id="lang_en">
|
||||
<field name="code">en_US</field>
|
||||
|
||||
@@ -135,7 +135,6 @@ class ir_model_fields(osv.osv):
|
||||
if vals.get('state','base')=='manual':
|
||||
if not vals['name'].startswith('x_'):
|
||||
raise except_orm('Error', "Custom fields must have a name that starts with 'x_' !")
|
||||
print vals['model']
|
||||
self.pool.get(vals['model']).__init__(self.pool, cr)
|
||||
self.pool.get(vals['model'])._auto_init(cr)
|
||||
return res
|
||||
@@ -230,7 +229,6 @@ class ir_model_access(osv.osv):
|
||||
return res
|
||||
ir_model_access()
|
||||
|
||||
print 'MODEL ACCESS'
|
||||
class ir_model_data(osv.osv):
|
||||
_name = 'ir.model.data'
|
||||
_columns = {
|
||||
|
||||
@@ -124,7 +124,6 @@
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="som"/>
|
||||
<field name="type"/>
|
||||
<field name="partner_type"/>
|
||||
<field name="user_id"/>
|
||||
</tree>
|
||||
|
||||
@@ -86,7 +86,7 @@ class res_partner_category(osv.osv):
|
||||
'parent_id': fields.many2one('res.partner.category', 'Parent Category', select=True),
|
||||
'complete_name': fields.function(_name_get_fnc, method=True, type="char", string='Name'),
|
||||
'child_ids': fields.one2many('res.partner.category', 'parent_id', 'Childs Category'),
|
||||
'active' : fields.boolean('Active'),
|
||||
'active' : fields.boolean('Active', help="The active field allows you to hide the category, without removing it."),
|
||||
}
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You can not create recursive categories.', ['parent_id'])
|
||||
@@ -131,22 +131,22 @@ class res_partner(osv.osv):
|
||||
_name = "res.partner"
|
||||
_order = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True, select=True, write=['base.group_admin'], read=['base.group_admin']),
|
||||
'name': fields.char('Name', size=128, required=True, select=True),
|
||||
'date': fields.date('Date', select=1),
|
||||
'title': fields.selection(_partner_title_get, 'Title', size=32),
|
||||
'parent_id': fields.many2one('res.partner','Main Company', select=2),
|
||||
'child_ids': fields.one2many('res.partner', 'parent_id', 'Partner Ref.'),
|
||||
'ref': fields.char('Code', size=64),
|
||||
'lang': fields.selection(_lang_get, 'Language', size=5),
|
||||
'user_id': fields.many2one('res.users', 'Salesman', read=['base.group_admin']),
|
||||
'user_id': fields.many2one('res.users', 'Dedicated Salesman'),
|
||||
'responsible': fields.many2one('res.users', 'Users'),
|
||||
'vat': fields.char('VAT',size=32 ,help="Value Added Tax number"),
|
||||
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
|
||||
'website': fields.char('Website',size=64),
|
||||
'comment': fields.text('Notes'),
|
||||
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts', read=['base.group_admin']),
|
||||
'category_id': fields.many2many('res.partner.category', 'res_partner_category_rel', 'partner_id', 'category_id', 'Categories', read=['base.group_user']),
|
||||
'events': fields.one2many('res.partner.event', 'partner_id', 'events', read=['base.group_user']),
|
||||
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'),
|
||||
'category_id': fields.many2many('res.partner.category', 'res_partner_category_rel', 'partner_id', 'category_id', 'Categories'),
|
||||
'events': fields.one2many('res.partner.event', 'partner_id', 'Events'),
|
||||
'credit_limit': fields.float(string='Credit Limit'),
|
||||
'ean13': fields.char('EAN13', size=13),
|
||||
'active': fields.boolean('Active'),
|
||||
|
||||
@@ -5,6 +5,17 @@
|
||||
<!--
|
||||
Resource: res.partner.title
|
||||
-->
|
||||
<record id="res_partner_title_pvt_ltd" model="res.partner.title">
|
||||
<field name="domain">partner</field>
|
||||
<field name="name">Pvt. Ltd</field>
|
||||
<field name="shortcut">pvt ltd</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_title_ltd" model="res.partner.title">
|
||||
<field name="domain">partner</field>
|
||||
<field name="name">Ltd</field>
|
||||
<field name="shortcut">ltd</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_title_madam" model="res.partner.title">
|
||||
<field name="domain">contact</field>
|
||||
@@ -22,6 +33,19 @@
|
||||
<field name="shortcut">M.</field>
|
||||
</record>
|
||||
|
||||
<record model="res.partner.function" id="function_director">
|
||||
<field name="name">Director</field>
|
||||
<field name="code">CEO</field>
|
||||
</record>
|
||||
<record model="res.partner.function" id="function_it">
|
||||
<field name="name">Chief Technical Officer</field>
|
||||
<field name="code">CTO</field>
|
||||
</record>
|
||||
<record model="res.partner.function" id="function_sale">
|
||||
<field name="name">Salesman</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
Resource: res.partner.category
|
||||
|
||||
@@ -178,10 +178,10 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partners">
|
||||
<field name="name"/>
|
||||
<field name="title" string="Type"/>
|
||||
<field name="ref"/>
|
||||
<field name="address"/>
|
||||
<field name="address" string="# of Contacts"/>
|
||||
<field name="lang"/>
|
||||
<field name="category_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -201,7 +201,7 @@
|
||||
<field name="address" mode="form,tree" colspan="4" nolabel="1" select="1">
|
||||
<form string="Partner contacts">
|
||||
<field name="name" select="2"/>
|
||||
<field name="title" domain="[('domain', '=', 'contact')]"/>
|
||||
<field name="title" domain="[('domain', '=', 'contact')]" string="Type"/>
|
||||
<field name="function"/>
|
||||
<field name="type" select="2"/>
|
||||
<field name="street" select="2"/>
|
||||
|
||||
@@ -303,11 +303,13 @@ class _rml_canvas(object):
|
||||
from reportlab.lib.utils import ImageReader
|
||||
|
||||
if not node.hasAttribute('file'):
|
||||
if node.getAttribute('name') in self.images:
|
||||
scontent = self.images[node.getAttribute('name')]
|
||||
s = StringIO.StringIO(scontent)
|
||||
|
||||
if node.hasAttribute('name'):
|
||||
s = self.images[node.getAttribute('name')]
|
||||
else:
|
||||
return True
|
||||
import base64
|
||||
image_data = base64.decodestring(node.firstChild.nodeValue)
|
||||
s = StringIO.StringIO(image_data)
|
||||
else:
|
||||
if node.getAttribute('file') in self.images:
|
||||
s = StringIO.StringIO(self.images[node.getAttribute('file')])
|
||||
|
||||
+116
-70
@@ -195,9 +195,13 @@ class xml_import(object):
|
||||
def _test_xml_id(self, xml_id):
|
||||
id = xml_id
|
||||
if '.' in xml_id:
|
||||
assert len(id.split('.'))==2, """The ID reference '"%s" must contains
|
||||
maximum one dot. They are used to refer to other modules ID, in the
|
||||
form: module.record_id""" % (xml_id,)
|
||||
base, id = xml_id.split('.')
|
||||
if len(id) > 64:
|
||||
self.logger.notifyChannel('init', netsvc.LOG_ERROR, 'id: %s is to long (max: 64)'%xml_id)
|
||||
|
||||
def _tag_delete(self, cr, rec, data_node=None):
|
||||
d_model = rec.getAttribute("model")
|
||||
d_search = rec.getAttribute("search")
|
||||
@@ -269,6 +273,27 @@ class xml_import(object):
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
return False
|
||||
|
||||
def _tag_url(self, cr, rec, data_node=None):
|
||||
url = rec.getAttribute("string").encode('utf8')
|
||||
target = rec.getAttribute("target").encode('utf8')
|
||||
name = rec.getAttribute("name").encode('utf8')
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
|
||||
res = {'name': name, 'url': url, 'target':target}
|
||||
|
||||
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.url", self.module, res, xml_id, mode=self.mode)
|
||||
self.idref[xml_id] = int(id)
|
||||
# ir_set
|
||||
if (not rec.hasAttribute('menu') or eval(rec.getAttribute('menu'))) and id:
|
||||
keyword = str(rec.getAttribute('keyword') or 'client_action_multi')
|
||||
keys = [('action',keyword)]
|
||||
value = 'ir.actions.url,'+str(id)
|
||||
replace = rec.hasAttribute('replace') and \
|
||||
rec.getAttribute("replace") or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id)
|
||||
return False
|
||||
|
||||
def _tag_act_window(self, cr, rec, data_node=None):
|
||||
name = rec.hasAttribute('name') and rec.getAttribute('name').encode('utf-8')
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
@@ -346,81 +371,101 @@ class xml_import(object):
|
||||
str(rec.getAttribute('action')), cr)
|
||||
return False
|
||||
|
||||
#
|
||||
# Support two types of notation:
|
||||
# name="Inventory Control/Sending Goods"
|
||||
# or
|
||||
# action="action_id"
|
||||
# parent="parent_id"
|
||||
#
|
||||
def _tag_menuitem(self, cr, rec, data_node=None):
|
||||
rec_id = rec.getAttribute("id").encode('ascii')
|
||||
self._test_xml_id(rec_id)
|
||||
m_l = map(escape, escape_re.split(rec.getAttribute("name").encode('utf8')))
|
||||
pid = False
|
||||
for idx, menu_elem in enumerate(m_l):
|
||||
if pid:
|
||||
cr.execute('select id from ir_ui_menu where parent_id=%d and name=%s', (pid, menu_elem))
|
||||
else:
|
||||
cr.execute('select id from ir_ui_menu where parent_id is null and name=%s', (menu_elem,))
|
||||
res = cr.fetchone()
|
||||
if idx==len(m_l)-1:
|
||||
# we are at the last menu element/level (it's a leaf)
|
||||
values = {'parent_id': pid,'name':menu_elem}
|
||||
|
||||
if rec.hasAttribute('action'):
|
||||
a_action = rec.getAttribute('action').encode('utf8')
|
||||
a_type = rec.getAttribute('type').encode('utf8') or 'act_window'
|
||||
icons = {
|
||||
"act_window": 'STOCK_NEW',
|
||||
"report.xml": 'STOCK_PASTE',
|
||||
"wizard": 'STOCK_EXECUTE',
|
||||
"url": 'STOCK_JUMP_TO'
|
||||
}
|
||||
values['icon'] = icons.get(a_type,'STOCK_NEW')
|
||||
if a_type=='act_window':
|
||||
a_id = self.id_get(cr, 'ir.actions.%s'% a_type, a_action)
|
||||
cr.execute('select view_type,view_mode,name,view_id from ir_act_window where id=%d', (int(a_id),))
|
||||
action_type,action_mode,action_name,view_id = cr.fetchone()
|
||||
if view_id:
|
||||
cr.execute('SELECT type FROM ir_ui_view WHERE id=%d', (int(view_id),))
|
||||
action_mode, = cr.fetchone()
|
||||
cr.execute('SELECT view_mode FROM ir_act_window_view WHERE act_window_id=%d ORDER BY sequence LIMIT 1', (int(a_id),))
|
||||
if cr.rowcount:
|
||||
action_mode, = cr.fetchone()
|
||||
if action_type=='tree':
|
||||
values['icon'] = 'STOCK_INDENT'
|
||||
elif action_mode and action_mode.startswith('tree'):
|
||||
values['icon'] = 'STOCK_JUSTIFY_FILL'
|
||||
elif action_mode and action_mode.startswith('graph'):
|
||||
values['icon'] = 'terp-graph'
|
||||
elif action_mode and action_mode.startswith('calendar'):
|
||||
values['icon'] = 'terp-calendar'
|
||||
if not values['name']:
|
||||
values['name'] = action_name
|
||||
if rec.hasAttribute('sequence'):
|
||||
values['sequence'] = int(rec.getAttribute('sequence'))
|
||||
if rec.hasAttribute('icon'):
|
||||
values['icon'] = str(rec.getAttribute('icon'))
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
if group.startswith('-'):
|
||||
group_id = self.id_get(cr, 'res.groups', group[1:])
|
||||
groups_value.append((3, group_id))
|
||||
else:
|
||||
group_id = self.id_get(cr, 'res.groups', group)
|
||||
groups_value.append((4, group_id))
|
||||
values['groups_id'] = groups_value
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
pid = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.ui.menu', self.module, values, xml_id, idx==len(m_l)-1, mode=self.mode, res_id=res and res[0] or False)
|
||||
elif res:
|
||||
# the menuitem already exists
|
||||
pid = res[0]
|
||||
xml_id = idx==len(m_l)-1 and rec.getAttribute('id').encode('utf8')
|
||||
try:
|
||||
npid = self.pool.get('ir.model.data')._update_dummy(cr, self.uid, 'ir.ui.menu', self.module, xml_id, idx==len(m_l)-1)
|
||||
except:
|
||||
print 'Menu Error', self.module, xml_id, idx==len(m_l)-1
|
||||
else:
|
||||
# the menuitem does't exist but we are in branch (not a leaf)
|
||||
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
|
||||
values = {'parent_id': False}
|
||||
if not rec.hasAttribute('parent'):
|
||||
pid = False
|
||||
for idx, menu_elem in enumerate(m_l):
|
||||
if pid:
|
||||
cr.execute('select id from ir_ui_menu where parent_id=%d and name=%s', (pid, menu_elem))
|
||||
else:
|
||||
cr.execute('select id from ir_ui_menu where parent_id is null and name=%s', (menu_elem,))
|
||||
res = cr.fetchone()
|
||||
if idx==len(m_l)-1:
|
||||
values = {'parent_id': pid,'name':menu_elem}
|
||||
elif res:
|
||||
pid = res[0]
|
||||
xml_id = idx==len(m_l)-1 and rec.getAttribute('id').encode('utf8')
|
||||
try:
|
||||
npid = self.pool.get('ir.model.data')._update_dummy(cr, self.uid, 'ir.ui.menu', self.module, xml_id, idx==len(m_l)-1)
|
||||
except:
|
||||
print 'Menu Error', self.module, xml_id, idx==len(m_l)-1
|
||||
else:
|
||||
# the menuitem does't exist but we are in branch (not a leaf)
|
||||
self.logger.notifyChannel("init", netsvc.LOG_INFO, 'Warning no ID for submenu %s of menu %s !' % (menu_elem, str(m_l)))
|
||||
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
|
||||
else:
|
||||
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.getAttribute('parent'))
|
||||
values = {'parent_id': menu_parent_id}
|
||||
if rec.hasAttribute('name'):
|
||||
values['name'] = rec.getAttribute('name')
|
||||
try:
|
||||
res = [ self.id_get(cr, 'ir.ui.menu', rec.getAttribute('id')) ]
|
||||
except:
|
||||
res = None
|
||||
|
||||
if rec.hasAttribute('action'):
|
||||
a_action = rec.getAttribute('action').encode('utf8')
|
||||
a_type = rec.getAttribute('type').encode('utf8') or 'act_window'
|
||||
icons = {
|
||||
"act_window": 'STOCK_NEW',
|
||||
"report.xml": 'STOCK_PASTE',
|
||||
"wizard": 'STOCK_EXECUTE',
|
||||
"url": 'STOCK_JUMP_TO'
|
||||
}
|
||||
values['icon'] = icons.get(a_type,'STOCK_NEW')
|
||||
if a_type=='act_window':
|
||||
a_id = self.id_get(cr, 'ir.actions.%s'% a_type, a_action)
|
||||
cr.execute('select view_type,view_mode,name,view_id from ir_act_window where id=%d', (int(a_id),))
|
||||
action_type,action_mode,action_name,view_id = cr.fetchone()
|
||||
if view_id:
|
||||
cr.execute('SELECT type FROM ir_ui_view WHERE id=%d', (int(view_id),))
|
||||
action_mode, = cr.fetchone()
|
||||
cr.execute('SELECT view_mode FROM ir_act_window_view WHERE act_window_id=%d ORDER BY sequence LIMIT 1', (int(a_id),))
|
||||
if cr.rowcount:
|
||||
action_mode, = cr.fetchone()
|
||||
if action_type=='tree':
|
||||
values['icon'] = 'STOCK_INDENT'
|
||||
elif action_mode and action_mode.startswith('tree'):
|
||||
values['icon'] = 'STOCK_JUSTIFY_FILL'
|
||||
elif action_mode and action_mode.startswith('graph'):
|
||||
values['icon'] = 'terp-graph'
|
||||
elif action_mode and action_mode.startswith('calendar'):
|
||||
values['icon'] = 'terp-calendar'
|
||||
if not values.get('name', False):
|
||||
values['name'] = action_name
|
||||
if rec.hasAttribute('sequence'):
|
||||
values['sequence'] = int(rec.getAttribute('sequence'))
|
||||
if rec.hasAttribute('icon'):
|
||||
values['icon'] = str(rec.getAttribute('icon'))
|
||||
if rec.hasAttribute('groups'):
|
||||
g_names = rec.getAttribute('groups').split(',')
|
||||
groups_value = []
|
||||
groups_obj = self.pool.get('res.groups')
|
||||
for group in g_names:
|
||||
if group.startswith('-'):
|
||||
group_id = self.id_get(cr, 'res.groups', group[1:])
|
||||
groups_value.append((3, group_id))
|
||||
else:
|
||||
group_id = self.id_get(cr, 'res.groups', group)
|
||||
groups_value.append((4, group_id))
|
||||
values['groups_id'] = groups_value
|
||||
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
pid = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.ui.menu', self.module, values, xml_id, True, mode=self.mode, res_id=res and res[0] or False)
|
||||
|
||||
if rec_id and pid:
|
||||
self.idref[rec_id] = int(pid)
|
||||
|
||||
@@ -623,6 +668,7 @@ class xml_import(object):
|
||||
'function': self._tag_function,
|
||||
'workflow': self._tag_workflow,
|
||||
'act_window': self._tag_act_window,
|
||||
'url': self._tag_url
|
||||
}
|
||||
|
||||
def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
|
||||
|
||||
Reference in New Issue
Block a user