Merge lp:~julie-w/unifield-server/US-5441 into lp:unifield-server
- US-5441
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5223 |
Proposed branch: | lp:~julie-w/unifield-server/US-5441 |
Merge into: | lp:unifield-server |
Diff against target: |
370 lines (+112/-49) 4 files modified
bin/addons/msf_homere_interface/hr.py (+3/-2) bin/addons/msf_homere_interface/hr_payroll_wizard.xml (+4/-3) bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py (+79/-17) bin/addons/msf_profile/i18n/fr_MF.po (+26/-27) |
To merge this branch: | bzr merge lp:~julie-w/unifield-server/US-5441 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+362316@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Updating diff...
An updated diff will be available in a few minutes. Reload to see the changes.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/msf_homere_interface/hr.py' |
2 | --- bin/addons/msf_homere_interface/hr.py 2018-07-16 12:44:02 +0000 |
3 | +++ bin/addons/msf_homere_interface/hr.py 2019-01-28 14:17:39 +0000 |
4 | @@ -199,12 +199,13 @@ |
5 | employee_name = employee.get('name', False) |
6 | if employee_name and employee_name not in names: |
7 | names.append(employee_name) |
8 | - raise osv.except_osv(_('Error'), _('Some employees have the same unique code: %s') % (';'.join(names))) |
9 | + raise osv.except_osv(_('Error'), _('Several employees have the same Identification No "%s": %s') % |
10 | + (e.identification_id, ' ; '.join(names))) |
11 | return False |
12 | return True |
13 | |
14 | _constraints = [ |
15 | - (_check_unicity, "Another employee has the same unique code.", ['identification_id']), |
16 | + (_check_unicity, "Another employee has the same Identification No.", ['identification_id']), |
17 | ] |
18 | |
19 | def create(self, cr, uid, vals, context=None): |
20 | |
21 | === modified file 'bin/addons/msf_homere_interface/hr_payroll_wizard.xml' |
22 | --- bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2018-04-19 12:11:56 +0000 |
23 | +++ bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2019-01-28 14:17:39 +0000 |
24 | @@ -105,10 +105,11 @@ |
25 | <field name="arch" type="xml"> |
26 | <form string="Import Confirmation"> |
27 | <field name="filename" attrs="{'invisible': [('filename', '=', False)]}"/> |
28 | - <group colspan="4" col="6"> |
29 | + <group colspan="4" col="8"> |
30 | + <field name="total" attrs="{'invisible': [('state', 'in', ['none', 'payroll'])]}"/> |
31 | <field name="created" attrs="{'invisible': [('state', '=', 'none')]}"/> |
32 | - <field name="updated" invisible="context.get('from', False) != 'expat_employee_import'"/> <!-- attrs="{'invisible': ['!', ('updated', '=', False), ('state', 'in', ['none', 'payroll'])]}"/--> |
33 | - <field name="total" attrs="{'invisible': [('state', 'in', ['none', 'payroll'])]}"/> |
34 | + <field name="updated" invisible="context.get('from', False) not in ['expat_employee_import', 'employee_import']"/> |
35 | + <field name="rejected" invisible="context.get('from', False) != 'employee_import'"/> |
36 | </group> |
37 | <field name="error_line_ids" nolabel="1" colspan="4" attrs="{'invisible': [('nberrors', '=', 0)]}"> |
38 | <tree string="Error List"> |
39 | |
40 | === modified file 'bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py' |
41 | --- bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py 2018-08-14 13:29:21 +0000 |
42 | +++ bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py 2019-01-28 14:17:39 +0000 |
43 | @@ -57,6 +57,7 @@ |
44 | _columns = { |
45 | 'updated': fields.integer(string="Updated", size=64, readonly=True), |
46 | 'created': fields.integer(string="Created", size=64, readonly=True), |
47 | + 'rejected': fields.integer(string="Rejected", size=64, readonly=True), |
48 | 'total': fields.integer(string="Processed", size=64, readonly=True), |
49 | 'state': fields.selection([('none', 'None'), ('employee', 'From Employee'), ('payroll', 'From Payroll'), ('hq', 'From HQ Entries')], |
50 | string="State", required=True, readonly=True), |
51 | @@ -70,6 +71,7 @@ |
52 | _defaults = { |
53 | 'updated': lambda *a: 0, |
54 | 'created': lambda *a: 0, |
55 | + 'rejected': lambda *a: 0, |
56 | 'total': lambda *a: 0, |
57 | 'state': lambda *a: 'none', |
58 | 'nberrors': lambda *a: 0, |
59 | @@ -188,7 +190,7 @@ |
60 | |
61 | def update_employee_check(self, cr, uid, |
62 | staffcode=False, missioncode=False, staff_id=False, uniq_id=False, |
63 | - wizard_id=None, employee_name=False, registered_keys=None): |
64 | + wizard_id=None, employee_name=False, registered_keys=None, homere_fields={}): |
65 | """ |
66 | Check that: |
67 | - no more than 1 employee exist for "missioncode + staff_id + uniq_id" |
68 | @@ -230,25 +232,41 @@ |
69 | # => as not already in db |
70 | check_key = missioncode + staff_id + uniq_id |
71 | if check_key in registered_keys: |
72 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, { |
73 | - 'wizard_id': wizard_id, |
74 | - 'msg': _("Import file have more than one employee with the combination key codeterrain/id_staff(/id_unique) of this employee: %s") % (employee_name,) |
75 | - }) |
76 | + # if check_key is in homere_fields BUT its value is empty, the related msg has already been created => skip the msg creation part |
77 | + if check_key not in homere_fields or homere_fields.get(check_key): |
78 | + # if possible list all the duplicated employees |
79 | + if homere_fields.get(check_key): |
80 | + list_duplicates = ['%s (%s)' % (empl, _('Import File')) for empl in homere_fields[check_key]] |
81 | + # empty the list so that the msg with all employees is displayed only once (and not once per duplicated employee) |
82 | + homere_fields[check_key] = [] |
83 | + # if not possible only the current employee name will be displayed |
84 | + else: |
85 | + list_duplicates = [employee_name] |
86 | + self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, { |
87 | + 'wizard_id': wizard_id, |
88 | + 'msg': _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
89 | + (missioncode, staff_id, uniq_id, ' ; '.join(list_duplicates)) |
90 | + }) |
91 | return (res, what_changed) |
92 | |
93 | # check duplicates already in db |
94 | search_ids = self.pool.get('hr.employee').search(cr, uid, [('homere_codeterrain', '=', missioncode), ('homere_id_staff', '=', staff_id), ('homere_id_unique', '=', uniq_id)]) |
95 | if search_ids and len(search_ids) > 1: |
96 | + emp_duplicates = self.pool.get('hr.employee').browse(cr, uid, search_ids, fields_to_fetch=['name']) |
97 | + # create a list with the employee from the file... |
98 | + name_duplicates = ['%s (%s)' % (employee_name, _('Import File'))] |
99 | + # ... and the duplicates already in UniField |
100 | + name_duplicates.extend(['%s (UniField)' % emp.name for emp in emp_duplicates if emp.name]) |
101 | self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, { |
102 | 'wizard_id': wizard_id, |
103 | - 'msg': _("Database have more than one employee with the unique code of this employee: %s") % (employee_name,) |
104 | + 'msg': _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
105 | + (missioncode, staff_id, uniq_id, ' ; '.join(name_duplicates)) |
106 | }) |
107 | return (res, what_changed) |
108 | |
109 | # Check staffcode |
110 | staffcode_ids = self.pool.get('hr.employee').search(cr, uid, [('identification_id', '=', staffcode)]) |
111 | if staffcode_ids: |
112 | - message = "Several employee have the same ID code: " |
113 | employee_error_list = [] |
114 | # UTP-1098: Do not make an error if the employee have the same code staff and the same name |
115 | for employee in self.pool.get('hr.employee').browse(cr, uid, staffcode_ids): |
116 | @@ -256,15 +274,37 @@ |
117 | if employee.name == employee_name: |
118 | continue |
119 | if what_changed != None: |
120 | - employee_error_list.append(employee.name) |
121 | + # duplicated employees in UniField |
122 | + employee_error_list.append("%s (UniField)" % (employee.name,)) |
123 | if employee_error_list: |
124 | - message += ' ; '.join([employee_name] + employee_error_list) |
125 | + # add the duplicated employee from Import File |
126 | + message = _('Several employees have the same Identification No "%s": %s') % \ |
127 | + (staffcode, ' ; '.join(["%s (%s)" % (employee_name, _('Import File'))] + employee_error_list)) |
128 | self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
129 | return (res, what_changed) |
130 | |
131 | res = True |
132 | return (res, what_changed) |
133 | |
134 | + def _check_identification_id_duplication(self, cr, uid, vals, employee_check, what_changed, current_id=None, context=None): |
135 | + """ |
136 | + Method used to check if the Identification No to be used for the employee about to be created/edited doesn't |
137 | + already exist for another employee in UniField. |
138 | + Returns False if there is a duplication AND we are in the use case where the related and detailed |
139 | + "hr.payroll.employee.import.error" has already been created (but the process wasn't blocked earlier since "what_changed" had a value). |
140 | + Otherwise returns True => the generic create/write checks will then apply (i.e. a generic error msg will be displayed) |
141 | + """ |
142 | + if context is None: |
143 | + context = {} |
144 | + employee_obj = self.pool.get('hr.employee') |
145 | + if not employee_check and what_changed and vals.get('identification_id'): |
146 | + employee_dom = [('identification_id', '=', vals['identification_id'])] |
147 | + if current_id is not None: |
148 | + employee_dom.append(('id', '!=', current_id)) |
149 | + if employee_obj.search_exist(cr, uid, employee_dom, context=context): |
150 | + return False |
151 | + return True |
152 | + |
153 | def read_employee_infos(self, cr, uid, line='', context=None): |
154 | """ |
155 | Read each line to extract infos (code, name and surname) |
156 | @@ -278,7 +318,7 @@ |
157 | return res |
158 | |
159 | def update_employee_infos(self, cr, uid, employee_data='', wizard_id=None, |
160 | - line_number=None, registered_keys=None, context=None): |
161 | + line_number=None, registered_keys=None, homere_fields={}, context=None): |
162 | """ |
163 | Get employee infos and set them to DB. |
164 | """ |
165 | @@ -287,6 +327,8 @@ |
166 | updated = 0 |
167 | if context is None: |
168 | context = {} |
169 | + if line_number is not None: |
170 | + line_number = line_number + 2 # cf. the count starts at "1" and the header line is ignored |
171 | payment_method_obj = self.pool.get('hr.payment.method') |
172 | if not employee_data or not wizard_id: |
173 | message = _('No data found for this line: %s.') % line_number |
174 | @@ -334,7 +376,7 @@ |
175 | staffcode=ustr(code_staff), missioncode=ustr(codeterrain), |
176 | staff_id=id_staff, uniq_id=ustr(uniq_id), |
177 | wizard_id=wizard_id, employee_name=employee_name, |
178 | - registered_keys=registered_keys) |
179 | + registered_keys=registered_keys, homere_fields=homere_fields) |
180 | if not employee_check and not what_changed: |
181 | return False, created, updated |
182 | |
183 | @@ -443,10 +485,14 @@ |
184 | if not current_contract: |
185 | vals.update({'active': False}) |
186 | if not e_ids: |
187 | + if not self._check_identification_id_duplication(cr, uid, vals, employee_check, what_changed, context=context): |
188 | + return False, created, updated |
189 | res = self.pool.get('hr.employee').create(cr, uid, vals, {'from': 'import'}) |
190 | if res: |
191 | created += 1 |
192 | else: |
193 | + if not self._check_identification_id_duplication(cr, uid, vals, employee_check, what_changed, current_id=e_ids[0], context=context): |
194 | + return False, created, updated |
195 | res = self.pool.get('hr.employee').write(cr, uid, e_ids, vals, {'from': 'import'}) |
196 | if res: |
197 | updated += 1 |
198 | @@ -644,6 +690,7 @@ |
199 | staff_codes = [] |
200 | duplicates = [] |
201 | staff_seen = [] |
202 | + homere_fields = {} |
203 | for line in staff_reader: |
204 | staff_seen.append(line) |
205 | data = self.read_employee_infos(cr, uid, line) |
206 | @@ -654,13 +701,23 @@ |
207 | if code in staff_codes: |
208 | duplicates.append(code) |
209 | staff_codes.append(code) |
210 | + # store the Homere fields combination for all employees |
211 | + if line.get('nom'): |
212 | + # "no id_unique" is replaced by the string "empty" |
213 | + homere_fields_key = "%s%s%s" % (line.get('codeterrain', ''), line.get('id_staff', ''), line.get('id_unique', 'empty')) |
214 | + if homere_fields_key not in homere_fields: |
215 | + homere_fields[homere_fields_key] = [] |
216 | + homere_fields[homere_fields_key].append(line['nom']) |
217 | # Delete duplicates of… duplicates! |
218 | duplicates = list(set(duplicates)) |
219 | - details = [] |
220 | + details = {} |
221 | for employee_infos in staff_data: |
222 | employee_code = employee_infos[0] |
223 | if employee_code in duplicates: |
224 | - details.append(','.join([ustr(employee_infos[1]), ustr(employee_infos[2])])) |
225 | + # add (Import File) after the employee info so that it is clearer for the user that the duplicates are inside the file itself |
226 | + if employee_code not in details: |
227 | + details[employee_code] = [] |
228 | + details[employee_code].append(','.join([ustr(employee_infos[1]), "%s (%s)" % (ustr(employee_infos[2]), _('Import File'))])) |
229 | res = True |
230 | if not details: |
231 | created = 0 |
232 | @@ -671,7 +728,7 @@ |
233 | for i, employee_data in enumerate(staff_seen): |
234 | update, nb_created, nb_updated = self.update_employee_infos( |
235 | cr, uid, employee_data, wiz.id, i, |
236 | - registered_keys=registered_keys, context=context) |
237 | + registered_keys=registered_keys, homere_fields=homere_fields, context=context) |
238 | if not update: |
239 | res = False |
240 | created += nb_created |
241 | @@ -679,8 +736,10 @@ |
242 | processed += 1 |
243 | else: |
244 | res = False |
245 | - message = _('Several employees have the same unique code: %s.') % (';'.join(details)) |
246 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wiz.id, 'msg': message}) |
247 | + # create a different error line for each employee code being duplicated |
248 | + for emp_code in details: |
249 | + message = _('Several employees have the same Identification No "%s": %s') % (emp_code, ' ; '.join(details[emp_code])) |
250 | + self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wiz.id, 'msg': message}) |
251 | # Close Temporary File |
252 | # Delete previous created lines for employee's contracts |
253 | if contract_ids: |
254 | @@ -702,7 +761,10 @@ |
255 | # This is to redirect to Employee Tree View |
256 | context.update({'from': 'employee_import'}) |
257 | |
258 | - res_id = self.pool.get('hr.payroll.import.confirmation').create(cr, uid, {'filename': filename, 'created': created, 'updated': updated, 'total': processed, 'state': 'employee'}, context) |
259 | + rejected = processed - created - updated |
260 | + res_id = self.pool.get('hr.payroll.import.confirmation').create(cr, uid, {'filename': filename, 'created': created, |
261 | + 'updated': updated, 'total': processed, |
262 | + 'rejected': rejected, 'state': 'employee'}, context) |
263 | return { |
264 | 'name': 'Employee Import Confirmation', |
265 | 'type': 'ir.actions.act_window', |
266 | |
267 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
268 | --- bin/addons/msf_profile/i18n/fr_MF.po 2019-01-17 15:11:02 +0000 |
269 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2019-01-28 14:17:39 +0000 |
270 | @@ -10929,12 +10929,6 @@ |
271 | msgid "Write-Off" |
272 | msgstr "Ajustement" |
273 | |
274 | -#. module: msf_homere_interface |
275 | -#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:653 |
276 | -#, python-format |
277 | -msgid "Several employees have the same unique code: %s." |
278 | -msgstr "Several employees have the same unique code: %s." |
279 | - |
280 | #. module: analytic_distribution |
281 | #: code:addons/analytic_distribution/wizard/import_commitment_wizard.py:135 |
282 | #, python-format |
283 | @@ -44265,12 +44259,6 @@ |
284 | msgid "Outgoing delivery" |
285 | msgstr "Livraison sortante" |
286 | |
287 | -#. module: msf_homere_interface |
288 | -#: code:addons/msf_homere_interface/hr.py:178 |
289 | -#, python-format |
290 | -msgid "Some employees have the same unique code: %s" |
291 | -msgstr "Certains employés ont le même code unique : %s" |
292 | - |
293 | #. module: purchase |
294 | #: help:purchase.order,date_approve:0 |
295 | msgid "Date on which purchase order has been approved" |
296 | @@ -47034,12 +47022,6 @@ |
297 | msgid "Select Products" |
298 | msgstr "Sélection des Produits" |
299 | |
300 | -#. module: msf_homere_interface |
301 | -#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:242 |
302 | -#, python-format |
303 | -msgid "Database have more than one employee with the unique code of this employee: %s" |
304 | -msgstr "La base de données compte plus d'un travailleur ayant le code unique de ce travailleur : %s" |
305 | - |
306 | #. module: msf_outgoing |
307 | #: code:addons/msf_outgoing/msf_outgoing.py:1267 |
308 | #, python-format |
309 | @@ -66066,9 +66048,10 @@ |
310 | msgid "Loss" |
311 | msgstr "Perte" |
312 | |
313 | -#. module: msf_tools |
314 | +#. modules: msf_tools, msf_homere_interface |
315 | #: code:addons/msf_tools/automated_import_job.py:529 |
316 | #: code:addons/msf_tools/automated_export_job.py:257 |
317 | +#: field:hr.payroll.import.confirmation,rejected:0 |
318 | #, python-format |
319 | msgid "Rejected" |
320 | msgstr "Rejeté" |
321 | @@ -83232,12 +83215,6 @@ |
322 | msgid "Seems that no G/L account was found for this Register Analytic Distribution Wizard. Please give one." |
323 | msgstr "Seems that no G/L account was found for this Register Analytic Distribution Wizard. Please give one." |
324 | |
325 | -#. module: msf_homere_interface |
326 | -#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:233 |
327 | -#, python-format |
328 | -msgid "Import file have more than one employee with the combination key codeterrain/id_staff(/id_unique) of this employee: %s" |
329 | -msgstr "Le fichier d'import a plus d'un employé avec la clé de combinaison codeterrain/id_staff(/id_unique) de cet employé: %s " |
330 | - |
331 | #. module: msf_doc_import |
332 | #: model:ir.model,name:msf_doc_import.model_abstract_wizard_import |
333 | msgid "Generic import wizard" |
334 | @@ -89411,8 +89388,8 @@ |
335 | #: constraint:hr.employee:0 |
336 | #: constraint:hr.employee:0 |
337 | #: constraint:hr.employee:0 |
338 | -msgid "Another employee has the same unique code." |
339 | -msgstr "Ce code est utilisé pour un autre employé." |
340 | +msgid "Another employee has the same Identification No." |
341 | +msgstr "Ce N° d'identification est utilisé pour un autre employé." |
342 | |
343 | #. module: msf_outgoing |
344 | #: model:ir.model,name:msf_outgoing.model_return_shipment_processor |
345 | @@ -103843,3 +103820,25 @@ |
346 | #, python-format |
347 | msgid "Partner %s (%s): you can not use %s currency" |
348 | msgstr "Partenaire %s (%s): vous ne pouvez pas utiliser la devise %s" |
349 | + |
350 | +#. module: msf_homere_interface |
351 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:265 |
352 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:669 |
353 | +#, python-format |
354 | +msgid "Import File" |
355 | +msgstr "Fichier d'Import" |
356 | + |
357 | +#. module: msf_homere_interface |
358 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:247 |
359 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:262 |
360 | +#, python-format |
361 | +msgid "Several employees have the same combination key codeterrain/id_staff/(id_unique) \"%s / %s / (%s)\": %s" |
362 | +msgstr "Plusieurs employés ont la même clé de combinaison codeterrain/id_staff/(id_unique) \"%s / %s / (%s)\": %s" |
363 | + |
364 | +#. module: msf_homere_interface |
365 | +#: code:addons/msf_homere_interface/hr.py:202 |
366 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:281 |
367 | +#: code:addons/msf_homere_interface/wizard/hr_payroll_employee_import.py:741 |
368 | +#, python-format |
369 | +msgid "Several employees have the same Identification No \"%s\": %s" |
370 | +msgstr "Plusieurs employés ont le même N° d'identification \"%s\": %s" |