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

« back to all changes in this revision

Viewing changes to kit/wizard/kit_selection.py

  • Committer: jf
  • Date: 2012-06-13 12:43:21 UTC
  • mfrom: (827.5.11 uf-635)
  • Revision ID: jf@tempo4-20120613124321-2b8cwgl86gyy2tb7
UF-635 [DEV] Documents workflow: Graphic representation
lp:~unifield-team/unifield-wm/uf-635 revno 838

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) Copyright (C) 2011 MSF, TeMPO Consulting.
 
6
#
 
7
#    This program is free software: you can redistribute it and/or modify
 
8
#    it under the terms of the GNU Affero General Public License as
 
9
#    published by the Free Software Foundation, either version 3 of the
 
10
#    License, or (at your option) any later version.
 
11
#
 
12
#    This program is distributed in the hope that it will be useful,
 
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#    GNU Affero General Public License for more details.
 
16
#
 
17
#    You should have received a copy of the GNU Affero General Public License
 
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
#
 
20
##############################################################################
 
21
 
 
22
from osv import fields, osv
 
23
from tools.translate import _
 
24
import decimal_precision as dp
 
25
 
 
26
import netsvc
 
27
 
 
28
from msf_outgoing import INTEGRITY_STATUS_SELECTION
 
29
 
 
30
class kit_selection(osv.osv_memory):
 
31
    '''
 
32
    kit selection
 
33
    '''
 
34
    _name = "kit.selection"
 
35
    _columns = {'product_id': fields.many2one('product.product', string='Kit Product', readonly=True),
 
36
                '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),
 
38
                # one2many
 
39
                'product_ids_kit_selection': fields.one2many('kit.selection.line', 'wizard_id_kit_selection_line', string='Replacement Products'),
 
40
                # related fields
 
41
                '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),
 
43
                'warehouse_id_kit_selection': fields.related('order_line_id_kit_selection', 'order_id', 'warehouse_id', string='Warehouse', type='many2one', relation='stock.warehouse', readonly=True),
 
44
                }
 
45
    
 
46
    _defaults = {'product_id': lambda s, cr, uid, c: c.get('product_id', False),
 
47
                 'order_line_id_kit_selection': lambda s, cr, uid, c: c.get('active_ids') and c.get('active_ids')[0] or False,
 
48
                 }
 
49
    
 
50
    def import_items(self, cr, uid, ids, context=None):
 
51
        '''
 
52
        import lines into product_ids_kit_selection
 
53
        '''
 
54
        # objects
 
55
        line_obj = self.pool.get('kit.selection.line')
 
56
        # purchase order line id
 
57
        pol_ids = context['active_ids']
 
58
        
 
59
        for obj in self.browse(cr, uid, ids, context=context):
 
60
            if not obj.kit_id:
 
61
                raise osv.except_osv(_('Warning !'), _('A theoretical version should be selected.'))
 
62
            if obj.kit_id.state != 'completed':
 
63
                raise osv.except_osv(_('Warning !'), _('The theoretical version must be completed.'))
 
64
            for item in obj.kit_id.composition_item_ids:
 
65
                values = {'order_line_id_kit_selection_line': obj.order_line_id_kit_selection.id,
 
66
                          'wizard_id_kit_selection_line': obj.id,
 
67
                          'product_id_kit_selection_line': item.item_product_id.id,
 
68
                          'qty_kit_selection_line': item.item_qty,
 
69
                          'uom_id_kit_selection_line': item.item_uom_id.id,
 
70
                          }
 
71
                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)
 
73
    
 
74
    def validate_lines(self, cr, uid, ids, context=None):
 
75
        '''
 
76
        validate the lines
 
77
        
 
78
        - qty > 0.0 (must_be_greater_than_0)
 
79
        - unit price > 0.0
 
80
        
 
81
        return True or False
 
82
        '''
 
83
        # objects
 
84
        prod_obj = self.pool.get('product.product')
 
85
        lot_obj = self.pool.get('stock.production.lot')
 
86
        # errors
 
87
        errors = {'must_be_greater_than_0': False,
 
88
                  'price_must_be_greater_than_0': False,
 
89
                  }
 
90
        for obj in self.browse(cr, uid, ids, context=context):
 
91
            for item in obj.product_ids_kit_selection:
 
92
                # reset the integrity status
 
93
                item.write({'integrity_status': 'empty'}, context=context)
 
94
                # qty
 
95
                if item.qty_kit_selection_line <= 0.0:
 
96
                    # qty is needed
 
97
                    errors.update(must_be_greater_than_0=True)
 
98
                    item.write({'integrity_status': 'must_be_greater_than_0'}, context=context)
 
99
                # unit price
 
100
                if item.price_unit_kit_selection_line <= 0.0:
 
101
                    # unit price is needed
 
102
                    errors.update(price_must_be_greater_than_0=True)
 
103
                    item.write({'integrity_status': 'price_must_be_greater_than_0'}, context=context)
 
104
        # check the encountered errors
 
105
        return all([not x for x in errors.values()])
 
106
 
 
107
    def do_de_kitting(self, cr, uid, ids, context=None):
 
108
        '''
 
109
        create a purchase order line for each kit item and delete the selected kit purchase order line
 
110
        '''
 
111
        # quick integrity check
 
112
        assert context, 'No context defined, problem on method call'
 
113
        if isinstance(ids, (int, long)):
 
114
            ids = [ids]
 
115
        # objects
 
116
        pol_obj = self.pool.get('purchase.order.line')
 
117
        # id of corresponding purchase order line
 
118
        pol_ids = context['active_ids']
 
119
        pol_id = context['active_ids'][0]
 
120
        pol = pol_obj.browse(cr, uid, pol_id, context=context)
 
121
        # integrity constraint
 
122
        integrity_check = self.validate_lines(cr, uid, ids, context=context)
 
123
        if not integrity_check:
 
124
            # 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)
 
126
        # process
 
127
        ctx_keep_info = context.copy()
 
128
        ctx_keep_info['keepDateAndDistrib'] = True
 
129
        for obj in self.browse(cr, uid, ids, context=context):
 
130
            if not len(obj.product_ids_kit_selection):
 
131
                raise osv.except_osv(_('Warning !'), _('Replacement Items must be selected.'))
 
132
            # for each item from the product_ids_kit_selection
 
133
            for item_v in obj.product_ids_kit_selection:
 
134
                # price unit is mandatory
 
135
                if item_v.price_unit_kit_selection_line <= 0.0:
 
136
                    raise osv.except_osv(_('Warning !'), _('Unit Price must be specified for each line.'))
 
137
                # selected product_id
 
138
                product_id = item_v.product_id_kit_selection_line.id
 
139
                # selected qty
 
140
                qty = item_v.qty_kit_selection_line
 
141
                if qty <= 0.0:
 
142
                    raise osv.except_osv(_('Warning !'), _('Quantity must be greater than 0.0.'))
 
143
                # selected uom
 
144
                uom_id = item_v.uom_id_kit_selection_line.id
 
145
                # price unit
 
146
                price_unit = item_v.price_unit_kit_selection_line
 
147
                # call purchase order line on change function
 
148
                data = self.pool.get('kit.selection.line')._call_pol_on_change(cr, uid, ids, product_id, qty, uom_id, price_unit,
 
149
                                                                               type='product_id_change',
 
150
                                                                               context=dict(context, pol_ids=context['active_ids']))
 
151
                # create a new pol
 
152
                p_values = {'product_id': product_id,
 
153
                            'product_qty': pol.product_qty*qty,
 
154
                            'price_unit': item_v.price_unit_kit_selection_line,
 
155
                            'product_uom': uom_id,
 
156
                            'default_code': data['value']['default_code'],
 
157
                            'name': data['value']['name'],
 
158
                            'date_planned': pol.date_planned,
 
159
                            'confirmed_delivery_date': pol.confirmed_delivery_date,
 
160
                            'default_name': data['value']['default_name'],
 
161
                            'order_id': pol.order_id.id,
 
162
                            'notes': pol.notes,
 
163
                            'comment': pol.comment,
 
164
                            'procurement_id': pol.procurement_id.id,
 
165
                            'partner_id': pol.partner_id.id,
 
166
                            'company_id': pol.company_id.id,
 
167
                            'state': pol.state,
 
168
                            }
 
169
                # copy the original purchase order line
 
170
                new_id = pol_obj.copy(cr, uid, pol_id, p_values, context=ctx_keep_info)
 
171
#                new_id = pol_obj.create(cr, uid, p_values, context=context)
 
172
                
 
173
        # delete the pol
 
174
        pol_obj.unlink(cr, uid, [pol_id], context=context)
 
175
                
 
176
        return {'type': 'ir.actions.act_window_close'}
 
177
    
 
178
kit_selection()
 
179
 
 
180
 
 
181
class kit_selection_line(osv.osv_memory):
 
182
    '''
 
183
    substitute items
 
184
    '''
 
185
    _name = 'kit.selection.line'
 
186
    
 
187
    def create(self, cr, uid, vals, context=None):
 
188
        '''
 
189
        default price unit from pol on_change function
 
190
        '''
 
191
        # objects
 
192
        pol_obj = self.pool.get('purchase.order.line')
 
193
        # id of corresponding purchase order line
 
194
        pol_id = context.get('active_ids', False) and context['active_ids'][0]
 
195
        if pol_id and ('price_unit_kit_selection_line' not in vals or vals.get('price_unit_kit_selection_line') == 0.0):
 
196
            pol = pol_obj.browse(cr, uid, pol_id, context=context)
 
197
            # selected product_id
 
198
            product_id = vals.get('product_id_kit_selection_line', False)
 
199
            # selected qty
 
200
            qty = vals.get('qty_kit_selection_line', 0.0)
 
201
            # selected uom
 
202
            uom_id = vals.get('uom_id_kit_selection_line', False)
 
203
            # price unit
 
204
            price_unit = vals.get('price_unit_kit_selection_line', 0.0)
 
205
            # gather default values
 
206
            data = self._call_pol_on_change(cr, uid, context['active_ids'],
 
207
                                            product_id, qty, uom_id, price_unit, type='product_id_on_change',
 
208
                                            context=dict(context, pol_ids=context['active_ids']))
 
209
            # update price_unit value
 
210
            vals.update({'price_unit_kit_selection_line': data['value']['price_unit']})
 
211
        return super(kit_selection_line, self).create(cr, uid, vals, context=context)
 
212
    
 
213
    def _call_pol_on_change(self, cr, uid, ids, product_id, qty, uom_id, price_unit, type, context=None):
 
214
        '''
 
215
        core function from purchase order line
 
216
        
 
217
        def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
 
218
            partner_id, date_order=False, fiscal_position=False, date_planned=False,
 
219
            name=False, price_unit=False, notes=False):
 
220
        '''
 
221
        # quick integrity check
 
222
        assert context, 'No context defined, problem on method call'
 
223
        if isinstance(ids, (int, long)):
 
224
            ids = [ids]
 
225
            
 
226
        # objects
 
227
        pol_obj = self.pool.get('purchase.order.line')
 
228
        prod_obj = self.pool.get('product.product')
 
229
        # id of corresponding purchase order line
 
230
        pol_id = context['pol_ids'][0]
 
231
        pol = pol_obj.browse(cr, uid, pol_id, context=context)
 
232
        # pricelist from purchase order
 
233
        pricelist_id = pol.order_id.pricelist_id.id
 
234
        # partner_id from purchase order
 
235
        partner_id = pol.order_id.partner_id.id
 
236
        # date_order from purchase order
 
237
        date_order = pol.order_id.date_order
 
238
        # fiscal_position from purchase order
 
239
        fiscal_position_id = pol.order_id.fiscal_position.id
 
240
        # date_planned from purchase order line
 
241
        date_planned = pol.date_planned
 
242
        # name
 
243
        name = False
 
244
        if product_id:
 
245
            name = prod_obj.read(cr, uid, product_id, ['name'], context=context)['name']
 
246
        # notes
 
247
        notes = pol.notes
 
248
        # state
 
249
        state = pol.order_id.state
 
250
        # gather default values
 
251
        if type in ['product_id_change', 'product_uom_change']:
 
252
            data = getattr(pol_obj, type)(cr, uid, ids, pricelist=pricelist_id, product=product_id, qty=qty, uom=uom_id,
 
253
                                          partner_id=partner_id, date_order=date_order, fiscal_position=fiscal_position_id, date_planned=date_planned,
 
254
                                          name=name, price_unit=price_unit, notes=notes)
 
255
        elif type == 'product_id_on_change':
 
256
            data = getattr(pol_obj, type)(cr, uid, ids, pricelist=pricelist_id, product=product_id,
 
257
                                          qty=qty, uom=uom_id, partner_id=partner_id, date_order=date_order,
 
258
                                          fiscal_position=fiscal_position_id, date_planned=date_planned, name=name,
 
259
                                          price_unit=price_unit, notes=notes, state=state, old_price_unit=False)
 
260
        return data
 
261
    
 
262
    def on_product_id_change(self, cr, uid, ids, product_id, qty, uom_id, price_unit, context=None):
 
263
        '''
 
264
        core function from purchase order line
 
265
        
 
266
        def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
 
267
            partner_id, date_order=False, fiscal_position=False, date_planned=False,
 
268
            name=False, price_unit=False, notes=False):
 
269
        '''
 
270
        # quick integrity check
 
271
        assert context, 'No context defined, problem on method call'
 
272
        if isinstance(ids, (int, long)):
 
273
            ids = [ids]
 
274
            
 
275
        # result
 
276
        result = {'value': {'qty_kit_selection_line': 0.0,
 
277
                            'uom_id_kit_selection_line': False,
 
278
                            'price_unit_kit_selection_line': 0.0}}
 
279
        # gather default values
 
280
#        data = self._call_pol_on_change(cr, uid, ids, product_id, qty, uom_id, price_unit, 'product_id_change', context=context)
 
281
        data = self._call_pol_on_change(cr, uid, ids, product_id, qty, uom_id, price_unit, 'product_id_on_change', context=context)
 
282
        # update result price_unit and default uom
 
283
        result['value'].update({'price_unit_kit_selection_line': 'price_unit' in data['value'] and data['value']['price_unit'] or 0.0,
 
284
                                'qty_kit_selection_line': 'product_qty' in data['value'] and data['value']['product_qty'] or 0.0,
 
285
                                'uom_id_kit_selection_line': 'product_uom' in data['value'] and data['value']['product_uom'] or False})
 
286
        # return result
 
287
        return result
 
288
    
 
289
    def on_uom_id_change(self, cr, uid, ids, product_id, qty, uom_id, price_unit, context=None):
 
290
        '''
 
291
        core function from purchase order line
 
292
        
 
293
        def product_uom_change(self, cr, uid, ids, pricelist, product, qty, uom,
 
294
            partner_id, date_order=False, fiscal_position=False, date_planned=False,
 
295
            name=False, price_unit=False, notes=False):
 
296
        '''
 
297
        # quick integrity check
 
298
        assert context, 'No context defined, problem on method call'
 
299
        if isinstance(ids, (int, long)):
 
300
            ids = [ids]
 
301
            
 
302
        # result
 
303
        result = {'value': {'qty_kit_selection_line': 0.0,
 
304
                            'price_unit_kit_selection_line': 0.0}}
 
305
        # gather default values
 
306
        data = self._call_pol_on_change(cr, uid, ids, product_id, qty, uom_id, price_unit, 'product_uom_change', context=context)
 
307
        # update result price_unit - qty
 
308
        result['value'].update({'price_unit_kit_selection_line': 'price_unit' in data['value'] and data['value']['price_unit'] or 0.0,
 
309
                                'qty_kit_selection_line': 'product_qty' in data['value'] and data['value']['product_qty'] or 0.0})
 
310
        # return result
 
311
        return result
 
312
    
 
313
    _columns = {'integrity_status': fields.selection(string=' ', selection=INTEGRITY_STATUS_SELECTION, readonly=True),
 
314
                'order_line_id_kit_selection_line': fields.many2one('purchase.order.line', string="Purchase Order Line", readonly=True, required=True),
 
315
                'wizard_id_kit_selection_line': fields.many2one('kit.selection', string='Kit Selection wizard'),
 
316
                # data
 
317
                'product_id_kit_selection_line': fields.many2one('product.product', string='Product', required=True),
 
318
                'qty_kit_selection_line': fields.float(string='Qty', digits_compute=dp.get_precision('Product UoM'), required=True),
 
319
                'uom_id_kit_selection_line': fields.many2one('product.uom', string='UoM', required=True),
 
320
                'price_unit_kit_selection_line': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Purchase Price')),
 
321
                }
 
322
    
 
323
    _defaults = {'integrity_status': 'empty',
 
324
                 }
 
325
    
 
326
kit_selection_line()
 
327
 
 
328