Merge lp:~unifield-team/unifield-server/us-750-752 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 3679
Proposed branch: lp:~unifield-team/unifield-server/us-750-752
Merge into: lp:unifield-server
Diff against target: 2427 lines (+1076/-350) (has conflicts)
32 files modified
bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py (+62/-18)
bin/addons/msf_outgoing/msf_outgoing.py (+26/-53)
bin/addons/msf_outgoing/report/empty_picking_ticket.rml (+7/-7)
bin/addons/msf_outgoing/report/labels.rml (+1/-1)
bin/addons/msf_outgoing/report/packing_list.rml (+7/-7)
bin/addons/msf_outgoing/report/packing_list_xls.mako (+3/-3)
bin/addons/msf_outgoing/report/picking_ticket.py (+3/-3)
bin/addons/msf_outgoing/report/picking_ticket.rml (+7/-7)
bin/addons/msf_outgoing/wizard/create_picking_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/internal_move_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/outgoing_delivery_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/picking_processor.py (+26/-16)
bin/addons/msf_outgoing/wizard/ppl_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/return_ppl_processor.py (+10/-6)
bin/addons/msf_outgoing/wizard/validate_picking_processor.py (+10/-6)
bin/addons/msf_printed_documents/report/freight_manifest.py (+3/-3)
bin/addons/msf_printed_documents/report/report_reception.py (+3/-1)
bin/addons/msf_profile/data/patches.xml (+47/-0)
bin/addons/msf_profile/msf_profile.py (+24/-0)
bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv (+3/-3)
bin/addons/product_attributes/product_attributes.py (+353/-17)
bin/addons/product_attributes/product_attributes_data.xml (+45/-30)
bin/addons/product_attributes/product_attributes_view.xml (+0/-1)
bin/addons/specific_rules/specific_rules.py (+276/-102)
bin/addons/specific_rules/specific_rules_view.xml (+1/-1)
bin/addons/specific_rules/wizard/stock_partial_move.py (+78/-18)
bin/addons/specific_rules/wizard/stock_partial_picking.py (+3/-3)
bin/addons/stock_forecast/wizard/stock_forecast.py (+3/-4)
bin/addons/stock_override/stock.py (+2/-9)
bin/addons/sync_so/sale.py (+8/-0)
bin/osv/orm.py (+15/-1)
Text conflict in bin/addons/msf_profile/data/patches.xml
Text conflict in bin/addons/sync_so/sale.py
To merge this branch: bzr merge lp:~unifield-team/unifield-server/us-750-752
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+289473@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py'
2--- bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2015-11-03 12:55:51 +0000
3+++ bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2016-03-18 10:41:28 +0000
4@@ -887,13 +887,15 @@
5
6
7 product = line.imp_product_id or line.move_product_id
8- res[line.id] = {'lot_check': product.batch_management,
9- 'exp_check': product.perishable,
10- 'kc_check': product.heat_sensitive_item and True or False,
11- 'dg_check': product.dangerous_goods,
12- 'np_check': product.narcotic,
13- 'move_price_unit': price_unit,
14- 'move_currency_id': curr_id, }
15+ res[line.id] = {
16+ 'lot_check': product.batch_management,
17+ 'exp_check': product.perishable,
18+ 'kc_check': product.kc_txt,
19+ 'dg_check': product.dg_txt,
20+ 'np_check': product.cs_txt,
21+ 'move_price_unit': price_unit,
22+ 'move_currency_id': curr_id,
23+ }
24
25 return res
26
27@@ -975,17 +977,59 @@
28 'message_esc1': fields.char(size=256, string='Message ESC 1', readonly=True),
29 'message_esc2': fields.char(size=256, string='Message ESC 2', readonly=True),
30 # Computed fields
31- 'lot_check': fields.function(_get_values, method=True, type='boolean',
32- string='B.Num', readonly=True, store=False, multi='computed'),
33- 'exp_check': fields.function(_get_values, method=True, type='boolean',
34- string='Exp', readonly=True, store=False, multi='computed'),
35- 'kc_check': fields.function(_get_values, method=True, type='boolean',
36- string='KC', readonly=True, store=False, multi='computed'),
37- 'dg_check': fields.function(_get_values, method=True, type='boolean',
38- string='DG', readonly=True, store=False, multi='computed'),
39- 'np_check': fields.function(_get_values, method=True, type='boolean',
40- string='NP', readonly=True, store=False, multi='computed'),
41- 'integrity_status': fields.selection(string=' ', selection=INTEGRITY_STATUS_SELECTION, readonly=True),
42+ 'lot_check': fields.function(
43+ _get_values,
44+ method=True,
45+ type='boolean',
46+ string='B.Num',
47+ readonly=True,
48+ store=False,
49+ multi='computed',
50+ ),
51+ 'exp_check': fields.function(
52+ _get_values,
53+ method=True,
54+ type='boolean',
55+ string='Exp',
56+ readonly=True,
57+ store=False,
58+ multi='computed',
59+ ),
60+ 'kc_check': fields.function(
61+ _get_values,
62+ method=True,
63+ type='char',
64+ size=8,
65+ string='KC',
66+ readonly=True,
67+ store=False,
68+ multi='computed',
69+ ),
70+ 'dg_check': fields.function(
71+ _get_values,
72+ method=True,
73+ type='char',
74+ size=8,
75+ string='DG',
76+ readonly=True,
77+ store=False,
78+ multi='computed',
79+ ),
80+ 'np_check': fields.function(
81+ _get_values,
82+ method=True,
83+ type='char',
84+ size=8,
85+ string='CS',
86+ readonly=True,
87+ store=False,
88+ multi='computed',
89+ ),
90+ 'integrity_status': fields.selection(
91+ selection=INTEGRITY_STATUS_SELECTION,
92+ string=' ',
93+ readonly=True,
94+ ),
95 }
96
97 _defaults = {
98
99=== modified file 'bin/addons/msf_outgoing/msf_outgoing.py'
100--- bin/addons/msf_outgoing/msf_outgoing.py 2016-03-14 10:07:38 +0000
101+++ bin/addons/msf_outgoing/msf_outgoing.py 2016-03-18 10:41:28 +0000
102@@ -2023,16 +2023,17 @@
103 result = {}
104
105 for stock_picking in self.read(cr, uid, ids, ['pack_family_memory_ids', 'move_lines'], context=context):
106- values = {'total_amount': 0.0,
107- 'currency_id': False,
108- 'is_dangerous_good': False,
109- 'is_keep_cool': False,
110- 'is_narcotic': False,
111- 'num_of_packs': 0,
112- 'total_volume': 0.0,
113- 'total_weight': 0.0,
114- # 'is_completed': False,
115- }
116+ values = {
117+ 'total_amount': 0.0,
118+ 'currency_id': False,
119+ 'is_dangerous_good': '',
120+ 'is_keep_cool': '',
121+ 'is_narcotic': '',
122+ 'num_of_packs': 0,
123+ 'total_volume': 0.0,
124+ 'total_weight': 0.0,
125+ # 'is_completed': False,
126+ }
127 result[stock_picking['id']] = values
128
129 if stock_picking['pack_family_memory_ids']:
130@@ -2057,11 +2058,11 @@
131 # currency
132 values['currency_id'] = move['currency_id'] or False
133 # dangerous good
134- values['is_dangerous_good'] = move['is_dangerous_good']
135+ values['is_dangerous_good'] = values['is_dangerous_good'] or move['is_dangerous_good']
136 # keep cool - if heat_sensitive_item is True
137- values['is_keep_cool'] = move['is_keep_cool']
138+ values['is_keep_cool'] = values['is_dangerous_good'] or move['is_keep_cool']
139 # narcotic
140- values['is_narcotic'] = move['is_narcotic']
141+ values['is_narcotic'] = values['is_dangerous_good'] or move['is_narcotic']
142
143 # completed field - based on the previous_step_ids field, recursive call from picking to draft packing and packing
144 # - picking checks that the corresponding ppl is completed
145@@ -2244,9 +2245,9 @@
146 'total_weight': fields.function(_vals_get, method=True, type='float', string='Total Weight[kg]', multi='get_vals'),
147 'total_amount': fields.function(_vals_get, method=True, type='float', string='Total Amount', digits_compute=dp.get_precision('Picking Price'), multi='get_vals'),
148 'currency_id': fields.function(_vals_get, method=True, type='many2one', relation='res.currency', string='Currency', multi='get_vals'),
149- 'is_dangerous_good': fields.function(_vals_get, method=True, type='boolean', string='Dangerous Good', multi='get_vals'),
150- 'is_keep_cool': fields.function(_vals_get, method=True, type='boolean', string='Keep Cool', multi='get_vals'),
151- 'is_narcotic': fields.function(_vals_get, method=True, type='boolean', string='Narcotic', multi='get_vals'),
152+ 'is_dangerous_good': fields.function(_vals_get, method=True, type='char', size=8, string='Dangerous Good', multi='get_vals'),
153+ 'is_keep_cool': fields.function(_vals_get, method=True, type='char', size=8, string='Keep Cool', multi='get_vals'),
154+ 'is_narcotic': fields.function(_vals_get, method=True, type='char', size=8, string='CS', multi='get_vals'),
155 'overall_qty': fields.function(_get_overall_qty, method=True, fnct_search=_qty_search, type='float', string='Overall Qty',
156 store={'stock.move': (_get_picking_ids, ['product_qty', 'picking_id'], 10), }),
157 'line_state': fields.function(_get_lines_state, method=True, type='selection',
158@@ -4462,34 +4463,6 @@
159 wizard()
160
161
162-class product_product(osv.osv):
163- '''
164- add a getter for keep cool notion
165- '''
166- _inherit = 'product.product'
167-
168- def _vals_get(self, cr, uid, ids, fields, arg, context=None):
169- '''
170- get functional values
171- '''
172- result = {}
173- for product in self.browse(cr, uid, ids, context=context):
174- values = {'is_keep_cool': False,
175- }
176- result[product.id] = values
177- # keep cool
178- is_keep_cool = bool(product.heat_sensitive_item) # in ('*', '**', '***',)
179- values['is_keep_cool'] = is_keep_cool
180-
181- return result
182-
183- _columns = {'is_keep_cool': fields.function(_vals_get, method=True, type='boolean', string='Keep Cool', multi='get_vals',),
184- 'prodlot_ids': fields.one2many('stock.production.lot', 'product_id', string='Batch Numbers',),
185- }
186-
187-product_product()
188-
189-
190 class stock_move(osv.osv):
191 '''
192 stock move
193@@ -4524,9 +4497,9 @@
194 'amount': 0.0,
195 'currency_id': False,
196 'num_of_packs': 0,
197- 'is_dangerous_good': False,
198- 'is_keep_cool': False,
199- 'is_narcotic': False,
200+ 'is_dangerous_good': '',
201+ 'is_keep_cool': '',
202+ 'is_narcotic': '',
203 'sale_order_line_number': 0,
204 }
205 result[move.id] = values
206@@ -4555,11 +4528,11 @@
207 # currency
208 values['currency_id'] = move.sale_line_id and move.sale_line_id.currency_id and move.sale_line_id.currency_id.id or False
209 # dangerous good
210- values['is_dangerous_good'] = move.product_id and move.product_id.dangerous_goods or False
211+ values['is_dangerous_good'] = move.product_id and move.product_id.dg_txt or ''
212 # keep cool - if heat_sensitive_item is True
213- values['is_keep_cool'] = bool(move.product_id and move.product_id.heat_sensitive_item or False)
214+ values['is_keep_cool'] = move.product_id and move.product_id.kc_txt or ''
215 # narcotic
216- values['is_narcotic'] = move.product_id and move.product_id.narcotic or False
217+ values['is_narcotic'] = move.product_id and move.product_id.cs_txt or ''
218 # sale_order_line_number
219 values['sale_order_line_number'] = move.sale_line_id and move.sale_line_id.line_number or 0
220
221@@ -4624,9 +4597,9 @@
222 'amount': fields.function(_vals_get, method=True, type='float', string='Pack Amount', digits_compute=dp.get_precision('Picking Price'), multi='get_vals',),
223 'num_of_packs': fields.function(_vals_get, method=True, type='integer', string='#Packs', multi='get_vals_X',), # old_multi get_vals
224 'currency_id': fields.function(_vals_get, method=True, type='many2one', relation='res.currency', string='Currency', multi='get_vals',),
225- 'is_dangerous_good': fields.function(_vals_get, method=True, type='boolean', string='Dangerous Good', multi='get_vals',),
226- 'is_keep_cool': fields.function(_vals_get, method=True, type='boolean', string='Keep Cool', multi='get_vals',),
227- 'is_narcotic': fields.function(_vals_get, method=True, type='boolean', string='Narcotic', multi='get_vals',),
228+ 'is_dangerous_good': fields.function(_vals_get, method=True, type='char', size=8, string='Dangerous Good', multi='get_vals',),
229+ 'is_keep_cool': fields.function(_vals_get, method=True, type='char', size=8, string='Keep Cool', multi='get_vals',),
230+ 'is_narcotic': fields.function(_vals_get, method=True, type='char', size=8, string='CS', multi='get_vals',),
231 'sale_order_line_number': fields.function(_vals_get, method=True, type='integer', string='Sale Order Line Number', multi='get_vals_X',), # old_multi get_vals
232 # Fields used for domain
233 'location_virtual_id': fields.many2one('stock.location', string='Virtual location'),
234
235=== modified file 'bin/addons/msf_outgoing/report/empty_picking_ticket.rml'
236--- bin/addons/msf_outgoing/report/empty_picking_ticket.rml 2016-01-27 16:20:09 +0000
237+++ bin/addons/msf_outgoing/report/empty_picking_ticket.rml 2016-03-18 10:41:28 +0000
238@@ -371,13 +371,13 @@
239 <para style="LineValue">[[ m.prodlot_id and formatLang(m.prodlot_id.life_date, date=True) or '' ]]</para>
240 </td>
241 <td>
242- <para style="LineValue">[[ m.kc_check and 'X' or ' ' ]]</para>
243- </td>
244- <td>
245- <para style="LineValue">[[ m.dg_check and 'X' or ' ' ]]</para>
246- </td>
247- <td>
248- <para style="LineValue">[[ m.np_check and 'X' or ' ' ]]</para>
249+ <para style="LineValue">[[ m.product_id.kc_txt or ' ' ]]</para>
250+ </td>
251+ <td>
252+ <para style="LineValue">[[ m.product_id.dg_txt or ' ' ]]</para>
253+ </td>
254+ <td>
255+ <para style="LineValue">[[ m.product_id.cs_txt or ' ' ]]</para>
256 </td>
257 <td>
258 <para style="LineValueGrey">[[ not m.no_product and removeParentNode('para') ]]</para>
259
260=== modified file 'bin/addons/msf_outgoing/report/labels.rml'
261--- bin/addons/msf_outgoing/report/labels.rml 2014-04-10 13:15:01 +0000
262+++ bin/addons/msf_outgoing/report/labels.rml 2016-03-18 10:41:28 +0000
263@@ -147,7 +147,7 @@
264 <para style="P4">[[ stock_picking.ppl_customize_label.specific_information and translate('Specific Information:') or ' ' ]]</para>
265 </td>
266 <td>
267- <para style="P2">[[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_keep_cool and translate('KC / ') or ' ' ]][[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_dangerous_good and translate('DG / ') or ' ' ]][[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_narcotic and translate('N') or ' ' ]]</para>
268+ <para style="P2">[[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_keep_cool and translate('KC / ') or ' ' ]][[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_dangerous_good and translate('DG / ') or ' ' ]][[ stock_picking.ppl_customize_label.specific_information and stock_picking.is_narcotic and translate('CS') or ' ' ]]</para>
269 </td>
270 </tr>
271 </blockTable>
272
273=== modified file 'bin/addons/msf_outgoing/report/packing_list.rml'
274--- bin/addons/msf_outgoing/report/packing_list.rml 2015-10-26 09:46:59 +0000
275+++ bin/addons/msf_outgoing/report/packing_list.rml 2016-03-18 10:41:28 +0000
276@@ -264,13 +264,13 @@
277 <para style="ParcelLineValue">[[ formatLang(m.prodlot_id.life_date, date=True) ]]</para>
278 </td>
279 <td>
280- <para style="ParcelLineValue">[[ m.kc_check and 'X' or ' ' ]]</para>
281- </td>
282- <td>
283- <para style="ParcelLineValue">[[ m.dg_check and 'X' or ' ' ]]</para>
284- </td>
285- <td>
286- <para style="ParcelLineValue">[[ m.np_check and 'X' or ' ' ]]</para>
287+ <para style="ParcelLineValue">[[ m.product_id.kc_txt or ' ' ]]</para>
288+ </td>
289+ <td>
290+ <para style="ParcelLineValue">[[ m.product_id.dg_txt or ' ' ]]</para>
291+ </td>
292+ <td>
293+ <para style="ParcelLineValue">[[ m.product_id.cs_txt or ' ' ]]</para>
294 </td>
295 <td>
296 <para style="ParcelLineValue"></para>
297
298=== modified file 'bin/addons/msf_outgoing/report/packing_list_xls.mako'
299--- bin/addons/msf_outgoing/report/packing_list_xls.mako 2015-07-24 10:07:46 +0000
300+++ bin/addons/msf_outgoing/report/packing_list_xls.mako 2016-03-18 10:41:28 +0000
301@@ -449,9 +449,9 @@
302 % else:
303 <Cell ss:StyleID="s134"><Data ss:Type="String"></Data></Cell>
304 % endif
305- <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.kc_check and 'X' or '')|x}</Data></Cell>
306- <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.dg_check and 'X' or '')|x}</Data></Cell>
307- <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.np_check and 'X' or '')|x}</Data></Cell>
308+ <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.product_id.kc_txt or '')|x}</Data></Cell>
309+ <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.product_id.dg_txt or '')|x}</Data></Cell>
310+ <Cell ss:StyleID="s134"><Data ss:Type="String">${(m.product_id.cs_txt or '')|x}</Data></Cell>
311 </Row>
312 % endfor
313 <Row></Row>
314
315=== modified file 'bin/addons/msf_outgoing/report/picking_ticket.py'
316--- bin/addons/msf_outgoing/report/picking_ticket.py 2016-01-20 13:03:09 +0000
317+++ bin/addons/msf_outgoing/report/picking_ticket.py 2016-03-18 10:41:28 +0000
318@@ -143,9 +143,9 @@
319 bm.product_uom = m.product_uom
320 bm.product_qty = m.product_qty
321 bm.prodlot_id = m.prodlot_id
322- bm.kc_check = m.kc_check
323- bm.dg_check = m.dg_check
324- bm.np_check = m.np_check
325+ bm.kc_check = m.product_id and m.product_id.is_kc or False
326+ bm.dg_check = m.product_id and m.product_id.is_dg or False
327+ bm.np_check = m.product_id and m.product_id.is_cs or False
328 if m.prodlot_id and dict_res[m.line_number]:
329 bm.no_product = True
330 dict_res[m.line_number][0].product_qty += pool.get('product.uom')._compute_qty(
331
332=== modified file 'bin/addons/msf_outgoing/report/picking_ticket.rml'
333--- bin/addons/msf_outgoing/report/picking_ticket.rml 2016-01-14 15:39:28 +0000
334+++ bin/addons/msf_outgoing/report/picking_ticket.rml 2016-03-18 10:41:28 +0000
335@@ -399,13 +399,13 @@
336 <para style="LineValue">[[ m.prodlot_id and formatLang(m.prodlot_id.life_date, date=True) or '' ]]</para>
337 </td>
338 <td>
339- <para style="LineValue">[[ m.kc_check and 'X' or ' ' ]]</para>
340- </td>
341- <td>
342- <para style="LineValue">[[ m.dg_check and 'X' or ' ' ]]</para>
343- </td>
344- <td>
345- <para style="LineValue">[[ m.np_check and 'X' or ' ' ]]</para>
346+ <para style="LineValue">[[ m.product_id.kc_txt or ' ' ]]</para>
347+ </td>
348+ <td>
349+ <para style="LineValue">[[ m.product_id.dg_txt or ' ' ]]</para>
350+ </td>
351+ <td>
352+ <para style="LineValue">[[ m.product_id.cs_txt or ' ' ]]</para>
353 </td>
354 </tr>
355 <tr>
356
357=== modified file 'bin/addons/msf_outgoing/wizard/create_picking_processor.py'
358--- bin/addons/msf_outgoing/wizard/create_picking_processor.py 2014-07-22 12:11:45 +0000
359+++ bin/addons/msf_outgoing/wizard/create_picking_processor.py 2016-03-18 10:41:28 +0000
360@@ -235,7 +235,8 @@
361 _get_product_info,
362 method=True,
363 string='KC',
364- type='boolean',
365+ type='char',
366+ size=8,
367 store={
368 'create.picking.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
369 },
370@@ -247,7 +248,8 @@
371 _get_product_info,
372 method=True,
373 string='SSL',
374- type='boolean',
375+ type='char',
376+ size=8,
377 store={
378 'create.picking.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
379 },
380@@ -259,7 +261,8 @@
381 _get_product_info,
382 method=True,
383 string='DG',
384- type='boolean',
385+ type='char',
386+ size=8,
387 store={
388 'create.picking.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
389 },
390@@ -270,14 +273,15 @@
391 'np_check': fields.function(
392 _get_product_info,
393 method=True,
394- string='NP',
395- type='boolean',
396+ string='CS',
397+ type='char',
398+ size=8,
399 store={
400 'create.picking.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
401 },
402 readonly=True,
403 multi='product_info',
404- help="Ticked if the product is a Narcotic",
405+ help="Ticked if the product is a Controlled Substance",
406 ),
407 }
408
409
410=== modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py'
411--- bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2015-11-16 08:28:07 +0000
412+++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2016-03-18 10:41:28 +0000
413@@ -656,7 +656,8 @@
414 _get_product_info,
415 method=True,
416 string='KC',
417- type='boolean',
418+ type='char',
419+ size=8,
420 store={
421 'stock.move.in.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
422 },
423@@ -668,7 +669,8 @@
424 _get_product_info,
425 method=True,
426 string='SSL',
427- type='boolean',
428+ type='char',
429+ size=8,
430 store={
431 'stock.move.in.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
432 },
433@@ -680,7 +682,8 @@
434 _get_product_info,
435 method=True,
436 string='DG',
437- type='boolean',
438+ type='char',
439+ size=8,
440 store={
441 'stock.move.in.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
442 },
443@@ -691,14 +694,15 @@
444 'np_check': fields.function(
445 _get_product_info,
446 method=True,
447- string='NP',
448- type='boolean',
449+ string='CS',
450+ type='char',
451+ size=8,
452 store={
453 'stock.move.in.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
454 },
455 readonly=True,
456 multi='product_info',
457- help="Ticked if the product is a Narcotic",
458+ help="Ticked if the product is a Controlled Substance",
459 ),
460 }
461
462
463=== modified file 'bin/addons/msf_outgoing/wizard/internal_move_processor.py'
464--- bin/addons/msf_outgoing/wizard/internal_move_processor.py 2014-09-19 12:34:58 +0000
465+++ bin/addons/msf_outgoing/wizard/internal_move_processor.py 2016-03-18 10:41:28 +0000
466@@ -534,7 +534,8 @@
467 _get_product_info,
468 method=True,
469 string='KC',
470- type='boolean',
471+ type='char',
472+ size=8,
473 store={
474 'internal.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
475 },
476@@ -546,7 +547,8 @@
477 _get_product_info,
478 method=True,
479 string='SSL',
480- type='boolean',
481+ type='char',
482+ size=8,
483 store={
484 'internal.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
485 },
486@@ -558,7 +560,8 @@
487 _get_product_info,
488 method=True,
489 string='DG',
490- type='boolean',
491+ type='char',
492+ size=8,
493 store={
494 'internal.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
495 },
496@@ -569,14 +572,15 @@
497 'np_check': fields.function(
498 _get_product_info,
499 method=True,
500- string='NP',
501- type='boolean',
502+ sstring='CS',
503+ type='char',
504+ size=8,
505 store={
506 'internal.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
507 },
508 readonly=True,
509 multi='product_info',
510- help="Ticked if the product is a Narcotic",
511+ help="Ticked if the product is a Controlled Substance",
512 ),
513 }
514
515
516=== modified file 'bin/addons/msf_outgoing/wizard/outgoing_delivery_processor.py'
517--- bin/addons/msf_outgoing/wizard/outgoing_delivery_processor.py 2014-03-05 10:32:45 +0000
518+++ bin/addons/msf_outgoing/wizard/outgoing_delivery_processor.py 2016-03-18 10:41:28 +0000
519@@ -322,7 +322,8 @@
520 _get_product_info,
521 method=True,
522 string='KC',
523- type='boolean',
524+ type='char',
525+ size=8,
526 store={
527 'outgoing.delivery.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
528 },
529@@ -334,7 +335,8 @@
530 _get_product_info,
531 method=True,
532 string='SSL',
533- type='boolean',
534+ type='char',
535+ size=8,
536 store={
537 'outgoing.delivery.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
538 },
539@@ -346,7 +348,8 @@
540 _get_product_info,
541 method=True,
542 string='DG',
543- type='boolean',
544+ type='char',
545+ size=8,
546 store={
547 'outgoing.delivery.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
548 },
549@@ -357,14 +360,15 @@
550 'np_check': fields.function(
551 _get_product_info,
552 method=True,
553- string='NP',
554- type='boolean',
555+ string='CS',
556+ type='char',
557+ size=8,
558 store={
559 'outgoing.delivery.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
560 },
561 readonly=True,
562 multi='product_info',
563- help="Ticked if the product is a Narcotic",
564+ help="Ticked if the product is a Controlled Substance",
565 ),
566 }
567
568
569=== modified file 'bin/addons/msf_outgoing/wizard/picking_processor.py'
570--- bin/addons/msf_outgoing/wizard/picking_processor.py 2016-03-02 15:57:47 +0000
571+++ bin/addons/msf_outgoing/wizard/picking_processor.py 2016-03-18 10:41:28 +0000
572@@ -58,11 +58,17 @@
573 'contains_dg': False,
574 }
575 # KC
576- kc_lines = line_obj.search(cr, uid, [('wizard_id', '=', wizard_id), ('kc_check', '=', True)], context=context)
577+ kc_lines = line_obj.search(cr, uid, [
578+ ('wizard_id', '=', wizard_id),
579+ ('kc_check', '!=', ''),
580+ ], limit=1, order='NO_ORDER', context=context)
581 if kc_lines:
582 res[wizard_id]['contains_kc'] = True
583 # DG
584- dg_lines = line_obj.search(cr, uid, [('wizard_id', '=', wizard_id), ('dg_check', '=', True)], context=context)
585+ dg_lines = line_obj.search(cr, uid, [
586+ ('wizard_id', '=', wizard_id),
587+ ('dg_check', '!=', ''),
588+ ], limit=1, order='NO_ORDER', context=context)
589 if dg_lines:
590 res[wizard_id]['contains_dg'] = True
591
592@@ -284,10 +290,10 @@
593 'exp_check': False,
594 'asset_check': False,
595 'kit_check': False,
596- 'kc_check': False,
597- 'ssl_check': False,
598- 'dg_check': False,
599- 'np_check': False,
600+ 'kc_check': '',
601+ 'ssl_check': '',
602+ 'dg_check': '',
603+ 'np_check': '',
604 }
605
606 if line.product_id:
607@@ -296,10 +302,10 @@
608 'exp_check': line.product_id.perishable,
609 'asset_check': line.product_id.type == 'product' and line.product_id.subtype == 'asset',
610 'kit_check': line.product_id.type == 'product' and line.product_id.subtype == 'kit' and not line.product_id.perishable,
611- 'kc_check': line.product_id.heat_sensitive_item and True or False,
612- 'ssl_check': line.product_id.short_shelf_life,
613- 'dg_check': line.product_id.dangerous_goods,
614- 'np_check': line.product_id.narcotic,
615+ 'kc_check': line.product_id.kc_txt,
616+ 'ssl_check': line.product_id.ssl_txt,
617+ 'dg_check': line.product_id.dg_txt,
618+ 'np_check': line.product_id.cs_txt,
619 }
620
621 return res
622@@ -576,7 +582,8 @@
623 _get_product_info,
624 method=True,
625 string='KC',
626- type='boolean',
627+ type='char',
628+ size=8,
629 store={
630 'stock.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
631 },
632@@ -588,7 +595,8 @@
633 _get_product_info,
634 method=True,
635 string='SSL',
636- type='boolean',
637+ type='char',
638+ size=8,
639 store={
640 'stock.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
641 },
642@@ -600,7 +608,8 @@
643 _get_product_info,
644 method=True,
645 string='DG',
646- type='boolean',
647+ type='char',
648+ size=8,
649 store={
650 'stock.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
651 },
652@@ -611,14 +620,15 @@
653 'np_check': fields.function(
654 _get_product_info,
655 method=True,
656- string='NP',
657- type='boolean',
658+ string='CS',
659+ type='char',
660+ size=8,
661 store={
662 'stock.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
663 },
664 readonly=True,
665 multi='product_info',
666- help="Ticked if the product is a Narcotic",
667+ help="Ticked if the product is a Controlled Substance",
668 ),
669 'prodlot_id': fields.many2one(
670 'stock.production.lot',
671
672=== modified file 'bin/addons/msf_outgoing/wizard/ppl_processor.py'
673--- bin/addons/msf_outgoing/wizard/ppl_processor.py 2015-08-27 08:44:05 +0000
674+++ bin/addons/msf_outgoing/wizard/ppl_processor.py 2016-03-18 10:41:28 +0000
675@@ -554,7 +554,8 @@
676 _get_product_info,
677 method=True,
678 string='KC',
679- type='boolean',
680+ type='char',
681+ size=8,
682 store={
683 'ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
684 },
685@@ -566,7 +567,8 @@
686 _get_product_info,
687 method=True,
688 string='SSL',
689- type='boolean',
690+ type='char',
691+ size=8,
692 store={
693 'ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
694 },
695@@ -578,7 +580,8 @@
696 _get_product_info,
697 method=True,
698 string='DG',
699- type='boolean',
700+ type='char',
701+ size=8,
702 store={
703 'ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
704 },
705@@ -589,14 +592,15 @@
706 'np_check': fields.function(
707 _get_product_info,
708 method=True,
709- string='NP',
710- type='boolean',
711+ string='CS',
712+ type='char',
713+ size=8,
714 store={
715 'ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
716 },
717 readonly=True,
718 multi='product_info',
719- help="Ticked if the product is a Narcotic",
720+ help="Ticked if the product is a Controlled Substance",
721 ),
722 }
723
724
725=== modified file 'bin/addons/msf_outgoing/wizard/return_ppl_processor.py'
726--- bin/addons/msf_outgoing/wizard/return_ppl_processor.py 2014-03-05 16:51:14 +0000
727+++ bin/addons/msf_outgoing/wizard/return_ppl_processor.py 2016-03-18 10:41:28 +0000
728@@ -258,7 +258,8 @@
729 _get_product_info,
730 method=True,
731 string='KC',
732- type='boolean',
733+ type='char',
734+ size=8,
735 store={
736 'return.ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
737 },
738@@ -270,7 +271,8 @@
739 _get_product_info,
740 method=True,
741 string='SSL',
742- type='boolean',
743+ type='char',
744+ size=8,
745 store={
746 'return.ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
747 },
748@@ -282,7 +284,8 @@
749 _get_product_info,
750 method=True,
751 string='DG',
752- type='boolean',
753+ type='char',
754+ size=8,
755 store={
756 'return.ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
757 },
758@@ -293,14 +296,15 @@
759 'np_check': fields.function(
760 _get_product_info,
761 method=True,
762- string='NP',
763- type='boolean',
764+ string='CS',
765+ type='char',
766+ size=8,
767 store={
768 'return.ppl.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
769 },
770 readonly=True,
771 multi='product_info',
772- help="Ticked if the product is a Narcotic",
773+ help="Ticked if the product is a Controlled Substance",
774 ),
775 }
776
777
778=== modified file 'bin/addons/msf_outgoing/wizard/validate_picking_processor.py'
779--- bin/addons/msf_outgoing/wizard/validate_picking_processor.py 2014-03-05 16:51:14 +0000
780+++ bin/addons/msf_outgoing/wizard/validate_picking_processor.py 2016-03-18 10:41:28 +0000
781@@ -329,7 +329,8 @@
782 _get_product_info,
783 method=True,
784 string='KC',
785- type='boolean',
786+ type='char',
787+ size=8,
788 store={
789 'validate.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
790 },
791@@ -341,7 +342,8 @@
792 _get_product_info,
793 method=True,
794 string='SSL',
795- type='boolean',
796+ type='char',
797+ size=8,
798 store={
799 'validate.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
800 },
801@@ -353,7 +355,8 @@
802 _get_product_info,
803 method=True,
804 string='DG',
805- type='boolean',
806+ type='char',
807+ size=8,
808 store={
809 'validate.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
810 },
811@@ -364,14 +367,15 @@
812 'np_check': fields.function(
813 _get_product_info,
814 method=True,
815- string='NP',
816- type='boolean',
817+ string='CS',
818+ type='char',
819+ size=8,
820 store={
821 'validate.move.processor': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 20),
822 },
823 readonly=True,
824 multi='product_info',
825- help="Ticked if the product is a Narcotic",
826+ help="Ticked if the product is a Controlled Substance",
827 ),
828 }
829
830
831=== modified file 'bin/addons/msf_printed_documents/report/freight_manifest.py'
832--- bin/addons/msf_printed_documents/report/freight_manifest.py 2015-10-26 09:42:39 +0000
833+++ bin/addons/msf_printed_documents/report/freight_manifest.py 2016-03-18 10:41:28 +0000
834@@ -95,11 +95,11 @@
835 np = ""
836 for x in line.move_lines:
837 if x.kc_check:
838- kc = 'X'
839+ kc = x.kc_check
840 if x.dg_check:
841- dg = 'X'
842+ dg = x.dg_check
843 if x.np_check:
844- np = 'X'
845+ np = x.np_check
846
847 if line_ref not in line_obj:
848 line_obj[line_ref] = {}
849
850=== modified file 'bin/addons/msf_printed_documents/report/report_reception.py'
851--- bin/addons/msf_printed_documents/report/report_reception.py 2015-05-22 08:34:02 +0000
852+++ bin/addons/msf_printed_documents/report/report_reception.py 2016-03-18 10:41:28 +0000
853@@ -180,8 +180,10 @@
854 'ed': 'exp_check',
855 }
856
857- if opt in options and hasattr(line, options[opt]) and getattr(line, options[opt]) == True:
858+ if opt in options and hasattr(line, options[opt]) and getattr(line, options[opt]) is True:
859 return 'X'
860+ elif opt in options and hasattr(line, options[opt]):
861+ return getattr(line, options[opt])
862
863 return ' '
864
865
866=== modified file 'bin/addons/msf_profile/data/patches.xml'
867--- bin/addons/msf_profile/data/patches.xml 2016-03-11 15:55:20 +0000
868+++ bin/addons/msf_profile/data/patches.xml 2016-03-18 10:41:28 +0000
869@@ -5,8 +5,55 @@
870 <field name="method">update_us_963_negative_rule_seq</field>
871 </record>
872
873+<<<<<<< TREE
874 <record id="another_translation_fix" model="patch.scripts">
875 <field name="method">another_translation_fix</field>
876+=======
877+ <record id="us_133_patch" model="patch.scripts">
878+ <field name="method">update_us_133</field>
879+ </record>
880+ <record id="us_489_patch" model="patch.scripts">
881+ <field name="method">update_parent_budget_us_489</field>
882+ </record>
883+ <record id="us_435_patch_2" model="patch.scripts">
884+ <field name="method">update_us_435_2</field>
885+ </record>
886+
887+ <record id="us_394_2_patch" model="patch.scripts">
888+ <field name="method">us_394_2_patch</field>
889+ </record>
890+
891+ <record id="us_394_3_patch" model="patch.scripts">
892+ <field name="method">us_394_3_patch</field>
893+ </record>
894+
895+ <record id="us_651_patch" model="patch.scripts">
896+ <field name="method">disable_crondoall</field>
897+ </record>
898+
899+ <record id="us_332_patch" model="patch.scripts">
900+ <field name="method">us_332_patch</field>
901+ </record>
902+
903+ <record id="us_898_patch" model="patch.scripts">
904+ <field name="method">us_898_patch</field>
905+ </record>
906+
907+ <record id="us_822_patch" model="patch.scripts">
908+ <field name="method">us_822_patch</field>
909+ </record>
910+
911+ <record id="us_908_patch" model="patch.scripts">
912+ <field name="method">us_908_patch</field>
913+ </record>
914+
915+ <record id="us_750_patch" model="patch.scripts">
916+ <field name="method">us_750_patch</field>
917+ </record>
918+
919+ <record id="bar_action_patch" model="patch.scripts">
920+ <field name="method">bar_action_patch</field>
921+>>>>>>> MERGE-SOURCE
922 </record>
923
924 </data>
925
926=== modified file 'bin/addons/msf_profile/msf_profile.py'
927--- bin/addons/msf_profile/msf_profile.py 2016-03-11 15:55:20 +0000
928+++ bin/addons/msf_profile/msf_profile.py 2016-03-18 10:41:28 +0000
929@@ -305,6 +305,30 @@
930 for view in view_to_gen:
931 view_obj.generate_button_access_rules(cr, uid, view)
932
933+ def us_750_patch(self, cr, uid, *a, **b):
934+ """
935+ Update the heat_sensitive_item field of product.product
936+ to 'Yes' if there is a value already defined by de-activated.
937+ :param cr: Cursor to the database
938+ :param uid: ID of the res.users that calls this method
939+ :param a: Non-named parameters
940+ :param b: Named parameters
941+ :return: True
942+ """
943+ prd_obj = self.pool.get('product.product')
944+ phs_obj = self.pool.get('product.heat_sensitive')
945+ data_obj = self.pool.get('ir.model.data')
946+
947+ heat_id = data_obj.get_object_reference(cr, uid, 'product_attributes', 'heat_yes')[1]
948+
949+ phs_ids = phs_obj.search(cr, uid, [('active', '=', False)])
950+ prd_ids = prd_obj.search(cr, uid, [('heat_sensitive_item', 'in', phs_ids)])
951+ if prd_ids:
952+ prd_obj.write(cr, uid, prd_ids, {
953+ 'heat_sensitive_item': heat_id,
954+ })
955+
956+ return True
957
958 def update_us_963_negative_rule_seq(self, cr, uid, *a, **b):
959 if self.pool.get('sync.client.update_received'):
960
961=== modified file 'bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv'
962--- bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2016-01-25 14:13:18 +0000
963+++ bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2016-03-18 10:41:28 +0000
964@@ -107,8 +107,8 @@
965 msf_sync_data_server.price_list_version,FALSE,TRUE,FALSE,FALSE,bidirectional,Bidirectional,[],"['active', 'date_end', 'date_start', 'name', 'pricelist_id/id']",MISSION,product.pricelist.version,,Price List Version,Valid,,561
966 msf_sync_data_server.country_restrictions,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,[],['name'],MISSION,res.country.restriction,,Country restrictions,Valid,,570
967 msf_sync_data_server.country_code_mapping,TRUE,TRUE,TRUE,TRUE,bidirectional,Down,[],"['instance_id/id', 'mapping_value']",COORDINATIONS,country.export.mapping,,Country Code Mapping,Valid,,571
968-msf_sync_data_server.oc_product_creator_itc_esc_hq,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"['|','|',('international_status','=','ITC'),('international_status','=','ESC'),('international_status','=','HQ')]","['alert_time', 'batch_management', 'categ_id/id', 'closed_article', 'code', 'cold_chain', 'composed_kit', 'xmlid_code', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'narcotic', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'asset_type_id', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume', 'soq_weight', 'soq_volume']",OC,product.product,,"OC Product (Creator = ITC, ESC or HQ)",Valid,,600
969-msf_sync_data_server.mission_product_creator_local,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"[('international_status','=','Local')]","['alert_time', 'batch_management', 'categ_id/id', 'closed_article', 'code', 'xmlid_code','cold_chain', 'composed_kit', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'narcotic', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'asset_type_id', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume','soq_weight','soq_volume']",MISSION,product.product,,Mission Product (Creator = local),Valid,,601
970+msf_sync_data_server.oc_product_creator_itc_esc_hq,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"['|','|',('international_status','=','ITC'),('international_status','=','ESC'),('international_status','=','HQ')]","['alert_time', 'batch_management', 'categ_id/id', 'closed_article', 'code', 'cold_chain', 'composed_kit', 'xmlid_code', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'controlled_substance', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'asset_type_id', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume', 'soq_weight', 'soq_volume']",OC,product.product,,"OC Product (Creator = ITC, ESC or HQ)",Valid,,600
971+msf_sync_data_server.mission_product_creator_local,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"[('international_status','=','Local')]","['alert_time', 'batch_management', 'categ_id/id', 'closed_article', 'code', 'xmlid_code','cold_chain', 'composed_kit', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'controlled_substance', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'asset_type_id', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume','soq_weight','soq_volume']",MISSION,product.product,,Mission Product (Creator = local),Valid,,601
972 msf_sync_data_server.standard_product_list,TRUE,TRUE,TRUE,TRUE,bidirectional,Down,"[('standard_list_ok','=','True')]","['creation_date', 'creator', 'description', 'last_update_date', 'name', 'order_list_print_ok', 'ref', 'standard_list_ok', 'type']",OC,product.list,,Standard Product List,Valid,,605
973 msf_sync_data_server.standard_product_list_line,TRUE,TRUE,TRUE,TRUE,bidirectional,Down,"[('list_id' , 'in', ('product.list', 'id', [('standard_list_ok','=','True')]))]","['comment','list_id/id','ref','name']",OC,product.list.line,,Standard Product List Line,Valid,,606
974 msf_sync_data_server.tax_code,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,[],"['code', 'info', 'name', 'notprintable', 'sign']",OC,account.tax.code,,Tax Code,Valid,,610
975@@ -199,7 +199,7 @@
976 msf_usb_sync_data_server.cp_all_partners_address,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,[],"['active', 'city', 'country_id/id', 'email', 'fax', 'function', 'mobile', 'name', 'partner_id/id', 'phone', 'state_id/id', 'street', 'street2', 'title/id', 'type', 'zip']",USB,res.partner.address,,[MASTER] Partner Address,Valid,,1662
977 msf_usb_sync_data_server.cp_product_price_list,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,[],"['active', 'company_id/id', 'currency_id/id', 'currency_name', 'name', 'type']",USB,product.pricelist,,[MASTER] Product_price_list,Valid,,1670
978 msf_usb_sync_data_server.cp_country_restrictions,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,[],['name'],USB,res.country.restriction,,[MASTER] Country restrictions,Valid,,1680
979-msf_usb_sync_data_server.cp_all_product,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,[],"['alert_time', 'batch_management', 'asset_type_id', 'categ_id/id', 'closed_article', 'code', 'cold_chain', 'composed_kit', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'narcotic', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'xmlid_code', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume','soq_weight','soq_volume']",USB,product.product,,[MASTER] Products,Valid,,1810
980+msf_usb_sync_data_server.cp_all_product,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,[],"['alert_time', 'batch_management', 'asset_type_id', 'categ_id/id', 'closed_article', 'code', 'cold_chain', 'composed_kit', 'cost_method', 'country_restriction/id', 'dangerous_goods', 'default_code', 'description', 'description2', 'description_purchase', 'description_sale', 'gmdn_code', 'gmdn_description', 'heat_sensitive_item', 'international_status', 'justification_code_id/id', 'library', 'life_time', 'list_ids/id','med_device_class', 'name', 'name_template', 'controlled_substance', 'nomen_manda_0/id', 'nomen_manda_1/id', 'nomen_manda_2/id', 'nomen_manda_3/id', 'options_ids/id', 'perishable', 'procure_delay', 'procure_method', 'produce_delay', 'product_catalog_page', 'product_catalog_path', 'property_account_expense/id', 'property_account_income/id', 'property_stock_account_input/id', 'property_stock_account_output/id', 'restricted_country', 'short_shelf_life', 'single_use', 'sterilized', 'standard_price', 'sublist', 'subtype', 'supply_method', 'type', 'un_code', 'uom_id/id', 'uom_po_id/id','use_time', 'valuation', 'weight', 'weight_net', 'xmlid_code', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume','soq_weight','soq_volume']",USB,product.product,,[MASTER] Products,Valid,,1810
981 msf_usb_sync_data_server.cp_standard_product_list,TRUE,TRUE,TRUE,TRUE,cp_to_rw,Bidirectional,"[('standard_list_ok','=','True')]","['creation_date', 'creator', 'description', 'last_update_date', 'name', 'order_list_print_ok', 'ref', 'standard_list_ok', 'type']",USB,product.list,,[MASTER] Standard Product List,Valid,,1820
982 msf_usb_sync_data_server.cp_standard_product_list_line,TRUE,TRUE,TRUE,TRUE,cp_to_rw,Bidirectional,"[('list_id' , 'in', ('product.list', 'id', [('standard_list_ok','=','True')]))]","['comment','list_id/id','ref','name/id']",USB,product.list.line,,[MASTER] Standard Product List Line,Valid,,1821
983 msf_usb_sync_data_server.cp_composition_kit,TRUE,TRUE,FALSE,TRUE,cp_to_rw,Bidirectional,"[('state','=','completed'),('composition_type','=','theoretical')]","['active', 'composition_creation_date', 'composition_description', 'composition_product_id/id', 'composition_type', 'composition_version', 'composition_version_txt', 'name', 'state']",USB,composition.kit,,[MASTER] Theoretical Kit Composition List,Valid,,1830
984
985=== modified file 'bin/addons/product_attributes/product_attributes.py'
986--- bin/addons/product_attributes/product_attributes.py 2016-01-25 10:53:51 +0000
987+++ bin/addons/product_attributes/product_attributes.py 2016-03-18 10:41:28 +0000
988@@ -103,9 +103,24 @@
989
990 class product_heat_sensitive(osv.osv):
991 _name = "product.heat_sensitive"
992+ _order = 'code desc'
993 _columns = {
994- 'code': fields.char('Code', size=256),
995- 'name': fields.char('Name', size=256, required=True),
996+ 'code': fields.char(
997+ string='Code',
998+ size=256,
999+ ),
1000+ 'name': fields.char(
1001+ string='Name',
1002+ size=256,
1003+ required=True,
1004+ ),
1005+ 'active': fields.boolean(
1006+ string='Active',
1007+ )
1008+ }
1009+
1010+ _defaults = {
1011+ 'active': True,
1012 }
1013
1014 def unlink(self, cr, uid, ids, context=None):
1015@@ -113,11 +128,14 @@
1016 context = {}
1017 if isinstance(ids, (int, long)):
1018 ids = [ids]
1019- ids_p = self.pool.get('product.product').search(cr, uid,
1020- [('heat_sensitive_item','in',ids)],
1021- limit=1, order='NO_ORDER')
1022+ ids_p = self.pool.get('product.product').search(cr, uid, [
1023+ ('heat_sensitive_item', 'in', ids),
1024+ ], limit=1, order='NO_ORDER')
1025 if ids_p:
1026- raise osv.except_osv(_('Error'), _('You cannot delete this heat sensitive because it\'s used at least in one product'))
1027+ raise osv.except_osv(
1028+ _('Error'),
1029+ _('You cannot delete this heat sensitive because it\'s used at least in one product'),
1030+ )
1031 return super(product_heat_sensitive, self).unlink(cr, uid, ids, context=context)
1032
1033 product_heat_sensitive()
1034@@ -206,6 +224,7 @@
1035
1036 product_template()
1037
1038+
1039 class product_attributes(osv.osv):
1040 _inherit = "product.product"
1041
1042@@ -219,6 +238,26 @@
1043 file = tools.file_open(pathname)
1044 tools.convert_xml_import(cr, 'product_attributes', file, {}, mode=mode, noupdate=True)
1045
1046+ def execute_migration(self, cr, moved_column, new_column):
1047+ super(product_attributes, self).execute_migration(cr, moved_column, new_column)
1048+ if new_column == 'dangerous_goods':
1049+ request = 'UPDATE product_product SET dangerous_goods = \'True\' WHERE %s = True' % moved_column
1050+ cr.execute(request)
1051+
1052+ if new_column == 'short_shelf_life':
1053+ request = 'UPDATE product_product SET short_shelf_life = \'True\' WHERE %s = True' % moved_column
1054+ cr.execute(request)
1055+
1056+ if new_column == 'controlled_substance':
1057+ # Update old ticked controlled substance but not narcotic
1058+ request = '''UPDATE product_product SET
1059+ controlled_substance = 'True',
1060+ is_cs = True,
1061+ cs_txt = 'X'
1062+ WHERE %s = True OR narcotic = True''' % moved_column
1063+
1064+ return
1065+
1066 def _get_nomen(self, cr, uid, ids, field_name, args, context=None):
1067 res = {}
1068
1069@@ -352,6 +391,140 @@
1070
1071 return []
1072
1073+ def _compute_is_kc(self, cr, uid, product, context=None):
1074+ """
1075+ Return True if the product is considered as a Keep Cool product
1076+ :param cr: Cursor to the database
1077+ :param uid: ID of the res.users that calls this method
1078+ :param product: browse_record of a product.product
1079+ :param context: Context of the call
1080+ :return: True or False
1081+ """
1082+ return product.heat_sensitive_item.code == 'yes'
1083+
1084+ def _compute_kc_txt(self, cr, uid, product, context=None):
1085+ """
1086+ Return the character to display on views or reports ('X' or '?' or '') for Keep Cool
1087+ :param cr: Cursor to the database
1088+ :param uid: ID of the res.users that calls this method
1089+ :param product: browse_record of a product.product
1090+ :param context: Context of the call
1091+ :return: 'X' or '?' or ''
1092+ """
1093+ if product.heat_sensitive_item.code == 'no_know':
1094+ return '?'
1095+ elif product.heat_sensitive_item.code == 'no':
1096+ return ''
1097+ else:
1098+ return 'X'
1099+
1100+ def _compute_is_dg(self, cr, uid, product, context=None):
1101+ """
1102+ Return True if the product is considered as a Dangerous Goods product
1103+ :param cr: Cursor to the database
1104+ :param uid: ID of the res.users that calls this method
1105+ :param product: browse_record of a product.product
1106+ :param context: Context of the call
1107+ :return: True or False
1108+ """
1109+ return product.dangerous_goods == 'True'
1110+
1111+ def _compute_dg_txt(self, cr, uid, product, context=None):
1112+ """
1113+ Return the character to display on views or reports ('X' or '?' or '') for Dangerous Goods
1114+ :param cr: Cursor to the database
1115+ :param uid: ID of the res.users that calls this method
1116+ :param product: browse_record of a product.product
1117+ :param context: Context of the call
1118+ :return: 'X' or '?' or ''
1119+ """
1120+ if product.dangerous_goods == 'True':
1121+ return 'X'
1122+ elif product.dangerous_goods == 'no_know':
1123+ return '?'
1124+
1125+ return ''
1126+
1127+ def _compute_is_cs(self, cr, uid, product, context=None):
1128+ """
1129+ Return True if the product is considered as a Controlled Substance product
1130+ :param cr: Cursor to the database
1131+ :param uid: ID of the res.users that calls this method
1132+ :param product: browse_record of a product.product
1133+ :param context: Context of the call
1134+ :return: True or False
1135+ """
1136+ return product.controlled_substance
1137+
1138+ def _compute_cs_txt(self, cr, uid, product, context=None):
1139+ """
1140+ Return the character to display on views or reports ('X' or '?' or '') for Controlled Substance
1141+ :param cr: Cursor to the database
1142+ :param uid: ID of the res.users that calls this method
1143+ :param product: browse_record of a product.product
1144+ :param context: Context of the call
1145+ :return: 'X' or '?' or ''
1146+ """
1147+ return product.controlled_substance and 'X' or ''
1148+
1149+ def _compute_is_ssl(self, cr, uid, product, context=None):
1150+ """
1151+ Return True if the product is considered as a Short Shelf Life product
1152+ :param cr: Cursor to the database
1153+ :param uid: ID of the res.users that calls this method
1154+ :param product: browse_record of a product.product
1155+ :param context: Context of the call
1156+ :return: True or False
1157+ """
1158+ return product.short_shelf_life == 'True'
1159+
1160+ def _compute_ssl_txt(self, cr, uid, product, context=None):
1161+ """
1162+ Return the character to display on views or reports ('X' or '?' or '') for Short Shelf Life
1163+ :param cr: Cursor to the database
1164+ :param uid: ID of the res.users that calls this method
1165+ :param product: browse_record of a product.product
1166+ :param context: Context of the call
1167+ :return: 'X' or '?' or ''
1168+ """
1169+ if product.short_shelf_life == 'True':
1170+ return 'X'
1171+ elif product.short_shelf_life == 'no_know':
1172+ return '?'
1173+
1174+ return ''
1175+
1176+ def _compute_kc_dg_cs_ssl_values(self, cr, uid, ids, field_names, args, context=None):
1177+ """
1178+ Compute the character to display ('X' or '?' or '') according to product values
1179+ for Keep Cool, Dangerous Goods, Controlled Substance and Short Shelf Life.
1180+ :param cr: Cursor to the database
1181+ :param uid: ID of the res.users that calls this method
1182+ :param ids: List of ID of product.product to compute values
1183+ :param field_names: Name of the fields to compute
1184+ :param args: Additionnal arguments
1185+ :param context: Conetxt of the call
1186+ :return: A dictionary with the ID of product.product as keys and
1187+ a dictionary with computed field values for each ID in ids.
1188+ """
1189+ if context is None:
1190+ context = {}
1191+
1192+ if isinstance(ids, (int, long)):
1193+ ids = [ids]
1194+
1195+ if not isinstance(field_names, list):
1196+ field_names = [field_names]
1197+
1198+ res = {}
1199+ for product in self.browse(cr, uid, ids, context=context):
1200+ res[product.id] = {}
1201+ for fld in field_names:
1202+ method_name = '_compute_%s' % fld
1203+ res[product.id][fld] = getattr(self, method_name)(cr, uid, product, context=context)
1204+
1205+ return res
1206+
1207 _columns = {
1208 'duplicate_ok': fields.boolean('Is a duplicate'),
1209 'loc_indic': fields.char('Indicative Location', size=64),
1210@@ -364,7 +537,38 @@
1211 'batch_management': fields.boolean('Batch Number Mandatory'),
1212 'product_catalog_page' : fields.char('Product Catalog Page', size=64),
1213 'product_catalog_path' : fields.char('Product Catalog Path', size=64),
1214- 'short_shelf_life': fields.boolean('Short Shelf Life'),
1215+ 'short_shelf_life': fields.selection(
1216+ selection=[
1217+ ('False', 'No'),
1218+ ('True', 'Yes'),
1219+ ('no_know', 'Don\'t know'),
1220+ ],
1221+ string='Short Shelf Life',
1222+ required=True,
1223+ ),
1224+ 'is_ssl': fields.function(
1225+ _compute_kc_dg_cs_ssl_values,
1226+ method=True,
1227+ type='boolean',
1228+ string='Is Short Shelf Life ?',
1229+ multi='ssl',
1230+ readonly=True,
1231+ store={
1232+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['short_shelf_life'], 10),
1233+ }
1234+ ),
1235+ 'ssl_txt': fields.function(
1236+ _compute_kc_dg_cs_ssl_values,
1237+ method=True,
1238+ type='char',
1239+ size=8,
1240+ string='Short Shelf Life icon',
1241+ multi='ssl',
1242+ readonly=True,
1243+ store={
1244+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['short_shelf_life'], 10),
1245+ }
1246+ ),
1247 'criticism': fields.selection([('',''),
1248 ('exceptional','1-Exceptional'),
1249 ('specific','2-Specific'),
1250@@ -390,7 +594,34 @@
1251 'composed_kit': fields.boolean('Kit Composed of Kits/Modules'),
1252 'options_ids': fields.many2many('product.product','product_options_rel','product_id','product_option_id','Options'),
1253
1254- 'heat_sensitive_item': fields.many2one('product.heat_sensitive', 'Temperature sensitive item',),
1255+ 'heat_sensitive_item': fields.many2one(
1256+ 'product.heat_sensitive',
1257+ string='Temperature sensitive item',
1258+ required=True,
1259+ ),
1260+ 'is_kc': fields.function(
1261+ _compute_kc_dg_cs_ssl_values,
1262+ method=True,
1263+ type='boolean',
1264+ string='Is Keep Cool ?',
1265+ multi='kc',
1266+ readonly=True,
1267+ store={
1268+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['heat_sensitive_item'], 10),
1269+ }
1270+ ),
1271+ 'kc_txt': fields.function(
1272+ _compute_kc_dg_cs_ssl_values,
1273+ method=True,
1274+ type='char',
1275+ size=8,
1276+ string='Keep Cool icon',
1277+ multi='kc',
1278+ readonly=True,
1279+ store={
1280+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['heat_sensitive_item'], 10),
1281+ }
1282+ ),
1283 'cold_chain': fields.many2one('product.cold_chain', 'Cold Chain',),
1284 'show_cold_chain': fields.boolean('Show cold chain'),
1285 # Inverse of m2m options_ids
1286@@ -403,7 +634,38 @@
1287 ('II','Class II (General control with special controls)'),
1288 ('III','Class III (General controls and premarket)')], 'Medical Device Class'),
1289 'closed_article': fields.selection([('yes', 'Yes'), ('no', 'No'),],string='Closed Article'),
1290- 'dangerous_goods': fields.boolean('Dangerous Goods'),
1291+ 'dangerous_goods': fields.selection(
1292+ selection=[
1293+ ('False', 'No'), # False is put as key for migration (see US-752)
1294+ ('True', 'Yes'), # True is put as key for migration (see US-752)
1295+ ('no_know', 'Don\'t know'),
1296+ ],
1297+ string='Dangerous goods',
1298+ required=True,
1299+ ),
1300+ 'is_dg': fields.function(
1301+ _compute_kc_dg_cs_ssl_values,
1302+ method=True,
1303+ type='boolean',
1304+ string='Is a Dangerous Goods ?',
1305+ multi='dg',
1306+ readonly=True,
1307+ store={
1308+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['dangerous_goods'], 10),
1309+ }
1310+ ),
1311+ 'dg_txt': fields.function(
1312+ _compute_kc_dg_cs_ssl_values,
1313+ method=True,
1314+ type='char',
1315+ size=8,
1316+ string='Dangerous Goods icon',
1317+ multi='dg',
1318+ readonly=True,
1319+ store={
1320+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['dangerous_goods'], 10),
1321+ }
1322+ ),
1323 'restricted_country': fields.boolean('Restricted in the Country'),
1324 'country_restriction': fields.many2one('res.country.restriction', 'Country Restriction'),
1325 # TODO: validation on 'un_code' field
1326@@ -421,7 +683,42 @@
1327 'field_currency_id': fields.many2one('res.currency', string='Currency', readonly=True),
1328 'nomen_ids': fields.function(_get_nomen, fnct_search=_search_nomen,
1329 type='many2many', relation='product.nomenclature', method=True, string='Nomenclatures'),
1330- 'controlled_substance': fields.boolean(string='Controlled substance'),
1331+ 'controlled_substance': fields.selection(
1332+ selection=[
1333+ ('!', '! - Requires national export license'),
1334+ ('N1', 'N1 - Narcotic 1'),
1335+ ('N2', 'N2 - Narcotic 2'),
1336+ ('P1', 'P1 - Psychotrop 1'),
1337+ ('P3', 'P3 - Psychotrop 3'),
1338+ ('P4', 'P4 - Psychotrop 4'),
1339+ ('Y', 'Y - Kit or module with controlled substance'),
1340+ ('True', 'CS / NP - Controlled Substance / Narcotic / Psychotropic')
1341+ ],
1342+ string='Controlled substance',
1343+ ),
1344+ 'is_cs': fields.function(
1345+ _compute_kc_dg_cs_ssl_values,
1346+ method=True,
1347+ type='boolean',
1348+ string='Is Controlled subst.',
1349+ multi='cs',
1350+ readonly=True,
1351+ store={
1352+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['controlled_substance'], 10),
1353+ }
1354+ ),
1355+ 'cs_txt': fields.function(
1356+ _compute_kc_dg_cs_ssl_values,
1357+ method=True,
1358+ type='char',
1359+ size=8,
1360+ string='Controlled subst. icon',
1361+ multi='cs',
1362+ readonly=True,
1363+ store={
1364+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['controlled_substance'], 10),
1365+ }
1366+ ),
1367 'uom_category_id': fields.related('uom_id', 'category_id', string='Uom Category', type='many2one', relation='product.uom.categ'),
1368 'no_external': fields.function(_get_restriction, method=True, type='boolean', string='External partners orders', readonly=True, multi='restriction',
1369 store={'product.product': (lambda self, cr, uid, ids, c=None: ids, ['international_status', 'state'], 20),
1370@@ -452,6 +749,11 @@
1371 'soq_weight': fields.float(digits=(16,5), string='SoQ Weight'),
1372 'soq_volume': fields.float(digits=(16,5), string='SoQ Volume'),
1373 'vat_ok': fields.function(_get_vat_ok, method=True, type='boolean', string='VAT OK', store=False, readonly=True),
1374+ 'prodlot_ids': fields.one2many(
1375+ 'stock.production.lot',
1376+ 'product_id',
1377+ string='Batch Numbers',
1378+ ),
1379 }
1380
1381 # US-43: Remove the default_get that set value on Product Creator field. By removing the required = True value
1382@@ -463,15 +765,27 @@
1383 # res.update({'international_status': id })
1384 # return res
1385
1386+ def _get_default_sensitive_item(self, cr, uid, context=None):
1387+ """
1388+ Return the ID of the product.heat_sensitive item with 'No' value.
1389+ :param cr: Cursor to the datase
1390+ :param uid: ID of the res.users that calls the method
1391+ :param context: Context of the call
1392+ :return: The ID of the product.heat_sensitive item with 'No' value.
1393+ """
1394+ return self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no')[1]
1395+
1396 _defaults = {
1397 'duplicate_ok': True,
1398 'perishable': False,
1399 'batch_management': False,
1400- 'short_shelf_life': False,
1401+ 'short_shelf_life': 'False',
1402 'narcotic': False,
1403 'composed_kit': False,
1404- 'dangerous_goods': False,
1405+ 'dangerous_goods': 'False',
1406+ 'controlled_substance': 'False',
1407 'restricted_country': False,
1408+ 'heat_sensitive_item': _get_default_sensitive_item,
1409 'currency_id': lambda obj, cr, uid, c: obj.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id,
1410 'field_currency_id': lambda obj, cr, uid, c: obj.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id,
1411 'vat_ok': lambda obj, cr, uid, c: obj.pool.get('unifield.setup.configuration').get_config(cr, uid).vat_ok,
1412@@ -661,12 +975,26 @@
1413
1414 return result, res
1415
1416-
1417 def onchange_heat(self, cr, uid, ids, heat, context=None):
1418- heat_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_1')[1]
1419- if not heat or heat == heat_id:
1420- return {'value': {'show_cold_chain':False}}
1421- return {'value': {'show_cold_chain':True}}
1422+ """
1423+ Set the value for the field 'show_cold_chain' according to
1424+ selection Temperature sensitive value.
1425+ If the returned value is True, the field Cold Chain will be displayed
1426+ :param cr: Cursor to the database
1427+ :param uid: ID of the res.users that calls the method
1428+ :param ids: List of ID of product.product on which the field is computed
1429+ :param heat: ID of the selected product.heat_sensitive
1430+ :param context: Context of the call
1431+ :return: True of False in the 'show_cold_chain' field
1432+ """
1433+ heat1_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_1')[1]
1434+ heat2_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no')[1]
1435+ heat3_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no_know')[1]
1436+ return {
1437+ 'value': {
1438+ 'show_cold_chain': heat and heat not in [heat1_id, heat2_id, heat3_id]
1439+ }
1440+ }
1441
1442 def _check_gmdn_code(self, cr, uid, ids, context=None):
1443 int_pattern = re.compile(r'^\d*$')
1444@@ -699,6 +1027,10 @@
1445 if category_id not in product_uom_categ:
1446 product_uom_categ.append(category_id)
1447
1448+ if 'narcotic' in vals or 'controlled_substance' in vals:
1449+ if vals.get('narcotic') == True or tools.ustr(vals.get('controlled_substance', '')) == 'True':
1450+ vals['controlled_substance'] = 'True'
1451+
1452 res = super(product_attributes, self).write(cr, uid, ids, vals, context=context)
1453
1454 if product_uom_categ:
1455@@ -1074,6 +1406,10 @@
1456 """
1457 sptc_obj = self.pool.get('standard.price.track.changes')
1458
1459+ if 'narcotic' in vals or 'controlled_substance' in vals:
1460+ if vals.get('narcotic') == True or tools.ustr(vals.get('controlled_substance', '')) == 'True':
1461+ vals['controlled_substance'] = 'True'
1462+
1463 res = super(product_attributes, self).create(cr, user, vals,
1464 context=context)
1465
1466
1467=== modified file 'bin/addons/product_attributes/product_attributes_data.xml'
1468--- bin/addons/product_attributes/product_attributes_data.xml 2015-10-20 09:59:33 +0000
1469+++ bin/addons/product_attributes/product_attributes_data.xml 2016-03-18 10:41:28 +0000
1470@@ -1,6 +1,6 @@
1471 <?xml version="1.0" encoding="utf-8"?>
1472 <openerp>
1473- <data noupdate="1">
1474+ <data noupdate="0">
1475
1476 <record model="product.status" id="status_1">
1477 <field name="code">valid</field>
1478@@ -76,79 +76,94 @@
1479 <record model="product.international.status" id="int_5">
1480 <field name="code">temp</field>
1481 <field name="name">Temporary</field>
1482- </record>
1483-
1484+ </record>
1485+
1486+ <record model="product.heat_sensitive" id="heat_yes">
1487+ <field name="code">yes</field>
1488+ <field name="name">Yes</field>
1489+ </record>
1490+ <record model="product.heat_sensitive" id="heat_no">
1491+ <field name="code">no</field>
1492+ <field name="name">No</field>
1493+ </record>
1494+ <record model="product.heat_sensitive" id="heat_no_know">
1495+ <field name="code">no_know</field>
1496+ <field name="name">Don't know</field>
1497+ </record>
1498 <record model="product.heat_sensitive" id="heat_1">
1499 <field name="code">KR</field>
1500 <field name="name">Keep refrigerated but not cold chain (+2 to +8°C) for transport')</field>
1501+ <field name="active" eval="False" />
1502 </record>
1503 <record model="product.heat_sensitive" id="heat_2">
1504 <field name="code">*</field>
1505 <field name="name">Keep Cool</field>
1506+ <field name="active" eval="False" />
1507 </record>
1508 <record model="product.heat_sensitive" id="heat_3">
1509 <field name="code">**</field>
1510 <field name="name">Keep Cool, airfreight</field>
1511+ <field name="active" eval="False" />
1512 </record>
1513 <record model="product.heat_sensitive" id="heat_4">
1514 <field name="code">***</field>
1515 <field name="name">Cold chain, 0° to 8°C strict</field>
1516+ <field name="active" eval="False" />
1517 </record>
1518
1519 <record model="product.cold_chain" id="cold_1">
1520- <field name="code">3*</field>
1521- <field name="name">3* Cold Chain * - Keep Cool: used for a kit containing cold chain module or item(s)</field>
1522+ <field name="code">*</field>
1523+ <field name="name">* - Keep Cool: used for a kit or article containing cold chain module or item(s)</field>
1524 </record>
1525 <record model="product.cold_chain" id="cold_2">
1526- <field name="code">6*0</field>
1527- <field name="name">6*0 Cold Chain *0 - Problem if any window blue</field>
1528+ <field name="code">*0</field>
1529+ <field name="name">*0 - Problem if any window blue</field>
1530 </record>
1531 <record model="product.cold_chain" id="cold_3">
1532- <field name="code">7*0F</field>
1533- <field name="name">7*0F Cold Chain *0F - Problem if any window blue or Freeze-tag = ALARM</field>
1534+ <field name="code">*0F</field>
1535+ <field name="name">*0F - Problem if any window blue or Freeze-tag = ALARM</field>
1536 </record>
1537 <record model="product.cold_chain" id="cold_4">
1538- <field name="code">8*A</field>
1539- <field name="name">8*A Cold Chain *A - Problem if B, C and/or D totally blue</field>
1540+ <field name="code">*A</field>
1541+ <field name="name">*A - Problem if A, B, C and/or D blue = ALARM</field>
1542 </record>
1543 <record model="product.cold_chain" id="cold_5">
1544- <field name="code">9*AF</field>
1545- <field name="name">9*AF Cold Chain *AF - Problem if B, C and/or D totally blue or Freeze-tag = ALARM</field>
1546+ <field name="code">*AF</field>
1547+ <field name="name">*AF - Problem if A, B, C and/or D blue or Freeze-tag = ALARM</field>
1548 </record>
1549 <record model="product.cold_chain" id="cold_6">
1550- <field name="code">10*B</field>
1551- <field name="name">10*B Cold Chain *B - Problem if C and/or D totally blue</field>
1552+ <field name="code">*B</field>
1553+ <field name="name">*B - Problem if B, C and/or D blue</field>
1554 </record>
1555 <record model="product.cold_chain" id="cold_7">
1556- <field name="code">11*BF</field>
1557- <field name="name">11*BF Cold Chain *BF - Problem if C and/or D totally blue or Freeze-tag = ALARM</field>
1558+ <field name="code">*BF</field>
1559+ <field name="name">*BF - Problem if B, C and/or D blue or Freeze-tag = ALARM</field>
1560 </record>
1561 <record model="product.cold_chain" id="cold_8">
1562- <field name="code">12*C</field>
1563- <field name="name">12*C Cold Chain *C - Problem if D totally blue</field>
1564+ <field name="code">*C</field>
1565+ <field name="name">*C - Problem if C and D blue</field>
1566 </record>
1567 <record model="product.cold_chain" id="cold_9">
1568- <field name="code">13*CF</field>
1569- <field name="name">13*CF Cold Chain *CF - Problem if D totally blue or Freeze-tag = ALARM</field>
1570+ <field name="code">*CF</field>
1571+ <field name="name">*CF - Problem if C and/or D blue or Freeze-tag = ALARM</field>
1572 </record>
1573 <record model="product.cold_chain" id="cold_10">
1574- <field name="code">14*D</field>
1575- <field name="name">14*D Cold Chain *D - Store and transport at -25°C (store in deepfreezer, transport with dry-ice)</field>
1576+ <field name="code">*D</field>
1577+ <field name="name">*D - Store and transport at -25°C (store in deepfreezer, transport with dry-ice)</field>
1578 </record>
1579 <record model="product.cold_chain" id="cold_11">
1580- <field name="code">15*F</field>
1581- <field name="name">15*F Cold Chain *F - Cannot be frozen: check Freeze-tag</field>
1582+ <field name="code">*F</field>
1583+ <field name="name">*F - Cannot be frozen: check FreezeWatch</field>
1584 </record>
1585 <record model="product.cold_chain" id="cold_12">
1586- <field name="code">16*25</field>
1587- <field name="name">16*25 Cold Chain *25 - Must be kept below 25°C (but not necesseraly in cold chain)</field>
1588+ <field name="code">*25</field>
1589+ <field name="name">*25 - Must be kept below 25°C (but not necesseraly in cold chain)</field>
1590 </record>
1591 <record model="product.cold_chain" id="cold_13">
1592- <field name="code">17*25F</field>
1593- <field name="name">17*25F Cold Chain *25F - Must be kept below 25°C and cannot be frozen: check Freeze-tag</field>
1594+ <field name="code">*25F</field>
1595+ <field name="name">*25F - Must be kept below 25°C and cannot be frozen: check FreezeWatch</field>
1596 </record>
1597
1598-
1599 </data>
1600 </openerp>
1601
1602
1603=== modified file 'bin/addons/product_attributes/product_attributes_view.xml'
1604--- bin/addons/product_attributes/product_attributes_view.xml 2015-05-29 15:33:12 +0000
1605+++ bin/addons/product_attributes/product_attributes_view.xml 2016-03-18 10:41:28 +0000
1606@@ -131,7 +131,6 @@
1607 <field name="cold_chain" colspan="2" attrs="{'invisible': [('show_cold_chain','=',False)]}" widget="selection"/>
1608 <field name="sterilized" colspan="2"/>
1609 <field name="single_use" colspan="2"/>
1610- <field name="narcotic" colspan="2"/>
1611 <field name="controlled_substance" colspan="2"/>
1612 </group>
1613 <group colspan="2" col="2">
1614
1615=== modified file 'bin/addons/specific_rules/specific_rules.py'
1616--- bin/addons/specific_rules/specific_rules.py 2016-02-08 10:00:07 +0000
1617+++ bin/addons/specific_rules/specific_rules.py 2016-03-18 10:41:28 +0000
1618@@ -55,10 +55,12 @@
1619
1620 for sol in self.browse(cr, uid, ids, context=context):
1621 if sol.product_id:
1622- if sol.product_id.heat_sensitive_item:
1623- result[sol.id] = 'KC'
1624- elif sol.product_id.dangerous_goods:
1625- result[sol.id] = 'DG'
1626+ if sol.product_id.kc_txt:
1627+ result[sol.id] += sol.product_id.is_kc and 'KC' or 'KC ?'
1628+ if sol.product_id.dg_txt:
1629+ if result[sol.id]:
1630+ result[sol.id] += ' / '
1631+ result[sol.id] += sol.product_id.is_dg and 'DG' or 'DG ?'
1632
1633 return result
1634
1635@@ -77,7 +79,7 @@
1636 # if the product is short shelf life, display a warning
1637 if product:
1638 prod_obj = self.pool.get('product.product')
1639- if prod_obj.browse(cr, uid, product).short_shelf_life:
1640+ if prod_obj.browse(cr, uid, product).is_ssl:
1641 warning = {
1642 'title': 'Short Shelf Life product',
1643 'message': _(SHORT_SHELF_LIFE_MESS)
1644@@ -105,7 +107,7 @@
1645 for obj in self.browse(cr, uid, ids, context=context):
1646 for line in obj.order_line:
1647 # log the message
1648- if line.product_id.short_shelf_life:
1649+ if line.product_id.is_ssl:
1650 # log the message
1651 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
1652
1653@@ -130,30 +132,33 @@
1654
1655 for pol in self.browse(cr, uid, ids, context=context):
1656 if pol.product_id:
1657- if pol.product_id.heat_sensitive_item:
1658- result[pol.id] = 'KC'
1659- elif pol.product_id.dangerous_goods:
1660- result[pol.id] = 'DG'
1661+ if pol.product_id.kc_txt:
1662+ result[pol.id] += pol.product_id.is_kc and 'KC' or 'KC ?'
1663+ if pol.product_id.dg_txt:
1664+ if result[pol.id]:
1665+ result[pol.id] += ' / '
1666+ result[pol.id] += pol.product_id.is_dg and 'DG' or 'DG ?'
1667
1668 return result
1669
1670 _columns = {'kc_dg': fields.function(_kc_dg, method=True, string='KC/DG', type='char'),}
1671
1672- def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
1673+ def product_id_on_change(self, cr, uid, ids, pricelist, product, qty, uom,
1674 partner_id, date_order=False, fiscal_position=False, date_planned=False,
1675- name=False, price_unit=False, notes=False):
1676+ name=False, price_unit=False, notes=False, state=False, old_price_unit=0.00, nomen_manda_0=False,
1677+ comment='', context=None):
1678 '''
1679 if the product is short shelf life we display a warning
1680 '''
1681 # call to super
1682- result = super(purchase_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty, uom,
1683+ result = super(purchase_order_line, self).product_id_on_change(cr, uid, ids, pricelist, product, qty, uom,
1684 partner_id, date_order, fiscal_position, date_planned,
1685- name, price_unit, notes)
1686+ name, price_unit, notes, state, old_price_unit, nomen_manda_0, comment, context)
1687
1688 # if the product is short shelf life, display a warning
1689 if product:
1690 prod_obj = self.pool.get('product.product')
1691- if prod_obj.browse(cr, uid, product).short_shelf_life:
1692+ if prod_obj.browse(cr, uid, product).is_ssl:
1693 warning = {
1694 'title': 'Short Shelf Life product',
1695 'message': _(SHORT_SHELF_LIFE_MESS)
1696@@ -183,7 +188,7 @@
1697 for obj in self.browse(cr, uid, ids, context=context):
1698 for line in obj.order_line:
1699 # log the message
1700- if line.product_id.short_shelf_life:
1701+ if line.product_id.is_ssl:
1702 # log the message
1703 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
1704
1705@@ -276,7 +281,7 @@
1706 product_obj = self.pool.get('product.product')
1707 product_id = vals.get('product_id', False)
1708 if product_id:
1709- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1710+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1711 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
1712
1713 return new_id
1714@@ -293,7 +298,7 @@
1715 product_obj = self.pool.get('product.product')
1716 product_id = vals.get('product_id', False)
1717 if product_id:
1718- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1719+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1720 for obj in self.browse(cr, uid, ids, context=context):
1721 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
1722
1723@@ -525,7 +530,7 @@
1724 product_obj = self.pool.get('product.product')
1725 product_id = vals.get('product_id', False)
1726 if product_id:
1727- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1728+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1729 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
1730
1731 return new_id
1732@@ -542,7 +547,7 @@
1733 product_obj = self.pool.get('product.product')
1734 product_id = vals.get('product_id', False)
1735 if product_id:
1736- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1737+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1738 for obj in self.browse(cr, uid, ids, context=context):
1739 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
1740
1741@@ -566,7 +571,7 @@
1742 product_obj = self.pool.get('product.product')
1743 product_id = vals.get('product_id', False)
1744 if product_id:
1745- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1746+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1747 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
1748
1749 return new_id
1750@@ -586,7 +591,7 @@
1751 product_obj = self.pool.get('product.product')
1752 product_id = vals.get('product_id', False)
1753 if product_id:
1754- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
1755+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
1756 for obj in self.browse(cr, uid, ids, context=context):
1757 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
1758
1759@@ -640,10 +645,12 @@
1760
1761 for move in self.browse(cr, uid, ids, context=context):
1762 if move.product_id:
1763- if move.product_id.heat_sensitive_item:
1764- result[move.id] = 'KC'
1765- elif move.product_id.dangerous_goods:
1766- result[move.id] = 'DG'
1767+ if move.product_id.kc_txt:
1768+ result[move.id] += move.product_id.is_kc and 'KC' or 'KC ?'
1769+ if move.product_id.dg_txt:
1770+ if result[move.id]:
1771+ result[move.id] += ' / '
1772+ result[move.id] += move.product_id.is_dg and 'DG' or 'DG ?'
1773
1774 return result
1775
1776@@ -751,17 +758,13 @@
1777
1778 for obj in self.browse(cr, uid, ids, context=context):
1779 # keep cool
1780- if obj.product_id.heat_sensitive_item:
1781- result[obj.id]['kc_check'] = True
1782+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
1783 # ssl
1784- if obj.product_id.short_shelf_life:
1785- result[obj.id]['ssl_check'] = True
1786+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
1787 # dangerous goods
1788- if obj.product_id.dangerous_goods:
1789- result[obj.id]['dg_check'] = True
1790+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
1791 # narcotic
1792- if obj.product_id.narcotic:
1793- result[obj.id]['np_check'] = True
1794+ result[obj.id]['np_check'] = obj.product_id.cs_txt
1795 # lot management
1796 if obj.product_id.batch_management:
1797 result[obj.id]['lot_check'] = True
1798@@ -788,14 +791,75 @@
1799 # if prodlot needs to be mandatory, add 'required': ['|', ('hidden_batch_management_mandatory','=',True), ('hidden_perishable_mandatory','=',True)] in attrs
1800 'hidden_batch_management_mandatory': fields.boolean(string='Hidden Flag for Batch Management product',),
1801 'hidden_perishable_mandatory': fields.boolean(string='Hidden Flag for Perishable product',),
1802- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
1803- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
1804- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
1805- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
1806- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
1807- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
1808- 'kit_check': fields.function(_get_checks_all, method=True, string='Kit', type='boolean', readonly=True, multi="m"),
1809- 'prodlot_id': fields.many2one('stock.production.lot', 'Batch', states={'done': [('readonly', True)]}, help="Batch number is used to put a serial number on the production", select=True),
1810+ 'kc_check': fields.function(
1811+ _get_checks_all,
1812+ method=True,
1813+ string='KC',
1814+ type='char',
1815+ size=8,
1816+ readonly=True,
1817+ multi="m",
1818+ ),
1819+ 'ssl_check': fields.function(
1820+ _get_checks_all,
1821+ method=True,
1822+ string='SSL',
1823+ type='char',
1824+ size=8,
1825+ readonly=True,
1826+ multi="m",
1827+ ),
1828+ 'dg_check': fields.function(
1829+ _get_checks_all,
1830+ method=True,
1831+ string='DG',
1832+ type='char',
1833+ size=8,
1834+ readonly=True,
1835+ multi="m",
1836+ ),
1837+ 'np_check': fields.function(
1838+ _get_checks_all,
1839+ method=True,
1840+ string='CS',
1841+ type='char',
1842+ size=8,
1843+ readonly=True,
1844+ multi="m",
1845+ ),
1846+ 'lot_check': fields.function(
1847+ _get_checks_all,
1848+ method=True,
1849+ string='B.Num',
1850+ type='boolean',
1851+ readonly=True,
1852+ multi="m",
1853+ ),
1854+ 'exp_check': fields.function(
1855+ _get_checks_all,
1856+ method=True,
1857+ string='Exp',
1858+ type='boolean',
1859+ readonly=True,
1860+ multi="m",
1861+ ),
1862+ 'kit_check': fields.function(
1863+ _get_checks_all,
1864+ method=True,
1865+ string='Kit',
1866+ type='boolean',
1867+ readonly=True,
1868+ multi="m",
1869+ ),
1870+ 'prodlot_id': fields.many2one(
1871+ 'stock.production.lot',
1872+ 'Batch',
1873+ states={
1874+ 'done': [('readonly', True)],
1875+ },
1876+ help="Batch number is used to put a serial number on the production",
1877+ select=True,
1878+ ),
1879 }
1880
1881 _constraints = [
1882@@ -1074,17 +1138,13 @@
1883
1884 for obj in self.browse(cr, uid, ids, context=context):
1885 # keep cool
1886- if obj.product_id.heat_sensitive_item:
1887- result[obj.id]['kc_check'] = True
1888+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
1889 # ssl
1890- if obj.product_id.short_shelf_life:
1891- result[obj.id]['ssl_check'] = True
1892+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
1893 # dangerous goods
1894- if obj.product_id.dangerous_goods:
1895- result[obj.id]['dg_check'] = True
1896+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
1897 # narcotic
1898- if obj.product_id.narcotic:
1899- result[obj.id]['np_check'] = True
1900+ result[obj.id]['np_check'] = obj.product_id.cs_txt
1901 # lot management
1902 if obj.product_id.batch_management:
1903 result[obj.id]['lot_check'] = True
1904@@ -1163,30 +1223,90 @@
1905
1906 return res
1907
1908- _columns = {'check_type': fields.function(_get_false, fnct_search=search_check_type, string='Check Type', type="boolean", readonly=True, method=True),
1909- # readonly is True, the user is only allowed to create standard lots - internal lots are system-created
1910- 'type': fields.selection([('standard', 'Standard'),('internal', 'Internal'),], string="Type", readonly=True),
1911- #'expiry_date': fields.date('Expiry Date'),
1912- 'name': fields.char('Batch Number', size=1024, required=True, help="Unique batch number, will be displayed as: PREFIX/SERIAL [INT_REF]"),
1913- 'date': fields.datetime('Auto Creation Date', required=True),
1914- 'sequence_id': fields.many2one('ir.sequence', 'Batch Sequence', required=True,),
1915- 'stock_virtual': fields.function(_get_stock_virtual, method=True, type="float", string="Available Stock", select=True,
1916- help="Current available quantity of products with this Batch Numbre Number in company warehouses",
1917- digits_compute=dp.get_precision('Product UoM'), readonly=True,
1918- fnct_search=_stock_search_virtual,),
1919- 'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Real Stock", select=True,
1920- help="Current real quantity of products with this Batch Number in company warehouses",
1921- digits_compute=dp.get_precision('Product UoM')),
1922- 'src_product_id': fields.function(_get_dummy, fnct_search=_src_product, method=True, type="boolean", string="By product"),
1923- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
1924- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
1925- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
1926- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
1927- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
1928- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
1929- 'delete_ok': fields.function(_get_delete_ok, method=True, string='Possible deletion ?', type='boolean', readonly=True),
1930- 'is_expired': fields.function(_is_expired, method=True, string='Expired ?', type='boolean', store=False, readonly=True),
1931- }
1932+ _columns = {
1933+ 'check_type': fields.function(_get_false, fnct_search=search_check_type, string='Check Type', type="boolean", readonly=True, method=True),
1934+ # readonly is True, the user is only allowed to create standard lots - internal lots are system-created
1935+ 'type': fields.selection([('standard', 'Standard'),('internal', 'Internal'),], string="Type", readonly=True),
1936+ #'expiry_date': fields.date('Expiry Date'),
1937+ 'name': fields.char('Batch Number', size=1024, required=True, help="Unique batch number, will be displayed as: PREFIX/SERIAL [INT_REF]"),
1938+ 'date': fields.datetime('Auto Creation Date', required=True),
1939+ 'sequence_id': fields.many2one('ir.sequence', 'Batch Sequence', required=True,),
1940+ 'stock_virtual': fields.function(_get_stock_virtual, method=True, type="float", string="Available Stock", select=True,
1941+ help="Current available quantity of products with this Batch Numbre Number in company warehouses",
1942+ digits_compute=dp.get_precision('Product UoM'), readonly=True,
1943+ fnct_search=_stock_search_virtual,),
1944+ 'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Real Stock", select=True,
1945+ help="Current real quantity of products with this Batch Number in company warehouses",
1946+ digits_compute=dp.get_precision('Product UoM')),
1947+ 'src_product_id': fields.function(_get_dummy, fnct_search=_src_product, method=True, type="boolean", string="By product"),
1948+ 'kc_check': fields.function(
1949+ _get_checks_all,
1950+ method=True,
1951+ string='KC',
1952+ type='char',
1953+ size=8,
1954+ readonly=True,
1955+ multi="m",
1956+ ),
1957+ 'ssl_check': fields.function(
1958+ _get_checks_all,
1959+ method=True,
1960+ string='SSL',
1961+ type='char',
1962+ size=8,
1963+ readonly=True,
1964+ multi="m",
1965+ ),
1966+ 'dg_check': fields.function(
1967+ _get_checks_all,
1968+ method=True,
1969+ string='DG',
1970+ type='char',
1971+ size=8,
1972+ readonly=True,
1973+ multi="m",
1974+ ),
1975+ 'np_check': fields.function(
1976+ _get_checks_all,
1977+ method=True,
1978+ string='CS',
1979+ type='char',
1980+ size=8,
1981+ readonly=True,
1982+ multi="m",
1983+ ),
1984+ 'lot_check': fields.function(
1985+ _get_checks_all,
1986+ method=True,
1987+ string='B.Num',
1988+ type='boolean',
1989+ readonly=True,
1990+ multi="m",
1991+ ),
1992+ 'exp_check': fields.function(
1993+ _get_checks_all,
1994+ method=True,
1995+ string='Exp',
1996+ type='boolean',
1997+ readonly=True,
1998+ multi="m",
1999+ ),
2000+ 'delete_ok': fields.function(
2001+ _get_delete_ok,
2002+ method=True,
2003+ string='Possible deletion ?',
2004+ type='boolean',
2005+ readonly=True,
2006+ ),
2007+ 'is_expired': fields.function(
2008+ _is_expired,
2009+ method=True,
2010+ string='Expired ?',
2011+ type='boolean',
2012+ store=False,
2013+ readonly=True,
2014+ ),
2015+ }
2016
2017 _defaults = {'type': 'standard',
2018 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'stock.production.lot', context=c),
2019@@ -1705,9 +1825,9 @@
2020 result.setdefault('value', {})['expiry_date'] = False
2021 result.setdefault('value', {})['lot_check'] = False
2022 result.setdefault('value', {})['exp_check'] = False
2023- result.setdefault('value', {})['dg_check'] = False
2024- result.setdefault('value', {})['kc_check'] = False
2025- result.setdefault('value', {})['np_check'] = False
2026+ result.setdefault('value', {})['dg_check'] = ''
2027+ result.setdefault('value', {})['kc_check'] = ''
2028+ result.setdefault('value', {})['np_check'] = ''
2029 # reset the hidden flags
2030 result.setdefault('value', {})['hidden_batch_management_mandatory'] = False
2031 result.setdefault('value', {})['hidden_perishable_mandatory'] = False
2032@@ -1725,17 +1845,13 @@
2033 result.setdefault('value', {})['hidden_perishable_mandatory'] = True
2034 result.setdefault('value', {})['exp_check'] = True
2035 # keep cool
2036- if product_obj.heat_sensitive_item:
2037- result.setdefault('value', {})['kc_check'] = True
2038+ result.setdefault('value', {})['kc_check'] = product_obj.kc_txt
2039 # ssl
2040- if product_obj.short_shelf_life:
2041- result.setdefault('value', {})['ssl_check'] = True
2042+ result.setdefault('value', {})['ssl_check'] = product_obj.ssl_txt
2043 # dangerous goods
2044- if product_obj.dangerous_goods:
2045- result.setdefault('value', {})['dg_check'] = True
2046+ result.setdefault('value', {})['dg_check'] = product_obj.dg_txt
2047 # narcotic
2048- if product_obj.narcotic:
2049- result.setdefault('value', {})['np_check'] = True
2050+ result.setdefault('value', {})['np_check'] = product_obj.cs_txt
2051 # if not product, result is 0.0 by super
2052 # compute qty
2053 result = self.common_on_change(cr, uid, ids, location_id, product, prod_lot_id, uom, to_date, result=result)
2054@@ -1802,17 +1918,13 @@
2055
2056 for obj in self.browse(cr, uid, ids, context=context):
2057 # keep cool
2058- if obj.product_id.heat_sensitive_item:
2059- result[obj.id]['kc_check'] = True
2060+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2061 # ssl
2062- if obj.product_id.short_shelf_life:
2063- result[obj.id]['ssl_check'] = True
2064+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2065 # dangerous goods
2066- if obj.product_id.dangerous_goods:
2067- result[obj.id]['dg_check'] = True
2068+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2069 # narcotic
2070- if obj.product_id.narcotic:
2071- result[obj.id]['np_check'] = True
2072+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2073 # lot management
2074 if obj.product_id.batch_management:
2075 result[obj.id]['lot_check'] = True
2076@@ -1924,15 +2036,77 @@
2077 'prod_lot_id': fields.many2one('stock.production.lot', 'Batch', domain="[('product_id','=',product_id)]"),
2078 'expiry_date': fields.date(string='Expiry Date'),
2079 'type_check': fields.char(string='Type Check', size=1024,),
2080- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2081- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2082- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2083- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2084- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2085- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2086- 'has_problem': fields.function(_get_checks_all, method=True, string='Has problem', type='boolean', readonly=True, multi="m"),
2087- 'duplicate_line': fields.function(_get_checks_all, method=True, string='Duplicate line', type='boolean', readonly=True, multi="m"),
2088- 'dont_move': fields.boolean(string='Don\'t create stock.move for this line'),
2089+ 'kc_check': fields.function(
2090+ _get_checks_all,
2091+ method=True,
2092+ string='KC',
2093+ type='char',
2094+ size=8,
2095+ readonly=True,
2096+ multi="m",
2097+ ),
2098+ 'ssl_check': fields.function(
2099+ _get_checks_all,
2100+ method=True,
2101+ string='SSL',
2102+ type='char',
2103+ size=8,
2104+ readonly=True,
2105+ multi="m",
2106+ ),
2107+ 'dg_check': fields.function(
2108+ _get_checks_all,
2109+ method=True,
2110+ string='DG',
2111+ type='char',
2112+ size=8,
2113+ readonly=True,
2114+ multi="m",
2115+ ),
2116+ 'np_check': fields.function(
2117+ _get_checks_all,
2118+ method=True,
2119+ string='CS',
2120+ type='char',
2121+ size=8,
2122+ readonly=True,
2123+ multi="m",
2124+ ),
2125+ 'lot_check': fields.function(
2126+ _get_checks_all,
2127+ method=True,
2128+ string='B.Num',
2129+ type='boolean',
2130+ readonly=True,
2131+ multi="m",
2132+ ),
2133+ 'exp_check': fields.function(
2134+ _get_checks_all,
2135+ method=True,
2136+ string='Exp',
2137+ type='boolean',
2138+ readonly=True,
2139+ multi="m",
2140+ ),
2141+ 'has_problem': fields.function(
2142+ _get_checks_all,
2143+ method=True,
2144+ string='Has problem',
2145+ type='boolean',
2146+ readonly=True,
2147+ multi="m",
2148+ ),
2149+ 'duplicate_line': fields.function(
2150+ _get_checks_all,
2151+ method=True,
2152+ string='Duplicate line',
2153+ type='boolean',
2154+ readonly=True,
2155+ multi="m",
2156+ ),
2157+ 'dont_move': fields.boolean(
2158+ string='Don\'t create stock.move for this line',
2159+ ),
2160 }
2161
2162 _defaults = {# in is used, meaning a new prod lot will be created if the specified expiry date does not exist
2163
2164=== modified file 'bin/addons/specific_rules/specific_rules_view.xml'
2165--- bin/addons/specific_rules/specific_rules_view.xml 2015-10-13 12:25:48 +0000
2166+++ bin/addons/specific_rules/specific_rules_view.xml 2016-03-18 10:41:28 +0000
2167@@ -55,7 +55,7 @@
2168 <data>
2169
2170 <field name="life_time" position="replace">
2171- <field name="life_time" attrs="{'required':[('short_shelf_life', '=', True)]}" />
2172+ <field name="life_time" attrs="{'required':[('short_shelf_life', '=', 'True')]}" />
2173 </field>
2174 </data>
2175 </field>
2176
2177=== modified file 'bin/addons/specific_rules/wizard/stock_partial_move.py'
2178--- bin/addons/specific_rules/wizard/stock_partial_move.py 2013-11-22 15:06:16 +0000
2179+++ bin/addons/specific_rules/wizard/stock_partial_move.py 2016-03-18 10:41:28 +0000
2180@@ -84,17 +84,13 @@
2181 result[obj.id]['batch_number_check'] = obj.product_id.batch_management
2182 result[obj.id]['expiry_date_check'] = obj.product_id.perishable
2183 # keep cool
2184- if obj.product_id.heat_sensitive_item:
2185- result[obj.id]['kc_check'] = True
2186+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2187 # ssl
2188- if obj.product_id.short_shelf_life:
2189- result[obj.id]['ssl_check'] = True
2190+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2191 # dangerous goods
2192- if obj.product_id.dangerous_goods:
2193- result[obj.id]['dg_check'] = True
2194+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2195 # narcotic
2196- if obj.product_id.narcotic:
2197- result[obj.id]['np_check'] = True
2198+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2199 # type of picking
2200 result[obj.id]['type_check'] = obj.move_id.type
2201 # lot management
2202@@ -188,16 +184,80 @@
2203 'expiry_date_check': fields.function(_get_checks_all, method=True, string='Expiry Date Check', type='boolean', readonly=True, multi="m"),
2204 'type_check': fields.function(_get_checks_all, method=True, string='Picking Type Check', type='char', readonly=True, multi="m"),
2205 'expiry_date': fields.date('Expiry Date'),
2206- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2207- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2208- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2209- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2210- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2211- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2212- 'location_id': fields.related('move_id', 'location_id', type='many2one', relation='stock.location', string='Source Location', readonly=True),
2213- 'quantity_ordered': fields.float('Quantity ordered'),
2214- 'uom_ordered': fields.many2one('product.uom', string='UoM ordered', readonly=True),
2215- 'uom_category': fields.related('uom_ordered', 'category_id', type='many2one', relation='product.uom.categ'),
2216+ 'kc_check': fields.function(
2217+ _get_checks_all,
2218+ method=True,
2219+ string='KC',
2220+ type='char',
2221+ size=8,
2222+ readonly=True,
2223+ multi="m",
2224+ ),
2225+ 'ssl_check': fields.function(
2226+ _get_checks_all,
2227+ method=True,
2228+ string='SSL',
2229+ type='char',
2230+ size=8,
2231+ readonly=True,
2232+ multi="m",
2233+ ),
2234+ 'dg_check': fields.function(
2235+ _get_checks_all,
2236+ method=True,
2237+ string='DG',
2238+ type='char',
2239+ size=8,
2240+ readonly=True,
2241+ multi="m",
2242+ ),
2243+ 'np_check': fields.function(
2244+ _get_checks_all,
2245+ method=True,
2246+ string='CS',
2247+ type='char',
2248+ size=8,
2249+ readonly=True,
2250+ multi="m",
2251+ ),
2252+ 'lot_check': fields.function(
2253+ _get_checks_all,
2254+ method=True,
2255+ string='B.Num',
2256+ type='boolean',
2257+ readonly=True,
2258+ multi="m",
2259+ ),
2260+ 'exp_check': fields.function(
2261+ _get_checks_all,
2262+ method=True,
2263+ string='Exp',
2264+ type='boolean',
2265+ readonly=True,
2266+ multi="m",
2267+ ),
2268+ 'location_id': fields.related(
2269+ 'move_id',
2270+ 'location_id',
2271+ type='many2one',
2272+ relation='stock.location',
2273+ string='Source Location',
2274+ readonly=True,
2275+ ),
2276+ 'quantity_ordered': fields.float(
2277+ 'Quantity ordered',
2278+ ),
2279+ 'uom_ordered': fields.many2one(
2280+ 'product.uom',
2281+ string='UoM ordered',
2282+ readonly=True,
2283+ ),
2284+ 'uom_category': fields.related(
2285+ 'uom_ordered',
2286+ 'category_id',
2287+ type='many2one',
2288+ relation='product.uom.categ',
2289+ ),
2290 }
2291
2292 stock_partial_move_memory_out()
2293
2294=== modified file 'bin/addons/specific_rules/wizard/stock_partial_picking.py'
2295--- bin/addons/specific_rules/wizard/stock_partial_picking.py 2014-02-24 15:41:57 +0000
2296+++ bin/addons/specific_rules/wizard/stock_partial_picking.py 2016-03-18 10:41:28 +0000
2297@@ -48,13 +48,13 @@
2298 type = False
2299 contains_kc = False
2300 contains_dg = False
2301-
2302+
2303 for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
2304 type = pick.type
2305 for m in pick.move_lines:
2306- if m.product_id.heat_sensitive_item:
2307+ if m.product_id.is_kc:
2308 contains_kc = True
2309- if m.product_id.dangerous_goods:
2310+ if m.product_id.is_dg:
2311 contains_dg = True
2312
2313 if contains_kc and contains_dg:
2314
2315=== modified file 'bin/addons/stock_forecast/wizard/stock_forecast.py'
2316--- bin/addons/stock_forecast/wizard/stock_forecast.py 2015-02-05 16:24:37 +0000
2317+++ bin/addons/stock_forecast/wizard/stock_forecast.py 2016-03-18 10:41:28 +0000
2318@@ -130,10 +130,9 @@
2319 values['product_family_info_id'] = wiz.product_id.nomen_manda_2.id
2320 values['procurement_method'] = wiz.product_id.procure_method
2321 values['supply_method'] = wiz.product_id.supply_method
2322- if wiz.product_id.heat_sensitive_item:
2323- values['keep_cool'] = True
2324- values['short_shelf_life'] = wiz.product_id.short_shelf_life
2325- values['dangerous_goods'] = wiz.product_id.dangerous_goods
2326+ values['keep_cool'] = wiz.product_id.is_kc
2327+ values['short_shelf_life'] = wiz.product_id.is_ssl
2328+ values['dangerous_goods'] = wiz.product_id.is_dg
2329 values['justification_code_id'] = wiz.product_id.justification_code_id.id
2330 return result
2331
2332
2333=== modified file 'bin/addons/stock_override/stock.py'
2334--- bin/addons/stock_override/stock.py 2016-03-14 10:07:38 +0000
2335+++ bin/addons/stock_override/stock.py 2016-03-18 10:41:28 +0000
2336@@ -2154,13 +2154,6 @@
2337 result = []
2338 for move in self.browse(cr, uid, ids, context=context):
2339 # add this move into the list of result
2340- dg_check_flag = ''
2341- if move.dg_check:
2342- dg_check_flag = 'x'
2343-
2344- np_check_flag = ''
2345- if move.np_check:
2346- np_check_flag = 'x'
2347 sub_total = move.product_qty * move.product_id.standard_price
2348
2349 currency = ''
2350@@ -2178,8 +2171,8 @@
2351 'origin': move.origin,
2352 'expired_date': move.expired_date,
2353 'prodlot_id': move.prodlot_id.name,
2354- 'dg_check': dg_check_flag,
2355- 'np_check': np_check_flag,
2356+ 'dg_check': move.product_id and move.product_id.dg_txt or '',
2357+ 'np_check': move.product_id and move.product_id.cs_txt or '',
2358 'uom': move.product_uom.name,
2359 'prod_qty': move.product_qty,
2360 })
2361
2362=== modified file 'bin/addons/sync_so/sale.py'
2363--- bin/addons/sync_so/sale.py 2016-03-03 11:05:04 +0000
2364+++ bin/addons/sync_so/sale.py 2016-03-18 10:41:28 +0000
2365@@ -382,6 +382,7 @@
2366
2367 if original_id:
2368 orig_partner_name = self.browse(cr, uid, original_id, context=context).partner_id.name
2369+<<<<<<< TREE
2370
2371 # Generate messages for cancel lines
2372 available_solc_ids = solc_obj.search(cr, uid, eval(solccl_rule.domain),
2373@@ -398,6 +399,13 @@
2374 order='NO_ORDER', context=context)
2375 if nfo_model_obj and nfo_rule and original_id in available_nfo_ids:
2376 generate_msg_to_send(nfo_rule, nfo_model_obj, original_id, orig_partner_name)
2377+=======
2378+ if nfo_model_obj and nfo_rule:
2379+ available_nfo_ids = self.search(cr, uid, eval(nfo_rule.domain),
2380+ order='NO_ORDER', context=context)
2381+ if original_id in available_nfo_ids:
2382+ generate_msg_to_send(nfo_rule, nfo_model_obj, original_id, orig_partner_name)
2383+>>>>>>> MERGE-SOURCE
2384 if vfo_model_obj and vfo_rule:
2385 generate_msg_to_send(vfo_rule, vfo_model_obj, original_id, orig_partner_name)
2386
2387
2388=== modified file 'bin/osv/orm.py'
2389--- bin/osv/orm.py 2016-02-24 10:21:02 +0000
2390+++ bin/osv/orm.py 2016-03-18 10:41:28 +0000
2391@@ -912,7 +912,8 @@
2392 res = value and float(value.replace(',','.')) or 0.0
2393 elif field_type == 'selection':
2394 for key, val in fields_def[field[len(prefix)]]['selection']:
2395- if value in [tools.ustr(key), tools.ustr(val)]:
2396+ if value in [tools.ustr(key), tools.ustr(val)] or \
2397+ tools.ustr(value) in [tools.ustr(key), tools.ustr(val)]:
2398 res = key
2399 break
2400 if not value:
2401@@ -2663,6 +2664,18 @@
2402 self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
2403 self._table, column['attname'])
2404
2405+ def execute_migration(self, cr, moved_column, new_column):
2406+ """
2407+ On change type of column, make a migration of data. The old values
2408+ are moved to a new column suffixed by _movedX.
2409+ This method must be overriden on needed objects.
2410+ :param cr: Cursor to the database
2411+ :param moved_column: The renamed old column
2412+ :param new_column: The column with the new type
2413+ :return: Nothing
2414+ """
2415+ pass
2416+
2417 def _auto_init(self, cr, context=None):
2418 if context is None:
2419 context = {}
2420@@ -2781,6 +2794,7 @@
2421 cr.commit()
2422 self.__schema.debug("Create table '%s': relation between '%s' and '%s'",
2423 f._rel, self._table, ref)
2424+ self.execute_migration(cr, newname, k)
2425 else:
2426 res = col_data.get(k, [])
2427 res = res and [res] or []

Subscribers

People subscribed via source and target branches

to all changes: