Merge lp:~jfb-tempo-consulting/unifield-server/US-6374 into lp:unifield-server

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
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+379948@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
=== modified file 'bin/addons/base/rng/view.rng'
--- bin/addons/base/rng/view.rng 2020-02-28 11:04:39 +0000
+++ bin/addons/base/rng/view.rng 2020-08-05 12:54:43 +0000
@@ -596,6 +596,7 @@
596 <rng:optional><rng:attribute name="help"/></rng:optional>596 <rng:optional><rng:attribute name="help"/></rng:optional>
597 <rng:optional><rng:attribute name="default_focus"/></rng:optional>597 <rng:optional><rng:attribute name="default_focus"/></rng:optional>
598 <rng:optional><rng:attribute name="header"/></rng:optional>598 <rng:optional><rng:attribute name="header"/></rng:optional>
599 <rng:optional><rng:attribute name="set_ids"/></rng:optional>
599 <rng:zeroOrMore>600 <rng:zeroOrMore>
600 <rng:choice>601 <rng:choice>
601 <rng:ref name="form" />602 <rng:ref name="form" />
602603
=== modified file 'bin/addons/delivery_mechanism/delivery_mechanism.py'
--- bin/addons/delivery_mechanism/delivery_mechanism.py 2020-03-20 14:08:02 +0000
+++ bin/addons/delivery_mechanism/delivery_mechanism.py 2020-08-05 12:54:43 +0000
@@ -711,11 +711,13 @@
711711
712 return res712 return res
713713
714 def do_incoming_shipment(self, cr, uid, wizard_ids, context=None):714 def do_incoming_shipment(self, cr, uid, wizard_ids, shipment_ref=False, context=None, with_ppl=False):
715 """715 """
716 Take the data in wizard_ids and lines of stock.incoming.processor and716 Take the data in wizard_ids and lines of stock.incoming.processor and
717 do the split of stock.move according to the data.717 do the split of stock.move according to the data.
718 """718 """
719
720
719 # Objects721 # Objects
720 inc_proc_obj = self.pool.get('stock.incoming.processor')722 inc_proc_obj = self.pool.get('stock.incoming.processor')
721 move_proc_obj = self.pool.get('stock.move.in.processor')723 move_proc_obj = self.pool.get('stock.move.in.processor')
@@ -802,7 +804,7 @@
802 line = False804 line = False
803 for line in move_proc_obj.browse(cr, uid, proc_ids, context=context):805 for line in move_proc_obj.browse(cr, uid, proc_ids, context=context):
804 values = self._get_values_from_line(cr, uid, move, line, db_data_dict, context=context)806 values = self._get_values_from_line(cr, uid, move, line, db_data_dict, context=context)
805 if context.get('do_not_process_incoming') and line.pack_info_id:807 if (sync_in or context.get('do_not_process_incoming')) and line.pack_info_id:
806 # we are processing auto import IN, we must register pack_info data808 # we are processing auto import IN, we must register pack_info data
807 values['pack_info_id'] = line.pack_info_id.id809 values['pack_info_id'] = line.pack_info_id.id
808810
@@ -851,7 +853,7 @@
851 if out_values.get('location_dest_id', False):853 if out_values.get('location_dest_id', False):
852 out_values.pop('location_dest_id')854 out_values.pop('location_dest_id')
853855
854 if line.pack_info_id:856 if with_ppl and line.pack_info_id:
855 all_pack_info[line.pack_info_id.id] = True857 all_pack_info[line.pack_info_id.id] = True
856 remaining_out_qty = line.quantity858 remaining_out_qty = line.quantity
857 out_move = None859 out_move = None
@@ -981,7 +983,16 @@
981 processed_out_moves_by_exp.setdefault(line.prodlot_id and line.prodlot_id.life_date or False, []).append(out_move.id)983 processed_out_moves_by_exp.setdefault(line.prodlot_id and line.prodlot_id.life_date or False, []).append(out_move.id)
982 else:984 else:
983 # Just update the data of the initial out move985 # Just update the data of the initial out move
984 processed_qty = lst_out_move is out_moves[-1] and uom_partial_qty - minus_qty or out_move.product_qty986 if lst_out_move is out_moves[-1]:
987 processed_qty = uom_partial_qty - minus_qty
988 if processed_qty <= 0:
989 processed_qty = out_move.product_qty
990 elif context.get('auto_import_ok'):
991 # IN pre-processing : do not add extra qty in OUT, it will be added later on IN processing
992 processed_qty = out_move.product_qty
993 else:
994 processed_qty = out_move.product_qty
995
985 out_values.update({996 out_values.update({
986 'product_qty': processed_qty,997 'product_qty': processed_qty,
987 'product_uom': line.uom_id.id,998 'product_uom': line.uom_id.id,
@@ -1053,6 +1064,7 @@
1053 })1064 })
10541065
1055 backorder_id = False1066 backorder_id = False
1067 backorder_ids = False
1056 if context.get('for_dpo', False) and picking_dict['purchase_id']:1068 if context.get('for_dpo', False) and picking_dict['purchase_id']:
1057 # Look for an available IN for the same purchase order in case of DPO1069 # Look for an available IN for the same purchase order in case of DPO
1058 backorder_ids = self.search(cr, uid, [1070 backorder_ids = self.search(cr, uid, [
@@ -1060,8 +1072,15 @@
1060 ('in_dpo', '=', True),1072 ('in_dpo', '=', True),
1061 ('state', '=', 'assigned'),1073 ('state', '=', 'assigned'),
1062 ], limit=1, context=context)1074 ], limit=1, context=context)
1063 if backorder_ids:1075 elif sync_in and picking_dict['purchase_id'] and shipment_ref:
1064 backorder_id = backorder_ids[0]1076 backorder_ids = self.search(cr, uid, [
1077 ('purchase_id', '=', picking_dict['purchase_id'][0]),
1078 ('shipment_ref', '=', shipment_ref),
1079 ('state', '=', 'shipped'),
1080 ], limit=1, context=context)
1081
1082 if backorder_ids:
1083 backorder_id = backorder_ids[0]
10651084
1066 backorder_name = picking_dict['name']1085 backorder_name = picking_dict['name']
1067 if not backorder_id:1086 if not backorder_id:
10681087
=== modified file 'bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py'
--- bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2020-07-02 15:09:34 +0000
+++ bin/addons/msf_doc_import/wizard/wizard_in_simulation_screen.py 2020-08-05 12:54:43 +0000
@@ -245,7 +245,7 @@
245 'context': context,245 'context': context,
246 }246 }
247247
248 def launch_import(self, cr, uid, ids, context=None):248 def launch_import(self, cr, uid, ids, context=None, with_ppl=False):
249 '''249 '''
250 '''250 '''
251 if context is None:251 if context is None:
@@ -254,10 +254,10 @@
254 if isinstance(ids, (int, long)):254 if isinstance(ids, (int, long)):
255 ids = [ids]255 ids = [ids]
256256
257 return self._import(cr, uid, ids, context=context)257 return self._import(cr, uid, ids, context=context, with_ppl=with_ppl)
258258
259 def launch_import_pack(self, cr, uid, ids, context=None):259 def launch_import_pack(self, cr, uid, ids, context=None):
260 return self.launch_import(cr, uid, ids, context)260 return self.launch_import(cr, uid, ids, context, with_ppl=True)
261261
262 def populate(self, cr, uid, import_id, picking_id, context=None):262 def populate(self, cr, uid, import_id, picking_id, context=None):
263 if context is None:263 if context is None:
@@ -519,6 +519,50 @@
519519
520 return values, nb_line, error520 return values, nb_line, error
521521
522 def error_pick_already_processed(self, cr, uid, sol_id_sum, sol_id_to_wiz_line, context):
523 if not sol_id_sum:
524 return ''
525 cr.execute('''
526 select m.sale_line_id, sum(m.product_qty)
527 from stock_move m, stock_picking p
528 where
529 m.picking_id = p.id and
530 p.type = 'out' and
531 p.subtype = 'picking' and
532 p.state = 'draft' and
533 m.state in ('assigned', 'confirmed') and
534 m.sale_line_id in %s
535 group by
536 m.sale_line_id
537 ''', (tuple(sol_id_sum.keys()),))
538 extra_qty = {}
539 for x in cr.fetchall():
540 if x[1] < sol_id_sum[x[0]]:
541 extra_qty[x[0]] = sol_id_sum[x[0]] - x[1]
542
543 already_process = {}
544 if extra_qty:
545 cr.execute('''
546 select m.sale_line_id, sum(m.product_qty)
547 from stock_move m, stock_picking p
548 where
549 m.picking_id = p.id and
550 p.type = 'out' and
551 p.state not in ('draft', 'cancel') and
552 m.sale_line_id in %s
553 group by
554 m.sale_line_id
555 ''', (tuple(extra_qty.keys()),))
556 for x in cr.fetchall():
557 already_process[x[0]] = x[1]
558
559 if already_process:
560 details = []
561 for sol in self.pool.get('sale.order.line').browse(cr, uid, already_process.keys(), fields_to_fetch=['product_id'], context=context):
562 details.append('Line number: %s, [%s] %s' % (sol_id_to_wiz_line.get(sol.id),sol.product_id.default_code, sol.product_id.name))
563 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))
564 return ''
565
522 # Simulation routing566 # Simulation routing
523 def simulate(self, dbname, uid, ids, context=None):567 def simulate(self, dbname, uid, ids, context=None):
524 '''568 '''
@@ -966,6 +1010,27 @@
966 err = _('Line %s of the Excel file: %s') % (file_line[0], err)1010 err = _('Line %s of the Excel file: %s') % (file_line[0], err)
967 values_line_errors.append(err)1011 values_line_errors.append(err)
9681012
1013 if wiz.with_pack and not context.get('auto_import_ok'):
1014 # check if an out line has been forced
1015 cr.execute('''
1016 select wiz_line.line_number, pol.linked_sol_id, sum(wiz_line.imp_product_qty)
1017 from wizard_import_in_line_simulation_screen wiz_line
1018 left join wizard_import_in_simulation_screen wiz on wiz.id = wiz_line.simu_id
1019 left join stock_move move_in on move_in.picking_id = wiz.picking_id and move_in.line_number = wiz_line.line_number
1020 left join purchase_order_line pol on pol.id = move_in.purchase_line_id
1021 where
1022 (wiz_line.type_change in ('', 'split') or wiz_line.type_change is NULL) and
1023 wiz.id = %s
1024 group by wiz_line.line_number, pol.linked_sol_id
1025 ''', (wiz.id,))
1026 sol_id_to_wiz_line = {}
1027 sol_id_sum = {}
1028 for x in cr.fetchall():
1029 sol_id_to_wiz_line[x[1]] = x[0]
1030 sol_id_sum[x[1]] = x[2]
1031 error_pick = self.error_pick_already_processed(cr, uid, sol_id_sum, sol_id_to_wiz_line, context)
1032 if error_pick:
1033 values_line_errors.append(error_pick)
9691034
970 # Create new lines1035 # Create new lines
971 for in_line in new_in_lines:1036 for in_line in new_in_lines:
@@ -1049,7 +1114,7 @@
10491114
1050 return {'type': 'ir.actions.act_window_close'}1115 return {'type': 'ir.actions.act_window_close'}
10511116
1052 def _import_with_thread(self, cr, uid, partial_id, simu_id, context=None):1117 def _import_with_thread(self, cr, uid, partial_id, simu_id, context=None, with_ppl=False):
1053 inc_proc_obj = self.pool.get('stock.incoming.processor')1118 inc_proc_obj = self.pool.get('stock.incoming.processor')
1054 in_proc_obj = self.pool.get('stock.move.in.processor')1119 in_proc_obj = self.pool.get('stock.move.in.processor')
1055 picking_obj = self.pool.get('stock.picking')1120 picking_obj = self.pool.get('stock.picking')
@@ -1063,7 +1128,7 @@
1063 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)1128 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)
1064 in_proc_obj.write(new_cr, uid, [line.id], {'prodlot_id': prodlot_id}, context=context)1129 in_proc_obj.write(new_cr, uid, [line.id], {'prodlot_id': prodlot_id}, context=context)
10651130
1066 new_picking = picking_obj.do_incoming_shipment(new_cr, uid, partial_id, context=context)1131 new_picking = picking_obj.do_incoming_shipment(new_cr, uid, partial_id, context=context, with_ppl=with_ppl)
1067 if isinstance(new_picking, (int,long)):1132 if isinstance(new_picking, (int,long)):
1068 context['new_picking'] = new_picking1133 context['new_picking'] = new_picking
1069 new_cr.commit()1134 new_cr.commit()
@@ -1087,7 +1152,7 @@
1087 return True1152 return True
10881153
10891154
1090 def _import(self, cr, uid, ids, context=None):1155 def _import(self, cr, uid, ids, context=None, with_ppl=False):
1091 '''1156 '''
1092 Create memeory moves and return to the standard incoming processing wizard1157 Create memeory moves and return to the standard incoming processing wizard
1093 '''1158 '''
@@ -1122,9 +1187,9 @@
1122 cr.commit()1187 cr.commit()
1123 if context.get('do_not_import_with_thread'):1188 if context.get('do_not_import_with_thread'):
1124 # Auto VI IN import: do not process IN1189 # Auto VI IN import: do not process IN
1125 self._import_with_thread(cr, uid, [partial_id], simu_id.id, context=context)1190 self._import_with_thread(cr, uid, [partial_id], simu_id.id, context=context, with_ppl=with_ppl)
1126 else:1191 else:
1127 new_thread = threading.Thread(target=self._import_with_thread, args=(cr, uid, [partial_id], simu_id.id, context))1192 new_thread = threading.Thread(target=self._import_with_thread, args=(cr, uid, [partial_id], simu_id.id, context, with_ppl))
1128 new_thread.start()1193 new_thread.start()
1129 new_thread.join(20)1194 new_thread.join(20)
1130 if new_thread.isAlive():1195 if new_thread.isAlive():
@@ -1157,18 +1222,35 @@
1157 _name = 'wizard.import.in.pack.simulation.screen'1222 _name = 'wizard.import.in.pack.simulation.screen'
1158 _rec_name = 'parcel_from'1223 _rec_name = 'parcel_from'
11591224
1225 def _get_real_total(self, cr, uid, ids, f, a, context=None):
1226 res = {}
1227 for pack in self.browse(cr, uid, ids, context=context):
1228 res[pack.id] = {'real_total_volume': False, 'real_total_weight': False}
1229
1230 if pack.parcel_to and pack.parcel_from:
1231 nb_pack = pack.parcel_to - pack.parcel_from + 1
1232 if pack.total_weight:
1233 res[pack.id]['real_total_weight'] = int(round(nb_pack * pack.total_weight, 0))
1234 if pack.total_height and pack.total_length and pack.total_width:
1235 res[pack.id]['real_total_volume'] = int(round(pack.total_height * pack.total_length * pack.total_width * nb_pack / 1000, 0))
1236 return res
1237
1160 _columns = {1238 _columns = {
1161 'wizard_id': fields.many2one('wizard.import.in.simulation.screen', 'Simu Wizard'),1239 'wizard_id': fields.many2one('wizard.import.in.simulation.screen', 'Simu Wizard'),
1162 'parcel_from': fields.integer('Parcel From'),1240 'parcel_from': fields.integer_null('Parcel From'),
1163 'parcel_to': fields.integer('Parcel To'),1241 'parcel_to': fields.integer_null('Parcel To'),
1164 'parcel_qty': fields.integer('Parcel Qty'),1242 'parcel_qty': fields.integer_null('Parcel Qty'),
1165 'total_weight': fields.float('Weight', digits=(16,2)),1243 # on IN VI import file the fields are named total_xxx but the figures are p.p
1166 'total_volume': fields.float('Volume', digits=(16,2)),1244 'total_weight': fields.float_null('Weight', digits=(16,2)),
1167 'total_height': fields.float('Height', digits=(16,2)),1245 'total_volume': fields.float_null('Volume', digits=(16,2)),
1168 'total_length': fields.float('Length', digits=(16,2)),1246 'total_height': fields.float_null('Height', digits=(16,2)),
1169 'total_width': fields.float('Width', digits=(16,2)),1247 'total_length': fields.float_null('Length', digits=(16,2)),
1248 'total_width': fields.float_null('Width', digits=(16,2)),
1170 'packing_list': fields.char('Supplier Packing List', size=30),1249 'packing_list': fields.char('Supplier Packing List', size=30),
1250 'ppl_name': fields.char('Supplier Packing List', size=128),
1171 'integrity_status': fields.selection(string='Integrity Status', selection=PACK_INTEGRITY_STATUS_SELECTION, readonly=True),1251 'integrity_status': fields.selection(string='Integrity Status', selection=PACK_INTEGRITY_STATUS_SELECTION, readonly=True),
1252 'real_total_volume': fields.function(_get_real_total, method=True, type='integer_null', string='Total volume for all packs', multi='real_total'),
1253 'real_total_weight': fields.function(_get_real_total, method=True, type='integer_null', string='Total weight for all packs', multi='real_total'),
1172 }1254 }
11731255
1174 _defaults = {1256 _defaults = {
11751257
=== modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py'
--- bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2019-08-28 08:33:22 +0000
+++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2020-08-05 12:54:43 +0000
@@ -125,10 +125,11 @@
125 context = {}125 context = {}
126126
127 res = {}127 res = {}
128 for wiz in self.browse(cr, uid, ids, context=context):128 for wiz in self.browse(cr, uid, ids, fields_to_fetch=['linked_to_out', 'picking_id'], context=context):
129 res[wiz.id] = False129 res[wiz.id] = False
130 if wiz.picking_id and wiz.picking_id.state == 'updated' and wiz.linked_to_out:130 if wiz.picking_id and wiz.linked_to_out:
131 res[wiz.id] = True131 if not self.pool.get('stock.move.in.processor').search_exist(cr, uid, [('wizard_id', '=', wiz.id),('pack_info_id', '=', False)], context=context):
132 res[wiz.id] = wiz.linked_to_out
132133
133 return res134 return res
134135
@@ -158,7 +159,6 @@
158159
159 return res160 return res
160161
161
162 _columns = {162 _columns = {
163 'move_ids': fields.one2many(163 'move_ids': fields.one2many(
164 'stock.move.in.processor',164 'stock.move.in.processor',
@@ -194,7 +194,7 @@
194 ),194 ),
195 'draft': fields.boolean('Draft'),195 'draft': fields.boolean('Draft'),
196 'already_processed': fields.boolean('Already processed'),196 'already_processed': fields.boolean('Already processed'),
197 'linked_to_out': fields.boolean('Is this IN linked to a single Pick (same FO) ?'),197 '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),
198 'register_a_claim': fields.boolean(198 'register_a_claim': fields.boolean(
199 string='Register a Claim to Supplier',199 string='Register a Claim to Supplier',
200 ),200 ),
@@ -218,8 +218,10 @@
218 'claim_description': fields.text(218 'claim_description': fields.text(
219 string='Claim Description',219 string='Claim Description',
220 ),220 ),
221 'display_process_to_ship_button': fields.function(_get_display_process_to_ship_button, method=True, type='boolean', string='Process to ship'),221 'display_process_to_ship_button': fields.function(_get_display_process_to_ship_button, method=True, type='char', string='Process to ship'),
222 'location_dest_active_ok': fields.function(_get_location_dest_active_ok, method=True, type='boolean', string='Dest location is inactive ?', store=False),222 'location_dest_active_ok': fields.function(_get_location_dest_active_ok, method=True, type='boolean', string='Dest location is inactive ?', store=False),
223 'fields_as_ro': fields.boolean('Set Cost/Split .. as RO', internal=True),
224 'sequence_issue': fields.boolean('Issue with To ship'),
223 }225 }
224226
225 _defaults = {227 _defaults = {
@@ -248,17 +250,33 @@
248 picking = picking_obj.browse(cr, uid, vals.get('picking_id'), context=context)250 picking = picking_obj.browse(cr, uid, vals.get('picking_id'), context=context)
249251
250 cr.execute("""252 cr.execute("""
251 select so.id from253 select so.id, array_agg(distinct(out.name)), count(distinct(so.procurement_request)) from
252 stock_move m254 stock_move m
253 left join stock_picking p on m.picking_id = p.id255 left join stock_picking p on m.picking_id = p.id
254 left join purchase_order_line pol on m.purchase_line_id = pol.id256 left join purchase_order_line pol on m.purchase_line_id = pol.id
255 left join sale_order_line sol on sol.id = pol.linked_sol_id257 left join sale_order_line sol on sol.id = pol.linked_sol_id
256 left join sale_order so on so.id = sol.order_id258 left join sale_order so on so.id = sol.order_id
257 where m.picking_id = %s and so.procurement_request = 'f' and coalesce(p.claim, 'f') = 'f'259 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'))
260 where
261 m.picking_id = %s and
262 coalesce(p.claim, 'f') = 'f'
258 group by so.id263 group by so.id
259 """, (vals.get('picking_id'), ))264 """, (vals.get('picking_id'), ))
260 if cr.rowcount == 1:265 if cr.rowcount == 1:
261 vals['linked_to_out'] = True266 fetch_data = cr.fetchone()
267 if fetch_data[2] > 1:
268 # IN mixed with FO/IR
269 vals['linked_to_out'] = False
270
271 out_names = fetch_data[1]
272 out_type = False
273 for out_name in out_names:
274 if out_name and out_name.startswith('OUT/'):
275 out_type = out_name
276 break
277 if not out_type:
278 out_type = out_names and len(out_names) == 1 and out_names[0] and out_names[0].startswith('PICK/') and 'picking' or False
279 vals['linked_to_out'] = out_type
262 else:280 else:
263 vals['linked_to_out'] = False281 vals['linked_to_out'] = False
264282
@@ -623,8 +641,18 @@
623641
624642
625 def launch_simulation_pack(self, cr, uid, ids, context=None):643 def launch_simulation_pack(self, cr, uid, ids, context=None):
644 if context is None:
645 context = {}
646
647 if not context.get('auto_import_ok'):
648 out = self.read(cr, uid, ids[0], ['linked_to_out'], context=context)
649 if out['linked_to_out'] != 'picking':
650 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'])
651
626 data = self.launch_simulation(cr, uid, ids, context)652 data = self.launch_simulation(cr, uid, ids, context)
627 self.pool.get('wizard.import.in.simulation.screen').write(cr, uid, data['res_id'], {'with_pack': True})653 self.pool.get('wizard.import.in.simulation.screen').write(cr, uid, data['res_id'], {'with_pack': True})
654
655
628 data['name'] = _('Incoming shipment simulation screen (pick and pack mode)')656 data['name'] = _('Incoming shipment simulation screen (pick and pack mode)')
629657
630 file_attached = self.check_if_has_import_file_in_attachment(cr, uid, ids, context=context)658 file_attached = self.check_if_has_import_file_in_attachment(cr, uid, ids, context=context)
@@ -634,7 +662,8 @@
634 'filetype': self.pool.get('stock.picking').get_import_filetype(cr, uid, file_attached['name'], context=context),662 'filetype': self.pool.get('stock.picking').get_import_filetype(cr, uid, file_attached['name'], context=context),
635 }, context=context)663 }, context=context)
636 self.pool.get('wizard.import.in.simulation.screen').launch_simulate(cr, uid, data['res_id'], context=context)664 self.pool.get('wizard.import.in.simulation.screen').launch_simulate(cr, uid, data['res_id'], context=context)
637 self.pool.get('wizard.import.in.simulation.screen').launch_import_pack(cr, uid, data['res_id'], context=context)665 # the following line process the IN but display the simu screen
666 #self.pool.get('wizard.import.in.simulation.screen').launch_import_pack(cr, uid, data['res_id'], context=context)
638 return data667 return data
639668
640669
@@ -657,11 +686,6 @@
657 if num_of_packs:686 if num_of_packs:
658 if not self.pool.get('ppl.processor')._check_rounding(cr, uid, move.uom_id, num_of_packs, move.quantity, context=context):687 if not self.pool.get('ppl.processor')._check_rounding(cr, uid, move.uom_id, num_of_packs, move.quantity, context=context):
659 rounding_issues.append(move.line_number)688 rounding_issues.append(move.line_number)
660 if move.integrity_status and move.integrity_status != 'empty':
661 raise osv.except_osv(
662 _('Error'),
663 _('Please correct red lines before processing')
664 )
665689
666 if not total_qty:690 if not total_qty:
667 raise osv.except_osv(691 raise osv.except_osv(
@@ -731,10 +755,35 @@
731 if isinstance(ids, (int,long)):755 if isinstance(ids, (int,long)):
732 ids = [ids]756 ids = [ids]
733757
758 out = self.read(cr, uid, ids[0], ['linked_to_out'], context=context)
759 if out['linked_to_out'] != 'picking':
760 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'])
761
734 rounding_issues, sequence_ok = self.check_before_creating_pack_lines(cr, uid, ids, context=context)762 rounding_issues, sequence_ok = self.check_before_creating_pack_lines(cr, uid, ids, context=context)
763 cr.execute('''
764 select wiz_line.line_number, pol.linked_sol_id, sum(wiz_line.quantity)
765 from stock_move_in_processor wiz_line
766 left join stock_incoming_processor wiz on wiz.id = wiz_line.wizard_id
767 left join stock_move move_in on move_in.picking_id = wiz.picking_id and move_in.line_number = wiz_line.line_number
768 left join purchase_order_line pol on pol.id = move_in.purchase_line_id
769 where
770 wiz.id = %s
771 group by wiz_line.line_number, pol.linked_sol_id
772 ''', (ids[0],))
773 sol_id_to_wiz_line = {}
774 sol_id_sum = {}
775 for x in cr.fetchall():
776 sol_id_to_wiz_line[x[1]] = x[0]
777 sol_id_sum[x[1]] = x[2]
778
779 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)
780 if error_pick:
781 raise osv.except_osv(_('Error'), error_pick)
735782
736 if not sequence_ok:783 if not sequence_ok:
737 view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'msf_outgoing', 'stock_incoming_processor_form_view')[1]784 view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'msf_outgoing', 'stock_incoming_processor_form_view')[1]
785 self.write(cr, uid, ids, {'sequence_issue': True}, context=context)
786
738 return {787 return {
739 'name': _('Products to Process'),788 'name': _('Products to Process'),
740 'type': 'ir.actions.act_window',789 'type': 'ir.actions.act_window',
@@ -765,7 +814,8 @@
765 'context': context,814 'context': context,
766 }815 }
767816
768 return self.do_process_to_ship(cr, uid, ids, context=context)817 self.pool.get('stock.picking').do_incoming_shipment(cr, uid, ids, context=context, with_ppl=True)
818 return {'type': 'ir.actions.act_window_close'}
769819
770820
771 def do_process_to_ship(self, cr, uid, ids, context=None):821 def do_process_to_ship(self, cr, uid, ids, context=None):
@@ -851,6 +901,7 @@
851 _name = 'stock.move.in.processor'901 _name = 'stock.move.in.processor'
852 _inherit = 'stock.move.processor'902 _inherit = 'stock.move.processor'
853 _description = 'Wizard lines for incoming shipment processing'903 _description = 'Wizard lines for incoming shipment processing'
904 _order = 'line_number, from_pack, id'
854905
855 def _get_move_info(self, cr, uid, ids, field_name, args, context=None):906 def _get_move_info(self, cr, uid, ids, field_name, args, context=None):
856 return super(stock_move_in_processor, self)._get_move_info(cr, uid, ids, field_name, args, context=context)907 return super(stock_move_in_processor, self)._get_move_info(cr, uid, ids, field_name, args, context=context)
@@ -958,6 +1009,31 @@
958 cr.execute(sql, (value, ml_id))1009 cr.execute(sql, (value, ml_id))
959 return True1010 return True
9601011
1012 def _get_pack_info(self, cr, uid, ids, field_name, args, context=None):
1013 if context is None:
1014 context = {}
1015 if isinstance(ids, (int,long)):
1016 ids = [ids]
1017
1018 res = {}
1019 for wiz in self.browse(cr, uid, ids, fields_to_fetch=['from_pack', 'to_pack'], context=context):
1020 if wiz['from_pack']:
1021 res[wiz.id] = '%s-%s' % (wiz['from_pack'], wiz['to_pack'])
1022 else:
1023 res[wiz.id] = False
1024 return res
1025
1026 def _search_pack_info(self, cr, uid, obj, name, args, context):
1027 dom = []
1028 for arg in args:
1029 if arg[2]:
1030 d_p = arg[2].split('-')
1031 if d_p and d_p[0] and d_p[0].strip():
1032 dom = [('from_pack', '=', d_p[0].strip())]
1033 if d_p and len(d_p)>1 and d_p[1] and d_p[1].strip():
1034 dom.append(('to_pack', '=', d_p[1].strip()))
1035 return dom
1036
961 _columns = {1037 _columns = {
962 # Parent wizard1038 # Parent wizard
963 'wizard_id': fields.many2one(1039 'wizard_id': fields.many2one(
@@ -1184,17 +1260,21 @@
1184 help="Ticked if the product is a Controlled Substance",1260 help="Ticked if the product is a Controlled Substance",
1185 ),1261 ),
1186 'pack_info_id': fields.many2one('wizard.import.in.pack.simulation.screen', 'Pack Info'),1262 'pack_info_id': fields.many2one('wizard.import.in.pack.simulation.screen', 'Pack Info'),
1187 'from_pack': fields.integer(string='From p.'),1263 'from_pack': fields.integer_null(string='From p.'),
1188 'to_pack': fields.integer(string='To p.'),1264 'to_pack': fields.integer_null(string='To p.'),
1189 'weight': fields.float('Weight', digits=(16,2)),1265 'weight': fields.float_null('Weight', digits=(16,2)),
1190 'volume': fields.float('Volume', digits=(16,2)),1266 'volume': fields.float_null('Volume', digits=(16,2)),
1191 'height': fields.float('Height', digits=(16,2)),1267 'height': fields.float_null('Height', digits=(16,2)),
1192 'length': fields.float('Length', digits=(16,2)),1268 'total_volume': fields.float_null(u'Total Volume [dm³]', digits=(16,0)),
1193 'width': fields.float('Width', digits=(16,2)),1269 'total_weight': fields.float_null(u'Total Weight [kg]', digits=(16,0)),
1270 'length': fields.float_null('Length', digits=(16,2)),
1271 'width': fields.float_null('Width', digits=(16,2)),
1194 'pack_id': fields.many2one('in.family.processor', string='Pack', ondelete='set null'),1272 'pack_id': fields.many2one('in.family.processor', string='Pack', ondelete='set null'),
1195 'packing_list': fields.char('Supplier Packing List', size=30),1273 'packing_list': fields.char('Supplier Packing List', size=30),
1274 'ppl_name': fields.char('Packing List', size=128),
1196 'sequence_issue': fields.selection(PACK_INTEGRITY_STATUS_SELECTION, 'Sequence issue', readonly=True),1275 'sequence_issue': fields.selection(PACK_INTEGRITY_STATUS_SELECTION, 'Sequence issue', readonly=True),
1197 'split_move_ok': fields.boolean(string='Is split move ?'),1276 'split_move_ok': fields.boolean(string='Is split move ?'),
1277 'filter_pack': fields.function(_get_pack_info, method=True, type='char', string='Pack', fnct_search=_search_pack_info),
1198 }1278 }
11991279
12001280
@@ -1217,13 +1297,21 @@
1217 if context is None:1297 if context is None:
1218 context = {}1298 context = {}
12191299
1300 if not vals.get('cost'):
1301 # issue on IN processor from sync if new line created (because of a split in coordo)
1302 # then the price_unit should not come from product standard_price but from the original stock.move (i.e: from POL)
1303 # before this the unit price was temporary set to the standard_price, but changed on IN processing, this was too late
1304 if vals.get('move_id'):
1305 move_data = self.pool.get('stock.move').browse(cr, uid, vals['move_id'], fields_to_fetch=['price_unit', 'currency_id'], context=context)
1306 vals['cost'] = move_data.price_unit
1307 vals['currency'] = move_data.currency_id.id
1308
1220 if vals.get('product_id', False):1309 if vals.get('product_id', False):
1221 if not vals.get('cost', False):1310 if not vals.get('cost', False):
1222 price = product_obj.browse(cr, uid, vals['product_id'], context=context).standard_price1311 price = product_obj.browse(cr, uid, vals['product_id'], context=context).standard_price
1223 vals['cost'] = price1312 vals['cost'] = price
1224 if not vals.get('currency', False):1313 if not vals.get('currency', False):
1225 vals['currency'] = user_obj.browse(cr, uid, uid, context=context).company_id.currency_id.id1314 vals['currency'] = user_obj.browse(cr, uid, uid, context=context).company_id.currency_id.id
1226
1227 return super(stock_move_in_processor, self).create(cr, uid, vals, context=context)1315 return super(stock_move_in_processor, self).create(cr, uid, vals, context=context)
12281316
12291317
12301318
=== modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml'
--- bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml 2019-08-28 08:33:22 +0000
+++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor_view.xml 2020-08-05 12:54:43 +0000
@@ -12,11 +12,13 @@
12 <field name="linked_to_out" invisible="1"/>12 <field name="linked_to_out" invisible="1"/>
13 <field name="picking_id" invisible="1" />13 <field name="picking_id" invisible="1" />
14 <field name="display_process_to_ship_button" invisible="1" />14 <field name="display_process_to_ship_button" invisible="1" />
15 <button name="copy_all" type="object" icon="gtk-jump-to" colspan="2" string="Copy all" />15 <field name="sequence_issue" invisible="1" />
16 <button name="uncopy_all" type="object" icon="gtk-undo" colspan="2" string="Clear all" />16 <field name="fields_as_ro" invisible="1" />
17 <button name="copy_all" type="object" icon="gtk-jump-to" colspan="2" string="Copy all" set_ids="move_ids"/>
18 <button name="uncopy_all" type="object" icon="gtk-undo" colspan="2" string="Clear all" set_ids="move_ids"/>
17 <group name="import_file_lines" string="Import Lines" colspan="4">19 <group name="import_file_lines" string="Import Lines" colspan="4">
18 <button name="launch_simulation" string="Import IN" icon="gtk-execute" colspan="1" type="object" />20 <button name="launch_simulation" string="Import IN" icon="gtk-execute" colspan="1" type="object" />
19 <button name="launch_simulation_pack" string="Import IN, process IN &amp; pick and pack" icon="gtk-execute" colspan="1" type="object" attrs="{'invisible': [('linked_to_out', '!=', True)]}"/>21 <button name="launch_simulation_pack" string="Import IN, process IN &amp; pick and pack" icon="gtk-execute" colspan="1" type="object" attrs="{'invisible': [('linked_to_out', '=', False)]}"/>
20 </group>22 </group>
21 <field name="contains_dg" invisible="1" />23 <field name="contains_dg" invisible="1" />
22 <field name="contains_kc" invisible="1" />24 <field name="contains_kc" invisible="1" />
@@ -49,6 +51,15 @@
49 </p>51 </p>
50 </html>52 </html>
51 </group>53 </group>
54 <group colspan="4" attrs="{'invisible': [('sequence_issue', '=', False)]}">
55 <html>
56 <p style="text-align: center; v-align: middle;color:#f27d0c; font-weight:bold; font-size:1.2em">
57 <img src="/openerp/static/images/stock/gtk-dialog-warning.png" height="12" width="12" />
58 <span><translate>Please correct red lines before processing or do not process to ship</translate></span>
59 <img src="/openerp/static/images/stock/gtk-dialog-warning.png" height="12" width="12" />
60 </p>
61 </html>
62 </group>
52 <separator colspan="4" string="Move lines" />63 <separator colspan="4" string="Move lines" />
53 <field name="move_ids" mode="tree" context="{'display_process_to_ship_button': display_process_to_ship_button}"64 <field name="move_ids" mode="tree" context="{'display_process_to_ship_button': display_process_to_ship_button}"
54 colspan="4" nolabel="1" />65 colspan="4" nolabel="1" />
@@ -88,7 +99,7 @@
88 <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', True)]}" />99 <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', True)]}" />
89 <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', False)]}"100 <button name="do_incoming_shipment" type="object" string="Process" icon="gtk-go-forward" attrs="{'invisible': [('location_dest_active_ok', '!=', False)]}"
90 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 ?" />101 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 ?" />
91 <button name="process_to_ship" attrs="{'invisible': [('display_process_to_ship_button', '!=', True)]}" type="object" string="Process to ship" icon="gtk-goto-last" />102 <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" />
92 </group>103 </group>
93 </form>104 </form>
94 </field>105 </field>
@@ -129,6 +140,7 @@
129 hide_delete_button="1"140 hide_delete_button="1"
130 hide_new_button="1"141 hide_new_button="1"
131 colors="red:integrity_status!='empty'"142 colors="red:integrity_status!='empty'"
143 editable_style="new"
132 >144 >
133 <!-- Invisible fields -->145 <!-- Invisible fields -->
134 <field name="type_check" invisible="1" />146 <field name="type_check" invisible="1" />
@@ -146,6 +158,7 @@
146 type="object"158 type="object"
147 icon="gtk-convert"159 icon="gtk-convert"
148 string="Change Product"160 string="Change Product"
161 attrs="{'invisible': [('fields_as_ro', '=', True)]}"
149 />162 />
150 <field name="asset_id"163 <field name="asset_id"
151 domain="[('product_id', '=', product_id)]"164 domain="[('product_id', '=', product_id)]"
@@ -164,14 +177,20 @@
164 <field name="uom_id"177 <field name="uom_id"
165 domain="[('category_id', '=', ordered_uom_category)]"178 domain="[('category_id', '=', ordered_uom_category)]"
166 on_change="onchange_uom_qty(uom_id, quantity)"179 on_change="onchange_uom_qty(uom_id, quantity)"
180 attrs="{'readonly': [('fields_as_ro', '=', True)]}"
167 />181 />
168 <field name="from_pack" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" />182 <field name="from_pack" readonly="1" />
169 <field name="to_pack" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" />183 <field name="to_pack" readonly="1" />
170 <field name="packing_list" on_change="onchange_from_pack_to_pack()" invisible="not context.get('display_process_to_ship_button')" />184 <field name="filter_pack" filter_selector="1" invisible="1" />
185 <field name="total_volume" readonly="1" />
186 <field name="total_weight" readonly="1" />
187 <field name="ppl_name" readonly="1" filter_selector="1" />
188 <field name="packing_list" readonly="1" filter_selector="1" />
171 <button name="open_split_wizard"189 <button name="open_split_wizard"
172 type="object"190 type="object"
173 icon="terp-stock_effects-object-colorize"191 icon="terp-stock_effects-object-colorize"
174 string="Split"192 string="Split"
193 attrs="{'invisible': [('fields_as_ro', '=', True)]}"
175 />194 />
176 <field name="prodlot_id"195 <field name="prodlot_id"
177 domain="[('product_id', '=', product_id), ('check_type', '=', True)]"196 domain="[('product_id', '=', product_id), ('check_type', '=', True)]"
@@ -187,7 +206,7 @@
187 <field name="kc_check" widget="null_boolean" />206 <field name="kc_check" widget="null_boolean" />
188 <field name="dg_check" widget="null_boolean" />207 <field name="dg_check" widget="null_boolean" />
189 <field name="np_check" widget="null_boolean" />208 <field name="np_check" widget="null_boolean" />
190 <field name="cost" />209 <field name="cost" attrs="{'readonly': [('fields_as_ro', '=', True)]}" />
191 <field name="currency" />210 <field name="currency" />
192 <field name="integrity_status" string="" />211 <field name="integrity_status" string="" />
193 </tree>212 </tree>
194213
=== modified file 'bin/addons/msf_outgoing/wizard/picking_processor.py'
--- bin/addons/msf_outgoing/wizard/picking_processor.py 2018-11-07 14:53:50 +0000
+++ bin/addons/msf_outgoing/wizard/picking_processor.py 2020-08-05 12:54:43 +0000
@@ -144,6 +144,21 @@
144 _('No wizard found !'),144 _('No wizard found !'),
145 )145 )
146146
147 if self._name == 'stock.incoming.processor':
148 line_obj = self.pool.get('stock.move.in.processor')
149 dom = context.get('selected_domain', [])
150 if dom:
151 dom = ['&', ('wizard_id', '=', ids[0])] + dom
152 else:
153 dom = [('wizard_id', '=', ids[0])]
154 lines_ids = line_obj.search(cr, uid, dom, context=context)
155 for move in line_obj.browse(cr, uid, lines_ids, context=context):
156 line_obj.write(cr, uid, [move.id], {'quantity': move.ordered_quantity}, context=context)
157 return {
158 'type': 'ir.actions.refresh_o2m',
159 'o2m_refresh': 'move_ids'
160 }
161
147 for wizard in self.browse(cr, uid, ids, context=context):162 for wizard in self.browse(cr, uid, ids, context=context):
148 for move in wizard.move_ids:163 for move in wizard.move_ids:
149 self.pool.get(move._name).write(cr, uid, [move.id], {'quantity': move.ordered_quantity}, context=context)164 self.pool.get(move._name).write(cr, uid, [move.id], {'quantity': move.ordered_quantity}, context=context)
@@ -173,6 +188,21 @@
173 _('No wizard found !'),188 _('No wizard found !'),
174 )189 )
175190
191 if self._name == 'stock.incoming.processor':
192 line_obj = self.pool.get('stock.move.in.processor')
193 dom = context.get('selected_domain', [])
194 if dom:
195 dom = ['&', ('wizard_id', '=', ids[0])] + dom
196 else:
197 dom = [('wizard_id', '=', ids[0])]
198 lines_ids = line_obj.search(cr, uid, dom, context=context)
199 for move in line_obj.browse(cr, uid, lines_ids, context=context):
200 line_obj.write(cr, uid, [move.id], {'quantity': 0}, context=context)
201 return {
202 'type': 'ir.actions.refresh_o2m',
203 'o2m_refresh': 'move_ids'
204 }
205
176 for wizard in self.browse(cr, uid, ids, context=context):206 for wizard in self.browse(cr, uid, ids, context=context):
177 move_obj = wizard.move_ids[0]._name207 move_obj = wizard.move_ids[0]._name
178 move_ids = [x.id for x in wizard.move_ids]208 move_ids = [x.id for x in wizard.move_ids]
@@ -218,13 +248,17 @@
218 'from_pack': move.pack_info_id.parcel_from,248 'from_pack': move.pack_info_id.parcel_from,
219 'to_pack': move.pack_info_id.parcel_to,249 'to_pack': move.pack_info_id.parcel_to,
220 'weight': move.pack_info_id.total_weight,250 'weight': move.pack_info_id.total_weight,
251 'total_weight': move.pack_info_id.real_total_weight,
221 'volume': move.pack_info_id.total_volume,252 'volume': move.pack_info_id.total_volume,
253 'total_volume': move.pack_info_id.real_total_volume,
222 'height': move.pack_info_id.total_height,254 'height': move.pack_info_id.total_height,
223 'length': move.pack_info_id.total_length,255 'length': move.pack_info_id.total_length,
224 'width': move.pack_info_id.total_width,256 'width': move.pack_info_id.total_width,
225 'packing_list': move.pack_info_id.packing_list,257 'packing_list': move.pack_info_id.packing_list,
258 'ppl_name': move.pack_info_id.ppl_name,
226 'cost': move.price_unit,259 'cost': move.price_unit,
227 'currency': move.currency_id.id,260 'currency': move.currency_id.id,
261 'pack_info_id': move.pack_info_id.id,
228 })262 })
229 line_obj.create(cr, uid, line_data, context=context)263 line_obj.create(cr, uid, line_data, context=context)
230264
@@ -1060,6 +1094,7 @@
1060 'nodestroy': True,1094 'nodestroy': True,
1061 'target': 'new',1095 'target': 'new',
1062 'res_id': split_wiz_id,1096 'res_id': split_wiz_id,
1097 'keep_open': 1,
1063 'context': context,1098 'context': context,
1064 }1099 }
10651100
10661101
=== modified file 'bin/addons/msf_outgoing/wizard/split_move_processor.py'
--- bin/addons/msf_outgoing/wizard/split_move_processor.py 2019-04-09 08:05:03 +0000
+++ bin/addons/msf_outgoing/wizard/split_move_processor.py 2020-08-05 12:54:43 +0000
@@ -83,6 +83,11 @@
83 return {83 return {
84 'type': 'ir.actions.act_window_close'84 'type': 'ir.actions.act_window_close'
85 }85 }
86 elif wiz['processor_type'] == 'stock.move.in.processor':
87 return {
88 'type': 'ir.actions.refresh_popupo2m',
89 'o2m_refresh': 'move_ids'
90 }
86 line_model = self.pool.get(wiz['processor_type'])91 line_model = self.pool.get(wiz['processor_type'])
87 line = line_model.browse(cr, uid, wiz['processor_line_id'], context=context)92 line = line_model.browse(cr, uid, wiz['processor_line_id'], context=context)
88 res_model = line_model._columns['wizard_id']._obj93 res_model = line_model._columns['wizard_id']._obj
8994
=== modified file 'bin/addons/msf_printed_documents/report/report_reception.py'
--- bin/addons/msf_printed_documents/report/report_reception.py 2020-07-29 16:14:59 +0000
+++ bin/addons/msf_printed_documents/report/report_reception.py 2020-08-05 12:54:43 +0000
@@ -32,7 +32,7 @@
32 'time': time,32 'time': time,
33 'getState': self.getState,33 'getState': self.getState,
34 'enumerate': enumerate,34 'enumerate': enumerate,
35 'get_lines': self.get_lines,35 'get_lines_by_packing': self.get_lines_by_packing,
36 'getDateCreation': self.getDateCreation,36 'getDateCreation': self.getDateCreation,
37 'getNbItem': self.getNbItem,37 'getNbItem': self.getNbItem,
38 'check': self.check,38 'check': self.check,
@@ -215,10 +215,16 @@
215 actual_receipt_date = time.strftime('%d/%m/%Y', time.strptime(o.date_done, '%Y-%m-%d %H:%M:%S'))215 actual_receipt_date = time.strftime('%d/%m/%Y', time.strptime(o.date_done, '%Y-%m-%d %H:%M:%S'))
216 return actual_receipt_date216 return actual_receipt_date
217217
218 def get_lines(self, o):218 def get_lines_by_packing(self, o):
219 return o.move_lines219 pack_info = {}
220220 for line in o.move_lines:
221221 pack_info.setdefault(line.pack_info_id or False, []).append(line)
222
223<<<<<<< TREE
224
225=======
226 return sorted(pack_info.items(), key=lambda x: x[0] and (x[0].ppl_name, x[0].packing_list, x[0].parcel_from))
227>>>>>>> MERGE-SOURCE
222report_sxw.report_sxw('report.msf.report_reception_in', 'stock.picking', 'addons/msf_printed_documents/report/report_reception.rml', parser=report_reception, header=False)228report_sxw.report_sxw('report.msf.report_reception_in', 'stock.picking', 'addons/msf_printed_documents/report/report_reception.rml', parser=report_reception, header=False)
223229
224# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:230# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
225231
=== modified file 'bin/addons/msf_printed_documents/report/report_reception.rml'
--- bin/addons/msf_printed_documents/report/report_reception.rml 2020-06-18 15:56:24 +0000
+++ bin/addons/msf_printed_documents/report/report_reception.rml 2020-08-05 12:54:43 +0000
@@ -106,7 +106,7 @@
106 <blockTableStyle id="OrderInformations2">106 <blockTableStyle id="OrderInformations2">
107 <blockAlignment value="CENTER" />107 <blockAlignment value="CENTER" />
108 <blockVAlign value="CENTER" />108 <blockVAlign value="CENTER" />
109 <blockBackground colorName="silver" start="0,6" stop="0,6" />109 <blockBackground colorName="silver" start="0,7" stop="0,7" />
110 <lineStyle kind="GRID" colorName="#000000" start="0,6" stop="-1,-1" thickness="0.5"/>110 <lineStyle kind="GRID" colorName="#000000" start="0,6" stop="-1,-1" thickness="0.5"/>
111 <blockTopPadding value="0" />111 <blockTopPadding value="0" />
112 <blockBottomPadding value="0" />112 <blockBottomPadding value="0" />
@@ -121,6 +121,20 @@
121 <lineStyle kind="LINEBEFORE" colorName="black" start="2,0" thickness="0.5" />121 <lineStyle kind="LINEBEFORE" colorName="black" start="2,0" thickness="0.5" />
122 </blockTableStyle>122 </blockTableStyle>
123123
124 <blockTableStyle id="PackingList">
125 <blockAlignment value="CENTER" />
126 <blockValign value="MIDDLE" />
127 <blockTopPadding value="10" />
128 <blockBottomPadding value="0" />
129 <blockBackground colorName="silver" start="0,0" stop="0,0" />
130 <blockBackground colorName="silver" start="2,0" stop="2,0" />
131 <blockBackground colorName="silver" start="4,0" stop="4,0" />
132 <blockBackground colorName="silver" start="6,0" stop="6,0" />
133 <blockBackground colorName="silver" start="8,0" stop="8,0" />
134 <blockBackground colorName="silver" start="10,0" stop="10,0" />
135 <lineStyle kind="LINEBEFORE" colorName="black" start="0,0" thickness="0.5" />
136 </blockTableStyle>
137
124 <blockTableStyle id="OrderInformations4">138 <blockTableStyle id="OrderInformations4">
125 <blockValign value="MIDDLE" />139 <blockValign value="MIDDLE" />
126 <lineStyle kind="INNERGRID" colorName="#000000" thickness="0.5" />140 <lineStyle kind="INNERGRID" colorName="#000000" thickness="0.5" />
@@ -410,7 +424,9 @@
410 <tr><td></td></tr>424 <tr><td></td></tr>
411 </blockTable>425 </blockTable>
412426
413 <blockTable colWidths="800.0" style="OrderInformations2" repeatRows="7">427<section>
428 [[ repeatIn(get_lines_by_packing(objects[0]), 'pack') ]]
429 <blockTable colWidths="800.0" style="OrderInformations2" repeatRows="8">
414430
415 <tr><td></td></tr>431 <tr><td></td></tr>
416 <tr>432 <tr>
@@ -476,23 +492,72 @@
476492
477 </td>493 </td>
478 </tr>494 </tr>
495 <tr>
496 <td>
497 <blockTable colWidths="60,80,100,70,60,30,50,40,90,75,91,54" style="PackingList">
498 <tr>
499 <td>
500 <para style="TextInformation5" alignment="CENTER">Packing List</para>
501 </td>
502
503 <td>
504 <para style="TextInformation5" alignment="CENTER">[[ pack[0].ppl_name ]]</para>
505
506 </td>
507
508 <td>
509 <para style="TextInformation5" alignment="CENTER">Supplier Packing List</para>
510 </td>
511 <td>
512 <para style="TextInformation5" alignment="CENTER">[[ pack[0].packing_list ]]</para>
513 </td>
514 <td>
515 <para style="TextInformation5" alignment="CENTER">From parcel</para>
516 </td>
517 <td>
518 <para style="TextInformation5" alignment="CENTER">[[ pack[0].parcel_from or '' ]]</para>
519 </td>
520 <td>
521 <para style="TextInformation5" alignment="CENTER">To parcel</para>
522 </td>
523 <td>
524 <para style="TextInformation5" alignment="CENTER">[[ pack[0].parcel_to or '' ]]</para>
525 </td>
526 <td>
527 <para style="TextInformation5" alignment="CENTER">Total volume</para>
528 </td>
529 <td>
530 <para style="TextInformation5" alignment="CENTER">[[ pack[0].real_total_volume and u'%s dm³'%pack[0].real_total_volume or '' ]]</para>
531 </td>
532 <td>
533 <para style="TextInformation5" alignment="CENTER">Total weight</para>
534 </td>
535 <td>
536 <para style="TextInformation5" alignment="CENTER">[[ pack[0].real_total_weight and '%s kg'%pack[0].real_total_weight or '' ]]</para>
537 </td>
538 </tr>
539 </blockTable>
540
541
542 </td>
543 </tr>
479544
480 <tr>545 <tr>
481 <td>546 <td>
482 <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3">547 <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3">
483 <tr>548 <tr>
484 <td>549 <td>
485 <para style="TextInformation4" alignment="CENTER">Item</para>550 <para style="TextInformation4" alignment="CENTER">Item</para> <!-- 30 -->
486 </td>551 </td>
487552
488 <td>553 <td>
489 <blockTable colWidths="110,260" style="OrderInformations4">554 <blockTable colWidths="110,260" style="OrderInformations4">
490 <tr>555 <tr>
491 <td>556 <td>
492 <para style="TextInformation" alignment="LEFT">Code</para>557 <para style="TextInformation" alignment="LEFT">Code</para> <!-- 110 -->
493 </td>558 </td>
494 <td>559 <td>
495 <para style="TextInformation" alignment="LEFT">Description</para>560 <para style="TextInformation" alignment="LEFT">Description</para> <!-- 260 -->
496 </td>561 </td>
497 </tr>562 </tr>
498 <tr>563 <tr>
@@ -508,37 +573,37 @@
508 </td>573 </td>
509574
510 <td>575 <td>
511 <para style="TextInformation5" alignment="CENTER">Qty confirmed</para>576 <para style="TextInformation5" alignment="CENTER">Qty confirmed</para> <!-- 50 -->
512 </td>577 </td>
513 <td>578 <td>
514 <para style="TextInformation5" alignment="CENTER">Unit of Measure</para>579 <para style="TextInformation5" alignment="CENTER">Unit of Measure</para> <!-- 40 -->
515 </td>580 </td>
516 <td>581 <td>
517 <para style="TextInformation5" alignment="CENTER">Qty backorder</para>582 <para style="TextInformation5" alignment="CENTER">Qty backorder</para> <!-- 50 -->
518 </td>583 </td>
519 <td>584 <td>
520 <para style="TextInformation5" alignment="CENTER">Qty received</para>585 <para style="TextInformation5" alignment="CENTER">Qty received</para> <!-- 40 -->
521 </td>586 </td>
522 <td>587 <td>
523 <para style="TextInformation5" alignment="CENTER">Batch / Serial number</para>588 <para style="TextInformation5" alignment="CENTER">Batch / Serial number</para> <!-- 75 -->
524 </td>589 </td>
525 <td>590 <td>
526 <para style="TextInformation5" alignment="CENTER">Expiry date</para>591 <para style="TextInformation5" alignment="CENTER">Expiry date</para> <!-- 53 -->
527 </td>592 </td>
528 <td>593 <td>
529 <para style="TextInformation4" alignment="CENTER">ED</para>594 <para style="TextInformation4" alignment="CENTER">ED</para> <!-- 20 -->
530 </td>595 </td>
531 <td>596 <td>
532 <para style="TextInformation4" alignment="CENTER">BM</para>597 <para style="TextInformation4" alignment="CENTER">BM</para> <!-- 18 -->
533 </td>598 </td>
534 <td>599 <td>
535 <para style="TextInformation4" alignment="CENTER">KC</para>600 <para style="TextInformation4" alignment="CENTER">KC</para> <!-- 18 -->
536 </td>601 </td>
537 <td>602 <td>
538 <para style="TextInformation4" alignment="CENTER">DG</para>603 <para style="TextInformation4" alignment="CENTER">DG</para> <!-- 18 -->
539 </td>604 </td>
540 <td>605 <td>
541 <para style="TextInformation4" alignment="CENTER">CS</para>606 <para style="TextInformation4" alignment="CENTER">CS</para> <!-- 18 -->
542 </td>607 </td>
543 </tr>608 </tr>
544 </blockTable>609 </blockTable>
@@ -552,7 +617,7 @@
552617
553618
554 <tr>619 <tr>
555 [[ repeatIn(get_lines(objects[0]), 'line') ]]620 [[ repeatIn(pack[1], 'line') ]]
556 <td>621 <td>
557 <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3">622 <blockTable colWidths="30,370,50,40,50,40,75,53,20,18,18,18,18" style="OrderInformations3">
558 <tr>623 <tr>
@@ -622,6 +687,7 @@
622 </tr>687 </tr>
623688
624 </blockTable>689 </blockTable>
690</section>
625691
626 <blockTable colWidths="800.0" style="OrderInformationsRien" >692 <blockTable colWidths="800.0" style="OrderInformationsRien" >
627 <tr>693 <tr>
628694
=== modified file 'bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv'
--- bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv 2020-06-09 09:58:28 +0000
+++ bin/addons/msf_sync_data_server/data/sync_server.message_rule.csv 2020-08-05 12:54:43 +0000
@@ -8,7 +8,11 @@
8msf_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,,Valid8msf_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
9msf_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)]",Valid9msf_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
10msf_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,,Valid10msf_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
11<<<<<<< TREE
11msf_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,,Valid12msf_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
13=======
14msf_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
15>>>>>>> MERGE-SOURCE
12msf_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,,Valid16msf_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
13msf_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,,Valid17msf_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
14msf_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,,Valid18msf_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
1519
=== modified file 'bin/addons/order_types/stock.py'
--- bin/addons/order_types/stock.py 2019-09-18 14:06:52 +0000
+++ bin/addons/order_types/stock.py 2020-08-05 12:54:43 +0000
@@ -210,8 +210,10 @@
210 self._check_restriction_line(cr, uid, ids, context=context)210 self._check_restriction_line(cr, uid, ids, context=context)
211211
212 certif = False212 certif = False
213 from_esc = False
213 for pick in self.browse(cr, uid, ids, context=context):214 for pick in self.browse(cr, uid, ids, context=context):
214 if pick.type in ['in', 'out']:215 if pick.type in ['in', 'out']:
216 from_esc = pick.partner_id.partner_type == 'esc' and pick.state == 'updated'
215 if not context.get('yesorno', False) :217 if not context.get('yesorno', False) :
216 for move in pick.move_lines:218 for move in pick.move_lines:
217 if move.order_type in ['donation_exp', 'donation_st', 'in_kind']:219 if move.order_type in ['donation_exp', 'donation_st', 'in_kind']:
@@ -256,7 +258,10 @@
256 if wiz_ids:258 if wiz_ids:
257 proc_id = wiz_ids[0]259 proc_id = wiz_ids[0]
258 else:260 else:
259 proc_id = wizard_obj.create(cr, uid, {'picking_id': pick.id})261 write_data = {'picking_id': pick.id}
262 if from_esc:
263 write_data['fields_as_ro'] = True
264 proc_id = wizard_obj.create(cr, uid, write_data)
260 wizard_obj.create_lines(cr, uid, proc_id, context=context)265 wizard_obj.create_lines(cr, uid, proc_id, context=context)
261266
262 res = {267 res = {
263268
=== modified file 'bin/addons/sync_client/message.py'
--- bin/addons/sync_client/message.py 2019-12-02 17:32:44 +0000
+++ bin/addons/sync_client/message.py 2020-08-05 12:54:43 +0000
@@ -261,21 +261,32 @@
261 ignored_ids = list(set(obj_ids_temp) - set(obj_ids))261 ignored_ids = list(set(obj_ids_temp) - set(obj_ids))
262 dest = self.pool.get(rule.model).get_destination_name(cr, uid, obj_ids, rule.destination_name, context=context)262 dest = self.pool.get(rule.model).get_destination_name(cr, uid, obj_ids, rule.destination_name, context=context)
263 args = {}263 args = {}
264 for obj_id in obj_ids:
265 if initial == False: # default action
266 args[obj_id] = self.pool.get(rule.model).get_message_arguments(cr, uid, obj_id, rule, context=context)
267 else: # UF-2483: fake RW sync on creation of the RW instance
268 args[obj_id] = "Initial RW Sync - Ignore"
269
270 generated_ids = []264 generated_ids = []
271 for id in obj_ids:265
272 for destination in (dest[id] if hasattr(dest[id], '__iter__') else [dest[id]]):266
273 # UF-2531: allow this when creating usb msg for the INT from scratch from RW to CP267 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'):
274 if destination is False:268 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),))
275 destination = 'fake'269 for picks in cr.fetchall():
276 # UF-2483: By default the "sent" parameter is False270 arg = self.pool.get('stock.picking').get_message_arguments(cr, uid, picks[0], rule, context=context)
277 self.create_message(cr, uid, identifiers[id], rule.remote_call, args[id], destination, initial, context)271 first_id = picks[0][0]
278 generated_ids.append(id)272 self.create_message(cr, uid, identifiers[first_id], rule.remote_call, arg, dest[first_id], initial, context)
273 generated_ids += picks[0]
274 else:
275 for obj_id in obj_ids:
276 if initial == False: # default action
277 args[obj_id] = self.pool.get(rule.model).get_message_arguments(cr, uid, obj_id, rule, context=context)
278 else: # UF-2483: fake RW sync on creation of the RW instance
279 args[obj_id] = "Initial RW Sync - Ignore"
280
281
282 for id in obj_ids:
283 for destination in (dest[id] if hasattr(dest[id], '__iter__') else [dest[id]]):
284 # UF-2531: allow this when creating usb msg for the INT from scratch from RW to CP
285 if destination is False:
286 destination = 'fake'
287 # UF-2483: By default the "sent" parameter is False
288 self.create_message(cr, uid, identifiers[id], rule.remote_call, args[id], destination, initial, context)
289 generated_ids.append(id)
279290
280 return generated_ids, ignored_ids291 return generated_ids, ignored_ids
281292
282293
=== modified file 'bin/addons/sync_client/orm.py'
--- bin/addons/sync_client/orm.py 2020-01-03 13:16:16 +0000
+++ bin/addons/sync_client/orm.py 2020-08-05 12:54:43 +0000
@@ -804,7 +804,9 @@
804 """804 """
805 rule_dest_field = rule.destination_name805 rule_dest_field = rule.destination_name
806 fields = eval(rule.arguments)806 fields = eval(rule.arguments)
807 res = self.export_data_json(cr, uid, [res_id], fields, destination=destination, rule_dest_field=rule_dest_field, context=context)807 if isinstance(res_id, (int, long)):
808 res_id = [res_id]
809 res = self.export_data_json(cr, uid, res_id, fields, destination=destination, rule_dest_field=rule_dest_field, context=context)
808 return res['datas']810 return res['datas']
809811
810 def export_data_json(self, cr, uid, ids, fields_to_export, destination=False, rule_dest_field=False, context=None):812 def export_data_json(self, cr, uid, ids, fields_to_export, destination=False, rule_dest_field=False, context=None):
811813
=== modified file 'bin/addons/sync_so/picking.py'
--- bin/addons/sync_so/picking.py 2019-10-29 09:27:27 +0000
+++ bin/addons/sync_so/picking.py 2020-08-05 12:54:43 +0000
@@ -27,6 +27,7 @@
2727
28from sync_common import xmlid_to_sdref28from sync_common import xmlid_to_sdref
29from sync_client import get_sale_purchase_logger29from sync_client import get_sale_purchase_logger
30from sync_client.message import dict_to_obj
3031
31from tools.translate import _32from tools.translate import _
3233
@@ -155,68 +156,79 @@
155 dpo_line_id = data.get('dpo_line_id', False)156 dpo_line_id = data.get('dpo_line_id', False)
156157
157 # build a dic which can be used directly to update the stock move158 # build a dic which can be used directly to update the stock move
158 result = {'line_number': data['line_number'],159 result = {
159 'product_id': product_id,160 'line_number': data['line_number'],
160 'product_uom': uom_id,161 'product_id': product_id,
161 'product_uos': uom_id,162 'product_uom': uom_id,
162 'uom_id': uom_id,163 'product_uos': uom_id,
163 'date': data['date'],164 'uom_id': uom_id,
164 'date_expected': data['date_expected'],165 'date': data['date'],
165 'state': state,166 'date_expected': data['date_expected'],
166167 'state': state,
167 'original_qty_partial': data['original_qty_partial'], # UTP-972168
168169 'original_qty_partial': data['original_qty_partial'], # UTP-972
169 'prodlot_id': batch_id,170
170 'expired_date': expired_date,171 'prodlot_id': batch_id,
171172 'expired_date': expired_date,
172 'dpo_line_id': dpo_line_id,173
173 'sync_dpo': dpo_line_id and True or False,174 'dpo_line_id': dpo_line_id,
174175 'sync_dpo': dpo_line_id and True or False,
175 'asset_id': asset_id,176
176 'change_reason': data['change_reason'] or None,177 'asset_id': asset_id,
177 'name': data['name'],178 'change_reason': data['change_reason'] or None,
178 'quantity': data['product_qty'] or 0.0,179 'name': data['name'],
179 'note': data['note'],180 'quantity': data['product_qty'] or 0.0,
180 'comment': data.get('comment'),181 'note': data['note'],
181 'sale_line_id': data.get('sale_line_id', False) and data['sale_line_id'].get('id', False) or False,182 'comment': data.get('comment'),
182 }183 'sale_line_id': data.get('sale_line_id', False) and data['sale_line_id'].get('id', False) or False,
184
185 }
186 for k in ['from_pack', 'to_pack', 'weight', 'height', 'length', 'width']:
187 result[k] = data.get(k)
183 return result188 return result
184189
185 def package_data_update_in(self, cr, uid, source, out_info, context=None):190 def package_data_update_in(self, cr, uid, source, pick_dict, context=None):
186 '''191 '''
187 package the data to get info concerning already processed or not192 package the data to get info concerning already processed or not
188 '''193 '''
189 result = {}194 result = {}
190 if out_info.get('move_lines', False):195 for out_info_dict_to_obj in pick_dict:
191 for line in out_info['move_lines']:196 out_info = out_info_dict_to_obj.to_dict()
192 # Don't get the returned pack lines197 if out_info.get('move_lines', False):
193 if line.get('location_dest_id', {}).get('usage', 'customer') == 'customer':198 for line in out_info['move_lines']:
194 # aggregate according to line number199 # Don't get the returned pack lines
195 line_dic = result.setdefault(line.get('line_number'), {})200 if line.get('location_dest_id', {}).get('usage', 'customer') == 'customer':
196 # set the data201 # aggregate according to line number
197 line_dic.setdefault('data', []).append(self.format_data(cr, uid, line, source, context=context))202 line_dic = result.setdefault(line.get('line_number'), {})
198 # set the flag to know if the data has already been processed (partially or completely) in Out side203 # set the data
199 line_dic.update({'out_processed': line_dic.setdefault('out_processed', False) or line['processed_stock_move']})204 line_dic.setdefault('data', []).append(self.format_data(cr, uid, line, source, context=context))
205 # set the flag to know if the data has already been processed (partially or completely) in Out side
206 line_dic.update({'out_processed': line_dic.setdefault('out_processed', False) or line['processed_stock_move']})
207 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')})
200208
201209
202 return result210 return result
203211
204 def picking_data_update_in(self, cr, uid, source, out_info, context=None):212 def picking_data_update_in(self, cr, uid, source, pick_info, context=None):
205 '''213 '''
206 If data come from a stock move (DPO), re-arrange data to match with partial_shipped_fo_updates_in_po method214 If data come from a stock move (DPO), re-arrange data to match with partial_shipped_fo_updates_in_po method
207 '''215 '''
208 result = {}216 result = []
209217
210 for key in out_info.keys():218 for data in pick_info:
211 if key != 'move_lines':219 out_info = data.to_dict()
212 result[key] = out_info.get(key)220 res = {}
213221 for key in out_info.keys():
214 if out_info.get('subtype', False) in ('standard', 'picking') and out_info.get('move_lines', False):222 if key != 'move_lines':
215 for line in out_info['move_lines']:223 res[key] = out_info.get(key)
216 # Don't get the lines without dpo_line_id224
217 if line.get('dpo_line_id', False):225 if out_info.get('subtype', False) in ('standard', 'picking') and out_info.get('move_lines', False):
218 result.setdefault('move_lines', [])226 for line in out_info['move_lines']:
219 result['move_lines'].append(line)227 # Don't get the lines without dpo_line_id
228 if line.get('dpo_line_id', False):
229 res.setdefault('move_lines', [])
230 res['move_lines'].append(line)
231 result.append(dict_to_obj(res))
220232
221 return result233 return result
222234
@@ -241,12 +253,14 @@
241 if not found:253 if not found:
242 already_shipped_moves.append({move_id: quantity})254 already_shipped_moves.append({move_id: quantity})
243255
244 def partial_shipped_fo_updates_in_po(self, cr, uid, source, out_info, context=None):256 def partial_shipped_fo_updates_in_po(self, cr, uid, source, *pick_info, **kwargs):
245 '''257 '''
246 ' This sync method is used for updating the IN of Project side when the OUT/PICK at Coordo side became done.258 ' This sync method is used for updating the IN of Project side when the OUT/PICK at Coordo side became done.
247 ' In partial shipment/OUT, when the last shipment/OUT is made, the original IN will become Available Shipped, no new IN will259 ' In partial shipment/OUT, when the last shipment/OUT is made, the original IN will become Available Shipped, no new IN will
248 ' be created, as the whole quantiy of the IN is delivered (but not yet received at Project side)260 ' be created, as the whole quantiy of the IN is delivered (but not yet received at Project side)
249 '''261 '''
262
263 context = kwargs.get('context')
250 move_proc = self.pool.get('stock.move.in.processor')264 move_proc = self.pool.get('stock.move.in.processor')
251 if context is None:265 if context is None:
252 context = {}266 context = {}
@@ -256,13 +270,13 @@
256 # Load common data (mainly for reason type) into context270 # Load common data (mainly for reason type) into context
257 self.pool.get('data.tools').load_common_data(cr, uid, [], context=context)271 self.pool.get('data.tools').load_common_data(cr, uid, [], context=context)
258272
259 if not isinstance(out_info, dict):273 #if not isinstance(out_info, dict):
260 pick_dict = out_info.to_dict()274 # pick_dict = out_info.to_dict()
261 else:275 #else:
262 pick_dict = out_info276 # pick_dict = out_info
263277
264 if context.get('for_dpo'):278 if context.get('for_dpo'):
265 pick_dict = self.picking_data_update_in(cr, uid, source, pick_dict, context=context)279 self.picking_data_update_in(cr, uid, source, pick_info, context=context)
266 #US-1352: Reset this flag immediately, otherwise it will impact on other normal shipments!280 #US-1352: Reset this flag immediately, otherwise it will impact on other normal shipments!
267 context.update({'for_dpo': False})281 context.update({'for_dpo': False})
268282
@@ -275,8 +289,9 @@
275 warehouse_obj = self.pool.get('stock.warehouse')289 warehouse_obj = self.pool.get('stock.warehouse')
276290
277 # package data291 # package data
278 pack_data = self.package_data_update_in(cr, uid, source, pick_dict, context=context)292 pack_data = self.package_data_update_in(cr, uid, source, pick_info, context=context)
279 # Look for the PO name, which has the reference to the FO on Coordo as source.out_info.origin293 # Look for the PO name, which has the reference to the FO on Coordo as source.out_info.origin
294 pick_dict = pick_info[0].to_dict()
280 so_ref = source + "." + pick_dict['origin']295 so_ref = source + "." + pick_dict['origin']
281 po_id = so_po_common.get_po_id_by_so_ref(cr, uid, so_ref, context)296 po_id = so_po_common.get_po_id_by_so_ref(cr, uid, so_ref, context)
282 # prepare the shipment/OUT reference to update to IN297 # prepare the shipment/OUT reference to update to IN
@@ -295,6 +310,7 @@
295 if po_ids:310 if po_ids:
296 po_id = po_ids[0]311 po_id = po_ids[0]
297312
313
298 if not po_id and not pick_dict.get('claim', False):314 if not po_id and not pick_dict.get('claim', False):
299 # 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 document315 # 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
300 if context.get('restore_flag'):316 if context.get('restore_flag'):
@@ -362,6 +378,9 @@
362378
363 in_id = self.create(cr, uid, in_claim_dict, context=context)379 in_id = self.create(cr, uid, in_claim_dict, context=context)
364380
381 pack_info_obj = self.pool.get('wizard.import.in.pack.simulation.screen')
382 pack_info_created = {}
383
365 if in_id:384 if in_id:
366 in_name = self.read(cr, uid, in_id, ['name'], context=context)['name']385 in_name = self.read(cr, uid, in_id, ['name'], context=context)['name']
367 in_processor = self.pool.get('stock.incoming.processor').create(cr, uid, {'picking_id': in_id}, context=context)386 in_processor = self.pool.get('stock.incoming.processor').create(cr, uid, {'picking_id': in_id}, context=context)
@@ -377,6 +396,20 @@
377 already_shipped_moves = []396 already_shipped_moves = []
378 # get the corresponding picking line ids397 # get the corresponding picking line ids
379 for data in line_data['data']:398 for data in line_data['data']:
399 if data.get('from_pack') and data.get('to_pack'):
400 pack_key = '%s-%s-%s' % (data.get('from_pack'), data.get('to_pack'), data.get('ppl_name'))
401 if pack_key not in pack_info_created:
402 pack_info_created[pack_key] = pack_info_obj.create(cr, uid, {
403 'parcel_from': data['from_pack'],
404 'parcel_to': data['to_pack'],
405 'total_weight': data['weight'],
406 'total_height': data['height'],
407 'total_length': data['length'],
408 'total_width': data['width'],
409 'packing_list': data.get('packing_list'),
410 'ppl_name': data.get('ppl_name'),
411 })
412 data['pack_info_id'] = pack_info_created[pack_key]
380 ln = data.get('line_number')413 ln = data.get('line_number')
381 # UF-2148: if the line contains 0 qty, just ignore it!414 # UF-2148: if the line contains 0 qty, just ignore it!
382 qty = data.get('quantity', 0)415 qty = data.get('quantity', 0)
@@ -453,7 +486,7 @@
453 self._logger.info(message)486 self._logger.info(message)
454 raise Exception(message)487 raise Exception(message)
455488
456 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!489 move_id = False
457 if move_ids and len(move_ids) == 1: # if there is only one move, take it for process490 if move_ids and len(move_ids) == 1: # if there is only one move, take it for process
458 move_id = move_ids[0]491 move_id = move_ids[0]
459 else: # if there are more than 1 moves, then pick the next one not existing in the partial_datas[in_id]492 else: # if there are more than 1 moves, then pick the next one not existing in the partial_datas[in_id]
@@ -525,7 +558,7 @@
525 self._add_to_shipped_moves(already_shipped_moves, move_id, data['quantity'])558 self._add_to_shipped_moves(already_shipped_moves, move_id, data['quantity'])
526559
527 # for the last Shipment of an FO, no new INcoming shipment will be created --> same value as in_id560 # for the last Shipment of an FO, no new INcoming shipment will be created --> same value as in_id
528 new_picking = self.do_incoming_shipment(cr, uid, in_processor, context)561 new_picking = self.do_incoming_shipment(cr, uid, in_processor, shipment_ref=shipment_ref, context=context)
529562
530 # Set the backorder reference to the IN !!!! THIS NEEDS TO BE CHECKED WITH SUPPLY PM!563 # Set the backorder reference to the IN !!!! THIS NEEDS TO BE CHECKED WITH SUPPLY PM!
531 if new_picking != in_id:564 if new_picking != in_id:
532565
=== modified file 'bin/report/report_sxw.py'
--- bin/report/report_sxw.py 2020-06-18 15:56:24 +0000
+++ bin/report/report_sxw.py 2020-08-05 12:54:43 +0000
@@ -176,8 +176,10 @@
176176
177_fields_process = {177_fields_process = {
178 'float': _float_format,178 'float': _float_format,
179 'float_null': _float_format,
179 'date': _date_format,180 'date': _date_format,
180 'integer': _int_format,181 'integer': _int_format,
182 'integer_null': _int_format,
181 'datetime' : _dttime_format183 'datetime' : _dttime_format
182}184}
183185

Subscribers

People subscribed via source and target branches