Merge lp:~julie-w/unifield-server/US-7545 into lp:unifield-server

Proposed by jftempo
Status: Needs review
Proposed branch: lp:~julie-w/unifield-server/US-7545
Merge into: lp:unifield-server
Diff against target: 719 lines (+290/-47) (has conflicts)
12 files modified
bin/addons/account_override/account.py (+23/-1)
bin/addons/analytic_override/analytic_account.py (+30/-9)
bin/addons/financing_contract/contract.py (+69/-16)
bin/addons/financing_contract/financing_contract_account_quadruplet.py (+104/-6)
bin/addons/financing_contract/financing_contract_view.xml (+1/-1)
bin/addons/financing_contract/format_line.py (+19/-3)
bin/addons/financing_contract/report/financing_interactive_xls.mako (+8/-0)
bin/addons/financing_contract/report/project_expenses_xls.mako (+1/-1)
bin/addons/financing_contract/report/report_interactive.py (+18/-2)
bin/addons/financing_contract/report/report_project_expenses.py (+6/-5)
bin/addons/financing_contract/wizard/wizard_interactive_report.py (+3/-2)
bin/addons/msf_profile/i18n/fr_MF.po (+8/-1)
Text conflict in bin/addons/account_override/account.py
Text conflict in bin/addons/financing_contract/contract.py
Text conflict in bin/addons/financing_contract/financing_contract_account_quadruplet.py
To merge this branch: bzr merge lp:~julie-w/unifield-server/US-7545
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+424865@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

5946. By Julie Nuguet

US-7545 [IMP] Financing Contracts: typo

5945. By Julie Nuguet

US-7545 [IMP] Analytic Accounts / get_cc_linked_to_fp: allow_all_cc is now a boolean instead of an instance

5944. By Julie Nuguet

US-7545 [MERGE] Merge with the latest version of the trunk lp:unifield-server

5943. By Julie Nuguet

US-7545 [IMP] Financing Contracts

1) Fix the following UC:
- add FP1 and PF to a contract
- create a reporting line with quadruplets for both FP
- remove FP1 and the CC from the contract
- all quads were reset, although those linked to PF were still valid

2) Add "TODO" for the remaining parts

5942. By Julie Nuguet

US-7545 [IMP] Financing Contracts: restrict the generation of quadruplets to:
1) if PF is selected => PF + all CC linked to the contract Prop. Instance
2) the other FP selected + the CC selected

5941. By Julie Nuguet

US-7545 [IMP] Financing Contracts: missing field in fields_to_fetch

5940. By Julie Nuguet

US-7545 [IMP] Financing Contracts: when PF is selected don't fill in the CC list automatically anymore but make the related combinations still usable

5939. By Julie Nuguet

US-7545 [IMP] Financing Contracts: by defaut display the contracts ordered by "Eligibility date to"

5938. By Julie Nuguet

US-7545 [IMP] Analytic Accounts get_cc_linked_to_fp: don't browse all CC for the UC where CC are selected in the FP form (perf)

5937. By Julie Nuguet

US-7545 [IMP] Financing Contracts / add_general_domain: remove "by reference" copy (avoid modifying "domain" in case "res" is modified)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/account_override/account.py'
2--- bin/addons/account_override/account.py 2022-05-08 14:15:29 +0000
3+++ bin/addons/account_override/account.py 2022-06-16 12:50:12 +0000
4@@ -391,12 +391,19 @@
5 """
6 Returns a domain with the G/L accounts selectable in the contract in context.
7 The accounts must appear either in the G/L accounts or in the Account/Destination combinations linked to the
8- Funding Pools selected in the contract.
9+ Funding Pools selected in the contract. In case PF has been selected, all accounts allowing an AD are selectable.
10 """
11 if context is None:
12 context = {}
13+<<<<<<< TREE
14+=======
15+ contract_obj = self.pool.get('financing.contract.contract')
16+ acc_obj = self.pool.get('account.account')
17+ analytic_acc_obj = self.pool.get('account.analytic.account')
18+>>>>>>> MERGE-SOURCE
19 acc_ids = set()
20 if context.get('contract_id'):
21+<<<<<<< TREE
22 cr.execute('''
23 select
24 distinct(rel.account_id)
25@@ -433,6 +440,21 @@
26 ''', (context['contract_id'], ))
27 acc_ids.update([x[0] for x in cr.fetchall()])
28
29+=======
30+ contract = contract_obj.browse(cr, uid, context['contract_id'], fields_to_fetch=['funding_pool_ids'], context=context)
31+ try:
32+ pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
33+ 'analytic_account_msf_private_funds')[1]
34+ except ValueError:
35+ pf_id = 0
36+ funding_pool_ids = [contract_fp_line.funding_pool_id.id for contract_fp_line in contract.funding_pool_ids]
37+ if pf_id in funding_pool_ids:
38+ acc_ids.update(acc_obj.search(cr, uid, [('type', '!=', 'view'), ('is_analytic_addicted', '=', True)], context=context))
39+ else:
40+ for funding_pool_id in funding_pool_ids:
41+ acc_ids.update([t[0] for t in
42+ analytic_acc_obj.get_acc_dest_linked_to_fp(cr, uid, funding_pool_id, context=context)])
43+>>>>>>> MERGE-SOURCE
44 return [('id', 'in', list(acc_ids))]
45
46 def _get_selected_in_contract(self, cr, uid, account_ids, name=False, args=False, context=None):
47
48=== modified file 'bin/addons/analytic_override/analytic_account.py'
49--- bin/addons/analytic_override/analytic_account.py 2022-04-27 14:31:31 +0000
50+++ bin/addons/analytic_override/analytic_account.py 2022-06-16 12:50:12 +0000
51@@ -1017,14 +1017,15 @@
52 'target': 'current',
53 }
54
55- def get_cc_linked_to_fp(self, cr, uid, fp_id, context=None):
56+ def get_cc_linked_to_fp(self, cr, uid, fp_id, pf=False, pf_restrict_instance_id=False, context=None):
57 """
58 Returns a browse record list of all Cost Centers compatible with the Funding Pool in parameter:
59 - if "Allow all Cost Centers" is ticked: all CC linked to the prop. instance of the FP
60 - else all CC selected in the FP form.
61
62 Note: this method matches with what has been selected in the Cost centers tab of the FP form.
63- It returns an empty list for PF.
64+ It returns an empty list for PF, unless "pf" is set to True. Then it returns either all CC, or all CC
65+ linked to the "pf_restrict_instance_id" if it is set.
66 """
67 if context is None:
68 context = {}
69@@ -1033,14 +1034,34 @@
70 fields_to_fetch=['category', 'allow_all_cc_with_fp', 'instance_id', 'cost_center_ids'],
71 context=context)
72 if fp.category == 'FUNDING':
73- if fp.allow_all_cc_with_fp and fp.instance_id:
74- # inactive CC are included on purpose, to match with selectable CC in FP form
75- for cc_id in self.search(cr, uid, [('category', '=', 'OC'), ('type', '!=', 'view')], order='code', context=context):
76- cc = self.browse(cr, uid, cc_id, context=context)
77- if fp.instance_id.id in [inst.id for inst in cc.cc_instance_ids]:
78- cc_list.append(cc)
79- else:
80+ try:
81+ pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
82+ 'analytic_account_msf_private_funds')[1]
83+ except ValueError:
84+ pf_id = 0
85+ is_pf = pf and fp.id == pf_id
86+ allow_all_cc = fp.instance_id and fp.allow_all_cc_with_fp
87+ if not is_pf and not allow_all_cc:
88+ # UC1: CC selected in the FP form
89 cc_list = fp.cost_center_ids or []
90+ else:
91+ # inactive CC are included on purpose, to match with the selectable CC in the FP form
92+ all_cc_ids = self.search(cr, uid, [('category', '=', 'OC'), ('type', '!=', 'view')], order='code', context=context)
93+ all_cc = all_cc_ids and self.browse(cr, uid, all_cc_ids, context=context) or []
94+ prop_instance_id = False
95+ if is_pf and pf_restrict_instance_id:
96+ # UC2: PF with restriction on a Prop. Instance
97+ prop_instance_id = pf_restrict_instance_id
98+ elif allow_all_cc:
99+ # UC3: Allow all Cost Centers
100+ prop_instance_id = fp.instance_id.id
101+ if prop_instance_id:
102+ for cc in all_cc:
103+ if prop_instance_id in [inst.id for inst in cc.cc_instance_ids]:
104+ cc_list.append(cc)
105+ elif is_pf:
106+ # UC4: PF with no restriction on Prop. Instance
107+ cc_list = all_cc
108 return cc_list
109
110 def get_acc_dest_linked_to_fp(self, cr, uid, fp_id, context=None):
111
112=== modified file 'bin/addons/financing_contract/contract.py'
113--- bin/addons/financing_contract/contract.py 2022-03-15 14:23:18 +0000
114+++ bin/addons/financing_contract/contract.py 2022-06-16 12:50:12 +0000
115@@ -65,12 +65,17 @@
116 if context is None:
117 context = {}
118 analytic_acc_obj = self.pool.get('account.analytic.account')
119+ contract_obj = self.pool.get('financing.contract.contract')
120 format_obj = self.pool.get('financing.contract.format')
121 contract_obj = self.pool.get('financing.contract.contract')
122 # US-113: Check if the call is from sync update
123 if context.get('sync_update_execution') and vals.get('contract_id', False):
124 # US-113: and if there is any financing contract existed for this format, if no, then ignore this call
125+<<<<<<< TREE
126 exist = contract_obj.search_exists(cr, uid, [('format_id', '=', vals['contract_id'])])
127+=======
128+ exist = contract_obj.search_exist(cr, uid, [('format_id', '=', vals['contract_id'])])
129+>>>>>>> MERGE-SOURCE
130 if not exist:
131 return None
132 # new fp from sync: request new quad generation
133@@ -83,8 +88,8 @@
134 #US-345: the following block cannot be executed in the sync context, because it would then reset all costcenters from the funding pools!
135 # making that the deleted costcenters from the sender were not taken into account
136 if not context.get('sync_update_execution') and vals.get('contract_id') and vals.get('funding_pool_id'):
137- # get the Cost Centers linked to the Funding Pool
138- fp_cc_ids = [c.id for c in analytic_acc_obj.get_cc_linked_to_fp(cr, uid, vals['funding_pool_id'], context=context)]
139+ # get the Cost Centers linked to the Funding Pool (empty list for PF)
140+ fp_cc_ids = [c.id for c in analytic_acc_obj.get_cc_linked_to_fp(cr, uid, vals['funding_pool_id'], pf=False, context=context)]
141
142 # get the format instance
143 cc_rows = format_obj.browse(cr, uid, vals['contract_id'], context=context).cost_center_ids
144@@ -136,7 +141,20 @@
145 _name = "financing.contract.contract"
146 _inherits = {"financing.contract.format": "format_id"}
147 _trace = True
148+<<<<<<< TREE
149 _order = 'id desc'
150+=======
151+ # _order: see search_web
152+
153+ def search_web(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
154+ """
155+ Changes the default display order of the contracts.
156+ The field "eligibility_to_date" can't be used directly in _order as it belongs to financing.contract.format.
157+ """
158+ if not count and not order:
159+ order = 'eligibility_to_date desc, id desc'
160+ return super(financing_contract_contract, self).search_web(cr, uid, args, offset, limit, order, context, count)
161+>>>>>>> MERGE-SOURCE
162
163 def contract_open_proxy(self, cr, uid, ids, context=None):
164 # utp-1030/7: check grant amount when going on in workflow
165@@ -237,11 +255,6 @@
166 def add_general_domain(self, cr, uid, domain, browse_format_id, reporting_type, context=None):
167 format_line_obj = self.pool.get('financing.contract.format.line')
168 general_domain = format_line_obj._get_general_domain(cr, uid, browse_format_id, reporting_type, context=context)
169- # UTP-1063: Don't use MSF Private Funds anymore
170- try:
171- fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
172- except Exception:
173- fp_id = 0
174
175 #US-385: Move the funding pool and cost center outside the loop, put them at header of the domain
176 temp_domain = []
177@@ -250,9 +263,9 @@
178 if general_domain.get('funding_pool_domain', False):
179 temp_domain = ['&', '&'] + [cc_domain] + [eval(general_domain['funding_pool_domain'])] + date_domain
180
181- res = [('account_id', '!=', fp_id)]
182+ res = []
183 if domain:
184- res = ['&'] + res + domain
185+ res = domain[:]
186
187 if temp_domain:
188 res = ['&'] + temp_domain + res
189@@ -551,19 +564,21 @@
190 Check if contract gives some FP. If not raise an error.
191 Otherwise launch the report.
192 """
193- # Some verifications
194- if not context:
195+ if context is None:
196 context = {}
197- if isinstance(ids, (int, long)):
198- ids = [ids]
199- for contract in self.browse(cr, uid, ids, context=context):
200+ contract_ids = context.get('active_ids', [])
201+ if not contract_ids:
202+ raise osv.except_osv(_('Error'), _('No contract selected.'))
203+ if isinstance(contract_ids, (int, long)):
204+ contract_ids = [contract_ids]
205+ for contract in self.browse(cr, uid, contract_ids, fields_to_fetch=['format_id', 'name'], context=context):
206 if not contract.format_id.funding_pool_ids:
207 raise osv.except_osv(_('Error'), _('No FP selected in the financing contract: %s') % (contract.name or ''))
208 # We launch the report
209 return {
210 'type': 'ir.actions.report.xml',
211 'report_name': 'financing.allocated.expenses.2',
212- 'datas': {'ids': ids},
213+ 'datas': {'ids': contract_ids},
214 'context': context,
215 }
216
217@@ -607,6 +622,7 @@
218 ids = [ids]
219 if context is None:
220 context = {}
221+ analytic_acc_obj = self.pool.get('account.analytic.account')
222
223 if 'donor_id' in vals:
224 donor = self.pool.get('financing.contract.donor').browse(cr, uid, vals['donor_id'], context=context)
225@@ -625,6 +641,7 @@
226
227 # if there is some FP in this contract format, then perform the "recovery" of cost center ids, if not just use the one from the form
228 if f_value.funding_pool_ids:
229+ # TODO JN: anything to change here?
230 cc_rows = f_value.cost_center_ids # retrieve all the cc stored previously in the DB
231 cc_ids = []
232 for cc in cc_rows:
233@@ -645,14 +662,50 @@
234 if fp_added_flag: # if the previous save has been recovered thanks to the flag set to True, then reset it back to False
235 cr.execute('''update financing_contract_contract set fp_added_flag = 'f' where id = %s''', (ids[0],))
236
237+<<<<<<< TREE
238 format = self.browse(cr,uid,ids,context=context)[0].format_id
239+=======
240+ # uf-2342 delete any assigned quads that are no longer valid due to changes in the contract
241+ # get list of all valid ids for this contract
242+ # TODO JN: make a loop on contract ids?
243+ financing_contract = self.browse(cr, uid, ids, context=context)[0]
244+ format = financing_contract.format_id
245+ funding_pool_ids = [x.funding_pool_id.id for x in format.funding_pool_ids]
246+>>>>>>> MERGE-SOURCE
247
248 if not context.get('sync_update_execution'):
249 earmarked_funding_pools = [x.funded for x in format.funding_pool_ids]
250 if not any(earmarked_funding_pools) and format.reporting_type == 'allocated':
251 raise osv.except_osv(_('Error'), _("At least one funding pool should be defined as earmarked in the funding pool list of this financing contract."))
252
253-
254+<<<<<<< TREE
255+
256+=======
257+ cost_center_ids = [x.id for x in format.cost_center_ids]
258+
259+ quad_obj = self.pool.get('financing.contract.account.quadruplet')
260+ quad_domain = []
261+ try:
262+ pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
263+ 'analytic_account_msf_private_funds')[1]
264+ except ValueError:
265+ pf_id = 0
266+ if pf_id in funding_pool_ids:
267+ # all CC linked to the contract Prop. Instance
268+ pf_cc_ids = [cc.id for cc in
269+ analytic_acc_obj.get_cc_linked_to_fp(cr, uid, pf_id, pf=True,
270+ pf_restrict_instance_id=financing_contract.instance_id.id, context=context)]
271+ funding_pool_ids.remove(pf_id)
272+ quad_domain.append('|')
273+ quad_domain.append('&')
274+ quad_domain.append(('cost_center_id', 'in', pf_cc_ids))
275+ quad_domain.append(('funding_pool_id', '=', pf_id))
276+ quad_domain.append('&')
277+ quad_domain.append(('cost_center_id', 'in', cost_center_ids))
278+ quad_domain.append(('funding_pool_id', 'in', funding_pool_ids))
279+ valid_quad_ids = quad_obj.search(cr, uid, quad_domain, context=context)
280+
281+>>>>>>> MERGE-SOURCE
282 # filter current assignments and re-write entries if necessary
283 format_obj = self.pool.get('financing.contract.format')
284 format_line_obj = self.pool.get('financing.contract.format.line')
285
286=== modified file 'bin/addons/financing_contract/financing_contract_account_quadruplet.py'
287--- bin/addons/financing_contract/financing_contract_account_quadruplet.py 2022-03-15 09:14:07 +0000
288+++ bin/addons/financing_contract/financing_contract_account_quadruplet.py 2022-06-16 12:50:12 +0000
289@@ -99,7 +99,13 @@
290 lnk.id = fpad.tuple_id AND
291 fp.id = fpad.funding_pool_id AND
292 lnk.destination_id = dest.id AND
293+<<<<<<< TREE
294 (dest.allow_all_cc = 't' or dest_cc_link.cc_id = cc.id)
295+=======
296+ (dest.allow_all_cc = 't' or dest_cc_rel.cost_center_id = cc.id) AND
297+ fp.id != (SELECT res_id FROM ir_model_data WHERE
298+ module='analytic_distribution' and name='analytic_account_msf_private_funds' LIMIT 1)
299+>>>>>>> MERGE-SOURCE
300
301 UNION
302
303@@ -126,7 +132,13 @@
304 fp_account_rel.account_id= gl_account.id and
305 lnk.account_id = gl_account.id and
306 lnk.destination_id = dest.id and
307+<<<<<<< TREE
308 (dest.allow_all_cc = 't' or dest_cc_link.cc_id = cc.id)
309+=======
310+ (dest.allow_all_cc = 't' or dest_cc_rel.cost_center_id = cc.id) AND
311+ fp.id != (SELECT res_id FROM ir_model_data WHERE
312+ module='analytic_distribution' and name='analytic_account_msf_private_funds' LIMIT 1)
313+>>>>>>> MERGE-SOURCE
314
315 UNION
316
317@@ -151,7 +163,13 @@
318 fp_account_rel.account_id= gl_account.id and
319 lnk.account_id = gl_account.id and
320 lnk.destination_id = dest.id and
321+<<<<<<< TREE
322 (dest.allow_all_cc = 't' or dest_cc_link.cc_id = cc.id)
323+=======
324+ (dest.allow_all_cc = 't' or dest_cc_rel.cost_center_id = cc.id) AND
325+ fp.id != (SELECT res_id FROM ir_model_data WHERE
326+ module='analytic_distribution' and name='analytic_account_msf_private_funds' LIMIT 1)
327+>>>>>>> MERGE-SOURCE
328
329 UNION
330
331@@ -176,7 +194,32 @@
332 lnk.id = fpad.tuple_id and
333 fp.id = fpad.funding_pool_id and
334 lnk.destination_id = dest.id and
335+<<<<<<< TREE
336 (dest.allow_all_cc = 't' or dest_cc_link.cc_id = cc.id)
337+=======
338+ (dest.allow_all_cc = 't' or dest_cc_rel.cost_center_id = cc.id) AND
339+ fp.id != (SELECT res_id FROM ir_model_data WHERE
340+ module='analytic_distribution' and name='analytic_account_msf_private_funds' LIMIT 1)
341+
342+ UNION
343+
344+ -- PF
345+ SELECT
346+ lnk.destination_id AS account_destination_id, cc.id AS cost_center_id,
347+ (SELECT res_id FROM ir_model_data WHERE
348+ module='analytic_distribution' and name='analytic_account_msf_private_funds' LIMIT 1) AS funding_pool_id,
349+ lnk.name AS account_destination_name, lnk.account_id, lnk.disabled, lnk.id AS account_destination_link_id
350+ FROM
351+ account_analytic_account cc,
352+ account_destination_link lnk,
353+ account_analytic_account dest
354+ LEFT JOIN destination_cost_center_rel dest_cc_rel ON dest_cc_rel.destination_id = dest.id
355+ WHERE
356+ cc.type != 'view' AND
357+ cc.category = 'OC' AND
358+ lnk.destination_id = dest.id AND
359+ (dest.allow_all_cc = 't' OR dest_cc_rel.cost_center_id = cc.id)
360+>>>>>>> MERGE-SOURCE
361 ) AS combinations
362 )""")
363 return res
364@@ -191,6 +234,7 @@
365 contract_id = context.get('contract_id', False)
366 if contract_id:
367 ctr_obj = self.pool.get('financing.contract.contract')
368+<<<<<<< TREE
369 contract = ctr_obj.browse(cr, uid, context['contract_id'], fields_to_fetch=['funding_pool_ids', 'cost_center_ids', 'quad_gen_date'], context=context)
370 # last_modification: is modified when the record is Save&Edit on the instance
371 # date_update: is modified by a sync update
372@@ -202,6 +246,14 @@
373 module='sd' and
374 model in ('account.analytic.account', 'account.destination.link', 'dest.cc.link')
375 ''')
376+=======
377+ analytic_acc_obj = self.pool.get('account.analytic.account')
378+ contract = ctr_obj.browse(cr, uid, context['contract_id'], fields_to_fetch=['funding_pool_ids', 'cost_center_ids',
379+ 'quad_gen_date', 'instance_id'], context=context)
380+ cr.execute('''select max(last_modification) from ir_model_data where module='sd' and (
381+ model in ('account.analytic.account', 'account.destination.link') or (model = 'financing.contract.contract' and res_id = %s)
382+ )''', (contract_id,))
383+>>>>>>> MERGE-SOURCE
384 last_obj_modified = cr.fetchone()[0]
385 if not contract.quad_gen_date or last_obj_modified > contract.quad_gen_date or contract.quad_gen_date > time.strftime('%Y-%m-%d %H:%M:%S'):
386 # ignore quad_gen_date in the future
387@@ -209,17 +261,42 @@
388 timer = time.time()
389 cc_ids = [cc.id for cc in contract.cost_center_ids]
390 fp_ids = [fp.funding_pool_id.id for fp in contract.funding_pool_ids]
391+ # do not traceback if cc / fp not set on contract
392 if not cc_ids:
393- # do not traceback if cc / fp not set on contract
394 cc_ids = [0]
395 if not fp_ids:
396 fp_ids = [0]
397+<<<<<<< TREE
398+=======
399+ pf_cc_ids = [0] # CC to link to PF ONLY IF PF has been selected in the contract form
400+ try:
401+ pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
402+ 'analytic_account_msf_private_funds')[1]
403+ except ValueError:
404+ pf_id = 0
405+ if pf_id in fp_ids:
406+ # all CC linked to the contract Prop. Instance
407+ pf_cc_ids = [cc.id for cc in
408+ analytic_acc_obj.get_cc_linked_to_fp(cr, uid, pf_id, pf=True,
409+ pf_restrict_instance_id=contract.instance_id.id, context=context)]
410+ fp_ids.remove(pf_id)
411+ if not fp_ids:
412+ fp_ids = [0]
413+>>>>>>> MERGE-SOURCE
414 cr.execute('''
415 update financing_contract_account_quadruplet set disabled='t'
416 where
417+<<<<<<< TREE
418 funding_pool_id in %s and
419 cost_center_id in %s
420 ''', (tuple(fp_ids), tuple(cc_ids)))
421+=======
422+ (funding_pool_id = %s and cost_center_id in %s)
423+ or
424+ (funding_pool_id in %s and cost_center_id in %s)
425+ ''', (pf_id, tuple(pf_cc_ids), tuple(fp_ids), tuple(cc_ids)))
426+
427+>>>>>>> MERGE-SOURCE
428 cr.execute('''
429 INSERT INTO financing_contract_account_quadruplet
430 (account_destination_name, account_id, cost_center_id, disabled, account_destination_link_id, funding_pool_id, account_destination_id)
431@@ -228,10 +305,12 @@
432 from
433 financing_contract_account_quadruplet_view
434 where
435- funding_pool_id in %s and
436- cost_center_id in %s
437+ (funding_pool_id = %s and cost_center_id in %s)
438+ or
439+ (funding_pool_id in %s and cost_center_id in %s)
440 )
441- ON CONFLICT ON CONSTRAINT financing_contract_account_quadruplet_check_unique DO UPDATE SET disabled=EXCLUDED.disabled''', (tuple(fp_ids), tuple(cc_ids)))
442+ ON CONFLICT ON CONSTRAINT financing_contract_account_quadruplet_check_unique DO UPDATE SET disabled=EXCLUDED.disabled''',
443+ (pf_id, tuple(pf_cc_ids), tuple(fp_ids), tuple(cc_ids)))
444 cr.execute('update financing_contract_contract set quad_gen_date=%s where id=%s', (last_obj_modified, contract_id))
445 self._logger.info('Gen time: %s' % (time.time() - timer))
446 return True
447@@ -307,10 +386,29 @@
448 return res
449
450 ctr_obj = self.pool.get('financing.contract.contract')
451- contract = ctr_obj.browse(cr, uid, context['contract_id'], fields_to_fetch=['funding_pool_ids', 'cost_center_ids'])
452+ analytic_acc_obj = self.pool.get('account.analytic.account')
453+ contract = ctr_obj.browse(cr, uid, context['contract_id'], fields_to_fetch=['funding_pool_ids', 'cost_center_ids', 'instance_id'])
454+ quad_domain = []
455 cc_ids = [cc.id for cc in contract.cost_center_ids]
456 fp_ids = [fp.funding_pool_id.id for fp in contract.funding_pool_ids]
457- return [('cost_center_id', 'in', cc_ids), ('funding_pool_id', 'in', fp_ids)]
458+ try:
459+ pf_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution',
460+ 'analytic_account_msf_private_funds')[1]
461+ except ValueError:
462+ pf_id = 0
463+ if pf_id in fp_ids:
464+ pf_cc_ids = [cc.id for cc in
465+ analytic_acc_obj.get_cc_linked_to_fp(cr, uid, pf_id, pf=True,
466+ pf_restrict_instance_id=contract.instance_id.id, context=context)]
467+ quad_domain.append('|')
468+ quad_domain.append('&')
469+ quad_domain.append(('cost_center_id', 'in', pf_cc_ids))
470+ quad_domain.append(('funding_pool_id', '=', pf_id))
471+ fp_ids.remove(pf_id)
472+ quad_domain.append('&')
473+ quad_domain.append(('cost_center_id', 'in', cc_ids))
474+ quad_domain.append(('funding_pool_id', 'in', fp_ids))
475+ return quad_domain
476
477 _columns = {
478 'account_destination_id': fields.many2one('account.analytic.account', 'Destination', relate=True, readonly=True, select=1),
479
480=== modified file 'bin/addons/financing_contract/financing_contract_view.xml'
481--- bin/addons/financing_contract/financing_contract_view.xml 2022-03-14 13:07:19 +0000
482+++ bin/addons/financing_contract/financing_contract_view.xml 2022-06-16 12:50:12 +0000
483@@ -41,7 +41,7 @@
484 <field colspan="4" name="funding_pool_ids" nolabel="1"
485 attrs="{'readonly': [('state', 'in', ('soft_closed', 'hard_closed'))]}">
486 <tree string="Funding pools" editable="top">
487- <field name="funding_pool_id" domain="[('type', '!=', 'view'), ('category', '=', 'FUNDING'), ('code', '!=', 'PF')]"/>
488+ <field name="funding_pool_id" domain="[('type', '!=', 'view'), ('category', '=', 'FUNDING')]"/>
489 <field name="funded"/>
490 <field name="total_project" readonly="1"/>
491 </tree>
492
493=== modified file 'bin/addons/financing_contract/format_line.py'
494--- bin/addons/financing_contract/format_line.py 2022-03-22 09:19:05 +0000
495+++ bin/addons/financing_contract/format_line.py 2022-06-16 12:50:12 +0000
496@@ -194,7 +194,9 @@
497 gen_domain = {}
498 gen_domain['date_domain'] = date_domain
499
500- cost_center_domain = self._create_domain('cost_center_id', browse_format.cost_center_ids)
501+ # TODO JN: adapt the cost_center_domain. Use this stub in the meantime:
502+ #cost_center_domain = self._create_domain('cost_center_id', browse_format.cost_center_ids)
503+ cost_center_domain = '(\'cost_center_id\', \'!=\', 0)'
504 gen_domain['cost_center_domain'] = cost_center_domain
505
506
507@@ -311,6 +313,9 @@
508 Method to compute the allocated budget/amounts, depending on the information in the line
509 """
510 res = {}
511+ if context is None:
512+ context = {}
513+ curr_obj = self.pool.get('res.currency')
514 # 1st step: get the real list of actual lines to compute
515 actual_line_ids = []
516 overhead = self._is_overhead_present(cr, uid, ids, context=context)
517@@ -340,6 +345,16 @@
518 if line.id not in res:
519 self._get_view_amount(line, total_budget_costs, res)
520
521+ # convert the amounts from the reporting currency of the contract to the output currency selected in the wizard
522+ res_in_curr = {}
523+ if context.get('contract_fx_date') and context.get('reporting_currency_id') and context.get('out_currency') and \
524+ context['reporting_currency_id'] != context['out_currency']:
525+ date_context = context.copy()
526+ date_context.update({'currency_date': context['contract_fx_date']}) # use the rate at "Eligibility from" date
527+ for r_id in res:
528+ res_in_curr[r_id] = curr_obj.compute(cr, uid, context['reporting_currency_id'], context['out_currency'],
529+ res[r_id] or 0.0, round=False, context=date_context)
530+ res = res_in_curr
531 return res
532
533 def _get_actual_amount(self, cr, uid, ids, field_name=None, arg=None, context=None):
534@@ -392,7 +407,8 @@
535 if analytic_domain:
536 analytic_domain = self.pool.get('financing.contract.contract').add_general_domain(cr, uid, analytic_domain, line.format_id, report_type, context)
537 # selection of analytic lines
538- if 'reporting_currency' in context: # TODO Why do we only get analytic lines if reporting_currency in context
539+ if 'out_currency' in context: # used for the computation in output currency
540+ # note: only analytic lines are retrieved in this report
541 analytic_line_obj = self.pool.get('account.analytic.line')
542 analytic_lines = analytic_line_obj.search(cr, uid, analytic_domain ,context=context)
543 # list of analytic journal_ids which are in the engagement journals
544@@ -413,7 +429,7 @@
545 real_sum += self.pool.get('res.currency').compute(cr,
546 uid,
547 analytic_line.currency_id.id,
548- context['reporting_currency'],
549+ context['out_currency'],
550 analytic_line.amount_currency or 0.0,
551 round=False,
552 context=date_context)
553
554=== modified file 'bin/addons/financing_contract/report/financing_interactive_xls.mako'
555--- bin/addons/financing_contract/report/financing_interactive_xls.mako 2018-06-08 08:56:46 +0000
556+++ bin/addons/financing_contract/report/financing_interactive_xls.mako 2022-06-16 12:50:12 +0000
557@@ -405,6 +405,14 @@
558 </Row>
559 <Row>
560 <Cell ss:StyleID="s21">
561+<Data ss:Type="String">${_('Output currency:')}</Data>
562+</Cell>
563+<Cell ss:StyleID="s21">
564+<Data ss:Type="String">${ getOutputCurrency(o) |x}</Data>
565+</Cell>
566+</Row>
567+<Row>
568+<Cell ss:StyleID="s21">
569 <Data ss:Type="String">${_('Eligible from:')}</Data>
570 </Cell>
571 % if isDate(o.eligibility_from_date):
572
573=== modified file 'bin/addons/financing_contract/report/project_expenses_xls.mako'
574--- bin/addons/financing_contract/report/project_expenses_xls.mako 2020-02-03 17:00:37 +0000
575+++ bin/addons/financing_contract/report/project_expenses_xls.mako 2022-06-16 12:50:12 +0000
576@@ -609,7 +609,7 @@
577 </Cell>
578 <Cell ss:StyleID="s49"></Cell>
579 <Cell ss:StyleID="s49">
580- <Data ss:Type="Number">${getTotalRptCurrency()}</Data>
581+ <Data ss:Type="Number">${getTotalRptCurrency(o)}</Data>
582 </Cell>
583 <Cell ss:StyleID="s49"></Cell>
584 </Row>
585
586=== modified file 'bin/addons/financing_contract/report/report_interactive.py'
587--- bin/addons/financing_contract/report/report_interactive.py 2018-06-05 14:03:07 +0000
588+++ bin/addons/financing_contract/report/report_interactive.py 2022-06-16 12:50:12 +0000
589@@ -14,6 +14,7 @@
590 'getLines':self.getLines,
591 'getTot':self.getTot,
592 'getCostCenter':self.getCostCenter,
593+ 'getOutputCurrency': self.getOutputCurrency,
594 'checkType':self.checkType,
595 'checkType2':self.checkType2,
596 })
597@@ -45,6 +46,17 @@
598 ccs += [cc.code]
599 return ', '.join(ccs)
600
601+ def getOutputCurrency(self, contract):
602+ """
603+ Returns the name of the currency in which the report is displayed
604+ """
605+ data = hasattr(self, 'datas') and getattr(self, 'datas') or {}
606+ if data.get('out_currency'):
607+ currency = self.pool.get('res.currency').read(self.cr, self.uid, data['out_currency'], ['name'])['name']
608+ else:
609+ currency = contract.reporting_currency.name
610+ return currency
611+
612 def getTot(self,o):
613 if self.tot[o]:
614 return self.tot[o]
615@@ -52,10 +64,14 @@
616
617 def getLines(self,contract):
618 pool = pooler.get_pool(self.cr.dbname)
619+ data = hasattr(self, 'datas') and getattr(self, 'datas') or {}
620
621 self.context.update({'mako': True})
622- if 'out_currency' in self.datas:
623- self.context.update({'out_currency': self.datas['out_currency']})
624+ if data.get('out_currency'):
625+ out_currency = data['out_currency']
626+ else:
627+ out_currency = contract.reporting_currency.id
628+ self.context.update({'out_currency': out_currency})
629
630 csv_data = pool.get('wizard.interactive.report')._get_interactive_data(self.cr, self.uid, contract.id, context=self.context)
631
632
633=== modified file 'bin/addons/financing_contract/report/report_project_expenses.py'
634--- bin/addons/financing_contract/report/report_project_expenses.py 2020-10-30 10:04:46 +0000
635+++ bin/addons/financing_contract/report/report_project_expenses.py 2022-06-16 12:50:12 +0000
636@@ -17,7 +17,7 @@
637 self.len1 = 0
638 self.len2 = 0
639 self.lines = {}
640- self.totalRptCurrency = 0
641+ self.totalRptCurrency = {}
642 self.totalBookAmt = 0
643 self.localcontext.update({
644 'getLines':self.getLines,
645@@ -27,7 +27,6 @@
646 'getSub1':self.getSub1,
647 'getSub2':self.getSub2,
648 'getLines2':self.getLines2,
649- 'totalRptCurrency': self.totalRptCurrency,
650 'totalBookAmt':self.totalBookAmt,
651 'getTotalRptCurrency': self.getTotalRptCurrency,
652 'getTotalBookAmt': self.getTotalBookAmt,
653@@ -37,8 +36,8 @@
654 def getTotalBookAmt(self):
655 return self.totalBookAmt
656
657- def getTotalRptCurrency(self):
658- return self.totalRptCurrency
659+ def getTotalRptCurrency(self, contract):
660+ return self.totalRptCurrency.get(contract.id, 0.0)
661
662 def getLines2(self,):
663 return self.lines
664@@ -65,7 +64,9 @@
665 self.len1 += 1
666 self.len2 += 1
667 self.totalBookAmt += analytic_line.amount_currency
668- self.totalRptCurrency += amount
669+ if contract.id not in self.totalRptCurrency:
670+ self.totalRptCurrency[contract.id] = 0.0
671+ self.totalRptCurrency[contract.id] += amount
672 return amount
673
674 def getAccountName(self,analytic_line):
675
676=== modified file 'bin/addons/financing_contract/wizard/wizard_interactive_report.py'
677--- bin/addons/financing_contract/wizard/wizard_interactive_report.py 2018-06-08 12:35:09 +0000
678+++ bin/addons/financing_contract/wizard/wizard_interactive_report.py 2022-06-16 12:50:12 +0000
679@@ -93,9 +93,10 @@
680 contract = contract_obj.browse(cr, uid, contract_id, context=context)
681
682 # Update the context
683- context.update({'reporting_currency': context['out_currency'],
684+ context.update({'reporting_currency_id': contract.reporting_currency.id,
685 'reporting_type': contract.reporting_type,
686- 'currency_table_id': contract.currency_table_id.id})
687+ 'currency_table_id': contract.currency_table_id.id,
688+ 'contract_fx_date': contract.eligibility_from_date})
689
690 header_data = self._get_contract_header(cr, uid, contract, context=context)
691 footer_data = self._get_contract_footer(cr, uid, contract, context=context)
692
693=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
694--- bin/addons/msf_profile/i18n/fr_MF.po 2022-05-25 14:15:34 +0000
695+++ bin/addons/msf_profile/i18n/fr_MF.po 2022-06-16 12:50:12 +0000
696@@ -67285,8 +67285,9 @@
697 msgid "Total Absolute value"
698 msgstr "Valeur absolue totale"
699
700-#. module: msf_budget
701+#. modules: msf_budget, financing_contract
702 #: code:addons/msf_budget/report/report_local_expenses.py:72
703+#: report:addons/financing_contract/report/financing_interactive_xls.mako:408
704 #, python-format
705 msgid "Output currency:"
706 msgstr "Devise d'impression:"
707@@ -68379,6 +68380,12 @@
708 msgid "No File Selected."
709 msgstr "Aucun fichier sélectionné."
710
711+#. module: financing_contract
712+#: code:addons/financing_contract/contract.py:546
713+#, python-format
714+msgid "No contract selected."
715+msgstr "Aucun contrat sélectionné."
716+
717 #. module: kit
718 #: view:kit.mass.import:0
719 msgid "Import log messages"

Subscribers

People subscribed via source and target branches