Merge lp:~jfb-tempo-consulting/unifield-server/US-6374 into lp:unifield-server
- US-6374
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5765 |
Proposed branch: | lp:~jfb-tempo-consulting/unifield-server/US-6374 |
Merge into: | lp:unifield-server |
Diff against target: |
1337 lines (+548/-170) (has conflicts) 15 files modified
bin/addons/base/rng/view.rng (+1/-0) bin/addons/delivery_mechanism/delivery_mechanism.py (+25/-6) bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py (+98/-16) bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py (+112/-24) bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml (+27/-8) bin/addons/msf_outgoing/wizard/picking_processor.py (+35/-0) bin/addons/msf_outgoing/wizard/split_move_processor.py (+5/-0) bin/addons/msf_printed_documents/report/report_reception.py (+11/-5) bin/addons/msf_printed_documents/report/report_reception.rml (+103/-37) bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv (+4/-0) bin/addons/order_types/stock.py (+6/-1) bin/addons/sync_client/message.py (+25/-14) bin/addons/sync_client/orm.py (+3/-1) bin/addons/sync_so/picking.py (+91/-58) bin/report/report_sxw.py (+2/-0) Text conflict in bin/addons/msf_printed_documents/report/report_reception.py Text conflict in bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv |
To merge this branch: | bzr merge lp:~jfb-tempo-consulting/unifield-server/US-6374 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+379948@code.launchpad.net |
Commit message
Description of the change
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/base/rng/view.rng' |
2 | --- bin/addons/base/rng/view.rng 2020-02-28 11:04:39 +0000 |
3 | +++ bin/addons/base/rng/view.rng 2020-08-05 12:54:43 +0000 |
4 | @@ -596,6 +596,7 @@ |
5 | <rng:optional><rng:attribute name="help"/></rng:optional> |
6 | <rng:optional><rng:attribute name="default_focus"/></rng:optional> |
7 | <rng:optional><rng:attribute name="header"/></rng:optional> |
8 | + <rng:optional><rng:attribute name="set_ids"/></rng:optional> |
9 | <rng:zeroOrMore> |
10 | <rng:choice> |
11 | <rng:ref name="form" /> |
12 | |
13 | === modified file 'bin/addons/delivery_mechanism/delivery_mechanism.py' |
14 | --- bin/addons/delivery_mechanism/delivery_mechanism.py 2020-03-20 14:08:02 +0000 |
15 | +++ bin/addons/delivery_mechanism/delivery_mechanism.py 2020-08-05 12:54:43 +0000 |
16 | @@ -711,11 +711,13 @@ |
17 | |
18 | return res |
19 | |
20 | - def do_incoming_shipment(self, cr, uid, wizard_ids, context=None): |
21 | + def do_incoming_shipment(self, cr, uid, wizard_ids, shipment_ref=False, context=None, with_ppl=False): |
22 | """ |
23 | Take the data in wizard_ids and lines of stock.incoming.processor and |
24 | do the split of stock.move according to the data. |
25 | """ |
26 | + |
27 | + |
28 | # Objects |
29 | inc_proc_obj = self.pool.get('stock.incoming.processor') |
30 | move_proc_obj = self.pool.get('stock.move.in.processor') |
31 | @@ -802,7 +804,7 @@ |
32 | line = False |
33 | for line in move_proc_obj.browse(cr, uid, proc_ids, context=context): |
34 | values = self._get_values_from_line(cr, uid, move, line, db_data_dict, context=context) |
35 | - if context.get('do_not_process_incoming') and line.pack_info_id: |
36 | + if (sync_in or context.get('do_not_process_incoming')) and line.pack_info_id: |
37 | # we are processing auto import IN, we must register pack_info data |
38 | values['pack_info_id'] = line.pack_info_id.id |
39 | |
40 | @@ -851,7 +853,7 @@ |
41 | if out_values.get('location_dest_id', False): |
42 | out_values.pop('location_dest_id') |
43 | |
44 | - if line.pack_info_id: |
45 | + if with_ppl and line.pack_info_id: |
46 | all_pack_info[line.pack_info_id.id] = True |
47 | remaining_out_qty = line.quantity |
48 | out_move = None |
49 | @@ -981,7 +983,16 @@ |
50 | processed_out_moves_by_exp.setdefault(line.prodlot_id and line.prodlot_id.life_date or False, []).append(out_move.id) |
51 | else: |
52 | # Just update the data of the initial out move |
53 | - processed_qty = lst_out_move is out_moves[-1] and uom_partial_qty - minus_qty or out_move.product_qty |
54 | + if lst_out_move is out_moves[-1]: |
55 | + processed_qty = uom_partial_qty - minus_qty |
56 | + if processed_qty <= 0: |
57 | + processed_qty = out_move.product_qty |
58 | + elif context.get('auto_import_ok'): |
59 | + # IN pre-processing : do not add extra qty in OUT, it will be added later on IN processing |
60 | + processed_qty = out_move.product_qty |
61 | + else: |
62 | + processed_qty = out_move.product_qty |
63 | + |
64 | out_values.update({ |
65 | 'product_qty': processed_qty, |
66 | 'product_uom': line.uom_id.id, |
67 | @@ -1053,6 +1064,7 @@ |
68 | }) |
69 | |
70 | backorder_id = False |
71 | + backorder_ids = False |
72 | if context.get('for_dpo', False) and picking_dict['purchase_id']: |
73 | # Look for an available IN for the same purchase order in case of DPO |
74 | backorder_ids = self.search(cr, uid, [ |
75 | @@ -1060,8 +1072,15 @@ |
76 | ('in_dpo', '=', True), |
77 | ('state', '=', 'assigned'), |
78 | ], limit=1, context=context) |
79 | - if backorder_ids: |
80 | - backorder_id = backorder_ids[0] |
81 | + elif sync_in and picking_dict['purchase_id'] and shipment_ref: |
82 | + backorder_ids = self.search(cr, uid, [ |
83 | + ('purchase_id', '=', picking_dict['purchase_id'][0]), |
84 | + ('shipment_ref', '=', shipment_ref), |
85 | + ('state', '=', 'shipped'), |
86 | + ], limit=1, context=context) |
87 | + |
88 | + if backorder_ids: |
89 | + backorder_id = backorder_ids[0] |
90 | |
91 | backorder_name = picking_dict['name'] |
92 | if not backorder_id: |
93 | |
94 | === modified file 'bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py' |
95 | --- bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2020-07-02 15:09:34 +0000 |
96 | +++ bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2020-08-05 12:54:43 +0000 |
97 | @@ -245,7 +245,7 @@ |
98 | 'context': context, |
99 | } |
100 | |
101 | - def launch_import(self, cr, uid, ids, context=None): |
102 | + def launch_import(self, cr, uid, ids, context=None, with_ppl=False): |
103 | ''' |
104 | ''' |
105 | if context is None: |
106 | @@ -254,10 +254,10 @@ |
107 | if isinstance(ids, (int, long)): |
108 | ids = [ids] |
109 | |
110 | - return self._import(cr, uid, ids, context=context) |
111 | + return self._import(cr, uid, ids, context=context, with_ppl=with_ppl) |
112 | |
113 | def launch_import_pack(self, cr, uid, ids, context=None): |
114 | - return self.launch_import(cr, uid, ids, context) |
115 | + return self.launch_import(cr, uid, ids, context, with_ppl=True) |
116 | |
117 | def populate(self, cr, uid, import_id, picking_id, context=None): |
118 | if context is None: |
119 | @@ -519,6 +519,50 @@ |
120 | |
121 | return values, nb_line, error |
122 | |
123 | + def error_pick_already_processed(self, cr, uid, sol_id_sum, sol_id_to_wiz_line, context): |
124 | + if not sol_id_sum: |
125 | + return '' |
126 | + cr.execute(''' |
127 | + select m.sale_line_id, sum(m.product_qty) |
128 | + from stock_move m, stock_picking p |
129 | + where |
130 | + m.picking_id = p.id and |
131 | + p.type = 'out' and |
132 | + p.subtype = 'picking' and |
133 | + p.state = 'draft' and |
134 | + m.state in ('assigned', 'confirmed') and |
135 | + m.sale_line_id in %s |
136 | + group by |
137 | + m.sale_line_id |
138 | + ''', (tuple(sol_id_sum.keys()),)) |
139 | + extra_qty = {} |
140 | + for x in cr.fetchall(): |
141 | + if x[1] < sol_id_sum[x[0]]: |
142 | + extra_qty[x[0]] = sol_id_sum[x[0]] - x[1] |
143 | + |
144 | + already_process = {} |
145 | + if extra_qty: |
146 | + cr.execute(''' |
147 | + select m.sale_line_id, sum(m.product_qty) |
148 | + from stock_move m, stock_picking p |
149 | + where |
150 | + m.picking_id = p.id and |
151 | + p.type = 'out' and |
152 | + p.state not in ('draft', 'cancel') and |
153 | + m.sale_line_id in %s |
154 | + group by |
155 | + m.sale_line_id |
156 | + ''', (tuple(extra_qty.keys()),)) |
157 | + for x in cr.fetchall(): |
158 | + already_process[x[0]] = x[1] |
159 | + |
160 | + if already_process: |
161 | + details = [] |
162 | + for sol in self.pool.get('sale.order.line').browse(cr, uid, already_process.keys(), fields_to_fetch=['product_id'], context=context): |
163 | + details.append('Line number: %s, [%s] %s' % (sol_id_to_wiz_line.get(sol.id),sol.product_id.default_code, sol.product_id.name)) |
164 | + return _('Warning the following product lines have already been processed in linked OUT/Pick document, so cannot be processed here. Please remove these lines before trying to processs the movement\n%s') % ("\n".join(details)) |
165 | + return '' |
166 | + |
167 | # Simulation routing |
168 | def simulate(self, dbname, uid, ids, context=None): |
169 | ''' |
170 | @@ -966,6 +1010,27 @@ |
171 | err = _('Line %s of the Excel file: %s') % (file_line[0], err) |
172 | values_line_errors.append(err) |
173 | |
174 | + if wiz.with_pack and not context.get('auto_import_ok'): |
175 | + # check if an out line has been forced |
176 | + cr.execute(''' |
177 | + select wiz_line.line_number, pol.linked_sol_id, sum(wiz_line.imp_product_qty) |
178 | + from wizard_import_in_line_simulation_screen wiz_line |
179 | + left join wizard_import_in_simulation_screen wiz on wiz.id = wiz_line.simu_id |
180 | + left join stock_move move_in on move_in.picking_id = wiz.picking_id and move_in.line_number = wiz_line.line_number |
181 | + left join purchase_order_line pol on pol.id = move_in.purchase_line_id |
182 | + where |
183 | + (wiz_line.type_change in ('', 'split') or wiz_line.type_change is NULL) and |
184 | + wiz.id = %s |
185 | + group by wiz_line.line_number, pol.linked_sol_id |
186 | + ''', (wiz.id,)) |
187 | + sol_id_to_wiz_line = {} |
188 | + sol_id_sum = {} |
189 | + for x in cr.fetchall(): |
190 | + sol_id_to_wiz_line[x[1]] = x[0] |
191 | + sol_id_sum[x[1]] = x[2] |
192 | + error_pick = self.error_pick_already_processed(cr, uid, sol_id_sum, sol_id_to_wiz_line, context) |
193 | + if error_pick: |
194 | + values_line_errors.append(error_pick) |
195 | |
196 | # Create new lines |
197 | for in_line in new_in_lines: |
198 | @@ -1049,7 +1114,7 @@ |
199 | |
200 | return {'type': 'ir.actions.act_window_close'} |
201 | |
202 | - def _import_with_thread(self, cr, uid, partial_id, simu_id, context=None): |
203 | + def _import_with_thread(self, cr, uid, partial_id, simu_id, context=None, with_ppl=False): |
204 | inc_proc_obj = self.pool.get('stock.incoming.processor') |
205 | in_proc_obj = self.pool.get('stock.move.in.processor') |
206 | picking_obj = self.pool.get('stock.picking') |
207 | @@ -1063,7 +1128,7 @@ |
208 | prodlot_id = self.pool.get('stock.production.lot')._get_prodlot_from_expiry_date(new_cr, uid, line.expiry_date, line.product_id.id, context=context) |
209 | in_proc_obj.write(new_cr, uid, [line.id], {'prodlot_id': prodlot_id}, context=context) |
210 | |
211 | - new_picking = picking_obj.do_incoming_shipment(new_cr, uid, partial_id, context=context) |
212 | + new_picking = picking_obj.do_incoming_shipment(new_cr, uid, partial_id, context=context, with_ppl=with_ppl) |
213 | if isinstance(new_picking, (int,long)): |
214 | context['new_picking'] = new_picking |
215 | new_cr.commit() |
216 | @@ -1087,7 +1152,7 @@ |
217 | return True |
218 | |
219 | |
220 | - def _import(self, cr, uid, ids, context=None): |
221 | + def _import(self, cr, uid, ids, context=None, with_ppl=False): |
222 | ''' |
223 | Create memeory moves and return to the standard incoming processing wizard |
224 | ''' |
225 | @@ -1122,9 +1187,9 @@ |
226 | cr.commit() |
227 | if context.get('do_not_import_with_thread'): |
228 | # Auto VI IN import: do not process IN |
229 | - self._import_with_thread(cr, uid, [partial_id], simu_id.id, context=context) |
230 | + self._import_with_thread(cr, uid, [partial_id], simu_id.id, context=context, with_ppl=with_ppl) |
231 | else: |
232 | - new_thread = threading.Thread(target=self._import_with_thread, args=(cr, uid, [partial_id], simu_id.id, context)) |
233 | + new_thread = threading.Thread(target=self._import_with_thread, args=(cr, uid, [partial_id], simu_id.id, context, with_ppl)) |
234 | new_thread.start() |
235 | new_thread.join(20) |
236 | if new_thread.isAlive(): |
237 | @@ -1157,18 +1222,35 @@ |
238 | _name = 'wizard.import.in.pack.simulation.screen' |
239 | _rec_name = 'parcel_from' |
240 | |
241 | + def _get_real_total(self, cr, uid, ids, f, a, context=None): |
242 | + res = {} |
243 | + for pack in self.browse(cr, uid, ids, context=context): |
244 | + res[pack.id] = {'real_total_volume': False, 'real_total_weight': False} |
245 | + |
246 | + if pack.parcel_to and pack.parcel_from: |
247 | + nb_pack = pack.parcel_to - pack.parcel_from + 1 |
248 | + if pack.total_weight: |
249 | + res[pack.id]['real_total_weight'] = int(round(nb_pack * pack.total_weight, 0)) |
250 | + if pack.total_height and pack.total_length and pack.total_width: |
251 | + res[pack.id]['real_total_volume'] = int(round(pack.total_height * pack.total_length * pack.total_width * nb_pack / 1000, 0)) |
252 | + return res |
253 | + |
254 | _columns = { |
255 | 'wizard_id': fields.many2one('wizard.import.in.simulation.screen', 'Simu Wizard'), |
256 | - 'parcel_from': fields.integer('Parcel From'), |
257 | - 'parcel_to': fields.integer('Parcel To'), |
258 | - 'parcel_qty': fields.integer('Parcel Qty'), |
259 | - 'total_weight': fields.float('Weight', digits=(16,2)), |
260 | - 'total_volume': fields.float('Volume', digits=(16,2)), |
261 | - 'total_height': fields.float('Height', digits=(16,2)), |
262 | - 'total_length': fields.float('Length', digits=(16,2)), |
263 | - 'total_width': fields.float('Width', digits=(16,2)), |
264 | + 'parcel_from': fields.integer_null('Parcel From'), |
265 | + 'parcel_to': fields.integer_null('Parcel To'), |
266 | + 'parcel_qty': fields.integer_null('Parcel Qty'), |
267 | + # on IN VI import file the fields are named total_xxx but the figures are p.p |
268 | + 'total_weight': fields.float_null('Weight', digits=(16,2)), |
269 | + 'total_volume': fields.float_null('Volume', digits=(16,2)), |
270 | + 'total_height': fields.float_null('Height', digits=(16,2)), |
271 | + 'total_length': fields.float_null('Length', digits=(16,2)), |
272 | + 'total_width': fields.float_null('Width', digits=(16,2)), |
273 | 'packing_list': fields.char('Supplier Packing List', size=30), |
274 | + 'ppl_name': fields.char('Supplier Packing List', size=128), |
275 | 'integrity_status': fields.selection(string='Integrity Status', selection=PACK_INTEGRITY_STATUS_SELECTION, readonly=True), |
276 | + 'real_total_volume': fields.function(_get_real_total, method=True, type='integer_null', string='Total volume for all packs', multi='real_total'), |
277 | + 'real_total_weight': fields.function(_get_real_total, method=True, type='integer_null', string='Total weight for all packs', multi='real_total'), |
278 | } |
279 | |
280 | _defaults = { |
281 | |
282 | === modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py' |
283 | --- bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2019-08-28 08:33:22 +0000 |
284 | +++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2020-08-05 12:54:43 +0000 |
285 | @@ -125,10 +125,11 @@ |
286 | context = {} |
287 | |
288 | res = {} |
289 | - for wiz in self.browse(cr, uid, ids, context=context): |
290 | + for wiz in self.browse(cr, uid, ids, fields_to_fetch=['linked_to_out', 'picking_id'], context=context): |
291 | res[wiz.id] = False |
292 | - if wiz.picking_id and wiz.picking_id.state == 'updated' and wiz.linked_to_out: |
293 | - res[wiz.id] = True |
294 | + if wiz.picking_id and wiz.linked_to_out: |
295 | + if not self.pool.get('stock.move.in.processor').search_exist(cr, uid, [('wizard_id', '=', wiz.id),('pack_info_id', '=', False)], context=context): |
296 | + res[wiz.id] = wiz.linked_to_out |
297 | |
298 | return res |
299 | |
300 | @@ -158,7 +159,6 @@ |
301 | |
302 | return res |
303 | |
304 | - |
305 | _columns = { |
306 | 'move_ids': fields.one2many( |
307 | 'stock.move.in.processor', |
308 | @@ -194,7 +194,7 @@ |
309 | ), |
310 | 'draft': fields.boolean('Draft'), |
311 | 'already_processed': fields.boolean('Already processed'), |
312 | - 'linked_to_out': fields.boolean('Is this IN linked to a single Pick (same FO) ?'), |
313 | + 'linked_to_out': fields.char('If the IN is linked to a single Pick (same FO) give the type of delivery doc (standard / picking)', size=16), |
314 | 'register_a_claim': fields.boolean( |
315 | string='Register a Claim to Supplier', |
316 | ), |
317 | @@ -218,8 +218,10 @@ |
318 | 'claim_description': fields.text( |
319 | string='Claim Description', |
320 | ), |
321 | - 'display_process_to_ship_button': fields.function(_get_display_process_to_ship_button, method=True, type='boolean', string='Process to ship'), |
322 | + 'display_process_to_ship_button': fields.function(_get_display_process_to_ship_button, method=True, type='char', string='Process to ship'), |
323 | 'location_dest_active_ok': fields.function(_get_location_dest_active_ok, method=True, type='boolean', string='Dest location is inactive ?', store=False), |
324 | + 'fields_as_ro': fields.boolean('Set Cost/Split .. as RO', internal=True), |
325 | + 'sequence_issue': fields.boolean('Issue with To ship'), |
326 | } |
327 | |
328 | _defaults = { |
329 | @@ -248,17 +250,33 @@ |
330 | picking = picking_obj.browse(cr, uid, vals.get('picking_id'), context=context) |
331 | |
332 | cr.execute(""" |
333 | - select so.id from |
334 | + select so.id, array_agg(distinct(out.name)), count(distinct(so.procurement_request)) from |
335 | stock_move m |
336 | left join stock_picking p on m.picking_id = p.id |
337 | left join purchase_order_line pol on m.purchase_line_id = pol.id |
338 | left join sale_order_line sol on sol.id = pol.linked_sol_id |
339 | left join sale_order so on so.id = sol.order_id |
340 | - where m.picking_id = %s and so.procurement_request = 'f' and coalesce(p.claim, 'f') = 'f' |
341 | + left join stock_picking out on out.sale_id = so.id and out.type = 'out' and (out.subtype = 'picking' and out.state='draft' or out.subtype = 'standard' and out.state in ('draft', 'confirmed', 'assigned')) |
342 | + where |
343 | + m.picking_id = %s and |
344 | + coalesce(p.claim, 'f') = 'f' |
345 | group by so.id |
346 | """, (vals.get('picking_id'), )) |
347 | if cr.rowcount == 1: |
348 | - vals['linked_to_out'] = True |
349 | + fetch_data = cr.fetchone() |
350 | + if fetch_data[2] > 1: |
351 | + # IN mixed with FO/IR |
352 | + vals['linked_to_out'] = False |
353 | + |
354 | + out_names = fetch_data[1] |
355 | + out_type = False |
356 | + for out_name in out_names: |
357 | + if out_name and out_name.startswith('OUT/'): |
358 | + out_type = out_name |
359 | + break |
360 | + if not out_type: |
361 | + out_type = out_names and len(out_names) == 1 and out_names[0] and out_names[0].startswith('PICK/') and 'picking' or False |
362 | + vals['linked_to_out'] = out_type |
363 | else: |
364 | vals['linked_to_out'] = False |
365 | |
366 | @@ -623,8 +641,18 @@ |
367 | |
368 | |
369 | def launch_simulation_pack(self, cr, uid, ids, context=None): |
370 | + if context is None: |
371 | + context = {} |
372 | + |
373 | + if not context.get('auto_import_ok'): |
374 | + out = self.read(cr, uid, ids[0], ['linked_to_out'], context=context) |
375 | + if out['linked_to_out'] != 'picking': |
376 | + raise osv.except_osv(_('Warning'), _('This type of import cannot be used because related PICK document has been converted to %s') % out['linked_to_out']) |
377 | + |
378 | data = self.launch_simulation(cr, uid, ids, context) |
379 | self.pool.get('wizard.import.in.simulation.screen').write(cr, uid, data['res_id'], {'with_pack': True}) |
380 | + |
381 | + |
382 | data['name'] = _('Incoming shipment simulation screen (pick and pack mode)') |
383 | |
384 | file_attached = self.check_if_has_import_file_in_attachment(cr, uid, ids, context=context) |
385 | @@ -634,7 +662,8 @@ |
386 | 'filetype': self.pool.get('stock.picking').get_import_filetype(cr, uid, file_attached['name'], context=context), |
387 | }, context=context) |
388 | self.pool.get('wizard.import.in.simulation.screen').launch_simulate(cr, uid, data['res_id'], context=context) |
389 | - self.pool.get('wizard.import.in.simulation.screen').launch_import_pack(cr, uid, data['res_id'], context=context) |
390 | + # the following line process the IN but display the simu screen |
391 | + #self.pool.get('wizard.import.in.simulation.screen').launch_import_pack(cr, uid, data['res_id'], context=context) |
392 | return data |
393 | |
394 | |
395 | @@ -657,11 +686,6 @@ |
396 | if num_of_packs: |
397 | if not self.pool.get('ppl.processor')._check_rounding(cr, uid, move.uom_id, num_of_packs, move.quantity, context=context): |
398 | rounding_issues.append(move.line_number) |
399 | - if move.integrity_status and move.integrity_status != 'empty': |
400 | - raise osv.except_osv( |
401 | - _('Error'), |
402 | - _('Please correct red lines before processing') |
403 | - ) |
404 | |
405 | if not total_qty: |
406 | raise osv.except_osv( |
407 | @@ -731,10 +755,35 @@ |
408 | if isinstance(ids, (int,long)): |
409 | ids = [ids] |
410 | |
411 | + out = self.read(cr, uid, ids[0], ['linked_to_out'], context=context) |
412 | + if out['linked_to_out'] != 'picking': |
413 | + raise osv.except_osv(_('Warning'), _('This type of import cannot be used because related PICK document has been converted to %s') % out['linked_to_out']) |
414 | + |
415 | rounding_issues, sequence_ok = self.check_before_creating_pack_lines(cr, uid, ids, context=context) |
416 | + cr.execute(''' |
417 | + select wiz_line.line_number, pol.linked_sol_id, sum(wiz_line.quantity) |
418 | + from stock_move_in_processor wiz_line |
419 | + left join stock_incoming_processor wiz on wiz.id = wiz_line.wizard_id |
420 | + left join stock_move move_in on move_in.picking_id = wiz.picking_id and move_in.line_number = wiz_line.line_number |
421 | + left join purchase_order_line pol on pol.id = move_in.purchase_line_id |
422 | + where |
423 | + wiz.id = %s |
424 | + group by wiz_line.line_number, pol.linked_sol_id |
425 | + ''', (ids[0],)) |
426 | + sol_id_to_wiz_line = {} |
427 | + sol_id_sum = {} |
428 | + for x in cr.fetchall(): |
429 | + sol_id_to_wiz_line[x[1]] = x[0] |
430 | + sol_id_sum[x[1]] = x[2] |
431 | + |
432 | + error_pick = self.pool.get('wizard.import.in.simulation.screen').error_pick_already_processed(cr, uid, sol_id_sum, sol_id_to_wiz_line, context) |
433 | + if error_pick: |
434 | + raise osv.except_osv(_('Error'), error_pick) |
435 | |
436 | if not sequence_ok: |
437 | view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'msf_outgoing', 'stock_incoming_processor_form_view')[1] |
438 | + self.write(cr, uid, ids, {'sequence_issue': True}, context=context) |
439 | + |
440 | return { |
441 | 'name': _('Products to Process'), |
442 | 'type': 'ir.actions.act_window', |
443 | @@ -765,7 +814,8 @@ |
444 | 'context': context, |
445 | } |
446 | |
447 | - return self.do_process_to_ship(cr, uid, ids, context=context) |
448 | + self.pool.get('stock.picking').do_incoming_shipment(cr, uid, ids, context=context, with_ppl=True) |
449 | + return {'type': 'ir.actions.act_window_close'} |
450 | |
451 | |
452 | def do_process_to_ship(self, cr, uid, ids, context=None): |
453 | @@ -851,6 +901,7 @@ |
454 | _name = 'stock.move.in.processor' |
455 | _inherit = 'stock.move.processor' |
456 | _description = 'Wizard lines for incoming shipment processing' |
457 | + _order = 'line_number, from_pack, id' |
458 | |
459 | def _get_move_info(self, cr, uid, ids, field_name, args, context=None): |
460 | return super(stock_move_in_processor, self)._get_move_info(cr, uid, ids, field_name, args, context=context) |
461 | @@ -958,6 +1009,31 @@ |
462 | cr.execute(sql, (value, ml_id)) |
463 | return True |
464 | |
465 | + def _get_pack_info(self, cr, uid, ids, field_name, args, context=None): |
466 | + if context is None: |
467 | + context = {} |
468 | + if isinstance(ids, (int,long)): |
469 | + ids = [ids] |
470 | + |
471 | + res = {} |
472 | + for wiz in self.browse(cr, uid, ids, fields_to_fetch=['from_pack', 'to_pack'], context=context): |
473 | + if wiz['from_pack']: |
474 | + res[wiz.id] = '%s-%s' % (wiz['from_pack'], wiz['to_pack']) |
475 | + else: |
476 | + res[wiz.id] = False |
477 | + return res |
478 | + |
479 | + def _search_pack_info(self, cr, uid, obj, name, args, context): |
480 | + dom = [] |
481 | + for arg in args: |
482 | + if arg[2]: |
483 | + d_p = arg[2].split('-') |
484 | + if d_p and d_p[0] and d_p[0].strip(): |
485 | + dom = [('from_pack', '=', d_p[0].strip())] |
486 | + if d_p and len(d_p)>1 and d_p[1] and d_p[1].strip(): |
487 | + dom.append(('to_pack', '=', d_p[1].strip())) |
488 | + return dom |
489 | + |
490 | _columns = { |
491 | # Parent wizard |
492 | 'wizard_id': fields.many2one( |
493 | @@ -1184,17 +1260,21 @@ |
494 | help="Ticked if the product is a Controlled Substance", |
495 | ), |
496 | 'pack_info_id': fields.many2one('wizard.import.in.pack.simulation.screen', 'Pack Info'), |
497 | - 'from_pack': fields.integer(string='From p.'), |
498 | - 'to_pack': fields.integer(string='To p.'), |
499 | - 'weight': fields.float('Weight', digits=(16,2)), |
500 | - 'volume': fields.float('Volume', digits=(16,2)), |
501 | - 'height': fields.float('Height', digits=(16,2)), |
502 | - 'length': fields.float('Length', digits=(16,2)), |
503 | - 'width': fields.float('Width', digits=(16,2)), |
504 | + 'from_pack': fields.integer_null(string='From p.'), |
505 | + 'to_pack': fields.integer_null(string='To p.'), |
506 | + 'weight': fields.float_null('Weight', digits=(16,2)), |
507 | + 'volume': fields.float_null('Volume', digits=(16,2)), |
508 | + 'height': fields.float_null('Height', digits=(16,2)), |
509 | + 'total_volume': fields.float_null(u'Total Volume [dm³]', digits=(16,0)), |
510 | + 'total_weight': fields.float_null(u'Total Weight [kg]', digits=(16,0)), |
511 | + 'length': fields.float_null('Length', digits=(16,2)), |
512 | + 'width': fields.float_null('Width', digits=(16,2)), |
513 | 'pack_id': fields.many2one('in.family.processor', string='Pack', ondelete='set null'), |
514 | 'packing_list': fields.char('Supplier Packing List', size=30), |
515 | + 'ppl_name': fields.char('Packing List', size=128), |
516 | 'sequence_issue': fields.selection(PACK_INTEGRITY_STATUS_SELECTION, 'Sequence issue', readonly=True), |
517 | 'split_move_ok': fields.boolean(string='Is split move ?'), |
518 | + 'filter_pack': fields.function(_get_pack_info, method=True, type='char', string='Pack', fnct_search=_search_pack_info), |
519 | } |
520 | |
521 | |
522 | @@ -1217,13 +1297,21 @@ |
523 | if context is None: |
524 | context = {} |
525 | |
526 | + if not vals.get('cost'): |
527 | + # issue on IN processor from sync if new line created (because of a split in coordo) |
528 | + # then the price_unit should not come from product standard_price but from the original stock.move (i.e: from POL) |
529 | + # before this the unit price was temporary set to the standard_price, but changed on IN processing, this was too late |
530 | + if vals.get('move_id'): |
531 | + move_data = self.pool.get('stock.move').browse(cr, uid, vals['move_id'], fields_to_fetch=['price_unit', 'currency_id'], context=context) |
532 | + vals['cost'] = move_data.price_unit |
533 | + vals['currency'] = move_data.currency_id.id |
534 | + |
535 | if vals.get('product_id', False): |
536 | if not vals.get('cost', False): |
537 | price = product_obj.browse(cr, uid, vals['product_id'], context=context).standard_price |
538 | vals['cost'] = price |
539 | if not vals.get('currency', False): |
540 | vals['currency'] = user_obj.browse(cr, uid, uid, context=context).company_id.currency_id.id |
541 | - |
542 | return super(stock_move_in_processor, self).create(cr, uid, vals, context=context) |
543 | |
544 | |
545 | |
546 | === modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml' |
547 | --- bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml 2019-08-28 08:33:22 +0000 |
548 | +++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml 2020-08-05 12:54:43 +0000 |
549 | @@ -12,11 +12,13 @@ |
550 | <field name="linked_to_out" invisible="1"/> |
551 | <field name="picking_id" invisible="1" /> |
552 | <field name="display_process_to_ship_button" invisible="1" /> |
553 | - <button name="copy_all" type="object" icon="gtk-jump-to" colspan="2" string="Copy all" /> |
554 | - <button name="uncopy_all" type="object" icon="gtk-undo" colspan="2" string="Clear all" /> |
555 | + <field name="sequence_issue" invisible="1" /> |
556 | + <field name="fields_as_ro" invisible="1" /> |
557 | + <button name="copy_all" type="object" icon="gtk-jump-to" colspan="2" string="Copy all" set_ids="move_ids"/> |
558 | + <button name="uncopy_all" type="object" icon="gtk-undo" colspan="2" string="Clear all" set_ids="move_ids"/> |
559 | <group name="import_file_lines" string="Import Lines" colspan="4"> |
560 | <button name="launch_simulation" string="Import IN" icon="gtk-execute" colspan="1" type="object" /> |
561 | - <button name="launch_simulation_pack" string="Import IN, process IN & pick and pack" icon="gtk-execute" colspan="1" type="object" attrs="{'invisible': [('linked_to_out', '!=', True)]}"/> |
562 | + <button name="launch_simulation_pack" string="Import IN, process IN & pick and pack" icon="gtk-execute" colspan="1" type="object" attrs="{'invisible': [('linked_to_out', '=', False)]}"/> |
563 | </group> |
564 | <field name="contains_dg" invisible="1" /> |
565 | <field name="contains_kc" invisible="1" /> |
566 | @@ -49,6 +51,15 @@ |
567 | </p> |
568 | </html> |
569 | </group> |
570 | + <group colspan="4" attrs="{'invisible': [('sequence_issue', '=', False)]}"> |
571 | + <html> |
572 | + <p style="text-align: center; v-align: middle;color:#f27d0c; font-weight:bold; font-size:1.2em"> |
573 | + <img src="/openerp/static/images/stock/gtk-dialog-warning.png" height="12" width="12" /> |
574 | + <span><translate>Please correct red lines before processing or do not process to ship</translate></span> |
575 | + <img src="/openerp/static/images/stock/gtk-dialog-warning.png" height="12" width="12" /> |
576 | + </p> |
577 | + </html> |
578 | + </group> |
579 | <separator colspan="4" string="Move lines" /> |
580 | <field name="move_ids" mode="tree" context="{'display_process_to_ship_button': display_process_to_ship_button}" |
581 | colspan="4" nolabel="1" /> |
582 | @@ -88,7 +99,7 @@ |
583 | <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', True)]}" /> |
584 | <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', False)]}" |
585 | confirm="Warning the final destination location of these goods is no longer active, IN will be processed as normal but please check and process the Internal move created after manually. Continue ?" /> |
586 | - <button name="process_to_ship" attrs="{'invisible': [('display_process_to_ship_button', '!=', True)]}" type="object" string="Process to ship" icon="gtk-goto-last" /> |
587 | + <button name="process_to_ship" attrs="{'invisible': ['|', ('display_process_to_ship_button', '=', False), ('register_a_claim', '=', True)]}" type="object" string="Process to ship" icon="gtk-goto-last" /> |
588 | </group> |
589 | </form> |
590 | </field> |
591 | @@ -129,6 +140,7 @@ |
592 | hide_delete_button="1" |
593 | hide_new_button="1" |
594 | colors="red:integrity_status!='empty'" |
595 | + editable_style="new" |
596 | > |
597 | <!-- Invisible fields --> |
598 | <field name="type_check" invisible="1" /> |
599 | @@ -146,6 +158,7 @@ |
600 | type="object" |
601 | icon="gtk-convert" |
602 | string="Change Product" |
603 | + attrs="{'invisible': [('fields_as_ro', '=', True)]}" |
604 | /> |
605 | <field name="asset_id" |
606 | domain="[('product_id', '=', product_id)]" |
607 | @@ -164,14 +177,20 @@ |
608 | <field name="uom_id" |
609 | domain="[('category_id', '=', ordered_uom_category)]" |
610 | on_change="onchange_uom_qty(uom_id, quantity)" |
611 | + attrs="{'readonly': [('fields_as_ro', '=', True)]}" |
612 | /> |
613 | - <field name="from_pack" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" /> |
614 | - <field name="to_pack" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" /> |
615 | - <field name="packing_list" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" /> |
616 | + <field name="from_pack" readonly="1" /> |
617 | + <field name="to_pack" readonly="1" /> |
618 | + <field name="filter_pack" filter_selector="1" invisible="1" /> |
619 | + <field name="total_volume" readonly="1" /> |
620 | + <field name="total_weight" readonly="1" /> |
621 | + <field name="ppl_name" readonly="1" filter_selector="1" /> |
622 | + <field name="packing_list" readonly="1" filter_selector="1" /> |
623 | <button name="open_split_wizard" |
624 | type="object" |
625 | icon="terp-stock_effects-object-colorize" |
626 | string="Split" |
627 | + attrs="{'invisible': [('fields_as_ro', '=', True)]}" |
628 | /> |
629 | <field name="prodlot_id" |
630 | domain="[('product_id', '=', product_id), ('check_type', '=', True)]" |
631 | @@ -187,7 +206,7 @@ |
632 | <field name="kc_check" widget="null_boolean" /> |
633 | <field name="dg_check" widget="null_boolean" /> |
634 | <field name="np_check" widget="null_boolean" /> |
635 | - <field name="cost" /> |
636 | + <field name="cost" attrs="{'readonly': [('fields_as_ro', '=', True)]}" /> |
637 | <field name="currency" /> |
638 | <field name="integrity_status" string="" /> |
639 | </tree> |
640 | |
641 | === modified file 'bin/addons/msf_outgoing/wizard/picking_processor.py' |
642 | --- bin/addons/msf_outgoing/wizard/picking_processor.py 2018-11-07 14:53:50 +0000 |
643 | +++ bin/addons/msf_outgoing/wizard/picking_processor.py 2020-08-05 12:54:43 +0000 |
644 | @@ -144,6 +144,21 @@ |
645 | _('No wizard found !'), |
646 | ) |
647 | |
648 | + if self._name == 'stock.incoming.processor': |
649 | + line_obj = self.pool.get('stock.move.in.processor') |
650 | + dom = context.get('selected_domain', []) |
651 | + if dom: |
652 | + dom = ['&', ('wizard_id', '=', ids[0])] + dom |
653 | + else: |
654 | + dom = [('wizard_id', '=', ids[0])] |
655 | + lines_ids = line_obj.search(cr, uid, dom, context=context) |
656 | + for move in line_obj.browse(cr, uid, lines_ids, context=context): |
657 | + line_obj.write(cr, uid, [move.id], {'quantity': move.ordered_quantity}, context=context) |
658 | + return { |
659 | + 'type': 'ir.actions.refresh_o2m', |
660 | + 'o2m_refresh': 'move_ids' |
661 | + } |
662 | + |
663 | for wizard in self.browse(cr, uid, ids, context=context): |
664 | for move in wizard.move_ids: |
665 | self.pool.get(move._name).write(cr, uid, [move.id], {'quantity': move.ordered_quantity}, context=context) |
666 | @@ -173,6 +188,21 @@ |
667 | _('No wizard found !'), |
668 | ) |
669 | |
670 | + if self._name == 'stock.incoming.processor': |
671 | + line_obj = self.pool.get('stock.move.in.processor') |
672 | + dom = context.get('selected_domain', []) |
673 | + if dom: |
674 | + dom = ['&', ('wizard_id', '=', ids[0])] + dom |
675 | + else: |
676 | + dom = [('wizard_id', '=', ids[0])] |
677 | + lines_ids = line_obj.search(cr, uid, dom, context=context) |
678 | + for move in line_obj.browse(cr, uid, lines_ids, context=context): |
679 | + line_obj.write(cr, uid, [move.id], {'quantity': 0}, context=context) |
680 | + return { |
681 | + 'type': 'ir.actions.refresh_o2m', |
682 | + 'o2m_refresh': 'move_ids' |
683 | + } |
684 | + |
685 | for wizard in self.browse(cr, uid, ids, context=context): |
686 | move_obj = wizard.move_ids[0]._name |
687 | move_ids = [x.id for x in wizard.move_ids] |
688 | @@ -218,13 +248,17 @@ |
689 | 'from_pack': move.pack_info_id.parcel_from, |
690 | 'to_pack': move.pack_info_id.parcel_to, |
691 | 'weight': move.pack_info_id.total_weight, |
692 | + 'total_weight': move.pack_info_id.real_total_weight, |
693 | 'volume': move.pack_info_id.total_volume, |
694 | + 'total_volume': move.pack_info_id.real_total_volume, |
695 | 'height': move.pack_info_id.total_height, |
696 | 'length': move.pack_info_id.total_length, |
697 | 'width': move.pack_info_id.total_width, |
698 | 'packing_list': move.pack_info_id.packing_list, |
699 | + 'ppl_name': move.pack_info_id.ppl_name, |
700 | 'cost': move.price_unit, |
701 | 'currency': move.currency_id.id, |
702 | + 'pack_info_id': move.pack_info_id.id, |
703 | }) |
704 | line_obj.create(cr, uid, line_data, context=context) |
705 | |
706 | @@ -1060,6 +1094,7 @@ |
707 | 'nodestroy': True, |
708 | 'target': 'new', |
709 | 'res_id': split_wiz_id, |
710 | + 'keep_open': 1, |
711 | 'context': context, |
712 | } |
713 | |
714 | |
715 | === modified file 'bin/addons/msf_outgoing/wizard/split_move_processor.py' |
716 | --- bin/addons/msf_outgoing/wizard/split_move_processor.py 2019-04-09 08:05:03 +0000 |
717 | +++ bin/addons/msf_outgoing/wizard/split_move_processor.py 2020-08-05 12:54:43 +0000 |
718 | @@ -83,6 +83,11 @@ |
719 | return { |
720 | 'type': 'ir.actions.act_window_close' |
721 | } |
722 | + elif wiz['processor_type'] == 'stock.move.in.processor': |
723 | + return { |
724 | + 'type': 'ir.actions.refresh_popupo2m', |
725 | + 'o2m_refresh': 'move_ids' |
726 | + } |
727 | line_model = self.pool.get(wiz['processor_type']) |
728 | line = line_model.browse(cr, uid, wiz['processor_line_id'], context=context) |
729 | res_model = line_model._columns['wizard_id']._obj |
730 | |
731 | === modified file 'bin/addons/msf_printed_documents/report/report_reception.py' |
732 | --- bin/addons/msf_printed_documents/report/report_reception.py 2020-07-29 16:14:59 +0000 |
733 | +++ bin/addons/msf_printed_documents/report/report_reception.py 2020-08-05 12:54:43 +0000 |
734 | @@ -32,7 +32,7 @@ |
735 | 'time': time, |
736 | 'getState': self.getState, |
737 | 'enumerate': enumerate, |
738 | - 'get_lines': self.get_lines, |
739 | + 'get_lines_by_packing': self.get_lines_by_packing, |
740 | 'getDateCreation': self.getDateCreation, |
741 | 'getNbItem': self.getNbItem, |
742 | 'check': self.check, |
743 | @@ -215,10 +215,16 @@ |
744 | actual_receipt_date = time.strftime('%d/%m/%Y', time.strptime(o.date_done, '%Y-%m-%d %H:%M:%S')) |
745 | return actual_receipt_date |
746 | |
747 | - def get_lines(self, o): |
748 | - return o.move_lines |
749 | - |
750 | - |
751 | + def get_lines_by_packing(self, o): |
752 | + pack_info = {} |
753 | + for line in o.move_lines: |
754 | + pack_info.setdefault(line.pack_info_id or False, []).append(line) |
755 | + |
756 | +<<<<<<< TREE |
757 | + |
758 | +======= |
759 | + return sorted(pack_info.items(), key=lambda x: x[0] and (x[0].ppl_name, x[0].packing_list, x[0].parcel_from)) |
760 | +>>>>>>> MERGE-SOURCE |
761 | report_sxw.report_sxw('report.msf.report_reception_in', 'stock.picking', 'addons/msf_printed_documents/report/report_reception.rml', parser=report_reception, header=False) |
762 | |
763 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
764 | |
765 | === modified file 'bin/addons/msf_printed_documents/report/report_reception.rml' |
766 | --- bin/addons/msf_printed_documents/report/report_reception.rml 2020-06-18 15:56:24 +0000 |
767 | +++ bin/addons/msf_printed_documents/report/report_reception.rml 2020-08-05 12:54:43 +0000 |
768 | @@ -106,7 +106,7 @@ |
769 | <blockTableStyle id="OrderInformations2"> |
770 | <blockAlignment value="CENTER" /> |
771 | <blockVAlign value="CENTER" /> |
772 | - <blockBackground colorName="silver" start="0,6" stop="0,6" /> |
773 | + <blockBackground colorName="silver" start="0,7" stop="0,7" /> |
774 | <lineStyle kind="GRID" colorName="#000000" start="0,6" stop="-1,-1" thickness="0.5"/> |
775 | <blockTopPadding value="0" /> |
776 | <blockBottomPadding value="0" /> |
777 | @@ -121,6 +121,20 @@ |
778 | <lineStyle kind="LINEBEFORE" colorName="black" start="2,0" thickness="0.5" /> |
779 | </blockTableStyle> |
780 | |
781 | + <blockTableStyle id="PackingList"> |
782 | + <blockAlignment value="CENTER" /> |
783 | + <blockValign value="MIDDLE" /> |
784 | + <blockTopPadding value="10" /> |
785 | + <blockBottomPadding value="0" /> |
786 | + <blockBackground colorName="silver" start="0,0" stop="0,0" /> |
787 | + <blockBackground colorName="silver" start="2,0" stop="2,0" /> |
788 | + <blockBackground colorName="silver" start="4,0" stop="4,0" /> |
789 | + <blockBackground colorName="silver" start="6,0" stop="6,0" /> |
790 | + <blockBackground colorName="silver" start="8,0" stop="8,0" /> |
791 | + <blockBackground colorName="silver" start="10,0" stop="10,0" /> |
792 | + <lineStyle kind="LINEBEFORE" colorName="black" start="0,0" thickness="0.5" /> |
793 | + </blockTableStyle> |
794 | + |
795 | <blockTableStyle id="OrderInformations4"> |
796 | <blockValign value="MIDDLE" /> |
797 | <lineStyle kind="INNERGRID" colorName="#000000" thickness="0.5" /> |
798 | @@ -410,7 +424,9 @@ |
799 | <tr><td></td></tr> |
800 | </blockTable> |
801 | |
802 | - <blockTable colWidths="800.0" style="OrderInformations2" repeatRows="7"> |
803 | +<section> |
804 | + [[ repeatIn(get_lines_by_packing(objects[0]), 'pack') ]] |
805 | + <blockTable colWidths="800.0" style="OrderInformations2" repeatRows="8"> |
806 | |
807 | <tr><td></td></tr> |
808 | <tr> |
809 | @@ -476,23 +492,72 @@ |
810 | |
811 | </td> |
812 | </tr> |
813 | + <tr> |
814 | + <td> |
815 | + <blockTable colWidths="60,80,100,70,60,30,50,40,90,75,91,54" style="PackingList"> |
816 | + <tr> |
817 | + <td> |
818 | + <para style="TextInformation5" alignment="CENTER">Packing List</para> |
819 | + </td> |
820 | + |
821 | + <td> |
822 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].ppl_name ]]</para> |
823 | + |
824 | + </td> |
825 | + |
826 | + <td> |
827 | + <para style="TextInformation5" alignment="CENTER">Supplier Packing List</para> |
828 | + </td> |
829 | + <td> |
830 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].packing_list ]]</para> |
831 | + </td> |
832 | + <td> |
833 | + <para style="TextInformation5" alignment="CENTER">From parcel</para> |
834 | + </td> |
835 | + <td> |
836 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].parcel_from or '' ]]</para> |
837 | + </td> |
838 | + <td> |
839 | + <para style="TextInformation5" alignment="CENTER">To parcel</para> |
840 | + </td> |
841 | + <td> |
842 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].parcel_to or '' ]]</para> |
843 | + </td> |
844 | + <td> |
845 | + <para style="TextInformation5" alignment="CENTER">Total volume</para> |
846 | + </td> |
847 | + <td> |
848 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].real_total_volume and u'%s dm³'%pack[0].real_total_volume or '' ]]</para> |
849 | + </td> |
850 | + <td> |
851 | + <para style="TextInformation5" alignment="CENTER">Total weight</para> |
852 | + </td> |
853 | + <td> |
854 | + <para style="TextInformation5" alignment="CENTER">[[ pack[0].real_total_weight and '%s kg'%pack[0].real_total_weight or '' ]]</para> |
855 | + </td> |
856 | + </tr> |
857 | + </blockTable> |
858 | + |
859 | + |
860 | + </td> |
861 | + </tr> |
862 | |
863 | <tr> |
864 | <td> |
865 | <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3"> |
866 | <tr> |
867 | <td> |
868 | - <para style="TextInformation4" alignment="CENTER">Item</para> |
869 | + <para style="TextInformation4" alignment="CENTER">Item</para> <!-- 30 --> |
870 | </td> |
871 | |
872 | <td> |
873 | <blockTable colWidths="110,260" style="OrderInformations4"> |
874 | <tr> |
875 | <td> |
876 | - <para style="TextInformation" alignment="LEFT">Code</para> |
877 | + <para style="TextInformation" alignment="LEFT">Code</para> <!-- 110 --> |
878 | </td> |
879 | <td> |
880 | - <para style="TextInformation" alignment="LEFT">Description</para> |
881 | + <para style="TextInformation" alignment="LEFT">Description</para> <!-- 260 --> |
882 | </td> |
883 | </tr> |
884 | <tr> |
885 | @@ -508,37 +573,37 @@ |
886 | </td> |
887 | |
888 | <td> |
889 | - <para style="TextInformation5" alignment="CENTER">Qty confirmed</para> |
890 | - </td> |
891 | - <td> |
892 | - <para style="TextInformation5" alignment="CENTER">Unit of Measure</para> |
893 | - </td> |
894 | - <td> |
895 | - <para style="TextInformation5" alignment="CENTER">Qty backorder</para> |
896 | - </td> |
897 | - <td> |
898 | - <para style="TextInformation5" alignment="CENTER">Qty received</para> |
899 | - </td> |
900 | - <td> |
901 | - <para style="TextInformation5" alignment="CENTER">Batch / Serial number</para> |
902 | - </td> |
903 | - <td> |
904 | - <para style="TextInformation5" alignment="CENTER">Expiry date</para> |
905 | - </td> |
906 | - <td> |
907 | - <para style="TextInformation4" alignment="CENTER">ED</para> |
908 | - </td> |
909 | - <td> |
910 | - <para style="TextInformation4" alignment="CENTER">BM</para> |
911 | - </td> |
912 | - <td> |
913 | - <para style="TextInformation4" alignment="CENTER">KC</para> |
914 | - </td> |
915 | - <td> |
916 | - <para style="TextInformation4" alignment="CENTER">DG</para> |
917 | - </td> |
918 | - <td> |
919 | - <para style="TextInformation4" alignment="CENTER">CS</para> |
920 | + <para style="TextInformation5" alignment="CENTER">Qty confirmed</para> <!-- 50 --> |
921 | + </td> |
922 | + <td> |
923 | + <para style="TextInformation5" alignment="CENTER">Unit of Measure</para> <!-- 40 --> |
924 | + </td> |
925 | + <td> |
926 | + <para style="TextInformation5" alignment="CENTER">Qty backorder</para> <!-- 50 --> |
927 | + </td> |
928 | + <td> |
929 | + <para style="TextInformation5" alignment="CENTER">Qty received</para> <!-- 40 --> |
930 | + </td> |
931 | + <td> |
932 | + <para style="TextInformation5" alignment="CENTER">Batch / Serial number</para> <!-- 75 --> |
933 | + </td> |
934 | + <td> |
935 | + <para style="TextInformation5" alignment="CENTER">Expiry date</para> <!-- 53 --> |
936 | + </td> |
937 | + <td> |
938 | + <para style="TextInformation4" alignment="CENTER">ED</para> <!-- 20 --> |
939 | + </td> |
940 | + <td> |
941 | + <para style="TextInformation4" alignment="CENTER">BM</para> <!-- 18 --> |
942 | + </td> |
943 | + <td> |
944 | + <para style="TextInformation4" alignment="CENTER">KC</para> <!-- 18 --> |
945 | + </td> |
946 | + <td> |
947 | + <para style="TextInformation4" alignment="CENTER">DG</para> <!-- 18 --> |
948 | + </td> |
949 | + <td> |
950 | + <para style="TextInformation4" alignment="CENTER">CS</para> <!-- 18 --> |
951 | </td> |
952 | </tr> |
953 | </blockTable> |
954 | @@ -552,7 +617,7 @@ |
955 | |
956 | |
957 | <tr> |
958 | - [[ repeatIn(get_lines(objects[0]), 'line') ]] |
959 | + [[ repeatIn(pack[1], 'line') ]] |
960 | <td> |
961 | <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3"> |
962 | <tr> |
963 | @@ -622,6 +687,7 @@ |
964 | </tr> |
965 | |
966 | </blockTable> |
967 | +</section> |
968 | |
969 | <blockTable colWidths="800.0" style="OrderInformationsRien" > |
970 | <tr> |
971 | |
972 | === modified file 'bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv' |
973 | --- bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv 2020-06-09 09:58:28 +0000 |
974 | +++ bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv 2020-08-05 12:54:43 +0000 |
975 | @@ -8,7 +8,11 @@ |
976 | msf_sync_data_server.pol_create_sol,TRUE,TRUE,"['sync_local_id', 'order_id/name','product_id/id', 'product_id/name', 'name', 'state', 'product_qty', 'product_uom', 'price_unit', 'analytic_distribution_id/id','comment','have_analytic_distribution_from_header','line_number', 'nomen_manda_0/id','nomen_manda_1/id','nomen_manda_2/id','nomen_manda_3/id', 'nomenclature_description','notes','default_name','default_code','is_line_split','date_planned', 'stock_take_date', 'ir_name_for_sync']","[('sync_linked_sol', '=', False), ('order_id.partner_type', 'not in',['external','esc']), ('state', 'in', ['validated', 'confirmed', 'done']), ('order_id.state', 'not in', ['draft', 'draft_p', 'cancel'])]",partner_id,MISSION,sale.order.line.create_so_line,purchase.order.line,PO line creates FO line,11,,Valid |
977 | msf_sync_data_server.sol_updates_pol,TRUE,TRUE,"['resourced_original_line/id', 'resourced_original_remote_line','sync_sourced_origin', 'sync_local_id', 'sync_linked_pol', 'order_id/name', 'product_id/id', 'product_id/name', 'name', 'state','product_uom_qty', 'product_uom', 'price_unit', 'in_name_goods_return', 'analytic_distribution_id/id','comment','have_analytic_distribution_from_header','line_number', 'nomen_manda_0/id','nomen_manda_1/id','nomen_manda_2/id','nomen_manda_3/id', 'nomenclature_description','notes','default_name','default_code','date_planned','is_line_split', 'original_line_id/id', 'confirmed_delivery_date', 'stock_take_date', 'cancel_split_ok', 'modification_comment', 'from_cancel_out', 'pol_external_ref']","[('order_id.partner_type', '!=', 'external'), ('state', '!=', 'draft'), ('product_uom_qty', '!=', 0.0), '!', '&', ('order_id.fo_created_by_po_sync', '=', False), ('order_id.state', '=', 'draft')]",partner_id,MISSION,purchase.order.line.sol_update_original_pol,sale.order.line,FO line updates PO line,12,"[('order_id.state', 'in', ['draft', 'draft_p']), ('order_id.partner_type', 'not in', ['external', 'esc']), ('order_id.client_order_ref', '=', False)]",Valid |
978 | msf_sync_data_server.pol_update_date_expected,TRUE,TRUE,"['sync_local_id', 'sync_linked_pol']","[('id', '=', 0)]",partner_id,MISSION,purchase.order.line.update_date_expected,sale.order.line,Update IN expected date,55,,Valid |
979 | +<<<<<<< TREE |
980 | msf_sync_data_server.partial_shipped_coordo_updates_in_at_project,TRUE,TRUE,"['name', 'state', 'origin', 'partner_type_stock_picking', 'shipment_id/name', 'min_date', 'note', 'claim', 'move_lines/processed_stock_move', 'move_lines/id', 'move_lines/state','move_lines/original_qty_partial', 'move_lines/line_number', 'move_lines/name', 'move_lines/change_reason', 'move_lines/product_id/id', 'move_lines/product_id/name', 'move_lines/product_id/default_code', 'move_lines/product_qty', 'move_lines/prodlot_id/id','move_lines/prodlot_id/name','move_lines/prodlot_id/life_date', 'move_lines/prodlot_id/type', 'move_lines/prodlot_id/comment', 'move_lines/expired_date', 'move_lines/asset_id/id','move_lines/product_uom/id', 'move_lines/product_uom/name', 'move_lines/date', 'move_lines/date_expected', 'move_lines/note', 'move_lines/location_dest_id/usage', 'move_lines/comment', 'move_lines/sale_line_id/id', 'move_lines/sale_line_id/in_name_goods_return', 'sale_id/claim_name_goods_return', 'sale_id/client_order_ref']","['&','&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'), ('subtype', 'in', ['standard', 'packing']), ('state', 'in', ['done', 'delivered']), ('already_shipped', '=', True), ('do_not_sync', '=', False)]",partner_id,MISSION,stock.picking.partial_shipped_fo_updates_in_po,stock.picking,Partial shipped at Coordo updates IN at Project,19,,Valid |
981 | +======= |
982 | +msf_sync_data_server.partial_shipped_coordo_updates_in_at_project,TRUE,TRUE,"['name', 'previous_step_id/name', 'state', 'origin', 'partner_type_stock_picking', 'shipment_id/name', 'min_date', 'note', 'claim', 'packing_list', 'move_lines/processed_stock_move', 'move_lines/id', 'move_lines/state','move_lines/original_qty_partial', 'move_lines/line_number', 'move_lines/name', 'move_lines/change_reason', 'move_lines/product_id/id', 'move_lines/product_id/name', 'move_lines/product_id/default_code', 'move_lines/product_qty', 'move_lines/prodlot_id/id','move_lines/prodlot_id/name','move_lines/prodlot_id/life_date', 'move_lines/prodlot_id/type', 'move_lines/prodlot_id/comment', 'move_lines/expired_date', 'move_lines/asset_id/id','move_lines/product_uom/id', 'move_lines/product_uom/name', 'move_lines/date', 'move_lines/date_expected', 'move_lines/note', 'move_lines/location_dest_id/usage', 'move_lines/comment', 'move_lines/sale_line_id/id', 'move_lines/sale_line_id/in_name_goods_return', 'move_lines/from_pack', 'move_lines/to_pack', 'move_lines/weight', 'move_lines/height', 'move_lines/length', 'move_lines/width', 'sale_id/claim_name_goods_return', 'sale_id/client_order_ref']","['&','&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'), ('subtype', 'in', ['standard', 'packing']), ('state', '=', 'done'), ('already_shipped', '=', True), ('do_not_sync', '=', False)]",partner_id,MISSION,stock.picking.partial_shipped_fo_updates_in_po,stock.picking,Partial shipped at Coordo updates IN at Project,19,,Valid |
983 | +>>>>>>> MERGE-SOURCE |
984 | msf_sync_data_server.moves_from_dpo_closed_coordo_updates_in_at_project,TRUE,TRUE,"['name', 'state', 'origin', 'subtype', 'partner_type_stock_picking', 'shipment_id/name', 'min_date', 'note', 'move_lines/processed_stock_move', 'move_lines/id', 'move_lines/state','move_lines/original_qty_partial', 'move_lines/line_number', 'move_lines/name', 'move_lines/change_reason', 'move_lines/product_id/id', 'move_lines/product_id/name', 'move_lines/product_id/default_code', 'move_lines/product_qty', 'move_lines/prodlot_id/id','move_lines/prodlot_id/name','move_lines/prodlot_id/life_date', 'move_lines/prodlot_id/type', 'move_lines/prodlot_id/comment', 'move_lines/expired_date', 'move_lines/asset_id/id','move_lines/product_uom/id', 'move_lines/product_uom/name', 'move_lines/date', 'move_lines/date_expected', 'move_lines/note', 'move_lines/dpo_line_id', 'move_lines/comment']","['&', '&', '&', ('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'), ('subtype', 'in', ['picking', 'standard']), ('dpo_out', '=', True)]",partner_id,MISSION,stock.picking.partial_shippped_dpo_updates_in_po,stock.picking,Moves from DPO closed at Coordo updates IN at Project,20,,Valid |
985 | msf_sync_data_server.dpo_service_lines_update_in_at_project,FALSE,TRUE,"['order_id/name', 'order_id/delivery_confirmed_date', 'sync_local_id', 'origin', 'confirmed_delivery_date', 'name', 'product_uom/id', 'product_uom/name', 'link_sol_id/line_number', 'notes', 'product_qty', 'product_id/name', 'product_id/id', 'product_id/default_code', 'comment']","[('dest_partner_id.partner_type', '=', 'internal'), ('order_id.order_type', '=', 'direct'), ('order_id.state', 'in', ['approved', 'done']), ('product_id.type', 'in', ['service', 'service_recep'])]",dest_partner_id,MISSION,purchase.order.line.confirmed_dpo_service_lines_update_in_po,purchase.order.line,DPO service lines update IN at Project,21,,Valid |
986 | msf_sync_data_server.closed_in_validates_delivery_out_ship,TRUE,TRUE,"['name', 'state', 'shipment_ref']","['&','&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'in'),('subtype', 'in', ['standard']), ('state', '=', 'done'), ('shipment_ref', '!=', False), ('dpo_incoming', '=', False)]",partner_id,MISSION,stock.picking.closed_in_validates_delivery_out_ship,stock.picking,Closed IN validates delivery of OUT-SHIP,26,,Valid |
987 | |
988 | === modified file 'bin/addons/order_types/stock.py' |
989 | --- bin/addons/order_types/stock.py 2019-09-18 14:06:52 +0000 |
990 | +++ bin/addons/order_types/stock.py 2020-08-05 12:54:43 +0000 |
991 | @@ -210,8 +210,10 @@ |
992 | self._check_restriction_line(cr, uid, ids, context=context) |
993 | |
994 | certif = False |
995 | + from_esc = False |
996 | for pick in self.browse(cr, uid, ids, context=context): |
997 | if pick.type in ['in', 'out']: |
998 | + from_esc = pick.partner_id.partner_type == 'esc' and pick.state == 'updated' |
999 | if not context.get('yesorno', False) : |
1000 | for move in pick.move_lines: |
1001 | if move.order_type in ['donation_exp', 'donation_st', 'in_kind']: |
1002 | @@ -256,7 +258,10 @@ |
1003 | if wiz_ids: |
1004 | proc_id = wiz_ids[0] |
1005 | else: |
1006 | - proc_id = wizard_obj.create(cr, uid, {'picking_id': pick.id}) |
1007 | + write_data = {'picking_id': pick.id} |
1008 | + if from_esc: |
1009 | + write_data['fields_as_ro'] = True |
1010 | + proc_id = wizard_obj.create(cr, uid, write_data) |
1011 | wizard_obj.create_lines(cr, uid, proc_id, context=context) |
1012 | |
1013 | res = { |
1014 | |
1015 | === modified file 'bin/addons/sync_client/message.py' |
1016 | --- bin/addons/sync_client/message.py 2019-12-02 17:32:44 +0000 |
1017 | +++ bin/addons/sync_client/message.py 2020-08-05 12:54:43 +0000 |
1018 | @@ -261,21 +261,32 @@ |
1019 | ignored_ids = list(set(obj_ids_temp) - set(obj_ids)) |
1020 | dest = self.pool.get(rule.model).get_destination_name(cr, uid, obj_ids, rule.destination_name, context=context) |
1021 | args = {} |
1022 | - for obj_id in obj_ids: |
1023 | - if initial == False: # default action |
1024 | - args[obj_id] = self.pool.get(rule.model).get_message_arguments(cr, uid, obj_id, rule, context=context) |
1025 | - else: # UF-2483: fake RW sync on creation of the RW instance |
1026 | - args[obj_id] = "Initial RW Sync - Ignore" |
1027 | - |
1028 | generated_ids = [] |
1029 | - for id in obj_ids: |
1030 | - for destination in (dest[id] if hasattr(dest[id], '__iter__') else [dest[id]]): |
1031 | - # UF-2531: allow this when creating usb msg for the INT from scratch from RW to CP |
1032 | - if destination is False: |
1033 | - destination = 'fake' |
1034 | - # UF-2483: By default the "sent" parameter is False |
1035 | - self.create_message(cr, uid, identifiers[id], rule.remote_call, args[id], destination, initial, context) |
1036 | - generated_ids.append(id) |
1037 | + |
1038 | + |
1039 | + if obj_ids and rule.model == 'stock.picking' and rule.remote_call in ('stock.picking.partial_shipped_fo_updates_in_po', 'stock.picking.partial_shippped_dpo_updates_in_po'): |
1040 | + cr.execute("select array_agg(id) from stock_picking where id in %s group by subtype, partner_id, origin, claim, coalesce(shipment_id, id)", (tuple(obj_ids),)) |
1041 | + for picks in cr.fetchall(): |
1042 | + arg = self.pool.get('stock.picking').get_message_arguments(cr, uid, picks[0], rule, context=context) |
1043 | + first_id = picks[0][0] |
1044 | + self.create_message(cr, uid, identifiers[first_id], rule.remote_call, arg, dest[first_id], initial, context) |
1045 | + generated_ids += picks[0] |
1046 | + else: |
1047 | + for obj_id in obj_ids: |
1048 | + if initial == False: # default action |
1049 | + args[obj_id] = self.pool.get(rule.model).get_message_arguments(cr, uid, obj_id, rule, context=context) |
1050 | + else: # UF-2483: fake RW sync on creation of the RW instance |
1051 | + args[obj_id] = "Initial RW Sync - Ignore" |
1052 | + |
1053 | + |
1054 | + for id in obj_ids: |
1055 | + for destination in (dest[id] if hasattr(dest[id], '__iter__') else [dest[id]]): |
1056 | + # UF-2531: allow this when creating usb msg for the INT from scratch from RW to CP |
1057 | + if destination is False: |
1058 | + destination = 'fake' |
1059 | + # UF-2483: By default the "sent" parameter is False |
1060 | + self.create_message(cr, uid, identifiers[id], rule.remote_call, args[id], destination, initial, context) |
1061 | + generated_ids.append(id) |
1062 | |
1063 | return generated_ids, ignored_ids |
1064 | |
1065 | |
1066 | === modified file 'bin/addons/sync_client/orm.py' |
1067 | --- bin/addons/sync_client/orm.py 2020-01-03 13:16:16 +0000 |
1068 | +++ bin/addons/sync_client/orm.py 2020-08-05 12:54:43 +0000 |
1069 | @@ -804,7 +804,9 @@ |
1070 | """ |
1071 | rule_dest_field = rule.destination_name |
1072 | fields = eval(rule.arguments) |
1073 | - res = self.export_data_json(cr, uid, [res_id], fields, destination=destination, rule_dest_field=rule_dest_field, context=context) |
1074 | + if isinstance(res_id, (int, long)): |
1075 | + res_id = [res_id] |
1076 | + res = self.export_data_json(cr, uid, res_id, fields, destination=destination, rule_dest_field=rule_dest_field, context=context) |
1077 | return res['datas'] |
1078 | |
1079 | def export_data_json(self, cr, uid, ids, fields_to_export, destination=False, rule_dest_field=False, context=None): |
1080 | |
1081 | === modified file 'bin/addons/sync_so/picking.py' |
1082 | --- bin/addons/sync_so/picking.py 2019-10-29 09:27:27 +0000 |
1083 | +++ bin/addons/sync_so/picking.py 2020-08-05 12:54:43 +0000 |
1084 | @@ -27,6 +27,7 @@ |
1085 | |
1086 | from sync_common import xmlid_to_sdref |
1087 | from sync_client import get_sale_purchase_logger |
1088 | +from sync_client.message import dict_to_obj |
1089 | |
1090 | from tools.translate import _ |
1091 | |
1092 | @@ -155,68 +156,79 @@ |
1093 | dpo_line_id = data.get('dpo_line_id', False) |
1094 | |
1095 | # build a dic which can be used directly to update the stock move |
1096 | - result = {'line_number': data['line_number'], |
1097 | - 'product_id': product_id, |
1098 | - 'product_uom': uom_id, |
1099 | - 'product_uos': uom_id, |
1100 | - 'uom_id': uom_id, |
1101 | - 'date': data['date'], |
1102 | - 'date_expected': data['date_expected'], |
1103 | - 'state': state, |
1104 | - |
1105 | - 'original_qty_partial': data['original_qty_partial'], # UTP-972 |
1106 | - |
1107 | - 'prodlot_id': batch_id, |
1108 | - 'expired_date': expired_date, |
1109 | - |
1110 | - 'dpo_line_id': dpo_line_id, |
1111 | - 'sync_dpo': dpo_line_id and True or False, |
1112 | - |
1113 | - 'asset_id': asset_id, |
1114 | - 'change_reason': data['change_reason'] or None, |
1115 | - 'name': data['name'], |
1116 | - 'quantity': data['product_qty'] or 0.0, |
1117 | - 'note': data['note'], |
1118 | - 'comment': data.get('comment'), |
1119 | - 'sale_line_id': data.get('sale_line_id', False) and data['sale_line_id'].get('id', False) or False, |
1120 | - } |
1121 | + result = { |
1122 | + 'line_number': data['line_number'], |
1123 | + 'product_id': product_id, |
1124 | + 'product_uom': uom_id, |
1125 | + 'product_uos': uom_id, |
1126 | + 'uom_id': uom_id, |
1127 | + 'date': data['date'], |
1128 | + 'date_expected': data['date_expected'], |
1129 | + 'state': state, |
1130 | + |
1131 | + 'original_qty_partial': data['original_qty_partial'], # UTP-972 |
1132 | + |
1133 | + 'prodlot_id': batch_id, |
1134 | + 'expired_date': expired_date, |
1135 | + |
1136 | + 'dpo_line_id': dpo_line_id, |
1137 | + 'sync_dpo': dpo_line_id and True or False, |
1138 | + |
1139 | + 'asset_id': asset_id, |
1140 | + 'change_reason': data['change_reason'] or None, |
1141 | + 'name': data['name'], |
1142 | + 'quantity': data['product_qty'] or 0.0, |
1143 | + 'note': data['note'], |
1144 | + 'comment': data.get('comment'), |
1145 | + 'sale_line_id': data.get('sale_line_id', False) and data['sale_line_id'].get('id', False) or False, |
1146 | + |
1147 | + } |
1148 | + for k in ['from_pack', 'to_pack', 'weight', 'height', 'length', 'width']: |
1149 | + result[k] = data.get(k) |
1150 | return result |
1151 | |
1152 | - def package_data_update_in(self, cr, uid, source, out_info, context=None): |
1153 | + def package_data_update_in(self, cr, uid, source, pick_dict, context=None): |
1154 | ''' |
1155 | package the data to get info concerning already processed or not |
1156 | ''' |
1157 | result = {} |
1158 | - if out_info.get('move_lines', False): |
1159 | - for line in out_info['move_lines']: |
1160 | - # Don't get the returned pack lines |
1161 | - if line.get('location_dest_id', {}).get('usage', 'customer') == 'customer': |
1162 | - # aggregate according to line number |
1163 | - line_dic = result.setdefault(line.get('line_number'), {}) |
1164 | - # set the data |
1165 | - line_dic.setdefault('data', []).append(self.format_data(cr, uid, line, source, context=context)) |
1166 | - # set the flag to know if the data has already been processed (partially or completely) in Out side |
1167 | - line_dic.update({'out_processed': line_dic.setdefault('out_processed', False) or line['processed_stock_move']}) |
1168 | + for out_info_dict_to_obj in pick_dict: |
1169 | + out_info = out_info_dict_to_obj.to_dict() |
1170 | + if out_info.get('move_lines', False): |
1171 | + for line in out_info['move_lines']: |
1172 | + # Don't get the returned pack lines |
1173 | + if line.get('location_dest_id', {}).get('usage', 'customer') == 'customer': |
1174 | + # aggregate according to line number |
1175 | + line_dic = result.setdefault(line.get('line_number'), {}) |
1176 | + # set the data |
1177 | + line_dic.setdefault('data', []).append(self.format_data(cr, uid, line, source, context=context)) |
1178 | + # set the flag to know if the data has already been processed (partially or completely) in Out side |
1179 | + line_dic.update({'out_processed': line_dic.setdefault('out_processed', False) or line['processed_stock_move']}) |
1180 | + line_dic['data'][-1].update({'packing_list': out_info.get('packing_list'), 'ppl_name': out_info.get('previous_step_id') and out_info.get('previous_step_id').get('name') or out_info.get('name')}) |
1181 | |
1182 | |
1183 | return result |
1184 | |
1185 | - def picking_data_update_in(self, cr, uid, source, out_info, context=None): |
1186 | + def picking_data_update_in(self, cr, uid, source, pick_info, context=None): |
1187 | ''' |
1188 | If data come from a stock move (DPO), re-arrange data to match with partial_shipped_fo_updates_in_po method |
1189 | ''' |
1190 | - result = {} |
1191 | - |
1192 | - for key in out_info.keys(): |
1193 | - if key != 'move_lines': |
1194 | - result[key] = out_info.get(key) |
1195 | - |
1196 | - if out_info.get('subtype', False) in ('standard', 'picking') and out_info.get('move_lines', False): |
1197 | - for line in out_info['move_lines']: |
1198 | - # Don't get the lines without dpo_line_id |
1199 | - if line.get('dpo_line_id', False): |
1200 | - result.setdefault('move_lines', []) |
1201 | - result['move_lines'].append(line) |
1202 | + result = [] |
1203 | + |
1204 | + for data in pick_info: |
1205 | + out_info = data.to_dict() |
1206 | + res = {} |
1207 | + for key in out_info.keys(): |
1208 | + if key != 'move_lines': |
1209 | + res[key] = out_info.get(key) |
1210 | + |
1211 | + if out_info.get('subtype', False) in ('standard', 'picking') and out_info.get('move_lines', False): |
1212 | + for line in out_info['move_lines']: |
1213 | + # Don't get the lines without dpo_line_id |
1214 | + if line.get('dpo_line_id', False): |
1215 | + res.setdefault('move_lines', []) |
1216 | + res['move_lines'].append(line) |
1217 | + result.append(dict_to_obj(res)) |
1218 | |
1219 | return result |
1220 | |
1221 | @@ -241,12 +253,14 @@ |
1222 | if not found: |
1223 | already_shipped_moves.append({move_id: quantity}) |
1224 | |
1225 | - def partial_shipped_fo_updates_in_po(self, cr, uid, source, out_info, context=None): |
1226 | + def partial_shipped_fo_updates_in_po(self, cr, uid, source, *pick_info, **kwargs): |
1227 | ''' |
1228 | ' This sync method is used for updating the IN of Project side when the OUT/PICK at Coordo side became done. |
1229 | ' In partial shipment/OUT, when the last shipment/OUT is made, the original IN will become Available Shipped, no new IN will |
1230 | ' be created, as the whole quantiy of the IN is delivered (but not yet received at Project side) |
1231 | ''' |
1232 | + |
1233 | + context = kwargs.get('context') |
1234 | move_proc = self.pool.get('stock.move.in.processor') |
1235 | if context is None: |
1236 | context = {} |
1237 | @@ -256,13 +270,13 @@ |
1238 | # Load common data (mainly for reason type) into context |
1239 | self.pool.get('data.tools').load_common_data(cr, uid, [], context=context) |
1240 | |
1241 | - if not isinstance(out_info, dict): |
1242 | - pick_dict = out_info.to_dict() |
1243 | - else: |
1244 | - pick_dict = out_info |
1245 | + #if not isinstance(out_info, dict): |
1246 | + # pick_dict = out_info.to_dict() |
1247 | + #else: |
1248 | + # pick_dict = out_info |
1249 | |
1250 | if context.get('for_dpo'): |
1251 | - pick_dict = self.picking_data_update_in(cr, uid, source, pick_dict, context=context) |
1252 | + self.picking_data_update_in(cr, uid, source, pick_info, context=context) |
1253 | #US-1352: Reset this flag immediately, otherwise it will impact on other normal shipments! |
1254 | context.update({'for_dpo': False}) |
1255 | |
1256 | @@ -275,8 +289,9 @@ |
1257 | warehouse_obj = self.pool.get('stock.warehouse') |
1258 | |
1259 | # package data |
1260 | - pack_data = self.package_data_update_in(cr, uid, source, pick_dict, context=context) |
1261 | + pack_data = self.package_data_update_in(cr, uid, source, pick_info, context=context) |
1262 | # Look for the PO name, which has the reference to the FO on Coordo as source.out_info.origin |
1263 | + pick_dict = pick_info[0].to_dict() |
1264 | so_ref = source + "." + pick_dict['origin'] |
1265 | po_id = so_po_common.get_po_id_by_so_ref(cr, uid, so_ref, context) |
1266 | # prepare the shipment/OUT reference to update to IN |
1267 | @@ -295,6 +310,7 @@ |
1268 | if po_ids: |
1269 | po_id = po_ids[0] |
1270 | |
1271 | + |
1272 | if not po_id and not pick_dict.get('claim', False): |
1273 | # UF-1830: Check if the PO exist, if not, and in restore mode, send a warning and create a message to remove the ref on the partner document |
1274 | if context.get('restore_flag'): |
1275 | @@ -362,6 +378,9 @@ |
1276 | |
1277 | in_id = self.create(cr, uid, in_claim_dict, context=context) |
1278 | |
1279 | + pack_info_obj = self.pool.get('wizard.import.in.pack.simulation.screen') |
1280 | + pack_info_created = {} |
1281 | + |
1282 | if in_id: |
1283 | in_name = self.read(cr, uid, in_id, ['name'], context=context)['name'] |
1284 | in_processor = self.pool.get('stock.incoming.processor').create(cr, uid, {'picking_id': in_id}, context=context) |
1285 | @@ -377,6 +396,20 @@ |
1286 | already_shipped_moves = [] |
1287 | # get the corresponding picking line ids |
1288 | for data in line_data['data']: |
1289 | + if data.get('from_pack') and data.get('to_pack'): |
1290 | + pack_key = '%s-%s-%s' % (data.get('from_pack'), data.get('to_pack'), data.get('ppl_name')) |
1291 | + if pack_key not in pack_info_created: |
1292 | + pack_info_created[pack_key] = pack_info_obj.create(cr, uid, { |
1293 | + 'parcel_from': data['from_pack'], |
1294 | + 'parcel_to': data['to_pack'], |
1295 | + 'total_weight': data['weight'], |
1296 | + 'total_height': data['height'], |
1297 | + 'total_length': data['length'], |
1298 | + 'total_width': data['width'], |
1299 | + 'packing_list': data.get('packing_list'), |
1300 | + 'ppl_name': data.get('ppl_name'), |
1301 | + }) |
1302 | + data['pack_info_id'] = pack_info_created[pack_key] |
1303 | ln = data.get('line_number') |
1304 | # UF-2148: if the line contains 0 qty, just ignore it! |
1305 | qty = data.get('quantity', 0) |
1306 | @@ -453,7 +486,7 @@ |
1307 | self._logger.info(message) |
1308 | raise Exception(message) |
1309 | |
1310 | - move_id = False # REF-99: declare the variable before using it, otherwise if it go to else, then line 268 "if not move_id" -> problem! |
1311 | + move_id = False |
1312 | if move_ids and len(move_ids) == 1: # if there is only one move, take it for process |
1313 | move_id = move_ids[0] |
1314 | else: # if there are more than 1 moves, then pick the next one not existing in the partial_datas[in_id] |
1315 | @@ -525,7 +558,7 @@ |
1316 | self._add_to_shipped_moves(already_shipped_moves, move_id, data['quantity']) |
1317 | |
1318 | # for the last Shipment of an FO, no new INcoming shipment will be created --> same value as in_id |
1319 | - new_picking = self.do_incoming_shipment(cr, uid, in_processor, context) |
1320 | + new_picking = self.do_incoming_shipment(cr, uid, in_processor, shipment_ref=shipment_ref, context=context) |
1321 | |
1322 | # Set the backorder reference to the IN !!!! THIS NEEDS TO BE CHECKED WITH SUPPLY PM! |
1323 | if new_picking != in_id: |
1324 | |
1325 | === modified file 'bin/report/report_sxw.py' |
1326 | --- bin/report/report_sxw.py 2020-06-18 15:56:24 +0000 |
1327 | +++ bin/report/report_sxw.py 2020-08-05 12:54:43 +0000 |
1328 | @@ -176,8 +176,10 @@ |
1329 | |
1330 | _fields_process = { |
1331 | 'float': _float_format, |
1332 | + 'float_null': _float_format, |
1333 | 'date': _date_format, |
1334 | 'integer': _int_format, |
1335 | + 'integer_null': _int_format, |
1336 | 'datetime' : _dttime_format |
1337 | } |
1338 |