Merge lp:~openerp-dev/openobject-addons/trunk-base_contact-stw into lp:openobject-addons
- trunk-base_contact-stw
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 6009 |
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-base_contact-stw |
Merge into: | lp:openobject-addons |
Diff against target: |
943 lines (+193/-441) (has conflicts) 12 files modified
base_contact/__init__.py (+0/-1) base_contact/__openerp__.py (+0/-1) base_contact/base_contact.py (+145/-183) base_contact/base_contact_demo.xml (+2/-0) base_contact/base_contact_installer.py (+0/-67) base_contact/base_contact_installer_view.xml (+0/-59) base_contact/base_contact_view.xml (+35/-99) base_contact/process/base_contact_process.xml (+1/-26) base_contact/security/ir.model.access.csv (+7/-0) base_contact/test/base_contact00.yml (+0/-2) event/__openerp__.py (+1/-1) event/event.py (+2/-2) Text conflict in base_contact/security/ir.model.access.csv |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-base_contact-stw |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Aline (OpenERP) | Needs Fixing | ||
Raphael Collet (OpenERP) (community) | Needs Fixing | ||
Christophe Simonis (OpenERP) | Pending | ||
Review via email: mp+83401@code.launchpad.net |
Commit message
Description of the change
this branch helps to fix some bugs with the base_contact module.
Regards,
- 5789. By Stephane Wirtel (OpenERP)
-
[FIX] event: Remove the dependency to base_contact
- 5790. By Stephane Wirtel (OpenERP)
-
[FIX] base_contact: Add some missing features
Raphael Collet (OpenERP) (rco-openerp) wrote : | # |
Aline (OpenERP) (apr-tinyerp) wrote : | # |
i tested and i confirm that it breaks some addons, i can't confirm SO
it is still in testing, i put other comments in related pad
- 5791. By Stephane Wirtel (OpenERP)
-
[FIX] base_contact: Review the algo
- 5792. By Stephane Wirtel (OpenERP)
-
[REVERT]
- 5793. By Stephane Wirtel (OpenERP)
-
[FIX] base_contact: Modify the migration script
- 5794. By Stephane Wirtel (OpenERP)
-
[REF] base_contact: Remove the old installer
- 5795. By Stephane Wirtel (OpenERP)
-
[IMP] base_contact: Add the migration script for the addresses
[FIX] base_contact: Add a name_get for the location and the address - 5796. By Stephane Wirtel (OpenERP)
-
[FIX] base_contact: Assign a partner only if there is a location on the address for the creation
[IMP] base_contact: Add a view for the location - 5797. By Stephane Wirtel (OpenERP)
-
[MERGE] Upstream
- 5798. By Stephane Wirtel (OpenERP)
-
[FIX] base_contact: Increment the last value of the sequence for the locationwq
- 5799. By Stephane Wirtel (OpenERP)
-
[IMP] base_contact: improve the form view if the use_existing_
address field has been selected
Preview Diff
1 | === modified file 'base_contact/__init__.py' |
2 | --- base_contact/__init__.py 2011-01-14 00:11:01 +0000 |
3 | +++ base_contact/__init__.py 2011-12-14 09:21:40 +0000 |
4 | @@ -20,7 +20,6 @@ |
5 | ############################################################################## |
6 | |
7 | import base_contact |
8 | -import base_contact_installer |
9 | |
10 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
11 | |
12 | |
13 | === modified file 'base_contact/__openerp__.py' |
14 | --- base_contact/__openerp__.py 2011-12-13 14:19:49 +0000 |
15 | +++ base_contact/__openerp__.py 2011-12-14 09:21:40 +0000 |
16 | @@ -47,7 +47,6 @@ |
17 | 'update_xml': [ |
18 | 'security/ir.model.access.csv', |
19 | 'base_contact_view.xml', |
20 | - 'base_contact_installer_view.xml', |
21 | 'process/base_contact_process.xml' |
22 | ], |
23 | 'demo_xml': ['base_contact_demo.xml'], |
24 | |
25 | === modified file 'base_contact/base_contact.py' |
26 | --- base_contact/base_contact.py 2011-10-27 21:11:24 +0000 |
27 | +++ base_contact/base_contact.py 2011-12-14 09:21:40 +0000 |
28 | @@ -20,6 +20,7 @@ |
29 | ############################################################################## |
30 | |
31 | from osv import fields, osv |
32 | +import addons |
33 | |
34 | class res_partner_contact(osv.osv): |
35 | """ Partner Contact """ |
36 | @@ -27,27 +28,6 @@ |
37 | _name = "res.partner.contact" |
38 | _description = "Contact" |
39 | |
40 | - def _main_job(self, cr, uid, ids, fields, arg, context=None): |
41 | - """ |
42 | - @param self: The object pointer |
43 | - @param cr: the current row, from the database cursor, |
44 | - @param uid: the current user’s ID for security checks, |
45 | - @param ids: List of partner contact’s IDs |
46 | - @fields: Get Fields |
47 | - @param context: A standard dictionary for contextual values |
48 | - @param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """ |
49 | - res = dict.fromkeys(ids, False) |
50 | - |
51 | - res_partner_job_obj = self.pool.get('res.partner.job') |
52 | - all_job_ids = res_partner_job_obj.search(cr, uid, []) |
53 | - all_job_names = dict(zip(all_job_ids, res_partner_job_obj.name_get(cr, uid, all_job_ids, context=context))) |
54 | - |
55 | - for contact in self.browse(cr, uid, ids, context=context): |
56 | - if contact.job_ids: |
57 | - res[contact.id] = all_job_names.get(contact.job_ids[0].id, False) |
58 | - |
59 | - return res |
60 | - |
61 | _columns = { |
62 | 'name': fields.char('Last Name', size=64, required=True), |
63 | 'first_name': fields.char('First Name', size=64), |
64 | @@ -55,53 +35,32 @@ |
65 | 'title': fields.many2one('res.partner.title','Title'), |
66 | 'website': fields.char('Website', size=120), |
67 | 'lang_id': fields.many2one('res.lang', 'Language'), |
68 | - 'job_ids': fields.one2many('res.partner.job', 'contact_id', 'Functions and Addresses'), |
69 | + 'job_ids': fields.one2many('res.partner.address', 'contact_id', 'Functions and Addresses'), |
70 | 'country_id': fields.many2one('res.country','Nationality'), |
71 | 'birthdate': fields.date('Birth Date'), |
72 | 'active': fields.boolean('Active', help="If the active field is set to False,\ |
73 | it will allow you to hide the partner contact without removing it."), |
74 | - 'partner_id': fields.related('job_ids', 'address_id', 'partner_id', type='many2one',\ |
75 | + 'partner_id': fields.related('job_ids', 'location_id', 'partner_id', type='many2one',\ |
76 | relation='res.partner', string='Main Employer'), |
77 | 'function': fields.related('job_ids', 'function', type='char', \ |
78 | string='Main Function'), |
79 | - 'job_id': fields.function(_main_job, type='many2one',\ |
80 | - relation='res.partner.job', string='Main Job'), |
81 | 'email': fields.char('E-Mail', size=240), |
82 | 'comment': fields.text('Notes', translate=True), |
83 | - 'photo': fields.binary('Image'), |
84 | + 'photo': fields.binary('Photo'), |
85 | |
86 | } |
87 | + |
88 | + def _get_photo(self, cr, uid, context=None): |
89 | + photo_path = addons.get_module_resource('base_contact', 'images', 'photo.png') |
90 | + return open(photo_path, 'rb').read().encode('base64') |
91 | + |
92 | _defaults = { |
93 | + 'photo' : _get_photo, |
94 | 'active' : lambda *a: True, |
95 | } |
96 | |
97 | _order = "name,first_name" |
98 | |
99 | - def name_get(self, cr, user, ids, context=None): |
100 | - |
101 | - """ will return name and first_name....... |
102 | - @param self: The object pointer |
103 | - @param cr: the current row, from the database cursor, |
104 | - @param user: the current user’s ID for security checks, |
105 | - @param ids: List of create menu’s IDs |
106 | - @return: name and first_name |
107 | - @param context: A standard dictionary for contextual values |
108 | - """ |
109 | - |
110 | - if not len(ids): |
111 | - return [] |
112 | - res = [] |
113 | - for contact in self.browse(cr, user, ids, context=context): |
114 | - _contact = "" |
115 | - if contact.title: |
116 | - _contact += "%s "%(contact.title.name) |
117 | - _contact += contact.name or "" |
118 | - if contact.name and contact.first_name: |
119 | - _contact += " " |
120 | - _contact += contact.first_name or "" |
121 | - res.append((contact.id, _contact)) |
122 | - return res |
123 | - |
124 | def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=None): |
125 | if not args: |
126 | args = [] |
127 | @@ -112,151 +71,154 @@ |
128 | else: |
129 | ids = self.search(cr, uid, args, limit=limit, context=context) |
130 | return self.name_get(cr, uid, ids, context=context) |
131 | + |
132 | + def name_get(self, cr, uid, ids, context=None): |
133 | + return [ |
134 | + (obj.id, " ".join(filter(None, [obj.first_name, obj.name])),) |
135 | + for obj in self.browse(cr, uid, ids, context=context) |
136 | + ] |
137 | + |
138 | |
139 | res_partner_contact() |
140 | |
141 | +class res_partner(osv.osv): |
142 | + _inherit = 'res.partner' |
143 | + |
144 | + _columns = { |
145 | + 'address': fields.one2many('res.partner.location', 'partner_id', 'Address') |
146 | + } |
147 | + |
148 | +res_partner() |
149 | + |
150 | +class res_partner_location(osv.osv): |
151 | + _name = 'res.partner.location' |
152 | + _inherit = 'res.partner.address' |
153 | + _columns = { |
154 | + 'job_ids': fields.one2many('res.partner.address', 'location2_id', 'Contacts'), |
155 | + } |
156 | + |
157 | + def _auto_init(self, cr, context=None): |
158 | + def table_exists(view_name): |
159 | + cr.execute('SELECT count(relname) FROM pg_class WHERE relname = %s', (view_name,)) |
160 | + value = cr.fetchone()[0] |
161 | + return bool(value == 1) |
162 | + |
163 | + exists = table_exists(self._table) |
164 | + super(res_partner_location, self)._auto_init(cr, context) |
165 | + |
166 | + if not exists: |
167 | + sequence_name = self.pool.get('res.partner.address')._sequence |
168 | + cr.execute("SELECT last_value FROM " + sequence_name) |
169 | + last_sequence = cr.fetchone()[0] |
170 | + |
171 | + cr.execute("INSERT INTO res_partner_location SELECT * FROM res_partner_address") |
172 | + cr.execute("ALTER SEQUENCE " + self._sequence + " RESTART WITH " + str(last_sequence)) |
173 | + |
174 | + |
175 | +res_partner_location() |
176 | |
177 | class res_partner_address(osv.osv): |
178 | - |
179 | - #overriding of the name_get defined in base in order to remove the old contact name |
180 | - def name_get(self, cr, user, ids, context=None): |
181 | - """ |
182 | - @param self: The object pointer |
183 | - @param cr: the current row, from the database cursor, |
184 | - @param user: the current user, |
185 | - @param ids: List of partner address’s IDs |
186 | - @param context: A standard dictionary for contextual values |
187 | - """ |
188 | - |
189 | - if not len(ids): |
190 | - return [] |
191 | - res = [] |
192 | - if context is None: |
193 | - context = {} |
194 | - for r in self.read(cr, user, ids, ['zip', 'city', 'partner_id', 'street']): |
195 | - if context.get('contact_display', 'contact')=='partner' and r['partner_id']: |
196 | - res.append((r['id'], r['partner_id'][1])) |
197 | - else: |
198 | - addr = str('') |
199 | - addr += "%s %s %s" % (r.get('street', '') or '', r.get('zip', '') \ |
200 | - or '', r.get('city', '') or '') |
201 | - res.append((r['id'], addr.strip() or '/')) |
202 | - return res |
203 | - |
204 | - def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100): |
205 | - if not args: |
206 | - args=[] |
207 | - ids = self.search(cr, user, [('name',operator,name)] + args, limit=limit, context=context) |
208 | - jobs = self.pool.get('res.partner.job') |
209 | - if name: |
210 | - job_ids = jobs.search(cr, user, [('contact_id', operator, name)] + args, limit=limit, context=context) |
211 | - for job in jobs.browse(cr, user, job_ids): |
212 | - ids += [job.address_id.id] |
213 | - return self.name_get(cr, user, ids, context) |
214 | - |
215 | _name = 'res.partner.address' |
216 | - _inherit = 'res.partner.address' |
217 | - _description ='Partner Address' |
218 | - |
219 | - _columns = { |
220 | - 'job_id': fields.related('job_ids','contact_id','job_id',type='many2one',\ |
221 | - relation='res.partner.job', string='Main Job'), |
222 | - 'job_ids': fields.one2many('res.partner.job', 'address_id', 'Contacts'), |
223 | - } |
224 | -res_partner_address() |
225 | - |
226 | -class res_partner_job(osv.osv): |
227 | - def name_get(self, cr, uid, ids, context=None): |
228 | - """ |
229 | - @param self: The object pointer |
230 | - @param cr: the current row, from the database cursor, |
231 | - @param user: the current user, |
232 | - @param ids: List of partner address’s IDs |
233 | - @param context: A standard dictionary for contextual values |
234 | - """ |
235 | - if context is None: |
236 | - context = {} |
237 | - |
238 | - if not ids: |
239 | - return [] |
240 | - res = [] |
241 | - |
242 | - jobs = self.browse(cr, uid, ids, context=context) |
243 | - |
244 | - contact_ids = [rec.contact_id.id for rec in jobs] |
245 | - contact_names = dict(self.pool.get('res.partner.contact').name_get(cr, uid, contact_ids, context=context)) |
246 | - |
247 | - for r in jobs: |
248 | - function_name = r.function |
249 | - funct = function_name and (", " + function_name) or "" |
250 | - res.append((r.id, contact_names.get(r.contact_id.id, '') + funct)) |
251 | - |
252 | - return res |
253 | - |
254 | - _name = 'res.partner.job' |
255 | - _description ='Contact Partner Function' |
256 | - _order = 'sequence_contact' |
257 | - |
258 | - _columns = { |
259 | - 'name': fields.related('address_id', 'partner_id', type='many2one',\ |
260 | - relation='res.partner', string='Partner', help="You may\ |
261 | - enter Address first,Partner will be linked automatically if any."), |
262 | - 'address_id': fields.many2one('res.partner.address', 'Address', \ |
263 | - help='Address which is linked to the Partner'), # TO Correct: domain=[('partner_id', '=', name)] |
264 | - 'contact_id': fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'), |
265 | + _inherits = { 'res.partner.location' : 'location_id' } |
266 | + |
267 | + def _get_use_existing_address(self, cr, uid, ids, fieldnames, args, context=None): |
268 | + result = dict.fromkeys(ids, 0) |
269 | + for obj in self.browse(cr, uid, ids, context=context): |
270 | + result[obj.id] = 0 |
271 | + return result |
272 | + |
273 | + def _set_use_existing_address(self, cr, uid, ids, field, value, arg, context=None): |
274 | + if isinstance(ids, (int, long)): |
275 | + ids = [ids] |
276 | + |
277 | + return True |
278 | + |
279 | + _columns = { |
280 | + 'location_id' : fields.many2one('res.partner.location', 'Location'), |
281 | + 'location2_id' : fields.many2one('res.partner.location', 'Location'), |
282 | + 'contact_id' : fields.many2one('res.partner.contact', 'Contact', required=True), |
283 | + |
284 | + 'partner_id' : fields.many2one('res.partner', 'Partner'), |
285 | + 'contact_firstname' : fields.related('contact_id', 'first_name', type='char', size=64, string='Firstname'), |
286 | + 'contact_name' : fields.related('contact_id', 'name', type='char', size='64', string="Lastname"), |
287 | 'function': fields.char('Partner Function', size=64, help="Function of this contact with this partner"), |
288 | - 'sequence_contact': fields.integer('Contact Seq.',help='Order of\ |
289 | - importance of this address in the list of addresses of the linked contact'), |
290 | - 'sequence_partner': fields.integer('Partner Seq.',help='Order of importance\ |
291 | - of this job title in the list of job title of the linked partner'), |
292 | - 'email': fields.char('E-Mail', size=240, help="Job E-Mail"), |
293 | - 'phone': fields.char('Phone', size=64, help="Job Phone no."), |
294 | - 'fax': fields.char('Fax', size=64, help="Job FAX no."), |
295 | - 'extension': fields.char('Extension', size=64, help='Internal/External extension phone number'), |
296 | - 'other': fields.char('Other', size=64, help='Additional phone field'), |
297 | 'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"), |
298 | 'date_stop': fields.date('Date Stop', help="Last date of job"), |
299 | 'state': fields.selection([('past', 'Past'),('current', 'Current')], \ |
300 | - 'State', required=True, help="Status of Address"), |
301 | + 'State', required=True, help="Status of Address"), |
302 | + 'use_existing_address' : fields.function(_get_use_existing_address, type="boolean", |
303 | + fnct_inv=_set_use_existing_address, |
304 | + string='Use Existing Address'), |
305 | } |
306 | |
307 | + def name_get(self, cr, uid, ids, context=None): |
308 | + result = [] |
309 | + |
310 | + append_call = result.append |
311 | + for obj in self.browse(cr, uid, ids, context=context): |
312 | + append_call((obj.id, "%s, %s" % (obj.contact_id.name_get()[0][1], obj.location_id.name_get()[0][1],))) |
313 | + return result |
314 | + |
315 | + |
316 | + _description ='Contact Partner Function' |
317 | + |
318 | _defaults = { |
319 | - 'sequence_contact' : lambda *a: 0, |
320 | - 'state': lambda *a: 'current', |
321 | + 'state': 'current', |
322 | } |
323 | - |
324 | - def onchange_name(self, cr, uid, ids, address_id='', name='', context=None): |
325 | - return {'value': {'address_id': address_id}, 'domain':{'partner_id':'name'}} |
326 | - |
327 | - def onchange_partner(self, cr, uid, _, partner_id, context=None): |
328 | - """ |
329 | - @param self: The object pointer |
330 | - @param cr: the current row, from the database cursor, |
331 | - @param uid: the current user, |
332 | - @param _: List of IDs, |
333 | - @partner_id : ID of the Partner selected, |
334 | - @param context: A standard dictionary for contextual values |
335 | - """ |
336 | - return {'value': {'address_id': False}} |
337 | - |
338 | - def onchange_address(self, cr, uid, _, address_id, context=None): |
339 | - """ |
340 | - @@param self: The object pointer |
341 | - @param cr: the current row, from the database cursor, |
342 | - @param uid: the current user, |
343 | - @param _: List of IDs, |
344 | - @address_id : ID of the Address selected, |
345 | - @param context: A standard dictionary for contextual values |
346 | - """ |
347 | - partner_id = False |
348 | - if address_id: |
349 | - address = self.pool.get('res.partner.address')\ |
350 | - .browse(cr, uid, address_id, context=context) |
351 | - partner_id = address.partner_id.id |
352 | - return {'value': {'name': partner_id}} |
353 | - |
354 | -res_partner_job() |
355 | - |
356 | + |
357 | + def create(self, cr, uid, values, context=None): |
358 | + record_id = super(res_partner_address, self).create(cr, uid, values, context=context) |
359 | + record = self.browse(cr, uid, record_id, context=context) |
360 | + if not record.partner_id: |
361 | + record.write({'partner_id' : record.location2_id.partner_id.id}, context=context) |
362 | + return record_id |
363 | + |
364 | + def _auto_init(self, cr, context=None): |
365 | + def column_exists(column): |
366 | + cr.execute("select count(attname) from pg_attribute where attrelid = \ |
367 | + (select oid from pg_class where relname = %s) \ |
368 | + and attname = %s", (self._table, column,)) |
369 | + value = cr.fetchone()[0] |
370 | + return bool(value == 1) |
371 | + |
372 | + exists = column_exists('location_id') |
373 | + super(res_partner_address, self)._auto_init(cr, context) |
374 | + |
375 | + if not exists: |
376 | + cr.execute("UPDATE res_partner_address SET location_id = id, location2_id = id") |
377 | + |
378 | + contact_proxy = self.pool.get('res.partner.contact') |
379 | + uid = 1 |
380 | + |
381 | + cr.execute("SELECT id, name, mobile, country_id, partner_id, phone, email, street, street2, city, company_id, state_id, zip, location_id \ |
382 | + FROM res_partner_address \ |
383 | + WHERE contact_id IS NULL AND name IS NOT NULL AND location_id IS NOT NULL") |
384 | + for item in cr.fetchall(): |
385 | + |
386 | + values = { |
387 | + 'name' : item[1], |
388 | + 'mobile' : item[2], |
389 | + 'country_id' : item[3], |
390 | + 'phone' : item[5], |
391 | + 'email' : item[6], |
392 | + 'company_id' : item[10], |
393 | + } |
394 | + |
395 | + contact_id = contact_proxy.create(cr, uid, values, context=context) |
396 | + values = { |
397 | + 'street' : item[7], |
398 | + 'street2' : item[8], |
399 | + 'city' : item[9], |
400 | + 'country_id' : item[3], |
401 | + 'company_id' : item[10], |
402 | + 'state_id' : item[11], |
403 | + 'zip' : item[12], |
404 | + } |
405 | + location_id = self.pool.get('res.partner.location').create(cr, uid, values, context=context) |
406 | + |
407 | + cr.execute("UPDATE res_partner_address SET location_id = %s, contact_id = %s, partner_id = %s WHERE id = %s", |
408 | + (location_id, contact_id, item[4], item[0],)) |
409 | + |
410 | +res_partner_address() |
411 | |
412 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
413 | - |
414 | |
415 | === modified file 'base_contact/base_contact_demo.xml' |
416 | --- base_contact/base_contact_demo.xml 2011-11-28 16:04:32 +0000 |
417 | +++ base_contact/base_contact_demo.xml 2011-12-14 09:21:40 +0000 |
418 | @@ -180,6 +180,7 @@ |
419 | </record> |
420 | |
421 | <!-- Create the jobs --> |
422 | + <!-- |
423 | <record id="res_partner_job_0" model="res.partner.job"> |
424 | <field name="address_id" ref="base.res_partner_address_1"/> |
425 | <field name="function">Salesman</field> |
426 | @@ -334,5 +335,6 @@ |
427 | <field name="function">CEO</field> |
428 | <field name="sequence_contact">1</field> |
429 | </record> |
430 | + --> |
431 | </data> |
432 | </openerp> |
433 | |
434 | === removed file 'base_contact/base_contact_installer.py' |
435 | --- base_contact/base_contact_installer.py 2011-01-17 09:36:23 +0000 |
436 | +++ base_contact/base_contact_installer.py 1970-01-01 00:00:00 +0000 |
437 | @@ -1,67 +0,0 @@ |
438 | -# -*- coding: utf-8 -*- |
439 | -############################################################################## |
440 | -# |
441 | -# OpenERP, Open Source Management Solution |
442 | -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). |
443 | -# |
444 | -# This program is free software: you can redistribute it and/or modify |
445 | -# it under the terms of the GNU Affero General Public License as |
446 | -# published by the Free Software Foundation, either version 3 of the |
447 | -# License, or (at your option) any later version. |
448 | -# |
449 | -# This program is distributed in the hope that it will be useful, |
450 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
451 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
452 | -# GNU Affero General Public License for more details. |
453 | -# |
454 | -# You should have received a copy of the GNU Affero General Public License |
455 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
456 | -# |
457 | -############################################################################## |
458 | - |
459 | -from osv import fields, osv |
460 | - |
461 | -class base_contact_installer(osv.osv_memory): |
462 | - _name = 'base.contact.installer' |
463 | - _inherit = 'res.config.installer' |
464 | - |
465 | - _columns = { |
466 | - 'name': fields.char('Name', size=64), |
467 | - 'migrate': fields.boolean('Migrate', help="If you select this, all addresses will be migrated."), |
468 | - } |
469 | - |
470 | - def execute(self, cr, uid, ids, context=None): |
471 | - """ |
472 | - This function is used to create contact and address from existing partner address |
473 | - """ |
474 | - obj = self.pool.get("base.contact.installer").browse(cr, uid, uid, context=context) |
475 | - if obj.migrate: |
476 | - # Enable PL/pgSQL if not enabled yet in the database |
477 | - cr.execute("SELECT 1 FROM pg_language WHERE lanname = 'plpgsql'") |
478 | - if not cr.fetchone(): |
479 | - cr.execute("CREATE LANGUAGE plpgsql;") |
480 | - |
481 | - cr.execute("""DROP TRIGGER IF EXISTS contactjob on res_partner_contact; |
482 | - CREATE OR REPLACE FUNCTION add_to_job() RETURNS TRIGGER AS $contactjob$ |
483 | - DECLARE |
484 | - new_name varchar; |
485 | - new_phonenum varchar; |
486 | - BEGIN |
487 | - IF(TG_OP='INSERT') THEN |
488 | - INSERT INTO res_partner_job(contact_id, address_id, function, state) VALUES(NEW.id, NEW.website::integer,NEW.first_name, 'current'); |
489 | - UPDATE res_partner_contact set first_name=Null, website=Null, active=True where id=NEW.id; |
490 | - END IF; |
491 | - RETURN NEW; |
492 | - END; |
493 | - $contactjob$ LANGUAGE plpgsql; |
494 | - CREATE TRIGGER contactjob AFTER INSERT ON res_partner_contact FOR EACH ROW EXECUTE PROCEDURE add_to_job();""") |
495 | - |
496 | - cr.execute("INSERT into res_partner_contact (name, title, email, first_name, website) (SELECT coalesce(name, 'Noname'), title, email, function , to_char(id, '99999999') from res_partner_address)") |
497 | - |
498 | - cr.execute("DROP TRIGGER IF EXISTS contactjob on res_partner_contact") |
499 | - |
500 | - cr.execute("DROP FUNCTION IF EXISTS add_to_job()") |
501 | - |
502 | -base_contact_installer() |
503 | - |
504 | -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
505 | |
506 | === removed file 'base_contact/base_contact_installer_view.xml' |
507 | --- base_contact/base_contact_installer_view.xml 2011-08-04 12:09:57 +0000 |
508 | +++ base_contact/base_contact_installer_view.xml 1970-01-01 00:00:00 +0000 |
509 | @@ -1,59 +0,0 @@ |
510 | -<openerp> |
511 | - <data> |
512 | - <record id="view_base_contact_installer" model="ir.ui.view"> |
513 | - <field name="name">base.contact.installer.view</field> |
514 | - <field name="model">base.contact.installer</field> |
515 | - <field name="type">form</field> |
516 | - <field name="inherit_id" ref="base.res_config_installer"/> |
517 | - <field name="arch" type="xml"> |
518 | - <data> |
519 | - <form position="attributes"> |
520 | - <attribute name="string">Address's Migration to Contacts</attribute> |
521 | - </form> |
522 | - |
523 | - <separator string="title" position="attributes"> |
524 | - <attribute name="string">Select the Option for Addresses Migration</attribute> |
525 | - </separator> |
526 | - <xpath expr="//label[@string='description']" position="attributes"> |
527 | - <attribute name="string">You can migrate Partner's current addresses to the contact.</attribute> |
528 | - </xpath> |
529 | - <xpath expr="//separator[@string="vsep"]" position="attributes"> |
530 | - <attribute name="rowspan">13</attribute> |
531 | - <attribute name="string"/> |
532 | - </xpath> |
533 | - <xpath expr="//button[@string='Install Modules']" position="attributes"> |
534 | - <attribute name="string">Configure</attribute> |
535 | - </xpath> |
536 | - <group colspan="8"> |
537 | - <group colspan="2" col="2"> |
538 | - <label string="Due to changes in Address and Partner's relation, some of the details from address are needed to be migrated into contact information." colspan="4"/> |
539 | - <label string="Otherwise these details will not be visible from address/contact." colspan="4"/> |
540 | - <label string="Do you want to migrate your Address data in Contact Data?" colspan="4"/> |
541 | - <group colspan="6"> |
542 | - <field name="migrate" string="Migrate" colspan="1"/> |
543 | - </group> |
544 | - </group> |
545 | - </group> |
546 | - </data> |
547 | - </field> |
548 | - </record> |
549 | - |
550 | - <record id="action_base_contact_installer" model="ir.actions.act_window"> |
551 | - <field name="name">Address Migration</field> |
552 | - <field name="type">ir.actions.act_window</field> |
553 | - <field name="res_model">base.contact.installer</field> |
554 | - <field name="view_id" ref="view_base_contact_installer"/> |
555 | - <field name="view_type">form</field> |
556 | - <field name="view_mode">form</field> |
557 | - <field name="target">new</field> |
558 | - </record> |
559 | - |
560 | - <record id="base_contact_installer_todo" model="ir.actions.todo"> |
561 | - <field name="action_id" ref="action_base_contact_installer"/> |
562 | - <field name="category_id" ref="base.category_administration_config"/> |
563 | - <field name="sequence">3</field> |
564 | - <field name="type">automatic</field> |
565 | - </record> |
566 | - |
567 | - </data> |
568 | -</openerp> |
569 | |
570 | === modified file 'base_contact/base_contact_view.xml' |
571 | --- base_contact/base_contact_view.xml 2011-10-27 21:11:24 +0000 |
572 | +++ base_contact/base_contact_view.xml 2011-12-14 09:21:40 +0000 |
573 | @@ -51,10 +51,8 @@ |
574 | <field name="job_ids" colspan="4" nolabel="1" mode="tree,form"> |
575 | <form string="Functions and Addresses"> |
576 | <group colspan="4" col="4"> |
577 | - <field name="sequence_contact" /> |
578 | <field name="function"/> |
579 | - <field name="name" on_change="onchange_name(name,address_id)"/> |
580 | - <field name="address_id"/> |
581 | + <field name="name" /> |
582 | <field name="date_start" /> |
583 | <field name="date_stop" /> |
584 | <field name="state" /> |
585 | @@ -65,19 +63,13 @@ |
586 | <field name="phone"/> |
587 | <field name="fax"/> |
588 | <field name="email" widget="email"/> |
589 | - <field name="extension"/> |
590 | - <field name="other"/> |
591 | </group> |
592 | </form> |
593 | <tree string="Functions and Addresses"> |
594 | - <field name="sequence_contact" string="Seq."/> |
595 | <field name="function"/> |
596 | <field name="name" on_change="onchange_partner(name)"/> |
597 | - <field name="address_id" attrs="{'required': [('name', '!=', False)]}" on_change="onchange_address(address_id)"/> |
598 | <field name="phone"/> |
599 | <field name="fax"/> |
600 | - <field name="extension"/> |
601 | - <field name="other"/> |
602 | <field name="email"/> |
603 | <field name="state" /> |
604 | </tree> |
605 | @@ -173,29 +165,23 @@ |
606 | </group> |
607 | <field name="job_ids" mode="tree,form" nolabel="1" colspan="4"> |
608 | <tree string="Contacts" editable="top"> |
609 | - <field name="sequence_partner"/> |
610 | <field name="contact_id"/> |
611 | <field name="function"/> |
612 | <field name="phone"/> |
613 | <field name="fax"/> |
614 | - <field name="extension"/> |
615 | - <field name="other"/> |
616 | <field name="email"/> |
617 | </tree> |
618 | <form string="Contacts"> |
619 | - <group colspan="4" col="4"> |
620 | - <field name="sequence_partner"/> |
621 | - <field name="contact_id"/> |
622 | - <field name="function"/> |
623 | - </group> |
624 | - <separator string="Communication" colspan="4"/> |
625 | - <group colspan="4" col="4"> |
626 | - <field name="phone"/> |
627 | - <field name="fax"/> |
628 | - <field name="extension"/> |
629 | - <field name="other"/> |
630 | - <field name="email" widget="email"/> |
631 | - </group> |
632 | + <group colspan="4" col="4"> |
633 | + <field name="contact_id"/> |
634 | + <field name="function"/> |
635 | + </group> |
636 | + <separator string="Communication" colspan="4"/> |
637 | + <group colspan="4" col="4"> |
638 | + <field name="phone"/> |
639 | + <field name="fax"/> |
640 | + <field name="email" widget="email"/> |
641 | + </group> |
642 | </form> |
643 | </field> |
644 | </form> |
645 | @@ -256,83 +242,29 @@ |
646 | |
647 | <!-- Views for Addresses --> |
648 | |
649 | - <record model="ir.ui.view" id="view_partner_address_tree_inherited1"> |
650 | - <field name="name">Partner addresses inherited</field> |
651 | - <field name="model">res.partner.address</field> |
652 | - <field name="inherit_id" ref="base.view_partner_address_tree"/> |
653 | - <field name="type">tree</field> |
654 | - <field name="arch" type="xml"> |
655 | - <field name="name" position="replace"> |
656 | - <field name='job_ids' string='# of Contacts'/> |
657 | - </field> |
658 | - </field> |
659 | - </record> |
660 | - |
661 | <record model="ir.ui.view" id="view_partner_address_form_inherited0"> |
662 | <field name='name'>res.partner.address.form.inherited0</field> |
663 | <field name='model'>res.partner.address</field> |
664 | <field name="inherit_id" ref="base.view_partner_address_form1"/> |
665 | <field name='type'>form</field> |
666 | <field name='arch' type='xml'> |
667 | - <field name="type" position="replace"> |
668 | - </field> |
669 | - </field> |
670 | - </record> |
671 | - |
672 | - <record model="ir.ui.view" id="view_partner_address_form_inherited1"> |
673 | - <field name='name'>res.partner.address.form.inherited1</field> |
674 | - <field name='model'>res.partner.address</field> |
675 | - <field name="inherit_id" ref="base.view_partner_address_form1"/> |
676 | - <field name='type'>form</field> |
677 | - <field name='arch' type='xml'> |
678 | - <field name="name" position="replace"> |
679 | - </field> |
680 | - </field> |
681 | - </record> |
682 | - |
683 | - <record id='view_partner_address_form_inherited2' model='ir.ui.view'> |
684 | - <field name='name'>res.partner.address.form.inherited2</field> |
685 | - <field name='model'>res.partner.address</field> |
686 | - <field name="inherit_id" ref="base.view_partner_address_form1"/> |
687 | - <field name='type'>form</field> |
688 | - <field name='arch' type='xml'> |
689 | - <field name="title" position="replace"> |
690 | - </field> |
691 | - </field> |
692 | - </record> |
693 | - |
694 | - <record id='view_partner_address_form_inherited3' model='ir.ui.view'> |
695 | - <field name='name'>res.partner.address.form.inherited3</field> |
696 | - <field name='model'>res.partner.address</field> |
697 | - <field name="inherit_id" ref="base.view_partner_address_form1"/> |
698 | - <field name='type'>form</field> |
699 | - <field name='arch' type='xml'> |
700 | - <field name="function" position="replace"> |
701 | - </field> |
702 | - </field> |
703 | - </record> |
704 | - |
705 | - <record id='view_partner_address_form_inherited4' model='ir.ui.view'> |
706 | - <field name='name'>res.partner.address.form.inherited4</field> |
707 | - <field name='model'>res.partner.address</field> |
708 | - <field name="inherit_id" ref="base.view_partner_address_form1"/> |
709 | - <field name='type'>form</field> |
710 | - <field name='arch' type='xml'> |
711 | - <field name='mobile' position="replace"> |
712 | - </field> |
713 | - </field> |
714 | - </record> |
715 | - |
716 | - <record model="ir.ui.view" id="view_partner_address_form_inherited6"> |
717 | - <field name='name'>res.partner.address.form.inherited6</field> |
718 | - <field name='model'>res.partner.address</field> |
719 | - <field name="inherit_id" ref="base.view_partner_address_form1"/> |
720 | - <field name='type'>form</field> |
721 | - <field name='arch' type='xml'> |
722 | + <field name="type" position="replace" /> |
723 | + <field name="title" position="replace" /> |
724 | + <field name="function" position="replace" /> |
725 | + <field name="name" position="replace" /> |
726 | + <field name="active" position="after"> |
727 | + <separator string="Contact" colspan="6" /> |
728 | + <group colspan="6" col="2"> |
729 | + <field name="title" /> |
730 | + <field name="contact_id" /> |
731 | + <field name="contact_firstname" /> |
732 | + <field name="contact_name" /> |
733 | + </group> |
734 | + </field> |
735 | <field name="partner_id" position="replace"> |
736 | <field name='partner_id' select='1'/> |
737 | - <field name='type' select='2'/> |
738 | - <field name='job_id' invisible="1"/> |
739 | + <field name='type' select='2' invisible="1"/> |
740 | + <field name="function" /> |
741 | </field> |
742 | </field> |
743 | </record> |
744 | @@ -344,13 +276,14 @@ |
745 | <field name="inherit_id" ref="base.view_res_partner_address_filter"/> |
746 | <field name="arch" type="xml"> |
747 | <search string="Search Contact"> |
748 | - <field name="job_ids"/> |
749 | + <field name="job_ids"/> |
750 | </search> |
751 | </field> |
752 | </record> |
753 | |
754 | <!-- Views for partner job Tree view --> |
755 | |
756 | + <!-- |
757 | <record model="ir.ui.view" id="view_partner_job_tree"> |
758 | <field name="name">res.partner.job.tree</field> |
759 | <field name="model">res.partner.job</field> |
760 | @@ -364,14 +297,15 @@ |
761 | <field name="email"/> |
762 | <field name="phone"/> |
763 | <field name="fax"/> |
764 | - <field name="extension"/> |
765 | <field name="state" /> |
766 | </tree> |
767 | </field> |
768 | </record> |
769 | + --> |
770 | |
771 | <!-- Views for partner job Form view --> |
772 | |
773 | + <!-- |
774 | <record model="ir.ui.view" id="view_partner_job_form"> |
775 | <field name="name">res.partner.job.form</field> |
776 | <field name="model">res.partner.job</field> |
777 | @@ -385,18 +319,17 @@ |
778 | <field name="email" widget="email"/> |
779 | <field name="phone"/> |
780 | <field name="fax"/> |
781 | - <field name="extension"/> |
782 | - <field name="sequence_contact" groups="base.group_user"/> |
783 | - <field name="sequence_partner" groups="base.group_user"/> |
784 | <field name="date_start" groups="base.group_user"/> |
785 | <field name="date_stop" groups="base.group_user"/> |
786 | <field name="state" /> |
787 | </form> |
788 | </field> |
789 | </record> |
790 | + --> |
791 | |
792 | <!-- Menuitem for res.partner.job --> |
793 | |
794 | + <!-- |
795 | <record model="ir.actions.act_window" id="action_res_partner_job"> |
796 | <field name="name">Contact's Jobs</field> |
797 | <field name="type">ir.actions.act_window</field> |
798 | @@ -409,9 +342,11 @@ |
799 | res_model="res.partner.job" |
800 | src_model="res.partner" |
801 | /> |
802 | + --> |
803 | |
804 | <!-- Act window defining a shorcut on partner address to open all his jobs --> |
805 | |
806 | + <!-- |
807 | <act_window |
808 | id="act_res_partner_jobs" |
809 | name="Open Jobs" |
810 | @@ -419,6 +354,7 @@ |
811 | res_model="res.partner.job" |
812 | src_model="res.partner.address" |
813 | /> |
814 | + --> |
815 | |
816 | </data> |
817 | </openerp> |
818 | |
819 | === added file 'base_contact/images/photo.png' |
820 | Binary files base_contact/images/photo.png 1970-01-01 00:00:00 +0000 and base_contact/images/photo.png 2011-12-14 09:21:40 +0000 differ |
821 | === modified file 'base_contact/process/base_contact_process.xml' |
822 | --- base_contact/process/base_contact_process.xml 2011-01-14 00:11:01 +0000 |
823 | +++ base_contact/process/base_contact_process.xml 2011-12-14 09:21:40 +0000 |
824 | @@ -36,15 +36,6 @@ |
825 | <field eval="1" name="flow_start"/> |
826 | </record> |
827 | |
828 | - <record id="process_node_function0" model="process.node"> |
829 | - <field name="model_id" ref="base_contact.model_res_partner_job"/> |
830 | - <field eval=""""state"""" name="kind"/> |
831 | - <field eval=""""Jobs at a same partner address."""" name="note"/> |
832 | - <field eval=""""Function"""" name="name"/> |
833 | - <field name="process_id" ref="process_process_basecontactprocess0"/> |
834 | - <field eval="0" name="flow_start"/> |
835 | - </record> |
836 | - |
837 | <record id="process_node_addresses0" model="process.node"> |
838 | <field name="menu_id" ref="base.menu_partner_address_form"/> |
839 | <field name="model_id" ref="base.model_res_partner_address"/> |
840 | @@ -59,22 +50,6 @@ |
841 | Process Transition |
842 | --> |
843 | |
844 | - <record id="process_transition_contacttofunction0" model="process.transition"> |
845 | - <field eval="[(6,0,[])]" name="transition_ids"/> |
846 | - <field eval=""""Contact to function"""" name="name"/> |
847 | - <field eval=""""Defines contacts and functions."""" name="note"/> |
848 | - <field model="process.node" name="target_node_id" ref="process_node_function0"/> |
849 | - <field model="process.node" name="source_node_id" ref="process_node_contacts0"/> |
850 | - </record> |
851 | - |
852 | - <record id="process_transition_functiontoaddress0" model="process.transition"> |
853 | - <field eval="[(6,0,[])]" name="transition_ids"/> |
854 | - <field eval=""""Function to address"""" name="name"/> |
855 | - <field eval=""""Define functions and address."""" name="note"/> |
856 | - <field model="process.node" name="target_node_id" ref="process_node_addresses0"/> |
857 | - <field model="process.node" name="source_node_id" ref="process_node_function0"/> |
858 | - </record> |
859 | - |
860 | <record id="process_transition_partnertoaddress0" model="process.transition"> |
861 | <field eval="[(6,0,[])]" name="transition_ids"/> |
862 | <field eval=""""Partner to address"""" name="name"/> |
863 | @@ -84,4 +59,4 @@ |
864 | </record> |
865 | |
866 | </data> |
867 | -</openerp> |
868 | \ No newline at end of file |
869 | +</openerp> |
870 | |
871 | === modified file 'base_contact/security/ir.model.access.csv' |
872 | --- base_contact/security/ir.model.access.csv 2011-12-12 18:11:13 +0000 |
873 | +++ base_contact/security/ir.model.access.csv 2011-12-14 09:21:40 +0000 |
874 | @@ -1,3 +1,4 @@ |
875 | +<<<<<<< TREE |
876 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
877 | access_res_partner_contact,res.partner.contact,model_res_partner_contact,base.group_partner_manager,1,1,1,1 |
878 | access_res_partner_job,res.partner.job,model_res_partner_job,base.group_partner_manager,1,1,1,1 |
879 | @@ -5,3 +6,9 @@ |
880 | access_res_partner_job_all,res.partner.job all,model_res_partner_job,base.group_user,1,0,0,0 |
881 | access_group_sale_salesman,res.partner.contact.sale.salesman,model_res_partner_contact,base.group_sale_salesman,1,1,1,0 |
882 | access_res_partner_job_salesman,res.partner.job.salesman,model_res_partner_job,base.group_sale_salesman,1,1,1,0 |
883 | +======= |
884 | +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
885 | +"access_res_partner_contact","res.partner.contact","model_res_partner_contact","base.group_partner_manager",1,1,1,1 |
886 | +"access_res_partner_contact_all","res.partner.contact all","model_res_partner_contact","base.group_user",1,0,0,0 |
887 | +"access_group_sale_salesman","res.partner.contact.sale.salesman","model_res_partner_contact","base.group_sale_salesman",1,1,1,0 |
888 | +>>>>>>> MERGE-SOURCE |
889 | |
890 | === modified file 'base_contact/test/base_contact00.yml' |
891 | --- base_contact/test/base_contact00.yml 2011-11-28 16:04:32 +0000 |
892 | +++ base_contact/test/base_contact00.yml 2011-12-14 09:21:40 +0000 |
893 | @@ -25,7 +25,6 @@ |
894 | - email: lwilliams@mydomain.com |
895 | function: PA |
896 | phone: (+32).10.45.18.77 |
897 | - sequence_contact: 1 |
898 | state: current |
899 | lang_id: res_lang_french0 |
900 | mobile: (+32).10.45.18.77 |
901 | @@ -45,7 +44,6 @@ |
902 | - address_id: res_partner_address_1 |
903 | function: CEO |
904 | contact_id: res_partner_contact_williams0 |
905 | - sequence_partner: 2 |
906 | state: current |
907 | lang: fr_BE |
908 | name: Laura's Company |
909 | |
910 | === modified file 'event/__openerp__.py' |
911 | --- event/__openerp__.py 2011-12-13 14:19:49 +0000 |
912 | +++ event/__openerp__.py 2011-12-14 09:21:40 +0000 |
913 | @@ -39,7 +39,7 @@ |
914 | Association / Configuration / Types of Events |
915 | """, |
916 | 'author': 'OpenERP SA', |
917 | - 'depends': ['crm', 'base_contact', 'account', 'marketing', 'mail'], |
918 | + 'depends': ['crm', 'account', 'marketing', 'mail'], |
919 | 'init_xml': [], |
920 | 'update_xml': [ |
921 | 'security/ir.model.access.csv', |
922 | |
923 | === modified file 'event/event.py' |
924 | --- event/event.py 2011-11-14 22:08:36 +0000 |
925 | +++ event/event.py 2011-12-14 09:21:40 +0000 |
926 | @@ -303,7 +303,7 @@ |
927 | 'event_id': fields.many2one('event.event', 'Event', required=True, readonly=True, states={'draft': [('readonly', False)]}), |
928 | 'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}), |
929 | "partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced', readonly=True, states={'draft': [('readonly', False)]}), |
930 | - "contact_id": fields.many2one('res.partner.contact', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}), #TODO: filter only the contacts that have a function into the selected partner_id |
931 | + "contact_id": fields.many2one('res.partner.address', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}), #TODO: filter only the contacts that have a function into the selected partner_id |
932 | "unit_price": fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Sale Price'), readonly=True, states={'draft': [('readonly', False)]}), |
933 | 'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute=dp.get_precision('Sale Price'), store=True), |
934 | "badge_ids": fields.one2many('event.registration.badge', 'registration_id', 'Badges', readonly=False, states={'done': [('readonly', True)]}), |
935 | @@ -382,7 +382,7 @@ |
936 | inv_lines_pool = self.pool.get('account.invoice.line') |
937 | inv_pool = self.pool.get('account.invoice') |
938 | product_pool = self.pool.get('product.product') |
939 | - contact_pool = self.pool.get('res.partner.contact') |
940 | + contact_pool = self.pool.get('res.partner.address') |
941 | if context is None: |
942 | context = {} |
943 | # If date was specified, use it as date invoiced, usefull when invoices are generated this month and put the |
It breaks module stock.
I created a database, and installed base_contact, then sale. The following error occurs:
[2011-11-30 15:09:12,683][foo] INFO:init. load:module stock: loading test/stock_test.yml id","name" ,"auto_ picking" ,"move_ type"," company_ id","invoice_ state", "state" ,"date" ,"type" ,create_ uid,create_ date) values (2,41,' test_picking' ,'False' ,'direct' ,1,'2binvoiced' ,'draft' ,'2011- 11-30 15:09:15' ,'out', 1,now() ) openerp/ openerp/ server/ trunk/openerp/ sql_db. py", line 215, in execute execute( query, params) picking_ address_ id_fkey"
[2011-11-30 15:09:15,241][foo] ERROR:db.cursor:bad query: insert into "stock_picking" (id,"address_
Traceback (most recent call last):
File "/home/
res = self._obj.
IntegrityError: insert or update on table "stock_picking" violates foreign key constraint "stock_
DETAIL: Key (address_id)=(41) is not present in table "res_partner_job".