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

« back to all changes in this revision

Viewing changes to sourcing/wizard/multiple_sourcing.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:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    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
 
23
from osv import osv
 
24
from tools.translate import _
 
25
 
 
26
from sourcing.sale_order_line import _SELECTION_PO_CFT
 
27
 
 
28
_SELECTION_TYPE = [
 
29
    ('make_to_stock', 'from stock'),
 
30
    ('make_to_order', 'on order'), ]
 
31
 
 
32
class multiple_sourcing_wizard(osv.osv_memory):
 
33
    _name = 'multiple.sourcing.wizard'
 
34
 
 
35
    _columns = {
 
36
        'line_ids': fields.many2many(
 
37
            'sale.order.line',
 
38
            'source_sourcing_line_rel',
 
39
            'line_id',
 
40
            'wizard_id',
 
41
            string='Sourcing lines',
 
42
        ),
 
43
        'type': fields.selection(
 
44
            _SELECTION_TYPE,
 
45
            string='Procurement Method',
 
46
            required=True,
 
47
        ),
 
48
        'po_cft': fields.selection(
 
49
            _SELECTION_PO_CFT,
 
50
            string='PO/CFT',
 
51
        ),
 
52
        'location_id': fields.many2one(
 
53
            'stock.location',
 
54
            string='Location',
 
55
        ),
 
56
        'supplier_id': fields.many2one(
 
57
            'res.partner',
 
58
            string='Supplier',
 
59
            help="If you have choose lines coming from Field Orders, only External/ESC suppliers will be available.",
 
60
        ),
 
61
        'company_id': fields.many2one(
 
62
            'res.company',
 
63
            string='Current company',
 
64
        ),
 
65
        'error_on_lines': fields.boolean(
 
66
            string='Error',
 
67
            help="If there is line without need sourcing on selected lines",
 
68
        ),
 
69
    }
 
70
 
 
71
    def default_get(self, cr, uid, fields_list, context=None):
 
72
        """
 
73
        Set lines with the selected lines to source
 
74
        """
 
75
        if not context:
 
76
            context = {}
 
77
 
 
78
        active_ids = context.get('active_ids')
 
79
        if not active_ids or len(active_ids) < 2:
 
80
            raise osv.except_osv(_('Error'), _('You should select at least two lines to process.'))
 
81
 
 
82
        res = super(multiple_sourcing_wizard, self).default_get(cr, uid, fields_list, context=context)
 
83
 
 
84
        res['line_ids'] = []
 
85
        res['error_on_lines'] = False
 
86
 
 
87
        # Check if all lines are with the same type, then set that type, otherwise set make_to_order
 
88
 
 
89
        # Ignore all lines which have already been sourced, if there are some alredy sourced lines, a message
 
90
        # will be displayed at the top of the wizard
 
91
        res['type'] = 'make_to_stock'
 
92
        res['po_cft'] = False
 
93
        loc = -1 # first location flag
 
94
        supplier = -1 # first location flag
 
95
        for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
 
96
            if line.state == 'draft' and line.sale_order_state == 'validated':
 
97
                res['line_ids'].append(line.id)
 
98
            else:
 
99
                res['error_on_lines'] = True
 
100
 
 
101
            if line.type == 'make_to_order':
 
102
                res['type'] = 'make_to_order'
 
103
                res['po_cft'] = 'po'
 
104
 
 
105
                loc = False # always set False for location if source on order
 
106
                if not line.supplier:
 
107
                    supplier = False
 
108
                else:
 
109
                    temp = line.supplier.id
 
110
                    if supplier == -1: # first location
 
111
                        supplier = temp
 
112
                    elif supplier != temp:
 
113
                        supplier = False
 
114
            else:
 
115
                # UTP-1021: Calculate the location to set into the wizard view if all lines are sourced from the same location
 
116
                supplier = False # if source from stock, always set False to partner
 
117
                temploc = line.location_id.id
 
118
                if loc == -1: # first location
 
119
                    loc = temploc
 
120
                elif temploc != loc:
 
121
                    loc = False
 
122
 
 
123
        # UTP-1021: Set default values on openning the wizard
 
124
        if loc != -1:
 
125
            res['location_id'] = loc
 
126
        if supplier != -1:
 
127
            res['supplier_id'] = supplier
 
128
 
 
129
        if not res['line_ids']:
 
130
            raise osv.except_osv(_('Error'), _('No non-sourced lines are selected. Please select non-sourced lines'))
 
131
 
 
132
        res['company_id'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
 
133
 
 
134
        return res
 
135
 
 
136
    def save_lines(self, cr, uid, ids, context=None):
 
137
        '''
 
138
        Set values to sourcing lines
 
139
        '''
 
140
        if not context:
 
141
            context = {}
 
142
 
 
143
        line_obj = self.pool.get('sale.order.line')
 
144
 
 
145
        for wiz in self.browse(cr, uid, ids, context=context):
 
146
            if wiz.type == 'make_to_order':
 
147
                if not wiz.po_cft:
 
148
                    raise osv.except_osv(_('Error'), _('The Procurement method should be filled !'))
 
149
                elif wiz.po_cft != 'cft' and not wiz.supplier_id:
 
150
                    raise osv.except_osv(_('Error'), _('You should select a supplier !'))
 
151
 
 
152
            errors = {}
 
153
            for line in wiz.line_ids:
 
154
                if line.order_id.procurement_request and wiz.po_cft == 'dpo':
 
155
                    err_msg = 'You cannot choose Direct Purchase Order as method to source Internal Request lines.'
 
156
                    errors.setdefault(err_msg, [])
 
157
                    errors[err_msg].append((line.id, '%s of %s' % (line.line_number, line.order_id.name)))
 
158
                else:
 
159
                    try:
 
160
                        line_obj.write(cr, uid, [line.id], {'type': wiz.type,
 
161
                                                            'po_cft': wiz.po_cft,
 
162
                                                            'supplier': wiz.supplier_id and wiz.supplier_id.id or False,
 
163
                                                            'location_id': wiz.location_id.id and wiz.location_id.id or False},
 
164
                                                             context=context)
 
165
                    except osv.except_osv, e:
 
166
                        errors.setdefault(e.value, [])
 
167
                        errors[e.value].append((line.id, '%s of %s' % (line.line_number, line.order_id.name)))
 
168
 
 
169
            if errors:
 
170
                error_msg = ''
 
171
                for e in errors:
 
172
                    if error_msg:
 
173
                        error_msg += ' // '
 
174
                    if len(errors[e]) > 1:
 
175
                        error_msg += 'Lines %s ' % ', '.join(str(x[1]) for x in errors[e])
 
176
                    else:
 
177
                        error_msg += 'Line %s ' % ', '.join(str(x[1]) for x in errors[e])
 
178
                    error_msg += ': %s' % e
 
179
                raise osv.except_osv(_('Errors'), _('There are some errors on sourcing lines : %s') % error_msg)
 
180
 
 
181
        # Commit the result to avoid problem confirmLine in thread with new cursor
 
182
        cr.commit()
 
183
 
 
184
        return {'type': 'ir.actions.act_window_close'}
 
185
 
 
186
    def source_lines(self, cr, uid, ids, context=None):
 
187
        '''
 
188
        Confirm all lines
 
189
        '''
 
190
        # Objects
 
191
        line_obj = self.pool.get('sale.order.line')
 
192
 
 
193
        if not context:
 
194
            context = {}
 
195
 
 
196
        if isinstance(ids, (int, long)):
 
197
            ids = [ids]
 
198
 
 
199
        lines_to_confirm = []
 
200
 
 
201
        for wiz in self.browse(cr, uid, ids, context=context):
 
202
            for line in wiz.line_ids:
 
203
                if line.order_id.procurement_request and wiz.po_cft == 'dpo':
 
204
                    raise osv.except_osv(_('Error'), _('You cannot choose Direct Purchase Order as method to source Internal Request lines.'))
 
205
                lines_to_confirm.append(line.id)
 
206
 
 
207
        line_obj.confirmLine(cr, uid, lines_to_confirm, context=context)
 
208
 
 
209
        return {'type': 'ir.actions.act_window_close'}
 
210
 
 
211
    def save_source_lines(self, cr, uid, ids, context=None):
 
212
        '''
 
213
        Set values to sourcing lines and confirm them
 
214
        '''
 
215
        if not context:
 
216
            context = {}
 
217
 
 
218
        self.save_lines(cr, uid, ids, context=context)
 
219
        self.source_lines(cr, uid, ids, context=context)
 
220
 
 
221
        return {'type': 'ir.actions.act_window_close'}
 
222
 
 
223
    def change_type(self, cr, uid, ids, l_type, context=None):
 
224
        '''
 
225
        Unset the other fields if the type is 'from stock'
 
226
        '''
 
227
        if l_type == 'make_to_order':
 
228
            return {'value': {'location_id': False}}
 
229
 
 
230
        res = {'value': {'po_cft': False, 'supplier_id': False}}
 
231
        if not context or not context[0] or not context[0][2]:
 
232
            return res
 
233
 
 
234
        # UF-2508: Set by default Stock if all the lines had either no location or stock before
 
235
        active_ids = context[0][2]
 
236
        context = {}
 
237
        if not active_ids:
 
238
            return res
 
239
 
 
240
        wh_obj = self.pool.get('stock.warehouse')
 
241
        wh_ids = wh_obj.search(cr, uid, [], context=context)
 
242
        if wh_ids:
 
243
            stock_loc = wh_obj.browse(cr, uid, wh_ids[0], context=context).lot_stock_id.id
 
244
 
 
245
        all_line_empty = True
 
246
        for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
 
247
            if line.location_id and line.location_id.id != stock_loc:
 
248
                all_line_empty = False
 
249
 
 
250
        if all_line_empty: # by default, and if all lines has no location, then set by default Stock
 
251
            return {'value': {'po_cft': False, 'supplier_id': False, 'location_id': stock_loc}}
 
252
        return {'value': {'po_cft': False, 'supplier_id': False}}
 
253
 
 
254
    def change_po_cft(self, cr, uid, ids, po_cft, context=None):
 
255
        '''
 
256
        Unset the supplier if tender is choosen
 
257
        '''
 
258
        if po_cft == 'cft':
 
259
            return {'value': {'supplier_id': False}}
 
260
 
 
261
        return {}
 
262
 
 
263
    def change_supplier(self, cr, uid, ids, supplier, context=None):
 
264
        '''
 
265
        Check if the partner has an address.
 
266
        '''
 
267
        partner_obj = self.pool.get('res.partner')
 
268
 
 
269
        result = {}
 
270
 
 
271
        if supplier:
 
272
            partner = partner_obj.browse(cr, uid, supplier, context)
 
273
            # Check if the partner has addresses
 
274
            if not partner.address:
 
275
                result['warning'] = {
 
276
                    'title': _('Warning'),
 
277
                    'message': _('The chosen partner has no address. Please define an address before continuing.'),
 
278
                }
 
279
        return result
 
280
 
 
281
    def change_location(self, cr, uid, ids, location_id, line_ids, context=None):
 
282
        res = {'value': {}}
 
283
        if not location_id:
 
284
            return res
 
285
 
 
286
        if not line_ids or not line_ids[0] or not line_ids[0][2]:
 
287
            return res
 
288
 
 
289
        line_obj = self.pool.get('sale.order.line')
 
290
        active_ids = line_ids[0][2]
 
291
 
 
292
        context = {}
 
293
        context.update({'from_multiple_line_sourcing': False})
 
294
        for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
 
295
            line_obj.write(cr, uid, [line.id], {'type': 'make_to_stock',
 
296
                                                        'po_cft': False,
 
297
                                                        'supplier': False,
 
298
                                                        'location_id': location_id}, # UTP-1021: Update loc and ask the view to refresh
 
299
                                                         context=context)
 
300
        res = {'value':
 
301
               {'line_ids': active_ids, 'error_on_lines': False, 'po_cft':False,}}
 
302
        return res
 
303
 
 
304
 
 
305
multiple_sourcing_wizard()
 
306
 
 
307
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: