2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
1 |
# -*- coding: utf-8 -*-
|
2 |
##############################################################################
|
|
3 |
#
|
|
4 |
# OpenERP, Open Source Management Solution
|
|
2.1.7
by jf
UF-133 [FIX] Copyright |
5 |
# Copyright (C) 2011 MSF, TeMPO Consulting.
|
2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
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 |
||
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
22 |
import datetime |
93.3.2
by Matthieu Dietrich
UF-160: [FIX] default activation date is now 3 months ago |
23 |
from dateutil.relativedelta import relativedelta |
2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
24 |
from osv import fields, osv |
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
25 |
from tools.translate import _ |
350.8.3
by Olivier DOSSMANN
UF-359 [IMP] Give a better method to change xml attribute in fields_view_get |
26 |
from lxml import etree |
827.8.64
by Olivier DOSSMANN
UF-1106 [FIX] FP search compatibility with selected destination in analytic distribution wizard |
27 |
from tools.misc import flatten |
1116.1.1
by jf
UF-1291: on destination (analytic.account), un-lazy m2m destination_ids + check to not delete a default destination |
28 |
from destination_tools import many2many_sorted, many2many_notlazy |
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
29 |
import decimal_precision as dp |
827.10.3
by jf
UF-1106: FP: order tuple by account.code, FIX: summary dest by accounts |
30 |
|
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
31 |
class analytic_account(osv.osv): |
232.7.1
by Matthieu Dietrich
UF-364: retrieve parent merge |
32 |
_name = "account.analytic.account" |
2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
33 |
_inherit = "account.analytic.account" |
601.1.1
by Olivier DOSSMANN
UF-814 [ADD] Change Analytic Account display |
34 |
|
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
35 |
def _get_active(self, cr, uid, ids, field_name, args, context=None): |
36 |
'''
|
|
1380.3.12
by Olivier DOSSMANN
UF-1678 [ADD] Check on analytic distribution wizard if posting/document date are compatible with Cost centers, destination and funding pool. |
37 |
If date out of date_start/date of given analytic account, then account is inactive.
|
38 |
The comparison could be done via a date given in context.
|
|
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
39 |
'''
|
40 |
res = {} |
|
1380.3.12
by Olivier DOSSMANN
UF-1678 [ADD] Check on analytic distribution wizard if posting/document date are compatible with Cost centers, destination and funding pool. |
41 |
cmp_date = datetime.date.today().strftime('%Y-%m-%d') |
42 |
if context.get('date', False): |
|
43 |
cmp_date = context.get('date') |
|
44 |
for a in self.browse(cr, uid, ids): |
|
45 |
res[a.id] = True |
|
46 |
if a.date_start > cmp_date: |
|
47 |
res[a.id] = False |
|
1380.3.24
by Olivier DOSSMANN
UF-1678 [FIX] Today not shown in inactive analytic accounts |
48 |
if a.date and a.date <= cmp_date: |
1380.3.12
by Olivier DOSSMANN
UF-1678 [ADD] Check on analytic distribution wizard if posting/document date are compatible with Cost centers, destination and funding pool. |
49 |
res[a.id] = False |
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
50 |
return res |
51 |
||
52 |
def _search_filter_active(self, cr, uid, ids, name, args, context=None): |
|
53 |
"""
|
|
54 |
UTP-410: Add the search on active/inactive CC
|
|
55 |
"""
|
|
56 |
arg = [] |
|
1380.3.9
by Olivier DOSSMANN
UF-1678 [ADD] Filtering inactive analytic account on name_search for analytic distribution wizard |
57 |
cmp_date = datetime.date.today().strftime('%Y-%m-%d') |
58 |
if context.get('date', False): |
|
59 |
cmp_date = context.get('date') |
|
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
60 |
for x in args: |
61 |
if x[0] == 'filter_active' and x[2] == True: |
|
1380.3.9
by Olivier DOSSMANN
UF-1678 [ADD] Filtering inactive analytic account on name_search for analytic distribution wizard |
62 |
arg.append(('date_start', '<=', cmp_date)) |
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
63 |
arg.append('|') |
1380.3.9
by Olivier DOSSMANN
UF-1678 [ADD] Filtering inactive analytic account on name_search for analytic distribution wizard |
64 |
arg.append(('date', '>', cmp_date)) |
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
65 |
arg.append(('date', '=', False)) |
1380.3.13
by Olivier DOSSMANN
UF-1678 [ADD] Add a new "Inactive" filter button to show only inactive accounts. |
66 |
elif x[0] == 'filter_active' and x[2] == False: |
67 |
arg.append('|') |
|
68 |
arg.append(('date_start', '>', cmp_date)) |
|
1380.3.24
by Olivier DOSSMANN
UF-1678 [FIX] Today not shown in inactive analytic accounts |
69 |
arg.append(('date', '<=', cmp_date)) |
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
70 |
return arg |
71 |
||
1390.4.4
by Olivier DOSSMANN
UTP-423 [FIX] Problem with FP display: could not display analytic item that have an FP on a soft/hard closed contract. So change behaviour. |
72 |
def _search_closed_by_a_fp(self, cr, uid, ids, name, args, context=None): |
73 |
"""
|
|
74 |
UTP-423: Do not display analytic accounts linked to a soft/hard closed contract.
|
|
75 |
"""
|
|
76 |
res = [('id', 'not in', [])] |
|
77 |
if args and args[0] and len(args[0]) == 3: |
|
78 |
if args[0][1] != '=': |
|
79 |
raise osv.except_osv(_('Error'), _('Operator not supported yet!')) |
|
80 |
# Search all fp_ids from soft_closed contract
|
|
81 |
sql="""SELECT a.id |
|
82 |
FROM account_analytic_account a, financing_contract_contract fcc, financing_contract_funding_pool_line fcfl
|
|
83 |
WHERE fcfl.contract_id = fcc.id
|
|
84 |
AND fcfl.funding_pool_id = a.id
|
|
85 |
AND fcc.state in ('soft_closed', 'hard_closed');"""
|
|
86 |
cr.execute(sql) |
|
87 |
sql_res = cr.fetchall() |
|
88 |
if sql_res: |
|
89 |
aa_ids = self.is_blocked_by_a_contract(cr, uid, [x and x[0] for x in sql_res]) |
|
90 |
if aa_ids: |
|
91 |
if isinstance(aa_ids, (int, long)): |
|
92 |
aa_ids = [aa_ids] |
|
93 |
res = [('id', 'not in', aa_ids)] |
|
94 |
return res |
|
95 |
||
1586.1.1
by jf
UF-1873 [FIX] Intermission PO/FO flow broken |
96 |
def _get_fake(self, cr, uid, ids, *a, **b): |
97 |
return {}.fromkeys(ids, False) |
|
98 |
||
1793.2.22
by Olivier DOSSMANN
UF-1718 [FIX] Compute in output currency if "output_currency_id" is in context for Balance by analytic/general accounts. |
99 |
def _compute_level_tree(self, cr, uid, ids, child_ids, res, field_names, context=None): |
100 |
"""
|
|
101 |
Change balance value using output_currency_id currency in context (if exists)
|
|
102 |
"""
|
|
103 |
# some checks
|
|
104 |
if not context: |
|
105 |
context = {} |
|
106 |
res = super(analytic_account, self)._compute_level_tree(cr, uid, ids, child_ids, res, field_names, context=context) |
|
107 |
company_currency = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id |
|
108 |
if context.get('output_currency_id', False): |
|
109 |
for res_id in res: |
|
110 |
if res[res_id].get('balance', False): |
|
111 |
new_balance = self.pool.get('res.currency').compute(cr, uid, context.get('output_currency_id'), company_currency, res[res_id].get('balance'), context=context) |
|
112 |
res[res_id].update({'balance': new_balance,}) |
|
113 |
return res |
|
114 |
||
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
115 |
# @@@override analytic.analytic
|
116 |
def _debit_credit_bal_qtty(self, cr, uid, ids, name, arg, context=None): |
|
117 |
res = {} |
|
118 |
if context is None: |
|
119 |
context = {} |
|
120 |
# use different criteria regarding analytic account category!
|
|
121 |
account_type = {} |
|
122 |
for line in self.browse(cr, uid, ids, context=context): |
|
123 |
res[line.id] = {} |
|
124 |
for field in name: |
|
125 |
res[line.id].update({field: False}) |
|
126 |
if line.category: |
|
127 |
if not line.category in account_type: |
|
128 |
account_type[line.category] = [] |
|
129 |
account_type[line.category].append(line.id) |
|
130 |
for cat in account_type: |
|
131 |
default_field = 'account_id' |
|
132 |
if cat == 'DEST': |
|
133 |
default_field = 'destination_id' |
|
134 |
elif cat == 'OC': |
|
135 |
default_field = 'cost_center_id' |
|
136 |
child_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', account_type[cat])])) |
|
137 |
for i in child_ids: |
|
138 |
res[i] = {} |
|
139 |
for n in name: |
|
140 |
res[i][n] = 0.0 |
|
141 |
||
142 |
#if not child_ids:
|
|
143 |
# return res
|
|
144 |
||
145 |
where_date = '' |
|
146 |
where_clause_args = [tuple(child_ids)] |
|
147 |
if context.get('from_date', False): |
|
148 |
where_date += " AND l.date >= %s" |
|
149 |
where_clause_args += [context['from_date']] |
|
150 |
if context.get('to_date', False): |
|
151 |
where_date += " AND l.date <= %s" |
|
152 |
where_clause_args += [context['to_date']] |
|
1793.2.48
by Olivier DOSSMANN
UF-1712 [FIX] Filtering on instance_ids field for "Balance by analytic accounts" wizard |
153 |
if context.get('instance_ids', False): |
154 |
instance_ids = context.get('instance_ids') |
|
155 |
if isinstance(instance_ids, (int, long)): |
|
156 |
instance_ids = [instance_ids] |
|
157 |
if len(instance_ids) == 1: |
|
158 |
where_date += " AND l.instance_id = %s" |
|
159 |
else: |
|
160 |
where_date += " AND l.instance_id in %s" |
|
161 |
where_clause_args += tuple(instance_ids) |
|
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
162 |
# UF-1713: Add currency arg
|
163 |
if context.get('currency_id', False): |
|
164 |
where_date += " AND l.currency_id = %s" |
|
165 |
where_clause_args += [context['currency_id']] |
|
166 |
cr.execute(""" |
|
167 |
SELECT a.id,
|
|
168 |
sum(
|
|
169 |
CASE WHEN l.amount > 0
|
|
170 |
THEN l.amount
|
|
171 |
ELSE 0.0
|
|
172 |
END
|
|
173 |
) as debit,
|
|
174 |
sum(
|
|
175 |
CASE WHEN l.amount < 0
|
|
176 |
THEN -l.amount
|
|
177 |
ELSE 0.0
|
|
178 |
END
|
|
179 |
) as credit,
|
|
180 |
COALESCE(SUM(l.amount),0) AS balance,
|
|
181 |
COALESCE(SUM(l.unit_amount),0) AS quantity
|
|
182 |
FROM account_analytic_account a
|
|
183 |
LEFT JOIN account_analytic_line l ON (a.id = l.""" + default_field + """) |
|
184 |
WHERE a.id IN %s |
|
185 |
""" + where_date + """ |
|
186 |
GROUP BY a.id""", where_clause_args) |
|
187 |
for ac_id, debit, credit, balance, quantity in cr.fetchall(): |
|
188 |
res[ac_id] = {'debit': debit, 'credit': credit, 'balance': balance, 'quantity': quantity} |
|
1793.2.23
by Olivier DOSSMANN
UF-1718 [FIX] Problem when using a currency in the report that breaks it |
189 |
tmp_res = self._compute_level_tree(cr, uid, ids, child_ids, res, name, context) |
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
190 |
res.update(tmp_res) |
191 |
return res |
|
192 |
||
2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
193 |
_columns = { |
1424.1.4
by jf
UF-1662 translate=1 added |
194 |
'name': fields.char('Name', size=128, required=True, translate=1), |
675.3.2
by duy.vo at msf
[IMP] UF-887: Rename some attributes of Analytic Account |
195 |
'code': fields.char('Code', size=24), |
196 |
'type': fields.selection([('view','View'), ('normal','Normal')], 'Type', help='If you select the View Type, it means you won\'t allow to create journal entries using that account.'), |
|
154.4.1
by Matthieu Dietrich
UF-287: [IMP] start date/end date are now active date/inactive date |
197 |
'date_start': fields.date('Active from', required=True), |
198 |
'date': fields.date('Inactive from', select=True), |
|
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
199 |
'category': fields.selection([('OC','Cost Center'), |
200 |
('FUNDING','Funding Pool'), |
|
201 |
('FREE1','Free 1'), |
|
827.8.1
by Olivier DOSSMANN
UF-1106 [ADD] Add new analytic account type : DESTINATION |
202 |
('FREE2','Free 2'), |
203 |
('DEST', 'Destination')], 'Category', select=1), |
|
827.8.62
by Olivier DOSSMANN
UF-1106 [ADD] Domain on cost_center for analytic account configuration |
204 |
'cost_center_ids': fields.many2many('account.analytic.account', 'funding_pool_associated_cost_centers', 'funding_pool_id', 'cost_center_id', string='Cost Centers', domain="[('type', '!=', 'view'), ('category', '=', 'OC')]"), |
584.14.1
by Olivier DOSSMANN
UF-806 [ADD] Default analytic account attribute for FX gain/loss |
205 |
'for_fx_gain_loss': fields.boolean(string="For FX gain/loss", help="Is this account for default FX gain/loss?"), |
1116.1.1
by jf
UF-1291: on destination (analytic.account), un-lazy m2m destination_ids + check to not delete a default destination |
206 |
'destination_ids': many2many_notlazy('account.account', 'account_destination_link', 'destination_id', 'account_id', 'Accounts'), |
827.10.3
by jf
UF-1106: FP: order tuple by account.code, FIX: summary dest by accounts |
207 |
'tuple_destination_account_ids': many2many_sorted('account.destination.link', 'funding_pool_associated_destinations', 'funding_pool_id', 'tuple_id', "Account/Destination"), |
827.9.10
by jf
FP: Account/destination Summary tab |
208 |
'tuple_destination_summary': fields.one2many('account.destination.summary', 'funding_pool_id', 'Destination by accounts'), |
1367.3.1
by duy.vo at msf
UTP-410: Modified the active search on account analytic tree |
209 |
'filter_active': fields.function(_get_active, fnct_search=_search_filter_active, type="boolean", method=True, store=False, string="Show only active analytic accounts",), |
1390.4.4
by Olivier DOSSMANN
UTP-423 [FIX] Problem with FP display: could not display analytic item that have an FP on a soft/hard closed contract. So change behaviour. |
210 |
'hide_closed_fp': fields.function(_get_active, fnct_search=_search_closed_by_a_fp, type="boolean", method=True, store=False, string="Linked to a soft/hard closed contract?"), |
1937
by jf
UF-1714 [IMP] General Ledger (modifications on existing feature) |
211 |
'intermission_restricted': fields.function(_get_fake, type="boolean", method=True, store=False, string="Domain to restrict intermission cc"), |
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
212 |
'balance': fields.function(_debit_credit_bal_qtty, method=True, type='float', string='Balance', digits_compute=dp.get_precision('Account'), multi='debit_credit_bal_qtty'), |
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
213 |
}
|
601.1.2
by Olivier DOSSMANN
UF-814 [MERGE] lp:~unifield-team/unifield-wm/trunk |
214 |
|
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
215 |
_defaults ={ |
584.14.1
by Olivier DOSSMANN
UF-806 [ADD] Default analytic account attribute for FX gain/loss |
216 |
'date_start': lambda *a: (datetime.datetime.today() + relativedelta(months=-3)).strftime('%Y-%m-%d'), |
217 |
'for_fx_gain_loss': lambda *a: False, |
|
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
218 |
}
|
1390.4.1
by Olivier DOSSMANN
UTP-423 [FIX] Do not permit user to select an analytic FP account if it is used in a soft/hard closed contract. |
219 |
|
707
by jf
[FIX] Default values |
220 |
def _check_unicity(self, cr, uid, ids, context=None): |
556.5.1
by Matthieu Dietrich
UF-533: [IMP] re-added analytic account constraint |
221 |
if not context: |
707
by jf
[FIX] Default values |
222 |
context = {} |
556.5.1
by Matthieu Dietrich
UF-533: [IMP] re-added analytic account constraint |
223 |
for account in self.browse(cr, uid, ids, context=context): |
1385.10.5
by jf
UF-1662 Import data |
224 |
bad_ids = self.search(cr, uid, [('category', '=', account.category),('|'),('name', '=ilike', account.name),('code', '=ilike', account.code)]) |
556.5.1
by Matthieu Dietrich
UF-533: [IMP] re-added analytic account constraint |
225 |
if len(bad_ids) and len(bad_ids) > 1: |
226 |
return False |
|
227 |
return True |
|
363.10.4
by Matthieu Dietrich
UF-533: case-insensitive unicity constraints |
228 |
|
707
by jf
[FIX] Default values |
229 |
def _check_gain_loss_account_unicity(self, cr, uid, ids, context=None): |
584.14.3
by Olivier DOSSMANN
UF-806 [ADD] Check account type and account category for fx gain/loss account: Should be 'normal' type and 'OC' category (Cost Center) |
230 |
"""
|
231 |
Check that no more account is "for_fx_gain_loss" available.
|
|
232 |
"""
|
|
584.14.2
by Olivier DOSSMANN
UF-806 [ADD] Add constraint for fx gain/loss account |
233 |
if not context: |
234 |
context = {} |
|
235 |
search_ids = self.search(cr, uid, [('for_fx_gain_loss', '=', True)]) |
|
236 |
if search_ids and len(search_ids) > 1: |
|
237 |
return False |
|
238 |
return True |
|
239 |
||
707
by jf
[FIX] Default values |
240 |
def _check_gain_loss_account_type(self, cr, uid, ids, context=None): |
584.14.3
by Olivier DOSSMANN
UF-806 [ADD] Check account type and account category for fx gain/loss account: Should be 'normal' type and 'OC' category (Cost Center) |
241 |
"""
|
242 |
Check account type for fx_gain_loss_account: should be Normal type and Cost Center category
|
|
243 |
"""
|
|
244 |
if not context: |
|
245 |
context = {} |
|
246 |
for account in self.browse(cr, uid, ids, context=context): |
|
584.14.6
by Olivier DOSSMANN
UF-806 [FIX] Some bug on account type for analytic account |
247 |
if account.for_fx_gain_loss == True and (account.type != 'normal' or account.category != 'OC'): |
584.14.3
by Olivier DOSSMANN
UF-806 [ADD] Check account type and account category for fx gain/loss account: Should be 'normal' type and 'OC' category (Cost Center) |
248 |
return False |
249 |
return True |
|
1116.1.1
by jf
UF-1291: on destination (analytic.account), un-lazy m2m destination_ids + check to not delete a default destination |
250 |
|
251 |
def _check_default_destination(self, cr, uid, ids, context=None): |
|
252 |
if isinstance(ids, (int, long)): |
|
253 |
ids = [ids] |
|
254 |
if not ids: |
|
255 |
return True |
|
256 |
cr.execute('''select a.code, a.name, d.name from |
|
257 |
'''+self._table+''' d |
|
258 |
left join account_account a on a.default_destination_id = d.id
|
|
259 |
left join account_destination_link l on l.destination_id = d.id and l.account_id = a.id
|
|
260 |
where a.default_destination_id is not null and l.destination_id is null and d.id in %s ''', (tuple(ids),) |
|
261 |
)
|
|
262 |
error = [] |
|
263 |
for x in cr.fetchall(): |
|
1116.1.2
by jf
UF-1291 raise message |
264 |
error.append(_('"%s" is the default destination for the G/L account "%s %s", you can\'t remove it.')%(x[2], x[0], x[1])) |
1116.1.1
by jf
UF-1291: on destination (analytic.account), un-lazy m2m destination_ids + check to not delete a default destination |
265 |
if error: |
266 |
raise osv.except_osv(_('Warning !'), "\n".join(error)) |
|
267 |
return True |
|
584.14.3
by Olivier DOSSMANN
UF-806 [ADD] Check account type and account category for fx gain/loss account: Should be 'normal' type and 'OC' category (Cost Center) |
268 |
|
556.5.1
by Matthieu Dietrich
UF-533: [IMP] re-added analytic account constraint |
269 |
_constraints = [ |
270 |
(_check_unicity, 'You cannot have the same code or name between analytic accounts in the same category!', ['code', 'name', 'category']), |
|
584.14.3
by Olivier DOSSMANN
UF-806 [ADD] Check account type and account category for fx gain/loss account: Should be 'normal' type and 'OC' category (Cost Center) |
271 |
(_check_gain_loss_account_unicity, 'You can only have one account used for FX gain/loss!', ['for_fx_gain_loss']), |
272 |
(_check_gain_loss_account_type, 'You have to use a Normal account type and Cost Center category for FX gain/loss!', ['for_fx_gain_loss']), |
|
1116.1.1
by jf
UF-1291: on destination (analytic.account), un-lazy m2m destination_ids + check to not delete a default destination |
273 |
(_check_default_destination, "You can't delete an account which has this destination as default", []), |
556.5.1
by Matthieu Dietrich
UF-533: [IMP] re-added analytic account constraint |
274 |
]
|
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
275 |
|
707
by jf
[FIX] Default values |
276 |
def copy(self, cr, uid, id, default=None, context=None, done_list=[], local=False): |
363.10.4
by Matthieu Dietrich
UF-533: case-insensitive unicity constraints |
277 |
account = self.browse(cr, uid, id, context=context) |
278 |
if not default: |
|
279 |
default = {} |
|
280 |
default = default.copy() |
|
281 |
default['code'] = (account['code'] or '') + '(copy)' |
|
282 |
default['name'] = (account['name'] or '') + '(copy)' |
|
1306.1.2
by jf
UF-1601 UTP-335 : duplicate fp: don't duplicate computed "Destinations by accounts" + set the code |
283 |
default['tuple_destination_summary'] = [] |
284 |
# code is deleted in copy method in addons
|
|
285 |
new_id = super(analytic_account, self).copy(cr, uid, id, default, context=context) |
|
286 |
self.write(cr, uid, new_id, {'code': '%s(copy)' % (account['code'] or '')}) |
|
287 |
return new_id |
|
363.10.4
by Matthieu Dietrich
UF-533: case-insensitive unicity constraints |
288 |
|
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
289 |
def set_funding_pool_parent(self, cr, uid, vals): |
363.10.3
by Matthieu Dietrich
Fix for installation |
290 |
if 'category' in vals and \ |
291 |
'code' in vals and \ |
|
292 |
vals['category'] == 'FUNDING' and \ |
|
293 |
vals['code'] != 'FUNDING': |
|
294 |
# for all accounts except the parent one
|
|
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
295 |
funding_pool_parent = self.search(cr, uid, [('category', '=', 'FUNDING'), ('parent_id', '=', False)])[0] |
296 |
vals['parent_id'] = funding_pool_parent |
|
584.14.2
by Olivier DOSSMANN
UF-806 [ADD] Add constraint for fx gain/loss account |
297 |
|
1748
by jf
UF-2079 [FIX] context={} in method def |
298 |
def _check_date(self, vals, context=None): |
299 |
if context is None: |
|
300 |
context = {} |
|
154.4.1
by Matthieu Dietrich
UF-287: [IMP] start date/end date are now active date/inactive date |
301 |
if 'date' in vals and vals['date'] is not False: |
1728.4.1
by Matthieu Dietrich
UF-2079: [FIX] removed inactivation date constraint if account created from sync |
302 |
if vals['date'] <= datetime.date.today().strftime('%Y-%m-%d') and not context.get('sync_update_execution', False): |
1316.4.1
by Olivier DOSSMANN
UF-1583 [DEL] Non-used libraries and variables |
303 |
# validate the date (must be > today)
|
304 |
raise osv.except_osv(_('Warning !'), _('You cannot set an inactivity date lower than tomorrow!')) |
|
154.4.1
by Matthieu Dietrich
UF-287: [IMP] start date/end date are now active date/inactive date |
305 |
elif 'date_start' in vals and not vals['date_start'] < vals['date']: |
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
306 |
# validate that activation date
|
307 |
raise osv.except_osv(_('Warning !'), _('Activation date must be lower than inactivation date!')) |
|
584.14.2
by Olivier DOSSMANN
UF-806 [ADD] Add constraint for fx gain/loss account |
308 |
|
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
309 |
def create(self, cr, uid, vals, context=None): |
584.14.2
by Olivier DOSSMANN
UF-806 [ADD] Add constraint for fx gain/loss account |
310 |
"""
|
311 |
Some verifications before analytic account creation
|
|
312 |
"""
|
|
1728.4.1
by Matthieu Dietrich
UF-2079: [FIX] removed inactivation date constraint if account created from sync |
313 |
self._check_date(vals, context=context) |
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
314 |
self.set_funding_pool_parent(cr, uid, vals) |
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
315 |
return super(analytic_account, self).create(cr, uid, vals, context=context) |
601.1.2
by Olivier DOSSMANN
UF-814 [MERGE] lp:~unifield-team/unifield-wm/trunk |
316 |
|
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
317 |
def write(self, cr, uid, ids, vals, context=None): |
584.14.2
by Olivier DOSSMANN
UF-806 [ADD] Add constraint for fx gain/loss account |
318 |
"""
|
319 |
Some verifications before analytic account write
|
|
320 |
"""
|
|
1728.4.1
by Matthieu Dietrich
UF-2079: [FIX] removed inactivation date constraint if account created from sync |
321 |
self._check_date(vals, context=context) |
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
322 |
self.set_funding_pool_parent(cr, uid, vals) |
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
323 |
return super(analytic_account, self).write(cr, uid, ids, vals, context=context) |
2.6.1
by Matthieu Dietrich
UF-133: [FIX] changed active flag to 2 activity periods |
324 |
|
827.8.64
by Olivier DOSSMANN
UF-1106 [FIX] FP search compatibility with selected destination in analytic distribution wizard |
325 |
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): |
326 |
"""
|
|
1390.4.1
by Olivier DOSSMANN
UTP-423 [FIX] Do not permit user to select an analytic FP account if it is used in a soft/hard closed contract. |
327 |
FIXME: this method do others things that not have been documented. Please complete here what method do.
|
827.8.64
by Olivier DOSSMANN
UF-1106 [FIX] FP search compatibility with selected destination in analytic distribution wizard |
328 |
"""
|
1390.4.3
by Olivier DOSSMANN
UTP-423 [FIX] context that break YAML tests |
329 |
if not context: |
330 |
context = {} |
|
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
331 |
if context and 'search_by_ids' in context and context['search_by_ids']: |
332 |
args2 = args[-1][2] |
|
333 |
del args[-1] |
|
334 |
ids = [] |
|
335 |
for arg in args2: |
|
336 |
ids.append(arg[1]) |
|
337 |
args.append(('id', 'in', ids)) |
|
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
338 |
# UF-1713: Active/inactive functionnality was missing.
|
339 |
if context and 'filter_inactive' in context and context['filter_inactive']: |
|
340 |
args.append(('filter_active', '=', context['filter_inactive'])) |
|
827.8.64
by Olivier DOSSMANN
UF-1106 [FIX] FP search compatibility with selected destination in analytic distribution wizard |
341 |
# Tuple Account/Destination search
|
342 |
for i, arg in enumerate(args): |
|
343 |
if arg[0] and arg[0] == 'tuple_destination': |
|
344 |
fp_ids = [] |
|
345 |
destination_ids = self.pool.get('account.destination.link').search(cr, uid, [('account_id', '=', arg[2][0]), ('destination_id', '=', arg[2][1])]) |
|
346 |
for adl in self.pool.get('account.destination.link').read(cr, uid, destination_ids, ['funding_pool_ids']): |
|
347 |
fp_ids.append(adl.get('funding_pool_ids')) |
|
348 |
fp_ids = flatten(fp_ids) |
|
349 |
args[i] = ('id', 'in', fp_ids) |
|
1390.4.1
by Olivier DOSSMANN
UTP-423 [FIX] Do not permit user to select an analytic FP account if it is used in a soft/hard closed contract. |
350 |
res = super(analytic_account, self).search(cr, uid, args, offset, limit, order, context=context, count=count) |
351 |
return res |
|
350.8.2
by Olivier DOSSMANN
UF-359 [ADD] Filter on OC in order to see all child |
352 |
|
353 |
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
|
354 |
if not context: |
|
355 |
context = {} |
|
356 |
view = super(analytic_account, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu) |
|
350.8.7
by jf
FIX unit test |
357 |
try: |
559.20.1
by Olivier DOSSMANN
[IMP] Disallow some analytic accounts deletion |
358 |
oc_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_project')[1] |
350.8.7
by jf
FIX unit test |
359 |
except ValueError: |
360 |
oc_id = 0 |
|
350.8.2
by Olivier DOSSMANN
UF-359 [ADD] Filter on OC in order to see all child |
361 |
if view_type=='form': |
350.8.3
by Olivier DOSSMANN
UF-359 [IMP] Give a better method to change xml attribute in fields_view_get |
362 |
tree = etree.fromstring(view['arch']) |
363 |
fields = tree.xpath('/form/field[@name="cost_center_ids"]') |
|
364 |
for field in fields: |
|
365 |
field.set('domain', "[('type', '!=', 'view'), ('id', 'child_of', [%s])]" % oc_id) |
|
366 |
view['arch'] = etree.tostring(tree) |
|
350.8.2
by Olivier DOSSMANN
UF-359 [ADD] Filter on OC in order to see all child |
367 |
return view |
368 |
||
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
369 |
def on_change_category(self, cr, uid, id, category): |
370 |
if not category: |
|
371 |
return {} |
|
372 |
res = {'value': {}, 'domain': {}} |
|
373 |
parent = self.search(cr, uid, [('category', '=', category), ('parent_id', '=', False)])[0] |
|
374 |
res['value']['parent_id'] = parent |
|
581.5.5
by Matthieu Dietrich
UF-683: [FIX] added consolidated budgets + bug fixes on reports and budgets |
375 |
res['domain']['parent_id'] = [('category', '=', category), ('type', '=', 'view')] |
363.10.1
by Matthieu Dietrich
UF-527: Change Active Date for Private Funds |
376 |
return res |
601.1.1
by Olivier DOSSMANN
UF-814 [ADD] Change Analytic Account display |
377 |
|
601.1.7
by jf
UF-814: name_search on acccount.analytic.account |
378 |
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): |
379 |
if not args: |
|
380 |
args=[] |
|
381 |
if context is None: |
|
382 |
context={} |
|
1380.3.9
by Olivier DOSSMANN
UF-1678 [ADD] Filtering inactive analytic account on name_search for analytic distribution wizard |
383 |
if context.get('hide_inactive', False): |
384 |
args.append(('filter_active', '=', True)) |
|
601.1.7
by jf
UF-814: name_search on acccount.analytic.account |
385 |
if context.get('current_model') == 'project.project': |
386 |
cr.execute("select analytic_account_id from project_project") |
|
387 |
project_ids = [x[0] for x in cr.fetchall()] |
|
388 |
return self.name_get(cr, uid, project_ids, context=context) |
|
389 |
account = self.search(cr, uid, ['|', ('code', 'ilike', '%%%s%%' % name), ('name', 'ilike', '%%%s%%' % name)]+args, limit=limit, context=context) |
|
390 |
return self.name_get(cr, uid, account, context=context) |
|
391 |
||
1748
by jf
UF-2079 [FIX] context={} in method def |
392 |
def name_get(self, cr, uid, ids, context=None): |
601.1.1
by Olivier DOSSMANN
UF-814 [ADD] Change Analytic Account display |
393 |
"""
|
394 |
Get name for analytic account with analytic account code.
|
|
395 |
Example: For an account OC/Project/Mission, we have something like this:
|
|
396 |
MIS-001 (OC-015/PROJ-859)
|
|
397 |
"""
|
|
398 |
# Some verifications
|
|
399 |
if not context: |
|
400 |
context = {} |
|
401 |
if isinstance(ids, (int, long)): |
|
402 |
ids = [ids] |
|
403 |
# Prepare some value
|
|
404 |
res = [] |
|
405 |
# Browse all accounts
|
|
406 |
for account in self.browse(cr, uid, ids, context=context): |
|
601.1.5
by Olivier DOSSMANN
UF-814 [ADD] Adapt name_get regarding last Jira comments |
407 |
# data = []
|
408 |
# acc = account
|
|
409 |
# while acc:
|
|
410 |
# data.insert(0, acc.code)
|
|
411 |
# acc = acc.parent_id
|
|
412 |
# data = ' / '.join(data[1:-1])
|
|
413 |
# display = "%s" % (account.code)
|
|
414 |
# if len(data) and len(data) > 0:
|
|
415 |
# display = "%s (%s)" % (account.code, data)
|
|
416 |
# res.append((account.id, display))
|
|
417 |
res.append((account.id, account.code)) |
|
601.1.1
by Olivier DOSSMANN
UF-814 [ADD] Change Analytic Account display |
418 |
return res |
419 |
||
707
by jf
[FIX] Default values |
420 |
def unlink(self, cr, uid, ids, context=None): |
559.20.1
by Olivier DOSSMANN
[IMP] Disallow some analytic accounts deletion |
421 |
"""
|
1193.12.3
by Olivier DOSSMANN
UF-1469 [DEL] Dummy CC from Unifield |
422 |
Delete some analytic account is forbidden!
|
559.20.1
by Olivier DOSSMANN
[IMP] Disallow some analytic accounts deletion |
423 |
"""
|
424 |
# Some verification
|
|
425 |
if not context: |
|
426 |
context = {} |
|
427 |
if isinstance(ids, (int, long)): |
|
428 |
ids = [ids] |
|
429 |
# Prepare some values
|
|
430 |
analytic_accounts = [] |
|
431 |
# Search OC CC
|
|
432 |
try: |
|
433 |
oc_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_project')[1] |
|
434 |
except ValueError: |
|
435 |
oc_id = 0 |
|
436 |
analytic_accounts.append(oc_id) |
|
437 |
# Search Funding Pool
|
|
438 |
try: |
|
439 |
fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_funding_pool')[1] |
|
440 |
except ValueError: |
|
441 |
fp_id = 0 |
|
442 |
analytic_accounts.append(fp_id) |
|
443 |
# Search Free 1
|
|
444 |
try: |
|
445 |
f1_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_free_1')[1] |
|
446 |
except ValueError: |
|
447 |
f1_id = 0 |
|
448 |
analytic_accounts.append(f1_id) |
|
449 |
# Search Free 2
|
|
450 |
try: |
|
451 |
f2_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_free_2')[1] |
|
452 |
except ValueError: |
|
453 |
f2_id = 0 |
|
454 |
analytic_accounts.append(f2_id) |
|
455 |
# Search MSF Private Fund
|
|
456 |
try: |
|
457 |
msf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
|
458 |
except ValueError: |
|
459 |
msf_id = 0 |
|
460 |
analytic_accounts.append(msf_id) |
|
461 |
# Accounts verification
|
|
462 |
for id in ids: |
|
463 |
if id in analytic_accounts: |
|
464 |
raise osv.except_osv(_('Error'), _('You cannot delete this Analytic Account!')) |
|
465 |
return super(analytic_account, self).unlink(cr, uid, ids, context=context) |
|
466 |
||
827.8.52
by Olivier DOSSMANN
UF-1106 [ADD] Analytic distribution correction with journal item correction |
467 |
def is_blocked_by_a_contract(self, cr, uid, ids): |
468 |
"""
|
|
469 |
Return ids (analytic accounts) that are blocked by a contract (just FP1)
|
|
470 |
"""
|
|
471 |
# Some verifications
|
|
472 |
if isinstance(ids, (int, long)): |
|
473 |
ids = [ids] |
|
474 |
# Prepare some values
|
|
475 |
res = [] |
|
476 |
for aa in self.browse(cr, uid, ids): |
|
477 |
# Only check funding pool accounts
|
|
478 |
if aa.category != 'FUNDING': |
|
479 |
continue
|
|
827.8.56
by Olivier DOSSMANN
UF-1106 [FIX] Error when change FP in analytic distribution correction wizard |
480 |
link_ids = self.pool.get('financing.contract.funding.pool.line').search(cr, uid, [('funding_pool_id', '=', aa.id)]) |
827.8.52
by Olivier DOSSMANN
UF-1106 [ADD] Analytic distribution correction with journal item correction |
481 |
format_ids = [] |
482 |
for link in self.pool.get('financing.contract.funding.pool.line').browse(cr, uid, link_ids): |
|
483 |
if link.contract_id: |
|
484 |
format_ids.append(link.contract_id.id) |
|
485 |
contract_ids = self.pool.get('financing.contract.contract').search(cr, uid, [('format_id', 'in', format_ids)]) |
|
827.8.56
by Olivier DOSSMANN
UF-1106 [FIX] Error when change FP in analytic distribution correction wizard |
486 |
for contract in self.pool.get('financing.contract.contract').browse(cr, uid, contract_ids): |
827.8.52
by Olivier DOSSMANN
UF-1106 [ADD] Analytic distribution correction with journal item correction |
487 |
if contract.state in ['soft_closed', 'hard_closed']: |
488 |
res.append(aa.id) |
|
489 |
return res |
|
1873
by jf
UF-530 [IMP] Add a "remove all" button in the CC and accounts tabs from the funding pool form view |
490 |
|
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
491 |
def get_analytic_line(self, cr, uid, ids, context=None): |
492 |
"""
|
|
493 |
Return analytic lines list linked to the given analytic accounts
|
|
494 |
"""
|
|
495 |
# Some verifications
|
|
496 |
if not context: |
|
497 |
context = {} |
|
498 |
if isinstance(ids, (int, long)): |
|
499 |
ids = [ids] |
|
500 |
default_field = 'account_id' |
|
501 |
for aaa in self.browse(cr, uid, ids): |
|
502 |
if aaa.category == 'OC': |
|
503 |
default_field = 'cost_center_id' |
|
504 |
elif aaa.category == 'DEST': |
|
505 |
default_field = 'destination_id' |
|
506 |
# Prepare some values
|
|
507 |
domain = [(default_field, 'child_of', ids)] |
|
508 |
context.update({default_field: context.get('active_id')}) |
|
509 |
return { |
|
510 |
'name': _('Analytic Journal Items'), |
|
511 |
'type': 'ir.actions.act_window', |
|
512 |
'res_model': 'account.analytic.line', |
|
513 |
'view_type': 'form', |
|
514 |
'view_mode': 'tree,form', |
|
515 |
'context': context, |
|
516 |
'domain': domain, |
|
517 |
'target': 'current', |
|
518 |
}
|
|
519 |
||
1864.3.1
by Sean Carroll
UF-530: [IMP] added delete all buttons |
520 |
def button_cc_clear(self, cr, uid, ids, context=None): |
1873
by jf
UF-530 [IMP] Add a "remove all" button in the CC and accounts tabs from the funding pool form view |
521 |
self.write(cr, uid, ids, {'cost_center_ids':[(6, 0, [])]}, context=context) |
1864.3.1
by Sean Carroll
UF-530: [IMP] added delete all buttons |
522 |
return True |
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
523 |
|
1864.3.1
by Sean Carroll
UF-530: [IMP] added delete all buttons |
524 |
def button_dest_clear(self, cr, uid, ids, context=None): |
1873
by jf
UF-530 [IMP] Add a "remove all" button in the CC and accounts tabs from the funding pool form view |
525 |
self.write(cr, uid, ids, {'tuple_destination_account_ids':[(6, 0, [])]}, context=context) |
1864.3.1
by Sean Carroll
UF-530: [IMP] added delete all buttons |
526 |
return True |
1793.2.2
by Olivier DOSSMANN
UF-1713 [ADD] Analytic chart of account rebuild |
527 |
|
232.5.1
by Matthieu Dietrich
UF-630: [IMP] 1st step of analytic distribution wizard (on registers and move lines) |
528 |
analytic_account() |
2.1.1
by Matthieu Dietrich
UF-133: [ADD] Analytical plans |
529 |
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|