Merge lp:~julie-w/unifield-server/US-7472 into lp:unifield-server
- US-7472
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5874 |
Proposed branch: | lp:~julie-w/unifield-server/US-7472 |
Merge into: | lp:unifield-server |
Diff against target: |
1141 lines (+301/-194) 26 files modified
bin/addons/account_corrections/wizard/analytic_distribution_wizard.py (+5/-0) bin/addons/account_hq_entries/hq_entries.py (+6/-3) bin/addons/account_hq_entries/wizard/hq_entries_split.py (+4/-1) bin/addons/account_hq_entries/wizard/hq_reallocation.py (+5/-26) bin/addons/account_hq_entries/wizard/wizard_view.xml (+1/-1) bin/addons/account_mcdb/mass_reallocation_search.py (+5/-3) bin/addons/analytic_distribution/account_commitment_view.xml (+1/-1) bin/addons/analytic_distribution/account_move_line.py (+4/-2) bin/addons/analytic_distribution/analytic_account_view.xml (+7/-3) bin/addons/analytic_distribution/analytic_distribution.py (+44/-2) bin/addons/analytic_distribution/analytic_distribution_wizard_view.xml (+1/-1) bin/addons/analytic_distribution/analytic_line.py (+10/-10) bin/addons/analytic_distribution/report/funding_pool.py (+1/-0) bin/addons/analytic_distribution/report/funding_pool.rml (+1/-1) bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py (+13/-25) bin/addons/analytic_distribution/wizard/commitment_analytic_reallocation.py (+5/-26) bin/addons/analytic_override/analytic_account.py (+107/-13) bin/addons/msf_audittrail/audittrail_invoice_data.yml (+1/-1) bin/addons/msf_doc_import/account.py (+3/-3) bin/addons/msf_homere_interface/hr.py (+16/-31) bin/addons/msf_homere_interface/hr_payroll.py (+7/-4) bin/addons/msf_homere_interface/hr_payroll_wizard.xml (+3/-1) bin/addons/msf_homere_interface/wizard/hr_analytic_reallocation.py (+3/-31) bin/addons/msf_profile/i18n/fr_MF.po (+44/-3) bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv (+1/-1) bin/addons/register_accounting/wizard/wizard_cash_return.py (+3/-1) |
To merge this branch: | bzr merge lp:~julie-w/unifield-server/US-7472 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+393177@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/account_corrections/wizard/analytic_distribution_wizard.py' |
2 | --- bin/addons/account_corrections/wizard/analytic_distribution_wizard.py 2020-02-06 16:52:43 +0000 |
3 | +++ bin/addons/account_corrections/wizard/analytic_distribution_wizard.py 2020-11-02 12:53:01 +0000 |
4 | @@ -269,6 +269,11 @@ |
5 | _('The Cost Center %s is not compatible with the Destination %s.') % |
6 | (wiz_line.cost_center_id.code or '', wiz_line.destination_id.code or '')) |
7 | |
8 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, wiz_line.analytic_id.id, wiz_line.cost_center_id.id, context=context): |
9 | + raise osv.except_osv(_('Error'), |
10 | + _('The Cost Center %s is not compatible with the Funding Pool %s.') % |
11 | + (wiz_line.cost_center_id.code or '', wiz_line.analytic_id.code or '')) |
12 | + |
13 | if not wiz_line.distribution_line_id or wiz_line.distribution_line_id.id not in old_line_ids: |
14 | # new distribution line |
15 | #if self.pool.get('account.analytic.account').is_blocked_by_a_contract(cr, uid, [wiz_line.analytic_id.id]): |
16 | |
17 | === modified file 'bin/addons/account_hq_entries/hq_entries.py' |
18 | --- bin/addons/account_hq_entries/hq_entries.py 2019-03-28 13:35:11 +0000 |
19 | +++ bin/addons/account_hq_entries/hq_entries.py 2020-11-02 12:53:01 +0000 |
20 | @@ -106,7 +106,7 @@ |
21 | continue |
22 | if line.analytic_id and not line.destination_id: # CASE 2/ |
23 | # D Check, except B check |
24 | - if line.cost_center_id.id not in [x.id for x in line.analytic_id.cost_center_ids] and line.analytic_id.id != fp_id: |
25 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, line.analytic_id.id, line.cost_center_id.id, context=context): |
26 | res[line.id] = 'invalid' |
27 | logger.notifyChannel('account_hq_entries', netsvc.LOG_WARNING, _('%s: CC (%s) not found in FP (%s)') % (line.id or '', line.cost_center_id.code or '', line.analytic_id.code or '')) |
28 | continue |
29 | @@ -124,7 +124,7 @@ |
30 | logger.notifyChannel('account_hq_entries', netsvc.LOG_WARNING, _('%s: Tuple Account/DEST (%s/%s) not found in FP (%s)') % (line.id or '', line.account_id.code or '', line.destination_id.code or '', line.analytic_id.code or '')) |
31 | continue |
32 | # D Check, except B check |
33 | - if line.cost_center_id.id not in [x.id for x in line.analytic_id.cost_center_ids] and line.analytic_id.id != fp_id: |
34 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, line.analytic_id.id, line.cost_center_id.id, context=context): |
35 | res[line.id] = 'invalid' |
36 | logger.notifyChannel('account_hq_entries', netsvc.LOG_WARNING, _('%s: CC (%s) not found in FP (%s)') % (line.id or '', line.cost_center_id.code or '', line.analytic_id.code or '')) |
37 | continue |
38 | @@ -470,7 +470,10 @@ |
39 | fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
40 | except ValueError: |
41 | fp_id = 0 |
42 | - fields[0].set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', '&', ('cost_center_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), ('id', '=', %s)]" % fp_id) |
43 | + fields[0].set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
44 | + "'|', " |
45 | + "'&', ('fp_compatible_with_cc_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), " |
46 | + "('id', '=', %s)]" % fp_id) |
47 | # Change Destination field |
48 | dest_fields = arch.xpath('field[@name="destination_id"]') |
49 | for field in dest_fields: |
50 | |
51 | === modified file 'bin/addons/account_hq_entries/wizard/hq_entries_split.py' |
52 | --- bin/addons/account_hq_entries/wizard/hq_entries_split.py 2018-08-17 08:28:25 +0000 |
53 | +++ bin/addons/account_hq_entries/wizard/hq_entries_split.py 2020-11-02 12:53:01 +0000 |
54 | @@ -292,7 +292,10 @@ |
55 | arch = etree.fromstring(viewtemp['tree']['arch']) # the analytic_id is found in the line_ids, one level down |
56 | fields = arch.xpath('field[@name="analytic_id"]') |
57 | if fields: |
58 | - fields[0].set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', '&', ('cost_center_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), ('id', '=', %s)]" % fp_id) |
59 | + fields[0].set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view')," |
60 | + "'|', " |
61 | + "'&', ('fp_compatible_with_cc_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), " |
62 | + "('id', '=', %s)]" % fp_id) |
63 | |
64 | # Change Destination field |
65 | dest_fields = arch.xpath('field[@name="destination_id"]') |
66 | |
67 | === modified file 'bin/addons/account_hq_entries/wizard/hq_reallocation.py' |
68 | --- bin/addons/account_hq_entries/wizard/hq_reallocation.py 2019-02-06 09:25:31 +0000 |
69 | +++ bin/addons/account_hq_entries/wizard/hq_reallocation.py 2020-11-02 12:53:01 +0000 |
70 | @@ -51,7 +51,7 @@ |
71 | |
72 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
73 | """ |
74 | - Change funding pool domain in order to include MSF Private fund |
75 | + Adapts domain for AD fields |
76 | """ |
77 | if not context: |
78 | context = {} |
79 | @@ -68,39 +68,18 @@ |
80 | for field in fields: |
81 | field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('id', 'child_of', [%s])]" % oc_id) |
82 | # Change FP field |
83 | - try: |
84 | - fp_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
85 | - except ValueError: |
86 | - fp_id = 0 |
87 | fp_fields = form.xpath('//field[@name="analytic_id"]') |
88 | # Do not use line with account_id, because of NO ACCOUNT_ID PRESENCE! |
89 | for field in fp_fields: |
90 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', ('cost_center_ids', '=', cost_center_id), ('id', '=', %s)]" % fp_id) |
91 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
92 | + "('fp_compatible_with_cc_ids', '=', cost_center_id)]") |
93 | # NO NEED TO CHANGE DESTINATION_ID FIELD because NO ACCOUNT_ID PRESENCE! |
94 | view['arch'] = etree.tostring(form) |
95 | return view |
96 | |
97 | def onchange_cost_center(self, cr, uid, ids, cost_center_id=False, analytic_id=False): |
98 | - """ |
99 | - Check given cost_center with funding pool |
100 | - """ |
101 | - # Prepare some values |
102 | - res = {} |
103 | - if cost_center_id and analytic_id: |
104 | - fp_line = self.pool.get('account.analytic.account').browse(cr, uid, analytic_id) |
105 | - # Search MSF Private Fund element, because it's valid with all accounts |
106 | - try: |
107 | - fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', |
108 | - 'analytic_account_msf_private_funds')[1] |
109 | - except ValueError: |
110 | - fp_id = 0 |
111 | - if cost_center_id not in [x.id for x in fp_line.cost_center_ids] and analytic_id != fp_id: |
112 | - res = {'value': {'analytic_id': False}} |
113 | - elif not cost_center_id: |
114 | - res = {} |
115 | - else: |
116 | - res = {'value': {'analytic_id': False}} |
117 | - return res |
118 | + return self.pool.get('analytic.distribution').\ |
119 | + onchange_ad_cost_center(cr, uid, ids, cost_center_id=cost_center_id, funding_pool_id=analytic_id, fp_field_name='analytic_id') |
120 | |
121 | def button_validate(self, cr, uid ,ids, context=None): |
122 | """ |
123 | |
124 | === modified file 'bin/addons/account_hq_entries/wizard/wizard_view.xml' |
125 | --- bin/addons/account_hq_entries/wizard/wizard_view.xml 2019-01-08 11:20:04 +0000 |
126 | +++ bin/addons/account_hq_entries/wizard/wizard_view.xml 2020-11-02 12:53:01 +0000 |
127 | @@ -51,7 +51,7 @@ |
128 | <field name="destination_id" attrs="{'readonly': [('is_not_ad_correctable', '=', True)]}"/> |
129 | <field name="cost_center_id" attrs="{'readonly': [('is_not_ad_correctable', '=', True)]}"/> |
130 | <field name="analytic_id" attrs="{'readonly': [('is_not_ad_correctable', '=', True)]}" |
131 | - domain="[('type', '!=', 'view'), ('category', '=', 'FUNDING'), ('state', '=', 'open'), ('cost_center_ids', '=', cost_center_id)]" |
132 | + domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('fp_compatible_with_cc_ids', '=', cost_center_id)]" |
133 | string="Funding Pool" |
134 | context="{'search_default_active': 1, 'hide_inactive': 1, 'date': context.get('document_date')}"/> |
135 | <field name="state"/> |
136 | |
137 | === modified file 'bin/addons/account_mcdb/mass_reallocation_search.py' |
138 | --- bin/addons/account_mcdb/mass_reallocation_search.py 2013-10-04 14:54:39 +0000 |
139 | +++ bin/addons/account_mcdb/mass_reallocation_search.py 2020-11-02 12:53:01 +0000 |
140 | @@ -37,8 +37,9 @@ |
141 | context = {} |
142 | if isinstance(ids, (int, long)): |
143 | ids = [ids] |
144 | + analytic_acc_obj = self.pool.get('account.analytic.account') |
145 | # Only process first id |
146 | - account = self.pool.get('account.analytic.account').browse(cr, uid, ids, context=context)[0] |
147 | + account = analytic_acc_obj.browse(cr, uid, ids, context=context)[0] |
148 | if account.category != 'FUNDING': |
149 | raise osv.except_osv(_('Error'), _('This action only works for Funding Pool accounts!')) |
150 | # Take all elements to create a domain |
151 | @@ -58,8 +59,9 @@ |
152 | else: |
153 | # trick to avoid problem with FP that have NO destination link. So we need to search a "False" Destination. |
154 | search.append(('destination_id', '=', 0)) |
155 | - if account.cost_center_ids: |
156 | - search.append(('cost_center_id', 'in', [x.id for x in account.cost_center_ids])) |
157 | + cost_centers = analytic_acc_obj.get_cc_linked_to_fp(cr, uid, account.id, context=context) |
158 | + if cost_centers: |
159 | + search.append(('cost_center_id', 'in', [c.id for c in cost_centers])) |
160 | else: |
161 | # trick to avoid problem with FP that have NO CC. |
162 | search.append(('cost_center_id', '=', 0)) |
163 | |
164 | === modified file 'bin/addons/analytic_distribution/account_commitment_view.xml' |
165 | --- bin/addons/analytic_distribution/account_commitment_view.xml 2020-05-07 08:28:47 +0000 |
166 | +++ bin/addons/analytic_distribution/account_commitment_view.xml 2020-11-02 12:53:01 +0000 |
167 | @@ -204,8 +204,8 @@ |
168 | <field name="arch" type="xml"> |
169 | <form string="Intl Commitments Analytic Reallocation"> |
170 | <group colspan="6" col="6"> |
171 | + <field name="cost_center_id" required="0" on_change="onchange_cost_center(cost_center_id, funding_pool_id)" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
172 | <field name="destination_id" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
173 | - <field name="cost_center_id" required="0" on_change="onchange_cost_center(cost_center_id, funding_pool_id)" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
174 | <field name="funding_pool_id" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
175 | </group> |
176 | <newline/> |
177 | |
178 | === modified file 'bin/addons/analytic_distribution/account_move_line.py' |
179 | --- bin/addons/analytic_distribution/account_move_line.py 2020-02-24 17:11:37 +0000 |
180 | +++ bin/addons/analytic_distribution/account_move_line.py 2020-11-02 12:53:01 +0000 |
181 | @@ -412,6 +412,7 @@ |
182 | context = {} |
183 | if isinstance(ids, (int, long)): |
184 | ids = [ids] |
185 | + ad_obj = self.pool.get('analytic.distribution') |
186 | aml_duplication = '__copy_data_seen' in context and 'account.move.line' in context['__copy_data_seen'] or False |
187 | from_duplication = context.get('copy', False) or aml_duplication |
188 | if context.get('from_je_import', False) or from_duplication: |
189 | @@ -432,7 +433,8 @@ |
190 | vals.update({'destination_id': l.account_id.default_destination_id.id}) |
191 | if l.employee_id.funding_pool_id: |
192 | vals.update({'analytic_id': l.employee_id.funding_pool_id.id}) |
193 | - if vals.get('cost_center_id') not in [cc.id for cc in l.employee_id.funding_pool_id.cost_center_ids]: |
194 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, l.employee_id.funding_pool_id.id, l.employee_id.cost_center_id.id, |
195 | + context=context): |
196 | # Fetch default funding pool: MSF Private Fund |
197 | try: |
198 | msf_fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
199 | @@ -458,7 +460,7 @@ |
200 | to_change = True |
201 | |
202 | if to_change: |
203 | - distrib_id = self.pool.get('analytic.distribution').create(cr, uid, {'name': 'check_employee_analytic_distribution'}) |
204 | + distrib_id = ad_obj.create(cr, uid, {'name': 'check_employee_analytic_distribution'}, context=context) |
205 | vals.update({'distribution_id': distrib_id, 'percentage': 100.0, 'currency_id': l.currency_id.id}) |
206 | # Create funding pool lines |
207 | self.pool.get('funding.pool.distribution.line').create(cr, uid, vals) |
208 | |
209 | === modified file 'bin/addons/analytic_distribution/analytic_account_view.xml' |
210 | --- bin/addons/analytic_distribution/analytic_account_view.xml 2020-01-30 10:18:45 +0000 |
211 | +++ bin/addons/analytic_distribution/analytic_account_view.xml 2020-11-02 12:53:01 +0000 |
212 | @@ -83,9 +83,13 @@ |
213 | <field name="date" select="2"/> |
214 | </page> |
215 | <page string="Cost centers" attrs="{'invisible': [('category', '!=', 'FUNDING')]}"> |
216 | - <button name="button_cc_clear" type="object" string="Remove all" icon="gtk-clear" colspan="1"/> |
217 | + <field name="allow_all_cc_with_fp" colspan="4" |
218 | + on_change="on_change_allow_all_cc_with_fp(allow_all_cc_with_fp, cost_center_ids)"/> |
219 | + <button name="button_cc_clear" type="object" string="Remove all" icon="gtk-clear" colspan="4"/> |
220 | <separator/> |
221 | - <field name="cost_center_ids" nolabel="1" domain="[('type', '!=', 'view'), ('category', '=', 'OC')]"> |
222 | + <field name="cost_center_ids" nolabel="1" colspan="4" |
223 | + domain="[('type', '!=', 'view'), ('category', '=', 'OC')]" |
224 | + on_change="on_change_cc_with_fp(cost_center_ids)"> |
225 | <tree string="Cost Centers" > |
226 | <field name="code"/> |
227 | <field name="name"/> |
228 | @@ -112,7 +116,7 @@ |
229 | <field name="allow_all_cc" colspan="4" on_change="on_change_allow_all_cc(allow_all_cc, dest_cc_ids)"/> |
230 | <button name="button_dest_cc_clear" type="object" string="Remove all" icon="gtk-clear" colspan="4"/> |
231 | <separator/> |
232 | - <field name="dest_cc_ids" nolabel="1" colspan="4" on_change="on_change_dest_cc_ids(dest_cc_ids)"> |
233 | + <field name="dest_cc_ids" nolabel="1" colspan="4" on_change="on_change_cc_ids(dest_cc_ids)"> |
234 | <tree string="Cost Centers"> |
235 | <field name="code"/> |
236 | <field name="name"/> |
237 | |
238 | === modified file 'bin/addons/analytic_distribution/analytic_distribution.py' |
239 | --- bin/addons/analytic_distribution/analytic_distribution.py 2020-01-30 17:08:29 +0000 |
240 | +++ bin/addons/analytic_distribution/analytic_distribution.py 2020-11-02 12:53:01 +0000 |
241 | @@ -44,6 +44,48 @@ |
242 | return False |
243 | return True |
244 | |
245 | + def check_fp_cc_compatibility(self, cr, uid, fp_id, cost_center_id, context=None): |
246 | + """ |
247 | + Checks the compatibility between the FP and the Cost Center (cf. CC tab in the FP form). |
248 | + Returns False if they aren't compatible. |
249 | + |
250 | + If "Allow all Cost Centers" is ticked: only CC linked to the prop. instance of the FP are allowed. |
251 | + """ |
252 | + if context is None: |
253 | + context = {} |
254 | + analytic_acc_obj = self.pool.get('account.analytic.account') |
255 | + ir_model_data_obj = self.pool.get('ir.model.data') |
256 | + res = True |
257 | + if fp_id and cost_center_id: |
258 | + # The Funding Pool PF is compatible with every CC |
259 | + try: |
260 | + pf_id = ir_model_data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
261 | + except ValueError: |
262 | + pf_id = 0 |
263 | + if fp_id != pf_id: |
264 | + fp = analytic_acc_obj.browse(cr, uid, fp_id, |
265 | + fields_to_fetch=['category', 'allow_all_cc_with_fp', 'instance_id', 'cost_center_ids'], |
266 | + context=context) |
267 | + cc = analytic_acc_obj.browse(cr, uid, cost_center_id, fields_to_fetch=['category', 'type', 'cc_instance_ids'], context=context) |
268 | + if fp and cc and fp.category == 'FUNDING' and cc.category == 'OC': |
269 | + if fp.allow_all_cc_with_fp and cc.type != 'view' and fp.instance_id and \ |
270 | + fp.instance_id.id in [inst.id for inst in cc.cc_instance_ids]: |
271 | + res = True |
272 | + elif cc.id in [c.id for c in fp.cost_center_ids]: |
273 | + res = True |
274 | + else: |
275 | + res = False |
276 | + return res |
277 | + |
278 | + def onchange_ad_cost_center(self, cr, uid, ids, cost_center_id=False, funding_pool_id=False, fp_field_name='funding_pool_id'): |
279 | + """ |
280 | + Resets the FP in case the CC selected isn't compatible with it. |
281 | + """ |
282 | + res = {} |
283 | + if cost_center_id and funding_pool_id and not self.check_fp_cc_compatibility(cr, uid, funding_pool_id, cost_center_id): |
284 | + res = {'value': {fp_field_name: False}} |
285 | + return res |
286 | + |
287 | def _get_distribution_state(self, cr, uid, distrib_id, parent_id, account_id, context=None, |
288 | doc_date=False, posting_date=False, manual=False, amount=False): |
289 | """ |
290 | @@ -110,7 +152,7 @@ |
291 | continue |
292 | if (account_id, fp_line.destination_id.id) not in [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in fp_line.analytic_id.tuple_destination_account_ids if not x.disabled]: |
293 | return 'invalid' |
294 | - if fp_line.cost_center_id.id not in [x.id for x in fp_line.analytic_id.cost_center_ids]: |
295 | + if not self.check_fp_cc_compatibility(cr, uid, fp_line.analytic_id.id, fp_line.cost_center_id.id, context=context): |
296 | return 'invalid' |
297 | # Check the date validity of the free accounts used in manual entries |
298 | if manual and doc_date: |
299 | @@ -152,7 +194,7 @@ |
300 | return 'invalid', _('Cost Center not compatible with destination') |
301 | if not is_private_fund: |
302 | # Check that cost center is compatible with FP (except if FP is MSF Private Fund) |
303 | - if cost_center_id not in [x.id for x in fp.cost_center_ids]: |
304 | + if not self.check_fp_cc_compatibility(cr, uid, analytic_id, cost_center_id, context=context): |
305 | return 'invalid', _('Cost Center not compatible with FP') |
306 | # Check that tuple account/destination is compatible with FP (except if FP is MSF Private Fund): |
307 | if (account_id, destination_id) not in [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in fp.tuple_destination_account_ids if not x.disabled]: |
308 | |
309 | === modified file 'bin/addons/analytic_distribution/analytic_distribution_wizard_view.xml' |
310 | --- bin/addons/analytic_distribution/analytic_distribution_wizard_view.xml 2020-02-10 14:51:45 +0000 |
311 | +++ bin/addons/analytic_distribution/analytic_distribution_wizard_view.xml 2020-11-02 12:53:01 +0000 |
312 | @@ -32,7 +32,7 @@ |
313 | <field name="destination_id" on_change="onchange_destination(destination_id, analytic_id, parent.account_id)" |
314 | context="{'search_default_active': 1, 'hide_inactive': 1, 'date': context.get('posting_date')}"/> |
315 | <field name="analytic_id" |
316 | - domain="[('type', '!=', 'view'), ('category', '=', 'FUNDING'), ('state', '=', 'open'), ('cost_center_ids', '=', cost_center_id)]" |
317 | + domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('fp_compatible_with_cc_ids', '=', cost_center_id)]" |
318 | string="Funding Pool" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': context.get('document_date')}"/> |
319 | <field name="percentage" sum="Total Percentage" digits="(16,2)"/> |
320 | <field name="amount" sum="Total Amount"/> |
321 | |
322 | === modified file 'bin/addons/analytic_distribution/analytic_line.py' |
323 | --- bin/addons/analytic_distribution/analytic_line.py 2019-12-12 14:07:37 +0000 |
324 | +++ bin/addons/analytic_distribution/analytic_line.py 2020-11-02 12:53:01 +0000 |
325 | @@ -46,6 +46,7 @@ |
326 | if not args: |
327 | return [] |
328 | res = [] |
329 | + analytic_acc_obj = self.pool.get('account.analytic.account') |
330 | # We just support '=' operator |
331 | for arg in args: |
332 | if not arg[1]: |
333 | @@ -54,9 +55,9 @@ |
334 | raise osv.except_osv(_('Warning'), _('This filter is not implemented yet!')) |
335 | if not arg[2]: |
336 | raise osv.except_osv(_('Warning'), _('Some search args are missing!')) |
337 | - analytic_account = self.pool.get('account.analytic.account').browse(cr, uid, arg[2]) |
338 | + analytic_account = analytic_acc_obj.browse(cr, uid, arg[2], fields_to_fetch=['tuple_destination_account_ids'], context=context) |
339 | tuple_list = [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in analytic_account.tuple_destination_account_ids if not x.disabled] |
340 | - cost_center_ids = [x and x.id for x in analytic_account.cost_center_ids] |
341 | + cost_center_ids = [c.id for c in analytic_acc_obj.get_cc_linked_to_fp(cr, uid, analytic_account.id, context=context)] |
342 | for cc in cost_center_ids: |
343 | for t in tuple_list: |
344 | if res: |
345 | @@ -457,12 +458,10 @@ |
346 | account_id, context=context): |
347 | if aline.account_id and aline.account_id.id == msf_private_fund: |
348 | res.append(aline.id) |
349 | - elif aline.account_id and aline.cost_center_id and aline.account_id.cost_center_ids: |
350 | - if account_id in [x and x.id for x in aline.account_id.cost_center_ids] or aline.account_id.id == msf_private_fund: |
351 | - res.append(aline.id) |
352 | + elif aline.account_id and ad_obj.check_fp_cc_compatibility(cr, uid, aline.account_id.id, account_id, context=context): |
353 | + res.append(aline.id) |
354 | elif account_type == 'FUNDING': |
355 | - fp = self.pool.get('account.analytic.account').read(cr, uid, account_id, ['cost_center_ids', 'tuple_destination_account_ids'], context=context) |
356 | - cc_ids = fp and fp.get('cost_center_ids', []) or [] |
357 | + fp = self.pool.get('account.analytic.account').read(cr, uid, account_id, ['tuple_destination_account_ids'], context=context) |
358 | tuple_destination_account_ids = fp and fp.get('tuple_destination_account_ids', []) or [] |
359 | tuple_list = [x.account_id and x.destination_id and (x.account_id.id, x.destination_id.id) for x in self.pool.get('account.destination.link').browse(cr, uid, tuple_destination_account_ids) if not x.disabled] |
360 | # Browse all analytic line to verify them |
361 | @@ -481,7 +480,9 @@ |
362 | # - the cost_center is in compatible cost center from the new funding pool |
363 | # - the general account is in compatible account/destination tuple |
364 | # - the destination is in compatible account/destination tuple |
365 | - if aline.cost_center_id and aline.cost_center_id.id in cc_ids and aline.general_account_id and aline.destination_id and (aline.general_account_id.id, aline.destination_id.id) in tuple_list: |
366 | + if aline.cost_center_id and ad_obj.check_fp_cc_compatibility(cr, uid, account_id, aline.cost_center_id.id, context=context)\ |
367 | + and aline.general_account_id and aline.destination_id and\ |
368 | + (aline.general_account_id.id, aline.destination_id.id) in tuple_list: |
369 | res.append(aline.id) |
370 | elif account_type == "DEST": |
371 | for aline in self.browse(cr, uid, ids, context=context): |
372 | @@ -541,8 +542,7 @@ |
373 | # check funding pool (expect for MSF Private Fund) |
374 | if not new_fp_id == msf_pf_id: # all OK for MSF Private Fund |
375 | # - cost center and funding pool compatibility |
376 | - cc_ids = [cc.id for cc in new_fp_br.cost_center_ids] |
377 | - if not new_cc_id in cc_ids: |
378 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, new_fp_id, new_cc_id, context=context): |
379 | # not compatible with CC |
380 | res.append((id, entry_sequence, _('CC'))) |
381 | return False |
382 | |
383 | === modified file 'bin/addons/analytic_distribution/report/funding_pool.py' |
384 | --- bin/addons/analytic_distribution/report/funding_pool.py 2019-04-03 13:47:21 +0000 |
385 | +++ bin/addons/analytic_distribution/report/funding_pool.py 2020-11-02 12:53:01 +0000 |
386 | @@ -29,6 +29,7 @@ |
387 | self.localcontext.update({ |
388 | 'locale': locale, |
389 | 'today': self.today, |
390 | + 'all_cc': lambda f: self.pool.get('account.analytic.account').get_cc_linked_to_fp(cr, uid, f, context=context), |
391 | }) |
392 | |
393 | def today(self): |
394 | |
395 | === modified file 'bin/addons/analytic_distribution/report/funding_pool.rml' |
396 | --- bin/addons/analytic_distribution/report/funding_pool.rml 2019-04-17 10:00:14 +0000 |
397 | +++ bin/addons/analytic_distribution/report/funding_pool.rml 2020-11-02 12:53:01 +0000 |
398 | @@ -206,7 +206,7 @@ |
399 | </td> |
400 | </tr> |
401 | <tr> |
402 | - <para style="P17">[[repeatIn(o.cost_center_ids,'line')]]</para> |
403 | + <para style="P17">[[repeatIn(all_cc(o.id), 'line')]]</para> |
404 | <td> |
405 | <para style="P7">[[ line.code or '' ]]</para> |
406 | </td> |
407 | |
408 | === modified file 'bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py' |
409 | --- bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py 2020-07-16 15:42:42 +0000 |
410 | +++ bin/addons/analytic_distribution/wizard/analytic_distribution_wizard.py 2020-11-02 12:53:01 +0000 |
411 | @@ -237,12 +237,18 @@ |
412 | elif (context.get('from_invoice', False) and isinstance(context.get('from_invoice'), int)) or (context.get('from_commitment', False) and isinstance(context.get('from_commitment'), int)) \ |
413 | or (context.get('from_model', False) and isinstance(context.get('from_model'), int)) \ |
414 | or (context.get('from_move', False) and isinstance(context.get('from_move'), int)) \ |
415 | - or (context.get('from_cash_return', False) and isinstance(context.get('from_cash_return'), int)): |
416 | - # Filter is only on cost_center and MSF Private Fund on invoice header |
417 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), ('hide_closed_fp', '=', True), '|', ('cost_center_ids', '=', cost_center_id), ('id', '=', %s)]" % fp_id) |
418 | + or (context.get('from_cash_return', False) and isinstance(context.get('from_cash_return'), int))\ |
419 | + or (context.get('direct_invoice_id', False) and isinstance(context.get('direct_invoice_id'), int)): |
420 | + # Filter is only on cost_centers on invoice header |
421 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
422 | + "('hide_closed_fp', '=', True), ('fp_compatible_with_cc_ids', '=', cost_center_id)]") |
423 | else: |
424 | # Add account_id constraints for invoice lines |
425 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), ('hide_closed_fp', '=', True), '|', '&', ('cost_center_ids', '=', cost_center_id), ('tuple_destination', '=', (parent.account_id, destination_id)), ('id', '=', %s)]" % fp_id) |
426 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
427 | + "('hide_closed_fp', '=', True), " |
428 | + "'|', " |
429 | + "'&', ('fp_compatible_with_cc_ids', '=', cost_center_id), ('tuple_destination', '=', (parent.account_id, destination_id)), " |
430 | + "('id', '=', %s)]" % fp_id) |
431 | # Change Destination field |
432 | dest_fields = tree.xpath('/tree/field[@name="destination_id"]') |
433 | for field in dest_fields: |
434 | @@ -433,31 +439,13 @@ |
435 | return res |
436 | |
437 | def onchange_cost_center(self, cr, uid, ids, cost_center_id=False, analytic_id=False): |
438 | - """ |
439 | - Check given cost_center with funding pool |
440 | - """ |
441 | - # Prepare some values |
442 | - res = {} |
443 | - # Search MSF Private Fund element, because it's valid with all accounts |
444 | - try: |
445 | - fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', |
446 | - 'analytic_account_msf_private_funds')[1] |
447 | - except ValueError: |
448 | - fp_id = 0 |
449 | + return self.pool.get('analytic.distribution').\ |
450 | + onchange_ad_cost_center(cr, uid, ids, cost_center_id=cost_center_id, funding_pool_id=analytic_id, fp_field_name='analytic_id') |
451 | |
452 | - if cost_center_id and analytic_id: |
453 | - fp_line = self.pool.get('account.analytic.account').browse(cr, uid, analytic_id) |
454 | - if cost_center_id not in [x.id for x in fp_line.cost_center_ids] and analytic_id != fp_id: |
455 | - res = {'value': {'analytic_id': False}} |
456 | - elif not cost_center_id \ |
457 | - or analytic_id == fp_id: # PF always compatible: |
458 | - res = {} |
459 | - else: |
460 | - res = {'value': {'analytic_id': False}} |
461 | - return res |
462 | |
463 | analytic_distribution_wizard_fp_lines() |
464 | |
465 | + |
466 | class analytic_distribution_wizard_f1_lines(osv.osv_memory): |
467 | _name = 'analytic.distribution.wizard.f1.lines' |
468 | _description = 'analytic.distribution.wizard.lines' |
469 | |
470 | === modified file 'bin/addons/analytic_distribution/wizard/commitment_analytic_reallocation.py' |
471 | --- bin/addons/analytic_distribution/wizard/commitment_analytic_reallocation.py 2015-02-09 12:53:11 +0000 |
472 | +++ bin/addons/analytic_distribution/wizard/commitment_analytic_reallocation.py 2020-11-02 12:53:01 +0000 |
473 | @@ -38,7 +38,7 @@ |
474 | |
475 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
476 | """ |
477 | - Change funding pool domain in order to include MSF Private fund |
478 | + Adapts domain for AD fields |
479 | """ |
480 | if context is None: |
481 | context = {} |
482 | @@ -55,40 +55,19 @@ |
483 | for field in fields: |
484 | field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('id', 'child_of', [%s])]" % oc_id) |
485 | # Change FP field |
486 | - try: |
487 | - fp_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
488 | - except ValueError: |
489 | - fp_id = 0 |
490 | fp_fields = form.xpath('//field[@name="funding_pool_id"]') |
491 | # Do not use line with account_id, because of NO ACCOUNT_ID PRESENCE! |
492 | for field in fp_fields: |
493 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', ('cost_center_ids', '=', cost_center_id), ('id', '=', %s)]" % fp_id) |
494 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
495 | + "('fp_compatible_with_cc_ids', '=', cost_center_id)]") |
496 | # NO NEED TO CHANGE DESTINATION_ID FIELD because NO ACCOUNT_ID PRESENCE! |
497 | # Apply changes |
498 | view['arch'] = etree.tostring(form) |
499 | return view |
500 | |
501 | def onchange_cost_center(self, cr, uid, ids, cost_center_id=False, funding_pool_id=False): |
502 | - """ |
503 | - Check given cost_center with funding pool |
504 | - """ |
505 | - # Prepare some values |
506 | - res = {} |
507 | - if cost_center_id and funding_pool_id: |
508 | - fp_line = self.pool.get('account.analytic.account').browse(cr, uid, funding_pool_id) |
509 | - # Search MSF Private Fund element, because it's valid with all accounts |
510 | - try: |
511 | - fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', |
512 | - 'analytic_account_msf_private_funds')[1] |
513 | - except ValueError: |
514 | - fp_id = 0 |
515 | - if cost_center_id not in [x.id for x in fp_line.cost_center_ids] and funding_pool_id != fp_id: |
516 | - res = {'value': {'funding_pool_id': False}} |
517 | - elif not cost_center_id: |
518 | - res = {} |
519 | - else: |
520 | - res = {'value': {'funding_pool_id': False}} |
521 | - return res |
522 | + return self.pool.get('analytic.distribution').\ |
523 | + onchange_ad_cost_center(cr, uid, ids, cost_center_id=cost_center_id, funding_pool_id=funding_pool_id) |
524 | |
525 | def button_validate(self, cr, uid ,ids, context=None): |
526 | """ |
527 | |
528 | === modified file 'bin/addons/analytic_override/analytic_account.py' |
529 | --- bin/addons/analytic_override/analytic_account.py 2020-10-09 14:34:01 +0000 |
530 | +++ bin/addons/analytic_override/analytic_account.py 2020-11-02 12:53:01 +0000 |
531 | @@ -290,6 +290,50 @@ |
532 | dom.append(('id', 'in', compatible_dest_ids)) |
533 | return dom |
534 | |
535 | + def _search_fp_compatible_with_cc_ids(self, cr, uid, obj, name, args, context=None): |
536 | + """ |
537 | + Returns a domain with all funding pools compatible with the selected Cost Center |
538 | + E.g.: to get the FPs compatible with the CC 2, use the dom [('fp_compatible_with_cc_ids', '=', 2)] |
539 | + """ |
540 | + dom = [] |
541 | + if context is None: |
542 | + context = {} |
543 | + ir_model_data_obj = self.pool.get('ir.model.data') |
544 | + for arg in args: |
545 | + if arg[0] == 'fp_compatible_with_cc_ids': |
546 | + operator = arg[1] |
547 | + cc_id = arg[2] |
548 | + if operator != '=': |
549 | + raise osv.except_osv(_('Error'), _('Filter not implemented on Funding Pools.')) |
550 | + cc = False |
551 | + if cc_id and isinstance(cc_id, (int, long)): |
552 | + cc = self.browse(cr, uid, cc_id, fields_to_fetch=['category', 'type', 'cc_instance_ids'], context=context) |
553 | + if cc.category != 'OC' or cc.type == 'view': |
554 | + raise osv.except_osv(_('Error'), _('Filter only compatible with a normal-type Cost Center.')) |
555 | + compatible_fp_ids = [] |
556 | + # The Funding Pool PF is compatible with every CC |
557 | + try: |
558 | + pf_id = ir_model_data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
559 | + except ValueError: |
560 | + pf_id = 0 |
561 | + compatible_fp_ids.append(pf_id) |
562 | + if cc: |
563 | + other_fp_ids = self.search(cr, uid, [('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('id', '!=', pf_id)], |
564 | + context=context) |
565 | + for fp in self.browse(cr, uid, other_fp_ids, |
566 | + fields_to_fetch=['allow_all_cc_with_fp', 'instance_id', 'cost_center_ids'], |
567 | + context=context): |
568 | + if fp.allow_all_cc_with_fp and fp.instance_id and fp.instance_id.id in [inst.id for inst in cc.cc_instance_ids]: |
569 | + compatible = True |
570 | + elif cc.id in [c.id for c in fp.cost_center_ids]: |
571 | + compatible = True |
572 | + else: |
573 | + compatible = False |
574 | + if compatible: |
575 | + compatible_fp_ids.append(fp.id) |
576 | + dom.append(('id', 'in', compatible_fp_ids)) |
577 | + return dom |
578 | + |
579 | def _get_cc_instance_ids(self, cr, uid, ids, fields, arg, context=None): |
580 | """ |
581 | Computes the values for fields.function fields, retrieving: |
582 | @@ -299,7 +343,8 @@ |
583 | ...as Cost centre picked for PO/FO reference => po_fo_cc_instance_ids |
584 | (Note that those fields should theoretically always be linked to one single instance, |
585 | but they are set as one2many in order to be consistent with the type of fields used in the related object.) |
586 | - - the Missions where the Cost Center is added to => cc_missions |
587 | + - the Instances where the Cost Center is added to => cc_instance_ids |
588 | + - the related Missions => cc_missions |
589 | """ |
590 | if context is None: |
591 | context = {} |
592 | @@ -311,6 +356,7 @@ |
593 | top_instance_ids = [] |
594 | target_instance_ids = [] |
595 | po_fo_instance_ids = [] |
596 | + all_instance_ids = [] |
597 | missions = set() |
598 | missions_str = "" |
599 | target_cc_ids = acc_target_cc_obj.search(cr, uid, [('cost_center_id', '=', analytic_acc_id)], context=context) |
600 | @@ -318,6 +364,7 @@ |
601 | field_list = ['instance_id', 'is_target', 'is_po_fo_cost_center', 'is_top_cost_center'] |
602 | for target_cc in acc_target_cc_obj.browse(cr, uid, target_cc_ids, fields_to_fetch=field_list, context=context): |
603 | instance = target_cc.instance_id |
604 | + all_instance_ids.append(instance.id) |
605 | if instance.mission: |
606 | missions.add(instance.mission) |
607 | if target_cc.is_top_cost_center: |
608 | @@ -333,6 +380,7 @@ |
609 | 'is_target_cc_instance_ids': target_instance_ids, |
610 | 'po_fo_cc_instance_ids': po_fo_instance_ids, |
611 | 'cc_missions': missions_str, |
612 | + 'cc_instance_ids': all_instance_ids, |
613 | } |
614 | return res |
615 | |
616 | @@ -357,13 +405,18 @@ |
617 | 'dest_cc_ids': fields.many2many('account.analytic.account', 'destination_cost_center_rel', |
618 | 'destination_id', 'cost_center_id', string='Cost Centers', |
619 | domain="[('type', '!=', 'view'), ('category', '=', 'OC')]"), |
620 | - 'allow_all_cc': fields.boolean(string="Allow all Cost Centers"), |
621 | + 'allow_all_cc': fields.boolean(string="Allow all Cost Centers"), # for the Destinations |
622 | + 'allow_all_cc_with_fp': fields.boolean(string="Allow all Cost Centers"), # for the Funding Pools |
623 | 'dest_compatible_with_cc_ids': fields.function(_get_fake, method=True, store=False, |
624 | string='Destinations compatible with the Cost Center', |
625 | type='many2many', relation='account.analytic.account', |
626 | fnct_search=_search_dest_compatible_with_cc_ids), |
627 | 'dest_without_cc': fields.function(_get_dest_without_cc, type='boolean', method=True, store=False, |
628 | string="Destination allowing no Cost Center",), |
629 | + 'fp_compatible_with_cc_ids': fields.function(_get_fake, method=True, store=False, |
630 | + string='Funding Pools compatible with the Cost Center', |
631 | + type='many2many', relation='account.analytic.account', |
632 | + fnct_search=_search_fp_compatible_with_cc_ids), |
633 | 'top_cc_instance_ids': fields.function(_get_cc_instance_ids, method=True, store=False, readonly=True, |
634 | string="Instances having the CC as Top CC", |
635 | type="one2many", relation="msf.instance", multi="cc_instances"), |
636 | @@ -376,12 +429,16 @@ |
637 | 'cc_missions': fields.function(_get_cc_instance_ids, method=True, store=False, readonly=True, |
638 | string="Missions where the CC is added to", |
639 | type='char', multi="cc_instances"), |
640 | + 'cc_instance_ids': fields.function(_get_cc_instance_ids, method=True, store=False, readonly=True, |
641 | + string="Instances where the CC is added to", |
642 | + type="one2many", relation="msf.instance", multi="cc_instances"), |
643 | } |
644 | |
645 | _defaults ={ |
646 | 'date_start': lambda *a: (datetime.today() + relativedelta(months=-3)).strftime('%Y-%m-%d'), |
647 | 'for_fx_gain_loss': lambda *a: False, |
648 | 'allow_all_cc': lambda *a: False, |
649 | + 'allow_all_cc_with_fp': lambda *a: False, |
650 | } |
651 | |
652 | def _check_code_unicity(self, cr, uid, ids, context=None): |
653 | @@ -453,30 +510,40 @@ |
654 | res['domain']['parent_id'] = [('category', '=', category), ('type', '=', 'view')] |
655 | return res |
656 | |
657 | - def on_change_allow_all_cc(self, cr, uid, ids, allow_all_cc, dest_cc_ids, context=None): |
658 | + def on_change_allow_all_cc(self, cr, uid, ids, allow_all_cc, cc_ids, acc_type='destination', field_name='allow_all_cc', context=None): |
659 | """ |
660 | If the user tries to tick the box "Allow all Cost Centers" whereas CC are selected, |
661 | informs him that he has to remove the CC first |
662 | + (acc_type = name of the Analytic Account Type to which the CC are linked, displayed in the warning msg) |
663 | """ |
664 | res = {} |
665 | - if allow_all_cc and dest_cc_ids and dest_cc_ids[0][2]: # e.g. [(6, 0, [1, 2])] |
666 | + if allow_all_cc and cc_ids and cc_ids[0][2]: # e.g. [(6, 0, [1, 2])] |
667 | + # NOTE: the msg is stored in a variable on purpose, otherwise the ".po" translation files would wrongly contain Python code |
668 | + msg = 'Please remove the Cost Centers linked to the %s before ticking this box.' % acc_type.title() |
669 | warning = { |
670 | 'title': _('Warning!'), |
671 | - 'message': _('Please remove the Cost Centers linked to the Destination before ticking this box.') |
672 | + 'message': _(msg) |
673 | } |
674 | res['warning'] = warning |
675 | - res['value'] = {'allow_all_cc': False, } |
676 | + res['value'] = {field_name: False, } |
677 | return res |
678 | |
679 | - def on_change_dest_cc_ids(self, cr, uid, ids, dest_cc_ids, context=None): |
680 | + def on_change_allow_all_cc_with_fp(self, cr, uid, ids, allow_all_cc_with_fp, cost_center_ids, context=None): |
681 | + return self.on_change_allow_all_cc(cr, uid, ids, allow_all_cc_with_fp, cost_center_ids, acc_type='funding pool', |
682 | + field_name='allow_all_cc_with_fp', context=context) |
683 | + |
684 | + def on_change_cc_ids(self, cr, uid, ids, cc_ids, field_name='allow_all_cc', context=None): |
685 | """ |
686 | If at least a CC is selected, unticks the box "Allow all Cost Centers" |
687 | """ |
688 | res = {} |
689 | - if dest_cc_ids and dest_cc_ids[0][2]: # e.g. [(6, 0, [1, 2])] |
690 | - res['value'] = {'allow_all_cc': False, } |
691 | + if cc_ids and cc_ids[0][2]: # e.g. [(6, 0, [1, 2])] |
692 | + res['value'] = {field_name: False, } |
693 | return res |
694 | |
695 | + def on_change_cc_with_fp(self, cr, uid, ids, cost_center_ids, context=None): |
696 | + return self.on_change_cc_ids(cr, uid, ids, cost_center_ids, field_name='allow_all_cc_with_fp', context=context) |
697 | + |
698 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
699 | if not context: |
700 | context = {} |
701 | @@ -539,12 +606,12 @@ |
702 | vals['parent_id'] = funding_pool_parent |
703 | |
704 | def remove_inappropriate_links(self, vals, context=None): |
705 | - ''' |
706 | - Remove relations that are incoherent regarding the category selected. For instance an account with |
707 | - category "Funding Pool" can have associated cost centers, whereas a "Destination" shouldn't. |
708 | + """ |
709 | + Removes relations that are inconsistent regarding the category selected. For instance an account with the |
710 | + category "Funding Pool" can have associated cost centers, whereas a "Cost Center" shouldn't. |
711 | (That would happen if the category is modified after that the relations have been created). |
712 | :return: corrected vals |
713 | - ''' |
714 | + """ |
715 | if context is None: |
716 | context = {} |
717 | if 'category' in vals: |
718 | @@ -555,6 +622,7 @@ |
719 | if vals['category'] != 'FUNDING': |
720 | vals['tuple_destination_account_ids'] = [(6, 0, [])] |
721 | vals['cost_center_ids'] = [(6, 0, [])] |
722 | + vals['allow_all_cc_with_fp'] = False # default value |
723 | return vals |
724 | |
725 | def _check_date(self, vals): |
726 | @@ -720,6 +788,32 @@ |
727 | 'target': 'current', |
728 | } |
729 | |
730 | + def get_cc_linked_to_fp(self, cr, uid, fp_id, context=None): |
731 | + """ |
732 | + Returns a browse record list of all Cost Centers compatible with the Funding Pool in parameter: |
733 | + - if "Allow all Cost Centers" is ticked: all CC linked to the prop. instance of the FP |
734 | + - else all CC selected in the FP form. |
735 | + |
736 | + Note: this method matches with what has been selected in the Cost centers tab of the FP form. |
737 | + It returns an empty list for PF. |
738 | + """ |
739 | + if context is None: |
740 | + context = {} |
741 | + cc_list = [] |
742 | + fp = self.browse(cr, uid, fp_id, |
743 | + fields_to_fetch=['category', 'allow_all_cc_with_fp', 'instance_id', 'cost_center_ids'], |
744 | + context=context) |
745 | + if fp.category == 'FUNDING': |
746 | + if fp.allow_all_cc_with_fp and fp.instance_id: |
747 | + # inactive CC are included on purpose, to match with selectable CC in FP form |
748 | + for cc_id in self.search(cr, uid, [('category', '=', 'OC'), ('type', '!=', 'view')], order='code', context=context): |
749 | + cc = self.browse(cr, uid, cc_id, context=context) |
750 | + if fp.instance_id.id in [inst.id for inst in cc.cc_instance_ids]: |
751 | + cc_list.append(cc) |
752 | + else: |
753 | + cc_list = fp.cost_center_ids or [] |
754 | + return cc_list |
755 | + |
756 | def button_cc_clear(self, cr, uid, ids, context=None): |
757 | self.write(cr, uid, ids, {'cost_center_ids':[(6, 0, [])]}, context=context) |
758 | return True |
759 | |
760 | === modified file 'bin/addons/msf_audittrail/audittrail_invoice_data.yml' |
761 | --- bin/addons/msf_audittrail/audittrail_invoice_data.yml 2019-06-26 10:13:00 +0000 |
762 | +++ bin/addons/msf_audittrail/audittrail_invoice_data.yml 2020-11-02 12:53:01 +0000 |
763 | @@ -259,7 +259,7 @@ |
764 | # Create the rule |
765 | fields = ['state', 'category', 'code', 'complete_name', 'cost_center_ids', 'date', 'date_start', 'name', 'parent_id', |
766 | 'type', 'for_fx_gain_loss', 'instance_id', 'tuple_destination_account_ids', 'description', 'destination_ids', |
767 | - 'dest_cc_ids', 'allow_all_cc'] |
768 | + 'dest_cc_ids', 'allow_all_cc', 'allow_all_cc_with_fp'] |
769 | |
770 | fields_ids = self.pool.get('ir.model.fields').search(cr, uid, [('model', '=' ,'account.analytic.account'), ('name', 'in', fields)], context=context) |
771 | |
772 | |
773 | === modified file 'bin/addons/msf_doc_import/account.py' |
774 | --- bin/addons/msf_doc_import/account.py 2020-06-25 08:27:13 +0000 |
775 | +++ bin/addons/msf_doc_import/account.py 2020-11-02 12:53:01 +0000 |
776 | @@ -519,9 +519,9 @@ |
777 | continue |
778 | # if the Fund. Pool used is NOT "PF" check the compatibility with the (account, dest) and the CC |
779 | if r_fp != msf_fp_id: |
780 | - fp_fields = ['tuple_destination_account_ids', 'cost_center_ids'] |
781 | fp = self.pool.get('account.analytic.account').browse(cr, uid, r_fp, |
782 | - fields_to_fetch=fp_fields, context=context) |
783 | + fields_to_fetch=['tuple_destination_account_ids'], |
784 | + context=context) |
785 | if (account.id, r_destination) not in \ |
786 | [t.account_id and t.destination_id and (t.account_id.id, t.destination_id.id) |
787 | for t in fp.tuple_destination_account_ids if not t.disabled]: |
788 | @@ -530,7 +530,7 @@ |
789 | (current_line_num, line[cols['G/L Account']], line[cols['Destination']], |
790 | line[cols['Funding Pool']])) |
791 | continue |
792 | - if cc.id not in [c.id for c in fp.cost_center_ids]: |
793 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, fp.id, cc.id, context=context): |
794 | errors.append(_('Line %s. The Cost Center %s is not compatible with the Funding Pool %s.') % |
795 | (current_line_num, line[cols['Cost Centre']], line[cols['Funding Pool']])) |
796 | continue |
797 | |
798 | === modified file 'bin/addons/msf_homere_interface/hr.py' |
799 | --- bin/addons/msf_homere_interface/hr.py 2020-09-01 08:22:26 +0000 |
800 | +++ bin/addons/msf_homere_interface/hr.py 2020-11-02 12:53:01 +0000 |
801 | @@ -209,21 +209,26 @@ |
802 | (_check_unicity, "Another employee has the same Identification No.", ['identification_id']), |
803 | ] |
804 | |
805 | - def _check_employe_dest_cc_compatibility(self, cr, uid, employee_id, context=None): |
806 | + def _check_employee_cc_compatibility(self, cr, uid, employee_id, context=None): |
807 | """ |
808 | - Raises an error in case the employee Destination and Cost Center are not compatible |
809 | + Raises an error in case the employee "Destination and Cost Center" or "Funding Pool and Cost Center" are not compatible. |
810 | """ |
811 | if context is None: |
812 | context = {} |
813 | ad_obj = self.pool.get('analytic.distribution') |
814 | - employee_fields = ['destination_id', 'cost_center_id', 'name_resource'] |
815 | + employee_fields = ['destination_id', 'cost_center_id', 'funding_pool_id', 'name_resource'] |
816 | employee = self.browse(cr, uid, employee_id, fields_to_fetch=employee_fields, context=context) |
817 | emp_dest = employee.destination_id |
818 | emp_cc = employee.cost_center_id |
819 | + emp_fp = employee.funding_pool_id |
820 | if emp_dest and emp_cc: |
821 | if not ad_obj.check_dest_cc_compatibility(cr, uid, emp_dest.id, emp_cc.id, context=context): |
822 | raise osv.except_osv(_('Error'), _('Employee %s: the Cost Center %s is not compatible with the Destination %s.') % |
823 | (employee.name_resource, emp_cc.code or '', emp_dest.code or '')) |
824 | + if emp_fp and emp_cc: |
825 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, emp_fp.id, emp_cc.id, context=context): |
826 | + raise osv.except_osv(_('Error'), _('Employee %s: the Cost Center %s is not compatible with the Funding Pool %s.') % |
827 | + (employee.name_resource, emp_cc.code or '', emp_fp.code or '')) |
828 | |
829 | def create(self, cr, uid, vals, context=None): |
830 | """ |
831 | @@ -246,7 +251,7 @@ |
832 | if (not context.get('from', False) or context.get('from') not in ['yaml', 'import']) and not context.get('sync_update_execution', False) and not allow_edition: |
833 | raise osv.except_osv(_('Error'), _('You are not allowed to create a local staff! Please use Import to create local staff.')) |
834 | employee_id = super(hr_employee, self).create(cr, uid, vals, context) |
835 | - self._check_employe_dest_cc_compatibility(cr, uid, employee_id, context=context) |
836 | + self._check_employee_cc_compatibility(cr, uid, employee_id, context=context) |
837 | return employee_id |
838 | |
839 | def write(self, cr, uid, ids, vals, context=None): |
840 | @@ -298,7 +303,7 @@ |
841 | employee_id = super(hr_employee, self).write(cr, uid, emp.id, new_vals, context) |
842 | if employee_id: |
843 | res.append(employee_id) |
844 | - self._check_employe_dest_cc_compatibility(cr, uid, emp.id, context=context) |
845 | + self._check_employee_cc_compatibility(cr, uid, emp.id, context=context) |
846 | return res |
847 | |
848 | def unlink(self, cr, uid, ids, context=None): |
849 | @@ -328,7 +333,7 @@ |
850 | |
851 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
852 | """ |
853 | - Change funding pool domain in order to include MSF Private fund |
854 | + Adapts domain for AD fields |
855 | """ |
856 | if not context: |
857 | context = {} |
858 | @@ -350,36 +355,16 @@ |
859 | dest_field.set('domain', "[('category', '=', 'DEST'), ('type', '!=', 'view'), " |
860 | "('dest_compatible_with_cc_ids', '=', cost_center_id)]") |
861 | # Change FP field |
862 | - try: |
863 | - fp_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
864 | - except ValueError: |
865 | - fp_id = 0 |
866 | - fp_fields = form.xpath('/' + view_type + '//field[@name="funding_pool_id"]') |
867 | + fp_fields = form.xpath('/' + view_type + '//field[@name="funding_pool_id"]') |
868 | for field in fp_fields: |
869 | - field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('state', '=', 'open'), '|', ('cost_center_ids', '=', cost_center_id), ('id', '=', %s)]" % fp_id) |
870 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
871 | + "('fp_compatible_with_cc_ids', '=', cost_center_id)]") |
872 | view['arch'] = etree.tostring(form) |
873 | return view |
874 | |
875 | def onchange_cc(self, cr, uid, ids, cost_center_id=False, funding_pool_id=False): |
876 | - """ |
877 | - Update FP or CC regarding both. |
878 | - """ |
879 | - # Prepare some values |
880 | - vals = {} |
881 | - if not cost_center_id or not funding_pool_id: |
882 | - return {} |
883 | - if cost_center_id and funding_pool_id: |
884 | - fp = self.pool.get('account.analytic.account').browse(cr, uid, funding_pool_id) |
885 | - try: |
886 | - fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
887 | - except ValueError: |
888 | - fp_id = 0 |
889 | - # Exception for MSF Private Fund |
890 | - if funding_pool_id == fp_id: |
891 | - return {} |
892 | - if cost_center_id not in [x.id for x in fp.cost_center_ids]: |
893 | - vals.update({'funding_pool_id': False}) |
894 | - return {'value': vals} |
895 | + return self.pool.get('analytic.distribution').\ |
896 | + onchange_ad_cost_center(cr, uid, ids, cost_center_id=cost_center_id, funding_pool_id=funding_pool_id) |
897 | |
898 | def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): |
899 | |
900 | |
901 | === modified file 'bin/addons/msf_homere_interface/hr_payroll.py' |
902 | --- bin/addons/msf_homere_interface/hr_payroll.py 2019-05-14 15:12:35 +0000 |
903 | +++ bin/addons/msf_homere_interface/hr_payroll.py 2020-11-02 12:53:01 +0000 |
904 | @@ -103,7 +103,7 @@ |
905 | continue |
906 | if line.funding_pool_id and not line.destination_id: # CASE 2/ |
907 | # D Check, except B check |
908 | - if line.cost_center_id.id not in [x.id for x in line.funding_pool_id.cost_center_ids] and line.funding_pool_id.id != fp_id: |
909 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, line.funding_pool_id.id, line.cost_center_id.id, context=context): |
910 | res[line.id] = 'invalid' |
911 | continue |
912 | elif not line.funding_pool_id and line.destination_id: # CASE 3/ |
913 | @@ -118,7 +118,7 @@ |
914 | res[line.id] = 'invalid' |
915 | continue |
916 | # D Check, except B check |
917 | - if line.cost_center_id.id not in [x.id for x in line.funding_pool_id.cost_center_ids] and line.funding_pool_id.id != fp_id: |
918 | + if not ad_obj.check_fp_cc_compatibility(cr, uid, line.funding_pool_id.id, line.cost_center_id.id, context=context): |
919 | res[line.id] = 'invalid' |
920 | continue |
921 | # E Check |
922 | @@ -255,7 +255,7 @@ |
923 | |
924 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
925 | """ |
926 | - Change funding pool domain in order to include MSF Private fund |
927 | + Adapts domain for AD fields |
928 | """ |
929 | if not context: |
930 | context = {} |
931 | @@ -278,7 +278,10 @@ |
932 | fp_id = 0 |
933 | fp_fields = form.xpath('//field[@name="funding_pool_id"]') |
934 | for field in fp_fields: |
935 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', '&', ('cost_center_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), ('id', '=', %s)]" % fp_id) |
936 | + field.set('domain', "[('category', '=', 'FUNDING'), ('type', '!=', 'view'), " |
937 | + "'|', " |
938 | + "'&', ('fp_compatible_with_cc_ids', '=', cost_center_id), ('tuple_destination', '=', (account_id, destination_id)), " |
939 | + " ('id', '=', %s)]" % fp_id) |
940 | # Change Destination field |
941 | dest_fields = form.xpath('//field[@name="destination_id"]') |
942 | for field in dest_fields: |
943 | |
944 | === modified file 'bin/addons/msf_homere_interface/hr_payroll_wizard.xml' |
945 | --- bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2020-02-07 15:20:55 +0000 |
946 | +++ bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2020-11-02 12:53:01 +0000 |
947 | @@ -18,7 +18,9 @@ |
948 | <field name="destination_id" context="{'search_default_active': 1, 'hide_inactive': 1}" |
949 | domain="[('category', '=', 'DEST'), ('type', '!=', 'view'), |
950 | ('dest_compatible_with_cc_ids', '=', cost_center_id)]"/> |
951 | - <field name="funding_pool_id" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
952 | + <field name="funding_pool_id" context="{'search_default_active': 1, 'hide_inactive': 1}" |
953 | + domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), |
954 | + ('fp_compatible_with_cc_ids', '=', cost_center_id)]"/> |
955 | </group> |
956 | <newline/> |
957 | <field name="free1_id" context="{'search_default_active': 1, 'hide_inactive': 1}"/> |
958 | |
959 | === modified file 'bin/addons/msf_homere_interface/wizard/hr_analytic_reallocation.py' |
960 | --- bin/addons/msf_homere_interface/wizard/hr_analytic_reallocation.py 2015-07-22 09:03:35 +0000 |
961 | +++ bin/addons/msf_homere_interface/wizard/hr_analytic_reallocation.py 2020-11-02 12:53:01 +0000 |
962 | @@ -40,7 +40,7 @@ |
963 | |
964 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
965 | """ |
966 | - Change funding pool domain in order to include MSF Private fund |
967 | + Computes the domain for the Cost Center field |
968 | """ |
969 | if not context: |
970 | context = {} |
971 | @@ -56,41 +56,13 @@ |
972 | fields = form.xpath('//field[@name="cost_center_id"]') |
973 | for field in fields: |
974 | field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('id', 'child_of', [%s])]" % oc_id) |
975 | - # Change FP field |
976 | - try: |
977 | - fp_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1] |
978 | - except ValueError: |
979 | - fp_id = 0 |
980 | - fp_fields = form.xpath('//field[@name="funding_pool_id"]') |
981 | - # Do not use line with account_id, because of NO ACCOUNT_ID PRESENCE! |
982 | - for field in fp_fields: |
983 | - field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('category', '=', 'FUNDING'), '|', ('cost_center_ids', '=', cost_center_id), ('id', '=', %s)]" % fp_id) |
984 | - # NO NEED TO CHANGE DESTINATION_ID FIELD because NO ACCOUNT_ID PRESENCE! |
985 | # Apply changes |
986 | view['arch'] = etree.tostring(form) |
987 | return view |
988 | |
989 | def onchange_cost_center(self, cr, uid, ids, cost_center_id=False, funding_pool_id=False): |
990 | - """ |
991 | - Check given cost_center with funding pool |
992 | - """ |
993 | - # Prepare some values |
994 | - res = {} |
995 | - if cost_center_id and funding_pool_id: |
996 | - fp_line = self.pool.get('account.analytic.account').browse(cr, uid, funding_pool_id) |
997 | - # Search MSF Private Fund element, because it's valid with all accounts |
998 | - try: |
999 | - fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', |
1000 | - 'analytic_account_msf_private_funds')[1] |
1001 | - except ValueError: |
1002 | - fp_id = 0 |
1003 | - if cost_center_id not in [x.id for x in fp_line.cost_center_ids] and funding_pool_id != fp_id: |
1004 | - res = {'value': {'funding_pool_id': False}} |
1005 | - elif not cost_center_id: |
1006 | - res = {} |
1007 | - else: |
1008 | - res = {'value': {'funding_pool_id': False}} |
1009 | - return res |
1010 | + return self.pool.get('analytic.distribution').\ |
1011 | + onchange_ad_cost_center(cr, uid, ids, cost_center_id=cost_center_id, funding_pool_id=funding_pool_id) |
1012 | |
1013 | def button_validate(self, cr, uid ,ids, context=None): |
1014 | """ |
1015 | |
1016 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
1017 | --- bin/addons/msf_profile/i18n/fr_MF.po 2020-10-28 17:16:11 +0000 |
1018 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2020-11-02 12:53:01 +0000 |
1019 | @@ -61535,10 +61535,10 @@ |
1020 | msgstr "Le total hors-taxe" |
1021 | |
1022 | #. module: register_accounting |
1023 | -#: code:addons/register_accounting/wizard/wizard_cash_return.py:800 |
1024 | +#: code:addons/register_accounting/wizard/wizard_cash_return.py:824 |
1025 | #, python-format |
1026 | -msgid "All advance lines with account that depends on analytic distribution must have an allocation." |
1027 | -msgstr "All advance lines with account that depends on analytic distribution must have an allocation." |
1028 | +msgid "All advance lines with an account depending on an analytic distribution must have a valid allocation." |
1029 | +msgstr "Toutes les lignes d'avance dont le compte dépend d'une distribution analytique doivent avoir une allocation valide." |
1030 | |
1031 | #. module: stock |
1032 | #: field:product.category,property_stock_account_output_categ:0 |
1033 | @@ -104790,7 +104790,20 @@ |
1034 | msgstr "Filtre non mis en oeuvre sur les Destinations." |
1035 | |
1036 | #. module: analytic_override |
1037 | +#: code:addons/analytic_override/analytic_account.py:307 |
1038 | +#, python-format |
1039 | +msgid "Filter not implemented on Funding Pools." |
1040 | +msgstr "Filtre non mis en oeuvre sur les Funding Pools." |
1041 | + |
1042 | +#. module: analytic_override |
1043 | +#: code:addons/analytic_override/analytic_account.py:312 |
1044 | +#, python-format |
1045 | +msgid "Filter only compatible with a normal-type Cost Center." |
1046 | +msgstr "Filtre compatible uniquement avec un Centre de Coût de type normal." |
1047 | + |
1048 | +#. module: analytic_override |
1049 | #: field:account.analytic.account,allow_all_cc:0 |
1050 | +#: field:account.analytic.account,allow_all_cc_with_fp:0 |
1051 | msgid "Allow all Cost Centers" |
1052 | msgstr "Autoriser tous les Centres de Coût" |
1053 | |
1054 | @@ -104806,17 +104819,34 @@ |
1055 | msgstr "Destinations compatibles avec le Centre de Coût" |
1056 | |
1057 | #. module: analytic_override |
1058 | +#: field:account.analytic.account,fp_compatible_with_cc_ids:0 |
1059 | +msgid "Funding Pools compatible with the Cost Center" |
1060 | +msgstr "Funding Pools compatibles avec le Centre de Coût" |
1061 | + |
1062 | +#. module: analytic_override |
1063 | #: code:addons/analytic_override/analytic_account.py:347 |
1064 | #, python-format |
1065 | msgid "Please remove the Cost Centers linked to the Destination before ticking this box." |
1066 | msgstr "Veuillez supprimer les Centres de Coût liés à la Destination avant de cocher cette case." |
1067 | |
1068 | +#. module: analytic_override |
1069 | +#: code:addons/analytic_override/analytic_account.py:347 |
1070 | +#, python-format |
1071 | +msgid "Please remove the Cost Centers linked to the Funding Pool before ticking this box." |
1072 | +msgstr "Veuillez supprimer les Centres de Coût liés au Funding Pool avant de cocher cette case." |
1073 | + |
1074 | #. module: account_corrections |
1075 | #: code:addons/account_corrections/wizard/analytic_distribution_wizard.py:246 |
1076 | #, python-format |
1077 | msgid "The Cost Center %s is not compatible with the Destination %s." |
1078 | msgstr "Le Centre de Coût %s n'est pas compatible avec la Destination %s." |
1079 | |
1080 | +#. module: account_corrections |
1081 | +#: code:addons/account_corrections/wizard/analytic_distribution_wizard.py:274 |
1082 | +#, python-format |
1083 | +msgid "The Cost Center %s is not compatible with the Funding Pool %s." |
1084 | +msgstr "Le Centre de Coût %s n'est pas compatible avec le Funding Pool %s." |
1085 | + |
1086 | #. module: msf_doc_import |
1087 | #: code:addons/msf_doc_import/account.py:490 |
1088 | #, python-format |
1089 | @@ -105166,6 +105196,12 @@ |
1090 | msgid "Employee %s: the Cost Center %s is not compatible with the Destination %s." |
1091 | msgstr "Employé %s : le Centre de Coût %s n'est pas compatible avec la Destination %s." |
1092 | |
1093 | +#. module: msf_homere_interface |
1094 | +#: code:addons/msf_homere_interface/hr.py:229 |
1095 | +#, python-format |
1096 | +msgid "Employee %s: the Cost Center %s is not compatible with the Funding Pool %s." |
1097 | +msgstr "Employé %s : le Centre de Coût %s n'est pas compatible avec le Funding Pool %s." |
1098 | + |
1099 | #. module: msf_supply_doc_export |
1100 | #: report:po.follow.up_rml:0 |
1101 | msgid "Status:" |
1102 | @@ -109907,6 +109943,11 @@ |
1103 | msgid "Missions where the CC is added to" |
1104 | msgstr "Missions dans lesquelles le CC est ajouté" |
1105 | |
1106 | +#. module: analytic_override |
1107 | +#: field:account.analytic.account,cc_instance_ids:0 |
1108 | +msgid "Instances where the CC is added to" |
1109 | +msgstr "Instances dans lesquelles le CC est ajouté" |
1110 | + |
1111 | #. module: sync_client |
1112 | #: field:sync_client.survey.user,nb_displayed:0 |
1113 | msgid "# Display" |
1114 | |
1115 | === modified file 'bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv' |
1116 | --- bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2020-09-01 08:22:26 +0000 |
1117 | +++ bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2020-11-02 12:53:01 +0000 |
1118 | @@ -26,7 +26,7 @@ |
1119 | msf_sync_data_server.analytical_journal_project,TRUE,TRUE,FALSE,TRUE,bidirectional,Bidirectional,"[('instance_id.level', '=', 'project'),('code','!=','ENGI')]","['code', 'name', 'type','instance_id/id']",MISSION,account.analytic.journal,,Analytical Journal (Project),Valid,,121 |
1120 | msf_sync_data_server.analytical_journal,TRUE,TRUE,FALSE,TRUE,bidirectional,Bidirectional-Private,[],"['code', 'name', 'type','instance_id/id']",OC,account.analytic.journal,instance_id,Analytical Journal,Valid,,122 |
1121 | msf_sync_data_server.link_accounts_destination,TRUE,TRUE,TRUE,TRUE,bidirectional,Down,[],"['account_id/id', 'destination_id/id', 'disabled']",OC,account.destination.link,,Link accounts Destination,Valid,,123 |
1122 | -msf_sync_data_server.funding_pool_to_coordo,TRUE,TRUE,FALSE,TRUE,bidirectional,Bidirectional-Private,"[('category' , '=' , 'FUNDING')]","['category', 'code', 'cost_center_ids/id', 'date', 'date_start', 'description', 'instance_id/id', 'name', 'tuple_destination_account_ids/id', 'type']",HQ + MISSION,account.analytic.account,instance_id,Funding Pool linked to a special coordo,Valid,,124 |
1123 | +msf_sync_data_server.funding_pool_to_coordo,TRUE,TRUE,FALSE,TRUE,bidirectional,Bidirectional-Private,"[('category' , '=' , 'FUNDING')]","['category', 'code', 'cost_center_ids/id', 'date', 'date_start', 'description', 'instance_id/id', 'name', 'tuple_destination_account_ids/id', 'type', 'allow_all_cc_with_fp']",HQ + MISSION,account.analytic.account,instance_id,Funding Pool linked to a special coordo,Valid,,124 |
1124 | msf_sync_data_server.fp_tree0,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"[('category', 'in', ['FREE1', 'FREE2', 'DEST']),('parent_id', '!=', '')]","['parent_id/id', 'instance_id/id']",OC,account.analytic.account,instance_id,"DestF1F2 tree (only F1, F2 and Dest)",Valid,,126 |
1125 | msf_sync_data_server.fp_tree,FALSE,TRUE,TRUE,FALSE,bidirectional,Bidirectional,"[('category', 'in', ['FREE1', 'FREE2', 'DEST']),('parent_id', '!=', '')]",['parent_id/id'],MISSION,account.analytic.account,,"Analytic account tree (only F1, F2 and Dest) – Coordo/Projects only",Valid,,127 |
1126 | msf_sync_data_server.currency_rate,TRUE,TRUE,FALSE,TRUE,bidirectional,Down,"[('rate' , '!=' , ''),('currency_id', '!=', ''), ('currency_id', 'in', ('res.currency', 'id', [('active', 'in', ['t', 'f']), ('currency_table_id', '=', '')]))]","['currency_id/id', 'name', 'rate']",OC,res.currency.rate,,Currency Rate,Valid,,128 |
1127 | |
1128 | === modified file 'bin/addons/register_accounting/wizard/wizard_cash_return.py' |
1129 | --- bin/addons/register_accounting/wizard/wizard_cash_return.py 2020-02-04 13:20:04 +0000 |
1130 | +++ bin/addons/register_accounting/wizard/wizard_cash_return.py 2020-11-02 12:53:01 +0000 |
1131 | @@ -820,7 +820,9 @@ |
1132 | # check if any line with an analytic-a-holic account missing the distribution_id value |
1133 | for st_line in wizard.advance_line_ids: |
1134 | if st_line.account_id.is_analytic_addicted and st_line.analytic_distribution_state != 'valid': |
1135 | - raise osv.except_osv(_('Warning'), _('All advance lines with account that depends on analytic distribution must have an allocation.')) |
1136 | + raise osv.except_osv(_('Warning'), |
1137 | + _('All advance lines with an account depending on an analytic distribution ' |
1138 | + 'must have a valid allocation.')) |
1139 | |
1140 | # Do computation of total_amount of advance return lines |
1141 | self.compute_total_amount(cr, uid, ids, context=context) |