~unifield-team/unifield-wm/us-826

« back to all changes in this revision

Viewing changes to kit/wizard/kit_selection.py

  • Committer: Quentin THEURET
  • Date: 2016-03-04 12:15:00 UTC
  • Revision ID: qt@tempo-consulting.fr-20160304121500-u2ay8zrf83ih9fu3
US-826 [IMP] Change the way to check if products is not consistent on add multiple line wizard

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
from msf_outgoing import INTEGRITY_STATUS_SELECTION
29
29
 
 
30
 
30
31
class kit_selection(osv.osv_memory):
31
32
    '''
32
33
    kit selection
33
34
    '''
34
35
    _name = "kit.selection"
 
36
    
 
37
    def _vals_get(self, cr, uid, ids, fields, arg, context=None):
 
38
        '''
 
39
        multi fields function method
 
40
        '''
 
41
        # Some verifications
 
42
        if context is None:
 
43
            context = {}
 
44
        if isinstance(ids, (int, long)):
 
45
            ids = [ids]
 
46
            
 
47
        # objects
 
48
        sol_obj = self.pool.get('sale.order.line')
 
49
        pol_obj = self.pool.get('purchase.order.line')
 
50
        
 
51
        result = {}
 
52
        for obj in self.browse(cr, uid, ids, context=context):
 
53
            result[obj.id] = {}
 
54
            # corresponding_so_line_id_kit_selection
 
55
            sol_ids = False
 
56
            if obj.order_line_id_kit_selection:
 
57
                sol_ids = pol_obj.get_sol_ids_from_pol_ids(cr, uid, [obj.order_line_id_kit_selection.id], context=context)
 
58
                assert len(sol_ids) <= 1, 'kit selection purchase line: the number of corresponding sale order line is greater than 1: %s'%len(sol_ids)
 
59
            # true if we get some sale order lines
 
60
            result[obj.id].update({'corresponding_so_line_id_kit_selection': sol_ids and sol_ids[0] or False})
 
61
            # corresponding_so_id_kit_selection
 
62
            so_id = False
 
63
            if sol_ids:
 
64
                datas = sol_obj.read(cr, uid, sol_ids, ['order_id'], context=context)
 
65
                for data in datas:
 
66
                    if data['order_id']:
 
67
                        so_id = data['order_id'][0]
 
68
            # write the value
 
69
            result[obj.id].update({'corresponding_so_id_kit_selection': so_id})
 
70
        return result
 
71
    
35
72
    _columns = {'product_id': fields.many2one('product.product', string='Kit Product', readonly=True),
36
73
                'kit_id': fields.many2one('composition.kit', string='Theoretical Kit'),
37
 
                'order_line_id_kit_selection': fields.many2one('purchase.order.line', string="Purchase Order Line", readonly=True, required=True),
 
74
                'order_line_id_kit_selection': fields.many2one('purchase.order.line', string='Purchase Order Line', readonly=True, required=True),
 
75
                'impact_so_kit_selection': fields.boolean('Impact Field Order', help='Impact corresponding Field Order by creating a corresponding Field Order line.'),
38
76
                # one2many
39
77
                'product_ids_kit_selection': fields.one2many('kit.selection.line', 'wizard_id_kit_selection_line', string='Replacement Products'),
40
78
                # related fields
41
79
                'partner_id_kit_selection': fields.related('order_line_id_kit_selection', 'order_id', 'partner_id', string='Partner', type='many2one', relation='res.partner', readonly=True),
42
 
                'pricelist_id_kit_selection': fields.related('order_line_id_kit_selection', 'order_id', 'pricelist_id', string='PriceList', type='many2one', relation='product.pricelist', readonly=True),
 
80
                'pricelist_id_kit_selection': fields.related('order_line_id_kit_selection', 'order_id', 'pricelist_id', string='Currency', type='many2one', relation='product.pricelist', readonly=True),
43
81
                'warehouse_id_kit_selection': fields.related('order_line_id_kit_selection', 'order_id', 'warehouse_id', string='Warehouse', type='many2one', relation='stock.warehouse', readonly=True),
 
82
                # function fields
 
83
                'corresponding_so_line_id_kit_selection': fields.function(_vals_get, method=True, type='many2one', relation='sale.order.line', string='Corresponding Fo Line', multi='get_vals_kit_selection', store=False, readonly=True),
 
84
                'corresponding_so_id_kit_selection': fields.function(_vals_get, method=True, type='many2one', relation='sale.order', string='Corresponding Fo', multi='get_vals_kit_selection', store=False, readonly=True),
44
85
                }
45
86
    
46
87
    _defaults = {'product_id': lambda s, cr, uid, c: c.get('product_id', False),
47
88
                 'order_line_id_kit_selection': lambda s, cr, uid, c: c.get('active_ids') and c.get('active_ids')[0] or False,
 
89
                 'impact_so_kit_selection': True,
48
90
                 }
49
91
    
50
92
    def import_items(self, cr, uid, ids, context=None):
69
111
                          'uom_id_kit_selection_line': item.item_uom_id.id,
70
112
                          }
71
113
                line_obj.create(cr, uid, values, context=dict(context, pol_ids=context['active_ids']))
72
 
        return self.pool.get('wizard').open_wizard(cr, uid, pol_ids, type='update', context=context)
 
114
        return self.pool.get('wizard').open_wizard(cr, uid, pol_ids, w_type='update', context=context)
73
115
    
74
116
    def validate_lines(self, cr, uid, ids, context=None):
75
117
        '''
113
155
        if isinstance(ids, (int, long)):
114
156
            ids = [ids]
115
157
        # objects
 
158
        wf_service = netsvc.LocalService("workflow")
116
159
        pol_obj = self.pool.get('purchase.order.line')
 
160
        so_obj = self.pool.get('sale.order')
 
161
        sol_obj = self.pool.get('sale.order.line')
117
162
        # id of corresponding purchase order line
118
163
        pol_ids = context['active_ids']
119
164
        pol_id = context['active_ids'][0]
122
167
        integrity_check = self.validate_lines(cr, uid, ids, context=context)
123
168
        if not integrity_check:
124
169
            # the windows must be updated to trigger tree colors
125
 
            return self.pool.get('wizard').open_wizard(cr, uid, pol_ids, type='update', context=context)
 
170
            return self.pool.get('wizard').open_wizard(cr, uid, pol_ids, w_type='update', context=context)
126
171
        # process
 
172
        ctx_keep_info = context.copy()
 
173
        ctx_keep_info['keepDateAndDistrib'] = True
127
174
        for obj in self.browse(cr, uid, ids, context=context):
128
175
            if not len(obj.product_ids_kit_selection):
129
176
                raise osv.except_osv(_('Warning !'), _('Replacement Items must be selected.'))
 
177
            # to keep a link to previous line (for copy) and as a flag to write in the first loop
 
178
            last_line_id = False
130
179
            # for each item from the product_ids_kit_selection
131
180
            for item_v in obj.product_ids_kit_selection:
132
181
                # price unit is mandatory
146
195
                data = self.pool.get('kit.selection.line')._call_pol_on_change(cr, uid, ids, product_id, qty, uom_id, price_unit,
147
196
                                                                               type='product_id_change',
148
197
                                                                               context=dict(context, pol_ids=context['active_ids']))
149
 
                # create a new pol
150
 
                p_values = {'product_id': product_id,
151
 
                            'product_qty': pol.product_qty*qty,
152
 
                            'price_unit': item_v.price_unit_kit_selection_line,
153
 
                            'product_uom': uom_id,
154
 
                            'default_code': data['value']['default_code'],
155
 
                            'name': data['value']['name'],
156
 
                            'date_planned': pol.date_planned,
157
 
                            'confirmed_delivery_date': pol.confirmed_delivery_date,
158
 
                            'default_name': data['value']['default_name'],
159
 
                            'order_id': pol.order_id.id,
160
 
                            'notes': pol.notes,
161
 
                            'comment': pol.comment,
162
 
                            'procurement_id': pol.procurement_id.id,
163
 
                            'partner_id': pol.partner_id.id,
164
 
                            'company_id': pol.company_id.id,
165
 
                            'state': pol.state,
166
 
                            }
167
 
                new_id = pol_obj.create(cr, uid, p_values, context=context)
168
 
                
169
 
        # delete the pol
170
 
        pol_obj.unlink(cr, uid, [pol_id], context=context)
 
198
                # common dictionary of data
 
199
                values = {'product_id': product_id,
 
200
                          'price_unit': item_v.price_unit_kit_selection_line,
 
201
                          'product_uom': uom_id,
 
202
                          'default_code': data['value']['default_code'],
 
203
                          'name': data['value']['name'],
 
204
                          'default_name': data['value']['default_name'],
 
205
                          }
 
206
                # if we are treating a line with link to so
 
207
                # if Internal Request, we do not update corresponding Internal Request
 
208
                if obj.corresponding_so_line_id_kit_selection and obj.impact_so_kit_selection and not obj.corresponding_so_id_kit_selection.procurement_request:
 
209
                    # if we have already update the existing pol, we create a new sol
 
210
                    # an go through the whole process
 
211
                    # if not, we simply update the pol, corresponding sol will be updated
 
212
                    # when the pol is confirmed
 
213
                    if last_line_id:
 
214
                        # we create a Fo line by copying related Fo line. we then execute procurement creation function, and process the procurement
 
215
                        # the merge into the actual Po is forced
 
216
                        # copy the original sale order line, reset po_cft to 'po' (we don't want a new tender if any)
 
217
                        values.update({'line_number': obj.corresponding_so_line_id_kit_selection.line_number, # the Fo is not draft anyway (sourced), following sequencing policy, split Fo line maintains original one
 
218
                                       'po_cft': 'po',
 
219
                                       'product_uom_qty': pol.product_qty*qty,
 
220
                                       'product_uom': uom_id,
 
221
                                       'product_uos_qty': pol.product_qty*qty,
 
222
                                       'product_uos': uom_id,
 
223
                                       'so_back_update_dest_po_id_sale_order_line': obj.order_line_id_kit_selection.order_id.id,
 
224
                                       'so_back_update_dest_pol_id_sale_order_line': obj.order_line_id_kit_selection.id,
 
225
                                       })
 
226
                        # copy existing sol
 
227
                        last_line_id = sol_obj.copy(cr, uid, last_line_id, values, context=ctx_keep_info)
 
228
                        # call the new procurement creation method
 
229
                        so_obj.action_ship_proc_create(cr, uid, [obj.corresponding_so_id_kit_selection.id], context=context)
 
230
                        # run the procurement, the make_po function detects the link to original po
 
231
                        # and force merge the line to this po (even if it is not draft anymore)
 
232
                        new_data_so = sol_obj.read(cr, uid, [last_line_id], ['procurement_id'], context=context)
 
233
                        new_proc_id = new_data_so[0]['procurement_id'][0]
 
234
                        wf_service.trg_validate(uid, 'procurement.order', new_proc_id, 'button_check', cr)
 
235
                        # if original po line is confirmed, we action_confirm new line
 
236
                        if obj.order_line_id_kit_selection.state == 'confirmed':
 
237
                            # the correct line number according to new line number policy is set in po_line_values_hook of order_line_number/order_line_number.py/procurement_order
 
238
                            new_po_ids = pol_obj.search(cr, uid, [('procurement_id', '=', new_proc_id)], context=context)
 
239
                            pol_obj.action_confirm(cr, uid, new_po_ids, context=context)
 
240
                    else:
 
241
                        # first item to be treated, we update the existing purchase order line
 
242
                        # sale order line will be updated when the Po is confirmed
 
243
                        last_line_id = obj.corresponding_so_line_id_kit_selection.id
 
244
                        # update values for pol structure
 
245
                        values.update({'product_qty': pol.product_qty*qty})
 
246
                        pol_obj.write(cr, uid, [obj.order_line_id_kit_selection.id], values, context=context)
 
247
                else:
 
248
                    # no link to so, or no impact desired
 
249
                    # create a new pol
 
250
                    # update values for pol structure
 
251
                    values.update({'product_qty': pol.product_qty*qty})
 
252
                    # following new sequencing policy, we check if resequencing occur (behavior 1).
 
253
                    # if not (behavior 2), the split line keeps the same line number as original line
 
254
                    if not pol_obj.allow_resequencing(cr, uid, [obj.order_line_id_kit_selection.id], context=context):
 
255
                        # set default value for line_number as the same as original line
 
256
                        values.update({'line_number': obj.order_line_id_kit_selection.line_number})
 
257
                    
 
258
                    if last_line_id:
 
259
                        # the existing purchase order line has already been updated, we create a new one
 
260
                        # copy the original purchase order line
 
261
                        last_line_id = pol_obj.copy(cr, uid, last_line_id, values, context=ctx_keep_info)
 
262
                        # if original po line is confirmed, we action_confirm new line
 
263
                        if obj.order_line_id_kit_selection.state == 'confirmed':
 
264
                            pol_obj.action_confirm(cr, uid, [last_line_id], context=context)
 
265
                    else:
 
266
                        # first item to be treated, we update the existing line
 
267
                        last_line_id = obj.order_line_id_kit_selection.id
 
268
                        pol_obj.write(cr, uid, [last_line_id], values, context=context)
171
269
                
172
270
        return {'type': 'ir.actions.act_window_close'}
173
271
    
267
365
        assert context, 'No context defined, problem on method call'
268
366
        if isinstance(ids, (int, long)):
269
367
            ids = [ids]
270
 
            
 
368
 
271
369
        # result
272
370
        result = {'value': {'qty_kit_selection_line': 0.0,
273
371
                            'uom_id_kit_selection_line': False,
279
377
        result['value'].update({'price_unit_kit_selection_line': 'price_unit' in data['value'] and data['value']['price_unit'] or 0.0,
280
378
                                'qty_kit_selection_line': 'product_qty' in data['value'] and data['value']['product_qty'] or 0.0,
281
379
                                'uom_id_kit_selection_line': 'product_uom' in data['value'] and data['value']['product_uom'] or False})
 
380
 
 
381
        uom_id = result.get('value', {}).get('uom_id_kit_selection_line')
 
382
        qty = result.get('value', {}).get('qty_kit_selection_line')
 
383
        if qty:
 
384
            result = self.pool.get('product.uom')._change_round_up_qty(cr, uid, uom_id, qty, 'qty_kit_selection_line', result=result)
 
385
 
282
386
        # return result
283
387
        return result
284
388