Merge lp:~julie-w/unifield-server/US-5658 into lp:unifield-server
- US-5658
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 5448 |
Proposed branch: | lp:~julie-w/unifield-server/US-5658 |
Merge into: | lp:unifield-server |
Diff against target: |
278 lines (+88/-28) 3 files modified
bin/addons/msf_homere_interface/hr_payroll_wizard.xml (+11/-1) bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py (+67/-27) bin/addons/msf_profile/i18n/fr_MF.po (+10/-0) |
To merge this branch: | bzr merge lp:~julie-w/unifield-server/US-5658 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+370915@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/msf_homere_interface/hr_payroll_wizard.xml' |
2 | --- bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2019-05-14 15:12:35 +0000 |
3 | +++ bin/addons/msf_homere_interface/hr_payroll_wizard.xml 2019-08-02 15:10:29 +0000 |
4 | @@ -108,13 +108,23 @@ |
5 | <field name="arch" type="xml"> |
6 | <form string="Import Confirmation"> |
7 | <field name="filename" attrs="{'invisible': [('filename', '=', False)]}"/> |
8 | + <field name="nberrors" invisible="1"/> |
9 | + <field name="from" invisible="1"/> |
10 | <group colspan="4" col="8"> |
11 | <field name="total" attrs="{'invisible': [('state', 'in', ['none', 'payroll'])]}"/> |
12 | <field name="created" attrs="{'invisible': [('state', '=', 'none')]}"/> |
13 | <field name="updated" invisible="context.get('from', False) not in ['expat_employee_import', 'employee_import']"/> |
14 | <field name="rejected" invisible="context.get('from', False) != 'employee_import'"/> |
15 | </group> |
16 | - <field name="error_line_ids" nolabel="1" colspan="4" attrs="{'invisible': [('nberrors', '=', 0)]}"> |
17 | + <group colspan="4" attrs="{'invisible': ['|', ('nberrors', '=', 0), ('from', '!=', 'employee_import')]}"> |
18 | + <html> |
19 | + <p id="label_import_employee_fail" |
20 | + style="text-align:center; color: red; font-weight: bold; font-size: 1.2em;"> |
21 | + <translate>The import of the file failed!</translate> |
22 | + </p> |
23 | + </html> |
24 | + </group> |
25 | + <field name="error_line_ids" nolabel="1" colspan="4"> |
26 | <tree string="Error List"> |
27 | <field name="msg"/> |
28 | </tree> |
29 | |
30 | === modified file 'bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py' |
31 | --- bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py 2019-02-15 09:33:04 +0000 |
32 | +++ bin/addons/msf_homere_interface/wizard/hr_payroll_employee_import.py 2019-08-02 15:10:29 +0000 |
33 | @@ -54,6 +54,17 @@ |
34 | _name = 'hr.payroll.import.confirmation' |
35 | _description = 'Import Confirmation' |
36 | |
37 | + def _get_from(self, cr, uid, ids, name, arg, context=None): |
38 | + """ |
39 | + Returns the value stored in context at index "from" = from where the wizard has been opened |
40 | + """ |
41 | + if context is None: |
42 | + context = {} |
43 | + res = {} |
44 | + for wiz_id in ids: |
45 | + res[wiz_id] = context.get('from') |
46 | + return res |
47 | + |
48 | _columns = { |
49 | 'updated': fields.integer(string="Updated", size=64, readonly=True), |
50 | 'created': fields.integer(string="Created", size=64, readonly=True), |
51 | @@ -66,6 +77,8 @@ |
52 | 'errors': fields.text(string="Errors", readonly=True), |
53 | 'nberrors': fields.integer(string="Errors", readonly=True), |
54 | 'filename': fields.char(string="Filename", size=256, readonly=True), |
55 | + # WARNING: this wizard model is used for the import of employees from Homere, expats, nat. staff, Payroll, HQ entries... |
56 | + 'from': fields.function(_get_from, type='char', method=True, string="From where has this wizard been opened?", store=False), |
57 | } |
58 | |
59 | _defaults = { |
60 | @@ -188,9 +201,32 @@ |
61 | 'filename': fields.char(string="Imported filename", size=256), |
62 | } |
63 | |
64 | + def store_error(self, errors, wizard_id, message): |
65 | + """ |
66 | + Stores the "message" in the dictionary "errors" at index "wizard_id" |
67 | + """ |
68 | + if errors is not None: |
69 | + if wizard_id not in errors: |
70 | + errors[wizard_id] = [] |
71 | + errors[wizard_id].append(message) |
72 | + |
73 | + def generate_errors(self, cr, uid, errors, context=None): |
74 | + """ |
75 | + Deletes the old errors in DB and replaces them by the new ones |
76 | + """ |
77 | + if context is None: |
78 | + context = {} |
79 | + error_obj = self.pool.get('hr.payroll.employee.import.errors') |
80 | + error_ids = error_obj.search(cr, uid, [], order='NO_ORDER', context=context) |
81 | + if error_ids: |
82 | + error_obj.unlink(cr, uid, error_ids, context=context) |
83 | + for wiz_id in errors: |
84 | + for err in errors[wiz_id]: |
85 | + error_obj.create(cr, uid, {'wizard_id': wiz_id, 'msg': err}, context=context) |
86 | + |
87 | def update_employee_check(self, cr, uid, |
88 | staffcode=False, missioncode=False, staff_id=False, uniq_id=False, |
89 | - wizard_id=None, employee_name=False, registered_keys=None, homere_fields=None): |
90 | + wizard_id=None, employee_name=False, registered_keys=None, homere_fields=None, errors=None): |
91 | """ |
92 | Check that: |
93 | - no more than 1 employee exist for "missioncode + staff_id + uniq_id" |
94 | @@ -227,7 +263,7 @@ |
95 | message = _('No "id_staff" found for employee %s!') % (name,) |
96 | elif not uniq_id: |
97 | message = _('No "id_unique" found for employee %s!') % (name,) |
98 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
99 | + self.store_error(errors, wizard_id, message) |
100 | return (res, what_changed) |
101 | |
102 | # Check employees |
103 | @@ -246,11 +282,10 @@ |
104 | # if not possible only the current employee name will be displayed |
105 | else: |
106 | list_duplicates = ['%s (%s)' % (employee_name, _('Import File'))] |
107 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, { |
108 | - 'wizard_id': wizard_id, |
109 | - 'msg': _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
110 | - (missioncode, staff_id, uniq_id, ' ; '.join(list_duplicates)) |
111 | - }) |
112 | + self.store_error(errors, wizard_id, |
113 | + _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
114 | + (missioncode, staff_id, uniq_id, ' ; '.join(list_duplicates)) |
115 | + ) |
116 | return (res, what_changed) |
117 | |
118 | # check duplicates already in db |
119 | @@ -261,11 +296,10 @@ |
120 | name_duplicates = ['%s (%s)' % (employee_name, _('Import File'))] |
121 | # ... and the duplicates already in UniField |
122 | name_duplicates.extend(['%s (UniField)' % emp.name for emp in emp_duplicates if emp.name]) |
123 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, { |
124 | - 'wizard_id': wizard_id, |
125 | - 'msg': _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
126 | - (missioncode, staff_id, uniq_id, ' ; '.join(name_duplicates)) |
127 | - }) |
128 | + self.store_error(errors, wizard_id, |
129 | + _('Several employees have the same combination key codeterrain/id_staff/(id_unique) "%s / %s / (%s)": %s') % |
130 | + (missioncode, staff_id, uniq_id, ' ; '.join(name_duplicates)) |
131 | + ) |
132 | return (res, what_changed) |
133 | |
134 | # Check staffcode |
135 | @@ -284,7 +318,7 @@ |
136 | # add the duplicated employee from Import File |
137 | message = _('Several employees have the same Identification No "%s": %s') % \ |
138 | (staffcode, ' ; '.join(["%s (%s)" % (employee_name, _('Import File'))] + employee_error_list)) |
139 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
140 | + self.store_error(errors, wizard_id, message) |
141 | return (res, what_changed) |
142 | |
143 | res = True |
144 | @@ -294,8 +328,8 @@ |
145 | """ |
146 | Method used to check if the Identification No to be used for the employee about to be created/edited doesn't |
147 | already exist for another employee in UniField. |
148 | - Returns False if there is a duplication AND we are in the use case where the related and detailed |
149 | - "hr.payroll.employee.import.error" has already been created (but the process wasn't blocked earlier since "what_changed" had a value). |
150 | + Returns False if there is a duplication AND we are in the use case where the related and detailed error has |
151 | + already been stored in the list of errors to display (but the process wasn't blocked earlier since "what_changed" had a value). |
152 | Otherwise returns True => the generic create/write checks will then apply (i.e. a generic error msg will be displayed) |
153 | """ |
154 | if context is None: |
155 | @@ -322,7 +356,7 @@ |
156 | return res |
157 | |
158 | def update_employee_infos(self, cr, uid, employee_data='', wizard_id=None, |
159 | - line_number=None, registered_keys=None, homere_fields=None, context=None): |
160 | + line_number=None, registered_keys=None, homere_fields=None, errors=None, context=None): |
161 | """ |
162 | Get employee infos and set them to DB. |
163 | """ |
164 | @@ -339,7 +373,7 @@ |
165 | payment_method_obj = self.pool.get('hr.payment.method') |
166 | if not employee_data or not wizard_id: |
167 | message = _('No data found for this line: %s.') % line_number |
168 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
169 | + self.store_error(errors, wizard_id, message) |
170 | return False, created, updated |
171 | # Prepare some values |
172 | vals = {} |
173 | @@ -383,7 +417,8 @@ |
174 | staffcode=ustr(code_staff), missioncode=ustr(codeterrain), |
175 | staff_id=id_staff, uniq_id=ustr(uniq_id), |
176 | wizard_id=wizard_id, employee_name=employee_name, |
177 | - registered_keys=registered_keys, homere_fields=homere_fields) |
178 | + registered_keys=registered_keys, homere_fields=homere_fields, |
179 | + errors=errors) |
180 | if not employee_check and not what_changed: |
181 | return False, created, updated |
182 | |
183 | @@ -426,7 +461,7 @@ |
184 | payment_method_id = payment_method_ids[0] |
185 | else: |
186 | message = _('Payment Method %s not found for line: %s. Please fix Homere configuration or request a new Payment Method to the HQ.') % (ustr(bqmodereglement), line_number) |
187 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
188 | + self.store_error(errors, wizard_id, message) |
189 | return False, created, updated |
190 | |
191 | vals.update({'payment_method_id': payment_method_id}) |
192 | @@ -506,7 +541,7 @@ |
193 | registered_keys[codeterrain + id_staff + uniq_id] = True |
194 | else: |
195 | message = _('Line %s. One of this column is missing: code_terrain, id_unique or id_staff. This often happens when the line is empty.') % (line_number) |
196 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wizard_id, 'msg': message}) |
197 | + self.store_error(errors, wizard_id, message) |
198 | return False, created, updated |
199 | |
200 | return True, created, updated |
201 | @@ -663,10 +698,7 @@ |
202 | processed = 0 |
203 | filename = "" |
204 | registered_keys = {} |
205 | - # Delete old errors |
206 | - error_ids = self.pool.get('hr.payroll.employee.import.errors').search(cr, uid, []) |
207 | - if error_ids: |
208 | - self.pool.get('hr.payroll.employee.import.errors').unlink(cr, uid, error_ids) |
209 | + errors = {} |
210 | for wiz in self.browse(cr, uid, ids): |
211 | if not wiz.file: |
212 | raise osv.except_osv(_('Error'), _('Nothing to import.')) |
213 | @@ -735,7 +767,7 @@ |
214 | for i, employee_data in enumerate(staff_seen): |
215 | update, nb_created, nb_updated = self.update_employee_infos( |
216 | cr, uid, employee_data, wiz.id, i, |
217 | - registered_keys=registered_keys, homere_fields=homere_fields, context=context) |
218 | + registered_keys=registered_keys, homere_fields=homere_fields, errors=errors, context=context) |
219 | if not update: |
220 | res = False |
221 | created += nb_created |
222 | @@ -746,7 +778,7 @@ |
223 | # create a different error line for each employee code being duplicated |
224 | for emp_code in details: |
225 | message = _('Several employees have the same Identification No "%s": %s') % (emp_code, ' ; '.join(details[emp_code])) |
226 | - self.pool.get('hr.payroll.employee.import.errors').create(cr, uid, {'wizard_id': wiz.id, 'msg': message}) |
227 | + self.store_error(errors, wiz.id, message) |
228 | # Close Temporary File |
229 | # Delete previous created lines for employee's contracts |
230 | if contract_ids: |
231 | @@ -757,9 +789,18 @@ |
232 | shutil.rmtree(tmpdir) |
233 | del registered_keys |
234 | if res: |
235 | + rejected = processed - created - updated |
236 | message = _("Employee import successful.") |
237 | else: |
238 | + # reject the import of all employees |
239 | + cr.rollback() |
240 | + rejected = processed |
241 | + created = updated = 0 |
242 | context.update({'employee_import_wizard_ids': ids}) |
243 | + |
244 | + # handle the errors at the end of the process to ensure the deletion & creation aren't affected by the rollback |
245 | + self.generate_errors(cr, uid, errors, context=context) |
246 | + |
247 | context.update({'message': message}) |
248 | |
249 | view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'msf_homere_interface', 'payroll_import_confirmation') |
250 | @@ -768,7 +809,6 @@ |
251 | # This is to redirect to Employee Tree View |
252 | context.update({'from': 'employee_import'}) |
253 | |
254 | - rejected = processed - created - updated |
255 | res_id = self.pool.get('hr.payroll.import.confirmation').create(cr, uid, {'filename': filename, 'created': created, |
256 | 'updated': updated, 'total': processed, |
257 | 'rejected': rejected, 'state': 'employee'}, context) |
258 | |
259 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
260 | --- bin/addons/msf_profile/i18n/fr_MF.po 2019-07-31 14:57:17 +0000 |
261 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2019-08-02 15:10:29 +0000 |
262 | @@ -107559,6 +107559,16 @@ |
263 | msgid "Line State" |
264 | msgstr "État de la Ligne" |
265 | |
266 | +#. module: msf_homere_interface |
267 | +#: view:hr.payroll.import.confirmation:0 |
268 | +msgid "The import of the file failed!" |
269 | +msgstr "L'import du fichier a échoué !" |
270 | + |
271 | +#. module: msf_homere_interface |
272 | +#: field:hr.payroll.import.confirmation,from:0 |
273 | +msgid "From where has this wizard been opened?" |
274 | +msgstr "Depuis où cet assistant a-t-il été ouvert ?" |
275 | + |
276 | #. modules: sales_followup, msf_supply_doc_export |
277 | #: code:sales_followup/wizard/sale_followup_multi_wizard.py:190 |
278 | #: code:addons/msf_supply_doc_export/wizard/po_follow_up.py:297 |