Merge lp:~dorian-kemps/unifield-server/US-10783 into lp:unifield-server
- US-10783
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 6533 |
Proposed branch: | lp:~dorian-kemps/unifield-server/US-10783 |
Merge into: | lp:unifield-server |
Diff against target: |
1022 lines (+202/-308) (has conflicts) 19 files modified
bin/addons/delivery_mechanism/delivery_mechanism.py (+2/-9) bin/addons/msf_audittrail/data/audittrail_data_purchase.yml (+1/-2) bin/addons/msf_cross_docking/cross_docking.py (+4/-133) bin/addons/msf_doc_import/wizard/wizard_import_po_line.py (+3/-4) bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py (+7/-12) bin/addons/msf_profile/data/patches.xml (+8/-0) bin/addons/msf_profile/i18n/es_MF.po (+0/-5) bin/addons/msf_profile/i18n/fr_MF.po (+18/-73) bin/addons/msf_profile/msf_profile.py (+59/-0) bin/addons/order_types/stock.py (+0/-1) bin/addons/purchase/purchase_order.py (+36/-55) bin/addons/purchase/purchase_order_line.py (+55/-2) bin/addons/purchase/purchase_view.xml (+3/-3) bin/addons/purchase/purchase_workflow.py (+1/-1) bin/addons/purchase/report/purchase_report.py (+2/-2) bin/addons/sync_so/purchase.py (+0/-1) bin/addons/sync_so/so_po_common.py (+0/-2) bin/addons/tender_flow/report/purchase_report.py (+2/-2) bin/addons/tender_flow/tender_flow_view.xml (+1/-1) Text conflict in bin/addons/msf_profile/data/patches.xml Text conflict in bin/addons/msf_profile/i18n/fr_MF.po |
To merge this branch: | bzr merge lp:~dorian-kemps/unifield-server/US-10783 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+445622@code.launchpad.net |
Commit message
Description of the change
- 6492. By Dorian
-
US-10783 [MERGE] Merge with trunk
- 6493. By Dorian
-
US-10783-11563 [IMP] PO: Replaced location_id by location_ids and location_names. Their value depends on each PO line's origin, and new location value at line level affects the destination of the created INs
- 6494. By Dorian
-
US-10783-11563 [IMP] PO: Fixed translations
- 6495. By Dorian
-
US-10783 [FIX] PO line: changed reception_dest_id to be a fields.many2one, added patch script to set the value of old PO lines, and fixed data setup in purchase.report
- 6496. By Dorian
-
US-10783 [FIX] PO line: Fixed data setup in purchase.report
- 6497. By Dorian
-
US-10783 [FIX] PO: Destination location calculation now uses SQL
- 6498. By Dorian
-
US-10783 [FIX] PO line destination: Destination is always service for service products, destination is cross docking when the line is linked to a FO even if the product is non-stockable, destination is non-stockable when the product is non-stockable and is from scratch or comes from an IR ; destination is input in all other cases
- 6499. By Dorian
-
US-10783-11563 [FIX] PO line destination: Fixed destination if the source is an internal IR
Preview Diff
1 | === modified file 'bin/addons/delivery_mechanism/delivery_mechanism.py' |
2 | --- bin/addons/delivery_mechanism/delivery_mechanism.py 2023-04-05 09:27:49 +0000 |
3 | +++ bin/addons/delivery_mechanism/delivery_mechanism.py 2023-08-01 08:54:21 +0000 |
4 | @@ -675,7 +675,6 @@ |
5 | values['location_dest_id'] = db_data.get('cd_loc') |
6 | elif wizard.picking_id and wizard.picking_id.type == 'in' and line.product_id.type == 'service_recep': |
7 | values['location_dest_id'] = db_data.get('service_loc') |
8 | - values['cd_from_bo'] = False |
9 | elif wizard.dest_type == 'to_cross_docking' and not service_non_stock_ok: |
10 | if db_data.get('setup').allocation_setup == 'unallocated': |
11 | raise osv.except_osv( |
12 | @@ -685,10 +684,7 @@ |
13 | # Below, "source_type" is only used for the outgoing shipment. We set it to "None" because by default it is |
14 | # "default" and we do not want that info on INCOMING shipment |
15 | wizard.source_type = None |
16 | - values.update({ |
17 | - 'location_dest_id': db_data.get('cd_loc'), |
18 | - 'cd_from_bo': False, |
19 | - }) |
20 | + values.update({'location_dest_id': db_data.get('cd_loc')}) |
21 | elif wizard.dest_type == 'to_stock' or service_non_stock_ok: |
22 | # Below, "source_type" is only used for the outgoing shipment. We set it to "None because by default it is |
23 | # "default" and we do not want that info on INCOMING shipment |
24 | @@ -700,8 +696,6 @@ |
25 | # treat moves towards STOCK if NOT SERVICE |
26 | values['location_dest_id'] = db_data.get('input_loc') |
27 | |
28 | - values['cd_from_bo'] = False |
29 | - |
30 | if wizard.dest_type != 'to_cross_docking': |
31 | values['direct_incoming'] = wizard.direct_incoming |
32 | |
33 | @@ -1273,8 +1267,7 @@ |
34 | }, context=context) |
35 | return backorder_id |
36 | |
37 | - self.write(cr, uid, [picking_id], {'backorder_id': backorder_id, 'cd_from_bo': values.get('cd_from_bo', False)}, |
38 | - context=context) |
39 | + self.write(cr, uid, [picking_id], {'backorder_id': backorder_id}, context=context) |
40 | |
41 | # Claim specific code |
42 | current_backorder = picking_obj.read(cr, uid, backorder_id, ['backorder_id'], context=context) |
43 | |
44 | === modified file 'bin/addons/msf_audittrail/data/audittrail_data_purchase.yml' |
45 | --- bin/addons/msf_audittrail/data/audittrail_data_purchase.yml 2017-11-24 09:30:12 +0000 |
46 | +++ bin/addons/msf_audittrail/data/audittrail_data_purchase.yml 2023-08-01 08:54:21 +0000 |
47 | @@ -32,8 +32,7 @@ |
48 | rule_id = self.search(cr, uid, [('name', '=', name)], context=context) |
49 | if object_ids: |
50 | # Create the rule |
51 | - fields = ['partner_ref', 'details', 'delivery_requested_date', 'delivery_confirmed_date', 'partner_id', 'notes', |
52 | - 'order_type', 'categ', 'priority', 'shipped', 'state', 'pricelist_id', 'origin', 'transport_type', 'cross_docking_ok', 'location_id', 'unallocation_ok'] |
53 | + fields = ['partner_ref', 'details', 'delivery_requested_date', 'delivery_confirmed_date', 'partner_id', 'notes', 'order_type', 'categ', 'priority', 'shipped', 'state', 'pricelist_id', 'origin', 'transport_type', 'cross_docking_ok', 'unallocation_ok'] |
54 | fields_ids = self.pool.get('ir.model.fields').search(cr, uid, [('model', '=' ,'purchase.order'), ('name', 'in', fields)], context=context) |
55 | vals= {'name': name, |
56 | 'object_id': object_ids[0], |
57 | |
58 | === modified file 'bin/addons/msf_cross_docking/cross_docking.py' |
59 | --- bin/addons/msf_cross_docking/cross_docking.py 2021-07-07 16:30:21 +0000 |
60 | +++ bin/addons/msf_cross_docking/cross_docking.py 2023-08-01 08:54:21 +0000 |
61 | @@ -34,98 +34,23 @@ |
62 | |
63 | _columns = { |
64 | 'cross_docking_ok': fields.boolean('Cross docking'), |
65 | - 'location_id': fields.many2one('stock.location', 'Destination', required=True, domain=[('usage', '<>', 'view')], |
66 | - help="""This location is set according to the Warehouse selected, or according to the option 'Cross docking' |
67 | - or freely if you do not select 'Warehouse'.But if the 'Order category' is set to 'Transport' or 'Service', |
68 | - you cannot have an other location than 'Service'"""), |
69 | } |
70 | |
71 | _defaults = { |
72 | 'cross_docking_ok': False, |
73 | } |
74 | |
75 | - def onchange_internal_type(self, cr, uid, ids, order_type, partner_id, categ, dest_partner_id=False, warehouse_id=False, delivery_requested_date=False): |
76 | - ''' |
77 | - Changes destination location |
78 | - ''' |
79 | - res = super(purchase_order, self).onchange_internal_type(cr, uid, ids, order_type, partner_id, categ, dest_partner_id, warehouse_id, delivery_requested_date) |
80 | - if order_type == 'direct': |
81 | - location_id = self.onchange_cross_docking_ok(cr, uid, ids, False, warehouse_id, categ)['value']['location_id'] |
82 | - if 'value' in res: |
83 | - res['value'].update({'location_id': location_id}) |
84 | - else: |
85 | - res.update({'value': {'location_id': location_id}}) |
86 | - return res |
87 | - |
88 | - def onchange_cross_docking_ok(self, cr, uid, ids, cross_docking_ok, warehouse_id, categ, context=None): |
89 | - """ Finds location id for changed cross_docking_ok. |
90 | - @param cross_docking_ok: Changed value of cross_docking_ok. |
91 | - @return: Dictionary of values. |
92 | - """ |
93 | - if isinstance(ids, (int, long)): |
94 | - ids = [ids] |
95 | - |
96 | - warning = {} |
97 | - if cross_docking_ok: |
98 | - c_dock_loc = self.pool.get('stock.location').get_cross_docking_location(cr, uid) |
99 | - warning = { |
100 | - 'title': _('Warning'), |
101 | - 'message': _('The IR lines to an internal location sourced by one of the lines of this PO will not affected by this modification'), |
102 | - } |
103 | - else: |
104 | - warehouse_obj = self.pool.get('stock.warehouse') |
105 | - if not warehouse_id: |
106 | - warehouse_ids = warehouse_obj.search(cr, uid, [], limit=1) |
107 | - if not warehouse_ids: |
108 | - return {'warning': {'title': _('Error !'), 'message': _('No Warehouse defined !')}, 'value': {'location_id': False}} |
109 | - warehouse_id = warehouse_ids[0] |
110 | - if categ not in ('service', 'transport'): |
111 | - c_dock_loc = warehouse_obj.read(cr, uid, [warehouse_id], ['lot_input_id'])[0]['lot_input_id'][0] |
112 | - else: |
113 | - c_dock_loc = self.pool.get('stock.location').get_service_location(cr, uid) |
114 | - return { |
115 | - 'value': {'location_id': c_dock_loc}, |
116 | - 'warning': warning, |
117 | - } |
118 | - |
119 | - def onchange_location_id(self, cr, uid, ids, location_id, categ, context=None): |
120 | - """ If location_id == cross docking we tick the box "cross docking". |
121 | - @param location_id: Changed value of location_id. |
122 | - @return: Dictionary of values. |
123 | - """ |
124 | - if isinstance(ids, (int, long)): |
125 | - ids = [ids] |
126 | - stock_loc_obj = self.pool.get('stock.location') |
127 | - res = {} |
128 | - res['value'] = {} |
129 | - if location_id == stock_loc_obj.get_cross_docking_location(cr, uid) and categ not in ['service', 'transport']: |
130 | - cross_docking_ok = True |
131 | - elif location_id != stock_loc_obj.get_cross_docking_location(cr, uid): |
132 | - cross_docking_ok = False |
133 | - elif location_id != stock_loc_obj.get_service_location(cr, uid) and categ in ['service', 'transport']: |
134 | - return {'warning': {'title': _('Error !'), 'message': _(""" |
135 | - If the 'Order Category' is 'Service' or 'Transport', you cannot have an other location than 'Service' |
136 | - """)}, 'value': {'location_id': stock_loc_obj.get_service_location(cr, uid)}} |
137 | - res['value']['cross_docking_ok'] = cross_docking_ok |
138 | - return res |
139 | - |
140 | - def onchange_categ(self, cr, uid, ids, category, warehouse_id, cross_docking_ok, location_id, context=None): |
141 | + def onchange_categ(self, cr, uid, ids, category, context=None): |
142 | """ |
143 | Check if the list of products is valid for this new category |
144 | :param cr: Cursor to the database |
145 | :param uid: ID of the res.users that calls the method |
146 | :param ids: List of ID of purchase.order to check |
147 | :param category: DB value of the new choosen category |
148 | - :param warehouse_id: ID of the new stock.warehouse of the PO |
149 | - :param cross_docking_ok: Boolean to know if the PO is a Cross-Docking PO or not |
150 | - :param location_id: ID of the new stock.location of the PO |
151 | :param context: Context of the call |
152 | :return: A dictionary containing the warning message if any |
153 | """ |
154 | nomen_obj = self.pool.get('product.nomenclature') |
155 | - loc_obj = self.pool.get('stock.location') |
156 | - wh_obj = self.pool.get('stock.warehouse') |
157 | - setup_obj = self.pool.get('unifield.setup.configuration') |
158 | |
159 | if context is None: |
160 | context = {} |
161 | @@ -133,27 +58,9 @@ |
162 | if isinstance(ids, (int, long)): |
163 | ids = [ids] |
164 | |
165 | - setup = setup_obj.get_config(cr, uid) |
166 | - |
167 | value = {} |
168 | message = {} |
169 | |
170 | - # Get specific location ID |
171 | - cross_loc = False |
172 | - service_loc = loc_obj.get_service_location(cr, uid) |
173 | - if setup.allocation_setup != 'unallocated': |
174 | - cross_loc = loc_obj.get_cross_docking_location(cr, uid) |
175 | - |
176 | - if cross_docking_ok: |
177 | - value['location_id'] = cross_loc |
178 | - elif category in ['service', 'transport']: |
179 | - value['location_id'] = service_loc |
180 | - elif location_id == service_loc or (setup.allocation_setup != 'unallocated' and location_id == cross_loc): |
181 | - if warehouse_id: |
182 | - value['location_id'] = wh_obj.read(cr, uid, [warehouse_id], ['lot_input_id'])[0]['lot_input_id'][0] |
183 | - else: |
184 | - value['location_id'] = False |
185 | - |
186 | res = False |
187 | if ids and category in ['log', 'medical']: |
188 | try: |
189 | @@ -203,52 +110,16 @@ |
190 | return True |
191 | if isinstance(ids, (int, long)): |
192 | ids = [ids] |
193 | - stock_loc_obj = self.pool.get('stock.location') |
194 | - if 'order_type' in vals and vals['order_type'] == 'direct': |
195 | + if ('order_type' in vals and vals['order_type'] == 'direct') or \ |
196 | + ('categ' in vals and vals['categ'] in ['service', 'transport']): |
197 | vals.update({'cross_docking_ok': False}) |
198 | - if 'cross_docking_ok' in vals and vals['cross_docking_ok']: |
199 | - vals.update({'location_id': stock_loc_obj.get_cross_docking_location(cr, uid)}) |
200 | - elif 'categ' in vals and vals['categ'] in ['service', 'transport']: |
201 | - vals.update({'cross_docking_ok': False, 'location_id': stock_loc_obj.get_service_location(cr, uid)}) |
202 | return super(purchase_order, self).write(cr, uid, ids, vals, context=context) |
203 | |
204 | def create(self, cr, uid, vals, context=None): |
205 | - stock_loc_obj = self.pool.get('stock.location') |
206 | - if vals.get('order_type') == 'direct': |
207 | + if vals.get('order_type') == 'direct' or ('categ' in vals and vals['categ'] in ['service', 'transport']): |
208 | vals.update({'cross_docking_ok': False}) |
209 | - if vals.get('cross_docking_ok'): |
210 | - vals.update({'location_id': stock_loc_obj.get_cross_docking_location(cr, uid)}) |
211 | - elif 'categ' in vals and vals['categ'] in ['service', 'transport']: |
212 | - vals.update({'cross_docking_ok': False, 'location_id': stock_loc_obj.get_service_location(cr, uid)}) |
213 | return super(purchase_order, self).create(cr, uid, vals, context=context) |
214 | |
215 | - def _check_cross_docking(self, cr, uid, ids, context=None): |
216 | - """ |
217 | - Check that if you select cross docking, you do not have an other location than cross docking |
218 | - """ |
219 | - if isinstance(ids, (int, long)): |
220 | - ids = [ids] |
221 | - if context is None: |
222 | - context = {} |
223 | - stock_loc_obj = self.pool.get('stock.location') |
224 | - setup = self.pool.get('unifield.setup.configuration').get_config(cr, uid) |
225 | - for purchase in self.browse(cr, uid, ids, context=context): |
226 | - if purchase.cross_docking_ok: |
227 | - if setup.allocation_setup == 'unallocated': |
228 | - raise osv.except_osv(_('Error'), _("""The Allocated stocks setup is set to Unallocated. |
229 | -In this configuration, you cannot made a Cross-docking Purchase order.""")) |
230 | - cross_docking_location = stock_loc_obj.get_cross_docking_location(cr, uid) |
231 | - if purchase.location_id.id != cross_docking_location: |
232 | - raise osv.except_osv(_('Warning !'), _("""If you tick the box \"cross docking\", |
233 | -you cannot have an other location than \"Cross docking\"""")) |
234 | - else: |
235 | - return True |
236 | - else: |
237 | - return True |
238 | - |
239 | - _constraints = [ |
240 | - (_check_cross_docking, 'If you tick the box \"cross docking\", you cannot have an other location than \"Cross docking\"', ['location_id']), |
241 | - ] |
242 | |
243 | purchase_order() |
244 | |
245 | |
246 | === modified file 'bin/addons/msf_doc_import/wizard/wizard_import_po_line.py' |
247 | --- bin/addons/msf_doc_import/wizard/wizard_import_po_line.py 2022-06-29 15:47:02 +0000 |
248 | +++ bin/addons/msf_doc_import/wizard/wizard_import_po_line.py 2023-08-01 08:54:21 +0000 |
249 | @@ -338,7 +338,7 @@ |
250 | # update POL : |
251 | purchase_line_obj.write(cr, uid, rfq_line_ids, to_write, context=context) |
252 | |
253 | - else: # its not RfQ |
254 | + else: # it's not RfQ |
255 | purchase_line_obj.create(cr, uid, to_write, context=context) |
256 | |
257 | |
258 | @@ -398,9 +398,8 @@ |
259 | cr.execute("RELEASE SAVEPOINT line_save") |
260 | |
261 | if not blocker_msg: |
262 | - categ_log = purchase_obj.onchange_categ( |
263 | - cr, uid, [wiz.po_id.id], wiz.po_id.categ, wiz.po_id.warehouse_id.id, wiz.po_id.cross_docking_ok, |
264 | - wiz.po_id.location_id.id, context=context).get('warning', {}).get('message', '').upper() |
265 | + categ_log = purchase_obj.onchange_categ(cr, uid, [wiz.po_id.id], wiz.po_id.categ, |
266 | + context=context).get('warning', {}).get('message', '').upper() |
267 | categ_log = categ_log.replace('THIS', 'THE') |
268 | |
269 | wizard_vals = {'percent_completed': 100} |
270 | |
271 | === modified file 'bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py' |
272 | --- bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2022-06-08 13:47:24 +0000 |
273 | +++ bin/addons/msf_outgoing/wizard/incoming_shipment_processor.py 2023-08-01 08:54:21 +0000 |
274 | @@ -284,25 +284,20 @@ |
275 | vals['linked_to_out'] = False |
276 | |
277 | if not vals.get('dest_type', False): |
278 | - cd_move = move_obj.search(cr, uid, [ |
279 | + cd_move = move_obj.search_exist(cr, uid, [ |
280 | ('picking_id', '=', picking.id), |
281 | ('location_dest_id.cross_docking_location_ok', '=', True), |
282 | - ], count=True, context=context) |
283 | - in_move = move_obj.search(cr, uid, [ |
284 | + ], context=context) |
285 | + in_move = move_obj.search_exist(cr, uid, [ |
286 | ('picking_id', '=', picking.id), |
287 | ('location_dest_id.input_ok', '=', True), |
288 | - ], count=True, context=context) |
289 | + ], context=context) |
290 | |
291 | - if cd_move and in_move: |
292 | + if (cd_move and in_move) or (not cd_move and not in_move): |
293 | vals['dest_type'] = 'default' |
294 | - elif not picking.backorder_id: |
295 | - if picking.purchase_id and picking.purchase_id.cross_docking_ok: |
296 | - vals['dest_type'] = 'to_cross_docking' |
297 | - elif picking.purchase_id: |
298 | - vals['dest_type'] = 'to_stock' |
299 | - elif picking.cd_from_bo or (cd_move and not in_move): |
300 | + elif cd_move and not in_move: |
301 | vals['dest_type'] = 'to_cross_docking' |
302 | - elif not picking.cd_from_bo or (in_move and not cd_move): |
303 | + elif not cd_move and in_move: |
304 | vals['dest_type'] = 'to_stock' |
305 | |
306 | if not vals.get('source_type', False): |
307 | |
308 | === modified file 'bin/addons/msf_profile/data/patches.xml' |
309 | --- bin/addons/msf_profile/data/patches.xml 2023-07-20 07:43:37 +0000 |
310 | +++ bin/addons/msf_profile/data/patches.xml 2023-08-01 08:54:21 +0000 |
311 | @@ -947,6 +947,7 @@ |
312 | <record id="us_11130_trigger_down_account_mapping" model="patch.scripts"> |
313 | <field name="method">us_11130_trigger_down_account_mapping</field> |
314 | </record> |
315 | +<<<<<<< TREE |
316 | |
317 | <record id="us_11448_update_rfq_line_state" model="patch.scripts"> |
318 | <field name="method">us_11448_update_rfq_line_state</field> |
319 | @@ -961,5 +962,12 @@ |
320 | </record> |
321 | |
322 | |
323 | +======= |
324 | + |
325 | + <!-- UF30.0 --> |
326 | + <record id="us_10783_11563_po_reception_destination" model="patch.scripts"> |
327 | + <field name="method">us_10783_11563_po_reception_destination</field> |
328 | + </record> |
329 | +>>>>>>> MERGE-SOURCE |
330 | </data> |
331 | </openerp> |
332 | |
333 | === modified file 'bin/addons/msf_profile/i18n/es_MF.po' |
334 | --- bin/addons/msf_profile/i18n/es_MF.po 2023-04-17 12:42:12 +0000 |
335 | +++ bin/addons/msf_profile/i18n/es_MF.po 2023-08-01 08:54:21 +0000 |
336 | @@ -71321,11 +71321,6 @@ |
337 | msgid "Theoretical Kit Composition" |
338 | msgstr "Composición de kit teórico " |
339 | |
340 | -#. module: order_types |
341 | -#: field:stock.picking,cd_from_bo:0 |
342 | -msgid "CD from BO" |
343 | -msgstr "CD de BO" |
344 | - |
345 | #. module: product |
346 | #: field:product.price_list,qty1:0 |
347 | msgid "Quantity-1" |
348 | |
349 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
350 | --- bin/addons/msf_profile/i18n/fr_MF.po 2023-07-20 07:58:06 +0000 |
351 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2023-08-01 08:54:21 +0000 |
352 | @@ -600,12 +600,6 @@ |
353 | msgid "Cost Center:" |
354 | msgstr "Centre de Coût" |
355 | |
356 | -#. module: msf_cross_docking |
357 | -#: code:addons/msf_cross_docking/cross_docking.py:80 |
358 | -#, python-format |
359 | -msgid "No Warehouse defined !" |
360 | -msgstr "Pas d'Entrepôt défini !" |
361 | - |
362 | #. modules: account, msf_instance |
363 | #: field:account.journal,default_debit_account_id:0 |
364 | #: field:account.journal.fake,default_debit_account_id:0 |
365 | @@ -6269,12 +6263,6 @@ |
366 | msgid "unconsistent.stock.report.line" |
367 | msgstr "unconsistent.stock.report.line" |
368 | |
369 | -#. module: msf_cross_docking |
370 | -#: code:addons/msf_cross_docking/cross_docking.py:73 |
371 | -#, python-format |
372 | -msgid "The IR lines to an internal location sourced by one of the lines of this PO will not affected by this modification" |
373 | -msgstr "The IR lines to an internal location sourced by one of the lines of this PO will not affected by this modification" |
374 | - |
375 | #. module: msf_field_access_rights |
376 | #: model:ir.actions.act_window,name:msf_field_access_rights.field_access_rule_line_list |
377 | #: model:ir.ui.menu,name:msf_field_access_rights.field_access_rule_line_list_menu |
378 | @@ -35128,13 +35116,11 @@ |
379 | " " |
380 | |
381 | #. module: purchase |
382 | -#: help:purchase.order,location_id:0 |
383 | -msgid "This location is set according to the Warehouse selected, or according to the option 'Cross docking'\n" |
384 | -" or freely if you do not select 'Warehouse'.But if the 'Order category' is set to 'Transport' or 'Service',\n" |
385 | -" you cannot have an other location than 'Service'" |
386 | -msgstr "Ce lieu est configuré selon l'entrepôt sélectionné ou selon l'option 'Transbordement'\n" |
387 | -" ou librement si vous ne sélectionnez pas 'Entrepôt'. Mais si, pour la 'Catégorie de commande', il est indiqué 'Transport' ou 'Service',\n" |
388 | -" vous ne pouvez pas avoir un autre zone que 'Service'" |
389 | +#: help:purchase.order,location_names:0 |
390 | +msgid "This location is set according to the origin of the line(s) of the document. \n" |
391 | +" It can have 'Input', 'Cross Docking', 'Non-Stockable' and/or 'Service' as data" |
392 | +msgstr "Ce lieu est configuré selon l'origine des lignes du document. \n" |
393 | +" Il peut avoir 'Entrée', 'Transbordement', 'Non Stockable' et/ou 'Service' comme donnée" |
394 | |
395 | #. module: base |
396 | #: selection:res.config.users,context_tz:0 |
397 | @@ -50667,14 +50653,6 @@ |
398 | msgid "Comment written" |
399 | msgstr "Commentaire écrit" |
400 | |
401 | -#. module: msf_cross_docking |
402 | -#: code:addons/msf_cross_docking/cross_docking.py:238 |
403 | -#, python-format |
404 | -msgid "The Allocated stocks setup is set to Unallocated.\n" |
405 | -"In this configuration, you cannot made a Cross-docking Purchase order." |
406 | -msgstr "La configuration des stocks alloués est configurée sur Non alloués.\n" |
407 | -"Dans cette configuration, vous ne pouvez pas établir de bon de commande de transbordement." |
408 | - |
409 | #. module: sales_followup |
410 | #: report:sales.follow.up.report_pdf:0 |
411 | msgid "FIELD ORDER FOLLOW UP" |
412 | @@ -59193,9 +59171,10 @@ |
413 | msgid "PO File" |
414 | msgstr "Fichier au format PO" |
415 | |
416 | -#. module: msf_cross_docking, product_attributes |
417 | +#. module: msf_cross_docking, product_attributes, purchase |
418 | #: model:stock.location,name:msf_cross_docking.stock_location_input |
419 | #: code:addons/product_attributes/report/merged_ud_products.py:139 |
420 | +#: code:addons/purchase/purchase_order.py:544 |
421 | msgid "Input" |
422 | msgstr "Entrée" |
423 | |
424 | @@ -71736,14 +71715,6 @@ |
425 | msgid "Commitments voucher" |
426 | msgstr "Bon d'Engagement" |
427 | |
428 | -#. module: msf_cross_docking |
429 | -#: code:addons/msf_cross_docking/cross_docking.py:242 |
430 | -#, python-format |
431 | -msgid "If you tick the box \"cross docking\",\n" |
432 | -"you cannot have an other location than \"Cross docking\"" |
433 | -msgstr "Si vous cochez la case \"transbordement\",\n" |
434 | -"vous ne pouvez pas avoir un autre lieu que \"Transbordement\"" |
435 | - |
436 | #. modules: register_accounting, account_mcdb |
437 | #: view:account.move:0 |
438 | #: view:account.move.line:0 |
439 | @@ -82712,11 +82683,6 @@ |
440 | msgid "]" |
441 | msgstr "]" |
442 | |
443 | -#. module: order_types |
444 | -#: field:stock.picking,cd_from_bo:0 |
445 | -msgid "CD from BO" |
446 | -msgstr "CD from BO" |
447 | - |
448 | #. modules: purchase_msf, purchase_override, msf_partner, product_manufacturer, product_attributes |
449 | #: field:product.supplierinfo,check_manufacturer:0 |
450 | #: field:product.supplierinfo,manufacturer_id:0 |
451 | @@ -83035,16 +83001,6 @@ |
452 | msgid "Delivered" |
453 | msgstr "Livré" |
454 | |
455 | -#. module: msf_cross_docking |
456 | -#: code:addons/msf_cross_docking/cross_docking.py:106 |
457 | -#, python-format |
458 | -msgid "\n" |
459 | -" If the 'Order Category' is 'Service' or 'Transport', you cannot have an other location than 'Service'\n" |
460 | -" " |
461 | -msgstr "\n" |
462 | -" Si la 'Catégorie d'ordre' est 'Service' ou 'Transport', vous ne pouvez avoir un autre lieu que 'Service'\n" |
463 | -" " |
464 | - |
465 | #. modules: msf_field_access_rights, sync_client, msf_audittrail, msf_doc_import, procurement_cycle |
466 | #: field:audittrail.log.line,rule_id:0 |
467 | #: view:msf_field_access_rights.field_access_rule_line:0 |
468 | @@ -83694,27 +83650,6 @@ |
469 | msgid "Open CSV file" |
470 | msgstr "Ouvrir le fichier CSV" |
471 | |
472 | -#. modules: msf_cross_docking, purchase, register_accounting, finance, sales_followup, service_purchasing, sourcing, specific_rules, transport_mgmt, purchase_allocation_report, order_line_number, msf_audittrail, delete_button, tender_flow, msf_doc_import, res_currency_functional, sync_so |
473 | -#: constraint:purchase.order:0 |
474 | -#: constraint:purchase.order:0 |
475 | -#: constraint:purchase.order:0 |
476 | -#: constraint:purchase.order:0 |
477 | -#: constraint:purchase.order:0 |
478 | -#: constraint:purchase.order:0 |
479 | -#: constraint:purchase.order:0 |
480 | -#: constraint:purchase.order:0 |
481 | -#: constraint:purchase.order:0 |
482 | -#: constraint:purchase.order:0 |
483 | -#: constraint:purchase.order:0 |
484 | -#: constraint:purchase.order:0 |
485 | -#: constraint:purchase.order:0 |
486 | -#: constraint:purchase.order:0 |
487 | -#: constraint:purchase.order:0 |
488 | -#: constraint:purchase.order:0 |
489 | -#: constraint:purchase.order:0 |
490 | -msgid "If you tick the box \"cross docking\", you cannot have an other location than \"Cross docking\"" |
491 | -msgstr "Si vous cochez la case \"transbordement\", vous ne pouvez pas avoir d'autre lieu que \"Transbordement\"" |
492 | - |
493 | #. module: msf_doc_import |
494 | #: model:ir.model,name:msf_doc_import.model_wizard_import_threshold_value_line |
495 | msgid "Import Threshold value lines from Excel sheet" |
496 | @@ -95767,7 +95702,8 @@ |
497 | #: report:addons/msf_supply_doc_export/report/report_validated_purchase_order_xls.mako:243 |
498 | #: report:addons/msf_supply_doc_export/report/report_validated_purchase_order_xls.mako:249 |
499 | #: report:po.follow.up_rml:0 |
500 | -#: field:purchase.order,location_id:0 |
501 | +#: field:purchase.order,location_ids:0 |
502 | +#: field:purchase.order,location_names:0 |
503 | #: report:addons/purchase_allocation_report/report/po_allocation_report.mako:229 |
504 | #: report:addons/purchase_allocation_report/report/po_line_allocation_report.mako:183 |
505 | #: report:po.line.allocation.report:0 |
506 | @@ -120555,6 +120491,7 @@ |
507 | #: view:res.company:0 |
508 | msgid "HQ System Accounts Mapping" |
509 | msgstr "Association comptes HQ" |
510 | +<<<<<<< TREE |
511 | |
512 | #. module: msf_supply_doc_export |
513 | #: report:po.follow.up_rml:0 |
514 | @@ -120762,3 +120699,11 @@ |
515 | #, python-format |
516 | msgid "%s line %s %s: Percentage is mandatory" |
517 | msgstr "%s ligne %s %s: Le Pourcentage est obligatoire" |
518 | +======= |
519 | + |
520 | +#. modules: purchase, purchase_override |
521 | +#: field:purchase.order.line,reception_dest_id:0 |
522 | +#: field:purchase.order.merged.line,reception_dest_id:0 |
523 | +msgid "Line Destination" |
524 | +msgstr "Destination de la ligne" |
525 | +>>>>>>> MERGE-SOURCE |
526 | |
527 | === modified file 'bin/addons/msf_profile/msf_profile.py' |
528 | --- bin/addons/msf_profile/msf_profile.py 2023-07-20 07:43:37 +0000 |
529 | +++ bin/addons/msf_profile/msf_profile.py 2023-08-01 08:54:21 +0000 |
530 | @@ -109,6 +109,65 @@ |
531 | |
532 | |
533 | |
534 | + # UF30.0 |
535 | + def us_10783_11563_po_reception_destination(self, cr, uid, *a, **b): |
536 | + ''' |
537 | + For each PO line, look at its origin to set the reception_destination_id. It can be Cross Docking, Service, |
538 | + Non-Stockable or Input |
539 | + ''' |
540 | + data_obj = self.pool.get('ir.model.data') |
541 | + srv_id = self.pool.get('stock.location').get_service_location(cr, uid, context={}) |
542 | + input_id = data_obj.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_input')[1] |
543 | + cross_id = data_obj.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_cross_docking')[1] |
544 | + n_stock_id = data_obj.get_object_reference(cr, uid, 'stock_override', 'stock_location_non_stockable')[1] |
545 | + |
546 | + # Cross Docking: PO line linked to a FO and product is not Service or an IR to Ext CU and product is neither |
547 | + # Service or Non-Stockable |
548 | + cr.execute("""UPDATE purchase_order_line SET reception_dest_id = %s WHERE id IN ( |
549 | + SELECT pl.id FROM purchase_order_line pl |
550 | + LEFT JOIN product_product pp ON pl.product_id = pp.id |
551 | + LEFT JOIN product_template pt ON pp.product_tmpl_id = pt.id |
552 | + LEFT JOIN sale_order so ON pl.link_so_id = so.id |
553 | + LEFT JOIN stock_location l ON so.location_requestor_id = l.id |
554 | + WHERE pl.link_so_id = so.id AND ((pt.type != 'service_recep' AND so.procurement_request = 'f') OR |
555 | + (pt.type NOT IN ('service_recep', 'consu') AND so.location_requestor_id IS NOT NULL AND l.usage = 'customer')) |
556 | + )""", (cross_id,)) |
557 | + self.log_info(cr, uid, "US-10783-11563: The Line Destination of %s PO line(s) have been set to 'Cross Docking'" % (cr.rowcount,)) |
558 | + |
559 | + # Service: PO line from scratch or linked to internal IR and product is Service |
560 | + cr.execute("""UPDATE purchase_order_line SET reception_dest_id = %s WHERE id IN ( |
561 | + SELECT pl.id FROM purchase_order_line pl |
562 | + LEFT JOIN product_product pp ON pl.product_id = pp.id |
563 | + LEFT JOIN product_template pt ON pp.product_tmpl_id = pt.id |
564 | + WHERE pt.type = 'service_recep' |
565 | + )""", (srv_id,)) |
566 | + self.log_info(cr, uid, "US-10783-11563: The Line Destination of %s PO line(s) have been set to 'Service'" % (cr.rowcount,)) |
567 | + |
568 | + # Non-Stockable: PO line from scratch or linked to internal IR and product is Non-Stockable |
569 | + cr.execute("""UPDATE purchase_order_line SET reception_dest_id = %s WHERE id IN ( |
570 | + SELECT pl.id FROM purchase_order_line pl |
571 | + LEFT JOIN product_product pp ON pl.product_id = pp.id |
572 | + LEFT JOIN product_template pt ON pp.product_tmpl_id = pt.id |
573 | + LEFT JOIN sale_order so ON pl.link_so_id = so.id |
574 | + LEFT JOIN stock_location l ON so.location_requestor_id = l.id |
575 | + WHERE pt.type = 'consu' AND (pl.link_so_id IS NULL OR so.procurement_request = 't') |
576 | + )""", (n_stock_id,)) |
577 | + self.log_info(cr, uid, "US-10783-11563: The Line Destination of %s PO line(s) have been set to 'Non-Stockable'" % (cr.rowcount,)) |
578 | + |
579 | + # Input: All others |
580 | + cr.execute("""UPDATE purchase_order_line SET reception_dest_id = %s WHERE id IN ( |
581 | + SELECT pl.id FROM purchase_order_line pl |
582 | + LEFT JOIN product_product pp ON pl.product_id = pp.id |
583 | + LEFT JOIN product_template pt ON pp.product_tmpl_id = pt.id |
584 | + LEFT JOIN sale_order so ON pl.link_so_id = so.id |
585 | + LEFT JOIN stock_location l ON so.location_requestor_id = l.id |
586 | + WHERE (pl.product_id IS NULL OR pt.type NOT IN ('service_recep', 'consu')) |
587 | + AND (pl.link_so_id IS NULL OR (so.procurement_request = 't' AND l.usage != 'customer')) |
588 | + )""", (input_id,)) |
589 | + self.log_info(cr, uid, "US-10783-11563: The Line Destination of %s PO line(s) have been set to 'Input'" % (cr.rowcount,)) |
590 | + |
591 | + return True |
592 | + |
593 | # UF29.0 |
594 | def us_11399_oca_mm_target(self, cr, uid, *a, **b): |
595 | if self.pool.get('res.users').browse(cr, uid, uid).company_id.instance_id: |
596 | |
597 | === modified file 'bin/addons/order_types/stock.py' |
598 | --- bin/addons/order_types/stock.py 2022-05-17 12:44:46 +0000 |
599 | +++ bin/addons/order_types/stock.py 2023-08-01 08:54:21 +0000 |
600 | @@ -130,7 +130,6 @@ |
601 | _columns = { |
602 | 'certificate_donation': fields.function(_get_certificate, string='Certif ?', type='boolean', method=True), |
603 | 'attach_cert': fields.boolean(string='Certificate attached ?', readonly=True), |
604 | - 'cd_from_bo': fields.boolean(string='CD from BO'), |
605 | } |
606 | |
607 | _defaults = { |
608 | |
609 | === modified file 'bin/addons/purchase/purchase_order.py' |
610 | --- bin/addons/purchase/purchase_order.py 2023-02-17 13:56:40 +0000 |
611 | +++ bin/addons/purchase/purchase_order.py 2023-08-01 08:54:21 +0000 |
612 | @@ -528,6 +528,33 @@ |
613 | |
614 | return res |
615 | |
616 | + def _get_location_data(self, cr, uid, ids, field_name, args, context=None): |
617 | + res = {} |
618 | + for po in self.browse(cr, uid, ids, fields_to_fetch=['order_line', 'state'], context=context): |
619 | + if po.order_line: |
620 | + not_cancel = "" |
621 | + if po.state != 'cancel': |
622 | + not_cancel = " AND pl.state NOT IN ('cancel', 'cancel_r')" |
623 | + cr.execute(""" |
624 | + SELECT DISTINCT(l.id), l.name FROM purchase_order p |
625 | + LEFT JOIN purchase_order_line pl ON pl.order_id = p.id |
626 | + LEFT JOIN stock_location l ON pl.reception_dest_id = l.id |
627 | + WHERE p.id = %s""" + not_cancel, (po.id,)) |
628 | + location_ids = [] |
629 | + location_names = [] |
630 | + for loc in cr.fetchall(): |
631 | + location_ids.append(loc[0]) |
632 | + location_names.append(loc[1]) |
633 | + res[po.id] = { |
634 | + 'location_ids': location_ids, |
635 | + 'location_names': "; ".join(location_names) |
636 | + } |
637 | + else: |
638 | + input_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'msf_cross_docking', |
639 | + 'stock_location_input')[1] |
640 | + res[po.id] = {'location_ids': [input_id], 'location_names': _('Input')} |
641 | + return res |
642 | + |
643 | def _get_less_advanced_pol_state(self, cr, uid, ids, field_name, arg, context=None): |
644 | """ |
645 | Get the less advanced state of the purchase order lines |
646 | @@ -908,7 +935,10 @@ |
647 | "In this case, it will remove the warehouse link and set the customer location." |
648 | ), |
649 | 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'), |
650 | - 'location_id': fields.many2one('stock.location', 'Destination', required=True, domain=[('usage', '<>', 'view')]), |
651 | + 'location_ids': fields.function(_get_location_data, type='many2many', relation='stock.location', string='Destination', method=True, multi='location_data', readonly=True), |
652 | + 'location_names': fields.function(_get_location_data, type='char', size=256, string='Destination', method=True, multi='location_data', |
653 | + readonly=True, store=False, help="""This location is set according to the origin of the line(s) of the document. |
654 | + It can have 'Input', 'Cross Docking', 'Non-Stockable' and/or 'Service' as data"""), |
655 | 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."), |
656 | 'state': fields.function(_get_less_advanced_pol_state, string='Order State', method=True, type='selection', selection=PURCHASE_ORDER_STATE_SELECTION, readonly=True, |
657 | store={ |
658 | @@ -1177,8 +1207,6 @@ |
659 | |
660 | if 'partner_id' in vals: |
661 | self._check_user_company(cr, uid, vals['partner_id'], context=context) |
662 | - # we need to update the location_id because it is readonly and so does not pass in the vals of create and write |
663 | - vals = self._get_location_id(cr, uid, vals, warehouse_id=vals.get('warehouse_id', False), context=context) |
664 | res = super(purchase_order, self).create(cr, uid, vals, context=context) |
665 | |
666 | if vals.get('stock_take_date'): |
667 | @@ -1305,8 +1333,7 @@ |
668 | vals.update({'invoice_method': 'manual'}) |
669 | else: |
670 | vals.update({'invoice_method': 'picking'}) |
671 | - # we need to update the location_id because it is readonly and so does not pass in the vals of create and write |
672 | - vals = self._get_location_id(cr, uid, vals, warehouse_id=vals.get('warehouse_id', order['warehouse_id'] and order['warehouse_id'][0] or False), context=context) |
673 | + |
674 | # FIXME here it is useless to continue as the next loop will overwrite vals |
675 | break |
676 | |
677 | @@ -1846,7 +1873,7 @@ |
678 | 'categ', 'priority', 'internal_type', 'arrival_date', |
679 | 'transport_type', 'shipment_date', 'ready_to_ship_date', |
680 | 'cross_docking_ok', 'delivery_confirmed_date', |
681 | - 'est_transport_lead_time', 'location_id', |
682 | + 'est_transport_lead_time', |
683 | 'dest_address_id', 'incoterm_id'] |
684 | |
685 | delivery_requested_date = getattr(order_id, 'delivery_requested_date') |
686 | @@ -1940,7 +1967,6 @@ |
687 | 'partner_address_id': porder.partner_address_id.id, |
688 | 'dest_address_id': porder.dest_address_id.id, |
689 | 'warehouse_id': porder.warehouse_id.id, |
690 | - 'location_id': porder.location_id.id, |
691 | 'pricelist_id': porder.pricelist_id.id, |
692 | 'state': 'draft', |
693 | 'order_line': [], |
694 | @@ -2286,8 +2312,7 @@ |
695 | ''' |
696 | res = {} |
697 | if not warehouse_id: |
698 | - wh_info = self.pool.get('stock.warehouse').read(cr, uid, [warehouse_id], ['lot_input_id']) |
699 | - res = {'value': {'location_id': wh_info[0]['lot_input_id'][0], 'dest_address_id': False, 'cross_docking_ok': False}} |
700 | + res = {'value': {'dest_address_id': False, 'cross_docking_ok': False}} |
701 | |
702 | if not res.get('value', {}).get('dest_address_id') and order_type != 'direct': |
703 | cp_address_id = self.pool.get('res.partner').address_get(cr, uid, self.pool.get('res.users').browse(cr, uid, uid).company_id.partner_id.id, ['delivery'])['delivery'] |
704 | @@ -2544,22 +2569,6 @@ |
705 | if not pol: |
706 | return False |
707 | |
708 | - dest = pol.order_id.location_id.id |
709 | - if pol.product_id.type == 'service_recep' and not pol.order_id.cross_docking_ok: |
710 | - # service with reception are directed to Service Location |
711 | - dest = self.pool.get('stock.location').get_service_location(cr, uid) |
712 | - else: |
713 | - sol = pol.linked_sol_id |
714 | - if sol and sol.order_id and not sol.order_id.procurement_request: |
715 | - # source a FO line => go to Cross Dock (set at PO header) |
716 | - pass |
717 | - elif pol.product_id.type == 'service_recep': |
718 | - dest = self.pool.get('stock.location').get_service_location(cr, uid) |
719 | - elif pol.product_id.type == 'consu': |
720 | - dest = data_obj.get_object_reference(cr, uid, 'stock_override', 'stock_location_non_stockable')[1] |
721 | - elif sol and sol.order_id and sol.order_id.location_requestor_id.usage != 'customer': |
722 | - dest = data_obj.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_input')[1] |
723 | - # please also check in delivery_mechanism/delivery_mechanism.py _get_values_from_line to set location_dest_id |
724 | values = { |
725 | 'name': ''.join((pol.order_id.name, ': ', (pol.name or ''))), |
726 | 'product_id': pol.product_id.id, |
727 | @@ -2568,7 +2577,7 @@ |
728 | 'product_uom': pol.product_uom.id, |
729 | 'product_uos': pol.product_uom.id, |
730 | 'location_id': pol.order_id.partner_id.property_stock_supplier.id, |
731 | - 'location_dest_id': dest, |
732 | + 'location_dest_id': pol.reception_dest_id.id, |
733 | 'picking_id': incoming.id, |
734 | 'move_dest_id': pol.move_dest_id.id, |
735 | 'state': 'draft', |
736 | @@ -2608,7 +2617,7 @@ |
737 | return False |
738 | |
739 | # compute source location: |
740 | - src_location = pol.order_id.location_id |
741 | + src_location = pol.reception_dest_id |
742 | |
743 | # compute destination location |
744 | dest = self.pool.get('purchase.order.line').final_location_dest(cr, uid, pol, context=context) |
745 | @@ -2646,34 +2655,6 @@ |
746 | |
747 | return move_obj.create(cr, uid, values, context=ctx) |
748 | |
749 | - def _get_location_id(self, cr, uid, vals, warehouse_id=False, context=None): |
750 | - """ |
751 | - Get the location_id according to the cross_docking_ok option |
752 | - Return vals |
753 | - """ |
754 | - if 'cross_docking_ok' not in vals: |
755 | - return vals |
756 | - |
757 | - stock_warehouse_obj = self.pool.get('stock.warehouse') |
758 | - if not warehouse_id: |
759 | - warehouse_id = stock_warehouse_obj.search(cr, uid, [], context=context)[0] |
760 | - |
761 | - if isinstance(warehouse_id, (str, unicode)): |
762 | - try: |
763 | - warehouse_id = int(warehouse_id) |
764 | - except ValueError: |
765 | - raise osv.except_osv( |
766 | - _('Error'), |
767 | - _('The field \'warehouse_id\' is a float field but value is a string - Please contact your administrator'), |
768 | - ) |
769 | - |
770 | - if not vals.get('cross_docking_ok', False): |
771 | - vals.update({'location_id': stock_warehouse_obj.read(cr, uid, warehouse_id, ['lot_input_id'], context=context)['lot_input_id'][0]}) |
772 | - elif vals.get('cross_docking_ok', False): |
773 | - vals.update({'location_id': self.pool.get('stock.location').get_cross_docking_location(cr, uid)}) |
774 | - |
775 | - return vals |
776 | - |
777 | def set_manually_done(self, cr, uid, ids, all_doc=True, context=None): |
778 | ''' |
779 | Set the PO to done state |
780 | |
781 | === modified file 'bin/addons/purchase/purchase_order_line.py' |
782 | --- bin/addons/purchase/purchase_order_line.py 2023-06-13 13:00:48 +0000 |
783 | +++ bin/addons/purchase/purchase_order_line.py 2023-08-01 08:54:21 +0000 |
784 | @@ -587,6 +587,7 @@ |
785 | ondelete='set null'), |
786 | 'move_dest_id': fields.many2one('stock.move', 'Reservation Destination', ondelete='set null', select=True), |
787 | 'location_dest_id': fields.many2one('stock.location', 'Final Destination of move', ondelete='set null', select=True), |
788 | + 'reception_dest_id': fields.many2one('stock.location', string='Line Destination', ondelete='set null', select=True), |
789 | 'price_unit': fields.float('Unit Price', required=True, |
790 | digits_compute=dp.get_precision('Purchase Price Computation'), en_thousand_sep=False), |
791 | 'vat_ok': fields.function(_get_vat_ok, method=True, type='boolean', string='VAT OK', store=False, |
792 | @@ -1308,6 +1309,8 @@ |
793 | #if not product_id and not vals.get('name'): # US-3530 |
794 | # vals.update({'name': 'None'}) |
795 | |
796 | + vals['reception_dest_id'] = self.get_reception_dest(cr, uid, vals, context=context) |
797 | + |
798 | # add the database Id to the sync_order_line_db_id |
799 | po_line_id = super(purchase_order_line, self).create(cr, uid, vals, context=context) |
800 | if not vals.get('sync_order_line_db_id', False): # 'sync_order_line_db_id' not in vals or vals: |
801 | @@ -1383,6 +1386,8 @@ |
802 | default.update({'stock_take_date': False, 'loan_line_id': False}) |
803 | if 'location_dest_id' not in default: |
804 | default['location_dest_id'] = False |
805 | + if 'reception_dest_id' not in default: |
806 | + default['reception_dest_id'] = False |
807 | |
808 | # from RfQ line to PO line: grab the linked sol if has: |
809 | if pol.order_id.rfq_ok and context.get('generate_po_from_rfq', False): |
810 | @@ -1481,6 +1486,8 @@ |
811 | if line.state == 'draft' and 'price_unit' in new_vals: |
812 | new_vals['original_price'] = new_vals.get('price_unit') |
813 | |
814 | + new_vals['reception_dest_id'] = self.get_reception_dest(cr, uid, new_vals, pol=line, context=context) |
815 | + |
816 | res = super(purchase_order_line, self).write(cr, uid, [line.id], new_vals, context=context) |
817 | |
818 | if self._name != 'purchase.order.merged.line' and vals.get('origin') and not vals.get('linked_sol_id', line.linked_sol_id): |
819 | @@ -2303,7 +2310,7 @@ |
820 | def final_location_dest(self, cr, uid, pol_obj, fo_obj=False, context=None): |
821 | data_obj = self.pool.get('ir.model.data') |
822 | |
823 | - dest = pol_obj.order_id.location_id.id |
824 | + dest = pol_obj.reception_dest_id.id |
825 | |
826 | if not pol_obj.product_id: |
827 | return dest |
828 | @@ -2319,7 +2326,7 @@ |
829 | if fo and fo.procurement_request and fo.location_requestor_id.usage != 'customer': |
830 | return fo.location_requestor_id.id |
831 | |
832 | - chained = self.pool.get('stock.location').chained_location_get(cr, uid, pol_obj.order_id.location_id, product=pol_obj.product_id, context=context) |
833 | + chained = self.pool.get('stock.location').chained_location_get(cr, uid, pol_obj.reception_dest_id, product=pol_obj.product_id, context=context) |
834 | if chained: |
835 | if chained[0].chained_location_type == 'nomenclature': |
836 | # 1st round : Input > Stock, 2nd round Stock -> MED/LOG |
837 | @@ -2330,6 +2337,52 @@ |
838 | |
839 | return dest |
840 | |
841 | + def get_reception_dest(self, cr, uid, vals, pol=None, context=None): |
842 | + ''' |
843 | + Get the location the linked IN move will be sent to during reception |
844 | + ''' |
845 | + if context is None: |
846 | + context = {} |
847 | + |
848 | + prod_obj = self.pool.get('product.product') |
849 | + data_obj = self.pool.get('ir.model.data') |
850 | + srv_id = self.pool.get('stock.location').get_service_location(cr, uid, context=context) |
851 | + input_id = data_obj.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_input')[1] |
852 | + cross_id = data_obj.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_cross_docking')[1] |
853 | + n_stock_id = data_obj.get_object_reference(cr, uid, 'stock_override', 'stock_location_non_stockable')[1] |
854 | + |
855 | + product_type, so = False, False |
856 | + if pol: |
857 | + if 'product_id' in vals and vals.get('product_id'): |
858 | + product_type = prod_obj.read(cr, uid, vals['product_id'], ['type'], context=context)['type'] |
859 | + else: |
860 | + product_type = pol.product_id.type |
861 | + if 'link_so_id' in vals and vals.get('link_so_id'): |
862 | + ftf = ['procurement_request', 'location_requestor_id'] |
863 | + so = self.pool.get('sale.order').browse(cr, uid, vals['link_so_id'], fields_to_fetch=ftf, context=context) |
864 | + else: |
865 | + so = pol.linked_sol_id and pol.linked_sol_id.order_id or pol.link_so_id or False |
866 | + else: |
867 | + if 'product_id' in vals and vals.get('product_id'): |
868 | + product_type = prod_obj.read(cr, uid, vals['product_id'], ['type'], context=context)['type'] |
869 | + if 'linked_sol_id' in vals and vals.get('linked_sol_id'): |
870 | + so = self.pool.get('sale.order.line').browse(cr, uid, vals['linked_sol_id'], |
871 | + fields_to_fetch=['order_id'], context=context).order_id |
872 | + |
873 | + dest = input_id |
874 | + # please also check in delivery_mechanism/delivery_mechanism.py _get_values_from_line to set location_dest_id |
875 | + if product_type == 'service_recep': |
876 | + dest = srv_id |
877 | + elif so: |
878 | + if product_type == 'consu' and so.procurement_request: |
879 | + dest = n_stock_id |
880 | + elif not so.procurement_request or (so.procurement_request and so.location_requestor_id.usage == 'customer'): |
881 | + dest = cross_id |
882 | + elif product_type == 'consu': |
883 | + dest = n_stock_id |
884 | + |
885 | + return dest |
886 | + |
887 | def open_po_form(self, cr, uid, ids, context=None): |
888 | pol = self.browse(cr, uid, ids[0], fields_to_fetch=['order_id'], context=context) |
889 | |
890 | |
891 | === modified file 'bin/addons/purchase/purchase_view.xml' |
892 | --- bin/addons/purchase/purchase_view.xml 2023-04-26 14:00:21 +0000 |
893 | +++ bin/addons/purchase/purchase_view.xml 2023-08-01 08:54:21 +0000 |
894 | @@ -194,7 +194,7 @@ |
895 | <field name="order_type" on_change="onchange_internal_type(order_type, partner_id, categ, dest_partner_id, warehouse_id, delivery_requested_date)" attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('order_type', '=', 'loan_return')]}"/> |
896 | <field name="priority" attrs="{'readonly': [('state', 'not in', ['draft', 'draft_p', 'validated'])]}"/> |
897 | <newline/> |
898 | - <field name="categ" on_change="onchange_categ(categ, warehouse_id, cross_docking_ok, location_id)" attrs="{'readonly': [('state', '!=', 'draft')]}"/> |
899 | + <field name="categ" on_change="onchange_categ(categ)" attrs="{'readonly': [('state', '!=', 'draft')]}"/> |
900 | <field name="details" attrs="{'readonly': [('state', '!=', 'draft')]}"/> |
901 | <newline/> |
902 | </group> |
903 | @@ -372,7 +372,7 @@ |
904 | <field name="dest_partner_id" attrs="{'invisible': [('order_type', '!=', 'direct')], 'required': [('order_type', '=', 'direct')], 'readonly': [('state', 'not in', ['draft', 'draft_p', 'validated'])]}" on_change="on_change_dest_partner_id(dest_partner_id)" domain="[('id', '!=', company_id), ('available_on_po_dpo', '=', active_id)]"/> |
905 | <field name="dest_address_id" domain="[('dest_address', '=', dest_partner_id)]" attrs="{'required': [('order_type', '=', 'direct')], 'readonly': [('state', 'not in', ['draft', 'draft_p', 'validated'])]}"/> |
906 | <field name="cross_docking_ok" invisible="1" /> |
907 | - <field name="location_id" domain="[('usage', '=', 'internal')]" readonly="1" on_change="onchange_location_id(location_id,categ)"/> |
908 | + <field name="location_names" readonly="1"/> |
909 | <field name="incoterm_id" attrs="{'invisible': [('intl_supplier_ok', '=', False)], 'readonly': [('state', 'not in', ['draft', 'draft_p', 'validated', 'validated_p'])]}" widget="selection"/> |
910 | </group> |
911 | <newline/> |
912 | @@ -703,7 +703,7 @@ |
913 | <field name="display_resourced_orig_line" readonly="1"/> |
914 | <field name="display_sync_ref" invisible="1"/> |
915 | <field name="instance_sync_order_ref" attrs="{'required': [('display_sync_ref', '=', True), ('created_by_vi_import', '=', False)], 'invisible': ['|', ('display_sync_ref', '=', False), ('origin', '=', False)]}" domain="[('order_id.name', '=', origin)]"/> |
916 | - |
917 | + <field name="reception_dest_id" readonly="1"/> |
918 | |
919 | <separator string="Changes" colspan="5"/> |
920 | <group colspan="5" col="8"> |
921 | |
922 | === modified file 'bin/addons/purchase/purchase_workflow.py' |
923 | --- bin/addons/purchase/purchase_workflow.py 2023-06-13 13:00:48 +0000 |
924 | +++ bin/addons/purchase/purchase_workflow.py 2023-08-01 08:54:21 +0000 |
925 | @@ -797,7 +797,7 @@ |
926 | self.pool.get('stock.move').in_action_confirm(cr, uid, incoming_move_id, context) |
927 | |
928 | # create internal moves (INT): |
929 | - if pol.order_id.location_id.input_ok and pol.product_id.type not in ('service_recep', 'consu'): |
930 | + if pol.reception_dest_id.input_ok and pol.product_id.type not in ('service_recep', 'consu'): |
931 | internal_pick = self.pool.get('stock.picking').search(cr, uid, [ |
932 | ('type', '=', 'internal'), |
933 | ('purchase_id', '=', pol.order_id.id), |
934 | |
935 | === modified file 'bin/addons/purchase/report/purchase_report.py' |
936 | --- bin/addons/purchase/report/purchase_report.py 2018-10-30 10:56:14 +0000 |
937 | +++ bin/addons/purchase/report/purchase_report.py 2023-08-01 08:54:21 +0000 |
938 | @@ -97,7 +97,7 @@ |
939 | else |
940 | u.id |
941 | end) as product_uom, |
942 | - s.location_id as location_id, |
943 | + l.reception_dest_id as location_id, |
944 | sum(l.product_qty/u.factor) as quantity, |
945 | extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay, |
946 | extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass, |
947 | @@ -119,7 +119,7 @@ |
948 | s.partner_id, |
949 | l.product_qty, |
950 | u.factor, |
951 | - s.location_id, |
952 | + l.reception_dest_id, |
953 | l.price_unit, |
954 | s.date_approve, |
955 | l.date_planned, |
956 | |
957 | === modified file 'bin/addons/sync_so/purchase.py' |
958 | --- bin/addons/sync_so/purchase.py 2023-04-03 15:05:12 +0000 |
959 | +++ bin/addons/sync_so/purchase.py 2023-08-01 08:54:21 +0000 |
960 | @@ -827,7 +827,6 @@ |
961 | original_po = self.browse(cr, uid, po_id, context=context) |
962 | # UTP-661: Get the 'Cross Docking' value of the original PO, and add it into the split PO |
963 | header_result['cross_docking_ok'] = original_po['cross_docking_ok'] |
964 | - header_result['location_id'] = original_po.location_id.id |
965 | |
966 | default = {} |
967 | default.update(header_result) |
968 | |
969 | === modified file 'bin/addons/sync_so/so_po_common.py' |
970 | --- bin/addons/sync_so/so_po_common.py 2023-01-30 15:49:16 +0000 |
971 | +++ bin/addons/sync_so/so_po_common.py 2023-08-01 08:54:21 +0000 |
972 | @@ -265,7 +265,6 @@ |
973 | |
974 | partner_id = self.get_partner_id(cr, uid, source, context) |
975 | address_id = self.get_partner_address_id(cr, uid, partner_id, context=context) |
976 | - location_id = self.get_location(cr, uid, partner_id, context) |
977 | # just roll back what has been modified --- NO MODIF HERE! |
978 | price_list = self.get_price_list_id(cr, uid, partner_id, context) |
979 | |
980 | @@ -273,7 +272,6 @@ |
981 | header_result['partner_id'] = partner_id |
982 | header_result['partner_address_id'] = address_id |
983 | header_result['pricelist_id'] = price_list |
984 | - header_result['location_id'] = location_id |
985 | |
986 | return header_result |
987 | |
988 | |
989 | === modified file 'bin/addons/tender_flow/report/purchase_report.py' |
990 | --- bin/addons/tender_flow/report/purchase_report.py 2022-12-12 15:51:35 +0000 |
991 | +++ bin/addons/tender_flow/report/purchase_report.py 2023-08-01 08:54:21 +0000 |
992 | @@ -116,7 +116,7 @@ |
993 | s.dest_address_id, |
994 | s.pricelist_id, |
995 | s.validator, |
996 | - s.location_id as location_id, |
997 | + l.reception_dest_id as location_id, |
998 | s.warehouse_id as warehouse_id, |
999 | (case when cc.percentage is not null then |
1000 | cc.analytic_id |
1001 | @@ -188,7 +188,7 @@ |
1002 | ccp.percentage, |
1003 | s.partner_id, |
1004 | part.zone, |
1005 | - s.location_id, |
1006 | + l.reception_dest_id, |
1007 | l.price_unit, |
1008 | s.date_approve, |
1009 | l.date_planned, |
1010 | |
1011 | === modified file 'bin/addons/tender_flow/tender_flow_view.xml' |
1012 | --- bin/addons/tender_flow/tender_flow_view.xml 2023-07-13 11:47:42 +0000 |
1013 | +++ bin/addons/tender_flow/tender_flow_view.xml 2023-08-01 08:54:21 +0000 |
1014 | @@ -289,7 +289,7 @@ |
1015 | <field name="order_type" on_change="onchange_internal_type(order_type, partner_id, categ, dest_partner_id, warehouse_id, delivery_requested_date)" attrs="{'readonly': [('rfq_state', 'in', ['updated','done','cancel'])]}"/> |
1016 | <field name="priority" attrs="{'readonly': [('rfq_state', 'in', ['updated','done','cancel'])]}"/> |
1017 | <newline /> |
1018 | - <field name="categ" on_change="onchange_categ(categ, warehouse_id, cross_docking_ok, location_id)" attrs="{'readonly': [('rfq_state', 'in', ['updated','done','cancel'])]}"/> |
1019 | + <field name="categ" on_change="onchange_categ(categ)" attrs="{'readonly': [('rfq_state', 'in', ['updated','done','cancel'])]}"/> |
1020 | <field name="details" attrs="{'readonly': [('rfq_state', 'in', ['updated','done','cancel'])]}"/> |
1021 | <field name="parent_order_name" readonly="True" attrs="{'invisible': [('parent_order_name', '=', False)]}" /> |
1022 | <newline /> |