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

« back to all changes in this revision

Viewing changes to analytic_distribution/invoice.py

UF-558 [ADD] Add account_id on analytic distribution wizard to add a constraint on Funding Pool

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
        res = super(account_invoice, self).line_get_convert(cr, uid, x, part, date, context=context)
35
35
        res['analytic_distribution_id'] = x.get('analytic_distribution_id', False)
36
36
        return res
37
 
    
 
37
 
38
38
    def button_analytic_distribution(self, cr, uid, ids, context={}):
39
 
        # we get the analytical distribution object linked to this line
40
 
        distrib_id = False
41
 
        negative_inv = False
42
 
        invoice_obj = self.browse(cr, uid, ids[0], context=context)
 
39
        """
 
40
        Launch analytic distribution wizard on an invoice
 
41
        """
 
42
        # Some verifications
 
43
        if not context:
 
44
            context = {}
 
45
        if isinstance(ids, (int, long)):
 
46
            ids = [ids]
 
47
        # Prepare some values
 
48
        invoice = self.browse(cr, uid, ids[0], context=context)
 
49
        amount = 0.0
 
50
        # Search elements for currency
43
51
        company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
44
 
        currency = invoice_obj.currency_id and invoice_obj.currency_id.id or company_currency
45
 
        amount_tot = 0.0
46
 
        if invoice_obj.type in ['out_invoice', 'in_refund']:
47
 
            negative_inv = True
48
 
        if invoice_obj.analytic_distribution_id:
49
 
            distrib_id = invoice_obj.analytic_distribution_id.id
50
 
        else:
51
 
            distrib_id = self.pool.get('analytic.distribution').create(cr, uid, {}, context=context)
52
 
            newvals = {'analytic_distribution_id': distrib_id}
53
 
            super(account_invoice, self).write(cr, uid, ids, newvals, context=context)
54
 
        child_distributions = []
55
 
        for invoice_line in invoice_obj.invoice_line:
56
 
            il_amount = invoice_line.price_subtotal
57
 
            if negative_inv:
58
 
                il_amount = -1 * il_amount
59
 
            amount_tot += il_amount
60
 
            if invoice_line.analytic_distribution_id:
61
 
                if invoice_line.analytic_distribution_id.global_distribution \
62
 
                or ('reset_all' in context and context['reset_all']):
63
 
                    child_distributions.append((invoice_line.analytic_distribution_id.id, il_amount))
64
 
            else:
65
 
                child_distrib_id = self.pool.get('analytic.distribution').create(cr, uid, {'global_distribution': True}, context=context)
66
 
                child_vals = {'analytic_distribution_id': child_distrib_id}
67
 
                self.pool.get('account.invoice.line').write(cr, uid, [invoice_line.id], child_vals, context=context)
68
 
                child_distributions.append((child_distrib_id, il_amount))
69
 
        wiz_obj = self.pool.get('wizard.costcenter.distribution')
70
 
        wiz_id = wiz_obj.create(cr, uid, {'total_amount': amount_tot, 'distribution_id': distrib_id, 'currency_id': currency}, context=context)
71
 
        # we open a wizard
 
52
        currency = invoice.currency_id and invoice.currency_id.id or company_currency
 
53
        for line in invoice.invoice_line:
 
54
            amount += line.price_subtotal
 
55
        # Get analytic_distribution_id
 
56
        distrib_id = invoice.analytic_distribution_id and invoice.analytic_distribution_id.id
 
57
        # Prepare values for wizard
 
58
        vals = {
 
59
            'total_amount': amount,
 
60
            'invoice_id': invoice.id,
 
61
            'currency_id': currency or False,
 
62
            'state': 'dispatch',
 
63
        }
 
64
        if distrib_id:
 
65
            vals.update({'distribution_id': distrib_id,})
 
66
        # Create the wizard
 
67
        wiz_obj = self.pool.get('analytic.distribution.wizard')
 
68
        wiz_id = wiz_obj.create(cr, uid, vals, context=context)
 
69
        # Update some context values
 
70
        context.update({
 
71
            'active_id': ids[0],
 
72
            'active_ids': ids,
 
73
        })
 
74
        # Open it!
72
75
        return {
73
76
                'type': 'ir.actions.act_window',
74
 
                'res_model': 'wizard.costcenter.distribution',
 
77
                'res_model': 'analytic.distribution.wizard',
75
78
                'view_type': 'form',
76
79
                'view_mode': 'form',
77
80
                'target': 'new',
78
81
                'res_id': [wiz_id],
79
 
                'context': {
80
 
                    'active_id': ids[0],
81
 
                    'active_ids': ids,
82
 
                    'wizard_ids': {'cost_center': wiz_id},
83
 
                    'child_distributions': child_distributions
84
 
               }
 
82
                'context': context,
85
83
        }
86
84
 
87
85
account_invoice()
90
88
    _name = 'account.invoice.line'
91
89
    _inherit = 'account.invoice.line'
92
90
 
 
91
    def _get_distribution_state(self, cr, uid, ids, name, args, context={}):
 
92
        """
 
93
        Get state of distribution:
 
94
         - if compatible with the invoice line, then "valid"
 
95
         - if no distribution, take a tour of invoice distribution, if compatible, then "valid"
 
96
         - if no distribution on invoice line and invoice, then "none"
 
97
         - all other case are "invalid"
 
98
        """
 
99
        # Some verifications
 
100
        if not context:
 
101
            context = {}
 
102
        if isinstance(ids, (int, long)):
 
103
            ids = [ids]
 
104
        # Prepare some values
 
105
        res = {}
 
106
        # Browse all given lines
 
107
        for line in self.browse(cr, uid, ids, context=context):
 
108
            # Default value is invalid
 
109
            res[line.id] = 'invalid'
 
110
            # Verify that the distribution is compatible with line account
 
111
            if line.analytic_distribution_id:
 
112
                total = 0.0
 
113
                for fp_line in line.analytic_distribution_id.funding_pool_lines:
 
114
                    # If account don't be on ONLY ONE funding_pool, then continue
 
115
                    if line.account_id.id not in [x.id for x in fp_line.analytic_id.account_ids]:
 
116
                        continue
 
117
                    else:
 
118
                        total += 1
 
119
                if total and total == len(line.analytic_distribution_id.funding_pool_lines):
 
120
                    res[line.id] = 'valid'
 
121
            # If no analytic_distribution on invoice line, check with invoice distribution
 
122
            elif line.invoice_id.analytic_distribution_id:
 
123
                for fp_line in line.invoice_id.analytic_distribution_id.funding_pool_lines:
 
124
                    total = 0.0
 
125
                    # If account don't be on ONLY ONE funding_pool, then continue
 
126
                    if line.account_id.id not in [x.id for x in fp_line.analytic_id.account_ids]:
 
127
                        continue
 
128
                    else:
 
129
                        total += 1
 
130
                if total and total == len(line.analytic_distribution_id.funding_pool_lines):
 
131
                    res[line.id] = 'valid'
 
132
            # If no analytic distribution on invoice line and on invoice, then give 'none' state
 
133
            else:
 
134
                # no analytic distribution on invoice line or invoice => 'none'
 
135
                res[line.id] = 'none'
 
136
        return res
 
137
 
93
138
    _columns = {
94
139
        'analytic_distribution_id': fields.many2one('analytic.distribution', 'Analytic Distribution'),
 
140
        'analytic_distribution_state': fields.function(_get_distribution_state, method=True, type='selection', 
 
141
            selection=[('none', 'None'), ('valid', 'Valid'), ('invalid', 'Invalid')], 
 
142
            string="Distribution state", help="Informs from distribution state among 'none', 'valid', 'invalid."),
95
143
    }
96
144
 
97
145
    def button_analytic_distribution(self, cr, uid, ids, context={}):
98
 
        # we get the analytical distribution object linked to this line
 
146
        """
 
147
        Launch analytic distribution wizard on an invoice line
 
148
        """
 
149
        # Some verifications
 
150
        if not context:
 
151
            context = {}
 
152
        if isinstance(ids, (int, long)):
 
153
            ids = [ids]
 
154
        if not ids:
 
155
            raise osv.except_osv(_('Error'), _('No invoice line given. Please save your invoice line before.'))
 
156
        # Prepare some values
 
157
        invoice_line = self.browse(cr, uid, ids[0], context=context)
99
158
        distrib_id = False
100
159
        negative_inv = False
101
 
        invoice_line_obj = self.browse(cr, uid, ids[0], context=context)
102
 
        amount = invoice_line_obj.price_subtotal or 0.0
 
160
        amount = invoice_line.price_subtotal or 0.0
103
161
        # Search elements for currency
104
162
        company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
105
 
        currency = invoice_line_obj.invoice_id.currency_id and invoice_line_obj.invoice_id.currency_id.id or company_currency
106
 
        if invoice_line_obj.invoice_id.type in ['out_invoice', 'in_refund']:
 
163
        currency = invoice_line.invoice_id.currency_id and invoice_line.invoice_id.currency_id.id or company_currency
 
164
        # Change amount sign if necessary
 
165
        if invoice_line.invoice_id.type in ['out_invoice', 'in_refund']:
107
166
            negative_inv = True
108
167
        if negative_inv:
109
168
            amount = -1 * amount
110
 
        if invoice_line_obj.analytic_distribution_id:
111
 
            distrib_id = invoice_line_obj.analytic_distribution_id.id
112
 
        else:
113
 
            raise osv.except_osv(_('No Analytic Distribution !'),_("You have to define an analytic distribution for the whole invoice first!"))
114
 
        wiz_obj = self.pool.get('wizard.costcenter.distribution')
115
 
        wiz_id = wiz_obj.create(cr, uid, {'total_amount': amount, 'distribution_id': distrib_id, 'currency_id': currency, 'invoice_line': ids[0]}, context=context)
116
 
        # we open a wizard
 
169
        # Get analytic distribution id from this line
 
170
        distrib_id = invoice_line and invoice_line.analytic_distribution_id and invoice_line.analytic_distribution_id.id or False
 
171
        # Prepare values for wizard
 
172
        vals = {
 
173
            'total_amount': amount,
 
174
            'invoice_line_id': invoice_line.id,
 
175
            'currency_id': currency or False,
 
176
            'state': 'dispatch',
 
177
            'account_id': invoice_line.account_id and invoice_line.account_id.id or False,
 
178
        }
 
179
        if distrib_id:
 
180
            vals.update({'distribution_id': distrib_id,})
 
181
        # Create the wizard
 
182
        wiz_obj = self.pool.get('analytic.distribution.wizard')
 
183
        wiz_id = wiz_obj.create(cr, uid, vals, context=context)
 
184
        # Update some context values
117
185
        context.update({
118
 
          'active_id': ids[0],
119
 
          'active_ids': ids,
120
 
          'wizard_ids': {'cost_center': wiz_id}
 
186
            'active_id': ids[0],
 
187
            'active_ids': ids,
121
188
        })
 
189
        # Open it!
122
190
        return {
123
191
                'type': 'ir.actions.act_window',
124
 
                'res_model': 'wizard.costcenter.distribution',
 
192
                'res_model': 'analytic.distribution.wizard',
125
193
                'view_type': 'form',
126
194
                'view_mode': 'form',
127
195
                'target': 'new',
129
197
                'context': context,
130
198
        }
131
199
 
132
 
    def create(self, cr, uid, vals, context=None):
133
 
        res_id = False
134
 
        analytic_obj = self.pool.get('analytic.distribution')
135
 
        if 'invoice_id' in vals and vals['invoice_id']:
136
 
            #new line, we add the global distribution
137
 
            if self._name == 'wizard.account.invoice.line':
138
 
                obj_name = 'wizard.account.invoice'
139
 
            else:
140
 
                obj_name = 'account.invoice'
141
 
            invoice_obj = self.pool.get(obj_name).browse(cr, uid, vals['invoice_id'], context=context)
142
 
            if invoice_obj.analytic_distribution_id and not vals.get('analytic_distribution_id'):
143
 
                child_distrib_id = analytic_obj.create(cr, uid, {'global_distribution': True}, context=context)
144
 
                vals['analytic_distribution_id'] = child_distrib_id
145
 
                res_id =  super(account_invoice_line, self).create(cr, uid, vals, context=context)
146
 
                amount = self._amount_line(cr, uid, [res_id], None, None, {})[res_id] or 0.0
147
 
                if invoice_obj.type in ['out_invoice', 'in_refund']:
148
 
                    amount = -1 * amount
149
 
                company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
150
 
                currency = invoice_obj.currency_id and invoice_obj.currency_id.id or company_currency
151
 
                analytic_obj.copy_from_global_distribution(cr,
152
 
                                                           uid,
153
 
                                                           invoice_obj.analytic_distribution_id.id,
154
 
                                                           child_distrib_id,
155
 
                                                           amount,
156
 
                                                           currency,
157
 
                                                           context=context)
158
 
        if res_id:
159
 
            return res_id
160
 
        else:
161
 
            return super(account_invoice_line, self).create(cr, uid, vals, context=context)
 
200
#    def create(self, cr, uid, vals, context=None):
 
201
#        res_id = False
 
202
#        analytic_obj = self.pool.get('analytic.distribution')
 
203
#        if 'invoice_id' in vals and vals['invoice_id']:
 
204
#            #new line, we add the global distribution
 
205
#            if self._name == 'wizard.account.invoice.line':
 
206
#                obj_name = 'wizard.account.invoice'
 
207
#            else:
 
208
#                obj_name = 'account.invoice'
 
209
#            invoice_obj = self.pool.get(obj_name).browse(cr, uid, vals['invoice_id'], context=context)
 
210
#            if invoice_obj.analytic_distribution_id:
 
211
#                child_distrib_id = analytic_obj.create(cr, uid, {'global_distribution': True}, context=context)
 
212
#                vals['analytic_distribution_id'] = child_distrib_id
 
213
#                res_id =  super(account_invoice_line, self).create(cr, uid, vals, context=context)
 
214
#                amount = self._amount_line(cr, uid, [res_id], None, None, {})[res_id] or 0.0
 
215
#                if invoice_obj.type in ['out_invoice', 'in_refund']:
 
216
#                    amount = -1 * amount
 
217
#                company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
 
218
#                currency = invoice_obj.currency_id and invoice_obj.currency_id.id or company_currency
 
219
#                analytic_obj.copy_from_global_distribution(cr,
 
220
#                                                           uid,
 
221
#                                                           invoice_obj.analytic_distribution_id.id,
 
222
#                                                           child_distrib_id,
 
223
#                                                           amount,
 
224
#                                                           currency,
 
225
#                                                           context=context)
 
226
#        if res_id:
 
227
#            return res_id
 
228
#        else:
 
229
#            return super(account_invoice_line, self).create(cr, uid, vals, context=context)
162
230
        
163
 
    def write(self, cr, uid, ids, vals, context=None):
164
 
        # Update values from invoice line
165
 
        res = super(account_invoice_line, self).write(cr, uid, ids, vals, context=context)
166
 
        # Browse invoice lines
167
 
        for line in self.browse(cr, uid, ids, context=context):
168
 
            # Do some update if this line have an analytic distribution
169
 
            if line.analytic_distribution_id:
170
 
                if 'price_unit' in vals or 'quantity' in vals or 'discount' in vals or context.get('reset_all', False):
171
 
                    amount = line.price_subtotal or 0.0
172
 
                    if line.invoice_id.type in ['out_invoice', 'in_refund']:
173
 
                        amount = -1 * amount
174
 
                    company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
175
 
                    currency = line.invoice_id.currency_id and line.invoice_id.currency_id.id or company_currency
176
 
                    distrib_obj = self.pool.get('analytic.distribution')
177
 
                    if line.analytic_distribution_id.global_distribution:
178
 
                        source = line.invoice_id.analytic_distribution_id.id
179
 
                        dest = line.analytic_distribution_id.id
180
 
                        distrib_obj.copy_from_global_distribution(cr, uid, source, dest, amount, currency, context=context)
181
 
                    else:
182
 
                        distrib_obj.update_distribution_line_amount(cr, uid, [line.analytic_distribution_id.id], amount, context=context)
183
 
        return res
 
231
#    def write(self, cr, uid, ids, vals, context=None):
 
232
#        # Update values from invoice line
 
233
#        res = super(account_invoice_line, self).write(cr, uid, ids, vals, context=context)
 
234
#        # Browse invoice lines
 
235
#        for line in self.browse(cr, uid, ids, context=context):
 
236
#            # Do some update if this line have an analytic distribution
 
237
#            if line.analytic_distribution_id:
 
238
#                if 'price_unit' in vals or 'quantity' in vals or 'discount' in vals or context.get('reset_all', False):
 
239
#                    amount = line.price_subtotal or 0.0
 
240
#                    if line.invoice_id.type in ['out_invoice', 'in_refund']:
 
241
#                        amount = -1 * amount
 
242
#                    company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
 
243
#                    currency = line.invoice_id.currency_id and line.invoice_id.currency_id.id or company_currency
 
244
#                    distrib_obj = self.pool.get('analytic.distribution')
 
245
#                    if line.analytic_distribution_id.global_distribution:
 
246
#                        source = line.invoice_id.analytic_distribution_id.id
 
247
#                        dest = line.analytic_distribution_id.id
 
248
#                        distrib_obj.copy_from_global_distribution(cr, uid, source, dest, amount, currency, context=context)
 
249
#                    else:
 
250
#                        distrib_obj.update_distribution_line_amount(cr, uid, [line.analytic_distribution_id.id], amount, context=context)
 
251
#        return res
184
252
 
185
253
    def move_line_get_item(self, cr, uid, line, context=None):
186
254
        res = super(account_invoice_line, self).move_line_get_item(cr, uid, line, context=context)