Merge lp:~unifield-team/unifield-wm/sync-utp-872-various-fixes into lp:unifield-wm/sync

Proposed by jftempo
Status: Merged
Merged at revision: 383
Proposed branch: lp:~unifield-team/unifield-wm/sync-utp-872-various-fixes
Merge into: lp:unifield-wm/sync
Diff against target: 254 lines (+106/-10) (has conflicts)
5 files modified
msf_sync_data_server/data/sync_server.message_rule.csv (+9/-1)
sync_so/picking.py (+69/-4)
sync_so/purchase.py (+14/-0)
sync_so/sale.py (+2/-2)
sync_so/so_po_common.py (+12/-3)
Text conflict in msf_sync_data_server/data/sync_server.message_rule.csv
Text conflict in sync_so/picking.py
Text conflict in sync_so/purchase.py
Text conflict in sync_so/so_po_common.py
To merge this branch: bzr merge lp:~unifield-team/unifield-wm/sync-utp-872-various-fixes
Reviewer Review Type Date Requested Status
UniField Dev Team Pending
Review via email: mp+199550@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'msf_sync_data_server/data/sync_server.message_rule.csv'
2--- msf_sync_data_server/data/sync_server.message_rule.csv 2013-12-12 16:31:10 +0000
3+++ msf_sync_data_server/data/sync_server.message_rule.csv 2013-12-18 20:24:09 +0000
4@@ -7,11 +7,19 @@
5 po_updates_so_ref,TRUE,TRUE,"['name','state','partner_ref']","['&','&',('partner_type','!=','external'),('state','in',['confirmed','sourced','split', 'approved']),('partner_ref','!=',False)]",partner_id,MISSION,sale.order.update_sub_so_ref,purchase.order,PO updates SO ref,6
6 validated_po_updates_so,FALSE,TRUE,"['name', 'partner_ref','analytic_distribution_id/id', 'delivery_requested_date','details','notes', 'categ', 'order_type', 'priority', 'loan_duration','order_line/product_id/id', 'order_line/product_id/name','order_line/id', 'order_line/name', 'order_line/product_qty', 'order_line/product_uom', 'order_line/price_unit', 'order_line/analytic_distribution_id/id','order_line/comment','order_line/have_analytic_distribution_from_header','order_line/line_number', 'order_line/nomen_manda_0/id','order_line/nomen_manda_1/id','order_line/nomen_manda_2/id','order_line/nomen_manda_3/id', 'order_line/sync_order_line_db_id', 'order_line/nomenclature_description','order_line/notes','order_line/default_name','order_line/default_code','order_line/date_planned']","['&',('partner_type','!=','external'),('state','in',['sourced', 'approved'])]",partner_id,MISSION,sale.order.validated_po_update_validated_so,purchase.order,Validated PO updates SO,7
7 canceled_fo_cancels_po,TRUE,TRUE,"['name','state', 'client_order_ref']","[('state', '=', 'cancel')]",partner_id,MISSION,purchase.order.canceled_fo_cancel_po,sale.order,Canceled FO cancels PO,18
8-partial_shipped_coordo_updates_in_at_project,TRUE,TRUE,"['name', 'state', 'origin', 'partner_type_stock_picking', 'shipment_id/name', 'min_date', 'note', 'move_lines/processed_stock_move', 'move_lines/id', 'move_lines/line_number', 'move_lines/name', 'move_lines/change_reason', 'move_lines/product_id/id', 'move_lines/product_id/name', 'move_lines/product_qty', 'move_lines/prodlot_id/id', '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']","['&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'), ('subtype', 'in', ['standard', 'packing']), ('state', '=', 'done'), ('already_shipped', '=', True)]",partner_id,MISSION,stock.picking.partial_shipped_fo_updates_in_po,stock.picking,Partial shipped at Coordo updates IN at Project,19
9+partial_shipped_coordo_updates_in_at_project,TRUE,TRUE,"['name', 'state', 'origin', 'partner_type_stock_picking', 'shipment_id/name', 'min_date', 'note', 'move_lines/processed_stock_move', 'move_lines/id', 'move_lines/state', 'move_lines/line_number', 'move_lines/name', 'move_lines/change_reason', 'move_lines/product_id/id', 'move_lines/product_id/name', 'move_lines/product_qty', 'move_lines/prodlot_id/id', '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']","['&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'), ('subtype', 'in', ['standard', 'packing']), ('state', '=', 'done'), ('already_shipped', '=', True)]",partner_id,MISSION,stock.picking.partial_shipped_fo_updates_in_po,stock.picking,Partial shipped at Coordo updates IN at Project,19
10 cancel_out_at_coordo_cancels_in_at_project,TRUE,TRUE,"['name', 'state', 'origin']","['&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'),('state', '=', 'cancel'),('subtype', '=', 'standard')]",partner_id,MISSION,stock.picking.cancel_out_pick_cancel_in,stock.picking,Canceled OUT at Coordo cancels IN at Project,20
11+<<<<<<< TREE
12 cancel_pick_at_coordo_cancels_in_at_project,TRUE,TRUE,"['name', 'state', 'origin']","['&','&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'),('state', '=', 'cancel'),('subtype', '=', 'picking'),('backorder_id', '=', False)]",partner_id,MISSION,stock.picking.cancel_out_pick_cancel_in,stock.picking,Canceled PICK at Coordo cancels IN at Project,21
13 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)]",partner_id,MISSION,stock.picking.closed_in_validates_delivery_out_ship,stock.picking,Closed IN validates delivery of OUT-SHIP,22
14 create_batch_object,TRUE,TRUE,"['name', 'xmlid_name', 'prefix', 'product_id/id', 'partner_id/id', 'date', 'ref','life_date','sequence_id','type']","[('name', '=', False)]",partner_id,MISSION,stock.picking.create_batch_number,stock.production.lot,Create Batch Object,1001
15 create_asset_object,TRUE,TRUE,"['name', 'xmlid_name', 'arrival_date', 'asset_type_id/id', 'partner_id/id', 'brand', 'comment', 'description', 'hq_ref', 'international_po', 'invo_certif_depreciation', 'invo_currency/id', 'invo_date', 'invo_donator_code', 'invo_num', 'invo_supplier', 'invo_value', 'local_ref', 'model', 'orig_mission_code', 'product_id/id', 'project_po', 'receipt_place', 'serial_nb', 'type', 'year']","[('name', '=', False)]",partner_id,MISSION,stock.picking.create_asset,product.asset,Create Asset Object,1002
16+=======
17+cancel_pick_at_coordo_cancels_in_at_project,TRUE,TRUE,"['name', 'state', 'origin']","['&','&','&',('partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'),('state', '=', 'cancel'),('subtype', '=', 'picking')]",partner_id,MISSION,stock.picking.cancel_out_pick_cancel_in,stock.picking,Canceled PICK at Coordo cancels IN at Project,21
18+cancel_stock_move_at_coordo_cancels_in_at_project,TRUE,TRUE,"['name', 'state', 'origin']","['&','&','&','&',('picking_id.partner_type_stock_picking', '!=', 'external'), ('type', '=', 'out'),('state', '=', 'cancel'),('picking_id.subtype', '=', 'picking'),('picking_id.state', '=', 'done')]",partner_id,MISSION,stock.picking.cancel_stock_move_of_pick_cancel_in,stock.move,Canceled stock move cancels IN,22
19+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)]",partner_id,MISSION,stock.picking.closed_in_validates_delivery_out_ship,stock.picking,Closed IN validates delivery of OUT-SHIP,25
20+create_batch_object,TRUE,TRUE,"['name', 'xmlid_name', 'prefix', 'product_id/id', 'instance_id/id', 'date', 'ref','life_date','sequence_id','type']","[('name', '=', False)]",partner_id,MISSION,stock.picking.create_batch_number,stock.production.lot,Create Batch Object,1001
21+create_asset_object,TRUE,TRUE,"['name', 'xmlid_name', 'arrival_date', 'asset_type_id/id', 'instance_id/id', 'brand', 'comment', 'description', 'hq_ref', 'international_po', 'invo_certif_depreciation', 'invo_currency/id', 'invo_date', 'invo_donator_code', 'invo_num', 'invo_supplier', 'invo_value', 'local_ref', 'model', 'orig_mission_code', 'product_id/id', 'project_po', 'receipt_place', 'serial_nb', 'type', 'year']","[('name', '=', False)]",partner_id,MISSION,stock.picking.create_asset,product.asset,Create Asset Object,1002
22+>>>>>>> MERGE-SOURCE
23 USB_purchase_order_close,TRUE,TRUE,['name'],,name,USB,purchase.order.msg_close,purchase.order,[PO] close,1500
24 USB_incoming_shipment_close,TRUE,TRUE,['name'],,name,USB,stock.picking.msg_close,stock.picking,[IN] close,1501
25
26=== modified file 'sync_so/picking.py'
27--- sync_so/picking.py 2013-12-12 16:31:10 +0000
28+++ sync_so/picking.py 2013-12-18 20:24:09 +0000
29@@ -71,6 +71,11 @@
30
31 expired_date = data['expired_date']
32
33+ # UTP-872: Add also the state into the move line, but if it is done, then change it to assigned (available)
34+ state = data['state']
35+ if state == 'done':
36+ state = 'assigned'
37+
38 # build a dic which can be used directly to update the stock move
39 result = {'line_number': data['line_number'],
40 'product_id': product_id,
41@@ -78,6 +83,7 @@
42 'product_uos': uom_id,
43 'date': data['date'],
44 'date_expected': data['date_expected'],
45+ 'state': state,
46
47 'prodlot_id': batch_id,
48 'expired_date': expired_date,
49@@ -143,7 +149,7 @@
50 shipment_ref = source + "." + pick_dict.get('name', False) # the case of OUT
51
52 # Then from this PO, get the IN with the reference to that PO, and update the data received from the OUT of FO to this IN
53- in_id = so_po_common.get_in_id_by_state(cr, uid, po_id, po_name, 'assigned', context)
54+ in_id = so_po_common.get_in_id_by_state(cr, uid, po_id, po_name, ['assigned'], context)
55 if in_id:
56 partial_datas = {}
57 partial_datas[in_id] = {}
58@@ -201,7 +207,7 @@
59 return message
60 else:
61 # still try to check whether this IN has already been manually processed
62- in_id = so_po_common.get_in_id_by_state(cr, uid, po_id, po_name, 'done', context)
63+ in_id = so_po_common.get_in_id_by_state(cr, uid, po_id, po_name, ['done', 'shipped'], context)
64 if not in_id:
65 message = "The IN linked to " + po_name + " is not found in the system!"
66 self._logger.info(message)
67@@ -255,6 +261,9 @@
68
69
70 def cancel_out_pick_cancel_in(self, cr, uid, source, out_info, context=None):
71+ '''
72+ ' Cancel the OUT/PICK at the supplier side cancels the corresponding IN at the project side
73+ '''
74 if not context:
75 context = {}
76 self._logger.info("+++ Cancel the relevant IN at %s due to the cancel of OUT at supplier %s"%(cr.dbname, source))
77@@ -274,8 +283,59 @@
78 # Cancel the IN object
79 wf_service.trg_validate(uid, 'stock.picking', in_id, 'button_cancel', cr)
80 return True
81-
82- raise Exception("There is a problem when cancel of the IN at project")
83+ else:
84+ # UTP-872: If there is no IN corresponding to the give OUT/SHIP/PICK, then check if the PO has any line
85+ # if it has no line, then no need to raise error, because PO without line does not generate any IN
86+ po = po_obj.browse(cr, uid, [po_id], context=context)[0]
87+ if len(po.order_line) == 0:
88+ message = "The message is ignored as there is no corresponding IN (because the PO " + po.name + " has no line)"
89+ self._logger.info(message)
90+ return message
91+
92+ raise Exception("There is a problem (no PO or IN found) when cancel the IN at project")
93+
94+ def cancel_stock_move_of_pick_cancel_in(self, cr, uid, source, out_info, context=None):
95+ '''
96+ ' UTP-872: Cancel only a few move lines of a closed PICK ticket in Coordo will also need to cancel the relevant lines at the IN
97+ '''
98+ if not context:
99+ context = {}
100+ self._logger.info("+++ Cancel the relevant IN at %s due to the cancel of some specific move of the Pick ticket at supplier %s"%(cr.dbname, source))
101+
102+ wf_service = netsvc.LocalService("workflow")
103+ so_po_common = self.pool.get('so.po.common')
104+ po_obj = self.pool.get('purchase.order')
105+ pick_dict = out_info.to_dict()
106+
107+ # Look for the PO name, which has the reference to the FO on Coordo as source.out_info.origin
108+ so_ref = source + "." + pick_dict['origin']
109+ po_id = so_po_common.get_po_id_by_so_ref(cr, uid, so_ref, context)
110+ if po_id:
111+ # Then from this PO, get the IN with the reference to that PO, and update the data received from the OUT of FO to this IN
112+ in_id = so_po_common.get_in_id_from_po_id(cr, uid, po_id, context)
113+ if in_id:
114+ # Cancel the IN object to have all lines cancelled, but the IN object remained as closed, so the update of state is done right after
115+ wf_service.trg_validate(uid, 'stock.picking', in_id, 'button_cancel', cr)
116+ self.write(cr, uid, in_id, {'state': 'done'}, context) # UTP-872: reset state of the IN to become closed
117+ return True
118+ else:
119+ po = po_obj.browse(cr, uid, [po_id], context=context)[0]
120+ if len(po.order_line) == 0:
121+ message = "The message is ignored as there is no corresponding IN (because the PO " + po.name + " has no line)"
122+ self._logger.info(message)
123+ return message
124+
125+ # UTP-872: If there is no IN corresponding to the give OUT/SHIP/PICK, then check if the PO has any line
126+ # if it has no line, then no need to raise error, because PO without line does not generate any IN
127+ # still try to check whether this IN has already been manually processed
128+ in_id = so_po_common.get_in_id_by_state(cr, uid, po_id, po.name, ['done'], context)
129+ if in_id:
130+ message = "The IN linked to " + po.name + " has been closed already, this message is thus ignored!"
131+ self._logger.info(message)
132+ return message
133+
134+ raise Exception("There is a problem (no PO or IN found) when cancel the IN at project")
135+
136
137 def closed_in_validates_delivery_out_ship(self, cr, uid, source, out_info, context=None):
138 if not context:
139@@ -588,9 +648,14 @@
140 cr, uid,
141 context['changes']['stock.move'].keys(),
142 context=context):
143+<<<<<<< TREE
144 if self.pool.get('stock.move').exists(cr, uid, rec_line.id, context):
145 lines.setdefault(rec_line.picking_id.id, {})[rec_line.id] = \
146 context['changes']['stock.move'][rec_line.id]
147+=======
148+ if self.pool.get('stock.move').exists(cr, uid, rec_line.id, context): # check the line exists
149+ lines.setdefault(rec_line.picking_id.id, {})[rec_line.id] = context['changes']['stock.move'][rec_line.id]
150+>>>>>>> MERGE-SOURCE
151 # monitor changes on purchase.order
152 for id, changes in changes.items():
153 logger = get_sale_purchase_logger(cr, uid, self, id, \
154
155=== modified file 'sync_so/purchase.py'
156--- sync_so/purchase.py 2013-12-12 16:31:10 +0000
157+++ sync_so/purchase.py 2013-12-18 20:24:09 +0000
158@@ -293,6 +293,11 @@
159
160 return True
161
162+ # UTP-872: If the PO is a split one, then still allow it to be confirmed without po_line
163+ def _hook_check_po_no_line(self, po, context):
164+ if not po.split_po and not po.order_line:
165+ raise osv.except_osv(_('Error !'), _('You can not confirm purchase order without Purchase Order Lines.'))
166+
167 def validated_fo_update_original_po(self, cr, uid, source, so_info, context=None):
168 if not context:
169 context = {}
170@@ -368,6 +373,7 @@
171 # dict_of_purchase.order.line_changes
172 lines = {}
173 if 'purchase.order.line' in context['changes']:
174+<<<<<<< TREE
175 lines_changed = context['changes']['purchase.order.line']
176 # UF-2244: remove the lines that have been deleted --
177 lines_to_delete = []
178@@ -380,6 +386,14 @@
179
180 for rec_line in self.pool.get('purchase.order.line').browse(cr, uid,lines_changed.keys(),context=context):
181 lines.setdefault(rec_line.order_id.id, {})[rec_line.id] = lines_changed[rec_line.id]
182+=======
183+ for rec_line in self.pool.get('purchase.order.line').browse(
184+ cr, uid,
185+ context['changes']['purchase.order.line'].keys(),
186+ context=context):
187+ if self.pool.get('purchase.order.line').exists(cr, uid, rec_line.id, context): # check the line exists
188+ lines.setdefault(rec_line.order_id.id, {})[rec_line.id] = context['changes']['purchase.order.line'][rec_line.id]
189+>>>>>>> MERGE-SOURCE
190 # monitor changes on purchase.order
191 for id, changes in changes.items():
192 logger = get_sale_purchase_logger(cr, uid, self, id, \
193
194=== modified file 'sync_so/sale.py'
195--- sync_so/sale.py 2013-12-02 16:25:20 +0000
196+++ sync_so/sale.py 2013-12-18 20:24:09 +0000
197@@ -180,8 +180,8 @@
198 cr, uid,
199 context['changes']['sale.order.line'].keys(),
200 context=context):
201- lines.setdefault(rec_line.order_id.id, {})[rec_line.id] = \
202- context['changes']['sale.order.line'][rec_line.id]
203+ if self.pool.get('sale.order.line').exists(cr, uid, rec_line.id, context): # check the line exists
204+ lines.setdefault(rec_line.order_id.id, {})[rec_line.id] = context['changes']['sale.order.line'][rec_line.id]
205 # monitor changes on purchase.order
206 for id, changes in changes.items():
207 logger = get_sale_purchase_logger(cr, uid, self, id, \
208
209=== modified file 'sync_so/so_po_common.py'
210--- sync_so/so_po_common.py 2013-12-12 16:31:10 +0000
211+++ sync_so/so_po_common.py 2013-12-18 20:24:09 +0000
212@@ -119,30 +119,39 @@
213
214 in_ids = self.pool.get('stock.picking').search(cr, uid, [('purchase_id', '=', po_id), ('state', '=', 'assigned')], 0, None, None, context)
215 if not in_ids:
216- raise Exception, "The IN of the PO not found!"
217+ return False
218 return in_ids[0]
219
220- def get_in_id_by_state(self, cr, uid, po_id, po_ref, state, context):
221+ def get_in_id_by_state(self, cr, uid, po_id, po_ref, states, context):
222 # Get the Id of the original PO to update these info back
223 if not po_id:
224 return False
225
226- in_ids = self.pool.get('stock.picking').search(cr, uid, [('purchase_id', '=', po_id), ('state', '=', state)], 0, None, None, context)
227+ in_ids = self.pool.get('stock.picking').search(cr, uid, [('purchase_id', '=', po_id), ('state', 'in', states)], 0, None, None, context)
228 return in_ids[0] if in_ids else False
229
230 # Update the next line number for the FO, PO that have been created by the synchro
231 def update_next_line_number_fo_po(self, cr, uid, order_id, fo_po_obj, order_line_object, context):
232 sequence_id = fo_po_obj.read(cr, uid, [order_id], ['sequence_id'], context=context)[0]['sequence_id'][0]
233+ seq_tools = self.pool.get('sequence.tools')
234
235 # Make sure that even if the FO/PO has no line, then the default value is 1
236 cr.execute("select max(line_number) from " + order_line_object + " where order_id = " + str(order_id))
237 for x in cr.fetchall():
238+<<<<<<< TREE
239 seq_tools = self.pool.get('sequence.tools')
240 val = 1
241 if x and x[0]:
242 val = int(x[0]) + 1
243 seq_tools.reset_next_number(cr, uid, sequence_id, val, context=context)
244
245+=======
246+ # For the FO without any line
247+ val = 1
248+ if x and x[0]:
249+ val = int(x[0]) + 1
250+ seq_tools.reset_next_number(cr, uid, sequence_id, val, context=context)
251+>>>>>>> MERGE-SOURCE
252 return True
253
254 def get_original_so_id(self, cr, uid, so_ref, context):

Subscribers

People subscribed via source and target branches

to all changes: