Code review comment for lp:~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1

Revision history for this message
Etienne Hirt (hirt) wrote :

Dear Reviewers,

Please find attached the diff vs. trunk 6480

Best Regards

Etienne

On 04.03.2012 14:05, Etienne Hirt wrote:
> Etienne Hirt has proposed merging lp:~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1 into lp:openobject-addons/6.1.
>
> Requested reviews:
> OpenERP Core Team (openerp)
> Related bugs:
> Bug #923440 in OpenERP Addons: "Base_contact: Missing Fields in new design [6.1]"
> https://bugs.launchpad.net/openobject-addons/+bug/923440
>
> For more details, see:
> https://code.launchpad.net/~openerp-community/openobject-addons/trunk-bug-923440-base_contact_finalise6.1/+merge/95777
>
> This branch is intended to update the new base_contact V6.1 with the functionality of V6.0 and to perform corrections (see also bug923440):
> * Triggers for storage and redefine only fields that are not available already
> * state field and date_from/to
> * Sequence for partner and contact view, corresponding sorting and correct selection of main function/partner and main address
> * Other phone in res_partner_address
> * Obsolete: Use field name for last_name in res_partner_contact to enable auto filling when creating a new contact
> ** use name again and setting _rec_name = 'last_name' but not followed for "create and edit"
> * Defining address tree view for partner and for contact and select them instead of defining the tree within the form
> * search for contacts connected to job_ids to search for all partners and partner is in name!
> * store firstname lastname in name as in the in the demo data of base/res/res_partner_demo.xml

1
2 #. module: base_contact
3 #: field:res.partner.location,city:0
4Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv
5===================================================================
6--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv (revision 12877)
7+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/security/ir.model.access.csv (revision 13001)
8@@ -1,7 +1,8 @@
9 "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
10 "access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1
11 "access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0
12-"access_res_partner_location","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
13+"access_res_partner_location_manager","res.partner.location","model_res_partner_location","base.group_partner_manager",1,1,1,1
14+"access_res_partner_location_all","res.partner.location","model_res_partner_location","base.group_user",1,0,0,0
15 "access_res_partner_location_sale_salesman","res.partner.location","model_res_partner_location","base.group_sale_salesman",1,1,1,0
16 "access_res_partner_address_sale_salesman","res.partner.address.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0
17 "access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0
18Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py
19===================================================================
20--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py (revision 12877)
21+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact.py (revision 13001)
22@@ -21,37 +21,80 @@
23
24 from osv import fields, osv
25 import addons
26+import pdb
27
28 class res_partner_contact(osv.osv):
29 """ Partner Contact """
30
31 _name = "res.partner.contact"
32 _description = "Contact"
33+
34+ _rec_name = 'last_name'
35
36+
37 def _name_get_full(self, cr, uid, ids, prop, unknow_none, context=None):
38 result = {}
39 for rec in self.browse(cr, uid, ids, context=context):
40- result[rec.id] = rec.last_name+' '+(rec.first_name or '')
41+ #use firstname lastname as in the demo data of base/res/res_partner_demo.xml
42+ if(rec.first_name):
43+ result[rec.id] = rec.first_name+' '+rec.last_name
44+ else:
45+ result[rec.id] = rec.last_name
46+
47 return result
48+
49+ def _main_job(self, cr, uid, ids, fields, arg, context=None):
50+ """
51+ @summary: Returns id and function of job with the lowest 'sequence_contact'
52+ @param self: The object pointer
53+ @param cr: the current row, from the database cursor,
54+ @param uid: the current user’s ID for security checks,
55+ @param ids: List of partner contact’s IDs
56+ @fields: Get Fields
57+ @param context: A standard dictionary for contextual values
58+ @param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """
59+
60+ res = dict.fromkeys(ids, False)
61+
62+ all_ids = self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)], order='sequence_contact')
63+ #pdb.set_trace()
64+ addresses = self.pool.get('res.partner.address').browse(cr, uid, all_ids)
65+ for addr in addresses:
66+ if(res[addr.contact_id.id] == False):
67+ res[addr.contact_id.id] = {'partner_id': addr.partner_id.id, 'function': addr.function}
68+
69+ for id in res:
70+ if (res[id]==False):
71+ res[id] = {'partner_id': False, 'function': False}
72+
73+ return res
74+
75+ def _get_contact_id_from_address(self, cr, uid, ids, context=None):
76+ #@todo: remove obsolete function
77+ result = {}
78+ for addr in self.pool.get('res.partner.address').browse(cr, uid, ids, context=context):
79+ result[addr.contact_id.id] = True
80+ return result.keys()
81
82+
83+
84 _columns = {
85- 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=True, select=True),
86+ 'name': fields.function(_name_get_full, string='Name', size=64, type="char", store=False, select=True),
87 'last_name': fields.char('Last Name', size=64, required=True),
88 'first_name': fields.char('First Name', size=64),
89 'mobile': fields.char('Mobile', size=64),
90 'title': fields.many2one('res.partner.title','Title', domain=[('domain','=','contact')]),
91- 'website': fields.char('Website', size=120),
92+ 'website': fields.char('Private Website', size=120),
93 'lang_id': fields.many2one('res.lang', 'Language'),
94 'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'),
95 'country_id': fields.many2one('res.country','Nationality'),
96- 'birthdate': fields.date('Birth Date'),
97+ 'birthdate': fields.char('Birthdate', size=64),
98 'active': fields.boolean('Active', help="If the active field is set to False,\
99 it will allow you to hide the partner contact without removing it."),
100- 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
101- relation='res.partner', string='Main Employer'),
102- 'function': fields.related('job_ids', 'function', type='char', \
103- string='Main Function'),
104- 'email': fields.char('E-Mail', size=240),
105+ #Storage for partner_id and function not fully worked and not required -> removed
106+ 'partner_id': fields.function(_main_job, type='many2one', relation='res.partner', string='Main Employer', store = False, multi='mainjob'),
107+ 'function': fields.function(_main_job, type='char', size=128, string='Main Function', store = False, multi='mainjob'),
108+ 'email': fields.char('Private E-Mail', size=240),
109 'comment': fields.text('Notes', translate=True),
110 'photo': fields.binary('Photo'),
111 }
112@@ -65,7 +108,7 @@
113 'active' : lambda *a: True,
114 }
115
116- _order = "name"
117+ _order = "last_name, first_name"
118
119 def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None):
120 if not args:
121@@ -73,7 +116,7 @@
122 if context is None:
123 context = {}
124 if name:
125- ids = self.search(cr, uid, ['|',('name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
126+ ids = self.search(cr, uid, ['|',('last_name', operator, name),('first_name', operator, name)] + args, limit=limit, context=context)
127 else:
128 ids = self.search(cr, uid, args, limit=limit, context=context)
129 return self.name_get(cr, uid, ids, context=context)
130@@ -85,6 +128,22 @@
131 if obj.partner_id:
132 result[obj.id] = result[obj.id] + ', ' + obj.partner_id.name
133 return result.items()
134+
135+ def view_init(self, cr, uid, fields, context=None):
136+ """
137+ This function shall fill the first and last name if empty from context
138+ """
139+
140+ if context is None:
141+ context = {}
142+ else:
143+ default_name = context.get('default_name')
144+ #if default_name:
145+ #pdb.set_trace()
146+ #The following does not work
147+ #self._columns['last_name'] = default_name
148+ pass
149+
150
151 def _auto_init(self, cr, context=None):
152 def table_exists(view_name):
153@@ -99,9 +158,9 @@
154 cr.execute("""
155 INSERT INTO
156 res_partner_contact
157- (id,name,last_name,title,active)
158+ (id,last_name,first_name,title,active,email,mobile,birthdate)
159 SELECT
160- id,COALESCE(name, '/'),COALESCE(name, '/'),title,true
161+ id,COALESCE(name, '/'),COALESCE(name, '/'),title,true,email,mobile,birthdate
162 FROM
163 res_partner_address""")
164 cr.execute("alter table res_partner_address add contact_id int references res_partner_contact")
165@@ -124,6 +183,8 @@
166 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'),
167 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\
168 relation='res.partner', string='Main Partner'),
169+ 'contact_id': fields.related('job_ids', 'contact_id', type='many2one',\
170+ relation='res.partner.contact', string='First Contact'),
171 }
172 _defaults = {
173 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c),
174@@ -166,6 +227,29 @@
175
176 class res_partner_address(osv.osv):
177 _inherit = 'res.partner.address'
178+
179+ def _get_address_from_location_ids(self, cr, uid, ids, context=None):
180+ result = {}
181+ #if self._name=="res.partner.location":
182+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('location_id','in',ids)]):
183+ result[addr] = True
184+ #else:
185+ #raise osv.except_osv(_('getAddressFromLocation'), self._name)
186+
187+ return result.keys()
188+
189+ def _get_address_from_contact_ids(self, cr, uid, ids, context=None):
190+ result = {}
191+ for addr in self.pool.get('res.partner.address').search(cr, uid, [('contact_id','in',ids)]):
192+ result[addr] = True
193+ return result.keys()
194+
195+ def _get_own_addresses(self, cr, uid, ids, context=None):
196+ result = {}
197+ for id in ids:
198+ result[id] = True
199+ return result.keys()
200+
201
202 def _default_location_id(self, cr, uid, context=None):
203 if context is None:
204@@ -175,6 +259,17 @@
205 ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context)
206 return ids and ids[0] or False
207
208+ def onchange_contact_id(self,cr, uid, ids, contact_id=False, context={}):
209+ if not contact_id:
210+ return {}
211+ contact = self.pool.get('res.partner.contact').browse(cr, uid, contact_id, context=context)
212+ return {'value':{
213+ 'mobile': contact.mobile,
214+ 'name': contact.name,
215+ 'title': contact.title and contact.title.id or False,
216+ }}
217+
218+
219 def onchange_location_id(self,cr, uid, ids, location_id=False, context={}):
220 if not location_id:
221 return {}
222@@ -191,23 +286,49 @@
223 _columns = {
224 'location_id' : fields.many2one('res.partner.location', 'Location'),
225 'contact_id' : fields.many2one('res.partner.contact', 'Contact'),
226+
227+ #field for administer functions
228+ 'sequence_contact': fields.integer('Contact Seq.',help='Order of\
229+ importance of this address in the list of addresses of the linked contact'),
230+ 'sequence_partner': fields.integer('Partner Seq.',help='Order of importance\
231+ of this job title in the list of job title of the linked partner'),
232+ 'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"),
233+ 'date_stop': fields.date('Date Stop', help="Last date of job"),
234+ 'state': fields.selection([('past', 'Past'),('current', 'Current')], \
235+ 'State', required=True, help="Status of Address"),
236
237 # fields from location
238- 'street': fields.related('location_id', 'street', string='Street', type="char", store=True, size=128),
239- 'street2': fields.related('location_id', 'street2', string='Street2', type="char", store=True, size=128),
240- 'zip': fields.related('location_id', 'zip', string='Zip', type="char", store=True, change_default=True, size=24),
241- 'city': fields.related('location_id', 'city', string='City', type="char", store=True, size=128),
242- 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", store=True, domain="[('country_id','=',country_id)]"),
243- 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', store=True, relation='res.country'),
244+ #Trigger for change of location id of self is not required because this is handled by onchange_location_id triggered in the only form!
245+ 'street': fields.related('location_id', 'street', string='Street', type="char", size=128,
246+ store = {'res.partner.location': (_get_address_from_location_ids, ['street'], 10),}),
247+ 'street2': fields.related('location_id', 'street2', string='Street2', type="char", size=128,
248+ store = {'res.partner.location': (_get_address_from_location_ids, ['street2'], 10),}),
249+ 'zip': fields.related('location_id', 'zip', string='Zip', type="char", change_default=True, size=24,
250+ store = {'res.partner.location': (_get_address_from_location_ids, ['zip'], 10),}),
251+ 'city': fields.related('location_id', 'city', string='City', type="char", size=128,
252+ store = {'res.partner.location': (_get_address_from_location_ids, ['city'], 10),}),
253+ 'state_id': fields.related('location_id', 'state_id', relation="res.country.state", string='Fed. State', type="many2one", domain="[('country_id','=',country_id)]",
254+ store = {'res.partner.location': (_get_address_from_location_ids, ['state_id'], 10),}),
255+ 'country_id': fields.related('location_id', 'country_id', type='many2one', string='Country', relation='res.country',
256+ store = {'res.partner.location': (_get_address_from_location_ids, ['country_id'], 10),}),
257
258- 'phone': fields.char('Phone', size=64),
259- 'fax': fields.char('Fax', size=64),
260- 'email': fields.char('E-Mail', size=240),
261+ #These fields exists
262+ #'phone': fields.char('Phone', size=64),
263+ #'fax': fields.char('Fax', size=64),
264+ #'email': fields.char('E-Mail', size=240),
265+ #this field is missing
266+ 'other': fields.char('Other Phone', size=64, help='Additional phone field'),
267
268 # fields from contact
269 'mobile' : fields.related('contact_id', 'mobile', type='char', size=64, string='Mobile'),
270- 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", store=True),
271- 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title", store=True),
272+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['mobile'], 10),
273+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}), @bug: query wants to store in crm_lead!!!!
274+ 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name",
275+ store = {'res.partner.contact': (_get_address_from_contact_ids, ['last_name', 'first_name'], 10),
276+ 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
277+ 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title"),
278+ #store = {'res.partner.contact': (_get_address_from_contact_ids, ['title'], 10),
279+ # 'res.partner.address': (_get_own_addresses,['contact_id'], 20)}),
280 }
281 def create(self, cr, uid, data, context={}):
282 if not data.get('location_id', False):
283@@ -238,9 +359,16 @@
284 return result.items()
285
286 _defaults = {
287- 'location_id': _default_location_id
288+ 'location_id': _default_location_id,
289+ 'sequence_contact' : lambda *a: 0,
290+ 'sequence_partner' : lambda *a: 10,
291+ 'state': lambda *a: 'current',
292 }
293+
294+ _order='sequence_partner, type, name'
295
296+
297+
298 def default_get(self, cr, uid, fields=[], context=None):
299 if context is None:
300 context = {}
301Index: /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml
302===================================================================
303--- /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml (revision 12877)
304+++ /media/truecrypt1/work/Openerp/trunk-addons/base_contact/base_contact_view.xml (revision 13001)
305@@ -1,6 +1,52 @@
306 <?xml version="1.0" encoding="utf-8"?>
307 <openerp>
308 <data>
309+
310+ <!-- Address views -->
311+
312+ <!-- Address Tree view for Contact -->
313+ <record id="view_partner_address_tree_contact" model="ir.ui.view">
314+ <field name="name">res.partner.address.tree.contact</field>
315+ <field name="model">res.partner.address</field>
316+ <field name="type">tree</field>
317+ <field eval="17" name="priority"/>
318+ <field name="arch" type="xml">
319+ <tree string="Functions and Addresses" colors="gray:state in ('past')">
320+ <field name="location_id"/>
321+ <field name="function"/>
322+ <field name="email" widget="email"/>
323+ <field name="phone"/>
324+ <field name="other" />
325+ <field name="fax"/>
326+ <field name="type"/>
327+ <field name="state" />
328+ <field name="sequence_contact" string="Seq."/>
329+ </tree>
330+ </field>
331+ </record>
332+
333+ <!-- Adress Tree view for Partner -->
334+ <record id="view_partner_address_tree_partner" model="ir.ui.view">
335+ <field name="name">res.partner.address.tree.partner</field>
336+ <field name="model">res.partner.address</field>
337+ <field name="type">tree</field>
338+ <field eval="18" name="priority"/>
339+ <field name="arch" type="xml">
340+ <tree string="Partner Contacts" colors="gray:state in ('past')" >
341+ <field name="name"/>
342+ <field name="location_id"/>
343+ <field name="function"/>
344+ <field name="email" widget="email"/>
345+ <field name="phone"/>
346+ <field name="mobile"/>
347+ <field name="other" />
348+ <field name="fax"/>
349+ <field name="type"/>
350+ <field name="state" />
351+ <field name="sequence_partner" string="Seq."/>
352+ </tree>
353+ </field>
354+ </record>
355
356 <!-- Views for Contacts Tree View -->
357
358@@ -10,7 +56,7 @@
359 <field name="type">tree</field>
360 <field name="arch" type="xml">
361 <tree string="Partner Contact">
362- <field name="name"/>
363+ <field name="last_name"/>
364 <field name="first_name"/>
365 <field name="mobile"/>
366 <field name="email"/>
367@@ -48,22 +94,7 @@
368 <field name="photo" widget='image' nolabel="1"/>
369 </group>
370 </group>
371- <field name="job_ids" colspan="4" nolabel="1" mode="tree,form">
372- <form string="Functions and Addresses">
373- <field name="partner_id" />
374- <field name="location_id" domain="[('partner_id', '=', partner_id)]"/>
375- <field name="function" />
376- <separator string="Professional Info" colspan="4"/>
377- <field name="phone"/>
378- <field name="fax"/>
379- <field name="email" widget="email"/>
380- </form>
381- <tree string="Functions and Addresses">
382- <field name="location_id"/>
383- <field name="function"/>
384- <field name="phone"/>
385- <field name="email"/>
386- </tree>
387+ <field name="job_ids" colspan="4" nolabel="1" mode="tree,form" context="{'tree_view_ref' : 'base_contact.view_partner_address_tree_contact'}">
388 </field>
389 </page>
390 <page string="Extra Information">
391@@ -93,7 +124,7 @@
392 <search string="Partner Contact">
393 <field name="name" string="First/Lastname"
394 filter_domain="['|', ('first_name','ilike', self), ('last_name', 'ilike', self)]"/>
395- <field name="partner_id" string="Partner"/>
396+ <field name="job_ids" string="Partner"/>
397 </search>
398 </field>
399 </record>
400@@ -127,6 +158,8 @@
401 <menuitem name="Contacts" id="menu_purchases_partner_contact_form" action="action_partner_contact_form"
402 parent = "base.menu_procurement_management_supplier" sequence="2"/>
403
404+ <!-- @todo: Menu addresses to be added in purchase module?! -->
405+
406 <!-- Views for Partners Form View -->
407
408 <record model="ir.ui.view" id="view_partner_form_inherit">
409@@ -135,30 +168,37 @@
410 <field name="inherit_id" ref="base.view_partner_form"/>
411 <field name="type">form</field>
412 <field name="arch" type="xml">
413- <separator string="Postal Address" position="after">
414- <field name="location_id" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', parent.id)]"/>
415- </separator>
416- <xpath expr="//field[@string='Contact Name']" position="replace">
417- <field name="contact_id"/>
418- </xpath>
419- <field name="title" position="replace"/>
420+ <field name="address" position="replace" >
421+ <field colspan="4" mode="tree,form" name="address" nolabel="1" select="1" height="260" context="{'tree_view_ref' : 'base_contact.view_partner_address_tree_partner'}">
422+ </field>
423+ </field>
424+
425 </field>
426 </record>
427+
428+
429+ <!-- Views for Location -->
430
431- <!-- Views for Addresses -->
432-
433 <record model="ir.ui.view" id="view_partner_location_form">
434 <field name="name">res.partner.location.form</field>
435 <field name="model">res.partner.location</field>
436 <field name="type">form</field>
437 <field name="arch" type="xml">
438 <form string="Locations">
439+ <field name="partner_id" readonly="1" />
440 <field name="street" colspan="4"/>
441 <field name="street2" colspan="4"/>
442 <field name="zip"/>
443 <field name="city"/>
444 <field name="country_id" />
445 <field name="state_id"/>
446+ <newline />
447+ <separator string="Contacts" colspan="4" />
448+ <field name="job_ids" nolabel="1" colspan="4" readonly="1" mode="tree">
449+ <tree>
450+ <field name = "contact_id" />
451+ </tree>
452+ </field>
453 </form>
454 </field>
455 </record>
456@@ -170,6 +210,9 @@
457 <field name="type">tree</field>
458 <field name="arch" type="xml">
459 <tree string="Locations">
460+ <field name="partner_id" string="Partner" />
461+ <field name="contact_id" />
462+ <field name="street" />
463 <field name="city"/>
464 <field name="country_id" />
465 <field name="state_id"/>
466@@ -177,6 +220,34 @@
467 </field>
468 </record>
469
470+ <record model="ir.ui.view" id="view_partner_location_search">
471+ <field name="name">res.partner.location.search</field>
472+ <field name="model">res.partner.location</field>
473+ <field name="type">search</field>
474+ <field name="arch" type="xml">
475+ <search string="Partner Location">
476+ <field name="partner_id" string="Partner"/>
477+ <field name="street" />
478+ </search>
479+ </field>
480+ </record>
481+
482+
483+ <record model="ir.actions.act_window" id="action_partner_location_form">
484+ <field name="name">Locations</field>
485+ <field name="res_model">res.partner.location</field>
486+ <field name="view_type">form</field>
487+ <field name="view_mode">tree,form</field>
488+ <field name="view_id" ref="view_partner_location_tree"/>
489+ <field name="search_view_id" ref="view_partner_location_search"/>
490+ </record>
491+ <!-- sequence=30 is because 11 is not enough for beeing below addresses to be checked further -->
492+ <menuitem name="Locations" id="menu_partner_location_form" action="action_partner_location_form" parent = "base.menu_address_book" sequence="30"/>
493+ <menuitem name="Locations" id="menu_purchase_partner_location_form" action="action_partner_location_form" parent = "base.menu_procurement_management_supplier" sequence="30"/>
494+
495+
496+ <!-- Update default address view -->
497+
498 <record model="ir.ui.view" id="view_partner_address_form_inherited0">
499 <field name='name'>res.partner.address.form.inherited0</field>
500 <field name='model'>res.partner.address</field>
501@@ -184,12 +255,22 @@
502 <field name='type'>form</field>
503 <field name='arch' type='xml'>
504 <field name="name" position="replace">
505- <field name="contact_id"/>
506+ <field name="contact_id" on_change="onchange_contact_id(contact_id)" />
507+ <!-- <field name="name" string="use this field for initial name only" /> would require adaption of create-->
508 </field>
509 <separator string="Postal Address" position="after">
510- <field name="location_id" on_change="onchange_location_id(location_id)"/>
511+ <field name="location_id" required="1" on_change="onchange_location_id(location_id)" domain="[('partner_id', '=', partner_id)]"/>
512 </separator>
513 <field name="title" position="replace"/>
514+ <field name="function" position="after">
515+ <separator string="Status" colspan="6"/>
516+ <field name="state" />
517+ <field name="date_start" />
518+ <field name="date_stop" />
519+ <separator string="Sequence" colspan="6" col="4"/>
520+ <field name="sequence_contact" string="Contact Seq."/>
521+ <field name="sequence_partner" string="Partner Seq."/>
522+ </field>
523 </field>
524 </record>
525

« Back to merge proposal