Merge lp:~unifield-team/unifield-server/us-749 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 3679
Proposed branch: lp:~unifield-team/unifield-server/us-749
Merge into: lp:unifield-server
Diff against target: 2861 lines (+1320/-402) (has conflicts)
33 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 (+51/-0)
bin/addons/msf_profile/msf_profile.py (+51/-0)
bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv (+11/-3)
bin/addons/product_attributes/data/product_justification_code.xml (+44/-16)
bin/addons/product_attributes/product_attributes.py (+488/-26)
bin/addons/product_attributes/product_attributes_data.xml (+44/-45)
bin/addons/product_attributes/product_attributes_view.xml (+27/-13)
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-749
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+289476@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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +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:42:44 +0000
869@@ -5,8 +5,59 @@
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+ <record id="update_volume_patch" model="patch.scripts">
925+ <field name="method">update_volume_patch</field>
926 </record>
927
928 </data>
929
930=== modified file 'bin/addons/msf_profile/msf_profile.py'
931--- bin/addons/msf_profile/msf_profile.py 2016-03-11 15:55:20 +0000
932+++ bin/addons/msf_profile/msf_profile.py 2016-03-18 10:42:44 +0000
933@@ -305,6 +305,57 @@
934 for view in view_to_gen:
935 view_obj.generate_button_access_rules(cr, uid, view)
936
937+ def update_volume_patch(self, cr, uid, *a, **b):
938+ """
939+ Update the volume from dm³ to m³ for OCB databases
940+ :param cr: Cursor to the database
941+ :param uid: ID of the res.users that calls the method
942+ :param a: Unnamed parameters
943+ :param b: Named parameters
944+ :return: True
945+ """
946+ instance = self.pool.get('res.users').browse(cr, uid, uid).company_id.instance_id
947+ while instance.level != 'section':
948+ instance = instance.parent_id
949+
950+ if instance.name != 'OCBHQ':
951+ cr.execute("""
952+ UPDATE product_template
953+ SET volume_updated = True
954+ WHERE volume_updated = False
955+ """)
956+ else:
957+ cr.execute("""
958+ UPDATE product_template
959+ SET volume = volume*1000,
960+ volume_updated = True
961+ WHERE volume_updated = False
962+ """)
963+
964+ def us_750_patch(self, cr, uid, *a, **b):
965+ """
966+ Update the heat_sensitive_item field of product.product
967+ to 'Yes' if there is a value already defined by de-activated.
968+ :param cr: Cursor to the database
969+ :param uid: ID of the res.users that calls this method
970+ :param a: Non-named parameters
971+ :param b: Named parameters
972+ :return: True
973+ """
974+ prd_obj = self.pool.get('product.product')
975+ phs_obj = self.pool.get('product.heat_sensitive')
976+ data_obj = self.pool.get('ir.model.data')
977+
978+ heat_id = data_obj.get_object_reference(cr, uid, 'product_attributes', 'heat_yes')[1]
979+
980+ phs_ids = phs_obj.search(cr, uid, [('active', '=', False)])
981+ prd_ids = prd_obj.search(cr, uid, [('heat_sensitive_item', 'in', phs_ids)])
982+ if prd_ids:
983+ prd_obj.write(cr, uid, prd_ids, {
984+ 'heat_sensitive_item': heat_id,
985+ })
986+
987+ return True
988
989 def update_us_963_negative_rule_seq(self, cr, uid, *a, **b):
990 if self.pool.get('sync.client.update_received'):
991
992=== modified file 'bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv'
993--- bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2016-01-25 14:13:18 +0000
994+++ bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2016-03-18 10:42:44 +0000
995@@ -107,8 +107,8 @@
996 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
997 msf_sync_data_server.country_restrictions,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,[],['name'],MISSION,res.country.restriction,,Country restrictions,Valid,,570
998 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
999-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
1000-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
1001+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', 'manufacturer_txt', 'manufacturer_ref', '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', 'active', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume', 'volume_updated', 'soq_weight', 'soq_volume']",OC,product.product,,"OC Product (Creator = ITC, ESC or HQ)",Valid,,600
1002+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', 'manufacturer_txt', 'manufacturer_ref', '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', 'active', 'state', 'old_code', 'function_value', 'form_value', 'fit_value', 'standard_ok','transport_ok','volume', 'volume_updated', 'soq_weight','soq_volume']",MISSION,product.product,,Mission Product (Creator = local),Valid,,601
1003 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
1004 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
1005 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
1006@@ -199,7 +199,15 @@
1007 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
1008 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
1009 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
1010-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
1011+<<<<<<< TREE
1012+<<<<<<< TREE
1013+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','manufacturer_txt', 'manufacturer_ref','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', 'active', '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
1014+=======
1015+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', 'volume_updated', 'soq_weight','soq_volume']",USB,product.product,,[MASTER] Products,Valid,,1810
1016+>>>>>>> MERGE-SOURCE
1017+=======
1018+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
1019+>>>>>>> MERGE-SOURCE
1020 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
1021 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
1022 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
1023
1024=== modified file 'bin/addons/product_attributes/data/product_justification_code.xml'
1025--- bin/addons/product_attributes/data/product_justification_code.xml 2012-10-30 12:00:35 +0000
1026+++ bin/addons/product_attributes/data/product_justification_code.xml 2016-03-18 10:42:44 +0000
1027@@ -1,59 +1,87 @@
1028 <?xml version="1.0" encoding="utf-8"?>
1029 <openerp>
1030- <data noupdate="1">
1031-
1032+ <data noupdate="0">
1033+
1034 <record id="justification_code_ja" model="product.justification.code">
1035- <field name="code">18 J(A)</field>
1036+ <field name="code">A</field>
1037 <field name="description">This kind of article need a more detailed description of the context in which it will be used.</field>
1038 </record>
1039+ <record id="justification_code_jc" model="product.justification.code">
1040+ <field name="code">C</field>
1041+ <field name="description">The article is potentially subject to important modifications (supply sources, better alternatives).</field>
1042+ </record>
1043 <record id="justification_code_je" model="product.justification.code">
1044- <field name="code">21 J(E)</field>
1045+ <field name="code">E</field>
1046 <field name="description">The article is expensive and its choice should be justified in relation to cheaper alternatives.</field>
1047 </record>
1048 <record id="justification_code_jf" model="product.justification.code">
1049- <field name="code">22 J(F)</field>
1050+ <field name="code">F</field>
1051 <field name="description">Monitor the use, efficacy for at least one year after the introduction of new drugs.</field>
1052 </record>
1053 <record id="justification_code_jm" model="product.justification.code">
1054- <field name="code">23 J(M)</field>
1055+ <field name="code">M</field>
1056 <field name="description">The article may imply medical risks if misused by persons with insufficient training or knowledge.</field>
1057 </record>
1058 <record id="justification_code_jme" model="product.justification.code">
1059- <field name="code">24 J(ME)</field>
1060+ <field name="code">ME</field>
1061 <field name="description">The article may imply medical risks if misused by persons with insufficient training, Expensive.</field>
1062 </record>
1063 <record id="justification_code_jmf" model="product.justification.code">
1064- <field name="code">25 J(MF)</field>
1065+ <field name="code">MF</field>
1066 <field name="description">The article may imply medical risks if misused + Monitor the use, efficacy at least one year.</field>
1067 </record>
1068 <record id="justification_code_jo" model="product.justification.code">
1069- <field name="code">27 J(O)</field>
1070+ <field name="code">O</field>
1071 <field name="description">The article and its specifications are obsolete or are no longer the international standard.</field>
1072 </record>
1073+ <record id="justification_code_jom" model="product.justification.code">
1074+ <field name="code">OM</field>
1075+ <field name="description">The article and its specifications are obsolete , it may imply a medical risk if misused.</field>
1076+ </record>
1077+ <record id="justification_code_jop" model="product.justification.code">
1078+ <field name="code">OP</field>
1079+ <field name="description">The article and its specifications are obsolete , it has to be used only in a specific program.</field>
1080+ </record>
1081 <record id="justification_code_jp" model="product.justification.code">
1082- <field name="code">30 J(P)</field>
1083+ <field name="code">P</field>
1084 <field name="description">The article must be used only in a properly designed programme.</field>
1085 </record>
1086 <record id="justification_code_jpa" model="product.justification.code">
1087- <field name="code">31 J(PA)</field>
1088+ <field name="code">PA</field>
1089 <field name="description">Article must be used only in a properly designed programme, need a more detailed description.</field>
1090 </record>
1091+ <record id="justification_code_jpcme" model="product.justification.code">
1092+ <field name="code">PCME</field>
1093+ <field name="description">????</field>
1094+ </record>
1095 <record id="justification_code_jpe" model="product.justification.code">
1096- <field name="code">35 J(PE)</field>
1097+ <field name="code">PE</field>
1098 <field name="description">Article must be used only in a properly designed programme, Expensive, cheaper alternatives exist.</field>
1099 </record>
1100 <record id="justification_code_jpf" model="product.justification.code">
1101- <field name="code">36 J(PF)</field>
1102+ <field name="code">PF</field>
1103 <field name="description">The article must be used only in a properly designed programme + monitor the use, efficacy.</field>
1104 </record>
1105 <record id="justification_code_jpm" model="product.justification.code">
1106- <field name="code">37 J(PM)</field>
1107+ <field name="code">PM</field>
1108 <field name="description">Article must be used only in a properly designed programme, it may imply a medical risk if misused.</field>
1109 </record>
1110 <record id="justification_code_jpme" model="product.justification.code">
1111- <field name="code">38 J(PME)</field>
1112+ <field name="code">PME</field>
1113 <field name="description">Article only for a properly designed Programme, it may imply a Medical risk if misused, Expensive.</field>
1114 </record>
1115+ <record id="justification_code_js" model="product.justification.code">
1116+ <field name="code">S</field>
1117+ <field name="description">Second choice. Article must only be used if the first choice is not available or cannot be used in a specific context.</field>
1118+ </record>
1119+ <record id="justification_code_jsm" model="product.justification.code">
1120+ <field name="code">SM</field>
1121+ <field name="description">Second choice &amp; medical risk. Article must be only used if the first choice is not available or cannot be used in a specific context. The article may imply medical risks if misused by persons with insufficient training or knowledge.</field>
1122+ </record>
1123+ <record id="justification_code_jsp" model="product.justification.code">
1124+ <field name="code">SP</field>
1125+ <field name="description">Second Choice &amp; specific programme. The article must only be used if the first choice</field>
1126+ </record>
1127
1128 </data>
1129-</openerp>
1130\ No newline at end of file
1131+</openerp>
1132
1133=== modified file 'bin/addons/product_attributes/product_attributes.py'
1134--- bin/addons/product_attributes/product_attributes.py 2016-01-25 10:53:51 +0000
1135+++ bin/addons/product_attributes/product_attributes.py 2016-03-18 10:42:44 +0000
1136@@ -103,9 +103,24 @@
1137
1138 class product_heat_sensitive(osv.osv):
1139 _name = "product.heat_sensitive"
1140+ _order = 'code desc'
1141 _columns = {
1142- 'code': fields.char('Code', size=256),
1143- 'name': fields.char('Name', size=256, required=True),
1144+ 'code': fields.char(
1145+ string='Code',
1146+ size=256,
1147+ ),
1148+ 'name': fields.char(
1149+ string='Name',
1150+ size=256,
1151+ required=True,
1152+ ),
1153+ 'active': fields.boolean(
1154+ string='Active',
1155+ )
1156+ }
1157+
1158+ _defaults = {
1159+ 'active': True,
1160 }
1161
1162 def unlink(self, cr, uid, ids, context=None):
1163@@ -113,11 +128,14 @@
1164 context = {}
1165 if isinstance(ids, (int, long)):
1166 ids = [ids]
1167- ids_p = self.pool.get('product.product').search(cr, uid,
1168- [('heat_sensitive_item','in',ids)],
1169- limit=1, order='NO_ORDER')
1170+ ids_p = self.pool.get('product.product').search(cr, uid, [
1171+ ('heat_sensitive_item', 'in', ids),
1172+ ], limit=1, order='NO_ORDER')
1173 if ids_p:
1174- raise osv.except_osv(_('Error'), _('You cannot delete this heat sensitive because it\'s used at least in one product'))
1175+ raise osv.except_osv(
1176+ _('Error'),
1177+ _('You cannot delete this heat sensitive because it\'s used at least in one product'),
1178+ )
1179 return super(product_heat_sensitive, self).unlink(cr, uid, ids, context=context)
1180
1181 product_heat_sensitive()
1182@@ -206,6 +224,7 @@
1183
1184 product_template()
1185
1186+
1187 class product_attributes(osv.osv):
1188 _inherit = "product.product"
1189
1190@@ -213,12 +232,36 @@
1191 if hasattr(super(product_attributes, self), 'init'):
1192 super(product_attributes, self).init(cr)
1193 mod_obj = self.pool.get('ir.module.module')
1194- mode = mod_obj.search(cr, 1, [('name', '=', 'product_attributes'), ('state', '=', 'to install')]) and 'init' or 'update'
1195+ mode = mod_obj.search(cr, 1, [('name', '=', 'product_attributes')])
1196 logging.getLogger('init').info('HOOK: module product_attributes: loading product_attributes_data.xml')
1197 pathname = path.join('product_attributes', 'product_attributes_data.xml')
1198 file = tools.file_open(pathname)
1199 tools.convert_xml_import(cr, 'product_attributes', file, {}, mode=mode, noupdate=True)
1200
1201+ def execute_migration(self, cr, moved_column, new_column):
1202+ super(product_attributes, self).execute_migration(cr, moved_column, new_column)
1203+ if new_column == 'standard_ok':
1204+ request = 'UPDATE product_product SET standard_ok = \'True\' WHERE %s = True' % moved_column
1205+ cr.execute(request)
1206+
1207+ if new_column == 'dangerous_goods':
1208+ request = 'UPDATE product_product SET dangerous_goods = \'True\' WHERE %s = True' % moved_column
1209+ cr.execute(request)
1210+
1211+ if new_column == 'short_shelf_life':
1212+ request = 'UPDATE product_product SET short_shelf_life = \'True\' WHERE %s = True' % moved_column
1213+ cr.execute(request)
1214+
1215+ if new_column == 'controlled_substance':
1216+ # Update old ticked controlled substance but not narcotic
1217+ request = '''UPDATE product_product SET
1218+ controlled_substance = 'True',
1219+ is_cs = True,
1220+ cs_txt = 'X'
1221+ WHERE %s = True OR narcotic = True''' % moved_column
1222+
1223+ return
1224+
1225 def _get_nomen(self, cr, uid, ids, field_name, args, context=None):
1226 res = {}
1227
1228@@ -352,19 +395,186 @@
1229
1230 return []
1231
1232+ def _compute_is_kc(self, cr, uid, product, context=None):
1233+ """
1234+ Return True if the product is considered as a Keep Cool product
1235+ :param cr: Cursor to the database
1236+ :param uid: ID of the res.users that calls this method
1237+ :param product: browse_record of a product.product
1238+ :param context: Context of the call
1239+ :return: True or False
1240+ """
1241+ return product.heat_sensitive_item.code == 'yes'
1242+
1243+ def _compute_kc_txt(self, cr, uid, product, context=None):
1244+ """
1245+ Return the character to display on views or reports ('X' or '?' or '') for Keep Cool
1246+ :param cr: Cursor to the database
1247+ :param uid: ID of the res.users that calls this method
1248+ :param product: browse_record of a product.product
1249+ :param context: Context of the call
1250+ :return: 'X' or '?' or ''
1251+ """
1252+ if product.heat_sensitive_item.code == 'no_know':
1253+ return '?'
1254+ elif product.heat_sensitive_item.code == 'no':
1255+ return ''
1256+ else:
1257+ return 'X'
1258+
1259+ def _compute_is_dg(self, cr, uid, product, context=None):
1260+ """
1261+ Return True if the product is considered as a Dangerous Goods product
1262+ :param cr: Cursor to the database
1263+ :param uid: ID of the res.users that calls this method
1264+ :param product: browse_record of a product.product
1265+ :param context: Context of the call
1266+ :return: True or False
1267+ """
1268+ return product.dangerous_goods == 'True'
1269+
1270+ def _compute_dg_txt(self, cr, uid, product, context=None):
1271+ """
1272+ Return the character to display on views or reports ('X' or '?' or '') for Dangerous Goods
1273+ :param cr: Cursor to the database
1274+ :param uid: ID of the res.users that calls this method
1275+ :param product: browse_record of a product.product
1276+ :param context: Context of the call
1277+ :return: 'X' or '?' or ''
1278+ """
1279+ if product.dangerous_goods == 'True':
1280+ return 'X'
1281+ elif product.dangerous_goods == 'no_know':
1282+ return '?'
1283+
1284+ return ''
1285+
1286+ def _compute_is_cs(self, cr, uid, product, context=None):
1287+ """
1288+ Return True if the product is considered as a Controlled Substance product
1289+ :param cr: Cursor to the database
1290+ :param uid: ID of the res.users that calls this method
1291+ :param product: browse_record of a product.product
1292+ :param context: Context of the call
1293+ :return: True or False
1294+ """
1295+ return product.controlled_substance
1296+
1297+ def _compute_cs_txt(self, cr, uid, product, context=None):
1298+ """
1299+ Return the character to display on views or reports ('X' or '?' or '') for Controlled Substance
1300+ :param cr: Cursor to the database
1301+ :param uid: ID of the res.users that calls this method
1302+ :param product: browse_record of a product.product
1303+ :param context: Context of the call
1304+ :return: 'X' or '?' or ''
1305+ """
1306+ return product.controlled_substance and 'X' or ''
1307+
1308+ def _compute_is_ssl(self, cr, uid, product, context=None):
1309+ """
1310+ Return True if the product is considered as a Short Shelf Life product
1311+ :param cr: Cursor to the database
1312+ :param uid: ID of the res.users that calls this method
1313+ :param product: browse_record of a product.product
1314+ :param context: Context of the call
1315+ :return: True or False
1316+ """
1317+ return product.short_shelf_life == 'True'
1318+
1319+ def _compute_ssl_txt(self, cr, uid, product, context=None):
1320+ """
1321+ Return the character to display on views or reports ('X' or '?' or '') for Short Shelf Life
1322+ :param cr: Cursor to the database
1323+ :param uid: ID of the res.users that calls this method
1324+ :param product: browse_record of a product.product
1325+ :param context: Context of the call
1326+ :return: 'X' or '?' or ''
1327+ """
1328+ if product.short_shelf_life == 'True':
1329+ return 'X'
1330+ elif product.short_shelf_life == 'no_know':
1331+ return '?'
1332+
1333+ return ''
1334+
1335+ def _compute_kc_dg_cs_ssl_values(self, cr, uid, ids, field_names, args, context=None):
1336+ """
1337+ Compute the character to display ('X' or '?' or '') according to product values
1338+ for Keep Cool, Dangerous Goods, Controlled Substance and Short Shelf Life.
1339+ :param cr: Cursor to the database
1340+ :param uid: ID of the res.users that calls this method
1341+ :param ids: List of ID of product.product to compute values
1342+ :param field_names: Name of the fields to compute
1343+ :param args: Additionnal arguments
1344+ :param context: Conetxt of the call
1345+ :return: A dictionary with the ID of product.product as keys and
1346+ a dictionary with computed field values for each ID in ids.
1347+ """
1348+ if context is None:
1349+ context = {}
1350+
1351+ if isinstance(ids, (int, long)):
1352+ ids = [ids]
1353+
1354+ if not isinstance(field_names, list):
1355+ field_names = [field_names]
1356+
1357+ res = {}
1358+ for product in self.browse(cr, uid, ids, context=context):
1359+ res[product.id] = {}
1360+ for fld in field_names:
1361+ method_name = '_compute_%s' % fld
1362+ res[product.id][fld] = getattr(self, method_name)(cr, uid, product, context=context)
1363+
1364+ return res
1365+
1366 _columns = {
1367 'duplicate_ok': fields.boolean('Is a duplicate'),
1368 'loc_indic': fields.char('Indicative Location', size=64),
1369 'description2': fields.text('Description 2'),
1370- 'old_code' : fields.char('Old code', size=64),
1371+ 'old_code' : fields.char(
1372+ string='Old code',
1373+ size=1024,
1374+ ),
1375 'new_code' : fields.char('New code', size=64),
1376-
1377 'international_status': fields.many2one('product.international.status', 'Product Creator', required=False),
1378 'perishable': fields.boolean('Expiry Date Mandatory'),
1379 'batch_management': fields.boolean('Batch Number Mandatory'),
1380 'product_catalog_page' : fields.char('Product Catalog Page', size=64),
1381- 'product_catalog_path' : fields.char('Product Catalog Path', size=64),
1382- 'short_shelf_life': fields.boolean('Short Shelf Life'),
1383+ 'product_catalog_path' : fields.char('Product Catalog Path', size=1024),
1384+ 'short_shelf_life': fields.selection(
1385+ selection=[
1386+ ('False', 'No'),
1387+ ('True', 'Yes'),
1388+ ('no_know', 'Don\'t know'),
1389+ ],
1390+ string='Short Shelf Life',
1391+ required=True,
1392+ ),
1393+ 'is_ssl': fields.function(
1394+ _compute_kc_dg_cs_ssl_values,
1395+ method=True,
1396+ type='boolean',
1397+ string='Is Short Shelf Life ?',
1398+ multi='ssl',
1399+ readonly=True,
1400+ store={
1401+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['short_shelf_life'], 10),
1402+ }
1403+ ),
1404+ 'ssl_txt': fields.function(
1405+ _compute_kc_dg_cs_ssl_values,
1406+ method=True,
1407+ type='char',
1408+ size=8,
1409+ string='Short Shelf Life icon',
1410+ multi='ssl',
1411+ readonly=True,
1412+ store={
1413+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['short_shelf_life'], 10),
1414+ }
1415+ ),
1416 'criticism': fields.selection([('',''),
1417 ('exceptional','1-Exceptional'),
1418 ('specific','2-Specific'),
1419@@ -390,22 +600,122 @@
1420 'composed_kit': fields.boolean('Kit Composed of Kits/Modules'),
1421 'options_ids': fields.many2many('product.product','product_options_rel','product_id','product_option_id','Options'),
1422
1423- 'heat_sensitive_item': fields.many2one('product.heat_sensitive', 'Temperature sensitive item',),
1424+ 'heat_sensitive_item': fields.many2one(
1425+ 'product.heat_sensitive',
1426+ string='Temperature sensitive item',
1427+ required=True,
1428+ ),
1429+ 'is_kc': fields.function(
1430+ _compute_kc_dg_cs_ssl_values,
1431+ method=True,
1432+ type='boolean',
1433+ string='Is Keep Cool ?',
1434+ multi='kc',
1435+ readonly=True,
1436+ store={
1437+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['heat_sensitive_item'], 10),
1438+ }
1439+ ),
1440+ 'kc_txt': fields.function(
1441+ _compute_kc_dg_cs_ssl_values,
1442+ method=True,
1443+ type='char',
1444+ size=8,
1445+ string='Keep Cool icon',
1446+ multi='kc',
1447+ readonly=True,
1448+ store={
1449+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['heat_sensitive_item'], 10),
1450+ }
1451+ ),
1452 'cold_chain': fields.many2one('product.cold_chain', 'Cold Chain',),
1453 'show_cold_chain': fields.boolean('Show cold chain'),
1454 # Inverse of m2m options_ids
1455 'options_ids_inv': fields.many2many('product.product', 'product_options_rel', 'product_option_id', 'product_id', 'Options Inv.'),
1456- 'sterilized': fields.selection([('yes', 'Yes'), ('no', 'No')], string='Sterile'),
1457- 'single_use': fields.selection([('yes', 'Yes'),('no', 'No')], string='Single Use'),
1458+ 'sterilized': fields.selection(
1459+ selection=[
1460+ ('yes', 'Yes'),
1461+ ('no', 'No'),
1462+ ('no_know', 'Don\'t know'),
1463+ ],
1464+ string='Sterile',
1465+ required=True,
1466+ ),
1467+ 'single_use': fields.selection(
1468+ selection=[
1469+ ('yes', 'Yes'),
1470+ ('no', 'No'),
1471+ ('no_know', 'Don\'t know'),
1472+ ],
1473+ string='Single Use',
1474+ required=True,
1475+ ),
1476 'justification_code_id': fields.many2one('product.justification.code', 'Justification Code'),
1477 'med_device_class': fields.selection([('',''),
1478 ('I','Class I (General controls)'),
1479 ('II','Class II (General control with special controls)'),
1480 ('III','Class III (General controls and premarket)')], 'Medical Device Class'),
1481- 'closed_article': fields.selection([('yes', 'Yes'), ('no', 'No'),],string='Closed Article'),
1482- 'dangerous_goods': fields.boolean('Dangerous Goods'),
1483+ 'manufacturer_txt': fields.text(
1484+ string='Manufacturer',
1485+ ),
1486+ 'manufacturer_ref': fields.char(
1487+ size=1024,
1488+ string='Manufacturer Ref.'
1489+ ),
1490+ 'closed_article': fields.selection(
1491+ selection=[
1492+ ('yes', 'Yes'),
1493+ ('no', 'No'),
1494+ ('recommanded', 'Recommanded'),
1495+ ],
1496+ string='Closed Article',
1497+ required=True,
1498+ ),
1499+ 'dangerous_goods': fields.selection(
1500+ selection=[
1501+ ('False', 'No'), # False is put as key for migration (see US-752)
1502+ ('True', 'Yes'), # True is put as key for migration (see US-752)
1503+ ('no_know', 'Don\'t know'),
1504+ ],
1505+ string='Dangerous goods',
1506+ required=True,
1507+ ),
1508+ 'is_dg': fields.function(
1509+ _compute_kc_dg_cs_ssl_values,
1510+ method=True,
1511+ type='boolean',
1512+ string='Is a Dangerous Goods ?',
1513+ multi='dg',
1514+ readonly=True,
1515+ store={
1516+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['dangerous_goods'], 10),
1517+ }
1518+ ),
1519+ 'dg_txt': fields.function(
1520+ _compute_kc_dg_cs_ssl_values,
1521+ method=True,
1522+ type='char',
1523+ size=8,
1524+ string='Dangerous Goods icon',
1525+ multi='dg',
1526+ readonly=True,
1527+ store={
1528+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['dangerous_goods'], 10),
1529+ }
1530+ ),
1531 'restricted_country': fields.boolean('Restricted in the Country'),
1532 'country_restriction': fields.many2one('res.country.restriction', 'Country Restriction'),
1533+ 'state_ud': fields.selection(
1534+ selection=[
1535+ ('valid', 'Valid'),
1536+ ('phase_out', 'Phase Out'),
1537+ ('stopped', 'Stopped'),
1538+ ('archived', 'Archived'),
1539+ ],
1540+ string='UniData Status',
1541+ readonly=True,
1542+ help="Automatically filled with UniData information.",
1543+ ),
1544 # TODO: validation on 'un_code' field
1545 'un_code': fields.char('UN Code', size=7),
1546 'gmdn_code' : fields.char('GMDN Code', size=5),
1547@@ -421,7 +731,42 @@
1548 'field_currency_id': fields.many2one('res.currency', string='Currency', readonly=True),
1549 'nomen_ids': fields.function(_get_nomen, fnct_search=_search_nomen,
1550 type='many2many', relation='product.nomenclature', method=True, string='Nomenclatures'),
1551- 'controlled_substance': fields.boolean(string='Controlled substance'),
1552+ 'controlled_substance': fields.selection(
1553+ selection=[
1554+ ('!', '! - Requires national export license'),
1555+ ('N1', 'N1 - Narcotic 1'),
1556+ ('N2', 'N2 - Narcotic 2'),
1557+ ('P1', 'P1 - Psychotrop 1'),
1558+ ('P3', 'P3 - Psychotrop 3'),
1559+ ('P4', 'P4 - Psychotrop 4'),
1560+ ('Y', 'Y - Kit or module with controlled substance'),
1561+ ('True', 'CS / NP - Controlled Substance / Narcotic / Psychotropic')
1562+ ],
1563+ string='Controlled substance',
1564+ ),
1565+ 'is_cs': fields.function(
1566+ _compute_kc_dg_cs_ssl_values,
1567+ method=True,
1568+ type='boolean',
1569+ string='Is Controlled subst.',
1570+ multi='cs',
1571+ readonly=True,
1572+ store={
1573+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['controlled_substance'], 10),
1574+ }
1575+ ),
1576+ 'cs_txt': fields.function(
1577+ _compute_kc_dg_cs_ssl_values,
1578+ method=True,
1579+ type='char',
1580+ size=8,
1581+ string='Controlled subst. icon',
1582+ multi='cs',
1583+ readonly=True,
1584+ store={
1585+ 'product.product': (lambda self, cr, uid, ids, c=None: ids, ['controlled_substance'], 10),
1586+ }
1587+ ),
1588 'uom_category_id': fields.related('uom_id', 'category_id', string='Uom Category', type='many2one', relation='product.uom.categ'),
1589 'no_external': fields.function(_get_restriction, method=True, type='boolean', string='External partners orders', readonly=True, multi='restriction',
1590 store={'product.product': (lambda self, cr, uid, ids, c=None: ids, ['international_status', 'state'], 20),
1591@@ -448,10 +793,22 @@
1592 'form_value': fields.text(string='Form', translate=True),
1593 'fit_value': fields.text(string='Fit', translate=True),
1594 'function_value': fields.text(string='Function', translate=True),
1595- 'standard_ok': fields.boolean(string='Standard'),
1596+ 'standard_ok': fields.selection(
1597+ selection=[
1598+ ('True', 'Standard'),
1599+ ('False', 'Non-standard'),
1600+ ],
1601+ string='Standardization Level',
1602+ required=True,
1603+ ),
1604 'soq_weight': fields.float(digits=(16,5), string='SoQ Weight'),
1605 'soq_volume': fields.float(digits=(16,5), string='SoQ Volume'),
1606 'vat_ok': fields.function(_get_vat_ok, method=True, type='boolean', string='VAT OK', store=False, readonly=True),
1607+ 'prodlot_ids': fields.one2many(
1608+ 'stock.production.lot',
1609+ 'product_id',
1610+ string='Batch Numbers',
1611+ ),
1612 }
1613
1614 # US-43: Remove the default_get that set value on Product Creator field. By removing the required = True value
1615@@ -463,15 +820,31 @@
1616 # res.update({'international_status': id })
1617 # return res
1618
1619+ def _get_default_sensitive_item(self, cr, uid, context=None):
1620+ """
1621+ Return the ID of the product.heat_sensitive item with 'No' value.
1622+ :param cr: Cursor to the datase
1623+ :param uid: ID of the res.users that calls the method
1624+ :param context: Context of the call
1625+ :return: The ID of the product.heat_sensitive item with 'No' value.
1626+ """
1627+ return self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no')[1]
1628+
1629 _defaults = {
1630+ 'closed_article': 'no',
1631 'duplicate_ok': True,
1632 'perishable': False,
1633 'batch_management': False,
1634- 'short_shelf_life': False,
1635+ 'short_shelf_life': 'False',
1636 'narcotic': False,
1637 'composed_kit': False,
1638- 'dangerous_goods': False,
1639+ 'dangerous_goods': 'False',
1640+ 'controlled_substance': 'False',
1641 'restricted_country': False,
1642+ 'sterilized': 'no',
1643+ 'single_use': 'no',
1644+ 'standard_ok': 'False',
1645+ 'heat_sensitive_item': _get_default_sensitive_item,
1646 'currency_id': lambda obj, cr, uid, c: obj.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id,
1647 'field_currency_id': lambda obj, cr, uid, c: obj.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id,
1648 'vat_ok': lambda obj, cr, uid, c: obj.pool.get('unifield.setup.configuration').get_config(cr, uid).vat_ok,
1649@@ -661,12 +1034,26 @@
1650
1651 return result, res
1652
1653-
1654 def onchange_heat(self, cr, uid, ids, heat, context=None):
1655- heat_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_1')[1]
1656- if not heat or heat == heat_id:
1657- return {'value': {'show_cold_chain':False}}
1658- return {'value': {'show_cold_chain':True}}
1659+ """
1660+ Set the value for the field 'show_cold_chain' according to
1661+ selection Temperature sensitive value.
1662+ If the returned value is True, the field Cold Chain will be displayed
1663+ :param cr: Cursor to the database
1664+ :param uid: ID of the res.users that calls the method
1665+ :param ids: List of ID of product.product on which the field is computed
1666+ :param heat: ID of the selected product.heat_sensitive
1667+ :param context: Context of the call
1668+ :return: True of False in the 'show_cold_chain' field
1669+ """
1670+ heat1_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_1')[1]
1671+ heat2_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no')[1]
1672+ heat3_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'product_attributes', 'heat_no_know')[1]
1673+ return {
1674+ 'value': {
1675+ 'show_cold_chain': heat and heat not in [heat1_id, heat2_id, heat3_id]
1676+ }
1677+ }
1678
1679 def _check_gmdn_code(self, cr, uid, ids, context=None):
1680 int_pattern = re.compile(r'^\d*$')
1681@@ -676,6 +1063,14 @@
1682 return True
1683
1684 def write(self, cr, uid, ids, vals, context=None):
1685+ data_obj = self.pool.get('ir.model.data')
1686+
1687+ if context is None:
1688+ context = {}
1689+
1690+ if isinstance(ids, (int, long)):
1691+ ids = [ids]
1692+
1693 if 'batch_management' in vals:
1694 vals['track_production'] = vals['batch_management']
1695 vals['track_incoming'] = vals['batch_management']
1696@@ -699,6 +1094,25 @@
1697 if category_id not in product_uom_categ:
1698 product_uom_categ.append(category_id)
1699
1700+ if context.get('sync_update_execution') and not context.get('bypass_sync_update', False):
1701+ stopped_status = data_obj.get_object_reference(cr, uid, 'product_attributes', 'status_3')[1]
1702+ phase_out_status = data_obj.get_object_reference(cr, uid, 'product_attributes', 'status_2')[1]
1703+ if vals.get('active', None) is False:
1704+ if self.deactivate_product(cr, uid, ids, context=context) is not True:
1705+ vals.update({
1706+ 'active': True,
1707+ 'state': stopped_status,
1708+ })
1709+ elif vals.get('active', None) is True and vals.get('state') == stopped_status:
1710+ vals.update({
1711+ 'active': True,
1712+ 'state': phase_out_status,
1713+ })
1714+
1715+ if 'narcotic' in vals or 'controlled_substance' in vals:
1716+ if vals.get('narcotic') == True or tools.ustr(vals.get('controlled_substance', '')) == 'True':
1717+ vals['controlled_substance'] = 'True'
1718+
1719 res = super(product_attributes, self).write(cr, uid, ids, vals, context=context)
1720
1721 if product_uom_categ:
1722@@ -733,6 +1147,7 @@
1723 if isinstance(ids, (int, long)):
1724 ids = [ids]
1725
1726+ data_obj = self.pool.get('ir.model.data')
1727 location_obj = self.pool.get('stock.location')
1728 po_line_obj = self.pool.get('purchase.order.line')
1729 tender_line_obj = self.pool.get('tender.line')
1730@@ -966,6 +1381,13 @@
1731 'doc_ref': invoice.invoice_id.number,
1732 'doc_id': invoice.invoice_id.id}, context=context)
1733
1734+ if context.get('sync_update_execution', False):
1735+ context['bypass_sync_update'] = True
1736+ self.write(cr, uid, product.id, {
1737+ 'active': True,
1738+ 'state': data_obj.get_object_reference(cr, uid, 'product_attributes', 'status_3')[1],
1739+ }, context=context)
1740+
1741 return {'type': 'ir.actions.act_window',
1742 'res_model': 'product.deactivation.error',
1743 'view_type': 'form',
1744@@ -1011,6 +1433,8 @@
1745 orderpoint_line_obj.unlink(cr, uid, [orderpoint_line.id],
1746 context=context)
1747
1748+ if context.get('sync_update_execution', False):
1749+ context['bypass_sync_update'] = True
1750 self.write(cr, uid, ids, {'active': False}, context=context)
1751
1752 return True
1753@@ -1074,6 +1498,10 @@
1754 """
1755 sptc_obj = self.pool.get('standard.price.track.changes')
1756
1757+ if 'narcotic' in vals or 'controlled_substance' in vals:
1758+ if vals.get('narcotic') == True or tools.ustr(vals.get('controlled_substance', '')) == 'True':
1759+ vals['controlled_substance'] = 'True'
1760+
1761 res = super(product_attributes, self).create(cr, user, vals,
1762 context=context)
1763
1764@@ -1089,11 +1517,45 @@
1765 _inherit = 'product.template'
1766
1767 _columns = {
1768- 'volume': fields.float('Volume', digits=(16,5), help="The volume in m3."),
1769+ 'volume': fields.float(
1770+ string='Volume',
1771+ digits=(16, 5),
1772+ help="The volume in dm3.",
1773+ ),
1774+ 'volume_updated': fields.boolean(
1775+ strinrg='Volume updated',
1776+ readonly=True,
1777+ ),
1778 'weight': fields.float('Gross weight', digits=(16,5), help="The gross weight in Kg."),
1779 'weight_net': fields.float('Net weight', digits=(16,5), help="The net weight in Kg."),
1780 }
1781
1782+ _defaults = {
1783+ 'volume_updated': False,
1784+ }
1785+
1786+ def write(self, cr, uid, ids, vals, context=None):
1787+ """
1788+ Update the volume from dm³ to m³ if the volume was not
1789+ yet updated.
1790+ :param cr: Cursor to the database
1791+ :param uid: ID of the res.users that calls this method
1792+ :param ids: List of ID of product.template to update
1793+ :param vals: Values to apply on list of ID
1794+ :param context: Context of the call
1795+ :return: super write() method.
1796+ """
1797+ if context is None:
1798+ context = {}
1799+
1800+ if isinstance(ids, (int, long)):
1801+ ids = [ids]
1802+
1803+ if 'volume' in vals and not vals.get('volume_updated', False):
1804+ del vals['volume']
1805+
1806+ return super(product_template, self).write(cr, uid, ids, vals, context=context)
1807+
1808 product_template()
1809
1810
1811
1812=== modified file 'bin/addons/product_attributes/product_attributes_data.xml'
1813--- bin/addons/product_attributes/product_attributes_data.xml 2015-10-20 09:59:33 +0000
1814+++ bin/addons/product_attributes/product_attributes_data.xml 2016-03-18 10:42:44 +0000
1815@@ -1,6 +1,6 @@
1816 <?xml version="1.0" encoding="utf-8"?>
1817 <openerp>
1818- <data noupdate="1">
1819+ <data noupdate="0">
1820
1821 <record model="product.status" id="status_1">
1822 <field name="code">valid</field>
1823@@ -77,78 +77,77 @@
1824 <field name="code">temp</field>
1825 <field name="name">Temporary</field>
1826 </record>
1827+ <record model="product.international.status" id="int_6">
1828+ <field name="code">unidata</field>
1829+ <field name="name">UniData</field>
1830+ </record>
1831+
1832+ <record model="product.heat_sensitive" id="heat_yes">
1833+ <field name="code">yes</field>
1834+ <field name="name">Yes</field>
1835+ </record>
1836+ <record model="product.heat_sensitive" id="heat_no">
1837+ <field name="code">no</field>
1838+ <field name="name">No</field>
1839+ </record>
1840+ <record model="product.heat_sensitive" id="heat_no_know">
1841+ <field name="code">no_know</field>
1842+ <field name="name">Don't know</field>
1843+ </record>
1844
1845- <record model="product.heat_sensitive" id="heat_1">
1846- <field name="code">KR</field>
1847- <field name="name">Keep refrigerated but not cold chain (+2 to +8°C) for transport')</field>
1848- </record>
1849- <record model="product.heat_sensitive" id="heat_2">
1850+ <record model="product.cold_chain" id="cold_1">
1851 <field name="code">*</field>
1852- <field name="name">Keep Cool</field>
1853- </record>
1854- <record model="product.heat_sensitive" id="heat_3">
1855- <field name="code">**</field>
1856- <field name="name">Keep Cool, airfreight</field>
1857- </record>
1858- <record model="product.heat_sensitive" id="heat_4">
1859- <field name="code">***</field>
1860- <field name="name">Cold chain, 0° to 8°C strict</field>
1861- </record>
1862-
1863- <record model="product.cold_chain" id="cold_1">
1864- <field name="code">3*</field>
1865- <field name="name">3* Cold Chain * - Keep Cool: used for a kit containing cold chain module or item(s)</field>
1866+ <field name="name">* - Keep Cool: used for a kit or article containing cold chain module or item(s)</field>
1867 </record>
1868 <record model="product.cold_chain" id="cold_2">
1869- <field name="code">6*0</field>
1870- <field name="name">6*0 Cold Chain *0 - Problem if any window blue</field>
1871+ <field name="code">*0</field>
1872+ <field name="name">*0 - Problem if any window blue</field>
1873 </record>
1874 <record model="product.cold_chain" id="cold_3">
1875- <field name="code">7*0F</field>
1876- <field name="name">7*0F Cold Chain *0F - Problem if any window blue or Freeze-tag = ALARM</field>
1877+ <field name="code">*0F</field>
1878+ <field name="name">*0F - Problem if any window blue or Freeze-tag = ALARM</field>
1879 </record>
1880 <record model="product.cold_chain" id="cold_4">
1881- <field name="code">8*A</field>
1882- <field name="name">8*A Cold Chain *A - Problem if B, C and/or D totally blue</field>
1883+ <field name="code">*A</field>
1884+ <field name="name">*A - Problem if A, B, C and/or D blue = ALARM</field>
1885 </record>
1886 <record model="product.cold_chain" id="cold_5">
1887- <field name="code">9*AF</field>
1888- <field name="name">9*AF Cold Chain *AF - Problem if B, C and/or D totally blue or Freeze-tag = ALARM</field>
1889+ <field name="code">*AF</field>
1890+ <field name="name">*AF - Problem if A, B, C and/or D blue or Freeze-tag = ALARM</field>
1891 </record>
1892 <record model="product.cold_chain" id="cold_6">
1893- <field name="code">10*B</field>
1894- <field name="name">10*B Cold Chain *B - Problem if C and/or D totally blue</field>
1895+ <field name="code">*B</field>
1896+ <field name="name">*B - Problem if B, C and/or D blue</field>
1897 </record>
1898 <record model="product.cold_chain" id="cold_7">
1899- <field name="code">11*BF</field>
1900- <field name="name">11*BF Cold Chain *BF - Problem if C and/or D totally blue or Freeze-tag = ALARM</field>
1901+ <field name="code">*BF</field>
1902+ <field name="name">*BF - Problem if B, C and/or D blue or Freeze-tag = ALARM</field>
1903 </record>
1904 <record model="product.cold_chain" id="cold_8">
1905- <field name="code">12*C</field>
1906- <field name="name">12*C Cold Chain *C - Problem if D totally blue</field>
1907+ <field name="code">*C</field>
1908+ <field name="name">*C - Problem if C and D blue</field>
1909 </record>
1910 <record model="product.cold_chain" id="cold_9">
1911- <field name="code">13*CF</field>
1912- <field name="name">13*CF Cold Chain *CF - Problem if D totally blue or Freeze-tag = ALARM</field>
1913+ <field name="code">*CF</field>
1914+ <field name="name">*CF - Problem if C and/or D blue or Freeze-tag = ALARM</field>
1915 </record>
1916 <record model="product.cold_chain" id="cold_10">
1917- <field name="code">14*D</field>
1918- <field name="name">14*D Cold Chain *D - Store and transport at -25°C (store in deepfreezer, transport with dry-ice)</field>
1919+ <field name="code">*D</field>
1920+ <field name="name">*D - Store and transport at -25°C (store in deepfreezer, transport with dry-ice)</field>
1921 </record>
1922 <record model="product.cold_chain" id="cold_11">
1923- <field name="code">15*F</field>
1924- <field name="name">15*F Cold Chain *F - Cannot be frozen: check Freeze-tag</field>
1925+ <field name="code">*F</field>
1926+ <field name="name">*F - Cannot be frozen: check FreezeWatch</field>
1927 </record>
1928 <record model="product.cold_chain" id="cold_12">
1929- <field name="code">16*25</field>
1930- <field name="name">16*25 Cold Chain *25 - Must be kept below 25°C (but not necesseraly in cold chain)</field>
1931+ <field name="code">*25</field>
1932+ <field name="name">*25 - Must be kept below 25°C (but not necesseraly in cold chain)</field>
1933 </record>
1934 <record model="product.cold_chain" id="cold_13">
1935- <field name="code">17*25F</field>
1936- <field name="name">17*25F Cold Chain *25F - Must be kept below 25°C and cannot be frozen: check Freeze-tag</field>
1937+ <field name="code">*25F</field>
1938+ <field name="name">*25F - Must be kept below 25°C and cannot be frozen: check FreezeWatch</field>
1939 </record>
1940
1941-
1942 </data>
1943 </openerp>
1944
1945
1946=== modified file 'bin/addons/product_attributes/product_attributes_view.xml'
1947--- bin/addons/product_attributes/product_attributes_view.xml 2015-05-29 15:33:12 +0000
1948+++ bin/addons/product_attributes/product_attributes_view.xml 2016-03-18 10:42:44 +0000
1949@@ -61,13 +61,13 @@
1950 <separator string="Codes" colspan="2"/>
1951 <field name="default_code" required="1" string="Code" on_change="onchange_code(default_code)"
1952 attrs="{'readonly':[('duplicate_ok','=',False)]}" />
1953- <field name="old_code"/>
1954+ <field name="new_code"/>
1955 <field name="duplicate_ok" invisible="1"/>
1956 </group>
1957 <group colspan="4" col="2">
1958 <separator string="Description" colspan="2"/>
1959 <field name="name" string="Description"/>
1960- <field name="new_code"/>
1961+ <field name="old_code"/>
1962 <field name="sale_ok" invisible="1" />
1963 <field name="purchase_ok" invisible="1" />
1964 </group>
1965@@ -94,6 +94,7 @@
1966 <group colspan="2" col="2">
1967 <separator string="Weights" colspan="2"/>
1968 <field name="volume" attrs="{'readonly':[('type','=','service')]}"/>
1969+ <field name="volume_updated" invisible="1" />
1970 <field name="soq_volume" attrs="{'readonly':[('type','=','service')]}"/>
1971 <field name="weight" attrs="{'readonly':[('type','=','service')]}"/>
1972 <field name="soq_weight" attrs="{'readonly':[('type','=','service')]}"/>
1973@@ -106,7 +107,9 @@
1974 <separator string="Status" colspan="3"/>
1975 <field name="categ_id" readonly="1" colspan="3"/>
1976 <field name="international_status" required="1" widget="selection" colspan="3" />
1977+ <field name="standard_ok" colspan="3" />
1978 <field name="state" colspan="3" widget="selection" />
1979+ <field name="state_ud" colspan="3" />
1980 <field name="active" readonly="1"/>
1981 <group colspan="1" col="1">
1982 <button name="deactivate_product" icon="gtk-execute" string="De-activate product" type="object" attrs="{'invisible': [('active', '=', False)]}" />
1983@@ -131,27 +134,26 @@
1984 <field name="cold_chain" colspan="2" attrs="{'invisible': [('show_cold_chain','=',False)]}" widget="selection"/>
1985 <field name="sterilized" colspan="2"/>
1986 <field name="single_use" colspan="2"/>
1987- <field name="narcotic" colspan="2"/>
1988 <field name="controlled_substance" colspan="2"/>
1989+ <separator string="Transport" colspan="2"/>
1990+ <field name="dangerous_goods" colspan="2"/>
1991+ <field name="un_code" colspan="2"/>
1992+ <separator string="Import restrictions" colspan="4"/>
1993+ <field name="restricted_country" colspan="2"/>
1994+ <field name="country_restriction" colspan="2" widget="selection" attrs="{'readonly':[('restricted_country','=',False)]}"/>
1995 </group>
1996 <group colspan="2" col="2">
1997 <separator string="Diffusion" colspan="2"/>
1998 <field name="standard_ok" colspan="2" />
1999- <field name="justification_code_id" colspan="2" widget="selection" />
2000+ <field name="justification_code_id" colspan="2" />
2001 <!-- uf-1544
2002 <field name="med_device_class" colspan="2" />
2003 <field name="gmdn_code" colspan="2" />
2004 <field name="gmdn_description" colspan="2" />
2005 -->
2006 <field name="closed_article" colspan="2"/>
2007- <separator string="Import restrictions" colspan="4"/>
2008- <field name="restricted_country" colspan="2"/>
2009- <field name="country_restriction" colspan="2" widget="selection" attrs="{'readonly':[('restricted_country','=',False)]}"/>
2010- </group>
2011- <group colspan="2" col="2">
2012- <separator string="Transport" colspan="2"/>
2013- <field name="dangerous_goods" colspan="2"/>
2014- <field name="un_code" colspan="2"/>
2015+ <field name="manufacturer_ref" attrs="{'invisible': [('closed_article', '=', 'no')]}" />
2016+ <field name="manufacturer_txt" attrs="{'invisible': [('closed_article', '=', 'no')]}" />
2017 </group>
2018 <group colspan="2" col="2">
2019 <separator string="Form" colspan="2" />
2020@@ -265,7 +267,7 @@
2021 <separator string="Description"/>
2022 <!-- uf-1544 invisible-->
2023 <field name="product_catalog_page" invisible="1"/>
2024- <field name="product_catalog_path"/>
2025+ <field name="product_catalog_path" widget="url"/>
2026 <separator string="Description"/>
2027 <field colspan="4" name="description" nolabel="1"/>
2028 <field colspan="4" name="description2" nolabel="1"/>
2029@@ -752,6 +754,18 @@
2030 action="product_cold_chain_action"
2031 parent="purchase.menu_product_in_config_purchase" />
2032
2033+ <record id="product_justification_code_form_view" model="ir.ui.view">
2034+ <field name="name">product.justification.code.form</field>
2035+ <field name="model">product.justification.code</field>
2036+ <field name="type">form</field>
2037+ <field name="arch" type="xml">
2038+ <form string="Justification Code">
2039+ <field name="code" readonly="True"/>
2040+ <field name="description" readonly="True"/>
2041+ </form>
2042+ </field>
2043+ </record>
2044+
2045 <record id="product_justification_code_tree_view" model="ir.ui.view">
2046 <field name="name">product.justification.code.tree</field>
2047 <field name="model">product.justification.code</field>
2048
2049=== modified file 'bin/addons/specific_rules/specific_rules.py'
2050--- bin/addons/specific_rules/specific_rules.py 2016-02-08 10:00:07 +0000
2051+++ bin/addons/specific_rules/specific_rules.py 2016-03-18 10:42:44 +0000
2052@@ -55,10 +55,12 @@
2053
2054 for sol in self.browse(cr, uid, ids, context=context):
2055 if sol.product_id:
2056- if sol.product_id.heat_sensitive_item:
2057- result[sol.id] = 'KC'
2058- elif sol.product_id.dangerous_goods:
2059- result[sol.id] = 'DG'
2060+ if sol.product_id.kc_txt:
2061+ result[sol.id] += sol.product_id.is_kc and 'KC' or 'KC ?'
2062+ if sol.product_id.dg_txt:
2063+ if result[sol.id]:
2064+ result[sol.id] += ' / '
2065+ result[sol.id] += sol.product_id.is_dg and 'DG' or 'DG ?'
2066
2067 return result
2068
2069@@ -77,7 +79,7 @@
2070 # if the product is short shelf life, display a warning
2071 if product:
2072 prod_obj = self.pool.get('product.product')
2073- if prod_obj.browse(cr, uid, product).short_shelf_life:
2074+ if prod_obj.browse(cr, uid, product).is_ssl:
2075 warning = {
2076 'title': 'Short Shelf Life product',
2077 'message': _(SHORT_SHELF_LIFE_MESS)
2078@@ -105,7 +107,7 @@
2079 for obj in self.browse(cr, uid, ids, context=context):
2080 for line in obj.order_line:
2081 # log the message
2082- if line.product_id.short_shelf_life:
2083+ if line.product_id.is_ssl:
2084 # log the message
2085 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
2086
2087@@ -130,30 +132,33 @@
2088
2089 for pol in self.browse(cr, uid, ids, context=context):
2090 if pol.product_id:
2091- if pol.product_id.heat_sensitive_item:
2092- result[pol.id] = 'KC'
2093- elif pol.product_id.dangerous_goods:
2094- result[pol.id] = 'DG'
2095+ if pol.product_id.kc_txt:
2096+ result[pol.id] += pol.product_id.is_kc and 'KC' or 'KC ?'
2097+ if pol.product_id.dg_txt:
2098+ if result[pol.id]:
2099+ result[pol.id] += ' / '
2100+ result[pol.id] += pol.product_id.is_dg and 'DG' or 'DG ?'
2101
2102 return result
2103
2104 _columns = {'kc_dg': fields.function(_kc_dg, method=True, string='KC/DG', type='char'),}
2105
2106- def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
2107+ def product_id_on_change(self, cr, uid, ids, pricelist, product, qty, uom,
2108 partner_id, date_order=False, fiscal_position=False, date_planned=False,
2109- name=False, price_unit=False, notes=False):
2110+ name=False, price_unit=False, notes=False, state=False, old_price_unit=0.00, nomen_manda_0=False,
2111+ comment='', context=None):
2112 '''
2113 if the product is short shelf life we display a warning
2114 '''
2115 # call to super
2116- result = super(purchase_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty, uom,
2117+ result = super(purchase_order_line, self).product_id_on_change(cr, uid, ids, pricelist, product, qty, uom,
2118 partner_id, date_order, fiscal_position, date_planned,
2119- name, price_unit, notes)
2120+ name, price_unit, notes, state, old_price_unit, nomen_manda_0, comment, context)
2121
2122 # if the product is short shelf life, display a warning
2123 if product:
2124 prod_obj = self.pool.get('product.product')
2125- if prod_obj.browse(cr, uid, product).short_shelf_life:
2126+ if prod_obj.browse(cr, uid, product).is_ssl:
2127 warning = {
2128 'title': 'Short Shelf Life product',
2129 'message': _(SHORT_SHELF_LIFE_MESS)
2130@@ -183,7 +188,7 @@
2131 for obj in self.browse(cr, uid, ids, context=context):
2132 for line in obj.order_line:
2133 # log the message
2134- if line.product_id.short_shelf_life:
2135+ if line.product_id.is_ssl:
2136 # log the message
2137 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
2138
2139@@ -276,7 +281,7 @@
2140 product_obj = self.pool.get('product.product')
2141 product_id = vals.get('product_id', False)
2142 if product_id:
2143- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2144+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2145 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
2146
2147 return new_id
2148@@ -293,7 +298,7 @@
2149 product_obj = self.pool.get('product.product')
2150 product_id = vals.get('product_id', False)
2151 if product_id:
2152- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2153+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2154 for obj in self.browse(cr, uid, ids, context=context):
2155 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
2156
2157@@ -525,7 +530,7 @@
2158 product_obj = self.pool.get('product.product')
2159 product_id = vals.get('product_id', False)
2160 if product_id:
2161- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2162+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2163 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
2164
2165 return new_id
2166@@ -542,7 +547,7 @@
2167 product_obj = self.pool.get('product.product')
2168 product_id = vals.get('product_id', False)
2169 if product_id:
2170- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2171+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2172 for obj in self.browse(cr, uid, ids, context=context):
2173 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
2174
2175@@ -566,7 +571,7 @@
2176 product_obj = self.pool.get('product.product')
2177 product_id = vals.get('product_id', False)
2178 if product_id:
2179- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2180+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2181 self.log(cr, uid, new_id, _(SHORT_SHELF_LIFE_MESS))
2182
2183 return new_id
2184@@ -586,7 +591,7 @@
2185 product_obj = self.pool.get('product.product')
2186 product_id = vals.get('product_id', False)
2187 if product_id:
2188- if product_obj.browse(cr, uid, product_id, context=context).short_shelf_life:
2189+ if product_obj.browse(cr, uid, product_id, context=context).is_ssl:
2190 for obj in self.browse(cr, uid, ids, context=context):
2191 self.log(cr, uid, obj.id, _(SHORT_SHELF_LIFE_MESS))
2192
2193@@ -640,10 +645,12 @@
2194
2195 for move in self.browse(cr, uid, ids, context=context):
2196 if move.product_id:
2197- if move.product_id.heat_sensitive_item:
2198- result[move.id] = 'KC'
2199- elif move.product_id.dangerous_goods:
2200- result[move.id] = 'DG'
2201+ if move.product_id.kc_txt:
2202+ result[move.id] += move.product_id.is_kc and 'KC' or 'KC ?'
2203+ if move.product_id.dg_txt:
2204+ if result[move.id]:
2205+ result[move.id] += ' / '
2206+ result[move.id] += move.product_id.is_dg and 'DG' or 'DG ?'
2207
2208 return result
2209
2210@@ -751,17 +758,13 @@
2211
2212 for obj in self.browse(cr, uid, ids, context=context):
2213 # keep cool
2214- if obj.product_id.heat_sensitive_item:
2215- result[obj.id]['kc_check'] = True
2216+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2217 # ssl
2218- if obj.product_id.short_shelf_life:
2219- result[obj.id]['ssl_check'] = True
2220+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2221 # dangerous goods
2222- if obj.product_id.dangerous_goods:
2223- result[obj.id]['dg_check'] = True
2224+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2225 # narcotic
2226- if obj.product_id.narcotic:
2227- result[obj.id]['np_check'] = True
2228+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2229 # lot management
2230 if obj.product_id.batch_management:
2231 result[obj.id]['lot_check'] = True
2232@@ -788,14 +791,75 @@
2233 # if prodlot needs to be mandatory, add 'required': ['|', ('hidden_batch_management_mandatory','=',True), ('hidden_perishable_mandatory','=',True)] in attrs
2234 'hidden_batch_management_mandatory': fields.boolean(string='Hidden Flag for Batch Management product',),
2235 'hidden_perishable_mandatory': fields.boolean(string='Hidden Flag for Perishable product',),
2236- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2237- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2238- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2239- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2240- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2241- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2242- 'kit_check': fields.function(_get_checks_all, method=True, string='Kit', type='boolean', readonly=True, multi="m"),
2243- '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),
2244+ 'kc_check': fields.function(
2245+ _get_checks_all,
2246+ method=True,
2247+ string='KC',
2248+ type='char',
2249+ size=8,
2250+ readonly=True,
2251+ multi="m",
2252+ ),
2253+ 'ssl_check': fields.function(
2254+ _get_checks_all,
2255+ method=True,
2256+ string='SSL',
2257+ type='char',
2258+ size=8,
2259+ readonly=True,
2260+ multi="m",
2261+ ),
2262+ 'dg_check': fields.function(
2263+ _get_checks_all,
2264+ method=True,
2265+ string='DG',
2266+ type='char',
2267+ size=8,
2268+ readonly=True,
2269+ multi="m",
2270+ ),
2271+ 'np_check': fields.function(
2272+ _get_checks_all,
2273+ method=True,
2274+ string='CS',
2275+ type='char',
2276+ size=8,
2277+ readonly=True,
2278+ multi="m",
2279+ ),
2280+ 'lot_check': fields.function(
2281+ _get_checks_all,
2282+ method=True,
2283+ string='B.Num',
2284+ type='boolean',
2285+ readonly=True,
2286+ multi="m",
2287+ ),
2288+ 'exp_check': fields.function(
2289+ _get_checks_all,
2290+ method=True,
2291+ string='Exp',
2292+ type='boolean',
2293+ readonly=True,
2294+ multi="m",
2295+ ),
2296+ 'kit_check': fields.function(
2297+ _get_checks_all,
2298+ method=True,
2299+ string='Kit',
2300+ type='boolean',
2301+ readonly=True,
2302+ multi="m",
2303+ ),
2304+ 'prodlot_id': fields.many2one(
2305+ 'stock.production.lot',
2306+ 'Batch',
2307+ states={
2308+ 'done': [('readonly', True)],
2309+ },
2310+ help="Batch number is used to put a serial number on the production",
2311+ select=True,
2312+ ),
2313 }
2314
2315 _constraints = [
2316@@ -1074,17 +1138,13 @@
2317
2318 for obj in self.browse(cr, uid, ids, context=context):
2319 # keep cool
2320- if obj.product_id.heat_sensitive_item:
2321- result[obj.id]['kc_check'] = True
2322+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2323 # ssl
2324- if obj.product_id.short_shelf_life:
2325- result[obj.id]['ssl_check'] = True
2326+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2327 # dangerous goods
2328- if obj.product_id.dangerous_goods:
2329- result[obj.id]['dg_check'] = True
2330+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2331 # narcotic
2332- if obj.product_id.narcotic:
2333- result[obj.id]['np_check'] = True
2334+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2335 # lot management
2336 if obj.product_id.batch_management:
2337 result[obj.id]['lot_check'] = True
2338@@ -1163,30 +1223,90 @@
2339
2340 return res
2341
2342- _columns = {'check_type': fields.function(_get_false, fnct_search=search_check_type, string='Check Type', type="boolean", readonly=True, method=True),
2343- # readonly is True, the user is only allowed to create standard lots - internal lots are system-created
2344- 'type': fields.selection([('standard', 'Standard'),('internal', 'Internal'),], string="Type", readonly=True),
2345- #'expiry_date': fields.date('Expiry Date'),
2346- 'name': fields.char('Batch Number', size=1024, required=True, help="Unique batch number, will be displayed as: PREFIX/SERIAL [INT_REF]"),
2347- 'date': fields.datetime('Auto Creation Date', required=True),
2348- 'sequence_id': fields.many2one('ir.sequence', 'Batch Sequence', required=True,),
2349- 'stock_virtual': fields.function(_get_stock_virtual, method=True, type="float", string="Available Stock", select=True,
2350- help="Current available quantity of products with this Batch Numbre Number in company warehouses",
2351- digits_compute=dp.get_precision('Product UoM'), readonly=True,
2352- fnct_search=_stock_search_virtual,),
2353- 'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Real Stock", select=True,
2354- help="Current real quantity of products with this Batch Number in company warehouses",
2355- digits_compute=dp.get_precision('Product UoM')),
2356- 'src_product_id': fields.function(_get_dummy, fnct_search=_src_product, method=True, type="boolean", string="By product"),
2357- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2358- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2359- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2360- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2361- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2362- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2363- 'delete_ok': fields.function(_get_delete_ok, method=True, string='Possible deletion ?', type='boolean', readonly=True),
2364- 'is_expired': fields.function(_is_expired, method=True, string='Expired ?', type='boolean', store=False, readonly=True),
2365- }
2366+ _columns = {
2367+ 'check_type': fields.function(_get_false, fnct_search=search_check_type, string='Check Type', type="boolean", readonly=True, method=True),
2368+ # readonly is True, the user is only allowed to create standard lots - internal lots are system-created
2369+ 'type': fields.selection([('standard', 'Standard'),('internal', 'Internal'),], string="Type", readonly=True),
2370+ #'expiry_date': fields.date('Expiry Date'),
2371+ 'name': fields.char('Batch Number', size=1024, required=True, help="Unique batch number, will be displayed as: PREFIX/SERIAL [INT_REF]"),
2372+ 'date': fields.datetime('Auto Creation Date', required=True),
2373+ 'sequence_id': fields.many2one('ir.sequence', 'Batch Sequence', required=True,),
2374+ 'stock_virtual': fields.function(_get_stock_virtual, method=True, type="float", string="Available Stock", select=True,
2375+ help="Current available quantity of products with this Batch Numbre Number in company warehouses",
2376+ digits_compute=dp.get_precision('Product UoM'), readonly=True,
2377+ fnct_search=_stock_search_virtual,),
2378+ 'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Real Stock", select=True,
2379+ help="Current real quantity of products with this Batch Number in company warehouses",
2380+ digits_compute=dp.get_precision('Product UoM')),
2381+ 'src_product_id': fields.function(_get_dummy, fnct_search=_src_product, method=True, type="boolean", string="By product"),
2382+ 'kc_check': fields.function(
2383+ _get_checks_all,
2384+ method=True,
2385+ string='KC',
2386+ type='char',
2387+ size=8,
2388+ readonly=True,
2389+ multi="m",
2390+ ),
2391+ 'ssl_check': fields.function(
2392+ _get_checks_all,
2393+ method=True,
2394+ string='SSL',
2395+ type='char',
2396+ size=8,
2397+ readonly=True,
2398+ multi="m",
2399+ ),
2400+ 'dg_check': fields.function(
2401+ _get_checks_all,
2402+ method=True,
2403+ string='DG',
2404+ type='char',
2405+ size=8,
2406+ readonly=True,
2407+ multi="m",
2408+ ),
2409+ 'np_check': fields.function(
2410+ _get_checks_all,
2411+ method=True,
2412+ string='CS',
2413+ type='char',
2414+ size=8,
2415+ readonly=True,
2416+ multi="m",
2417+ ),
2418+ 'lot_check': fields.function(
2419+ _get_checks_all,
2420+ method=True,
2421+ string='B.Num',
2422+ type='boolean',
2423+ readonly=True,
2424+ multi="m",
2425+ ),
2426+ 'exp_check': fields.function(
2427+ _get_checks_all,
2428+ method=True,
2429+ string='Exp',
2430+ type='boolean',
2431+ readonly=True,
2432+ multi="m",
2433+ ),
2434+ 'delete_ok': fields.function(
2435+ _get_delete_ok,
2436+ method=True,
2437+ string='Possible deletion ?',
2438+ type='boolean',
2439+ readonly=True,
2440+ ),
2441+ 'is_expired': fields.function(
2442+ _is_expired,
2443+ method=True,
2444+ string='Expired ?',
2445+ type='boolean',
2446+ store=False,
2447+ readonly=True,
2448+ ),
2449+ }
2450
2451 _defaults = {'type': 'standard',
2452 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'stock.production.lot', context=c),
2453@@ -1705,9 +1825,9 @@
2454 result.setdefault('value', {})['expiry_date'] = False
2455 result.setdefault('value', {})['lot_check'] = False
2456 result.setdefault('value', {})['exp_check'] = False
2457- result.setdefault('value', {})['dg_check'] = False
2458- result.setdefault('value', {})['kc_check'] = False
2459- result.setdefault('value', {})['np_check'] = False
2460+ result.setdefault('value', {})['dg_check'] = ''
2461+ result.setdefault('value', {})['kc_check'] = ''
2462+ result.setdefault('value', {})['np_check'] = ''
2463 # reset the hidden flags
2464 result.setdefault('value', {})['hidden_batch_management_mandatory'] = False
2465 result.setdefault('value', {})['hidden_perishable_mandatory'] = False
2466@@ -1725,17 +1845,13 @@
2467 result.setdefault('value', {})['hidden_perishable_mandatory'] = True
2468 result.setdefault('value', {})['exp_check'] = True
2469 # keep cool
2470- if product_obj.heat_sensitive_item:
2471- result.setdefault('value', {})['kc_check'] = True
2472+ result.setdefault('value', {})['kc_check'] = product_obj.kc_txt
2473 # ssl
2474- if product_obj.short_shelf_life:
2475- result.setdefault('value', {})['ssl_check'] = True
2476+ result.setdefault('value', {})['ssl_check'] = product_obj.ssl_txt
2477 # dangerous goods
2478- if product_obj.dangerous_goods:
2479- result.setdefault('value', {})['dg_check'] = True
2480+ result.setdefault('value', {})['dg_check'] = product_obj.dg_txt
2481 # narcotic
2482- if product_obj.narcotic:
2483- result.setdefault('value', {})['np_check'] = True
2484+ result.setdefault('value', {})['np_check'] = product_obj.cs_txt
2485 # if not product, result is 0.0 by super
2486 # compute qty
2487 result = self.common_on_change(cr, uid, ids, location_id, product, prod_lot_id, uom, to_date, result=result)
2488@@ -1802,17 +1918,13 @@
2489
2490 for obj in self.browse(cr, uid, ids, context=context):
2491 # keep cool
2492- if obj.product_id.heat_sensitive_item:
2493- result[obj.id]['kc_check'] = True
2494+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2495 # ssl
2496- if obj.product_id.short_shelf_life:
2497- result[obj.id]['ssl_check'] = True
2498+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2499 # dangerous goods
2500- if obj.product_id.dangerous_goods:
2501- result[obj.id]['dg_check'] = True
2502+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2503 # narcotic
2504- if obj.product_id.narcotic:
2505- result[obj.id]['np_check'] = True
2506+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2507 # lot management
2508 if obj.product_id.batch_management:
2509 result[obj.id]['lot_check'] = True
2510@@ -1924,15 +2036,77 @@
2511 'prod_lot_id': fields.many2one('stock.production.lot', 'Batch', domain="[('product_id','=',product_id)]"),
2512 'expiry_date': fields.date(string='Expiry Date'),
2513 'type_check': fields.char(string='Type Check', size=1024,),
2514- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2515- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2516- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2517- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2518- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2519- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2520- 'has_problem': fields.function(_get_checks_all, method=True, string='Has problem', type='boolean', readonly=True, multi="m"),
2521- 'duplicate_line': fields.function(_get_checks_all, method=True, string='Duplicate line', type='boolean', readonly=True, multi="m"),
2522- 'dont_move': fields.boolean(string='Don\'t create stock.move for this line'),
2523+ 'kc_check': fields.function(
2524+ _get_checks_all,
2525+ method=True,
2526+ string='KC',
2527+ type='char',
2528+ size=8,
2529+ readonly=True,
2530+ multi="m",
2531+ ),
2532+ 'ssl_check': fields.function(
2533+ _get_checks_all,
2534+ method=True,
2535+ string='SSL',
2536+ type='char',
2537+ size=8,
2538+ readonly=True,
2539+ multi="m",
2540+ ),
2541+ 'dg_check': fields.function(
2542+ _get_checks_all,
2543+ method=True,
2544+ string='DG',
2545+ type='char',
2546+ size=8,
2547+ readonly=True,
2548+ multi="m",
2549+ ),
2550+ 'np_check': fields.function(
2551+ _get_checks_all,
2552+ method=True,
2553+ string='CS',
2554+ type='char',
2555+ size=8,
2556+ readonly=True,
2557+ multi="m",
2558+ ),
2559+ 'lot_check': fields.function(
2560+ _get_checks_all,
2561+ method=True,
2562+ string='B.Num',
2563+ type='boolean',
2564+ readonly=True,
2565+ multi="m",
2566+ ),
2567+ 'exp_check': fields.function(
2568+ _get_checks_all,
2569+ method=True,
2570+ string='Exp',
2571+ type='boolean',
2572+ readonly=True,
2573+ multi="m",
2574+ ),
2575+ 'has_problem': fields.function(
2576+ _get_checks_all,
2577+ method=True,
2578+ string='Has problem',
2579+ type='boolean',
2580+ readonly=True,
2581+ multi="m",
2582+ ),
2583+ 'duplicate_line': fields.function(
2584+ _get_checks_all,
2585+ method=True,
2586+ string='Duplicate line',
2587+ type='boolean',
2588+ readonly=True,
2589+ multi="m",
2590+ ),
2591+ 'dont_move': fields.boolean(
2592+ string='Don\'t create stock.move for this line',
2593+ ),
2594 }
2595
2596 _defaults = {# in is used, meaning a new prod lot will be created if the specified expiry date does not exist
2597
2598=== modified file 'bin/addons/specific_rules/specific_rules_view.xml'
2599--- bin/addons/specific_rules/specific_rules_view.xml 2015-10-13 12:25:48 +0000
2600+++ bin/addons/specific_rules/specific_rules_view.xml 2016-03-18 10:42:44 +0000
2601@@ -55,7 +55,7 @@
2602 <data>
2603
2604 <field name="life_time" position="replace">
2605- <field name="life_time" attrs="{'required':[('short_shelf_life', '=', True)]}" />
2606+ <field name="life_time" attrs="{'required':[('short_shelf_life', '=', 'True')]}" />
2607 </field>
2608 </data>
2609 </field>
2610
2611=== modified file 'bin/addons/specific_rules/wizard/stock_partial_move.py'
2612--- bin/addons/specific_rules/wizard/stock_partial_move.py 2013-11-22 15:06:16 +0000
2613+++ bin/addons/specific_rules/wizard/stock_partial_move.py 2016-03-18 10:42:44 +0000
2614@@ -84,17 +84,13 @@
2615 result[obj.id]['batch_number_check'] = obj.product_id.batch_management
2616 result[obj.id]['expiry_date_check'] = obj.product_id.perishable
2617 # keep cool
2618- if obj.product_id.heat_sensitive_item:
2619- result[obj.id]['kc_check'] = True
2620+ result[obj.id]['kc_check'] = obj.product_id.kc_txt
2621 # ssl
2622- if obj.product_id.short_shelf_life:
2623- result[obj.id]['ssl_check'] = True
2624+ result[obj.id]['ssl_check'] = obj.product_id.ssl_txt
2625 # dangerous goods
2626- if obj.product_id.dangerous_goods:
2627- result[obj.id]['dg_check'] = True
2628+ result[obj.id]['dg_check'] = obj.product_id.dg_txt
2629 # narcotic
2630- if obj.product_id.narcotic:
2631- result[obj.id]['np_check'] = True
2632+ result[obj.id]['np_check'] = obj.product_id.cs_txt
2633 # type of picking
2634 result[obj.id]['type_check'] = obj.move_id.type
2635 # lot management
2636@@ -188,16 +184,80 @@
2637 'expiry_date_check': fields.function(_get_checks_all, method=True, string='Expiry Date Check', type='boolean', readonly=True, multi="m"),
2638 'type_check': fields.function(_get_checks_all, method=True, string='Picking Type Check', type='char', readonly=True, multi="m"),
2639 'expiry_date': fields.date('Expiry Date'),
2640- 'kc_check': fields.function(_get_checks_all, method=True, string='KC', type='boolean', readonly=True, multi="m"),
2641- 'ssl_check': fields.function(_get_checks_all, method=True, string='SSL', type='boolean', readonly=True, multi="m"),
2642- 'dg_check': fields.function(_get_checks_all, method=True, string='DG', type='boolean', readonly=True, multi="m"),
2643- 'np_check': fields.function(_get_checks_all, method=True, string='NP', type='boolean', readonly=True, multi="m"),
2644- 'lot_check': fields.function(_get_checks_all, method=True, string='B.Num', type='boolean', readonly=True, multi="m"),
2645- 'exp_check': fields.function(_get_checks_all, method=True, string='Exp', type='boolean', readonly=True, multi="m"),
2646- 'location_id': fields.related('move_id', 'location_id', type='many2one', relation='stock.location', string='Source Location', readonly=True),
2647- 'quantity_ordered': fields.float('Quantity ordered'),
2648- 'uom_ordered': fields.many2one('product.uom', string='UoM ordered', readonly=True),
2649- 'uom_category': fields.related('uom_ordered', 'category_id', type='many2one', relation='product.uom.categ'),
2650+ 'kc_check': fields.function(
2651+ _get_checks_all,
2652+ method=True,
2653+ string='KC',
2654+ type='char',
2655+ size=8,
2656+ readonly=True,
2657+ multi="m",
2658+ ),
2659+ 'ssl_check': fields.function(
2660+ _get_checks_all,
2661+ method=True,
2662+ string='SSL',
2663+ type='char',
2664+ size=8,
2665+ readonly=True,
2666+ multi="m",
2667+ ),
2668+ 'dg_check': fields.function(
2669+ _get_checks_all,
2670+ method=True,
2671+ string='DG',
2672+ type='char',
2673+ size=8,
2674+ readonly=True,
2675+ multi="m",
2676+ ),
2677+ 'np_check': fields.function(
2678+ _get_checks_all,
2679+ method=True,
2680+ string='CS',
2681+ type='char',
2682+ size=8,
2683+ readonly=True,
2684+ multi="m",
2685+ ),
2686+ 'lot_check': fields.function(
2687+ _get_checks_all,
2688+ method=True,
2689+ string='B.Num',
2690+ type='boolean',
2691+ readonly=True,
2692+ multi="m",
2693+ ),
2694+ 'exp_check': fields.function(
2695+ _get_checks_all,
2696+ method=True,
2697+ string='Exp',
2698+ type='boolean',
2699+ readonly=True,
2700+ multi="m",
2701+ ),
2702+ 'location_id': fields.related(
2703+ 'move_id',
2704+ 'location_id',
2705+ type='many2one',
2706+ relation='stock.location',
2707+ string='Source Location',
2708+ readonly=True,
2709+ ),
2710+ 'quantity_ordered': fields.float(
2711+ 'Quantity ordered',
2712+ ),
2713+ 'uom_ordered': fields.many2one(
2714+ 'product.uom',
2715+ string='UoM ordered',
2716+ readonly=True,
2717+ ),
2718+ 'uom_category': fields.related(
2719+ 'uom_ordered',
2720+ 'category_id',
2721+ type='many2one',
2722+ relation='product.uom.categ',
2723+ ),
2724 }
2725
2726 stock_partial_move_memory_out()
2727
2728=== modified file 'bin/addons/specific_rules/wizard/stock_partial_picking.py'
2729--- bin/addons/specific_rules/wizard/stock_partial_picking.py 2014-02-24 15:41:57 +0000
2730+++ bin/addons/specific_rules/wizard/stock_partial_picking.py 2016-03-18 10:42:44 +0000
2731@@ -48,13 +48,13 @@
2732 type = False
2733 contains_kc = False
2734 contains_dg = False
2735-
2736+
2737 for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
2738 type = pick.type
2739 for m in pick.move_lines:
2740- if m.product_id.heat_sensitive_item:
2741+ if m.product_id.is_kc:
2742 contains_kc = True
2743- if m.product_id.dangerous_goods:
2744+ if m.product_id.is_dg:
2745 contains_dg = True
2746
2747 if contains_kc and contains_dg:
2748
2749=== modified file 'bin/addons/stock_forecast/wizard/stock_forecast.py'
2750--- bin/addons/stock_forecast/wizard/stock_forecast.py 2015-02-05 16:24:37 +0000
2751+++ bin/addons/stock_forecast/wizard/stock_forecast.py 2016-03-18 10:42:44 +0000
2752@@ -130,10 +130,9 @@
2753 values['product_family_info_id'] = wiz.product_id.nomen_manda_2.id
2754 values['procurement_method'] = wiz.product_id.procure_method
2755 values['supply_method'] = wiz.product_id.supply_method
2756- if wiz.product_id.heat_sensitive_item:
2757- values['keep_cool'] = True
2758- values['short_shelf_life'] = wiz.product_id.short_shelf_life
2759- values['dangerous_goods'] = wiz.product_id.dangerous_goods
2760+ values['keep_cool'] = wiz.product_id.is_kc
2761+ values['short_shelf_life'] = wiz.product_id.is_ssl
2762+ values['dangerous_goods'] = wiz.product_id.is_dg
2763 values['justification_code_id'] = wiz.product_id.justification_code_id.id
2764 return result
2765
2766
2767=== modified file 'bin/addons/stock_override/stock.py'
2768--- bin/addons/stock_override/stock.py 2016-03-14 10:07:38 +0000
2769+++ bin/addons/stock_override/stock.py 2016-03-18 10:42:44 +0000
2770@@ -2154,13 +2154,6 @@
2771 result = []
2772 for move in self.browse(cr, uid, ids, context=context):
2773 # add this move into the list of result
2774- dg_check_flag = ''
2775- if move.dg_check:
2776- dg_check_flag = 'x'
2777-
2778- np_check_flag = ''
2779- if move.np_check:
2780- np_check_flag = 'x'
2781 sub_total = move.product_qty * move.product_id.standard_price
2782
2783 currency = ''
2784@@ -2178,8 +2171,8 @@
2785 'origin': move.origin,
2786 'expired_date': move.expired_date,
2787 'prodlot_id': move.prodlot_id.name,
2788- 'dg_check': dg_check_flag,
2789- 'np_check': np_check_flag,
2790+ 'dg_check': move.product_id and move.product_id.dg_txt or '',
2791+ 'np_check': move.product_id and move.product_id.cs_txt or '',
2792 'uom': move.product_uom.name,
2793 'prod_qty': move.product_qty,
2794 })
2795
2796=== modified file 'bin/addons/sync_so/sale.py'
2797--- bin/addons/sync_so/sale.py 2016-03-03 11:05:04 +0000
2798+++ bin/addons/sync_so/sale.py 2016-03-18 10:42:44 +0000
2799@@ -382,6 +382,7 @@
2800
2801 if original_id:
2802 orig_partner_name = self.browse(cr, uid, original_id, context=context).partner_id.name
2803+<<<<<<< TREE
2804
2805 # Generate messages for cancel lines
2806 available_solc_ids = solc_obj.search(cr, uid, eval(solccl_rule.domain),
2807@@ -398,6 +399,13 @@
2808 order='NO_ORDER', context=context)
2809 if nfo_model_obj and nfo_rule and original_id in available_nfo_ids:
2810 generate_msg_to_send(nfo_rule, nfo_model_obj, original_id, orig_partner_name)
2811+=======
2812+ if nfo_model_obj and nfo_rule:
2813+ available_nfo_ids = self.search(cr, uid, eval(nfo_rule.domain),
2814+ order='NO_ORDER', context=context)
2815+ if original_id in available_nfo_ids:
2816+ generate_msg_to_send(nfo_rule, nfo_model_obj, original_id, orig_partner_name)
2817+>>>>>>> MERGE-SOURCE
2818 if vfo_model_obj and vfo_rule:
2819 generate_msg_to_send(vfo_rule, vfo_model_obj, original_id, orig_partner_name)
2820
2821
2822=== modified file 'bin/osv/orm.py'
2823--- bin/osv/orm.py 2016-02-24 10:21:02 +0000
2824+++ bin/osv/orm.py 2016-03-18 10:42:44 +0000
2825@@ -912,7 +912,8 @@
2826 res = value and float(value.replace(',','.')) or 0.0
2827 elif field_type == 'selection':
2828 for key, val in fields_def[field[len(prefix)]]['selection']:
2829- if value in [tools.ustr(key), tools.ustr(val)]:
2830+ if value in [tools.ustr(key), tools.ustr(val)] or \
2831+ tools.ustr(value) in [tools.ustr(key), tools.ustr(val)]:
2832 res = key
2833 break
2834 if not value:
2835@@ -2663,6 +2664,18 @@
2836 self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
2837 self._table, column['attname'])
2838
2839+ def execute_migration(self, cr, moved_column, new_column):
2840+ """
2841+ On change type of column, make a migration of data. The old values
2842+ are moved to a new column suffixed by _movedX.
2843+ This method must be overriden on needed objects.
2844+ :param cr: Cursor to the database
2845+ :param moved_column: The renamed old column
2846+ :param new_column: The column with the new type
2847+ :return: Nothing
2848+ """
2849+ pass
2850+
2851 def _auto_init(self, cr, context=None):
2852 if context is None:
2853 context = {}
2854@@ -2867,6 +2880,7 @@
2855 cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
2856 self.__schema.debug("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !",
2857 self._table, k, f_pg_type, f._type, newname)
2858+ self.execute_migration(cr, newname, k)
2859
2860 # if the field is required and hasn't got a NOT NULL constraint
2861 if f.required and f_pg_notnull == 0:

Subscribers

People subscribed via source and target branches

to all changes: