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

« back to all changes in this revision

Viewing changes to analytic_override/analytic_distribution.py

  • Committer: jf
  • Date: 2012-08-03 14:15:44 UTC
  • mfrom: (1071.2.4 uf-1303)
  • Revision ID: jf@tempo4-20120803141544-xaplb4ot6do2b7iz
UF-1311 [FIX] Column of local expense should not be all in bold
UF-1310 [FIX] A menu is missing in supply configuration
lp:~unifield-team/unifield-wm/uf-1310

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) 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 osv
23
 
from osv import fields
24
 
from time import strftime
25
 
import decimal_precision as dp
26
 
 
27
 
class analytic_distribution1(osv.osv):
28
 
    _name = "analytic.distribution"
29
 
 
30
 
    _columns = {
31
 
        'analytic_lines': fields.one2many('account.analytic.line', 'distribution_id', 'Analytic Lines'),
32
 
        'invoice_ids': fields.one2many('account.invoice', 'analytic_distribution_id', string="Invoices"),
33
 
        'invoice_line_ids': fields.one2many('account.invoice.line', 'analytic_distribution_id', string="Invoice Lines"),
34
 
        'register_line_ids': fields.one2many('account.bank.statement.line', 'analytic_distribution_id', string="Register Lines"),
35
 
        'move_line_ids': fields.one2many('account.move.line', 'analytic_distribution_id', string="Move Lines"),
36
 
        'commitment_ids': fields.one2many('account.commitment', 'analytic_distribution_id', string="Commitments voucher"),
37
 
        'commitment_line_ids': fields.one2many('account.commitment.line', 'analytic_distribution_id', string="Commitment voucher lines"),
38
 
    }
39
 
 
40
 
    def copy(self, cr, uid, distrib_id, default=None, context=None):
41
 
        """
42
 
        Copy an analytic distribution without the one2many links
43
 
        """
44
 
        if default is None:
45
 
            default = {}
46
 
        default.update({
47
 
            'analytic_lines': False,
48
 
            'invoice_ids': False,
49
 
            'invoice_line_ids': False,
50
 
            'register_line_ids': False,
51
 
            'move_line_ids': False,
52
 
            'commitment_ids': False,
53
 
            'commitment_line_ids': False,
54
 
        })
55
 
        return super(osv.osv, self).copy(cr, uid, distrib_id, default, context=context)
56
 
 
57
 
    def update_distribution_line_amount(self, cr, uid, ids, amount=False, context=None):
58
 
        """
59
 
        Update amount on distribution lines for given distribution (ids)
60
 
        """
61
 
        # Some verifications
62
 
        if not context:
63
 
            context = {}
64
 
        if isinstance(ids, (int, long)):
65
 
            ids = [ids]
66
 
        if not amount:
67
 
            return False
68
 
        # Process distributions
69
 
        for distrib_id in ids:
70
 
            for dl_name in ['cost.center.distribution.line', 'funding.pool.distribution.line', 'free.1.distribution.line', 'free.2.distribution.line']:
71
 
                dl_obj = self.pool.get(dl_name)
72
 
                dl_ids = dl_obj.search(cr, uid, [('distribution_id', '=', distrib_id)], context=context)
73
 
                for dl in dl_obj.read(cr, uid, dl_ids, ['percentage'], context=context):
74
 
                    dl_vals = {
75
 
                        'amount': round(dl.get('percentage', False) * amount) / 100.0,
76
 
                    }
77
 
                    dl_obj.write(cr, uid, [dl.get('id')], dl_vals, context=context)
78
 
        return True
79
 
 
80
 
    def update_distribution_line_account(self, cr, uid, line_ids, account_id, context=None):
81
 
        """
82
 
        Update account on distribution line
83
 
        """
84
 
        # Some verifications
85
 
        if not context:
86
 
            context = {}
87
 
        # Return False if no line_ids
88
 
        if not account_id or not line_ids: # fix bug on UF-2205 with analytic lines that comes from INTL Engagement journal without any distribution
89
 
            return False
90
 
        if isinstance(line_ids, (int, long)):
91
 
            line_ids = [line_ids]
92
 
        # Prepare some values
93
 
        account = self.pool.get('account.analytic.account').browse(cr, uid, [account_id], context=context)[0]
94
 
        if account.category == 'OC':
95
 
            vals = {'cost_center_id': account_id}
96
 
        else:
97
 
            vals = {'analytic_id': account_id}
98
 
        return self.pool.get('funding.pool.distribution.line').write(cr, uid, line_ids, vals)
99
 
 
100
 
    def create_funding_pool_lines(self, cr, uid, ids, account_id=False, context=None):
101
 
        """
102
 
        Create funding pool lines regarding cost_center_lines from analytic distribution.
103
 
        If funding_pool_lines exists, then nothing appends.
104
 
        By default, add funding_pool_lines with MSF Private Fund element (written in an OpenERP demo file).
105
 
        For destination axis, get those from account_id default configuration (default_destination_id).
106
 
        """
107
 
        # Some verifications
108
 
        if not context:
109
 
            context = {}
110
 
        if isinstance(ids, (int, long)):
111
 
            ids = [ids]
112
 
        # Prepare some values
113
 
        res = {}
114
 
        # Browse distributions
115
 
        for distrib in self.browse(cr, uid, ids, context=context):
116
 
            if distrib.funding_pool_lines:
117
 
                res[distrib.id] = False
118
 
                continue
119
 
            # Browse cost center lines
120
 
            for line in distrib.cost_center_lines:
121
 
                # Search MSF Private Fund
122
 
                try:
123
 
                    pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
124
 
                    'analytic_account_msf_private_funds')[1]
125
 
                except ValueError:
126
 
                    pf_id = 0
127
 
                if pf_id:
128
 
                    vals = {
129
 
                        'analytic_id': pf_id,
130
 
                        'amount': line.amount or 0.0,
131
 
                        'percentage': line.percentage or 0.0,
132
 
                        'currency_id': line.currency_id and line.currency_id.id or False,
133
 
                        'distribution_id': distrib.id or False,
134
 
                        'cost_center_id': line.analytic_id and line.analytic_id.id or False,
135
 
                        'destination_id': line.destination_id and line.destination_id.id or False,
136
 
                    }
137
 
                    if distrib and distrib.partner_type:
138
 
                        vals.update({'partner_type': distrib.partner_type})
139
 
 
140
 
                    # Search default destination if no one given
141
 
                    if account_id and not vals.get('destination_id'):
142
 
                        account = self.pool.get('account.account').browse(cr, uid, account_id)
143
 
                        if account and account.is_analytic_addicted:
144
 
                            vals.update({'destination_id': account.default_destination_id and account.default_destination_id.id or False})
145
 
                    self.pool.get('funding.pool.distribution.line').create(cr, uid, vals, context=context)
146
 
            res[distrib.id] = True
147
 
        return res
148
 
 
149
 
    def create_analytic_lines(self, cr, uid, ids, name, date, amount, journal_id, currency_id, document_date=False, ref=False, source_date=False, general_account_id=False, \
150
 
        move_id=False, invoice_line_id=False, commitment_line_id=False, context=None):
151
 
        """
152
 
        Create analytic lines from given elements:
153
 
         - date
154
 
         - name
155
 
         - amount
156
 
         - journal_id (analytic_journal_id)
157
 
         - currency_id
158
 
         - ref (optional)
159
 
         - source_date (optional)
160
 
         - general_account_id (optional)
161
 
         - move_id (optional)
162
 
         - invoice_line_id (optional)
163
 
         - commitment_line_id (optional)
164
 
        Return all created ids, otherwise return false (or [])
165
 
        """
166
 
        # Some verifications
167
 
        if not context:
168
 
            context = {}
169
 
        if isinstance(ids, (int, long)):
170
 
            ids = [ids]
171
 
        if not name or not date or not amount or not journal_id or not currency_id:
172
 
            return False
173
 
        if not document_date:
174
 
            document_date = date
175
 
        # Prepare some values
176
 
        res = []
177
 
        vals = {
178
 
            'name': name,
179
 
            'date': source_date or date,
180
 
            'document_date': document_date,
181
 
            'ref': ref or '',
182
 
            'journal_id': journal_id,
183
 
            'general_account_id': general_account_id or False,
184
 
            'move_id': move_id or False,
185
 
            'invoice_line_id': invoice_line_id or False,
186
 
            'user_id': uid,
187
 
            'currency_id': currency_id,
188
 
            'source_date': source_date or False,
189
 
            'commitment_line_id': commitment_line_id or False,
190
 
        }
191
 
        company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
192
 
        # Browse distribution(s)
193
 
        for distrib in self.browse(cr, uid, ids, context=context):
194
 
            vals.update({'distribution_id': distrib.id,})
195
 
            # create lines
196
 
            for distrib_lines in [distrib.funding_pool_lines, distrib.free_1_lines, distrib.free_2_lines]:
197
 
                for distrib_line in distrib_lines:
198
 
                    context.update({'date': source_date or date}) # for amount computing
199
 
                    anal_amount = (distrib_line.percentage * amount) / 100
200
 
                    vals.update({
201
 
                        'amount': -1 * self.pool.get('res.currency').compute(cr, uid, currency_id, company_currency,
202
 
                            anal_amount, round=False, context=context),
203
 
                        'amount_currency': -1 * anal_amount,
204
 
                        'account_id': distrib_line.analytic_id.id,
205
 
                        'cost_center_id': False,
206
 
                        'destination_id': False,
207
 
                        'distrib_line_id': '%s,%s'%(distrib_line._name, distrib_line.id),
208
 
                    })
209
 
                    # Update values if we come from a funding pool
210
 
                    if distrib_line._name == 'funding.pool.distribution.line':
211
 
                        vals.update({'cost_center_id': distrib_line.cost_center_id and distrib_line.cost_center_id.id or False,
212
 
                            'destination_id': distrib_line.destination_id and distrib_line.destination_id.id or False,})
213
 
                    # create analytic line
214
 
                    al_id = self.pool.get('account.analytic.line').create(cr, uid, vals, context=context)
215
 
                    res.append(al_id)
216
 
        return res
217
 
 
218
 
analytic_distribution1()
219
 
 
220
 
class distribution_line(osv.osv):
221
 
    _name = "distribution.line"
222
 
 
223
 
    _columns = {
224
 
        'name': fields.char('Name', size=64),
225
 
        "distribution_id": fields.many2one('analytic.distribution', 'Associated Analytic Distribution', ondelete='cascade'),
226
 
        "analytic_id": fields.many2one('account.analytic.account', 'Analytical Account'),
227
 
        "amount": fields.float('Amount', digits_compute=dp.get_precision('Account')),
228
 
        "percentage": fields.float('Percentage', digits=(16,4)),
229
 
        "currency_id": fields.many2one('res.currency', 'Currency', required=True),
230
 
        "date": fields.date(string="Date"),
231
 
        "source_date": fields.date(string="Source Date", help="This date is for source_date for analytic lines"),
232
 
        'partner_type': fields.text(string='Partner Type of FO/PO', required=False, readonly=True),
233
 
    }
234
 
 
235
 
    _defaults ={
236
 
        'name': 'Distribution Line',
237
 
        'date': lambda *a: strftime('%Y-%m-%d'),
238
 
        'source_date': lambda *a: strftime('%Y-%m-%d'),
239
 
    }
240
 
 
241
 
    def _check_percentage(self, cr, uid, ids, context=None):
242
 
        """
243
 
        Do not allow 0.0 percentage value
244
 
        """
245
 
        for l in self.browse(cr, uid, ids):
246
 
            if l.percentage == 0.0:
247
 
                return False
248
 
        return True
249
 
 
250
 
    _constraints = [
251
 
        (_check_percentage, '0 is not allowed as percentage value!', ['percentage']),
252
 
    ]
253
 
 
254
 
distribution_line()
255
 
 
256
 
class cost_center_distribution_line(osv.osv):
257
 
    _name = "cost.center.distribution.line"
258
 
    _inherit = "distribution.line"
259
 
    _columns = {
260
 
        "destination_id": fields.many2one('account.analytic.account', 'Destination', domain="[('type', '!=', 'view'), ('category', '=', 'DEST')]", required=True),
261
 
    }
262
 
 
263
 
cost_center_distribution_line()
264
 
 
265
 
class funding_pool_distribution_line(osv.osv):
266
 
    _name = "funding.pool.distribution.line"
267
 
    _inherit = "distribution.line"
268
 
    _columns = {
269
 
        "cost_center_id": fields.many2one('account.analytic.account', 'Cost Center Account', required=True),
270
 
        "destination_id": fields.many2one('account.analytic.account', 'Destination', domain="[('type', '!=', 'view'), ('category', '=', 'DEST')]", required=True),
271
 
    }
272
 
 
273
 
funding_pool_distribution_line()
274
 
 
275
 
class free_1_distribution_line(osv.osv):
276
 
    _name = "free.1.distribution.line"
277
 
    _inherit = "distribution.line"
278
 
    _columns = {
279
 
        "destination_id": fields.many2one('account.analytic.account', 'Destination', domain="[('type', '!=', 'view'), ('category', '=', 'DEST')]", required=False),
280
 
    }
281
 
 
282
 
free_1_distribution_line()
283
 
 
284
 
class free_2_distribution_line(osv.osv):
285
 
    _name = "free.2.distribution.line"
286
 
    _inherit = "distribution.line"
287
 
    _columns = {
288
 
        "destination_id": fields.many2one('account.analytic.account', 'Destination', domain="[('type', '!=', 'view'), ('category', '=', 'DEST')]", required=False),
289
 
    }
290
 
 
291
 
free_2_distribution_line()
292
 
 
293
 
class analytic_distribution(osv.osv):
294
 
    _name = 'analytic.distribution'
295
 
    _inherit = "analytic.distribution"
296
 
 
297
 
    def _get_lines_count(self, cr, uid, ids, name=False, args=False, context=None):
298
 
        """
299
 
        Get count of each analytic distribution lines type.
300
 
        Example: with an analytic distribution with 2 cost center, 3 funding pool and 1 Free 1:
301
 
        2 CC; 3 FP; 1 F1; 0 F2;
302
 
        (Number of chars: 20 chars + 4 x some lines number)
303
 
        """
304
 
        # Some verifications
305
 
        if not context:
306
 
            context = {}
307
 
        # Prepare some values
308
 
        res = {}
309
 
        if not ids:
310
 
            return res
311
 
        if isinstance(ids, (int, long)):
312
 
            ids = [ids]
313
 
        # Browse given invoices
314
 
        for distrib in self.browse(cr, uid, ids, context=context):
315
 
            txt = ''
316
 
            txt += str(len(distrib.cost_center_lines) or '0') + ' CC; '
317
 
            txt += str(len(distrib.funding_pool_lines) or '0') + ' FP; '
318
 
            txt += str(len(distrib.free_1_lines) or '0') + ' F1; '
319
 
            txt += str(len(distrib.free_2_lines) or '0') + ' F2'
320
 
            if not txt:
321
 
                txt = ''
322
 
            res[distrib.id] = txt
323
 
        return res
324
 
 
325
 
    _columns = {
326
 
        'cost_center_lines': fields.one2many('cost.center.distribution.line', 'distribution_id', 'Cost Center Distribution'),
327
 
        'funding_pool_lines': fields.one2many('funding.pool.distribution.line', 'distribution_id', 'Funding Pool Distribution'),
328
 
        'free_1_lines': fields.one2many('free.1.distribution.line', 'distribution_id', 'Free 1 Distribution'),
329
 
        'free_2_lines': fields.one2many('free.2.distribution.line', 'distribution_id', 'Free 2 Distribution'),
330
 
        'name': fields.function(_get_lines_count, method=True, type='char', size=256, string="Name", readonly=True, store=False),
331
 
    }
332
 
 
333
 
analytic_distribution()
334
 
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
 
b'\\ No newline at end of file'