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

« back to all changes in this revision

Viewing changes to analytic_distribution/analytic_distribution.py

  • Committer: Quentin THEURET
  • Date: 2011-11-30 13:31:37 UTC
  • mto: This revision was merged to the branch mainline in revision 515.
  • Revision ID: qt@tempo-consulting.fr-20111130133137-mdf2fp6hkqmwbppn
UF-647 [ADD] Added a line in Purchase Order to have information about international transport costs

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
 
import netsvc
24
 
from tools.translate import _
25
 
 
26
 
class analytic_distribution(osv.osv):
27
 
    _name = 'analytic.distribution'
28
 
    _inherit = 'analytic.distribution'
29
 
 
30
 
    def _get_distribution_state(self, cr, uid, distrib_id, parent_id, account_id, context=None):
31
 
        """
32
 
        Return distribution state
33
 
        """
34
 
        if context is None:
35
 
            context = {}
36
 
        # Have an analytic distribution on another account than analytic-a-holic account make no sense. So their analytic distribution is valid
37
 
        logger = netsvc.Logger()
38
 
        if account_id:
39
 
            account =  self.pool.get('account.account').read(cr, uid, account_id, ['is_analytic_addicted'])
40
 
            if account and not account.get('is_analytic_addicted', False):
41
 
                return 'valid'
42
 
        if not distrib_id:
43
 
            if parent_id:
44
 
                return self._get_distribution_state(cr, uid, parent_id, False, account_id, context)
45
 
            logger.notifyChannel("analytic distribution", netsvc.LOG_WARNING, _("%s: NONE!") % (distrib_id or ''))
46
 
            return 'none'
47
 
        distrib = self.browse(cr, uid, distrib_id)
48
 
        # Search MSF Private Fund element, because it's valid with all accounts
49
 
        try:
50
 
            fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
51
 
            'analytic_account_msf_private_funds')[1]
52
 
        except ValueError:
53
 
            fp_id = 0
54
 
        account = self.pool.get('account.account').read(cr, uid, account_id, ['destination_ids'])
55
 
        # Check Cost Center lines with destination/account link
56
 
        for cc_line in distrib.cost_center_lines:
57
 
            if cc_line.destination_id.id not in account.get('destination_ids', []):
58
 
                logger.notifyChannel("analytic distribution", netsvc.LOG_WARNING, _("%s: Error, destination not compatible with G/L account in CC lines") % (distrib_id or ''))
59
 
                return 'invalid'
60
 
        # Check Funding pool lines regarding:
61
 
        # - destination / account
62
 
        # - If analytic account is MSF Private funds
63
 
        # - Cost center and funding pool compatibility
64
 
        for fp_line in distrib.funding_pool_lines:
65
 
            if fp_line.destination_id.id not in account.get('destination_ids', []):
66
 
                logger.notifyChannel("analytic distribution", netsvc.LOG_WARNING, _("%s: Error, destination not compatible with G/L account for FP lines") % (distrib_id or ''))
67
 
                return 'invalid'
68
 
            # If fp_line is MSF Private Fund, all is ok
69
 
            if fp_line.analytic_id.id == fp_id:
70
 
                continue
71
 
            if (account_id, fp_line.destination_id.id) not in [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in fp_line.analytic_id.tuple_destination_account_ids]:
72
 
                logger.notifyChannel("analytic distribution", netsvc.LOG_WARNING, _("%s: Error, account/destination tuple not compatible with given FP analytic account") % (distrib_id or ''))
73
 
                return 'invalid'
74
 
            if fp_line.cost_center_id.id not in [x.id for x in fp_line.analytic_id.cost_center_ids]:
75
 
                logger.notifyChannel("analytic distribution", netsvc.LOG_WARNING, _("%s: Error, CC is not compatible with given FP analytic account") % (distrib_id or ''))
76
 
                return 'invalid'
77
 
        return 'valid'
78
 
 
79
 
    def analytic_state_from_info(self, cr, uid, account_id, destination_id, cost_center_id, analytic_id, context=None):
80
 
        """
81
 
        Give analytic state from the given information.
82
 
        Return result and some info if needed.
83
 
        """
84
 
        # Checks
85
 
        if context is None:
86
 
            context = {}
87
 
        # Prepare some values
88
 
        res = 'valid'
89
 
        info = ''
90
 
        ana_obj = self.pool.get('account.analytic.account')
91
 
        account = self.pool.get('account.account').browse(cr, uid, account_id, context=context)
92
 
        fp = ana_obj.browse(cr, uid, analytic_id, context=context)
93
 
        try:
94
 
            fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
95
 
        except ValueError:
96
 
            fp_id = 0
97
 
        is_private_fund = False
98
 
        if analytic_id == fp_id:
99
 
            is_private_fund = True
100
 
        # DISTRIBUTION VERIFICATION
101
 
        # Check account user_type
102
 
        if account.user_type_code != 'expense':
103
 
            return res, _('Not an expense account')
104
 
        # Check that destination is compatible with account
105
 
        if destination_id not in [x.id for x in account.destination_ids]:
106
 
            return 'invalid', _('Destination not compatible with account')
107
 
        if not is_private_fund:
108
 
            # Check that cost center is compatible with FP (except if FP is MSF Private Fund)
109
 
            if cost_center_id not in [x.id for x in fp.cost_center_ids]:
110
 
                return 'invalid', _('Cost Center not compatible with FP')
111
 
            # Check that tuple account/destination is compatible with FP (except if FP is MSF Private Fund):
112
 
            if (account_id, destination_id) not in [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in fp.tuple_destination_account_ids]:
113
 
                return 'invalid', _('account/destination tuple not compatible with given FP analytic account')
114
 
        return res, info
115
 
 
116
 
analytic_distribution()
117
 
 
118
 
class distribution_line(osv.osv):
119
 
    _name = "distribution.line"
120
 
    _inherit = "distribution.line"
121
 
 
122
 
    def create_analytic_lines(self, cr, uid, ids, move_line_id, date, document_date, source_date=False, name=False, context=None):
123
 
        '''
124
 
        Creates an analytic lines from a distribution line and an account.move.line
125
 
        '''
126
 
        if isinstance(ids, (int, long)):
127
 
            ids = [ids]
128
 
 
129
 
        ret = {}
130
 
        move_line = self.pool.get('account.move.line').browse(cr, uid, move_line_id)
131
 
        company_currency_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id
132
 
 
133
 
        for line in self.browse(cr, uid, ids):
134
 
            amount_cur = (move_line.credit_currency - move_line.debit_currency) * line.percentage / 100
135
 
            ctx = {'date': source_date or date}
136
 
            amount = self.pool.get('res.currency').compute(cr, uid, move_line.currency_id.id, company_currency_id, amount_cur, round=False, context=ctx)
137
 
            vals = {
138
 
                'account_id': line.analytic_id.id,
139
 
                'amount_currency': amount_cur,
140
 
                'amount': amount,
141
 
                'currency_id': move_line.currency_id.id,
142
 
                'general_account_id': move_line.account_id.id,
143
 
                'date': date,
144
 
                'source_date': source_date,
145
 
                'document_date': document_date,
146
 
                'journal_id': move_line.journal_id and move_line.journal_id.analytic_journal_id and move_line.journal_id.analytic_journal_id.id or False,
147
 
                'move_id': move_line.id,
148
 
                'name': name or move_line.name,
149
 
                'distrib_id': line.distribution_id.id,
150
 
                'distrib_line_id': '%s,%s'%(self._name, line.id),
151
 
            }
152
 
            if self._name == 'funding.pool.distribution.line':
153
 
                vals.update({
154
 
                    'destination_id': line.destination_id and line.destination_id.id or False,
155
 
                    'cost_center_id': line.cost_center_id and line.cost_center_id.id or False,
156
 
                })
157
 
            ret[line.id] = self.pool.get('account.analytic.line').create(cr, uid, vals)
158
 
 
159
 
        return ret
160
 
 
161
 
distribution_line()
162
 
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: