Merge lp:~unifield-team/unifield-wm/sync-utp-872-various-fixes into lp:unifield-wm/sync
- sync-utp-872-various-fixes
- Merge into sync_module_prod
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Dev Team | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '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): |