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

Proposed by jftempo
Status: Merged
Merged at revision: 5220
Proposed branch: lp:~julie-w/unifield-server/US-5376
Merge into: lp:unifield-server
Diff against target: 751 lines (+288/-90) (has conflicts)
11 files modified
bin/addons/account_corrections/wizard/journal_items_corrections.py (+31/-4)
bin/addons/account_hq_entries/account_view.xml (+23/-7)
bin/addons/account_hq_entries/hq_entries.py (+48/-11)
bin/addons/account_hq_entries/wizard/hq_entries_import.py (+45/-35)
bin/addons/account_hq_entries/wizard/hq_entries_validation.py (+22/-3)
bin/addons/account_hq_entries/wizard/hq_reallocation.py (+2/-1)
bin/addons/account_hq_entries/wizard/wizard_view.xml (+2/-1)
bin/addons/account_override/__init__.py (+14/-3)
bin/addons/account_override/account.py (+44/-9)
bin/addons/finance/cash_request_view.xml (+12/-12)
bin/addons/msf_profile/i18n/fr_MF.po (+45/-4)
Text conflict in bin/addons/msf_profile/i18n/fr_MF.po
To merge this branch: bzr merge lp:~julie-w/unifield-server/US-5376
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+361908@code.launchpad.net
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/journal_items_corrections.py'
2--- bin/addons/account_corrections/wizard/journal_items_corrections.py 2018-10-11 10:21:46 +0000
3+++ bin/addons/account_corrections/wizard/journal_items_corrections.py 2019-01-31 13:38:39 +0000
4@@ -462,12 +462,38 @@
5 :param account: new account selected in the Correction Wizard
6 :param aml: Journal Item with the Third Party to check
7 """
8+ if context is None:
9+ context = {}
10 acc_obj = self.pool.get('account.account')
11+ employee_obj = self.pool.get('hr.employee')
12+ partner_obj = self.pool.get('res.partner')
13+ journal_obj = self.pool.get('account.journal')
14 acc_type = account.type_for_register
15 if acc_type != 'none':
16+ # get the right Third Party to check if there is a partner_txt ONLY (e.g.: correction made on HQ entry)
17+ partner_txt = aml.partner_txt
18+ partner_id = aml.partner_id and aml.partner_id.id or False
19+ employee_id = aml.employee_id and aml.employee_id.id or False
20+ partner_journal = aml.transfer_journal_id
21+ if partner_txt and not partner_id and not employee_id and not partner_journal:
22+ employee_ids = employee_obj.search(cr, uid, [('name', '=', partner_txt)], limit=1, context=context)
23+ if employee_ids:
24+ employee_id = employee_ids[0]
25+ else:
26+ partner_ids = partner_obj.search(cr, uid, [('name', '=', partner_txt), ('active', 'in', ['t', 'f'])],
27+ limit=1, context=context)
28+ if partner_ids:
29+ partner_id = partner_ids[0]
30+ else:
31+ journal_ids = journal_obj.search(cr, uid, [('code', '=', partner_txt)], limit=1, context=context)
32+ if journal_ids:
33+ partner_journal = journal_obj.browse(cr, uid, journal_ids[0], context=context)
34+ # if there is a partner_txt but no related Third Party found:
35+ # ignore the check if "ignore_non_existing_tp" is in context (e.g. when validating HQ entries)
36+ if not partner_id and not employee_id and not partner_journal and context.get('ignore_non_existing_tp', False):
37+ return True
38 # Check the compatibility with the "Type For Specific Treatment" of the account
39 if acc_type in ['transfer', 'transfer_same']:
40- partner_journal = aml.transfer_journal_id
41 is_liquidity = partner_journal and partner_journal.type in ['cash', 'bank', 'cheque'] and partner_journal.currency
42 if acc_type == 'transfer_same' and (not is_liquidity or partner_journal.currency.id != aml.currency_id.id):
43 raise osv.except_osv(_('Warning'),
44@@ -477,13 +503,13 @@
45 raise osv.except_osv(_('Warning'),
46 _('The account "%s - %s" is only compatible with a Liquidity Journal Third Party\n'
47 'having a currency different from the booking one.') % (account.code, account.name))
48- elif acc_type == 'advance' and not aml.employee_id:
49+ elif acc_type == 'advance' and not employee_id:
50 raise osv.except_osv(_('Warning'), _('The account "%s - %s" is only compatible '
51 'with an Employee Third Party.') % (account.code, account.name))
52- elif acc_type == 'down_payment' and not aml.partner_id:
53+ elif acc_type == 'down_payment' and not partner_id:
54 raise osv.except_osv(_('Warning'), _('The account "%s - %s" is only compatible '
55 'with a Partner Third Party.') % (account.code, account.name))
56- elif acc_type == 'payroll' and not aml.partner_id and not aml.employee_id:
57+ elif acc_type == 'payroll' and not partner_id and not employee_id:
58 raise osv.except_osv(_('Warning'), _('The account "%s - %s" is only compatible '
59 'with a Partner or an Employee Third Party.') % (account.code, account.name))
60 else:
61@@ -492,6 +518,7 @@
62 acc_obj.is_allowed_for_thirdparty(cr, uid, [account.id], partner_type=aml.partner_type or False, partner_txt=aml.partner_txt or False,
63 employee_id=aml.employee_id or False, transfer_journal_id=aml.transfer_journal_id or False,
64 partner_id=aml.partner_id or False, raise_it=True, context=context)
65+ return True
66
67 def correct_manually(self, cr, uid, ids, context=None):
68 """
69
70=== modified file 'bin/addons/account_hq_entries/account_view.xml'
71--- bin/addons/account_hq_entries/account_view.xml 2018-08-17 08:28:25 +0000
72+++ bin/addons/account_hq_entries/account_view.xml 2019-01-31 13:38:39 +0000
73@@ -9,20 +9,36 @@
74 <field name="type">tree</field>
75 <field name="arch" type="xml">
76 <tree string="HQ Entries List" editable="top" noteditable="user_validated==True or is_original==True" hide_new_button="1" colors="black: analytic_state=='valid' and is_split==True;blue:analytic_state in ('valid') and is_original==False and is_split==False;gray:is_original==True;red:analytic_state in ('invalid')" limit="50">
77+ <field name="current_instance_level" invisible="1"/>
78+ <field name="account_user_type_code" invisible="1"/>
79 <field name="name"/>
80- <field name="ref"/>
81+ <field name="ref" attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
82 <field name="document_date"/>
83 <field name="date"/>
84 <field name="period_id"/>
85- <field name="account_id" domain="[('type', '!=', 'view'), ('restricted_area', '=', 'hq_lines'), ('is_not_hq_correctible', '=', False), ('filter_active', '=', True)]" context="{'date': date}"/>
86+ <field name="account_id"
87+ domain="[('restricted_area', '=', 'hq_lines_correction'), ('filter_active', '=', True)]"
88+ context="{'date': date}"
89+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
90 <field name="partner_txt"/>
91 <field name="amount"/>
92 <field name="currency_id"/>
93- <field name="destination_id" on_change="onchange_destination(destination_id, analytic_id, account_id)" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"/>
94- <field name="cost_center_id" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"/>
95- <field name="analytic_id" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': document_date}"/>
96- <field name="free_1_id" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"/>
97- <field name="free_2_id" context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"/>
98+ <field name="destination_id"
99+ on_change="onchange_destination(destination_id, analytic_id, account_id)"
100+ context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"
101+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
102+ <field name="cost_center_id"
103+ context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"
104+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
105+ <field name="analytic_id"
106+ context="{'search_default_active': 1, 'hide_inactive': 1, 'date': document_date}"
107+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
108+ <field name="free_1_id"
109+ context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"
110+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
111+ <field name="free_2_id"
112+ context="{'search_default_active': 1, 'hide_inactive': 1, 'date': date}"
113+ attrs="{'readonly': ['|', ('current_instance_level', '=', 'section'), ('account_user_type_code', 'not in', ['expense', 'income'])]}"/>
114 <field name="user_validated" invisible="1"/>
115 <field name="analytic_state" invisible="1"/>
116 <field name="is_original" invisible="1"/>
117
118=== modified file 'bin/addons/account_hq_entries/hq_entries.py'
119--- bin/addons/account_hq_entries/hq_entries.py 2018-08-17 10:08:35 +0000
120+++ bin/addons/account_hq_entries/hq_entries.py 2019-01-31 13:38:39 +0000
121@@ -67,8 +67,8 @@
122 for line in self.browse(cr, uid, ids, context=context):
123 res[line.id] = 'valid' # by default
124 #### SOME CASE WHERE DISTRO IS OK
125- # if account is not expense, so it's valid
126- if line.account_id and line.account_id.user_type_code and line.account_id.user_type_code != 'expense':
127+ # if it's neither an expense nor an income account, the AD is valid
128+ if line.account_id and line.account_id.user_type_code not in ['expense', 'income']:
129 continue
130 # Date checks
131 # F Check
132@@ -176,18 +176,45 @@
133 account_obj = self.pool.get('account.account')
134
135 for r in self.browse(cr, uid, ids, context=context):
136- res[r.id] = True
137+ is_compatible = True
138 if r.account_id:
139- res[r.id] = account_obj.is_allowed_for_thirdparty(cr, uid,
140- r.account_id.id, partner_txt=r.partner_txt or False,
141- context=context)[r.account_id.id]
142+ # check the Allowed Partner Types
143+ is_compatible = account_obj.is_allowed_for_thirdparty(cr, uid, r.account_id.id,
144+ partner_txt=r.partner_txt or False,
145+ context=context)[r.account_id.id]
146+ # if the partner type compatibility is OK: also check the "Type for specific treatment"
147+ if is_compatible:
148+ # will raise an error if the Third Party exists in Unifield, and isn't compatible with the account
149+ context.update({'ignore_non_existing_tp': True})
150+ account_obj.check_type_for_specific_treatment(cr, uid, r.account_id.id,
151+ partner_txt=r.partner_txt or False,
152+ currency_id=r.currency_id.id,
153+ context=context)
154+
155+ res[r.id] = is_compatible
156 return res
157
158+ def _get_current_instance_level(self, cr, uid, ids, name, args, context=None):
159+ """
160+ Returns a String with the level of the current instance (section, coordo, project)
161+ """
162+ if context is None:
163+ context = {}
164+ levels = {}
165+ user_obj = self.pool.get('res.users')
166+ company = user_obj.browse(cr, uid, uid, fields_to_fetch=['company_id'], context=context).company_id
167+ level = company.instance_id and company.instance_id.level or ''
168+ for hq_entry_id in ids:
169+ levels[hq_entry_id] = level
170+ return levels
171+
172 _columns = {
173 'account_id': fields.many2one('account.account', "Account", required=True),
174- 'destination_id': fields.many2one('account.analytic.account', string="Destination", required=True, domain="[('category', '=', 'DEST'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
175+ 'account_user_type_code': fields.related('account_id', 'user_type_code', string="Account Type",
176+ type='char', size=32, readonly=True, store=False),
177+ 'destination_id': fields.many2one('account.analytic.account', string="Destination", domain="[('category', '=', 'DEST'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
178 'cost_center_id': fields.many2one('account.analytic.account', "Cost Center", required=False, domain="[('category','=','OC'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
179- 'analytic_id': fields.many2one('account.analytic.account', "Funding Pool", required=True, domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
180+ 'analytic_id': fields.many2one('account.analytic.account', "Funding Pool", domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
181 'free_1_id': fields.many2one('account.analytic.account', "Free 1", domain="[('category', '=', 'FREE1'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
182 'free_2_id': fields.many2one('account.analytic.account', "Free 2", domain="[('category', '=', 'FREE2'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
183 'user_validated': fields.boolean("User validated?", help="Is this line validated by a user in a OpenERP field instance?", readonly=True),
184@@ -201,8 +228,8 @@
185 'amount': fields.float('Amount', readonly=True),
186 'account_id_first_value': fields.many2one('account.account', "Account @import", required=True, readonly=True),
187 'cost_center_id_first_value': fields.many2one('account.analytic.account', "Cost Center @import", required=False, readonly=False),
188- 'analytic_id_first_value': fields.many2one('account.analytic.account', "Funding Pool @import", required=True, readonly=True),
189- 'destination_id_first_value': fields.many2one('account.analytic.account', "Destination @import", required=True, readonly=True),
190+ 'analytic_id_first_value': fields.many2one('account.analytic.account', "Funding Pool @import", readonly=True),
191+ 'destination_id_first_value': fields.many2one('account.analytic.account', "Destination @import", readonly=True),
192 'analytic_state': fields.function(_get_analytic_state, type='selection', method=True, readonly=True, string="Distribution State",
193 selection=[('none', 'None'), ('valid', 'Valid'), ('invalid', 'Invalid')], help="Give analytic distribution state"),
194 'is_original': fields.boolean("Is Original HQ Entry?", help="This line was split into other one.", readonly=True),
195@@ -212,6 +239,8 @@
196 'cc_changed': fields.function(_get_cc_changed, method=True, type='boolean', string='Have Cost Center changed?', help="When you change the cost center from the initial value (from a HQ Entry or a Split line), so the Cost Center changed is True."),
197 'account_changed': fields.function(_get_account_changed, method=True, type='boolean', string='Have account changed?', help="When your entry have a different account from the initial one or from the original one."),
198 'is_account_partner_compatible': fields.function(_get_is_account_partner_compatible, method=True, type='boolean', string='Account and partner compatible ?'),
199+ 'current_instance_level': fields.function(_get_current_instance_level, method=True, type='char',
200+ string='Current Instance Level', store=False, readonly=True),
201 }
202
203 _defaults = {
204@@ -565,8 +594,9 @@
205 # US-306: forbid to validate mission closed or + entries
206 # => at coordo level you can not validate entries since field closed
207 # period; but they can come from HQ mission opened via SYNC)
208+ hq_entries = self.browse(cr, uid, ids, context=context)
209 period_ids = list(set([ he.period_id.id \
210- for he in self.browse(cr, uid, ids, context=context) ]))
211+ for he in hq_entries ]))
212 # warning if an HQ Entry is in a non-opened period
213 if period_ids:
214 periods = self.pool.get("account.period").browse(cr, uid, period_ids, context)
215@@ -578,6 +608,13 @@
216 elif p.number == 12 and not self._is_dec_period_open(cr, uid, context):
217 raise mission_closed_except
218
219+ # block edition and split on B/S entries
220+ if wizard_model in ['hq.entries.split', 'hq.analytic.reallocation', 'hq.reallocation']:
221+ for hq_entry in hq_entries:
222+ if hq_entry.account_id.user_type_code not in ['expense', 'income']:
223+ raise osv.except_osv(_("Warning"),
224+ _("You can not perform this action on a B/S line."))
225+
226 def check_ad_change_allowed(self, cr, uid, ids, vals, context=None):
227 """
228 Raises a warning if the HQ entry Analytic Distribution is about to be modified although the general account is
229
230=== modified file 'bin/addons/account_hq_entries/wizard/hq_entries_import.py'
231--- bin/addons/account_hq_entries/wizard/hq_entries_import.py 2018-08-17 08:28:25 +0000
232+++ bin/addons/account_hq_entries/wizard/hq_entries_import.py 2019-01-31 13:38:39 +0000
233@@ -105,7 +105,7 @@
234 account_code = account_data and account_data[0] or False
235 if not account_code:
236 raise osv.except_osv(_('Error'), _('No account code found!'))
237- account_ids = acc_obj.search(cr, uid, [('code', '=', account_code)] + ACCOUNT_RESTRICTED_AREA['hq_lines'])
238+ account_ids = acc_obj.search(cr, uid, [('code', '=', account_code)] + ACCOUNT_RESTRICTED_AREA['hq_lines_import'])
239 if not account_ids:
240 raise osv.except_osv(_('Error'), _('Account code %s doesn\'t exist or is not allowed in HQ Entries!') % (account_code,))
241
242@@ -115,14 +115,24 @@
243 vals.update({'account_id': account_ids[0], 'account_id_first_value': account_ids[0]})
244 else:
245 raise osv.except_osv(_('Error'), _('No account code found!'))
246- # Retrieve Destination
247 aa_check_ids = []
248 destination_id = False
249+ fp_id = False
250+ free1_id = False
251+ free2_id = False
252 account = acc_obj.browse(cr, uid, account_ids[0])
253- if account.user_type.code == 'expense':
254+ if not cost_center:
255+ # CC is needed for synchro (and usually it can't be added after the import in HQ because of the user rights)
256+ raise osv.except_osv(_('Error'), _('Cost Center is missing for the account %s.') % (account_description,))
257+ if account.user_type.code not in ['expense', 'income']: # B/S accounts
258+ if destination or funding_pool or free1 or free2:
259+ raise osv.except_osv(_('Error'), _('The B/S account %s cannot have an Analytic Distribution. '
260+ 'Only a Cost Center should be given.') % (account_description,))
261+ else: # expense or income accounts
262+ # Retrieve Destination
263 # Set default destination
264 if not account.default_destination_id:
265- raise osv.except_osv(_('Warning'), _('No default Destination defined for expense account: %s') % (account.code or '',))
266+ raise osv.except_osv(_('Warning'), _('No default Destination defined for account: %s') % (account.code or '',))
267 destination_id = account.default_destination_id and account.default_destination_id.id or False
268 # But use those from CSV file if given
269 if destination:
270@@ -133,7 +143,34 @@
271 raise osv.except_osv(_('Error'), _('Destination "%s" doesn\'t exist!') % (destination,))
272 if destination_id:
273 aa_check_ids.append(destination_id)
274- # Retrieve Cost Center and Funding Pool
275+ # Retrieve Funding Pool
276+ if funding_pool:
277+ fp_id = anacc_obj.search(cr, uid, ['|', ('code', '=', funding_pool), ('name', '=', funding_pool), ('category', '=', 'FUNDING')])
278+ if not fp_id:
279+ raise osv.except_osv(_('Error'), _('Funding Pool "%s" doesn\'t exist!') % (funding_pool,))
280+ fp_id = fp_id[0]
281+ else:
282+ try:
283+ fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
284+ except ValueError:
285+ fp_id = 0
286+ if fp_id:
287+ aa_check_ids.append(fp_id)
288+ # Retrieve Free 1 / Free 2
289+ if free1:
290+ free1_id = anacc_obj.search(cr, uid, ['|', ('code', '=', free1), ('name', '=', free1), ('category', '=', 'FREE1')])
291+ if not free1_id:
292+ raise osv.except_osv(_('Error'), _('Free 1 "%s" doesn\'t exist!') % (free1,))
293+ free1_id = free1_id[0]
294+ aa_check_ids.append(free1_id)
295+ if free2:
296+ free2_id = anacc_obj.search(cr, uid, ['|', ('code', '=', free2), ('name', '=', free2), ('category', '=', 'FREE2')])
297+ if not free2_id:
298+ raise osv.except_osv(_('Error'), _('Free 2 "%s" doesn\'t exist!') % (free2,))
299+ free2_id = free2_id[0]
300+ aa_check_ids.append(free2_id)
301+
302+ # Retrieve Cost Center
303 cc_id = False
304 if cost_center:
305 cc_id = anacc_obj.search(cr, uid, ['|', ('code', '=', cost_center), ('name', '=', cost_center), ('category', '=', 'OC')])
306@@ -142,35 +179,7 @@
307 cc_id = cc_id[0]
308 if cc_id:
309 aa_check_ids.append(cc_id)
310- # Retrieve Funding Pool
311- if funding_pool:
312- fp_id = anacc_obj.search(cr, uid, ['|', ('code', '=', funding_pool), ('name', '=', funding_pool), ('category', '=', 'FUNDING')])
313- if not fp_id:
314- raise osv.except_osv(_('Error'), _('Funding Pool "%s" doesn\'t exist!') % (funding_pool,))
315- fp_id = fp_id[0]
316- else:
317- try:
318- fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
319- except ValueError:
320- fp_id = 0
321- if fp_id:
322- aa_check_ids.append(fp_id)
323
324- # Retrive Free 1 / Free 2
325- free1_id = False
326- free2_id = False
327- if free1:
328- free1_id = anacc_obj.search(cr, uid, ['|', ('code', '=', free1), ('name', '=', free1), ('category', '=', 'FREE1')])
329- if not free1_id:
330- raise osv.except_osv(_('Error'), _('Free 1 "%s" doesn\'t exist!') % (free1,))
331- free1_id = free1_id[0]
332- aa_check_ids.append(free1_id)
333- if free2:
334- free2_id = anacc_obj.search(cr, uid, ['|', ('code', '=', free2), ('name', '=', free2), ('category', '=', 'FREE2')])
335- if not free2_id:
336- raise osv.except_osv(_('Error'), _('Free 2 "%s" doesn\'t exist!') % (free2,))
337- free2_id = free2_id[0]
338- aa_check_ids.append(free2_id)
339 vals.update({'destination_id_first_value': destination_id, 'destination_id': destination_id, 'cost_center_id': cc_id, 'analytic_id': fp_id, 'cost_center_id_first_value': cc_id, 'analytic_id_first_value': fp_id, 'free_1_id': free1_id, 'free_2_id': free2_id,})
340
341 # [utp-928] do not import line with a
342@@ -187,12 +196,13 @@
343 if aa_check_ids:
344 for aa_r in anacc_obj.read(cr, uid, aa_check_ids,
345 ['code', 'name', 'type', 'category']):
346- if aa_r['type'] and aa_r['type'] == 'view':
347+ if aa_r['type'] and aa_r['type'] == 'view' and account.user_type_code in ['expense', 'income']:
348 category = ''
349 if aa_r['category']:
350 if aa_r['category'] in aa_check_category_map:
351 category += aa_check_category_map[aa_r['category']] + ' '
352- aa_check_errors.append('%s"%s - %s" of type "view" is not allowed for import' % (category, aa_r['code'], aa_r['name']))
353+ aa_check_errors.append(_('%s "%s - %s" of type "view" is not allowed '
354+ 'for the account "%s - %s"') % (category, aa_r['code'], aa_r['name'], account.code, account.name))
355 if aa_check_errors:
356 raise osv.except_osv(_('Error'), ", ".join(aa_check_errors))
357
358
359=== modified file 'bin/addons/account_hq_entries/wizard/hq_entries_validation.py'
360--- bin/addons/account_hq_entries/wizard/hq_entries_validation.py 2018-05-28 10:19:58 +0000
361+++ bin/addons/account_hq_entries/wizard/hq_entries_validation.py 2019-01-31 13:38:39 +0000
362@@ -176,9 +176,12 @@
363 for line in hqentries_obj.browse(cr, uid, ids, context=context):
364 if not line.account_id_first_value:
365 raise osv.except_osv(_('Error'), _('An account is missing!'))
366- # create new distribution (only for expense accounts)
367+ # create new distribution (only for expense or income accounts)
368 line_account = split and line.account_id or line.account_id_first_value
369- distrib_id = self.create_distribution_id(cr, uid, currency_id, line, line_account, split=split)
370+ if line_account.user_type_code in ['income', 'expense']:
371+ distrib_id = self.create_distribution_id(cr, uid, currency_id, line, line_account, split=split)
372+ else:
373+ distrib_id = False
374 vals = {
375 'account_id': line_account.id,
376 'period_id': period_id,
377@@ -316,7 +319,7 @@
378 # Create also the AD from the original line and update it into the counterpart move
379 if not line.account_id_first_value:
380 raise osv.except_osv(_('Error'), _('An account is missing!'))
381- # create new distribution (only for expense accounts)
382+ # create new distribution
383 distrib_id = self.create_distribution_id(cr, uid, line.currency_id.id, line, line.account_id_first_value)
384 aml_obj.write(cr, uid, counterpart_id, {
385 'reversal': True,
386@@ -460,6 +463,22 @@
387 elif line.cost_center_id.id != line.cost_center_id_first_value.id or line.destination_id.id != line.destination_id_first_value.id:
388 if line.cost_center_id_first_value and line.cost_center_id_first_value.id:
389 cc_change.append(line)
390+ if line in account_change or line in cc_account_change:
391+ # non-correctable accounts should neither be corrected nor used in the correction lines
392+ non_correctable_account = (line.account_id_first_value.is_not_hq_correctible and line.account_id_first_value) or \
393+ (line.account_id.is_not_hq_correctible and line.account_id) or False
394+ if non_correctable_account:
395+ raise osv.except_osv(_('Warning'), _('The account %s - %s should neither be corrected nor be used in '
396+ 'correction lines.') % (non_correctable_account.code,
397+ non_correctable_account.name))
398+ if line in cc_change or line in cc_account_change:
399+ # accounts "non correctable on AD" should neither be corrected on AD nor used in the AD corr. lines
400+ ad_non_correctable_account = (line.account_id_first_value.is_not_ad_correctable and line.account_id_first_value) or \
401+ (line.account_id.is_not_ad_correctable and line.account_id) or False
402+ if ad_non_correctable_account:
403+ raise osv.except_osv(_('Warning'), _('The account %s - %s should not be used in '
404+ 'AD corrections.') % (ad_non_correctable_account.code,
405+ ad_non_correctable_account.name))
406 all_lines = {}
407 for currency in to_write:
408 for period in to_write[currency]:
409
410=== modified file 'bin/addons/account_hq_entries/wizard/hq_reallocation.py'
411--- bin/addons/account_hq_entries/wizard/hq_reallocation.py 2015-05-27 15:54:46 +0000
412+++ bin/addons/account_hq_entries/wizard/hq_reallocation.py 2019-01-31 13:38:39 +0000
413@@ -138,7 +138,8 @@
414 _description = 'HQ reallocation wizard'
415
416 _columns = {
417- 'account_id': fields.many2one('account.account', string="Account", required=True, domain="[('type', '!=', 'view'), ('user_type.code', '=', 'expense')]"),
418+ 'account_id': fields.many2one('account.account', string="Account", required=True,
419+ domain="[('restricted_area', '=', 'hq_lines_correction')]"),
420 }
421
422 def default_get(self, cr, uid, fields, context=None):
423
424=== modified file 'bin/addons/account_hq_entries/wizard/wizard_view.xml'
425--- bin/addons/account_hq_entries/wizard/wizard_view.xml 2018-08-17 08:28:25 +0000
426+++ bin/addons/account_hq_entries/wizard/wizard_view.xml 2019-01-31 13:38:39 +0000
427@@ -45,7 +45,8 @@
428 <field name="account_hq_correctible" invisible="1"/>
429 <field name="is_not_ad_correctable" invisible="1"/>
430 <field name="account_id" attrs="{'readonly': [('account_hq_correctible', '=', True)]}"
431- domain="[('type', '!=', 'view'), ('restricted_area', '=', 'hq_lines'), ('is_not_hq_correctible', '=', False), ('filter_active', '=', True)]" />
432+ domain="[('restricted_area', '=', 'hq_lines_correction'), ('filter_active', '=', True)]"
433+ />
434 <field name="amount"/>
435 <field name="destination_id" attrs="{'readonly': [('is_not_ad_correctable', '=', True)]}"/>
436 <field name="cost_center_id" attrs="{'readonly': [('is_not_ad_correctable', '=', True)]}"/>
437
438=== modified file 'bin/addons/account_override/__init__.py'
439--- bin/addons/account_override/__init__.py 2018-08-27 14:53:15 +0000
440+++ bin/addons/account_override/__init__.py 2019-01-31 13:38:39 +0000
441@@ -138,12 +138,23 @@
442 ('accrual_account', '=', True),
443 ],
444 # HQ ENTRIES
445- 'hq_lines': [
446+ # /!\ The accounts allowed at import are different from the ones allowed for correction
447+ 'hq_lines_import': [
448 ('type', '!=', 'view'),
449- ('user_type_code', '=', 'expense'),
450- '|', ('user_type_code', '!=', 'expense'), ('user_type.report_type', '!=', 'none'), # Exclude non-extra accounting expense accounts
451+ '|', ('user_type_code', '!=', 'expense'), ('user_type.report_type', '!=', 'none'), # Exclude extra-accounting expense accounts
452+ ('type_for_register', '!=', 'donation'),
453 #('is_not_hq_correctible', '=', False), # UF-2312: not possibleto add this domain because WE SHOULD ALLOW "Not HQ Correctible" account during the import
454 ],
455+ 'hq_lines_correction': [
456+ ('type', '!=', 'view'),
457+ ('type_for_register', '!=', 'donation'),
458+ ('is_not_hq_correctible', '=', False),
459+ '|',
460+ ('user_type.code', '=', 'income'),
461+ '&', ('user_type.code', '=', 'expense'), ('user_type.report_type', '!=', 'none'), # Exclude extra-accounting expense accounts
462+ # note : filter_active isn't set to True here as that would prevent to "Change Account" to an account
463+ # currently inactive but active at the date of the entry
464+ ],
465 # MANUEL JOURNAL ENTRIES
466 'account_move_lines': [
467 ('type', 'not in', ['view', 'consolidation', 'closed']),
468
469=== modified file 'bin/addons/account_override/account.py'
470--- bin/addons/account_override/account.py 2019-01-10 10:47:12 +0000
471+++ bin/addons/account_override/account.py 2019-01-31 13:38:39 +0000
472@@ -576,6 +576,7 @@
473 # existing partner
474 emp_obj = self.pool.get('hr.employee')
475 partner_obj = self.pool.get('res.partner')
476+ journal_obj = self.pool.get('account.journal')
477 if partner_type:
478 pt_model, pt_id = tuple(partner_type.split(',')) if from_vals \
479 else (partner_type._name, partner_type.id, )
480@@ -589,15 +590,18 @@
481 elif pt_model == 'res.partner':
482 partner_id = pt_id
483 elif partner_txt:
484- employee_ids = emp_obj.search(cr, uid, [('name', '=', partner_txt)],
485- order='NO_ORDER', limit=1, context=context)
486+ employee_ids = emp_obj.search(cr, uid, [('name', '=', partner_txt)], limit=1, context=context)
487 if employee_ids:
488 employee_id = employee_ids[0]
489 else:
490- partner_ids = partner_obj.search(cr, uid, [('name', '=', partner_txt)],
491- order='NO_ORDER', limit=1, context=context)
492+ partner_ids = partner_obj.search(cr, uid, [('name', '=', partner_txt), ('active', 'in', ['t', 'f'])],
493+ limit=1, context=context)
494 if partner_ids:
495 partner_id = partner_ids[0]
496+ else:
497+ transfer_journal_ids = journal_obj.search(cr, uid, [('code', '=', partner_txt)], limit=1, context=context)
498+ if transfer_journal_ids:
499+ transfer_journal_id = transfer_journal_ids[0]
500 if employee_id:
501 tp_rec = emp_obj.browse(cr, uid, employee_id, fields_to_fetch=['employee_type'], context=context)
502 # note: allowed for employees with no type
503@@ -632,24 +636,55 @@
504 raise osv.except_osv(_('Error'), error_msg)
505
506 def check_type_for_specific_treatment(self, cr, uid, account_ids, partner_id=False, employee_id=False,
507- journal_id=False, context=None):
508+ journal_id=False, partner_txt=False, currency_id=False, context=None):
509 """
510 Checks if the Third parties and accounts in parameter are compatible regarding the "Type for specific treatment"
511- of the accounts (raises an error if not)
512+ of the accounts (raises an error if not).
513+ Note that the currency_id is the one of the entry to be checked and is used ONLY for the checks on
514+ transfer journals (if a currency is given).
515 """
516 if isinstance(account_ids, (int, long)):
517 account_ids = [account_ids]
518 if context is None:
519 context = {}
520 acc_obj = self.pool.get('account.account')
521+ employee_obj = self.pool.get('hr.employee')
522+ partner_obj = self.pool.get('res.partner')
523+ journal_obj = self.pool.get('account.journal')
524 not_compatible_ids = []
525 for acc_id in acc_obj.browse(cr, uid, account_ids, fields_to_fetch=['type_for_register'], context=context):
526+ # get the right Third Party if a partner_txt only has been given
527+ if partner_txt and not partner_id and not employee_id and not journal_id:
528+ employee_ids = employee_obj.search(cr, uid, [('name', '=', partner_txt)], limit=1, context=context)
529+ if employee_ids:
530+ employee_id = employee_ids[0]
531+ else:
532+ partner_ids = partner_obj.search(cr, uid, [('name', '=', partner_txt), ('active', 'in', ['t', 'f'])],
533+ limit=1, context=context)
534+ if partner_ids:
535+ partner_id = partner_ids[0]
536+ else:
537+ journal_ids = journal_obj.search(cr, uid, [('code', '=', partner_txt)], limit=1, context=context)
538+ if journal_ids:
539+ journal_id = journal_ids[0]
540+ # if there is a partner_txt but no related Third Party found:
541+ # ignore the check if "ignore_non_existing_tp" is in context (e.g. when validating HQ entries)
542+ if not partner_id and not employee_id and not journal_id and context.get('ignore_non_existing_tp', False):
543+ continue
544 acc_type = acc_id.type_for_register
545- transfer_not_ok = acc_type in ['transfer', 'transfer_same'] and (not journal_id or partner_id or employee_id)
546 advance_not_ok = acc_type == 'advance' and (not employee_id or journal_id or partner_id)
547 dp_not_ok = acc_type == 'down_payment' and (not partner_id or journal_id or employee_id)
548 payroll_not_ok = acc_type == 'payroll' and ((not partner_id and not employee_id) or journal_id)
549- if transfer_not_ok or advance_not_ok or dp_not_ok or payroll_not_ok:
550+ transfer_not_ok = acc_type in ['transfer', 'transfer_same'] and (not journal_id or partner_id or employee_id)
551+ if currency_id and journal_id and not transfer_not_ok:
552+ # check the journal type and currency
553+ journal = journal_obj.browse(cr, uid, journal_id, fields_to_fetch=['type', 'currency'], context=context)
554+ is_liquidity = journal and journal.type in ['cash', 'bank', 'cheque'] and journal.currency
555+ if acc_type == 'transfer_same' and (not is_liquidity or journal.currency.id != currency_id):
556+ transfer_not_ok = True
557+ elif acc_type == 'transfer' and (not is_liquidity or journal.currency.id == currency_id):
558+ transfer_not_ok = True
559+ if advance_not_ok or dp_not_ok or payroll_not_ok or transfer_not_ok:
560 not_compatible_ids.append(acc_id.id)
561 if not_compatible_ids:
562 self._display_account_partner_compatibility_error(cr, uid, not_compatible_ids, context, type_for_specific_treatment=True)
563@@ -686,7 +721,7 @@
564 allowed_partner_field = self._get_allowed_partner_field(cr, uid, partner_type, partner_txt, employee_id,
565 transfer_journal_id, partner_id, from_vals, context)
566 if not allowed_partner_field:
567- res[r.id] = True # allowed with no specific field
568+ res[r.id] = True # allowed with no specific field (e.g. don't block validation of HQ entries with non-existing 3d Party)
569 else:
570 res[r.id] = hasattr(r, allowed_partner_field) and getattr(r, allowed_partner_field) or False
571 # once the checks are done, remove allowed_partner_field from context so as not to reuse it for another record
572
573=== modified file 'bin/addons/finance/cash_request_view.xml'
574--- bin/addons/finance/cash_request_view.xml 2018-10-04 13:56:00 +0000
575+++ bin/addons/finance/cash_request_view.xml 2019-01-31 13:38:39 +0000
576@@ -28,13 +28,13 @@
577 <field name="current_instance_level" invisible="1"/>
578 <field name="name"/>
579 <field name="state"/>
580- <field name="request_date" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '==', 'project')]}"/>
581- <field name="month_period_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '==', 'project')]}"/>
582+ <field name="request_date" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '=', 'project')]}"/>
583+ <field name="month_period_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '=', 'project')]}"/>
584 <field name="mission"/>
585 <field name="prop_instance_id"/>
586- <field name="transfer_account_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '==', 'project')]}"/>
587- <field name="bank_journal_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '==', 'project')]}"/>
588- <field name="transfer_currency_ids" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '==', 'project')]}">
589+ <field name="transfer_account_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '=', 'project')]}"/>
590+ <field name="bank_journal_id" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '=', 'project')]}"/>
591+ <field name="transfer_currency_ids" attrs="{'readonly': ['|', ('state', '=', 'done'), ('current_instance_level', '=', 'project')]}">
592 <tree string="Currencies" editable="bottom">
593 <field name="currency_id"/>
594 <field name="percentage"/>
595@@ -51,7 +51,7 @@
596 </tree>
597 </field>
598 </group>
599- <group colspan="4" col="4" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
600+ <group colspan="4" col="4" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
601 <separator colspan="4" string="Recap"/>
602 <button name="compute_recap_and_total" type="object"
603 string="Compute recap lines &amp; total to transfer" icon="gtk-refresh"
604@@ -92,7 +92,7 @@
605 </group>
606 </page>
607 <!-- BANKING TAB -->
608- <page string="Banking" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
609+ <page string="Banking" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
610 <separator colspan="4" string="Banking references"/>
611 <field name="journal_name"/>
612 <field name="journal_code"/>
613@@ -102,7 +102,7 @@
614 <field name="bank_address"/>
615 </page>
616 <!-- LIQUIDITY POSITION TAB -->
617- <page string="Liquidity Position" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
618+ <page string="Liquidity Position" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
619 <!-- CASH -->
620 <group colspan="4" col="2">
621 <button name="display_details_cash" type="object" colspan="1"
622@@ -182,7 +182,7 @@
623 </group>
624 </page>
625 <!-- PAYABLES TAB -->
626- <page string="Payables" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
627+ <page string="Payables" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
628 <field name="payable_ids" nolabel="1">
629 <tree string="Payables">
630 <field name="instance_id"/>
631@@ -193,7 +193,7 @@
632 </field>
633 </page>
634 <!-- COMMITMENT TAB -->
635- <page string="Commitment" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
636+ <page string="Commitment" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
637 <separator colspan="4" string="Commitment"/>
638 <field name="commitment_ids" nolabel="1">
639 <tree string="Engagement Entries in func. currency">
640@@ -206,7 +206,7 @@
641 <!-- PLANNED EXPENSE TAB -->
642 <page string="Planned Expense">
643 <separator colspan="4" string="Planned expense for the coming period"/>
644- <group colspan="4" col="2" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
645+ <group colspan="4" col="2" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
646 <field name="recap_expense_ids" nolabel="1">
647 <tree string="Recap Planned Expenses in func. currency">
648 <field name="instance_id"/>
649@@ -238,7 +238,7 @@
650 </group>
651 </page>
652 <!-- TRANSFERS FOLLOW-UP TAB -->
653- <page string="Transfers Follow-up" attrs="{'invisible': [('current_instance_level', '==', 'project')]}">
654+ <page string="Transfers Follow-up" attrs="{'invisible': [('current_instance_level', '=', 'project')]}">
655 <field name="past_transfer_ids" nolabel="1">
656 <tree string="Past Transfers">
657 <field name="instance_id"/>
658
659=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
660--- bin/addons/msf_profile/i18n/fr_MF.po 2019-01-17 15:11:02 +0000
661+++ bin/addons/msf_profile/i18n/fr_MF.po 2019-01-31 13:38:39 +0000
662@@ -26809,8 +26809,8 @@
663 #. module: account_hq_entries
664 #: code:addons/account_hq_entries/wizard/hq_entries_import.py:121
665 #, python-format
666-msgid "No default Destination defined for expense account: %s"
667-msgstr "Pas de Destination par défaut définie pour le compte de charge: %s"
668+msgid "No default Destination defined for account: %s"
669+msgstr "Pas de Destination par défaut définie pour le compte : %s"
670
671 #. module: sales_followup
672 #: model:ir.model,name:sales_followup.model_sale_order_followup_test
673@@ -91895,9 +91895,10 @@
674 msgid "Unit price"
675 msgstr "Prix unitaire"
676
677-#. modules: msf_instance, finance
678+#. modules: msf_instance, finance, account_hq_entries
679 #: field:cash.request,current_instance_level:0
680 #: field:msf.instance,current_instance_level:0
681+#: field:hq.entries,current_instance_level:0
682 msgid "Current Instance Level"
683 msgstr "Niveau de l'Instance Actuelle"
684
685@@ -93247,7 +93248,7 @@
686 msgid "Periodical Processing"
687 msgstr "Traitements Périodiques"
688
689-#. modules: account_override, account, res_currency_functional, account_mcdb, analytic_distribution
690+#. modules: account_override, account, res_currency_functional, account_mcdb, analytic_distribution, account_hq_entries
691 #: selection:account.journal.column,field:0
692 #: view:account.account:0
693 #: field:account.account,user_type:0
694@@ -93263,6 +93264,7 @@
695 #: model:ir.model,name:account_override.model_account_account_type
696 #: view:account.analytic.account:0
697 #: field:account.move.line,account_type:0
698+#: field:hq.entries,account_user_type_code:0
699 #: code:addons/account/report/account_general_ledger.py:526
700 #, python-format
701 msgid "Account Type"
702@@ -103798,6 +103800,7 @@
703 #, python-format
704 msgid "Source Location %s is inactive"
705 msgstr "La Zone Source %s est inactive"
706+<<<<<<< TREE
707
708 #. module: msf_homere_interface
709 #: code:addons/msf_homere_interface/wizard/hr_payroll_import.py:428
710@@ -103843,3 +103846,41 @@
711 #, python-format
712 msgid "Partner %s (%s): you can not use %s currency"
713 msgstr "Partenaire %s (%s): vous ne pouvez pas utiliser la devise %s"
714+=======
715+
716+#. module: account_hq_entries
717+#: code:addons/account_hq_entries/wizard/hq_entries_import.py:195
718+#, python-format
719+msgid "%s \"%s - %s\" of type \"view\" is not allowed for the account \"%s - %s\""
720+msgstr "%s \"%s - %s\" de type \"vue\" n'est pas autorisé pour le compte \"%s - %s\""
721+
722+#. module: account_hq_entries
723+#: code:addons/account_hq_entries/hq_entries.py:607
724+#, python-format
725+msgid "You can not perform this action on a B/S line."
726+msgstr "Vous ne pouvez pas effectuer cette action sur une ligne de bilan."
727+
728+#. module: account_hq_entries
729+#: code:addons/account_hq_entries/wizard/hq_entries_import.py:126
730+#, python-format
731+msgid "The B/S account %s cannot have an Analytic Distribution. Only a Cost Center should be given."
732+msgstr "Le compte de bilan %s ne peut pas avoir de Distribution Analytique. Seul un Centre de Coût doit être indiqué."
733+
734+#. module: account_hq_entries
735+#: code:addons/account_hq_entries/wizard/hq_entries_import.py:126
736+#, python-format
737+msgid "Cost Center is missing for the account %s."
738+msgstr "Il manque le Centre de Coût pour le compte %s."
739+
740+#. module: account_hq_entries
741+#: code:addons/account_hq_entries/wizard/hq_entries_validation.py:479
742+#, python-format
743+msgid "The account %s - %s should not be used in AD corrections."
744+msgstr "Le compte %s - %s ne doit pas être utilisé dans les corrections analytiques."
745+
746+#. module: account_hq_entries
747+#: code:addons/account_hq_entries/wizard/hq_entries_validation.py:471
748+#, python-format
749+msgid "The account %s - %s should neither be corrected nor be used in correction lines."
750+msgstr "Le compte %s - %s ne doit ni être corrigé ni être utilisé dans les lignes de correction."
751+>>>>>>> MERGE-SOURCE

Subscribers

People subscribed via source and target branches