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

613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
##############################################################################
4
#
5
#    OpenERP, Open Source Management Solution
6
#    Copyright (C) 2012 TeMPO Consulting, MSF. All Rights Reserved
7
#    Developer: Olivier DOSSMANN
8
#
9
#    This program is free software: you can redistribute it and/or modify
10
#    it under the terms of the GNU Affero General Public License as
11
#    published by the Free Software Foundation, either version 3 of the
12
#    License, or (at your option) any later version.
13
#
14
#    This program is distributed in the hope that it will be useful,
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
#    GNU Affero General Public License for more details.
18
#
19
#    You should have received a copy of the GNU Affero General Public License
20
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
#
22
##############################################################################
23
24
from osv import osv
25
from osv import fields
727 by jf
UF-818 [DEV] Inter-section records
26
from tools.translate import _
1380.3.11 by Olivier DOSSMANN
UF-1678 [ADD] Display analytic account regarding date
27
from time import strftime
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
28
29
class sale_order(osv.osv):
30
    _name = 'sale.order'
31
    _inherit = 'sale.order'
32
33
    _columns = {
34
        'analytic_distribution_id': fields.many2one('analytic.distribution', string="Analytic distribution"),
35
    }
36
727 by jf
UF-818 [DEV] Inter-section records
37
    def button_analytic_distribution(self, cr, uid, ids, context=None):
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
38
        """
39
        Launch analytic distribution wizard on a sale order
40
        """
41
        # Some verifications
42
        if not context:
43
            context = {}
44
        if isinstance(ids, (int, long)):
45
            ids = [ids]
46
        # Prepare some values
47
        so = self.browse(cr, uid, ids[0], context=context)
48
        amount = so.amount_total or 0.0
49
        # Search elements for currency
50
        company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
51
        currency = so.currency_id and so.currency_id.id or company_currency
52
        # Get analytic_distribution_id
53
        distrib_id = so.analytic_distribution_id and so.analytic_distribution_id.id
54
        # Prepare values for wizard
55
        vals = {
56
            'total_amount': amount,
57
            'sale_order_id': so.id,
58
            'currency_id': currency or False,
59
            'state': 'cc',
1380.3.11 by Olivier DOSSMANN
UF-1678 [ADD] Display analytic account regarding date
60
            'posting_date': strftime('%Y-%m-%d'),
61
            'document_date': strftime('%Y-%m-%d'),
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
62
        }
63
        if distrib_id:
64
            vals.update({'distribution_id': distrib_id,})
65
        # Create the wizard
66
        wiz_obj = self.pool.get('analytic.distribution.wizard')
67
        wiz_id = wiz_obj.create(cr, uid, vals, context=context)
68
        # Update some context values
69
        context.update({
70
            'active_id': ids[0],
71
            'active_ids': ids,
72
        })
73
        # Open it!
74
        return {
1453.7.12 by jf
UF-1781: Trans analytic distribution
75
                'name': _('Global analytic distribution'),
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
76
                'type': 'ir.actions.act_window',
77
                'res_model': 'analytic.distribution.wizard',
78
                'view_type': 'form',
79
                'view_mode': 'form',
80
                'target': 'new',
81
                'res_id': [wiz_id],
82
                'context': context,
83
        }
84
833.1.1 by jf
UF-998: reset ana. disti. on po/fo/po lines/so lines duplication
85
    def copy_data(self, cr, uid, id, default=None, context=None):
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
86
        """
87
        Copy global distribution and give it to new sale order.
88
        """
89
        # Some verifications
90
        if not context:
91
            context = {}
727 by jf
UF-818 [DEV] Inter-section records
92
        if default is None:
93
            default = {}
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
94
        # Default method
1016.1.2 by jf
[FIX] Duplicate so with keepDateAndDistrib: copy header distrib
95
        if 'analytic_distribution_id' not in default and not context.get('keepDateAndDistrib'):
833.1.1 by jf
UF-998: reset ana. disti. on po/fo/po lines/so lines duplication
96
            default['analytic_distribution_id'] = False
1016.1.2 by jf
[FIX] Duplicate so with keepDateAndDistrib: copy header distrib
97
        new_data = super(sale_order, self).copy_data(cr, uid, id, default=default, context=context)
98
        if new_data and new_data.get('analytic_distribution_id'):
99
            new_data['analytic_distribution_id'] = self.pool.get('analytic.distribution').copy(cr, uid, new_data['analytic_distribution_id'], {}, context=context)
100
        return new_data
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
101
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
102
    def _get_destination_ok(self, cr, uid, lines, context):
1097.1.2 by pierre-marie
Improvement on check analytic function for SO and PO
103
        dest_ok = False
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
104
        for line in lines:
105
            dest_ok = line.account_4_distribution and line.account_4_distribution.destination_ids or False
1130.1.5 by Olivier DOSSMANN
UF-1364 [FIX] Problem with income account for SO and analytic distribution automatic correction
106
            if not dest_ok:
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
107
                raise osv.except_osv(_('Error'), _('No destination found for this line: %s.') % (line.name or '',))
1097.1.2 by pierre-marie
Improvement on check analytic function for SO and PO
108
        return dest_ok
109
1074.17.10 by chloups208
uf-1118 merge lp:~unifield-team/unifield-wm/UF_1352@1082..1083
110
    def analytic_distribution_checks(self, cr, uid, ids, context=None):
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
111
        """
892.14.34 by Olivier DOSSMANN
UF-1091 [ADD] Analytic distribution is now mandatory on ALL FO
112
        Check analytic distribution for each sale order line (except if we come from YAML tests)
892.14.39 by Olivier DOSSMANN
UF-1091 [ADD] Check analytic distribution @FO confirmation
113
        Get a default analytic distribution if intermission.
114
        Change analytic distribution if intermission.
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
115
        """
116
        # Some verifications
117
        if not context:
118
            context = {}
119
        if isinstance(ids, (int, long)):
120
            ids = [ids]
892.14.38 by Olivier DOSSMANN
UF-1091 [WIP] work in progress - Change CC by intermission for FO that are intermission
121
        # Analytic distribution verification
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
122
        ana_obj = self.pool.get('analytic.distribution')
123
        for so in self.browse(cr, uid, ids, context=context):
892.14.39 by Olivier DOSSMANN
UF-1091 [ADD] Check analytic distribution @FO confirmation
124
            for line in so.order_line:
125
                # Search intermission
126
                intermission_cc = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 
127
                    'analytic_account_project_intermission')
128
                # check distribution presence
129
                distrib_id = (line.analytic_distribution_id and line.analytic_distribution_id.id) or (so.analytic_distribution_id and so.analytic_distribution_id.id) or False
130
                if not distrib_id and so.partner_id.partner_type == 'intermission':
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
131
                    account_id = line.account_4_distribution and line.account_4_distribution.id or False
892.14.39 by Olivier DOSSMANN
UF-1091 [ADD] Check analytic distribution @FO confirmation
132
                    # Search default destination_id
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
133
                    destination_id = self.pool.get('account.account').read(cr, uid, account_id, ['default_destination_id']).get('default_destination_id', False)
892.14.39 by Olivier DOSSMANN
UF-1091 [ADD] Check analytic distribution @FO confirmation
134
                    distrib_id = ana_obj.create(cr, uid, {'sale_order_line_ids': [(4,line.id)], 
135
                        'cost_center_lines': [(0, 0, {'destination_id': destination_id[0], 'analytic_id': intermission_cc[1] , 'percentage':'100', 'currency_id': so.currency_id.id})]})
136
                    self.pool.get('sale.order.line').write(cr, uid, [line.id], {'analytic_distribution_id': distrib_id})
137
                    line = self.pool.get('sale.order.line').browse(cr, uid, line.id)
138
                elif distrib_id and so.partner_id.partner_type == 'intermission':
139
                    # Change CC lines
140
                    for cc_line in ana_obj.browse(cr, uid, distrib_id).cost_center_lines:
141
                        self.pool.get('cost.center.distribution.line').write(cr, uid, cc_line.id, {'analytic_id': intermission_cc[1]})
1539.28.2 by matthieu.choplin at msf
[IMP] uf-1784: don't raise an error if there isn't analytic distrib and that the order_type is loan or donation before expiry or standard donation for the FO and PO validation
142
                if not distrib_id and not so.from_yml_test and not so.order_type in ('loan', 'donation_st', 'donation_exp'):
892.14.39 by Olivier DOSSMANN
UF-1091 [ADD] Check analytic distribution @FO confirmation
143
                    raise osv.except_osv(_('Warning'), _('Analytic distribution is mandatory for this line: %s!') % (line.name or '',))
144
                # check distribution state
1539.28.5 by matthieu.choplin at msf
[FIX] uf-1784: add a check if there is no distrib_id
145
                if distrib_id and line.analytic_distribution_state != 'valid' and not so.from_yml_test:
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
146
                    # raise an error if no analytic distribution on line and NONE on header (because no possibility to change anything)
147
                    if (not line.analytic_distribution_id or line.analytic_distribution_state == 'none') and not so.analytic_distribution_id:
1539.28.4 by matthieu.choplin at msf
[FIX]:uf-1784. more explicit ignore of check if types in ('loan', 'donation_st', 'donation_exp')
148
                        # we don't raise an error for these types
149
                        if not so.order_type in ('loan', 'donation_st', 'donation_exp'):
150
                            raise osv.except_osv(_('Warning'), _('Analytic distribution is mandatory for this line: %s') % (line.name or '',))
151
                        else:
152
                            continue
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
153
                    # Change distribution to be valid if needed by using those from header
1097.1.2 by pierre-marie
Improvement on check analytic function for SO and PO
154
                    id_ad = self.pool.get('analytic.distribution').create(cr,uid,{})
1130.1.1 by jf
Merge with unifield-wm + code to get the destination on so line for nomenclature (to be tested)
155
                    for x in line.analytic_distribution_id and line.analytic_distribution_id.cost_center_lines or so.analytic_distribution_id.cost_center_lines:
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
156
                        # fetch compatible destinations then use one of them:
157
                        # - destination if compatible
158
                        # - else default destination of given account
1097.1.2 by pierre-marie
Improvement on check analytic function for SO and PO
159
                        bro_dests = self._get_destination_ok(cr, uid, [line], context=context)
160
                        if x.destination_id in bro_dests:
1130.1.6 by Olivier DOSSMANN
UF-1364 [IMP] Improve code that permit invalid lines to be valid in SO and PO
161
                            bro_dest_ok = x.destination_id
162
                        else:
163
                            bro_dest_ok = line.account_4_distribution.default_destination_id
164
                        # Copy cost center line to the new distribution
165
                        self.pool.get('cost.center.distribution.line').copy(cr, uid, x.id, {'distribution_id': id_ad, 'destination_id': bro_dest_ok.id})
166
                        # Write new distribution and link it to the line
167
                        self.pool.get('sale.order.line').write(cr, uid, [line.id], {'analytic_distribution_id': id_ad})
1074.17.10 by chloups208
uf-1118 merge lp:~unifield-team/unifield-wm/UF_1352@1082..1083
168
        return True
169
170
    def action_ship_proc_create(self, cr, uid, ids, context=None):
171
        """
172
        Do some analytic distribution checks for SO confirmation.
173
        """
174
        # Some verifications
175
        if not context:
176
            context = {}
177
        if isinstance(ids, (int, long)):
178
            ids = [ids]
179
        # Launch some checks
180
        self.analytic_distribution_checks(cr, uid, ids)
181
        # Default behaviour
182
        res = super(sale_order, self).action_ship_proc_create(cr, uid, ids, context=context)
183
        return res
184
185
    def wkf_validated(self, cr, uid, ids, context=None):
186
        """
187
        Do some analytic distribution checks for SO validation.
188
        """
189
        # Some verifications
190
        if not context:
191
            context = {}
192
        if isinstance(ids, (int, long)):
193
            ids = [ids]
194
        self.analytic_distribution_checks(cr, uid, ids)
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
195
        # Default behaviour
1130.1.1 by jf
Merge with unifield-wm + code to get the destination on so line for nomenclature (to be tested)
196
        return super(sale_order, self).wkf_validated(cr, uid, ids, context=context)
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
197
1539.23.1 by Olivier DOSSMANN
UF-1886 [FIX] Set analytic distribution from FO header to invoice header for intersection and external partners
198
    # action_invoice_create have been deleted because of no wizard_sale_invoice since 2.0b2
199
#    def action_invoice_create(self, cr, uid, ids, *args):
200
#        """
201
#        Add analytic distribution from SO to invoice
202
#        """
203
#        # Retrieve some data
204
#        res = super(sale_order, self).action_invoice_create(cr, uid, ids, *args) # invoice_id
205
#        # Set analytic distribution from sale order to invoice
206
#        ana_obj = self.pool.get('analytic.distribution')
207
#        for so in self.browse(cr, uid, ids):
208
#            # Create analytic distribution on invoices regarding FO
209
#            if so.analytic_distribution_id and so.invoice_ids:
210
#                invoice_ids = so.invoice_ids
211
#                if isinstance(invoice_ids, (int, long)):
212
#                    invoice_ids = [invoice_ids]
213
#                distrib_id = so.analytic_distribution_id and so.analytic_distribution_id.id or False
214
#                if distrib_id:
215
#                    new_distrib_id = ana_obj.copy(cr, uid, distrib_id, {})
216
#                    if not new_distrib_id:
217
#                        raise osv.except_osv(_('Error'), _('An error occured for analytic distribution copy for invoice.'))
218
#                    # create default funding pool lines
219
#                    ana_obj.create_funding_pool_lines(cr, uid, [new_distrib_id])
220
#                    self.pool.get('account.invoice').write(cr, uid, [invoice_ids], {'analytic_distribution_id': new_distrib_id,})
221
#            # Copy analytic distribution from sale order line to invoice lines
222
#            for sol in so.order_line:
223
#                if sol.analytic_distribution_id and sol.invoice_lines:
224
#                    sol_distrib_id = sol.analytic_distribution_id and sol.analytic_distribution_id.id or False
225
#                    if sol_distrib_id:
226
#                        for invl in sol.invoice_lines:
227
#                            new_sol_distrib_id = ana_obj.copy(cr, uid, sol_distrib_id, {})
228
#                            if not new_sol_distrib_id:
229
#                                raise osv.except_osv(_('Error'), _('An error occured for analytic distribution copy for invoice line.'))
230
#                            # create default funding pool lines
231
#                            ana_obj.create_funding_pool_lines(cr, uid, [new_sol_distrib_id])
232
#                            self.pool.get('account.invoice.line').write(cr, uid, [invl.id], {'analytic_distribution_id': new_sol_distrib_id,})
233
#        return res
613.3.28 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution fetch from SO to generated invoice
234
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
235
sale_order()
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
236
237
class sale_order_line(osv.osv):
238
    _name = 'sale.order.line'
239
    _inherit = 'sale.order.line'
240
727 by jf
UF-818 [DEV] Inter-section records
241
    def _have_analytic_distribution_from_header(self, cr, uid, ids, name, arg, context=None):
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
242
        if isinstance(ids, (int, long)):
243
            ids = [ids]
244
        res = {}
245
        for line in self.read(cr, uid, ids, ['analytic_distribution_id']):
246
            if line['analytic_distribution_id']:
247
                res[line['id']] = False
248
            else:
249
                res[line['id']] = True
250
        return res
251
1037.3.1 by Olivier DOSSMANN
UF-1238 [DEL] analytic_distribution_available method because Distribution is now mandatory on FO
252
    # METHOD _get_analytic_distribution_available removed (become useless since analytic distribution is mandatory on ALL FO)
613.3.19 by Olivier DOSSMANN
UF-818 [ADD] Hide analytic distribution on sale order that have a partner different from inter-section
253
827.8.103 by Olivier DOSSMANN
UF-1188 [ADD] Check analytic distribution state on FO validation
254
    def _get_distribution_state(self, cr, uid, ids, name, args, context=None):
255
        """
256
        Get state of distribution:
257
         - if compatible with the sale order line, then "valid"
258
         - if no distribution, take a tour of sale order distribution, if compatible, then "valid"
259
         - if no distribution on sale order line and sale order, then "none"
260
         - all other case are "invalid"
261
        """
262
        # Some verifications
263
        if not context:
264
            context = {}
265
        if isinstance(ids, (int, long)):
266
            ids = [ids]
267
        # Prepare some values
268
        res = {}
269
        # Browse all given lines
270
        for line in self.browse(cr, uid, ids, context=context):
271
            if line.order_id and line.order_id.from_yml_test:
272
                res[line.id] = 'valid'
1122.13.1 by pierre-marie
UF-1384 bug on valid anlalytic distrib when there is no AD
273
            elif line.order_id and ( not line.order_id.analytic_distribution_id or not line.order_id.analytic_distribution_id.cost_center_lines ) and ( not line.analytic_distribution_id or not line.analytic_distribution_id.cost_center_lines ) :
827.8.103 by Olivier DOSSMANN
UF-1188 [ADD] Check analytic distribution state on FO validation
274
                res[line.id] = 'none'
275
            else:
276
                so_distrib_id = line.order_id and line.order_id.analytic_distribution_id and line.order_id.analytic_distribution_id.id or False
277
                distrib_id = line.analytic_distribution_id and line.analytic_distribution_id.id or False
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
278
                account_id = line.account_4_distribution and line.account_4_distribution.id or False
279
                if not account_id:
280
                    res[line.id] = 'invalid'
281
                    continue
282
                res[line.id] = self.pool.get('analytic.distribution')._get_distribution_state(cr, uid, distrib_id, so_distrib_id, account_id)
827.8.103 by Olivier DOSSMANN
UF-1188 [ADD] Check analytic distribution state on FO validation
283
        return res
284
1016.1.6 by jf
[IMP] Distribution state on PO/FO
285
    def _get_distribution_state_recap(self, cr, uid, ids, name, arg, context=None):
286
        if isinstance(ids, (int, long)):
287
            ids = [ids]
288
        res = {}
1453.7.12 by jf
UF-1781: Trans analytic distribution
289
        get_sel = self.pool.get('ir.model.fields').get_selection
1016.1.6 by jf
[IMP] Distribution state on PO/FO
290
        for sol in self.read(cr, uid, ids, ['analytic_distribution_state', 'have_analytic_distribution_from_header']):
1453.7.12 by jf
UF-1781: Trans analytic distribution
291
            d_state = get_sel(cr, uid, self._name, 'analytic_distribution_state', sol['analytic_distribution_state'], context)
292
            res[sol['id']] = "%s%s"%(d_state, sol['have_analytic_distribution_from_header'] and _(" (from header)") or "")
1016.1.6 by jf
[IMP] Distribution state on PO/FO
293
        return res
294
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
295
    def _get_distribution_account(self, cr, uid, ids, name, arg, context=None):
296
        """
297
        Get account for given lines regarding:
298
        - product expense account if product_id
299
        - product category expense account if product_id but no product expense account
300
        - product category expense account if no product_id (come from family's product category link)
301
        """
302
        # Some verifications
303
        if isinstance(ids, (int, long)):
304
            ids = [ids]
305
        # Prepare some values
306
        res = {}
307
        for line in self.browse(cr, uid, ids):
308
            # Prepare some values
309
            res[line.id] = False
310
            a = False
311
            # Fetch account
312
            if line.product_id:
313
                a = line.product_id.product_tmpl_id.property_account_income.id or False
314
                if not a:
315
                    a = line.product_id.categ_id.property_account_income_categ.id or False
316
            else:
317
                a = line.nomen_manda_2 and line.nomen_manda_2.category_id and line.nomen_manda_2.category_id.property_account_income_categ and line.nomen_manda_2.category_id.property_account_income_categ.id or False
318
            res[line.id] = a
319
        return res
320
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
321
    _columns = {
322
        'analytic_distribution_id': fields.many2one('analytic.distribution', 'Analytic Distribution'),
323
        'have_analytic_distribution_from_header': fields.function(_have_analytic_distribution_from_header, method=True, type='boolean', 
324
            string='Header Distrib.?'),
827.8.103 by Olivier DOSSMANN
UF-1188 [ADD] Check analytic distribution state on FO validation
325
        'analytic_distribution_state': fields.function(_get_distribution_state, method=True, type='selection', 
326
            selection=[('none', 'None'), ('valid', 'Valid'), ('invalid', 'Invalid')], 
327
            string="Distribution state", help="Informs from distribution state among 'none', 'valid', 'invalid."),
1016.1.6 by jf
[IMP] Distribution state on PO/FO
328
        'analytic_distribution_state_recap': fields.function(_get_distribution_state_recap, method=True, type='char', size=30, string="Distribution"),
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
329
        'account_4_distribution': fields.function(_get_distribution_account, method=True, type='many2one', relation="account.account", string="Account for analytical distribution", readonly=True),
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
330
    }
331
332
    _defaults = {
333
        'have_analytic_distribution_from_header': lambda *a: True,
334
    }
335
727 by jf
UF-818 [DEV] Inter-section records
336
    def button_analytic_distribution(self, cr, uid, ids, context=None):
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
337
        """
338
        Launch analytic distribution wizard on a sale order line
339
        """
340
        # Some verifications
341
        if not context:
342
            context = {}
343
        if isinstance(ids, (int, long)):
344
            ids = [ids]
345
        # Prepare some values
346
        sol = self.browse(cr, uid, ids[0], context=context)
347
        amount = sol.price_subtotal or 0.0
348
        # Search elements for currency
349
        company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
350
        currency = sol.order_id.currency_id and sol.order_id.currency_id.id or company_currency
351
        # Get analytic_distribution_id
352
        distrib_id = sol.analytic_distribution_id and sol.analytic_distribution_id.id
827.8.102 by Olivier DOSSMANN
UF-1188 [ADD] Check analytic distribution presence on sale order line if partner is section
353
        # Search account_id
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
354
        account_id = sol.account_4_distribution and sol.account_4_distribution.id or False
355
        if not account_id:
356
            raise osv.except_osv(_('Error !'), _('There is no income account defined for this product: "%s" (id:%d)') % \
357
                (sol.product_id.name, sol.product_id.id,))
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
358
        # Prepare values for wizard
359
        vals = {
360
            'total_amount': amount,
361
            'sale_order_line_id': sol.id,
362
            'currency_id': currency or False,
363
            'state': 'cc',
1038.17.5 by Olivier DOSSMANN
UF-1345 [ADD] Change account_id selection for FO lines
364
            'account_id': account_id or False,
1380.3.11 by Olivier DOSSMANN
UF-1678 [ADD] Display analytic account regarding date
365
            'posting_date': strftime('%Y-%m-%d'),
366
            'document_date': strftime('%Y-%m-%d'),
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
367
        }
368
        if distrib_id:
369
            vals.update({'distribution_id': distrib_id,})
370
        # Create the wizard
371
        wiz_obj = self.pool.get('analytic.distribution.wizard')
372
        wiz_id = wiz_obj.create(cr, uid, vals, context=context)
373
        # Update some context values
374
        context.update({
375
            'active_id': ids[0],
376
            'active_ids': ids,
377
        })
378
        # Open it!
379
        return {
1453.7.12 by jf
UF-1781: Trans analytic distribution
380
                'name': _('Analytic distribution'),
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
381
                'type': 'ir.actions.act_window',
382
                'res_model': 'analytic.distribution.wizard',
383
                'view_type': 'form',
384
                'view_mode': 'form',
385
                'target': 'new',
386
                'res_id': [wiz_id],
387
                'context': context,
388
        }
389
727 by jf
UF-818 [DEV] Inter-section records
390
    def copy_data(self, cr, uid, id, default=None, context=None):
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
391
        """
392
        Copy global distribution and give it to new sale order line
393
        """
394
        # Some verifications
395
        if not context:
396
            context = {}
727 by jf
UF-818 [DEV] Inter-section records
397
        if default is None:
398
            default = {}
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
399
        # Copy analytic distribution
860 by jf
UF-998 [FIX] FO/PO duplication: distrib and dates removed
400
        if 'analytic_distribution_id' not in default and not context.get('keepDateAndDistrib'):
833.1.1 by jf
UF-998: reset ana. disti. on po/fo/po lines/so lines duplication
401
            default['analytic_distribution_id'] = False
833.1.3 by jf
Context keepDate on po/so lines: duplicates distrib
402
        new_data = super(sale_order_line, self).copy_data(cr, uid, id, default, context)
403
        if new_data and new_data.get('analytic_distribution_id'):
404
            new_data['analytic_distribution_id'] = self.pool.get('analytic.distribution').copy(cr, uid, new_data['analytic_distribution_id'], {}, context=context)
405
        return new_data
613.3.15 by Olivier DOSSMANN
UF-818 [ADD] Analytic distribution on Sale Order (SO)
406
407
sale_order_line()
613.3.14 by Olivier DOSSMANN
UF-818 [ADD] Add analytic distribution on sale order header.
408
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: