Merge lp:~julie-w/unifield-server/US-7545 into lp:unifield-server
- US-7545
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+424865@code.launchpad.net |
Commit message
Description of the change
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 valid2) 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
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" |