Merge lp:~mallorymarcot/unifield-server/us-1830 into lp:unifield-server
- us-1830
- Merge into trunk
Proposed by
Quentin THEURET @Amaris
Status: | Rejected |
---|---|
Rejected by: | jftempo |
Proposed branch: | lp:~mallorymarcot/unifield-server/us-1830 |
Merge into: | lp:unifield-server |
Diff against target: |
755 lines (+517/-18) (has conflicts) 6 files modified
bin/addons/msf_profile/i18n/fr_MF.po (+180/-8) bin/addons/msf_tools/__init__.py (+3/-0) bin/addons/msf_tools/__openerp__.py (+1/-0) bin/addons/msf_tools/automated_import_job.py (+133/-10) bin/addons/msf_tools/manual_import_job.py (+101/-0) bin/addons/msf_tools/views/manual_import_job_view.xml (+99/-0) Text conflict in bin/addons/msf_profile/i18n/fr_MF.po Text conflict in bin/addons/msf_tools/__init__.py Text conflict in bin/addons/msf_tools/automated_import_job.py |
To merge this branch: | bzr merge lp:~mallorymarcot/unifield-server/us-1830 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+310850@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 4021. By Mallory MARCOT
-
US-1830 [IMP] Cannot delete manual import job in progress
- 4022. By Mallory MARCOT
-
US-1830 [IMP] CSV error report in attachment
- 4023. By Mallory MARCOT
-
US-1830 [IMP] add missing french translation
- 4024. By Mallory MARCOT
-
US-1830 [IMP] fixing encoding issue with french translation
Unmerged revisions
- 4024. By Mallory MARCOT
-
US-1830 [IMP] fixing encoding issue with french translation
- 4023. By Mallory MARCOT
-
US-1830 [IMP] add missing french translation
- 4022. By Mallory MARCOT
-
US-1830 [IMP] CSV error report in attachment
- 4021. By Mallory MARCOT
-
US-1830 [IMP] Cannot delete manual import job in progress
- 4020. By Mallory MARCOT
-
US-1830 [IMP] translate missing strings
- 4019. By Mallory MARCOT
-
US-1830 [IMP] Better warning/error messages with translations
- 4018. By Mallory MARCOT
-
US-1830 [IMP] Manual import, background import functionnality
- 4017. By Mallory MARCOT
-
US-1830 [IMP] make changes compatible with automated imports
- 4016. By Mallory MARCOT
-
US-1830 [IMP] Manual import basic functionnalities OK
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
2 | --- bin/addons/msf_profile/i18n/fr_MF.po 2016-11-21 13:32:46 +0000 |
3 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2016-11-22 13:43:46 +0000 |
4 | @@ -6413,10 +6413,18 @@ |
5 | msgid "Either there are no moves linked to the picking or Accounting Journals are misconfigured!" |
6 | msgstr "Soit les Journaux Comptables sont mal configurés, soit il n'y a pas de mouvement connexe à ce prélèvement !" |
7 | |
8 | +<<<<<<< TREE |
9 | #. modules: msf_tools, tender_flow, financing_contract, account_voucher, account_override, purchase_allocation_report, register_accounting, msf_accrual, account_msf, return_claim, res_currency_tables, procurement_request, stock_forecast, analytic, msf_doc_import, analytic_distribution, msf_order_date, account_payment, msf_homere_interface, msf_instance, purchase_override, specific_rules, kit, out_step, base, msf_budget, account_corrections, account, msf_outgoing, sale_override, sale, sales_followup, procurement, sourcing, purchase, msf_audittrail, stock |
10 | #: view:automated.import.job:0 |
11 | #: selection:automated.import.job,state:0 |
12 | #: selection:export.report.stopped.products,state:0 |
13 | +======= |
14 | +#. modules: tender_flow, financing_contract, account_voucher, account_override, purchase_allocation_report, register_accounting, msf_accrual, account_msf, return_claim, res_currency_tables, procurement_request, stock_forecast, analytic, msf_doc_import, analytic_distribution, msf_order_date, account_payment, msf_homere_interface, msf_instance, purchase_override, specific_rules, kit, out_step, base, msf_budget, account_corrections, account, msf_outgoing, sale_override, sale, sales_followup, procurement, sourcing, purchase, msf_audittrail, stock, msf_tools |
15 | +#: view:automated.import.job:0 |
16 | +#: selection:automated.import.job,state:0 |
17 | +#: view:manual.import.job:0 |
18 | +#: selection:manual.import.job,state:0 |
19 | +>>>>>>> MERGE-SOURCE |
20 | #: view:account.bank.statement:0 |
21 | #: selection:account.bank.statement,state:0 |
22 | #: view:account.invoice:0 |
23 | @@ -9951,12 +9959,14 @@ |
24 | msgid "Destinations" |
25 | msgstr "Destinations" |
26 | |
27 | -#. module: msf_doc_import |
28 | +#. modules: msf_doc_import, msf_tools |
29 | +#: field:automated.import.job,file_to_import:0 |
30 | +#: field:manual.import.job,file_to_import:0 |
31 | #: field:stock.partial.picking,file_to_import:0 |
32 | #: view:wizard.import.po:0 |
33 | #: field:wizard.import.po,file:0 |
34 | msgid "File to import" |
35 | -msgstr "File to import" |
36 | +msgstr "Fichier à importer" |
37 | |
38 | #. module: analytic_distribution |
39 | #: code:addons/analytic_distribution/account_commitment.py:137 |
40 | @@ -10094,7 +10104,9 @@ |
41 | msgid "System message" |
42 | msgstr "Message système" |
43 | |
44 | -#. modules: register_accounting, msf_field_access_rights, consumption_calculation, kit, analytic_distribution_invoice, msf_button_access_rights, msf_doc_import, tender_flow |
45 | +#. modules: register_accounting, msf_field_access_rights, consumption_calculation, kit, analytic_distribution_invoice, msf_button_access_rights, msf_doc_import, tender_flow, msf_tools |
46 | +#: field:automated.import.job,comment:0 |
47 | +#: field:manual.import.job,comment:0 |
48 | #: field:account.invoice.line,inactive_error:0 |
49 | #: field:composition.item,inactive_error:0 |
50 | #: field:msf_button_access_rights.button_access_rule,comment:0 |
51 | @@ -15410,7 +15422,11 @@ |
52 | msgid "Debit Note" |
53 | msgstr "Note de débit" |
54 | |
55 | -#. modules: product_nomenclature, process, financing_contract, product_asset, mission_stock, return_claim, account_mcdb, supplier_catalogue, unifield_setup, analytic, report_webkit, analytic_distribution, product, reason_types_moves, account_payment, msf_homere_interface, hr, consumption_calculation, msf_instance, kit, base, procurement_report, msf_budget, sales_followup, account, msf_outgoing, resource, documents_done, sale, procurement, sourcing, product_list, object_query, stock, msf_profile |
56 | +#. modules: product_nomenclature, process, financing_contract, product_asset, mission_stock, return_claim, account_mcdb, supplier_catalogue, unifield_setup, analytic, report_webkit, analytic_distribution, product, reason_types_moves, account_payment, msf_homere_interface, hr, consumption_calculation, msf_instance, kit, base, procurement_report, msf_budget, sales_followup, account, msf_outgoing, resource, documents_done, sale, procurement, sourcing, product_list, object_query, stock, msf_profile, msf_tools |
57 | +#: field:automated.import,name:0 |
58 | +#: field:automated.import.function,name:0 |
59 | +#: field:automated.import.job,name:0 |
60 | +#: field:manual.import.job,name:0 |
61 | #: field:account.account,name:0 |
62 | #: field:account.account.template,name:0 |
63 | #: report:account.analytic.account.inverted.balance:0 |
64 | @@ -21666,7 +21682,9 @@ |
65 | msgid "Flow Stop" |
66 | msgstr "Flux d'Arrivée" |
67 | |
68 | -#. modules: account, res_currency_functional, sale |
69 | +#. modules: account, res_currency_functional, sale, msf_tools |
70 | +#: view:automated.import.job:0 |
71 | +#: view:manual.import.job:0 |
72 | #: view:account.fiscalyear:0 |
73 | #: view:account.move:0 |
74 | #: view:account.move.line:0 |
75 | @@ -32299,7 +32317,11 @@ |
76 | msgid "heat sensitive and dangerous goods" |
77 | msgstr "produits sensibles à la chaleur et des marchandises dangereuses" |
78 | |
79 | -#. modules: sales_followup, purchase, sale, stock_forecast, procurement, sourcing |
80 | +#. modules: sales_followup, purchase, sale, stock_forecast, procurement, sourcing, msf_tools |
81 | +#: view:automated.import.job:0 |
82 | +#: selection:automated.import.job,state:0 |
83 | +#: view:manual.import.job:0 |
84 | +#: selection:manual.import.job,state:0 |
85 | #: selection:procurement.order,state:0 |
86 | #: view:purchase.order:0 |
87 | #: selection:sale.order.line,state:0 |
88 | @@ -38909,7 +38931,9 @@ |
89 | msgid "ID of the view defined in xml file" |
90 | msgstr "Identité de la vue défini dans le fichier XML" |
91 | |
92 | -#. modules: msf_doc_import, consumption_calculation, procurement_request |
93 | +#. modules: msf_doc_import, consumption_calculation, procurement_request, msf_tools |
94 | +#: view:automated.import.job:0 |
95 | +#: view:manual.import.job:0 |
96 | #: view:wizard.import.fmc:0 |
97 | #: view:wizard.import.rac:0 |
98 | #: view:wizard.import.fo.line:0 |
99 | @@ -43888,9 +43912,15 @@ |
100 | msgid "Average monthly consumption" |
101 | msgstr "consommation mensuelle réelle" |
102 | |
103 | +<<<<<<< TREE |
104 | #. modules: account_override, msf_doc_import, account, consumption_calculation, msf_tools |
105 | #: field:automated.import.job,state:0 |
106 | #: field:export.report.stopped.products,state:0 |
107 | +======= |
108 | +#. modules: account_override, msf_doc_import, account, consumption_calculation , msf_tools |
109 | +#: field:automated.import.job,state:0 |
110 | +#: field:manual.import.job,state:0 |
111 | +>>>>>>> MERGE-SOURCE |
112 | #: selection:account.journal.column,field:0 |
113 | #: report:addons/account_override/report/open_invoices_xls.mako:304 |
114 | #: field:real.average.consumption,state:0 |
115 | @@ -61378,7 +61408,11 @@ |
116 | msgid "Asia/Yekaterinburg" |
117 | msgstr "Asia/Yekaterinburg" |
118 | |
119 | -#. modules: msf_budget, purchase, account, msf_outgoing, account_payment, purchase_override, specific_rules, sale, sourcing, base, stock, msf_doc_import, return_claim, analytic_distribution, register_accounting |
120 | +#. modules: msf_budget, purchase, account, msf_outgoing, account_payment, purchase_override, specific_rules, sale, sourcing, base, stock, msf_doc_import, return_claim, analytic_distribution, register_accounting, msf_tools |
121 | +#: view:automated.import.job:0 |
122 | +#: selection:automated.import.job,state:0 |
123 | +#: view:manual.import.job:0 |
124 | +#: selection:manual.import.job,state:0 |
125 | #: selection:account.invoice.report,state:0 |
126 | #: selection:account.journal.period,state:0 |
127 | #: selection:account.subscription,state:0 |
128 | @@ -74778,6 +74812,7 @@ |
129 | msgid "You can't search on this object without using at least one exact search term (precede your search with the character '=')." |
130 | msgstr "Vous ne pouvez pas exécuter de recherche sur cet objet sans utiliser au moins une recherche exacte (ajoutez le caractère = devant votre filtre)." |
131 | |
132 | +<<<<<<< TREE |
133 | #. module: procurement_request |
134 | #: code:addons/procurement_request/procurement_request.py:553 |
135 | #, python-format |
136 | @@ -75713,3 +75748,140 @@ |
137 | msgid "There is no stopped products to report" |
138 | msgstr "Il n'y a aucun produit stoppé à afficher" |
139 | |
140 | +======= |
141 | +#. module: msf_tools |
142 | +#: field:automated.import,function_id:0 |
143 | +#: field:manual.import.job,function_id:0 |
144 | +msgid "Functionality" |
145 | +msgstr "Fonctionnalité" |
146 | + |
147 | +#. module: msf_tools |
148 | +#: field:automated.import.job,end_time:0 |
149 | +#: field:manual.import.job,end_time:0 |
150 | +msgid "End time" |
151 | +msgstr "Terminé à" |
152 | + |
153 | +#. module: msf_tools |
154 | +#: view:automated.import.job:0 |
155 | +#: selection:automated.import.job,state:0 |
156 | +#: view:manual.import.job:0 |
157 | +#: selection:manual.import.job,state:0 |
158 | +msgid "In progress" |
159 | +msgstr "En cours" |
160 | + |
161 | +#. module: msf_tools |
162 | +#: view:manual.import.job:0 |
163 | +msgid "Status of the import" |
164 | +msgstr "Etat de l'import" |
165 | + |
166 | +#. module: msf_tools |
167 | +#: view:automated.import.job:0 |
168 | +#: view:manual.import.job:0 |
169 | +msgid "Import job report" |
170 | +msgstr "Rapport sur l'import" |
171 | + |
172 | +#. module: msf_tools |
173 | +#: view:automated.import:0 |
174 | +#: field:automated.import.job,import_id:0 |
175 | +#: field:manual.import.job,import_id:0 |
176 | +msgid "Automated import" |
177 | +msgstr "Import automatique" |
178 | + |
179 | +#. module: msf_tools |
180 | +#: field:automated.import.job,nb_rejected_records:0 |
181 | +#: field:manual.import.job,nb_rejected_records:0 |
182 | +msgid "# of rejected records" |
183 | +msgstr "Nombre d'enregistrements rejetés" |
184 | + |
185 | +#. module: msf_tools |
186 | +#: field:automated.import.job,start_time:0 |
187 | +#: field:manual.import.job,start_time:0 |
188 | +msgid "Start time" |
189 | +msgstr "Débuté à" |
190 | + |
191 | +#. module: msf_tools |
192 | +#: view:automated.import.job:0 |
193 | +#: view:manual.import.job:0 |
194 | +msgid "Process import" |
195 | +msgstr "Importer" |
196 | + |
197 | +#. module: msf_tools |
198 | +#: view:automated.import.job:0 |
199 | +#: model:ir.actions.act_window,name:msf_tools.automated_import_job_action |
200 | +#: model:ir.ui.menu,name:msf_tools.automated_import_job_menu |
201 | +#: view:manual.import.job:0 |
202 | +msgid "Import job reports" |
203 | +msgstr "Importer le rapport" |
204 | + |
205 | +#. module: msf_tools |
206 | +#: field:automated.import.job,file_sum:0 |
207 | +#: field:manual.import.job,file_sum:0 |
208 | +msgid "Check sum" |
209 | +msgstr "Somme d'intégrité" |
210 | + |
211 | +#. module: msf_tools |
212 | +#: view:automated.import.job:0 |
213 | +#: view:manual.import.job:0 |
214 | +msgid "Import results" |
215 | +msgstr "Résultats de l'import" |
216 | + |
217 | +#. module: msf_tools |
218 | +#: view:manual.import.job:0 |
219 | +msgid "Process in background" |
220 | +msgstr "Exécuter en tâche de fond" |
221 | + |
222 | +#. module: msf_tools |
223 | +#: view:automated.import.job:0 |
224 | +#: view:manual.import.job:0 |
225 | +msgid "Import job requests" |
226 | +msgstr "Importer une tâche" |
227 | + |
228 | +#. module: msf_tools |
229 | +#: field:automated.import.job,filename:0 |
230 | +#: field:manual.import.job,filename:0 |
231 | +msgid "Name of the file to import" |
232 | +msgstr "Nom du fichier à importer" |
233 | + |
234 | +#. module: msf_tools |
235 | +#: field:automated.import.job,nb_processed_records:0 |
236 | +#: field:manual.import.job,nb_processed_records:0 |
237 | +msgid "# of processed records" |
238 | +msgstr "Nombre d'enregistrements exécutés" |
239 | + |
240 | +#. module: msf_tools |
241 | +#: code:addons/msf_tools/automated_import_job.py:306 |
242 | +#, python-format |
243 | +msgid "All entries have been rejected , bad file format ? See the import report in attachment for further informations" |
244 | +msgstr "Toutes les entrées ont été rejeté, le fichier est-il bien formaté ? Pour plus d'informations, vous pouvez consulter le rapport en attachement." |
245 | + |
246 | +#. module: msf_tools |
247 | +#: code:addons/msf_tools/automated_import_job.py:310 |
248 | +#, python-format |
249 | +msgid "Some lines has been rejected, so we did not import anything. See the import report in attachment for further informations" |
250 | +msgstr "Des enregistrements ont été rejeté, nous n'avons rien importé. Pour plus d'informations, vous pouvez consulter le rapport en attachement." |
251 | + |
252 | +#. module: msf_tools |
253 | +#: code:addons/msf_tools/automated_import_job.py:271 |
254 | +#, python-format |
255 | +msgid "The input file doesn't contain any record" |
256 | +msgstr "Le fichier ne contient aucun enregistrement" |
257 | + |
258 | +#. module: msf_tools |
259 | +#: model:ir.actions.act_window,name:msf_tools.manual_import_job_action |
260 | +#: model:ir.ui.menu,name:msf_tools.manual_import_job_menu |
261 | +msgid "Manual imports" |
262 | +msgstr "Import manuel" |
263 | + |
264 | +#. module: msf_tools |
265 | +#: view:automated.import:0 |
266 | +#: model:ir.actions.act_window,name:msf_tools.automated_import_action |
267 | +#: model:ir.ui.menu,name:msf_tools.automated_import_menu |
268 | +msgid "Automated imports" |
269 | +msgstr "Import automatique" |
270 | + |
271 | +#. module: msf_tools |
272 | +#: code:addons/msf_tools/manual_import_job.py:63 |
273 | +#, python-format |
274 | +msgid "You cannot delete an import job which is in progress" |
275 | +msgstr "Vous ne pouvez pas supprimer un import en cours" |
276 | +>>>>>>> MERGE-SOURCE |
277 | |
278 | === modified file 'bin/addons/msf_tools/__init__.py' |
279 | --- bin/addons/msf_tools/__init__.py 2016-10-26 16:06:31 +0000 |
280 | +++ bin/addons/msf_tools/__init__.py 2016-11-22 13:43:46 +0000 |
281 | @@ -23,4 +23,7 @@ |
282 | import automated_import_function |
283 | import automated_import |
284 | import automated_import_job |
285 | +<<<<<<< TREE |
286 | import report |
287 | +======= |
288 | +import manual_import_job>>>>>>> MERGE-SOURCE |
289 | |
290 | === modified file 'bin/addons/msf_tools/__openerp__.py' |
291 | --- bin/addons/msf_tools/__openerp__.py 2016-10-26 16:06:31 +0000 |
292 | +++ bin/addons/msf_tools/__openerp__.py 2016-11-22 13:43:46 +0000 |
293 | @@ -38,6 +38,7 @@ |
294 | 'views/automated_import_view.xml', |
295 | 'views/automated_import_function_view.xml', |
296 | 'views/automated_import_job_view.xml', |
297 | + 'views/manual_import_job_view.xml', |
298 | 'security/ir.model.access.csv', |
299 | 'report/report_stopped_products_view.xml', |
300 | 'report/report_stopped_products_report.xml', |
301 | |
302 | === modified file 'bin/addons/msf_tools/automated_import_job.py' |
303 | --- bin/addons/msf_tools/automated_import_job.py 2016-11-18 09:45:12 +0000 |
304 | +++ bin/addons/msf_tools/automated_import_job.py 2016-11-22 13:43:46 +0000 |
305 | @@ -23,8 +23,11 @@ |
306 | import csv |
307 | import time |
308 | import shutil |
309 | +import pooler |
310 | import base64 |
311 | import hashlib |
312 | +from tempfile import NamedTemporaryFile |
313 | +from tools import ustr |
314 | |
315 | from osv import osv |
316 | from osv import fields |
317 | @@ -78,7 +81,10 @@ |
318 | |
319 | res = {} |
320 | for job in self.browse(cr, uid, ids, context=context): |
321 | - res[job.id] = '%s - %s' % (job.import_id.function_id.name, job.start_time or _('Not started')) |
322 | + if self._name == 'manual.import.job': |
323 | + res[job.id] = '%s' % (job.start_time or _('Not started')) |
324 | + else: |
325 | + res[job.id] = '%s - %s' % (job.import_id.function_id.name, job.start_time or _('Not started')) |
326 | |
327 | return res |
328 | |
329 | @@ -161,11 +167,14 @@ |
330 | data_obj = self.pool.get('ir.model.data') |
331 | |
332 | if context is None: |
333 | - context = [] |
334 | + context = {} |
335 | |
336 | if isinstance(ids, (int, long)): |
337 | ids = [ids] |
338 | |
339 | + if context.get('import_in_bg'): |
340 | + cr = pooler.get_db(cr.dbname).cursor() |
341 | + |
342 | for job in self.browse(cr, uid, ids, context=context): |
343 | nb_rejected = 0 |
344 | nb_processed = 0 |
345 | @@ -175,10 +184,15 @@ |
346 | error = None |
347 | data64 = None |
348 | filename = False |
349 | + |
350 | + self.write(cr, uid, [job.id], {'state': 'in_progress'}, context=context) |
351 | + if context.get('import_in_bg'): |
352 | + cr.commit() |
353 | |
354 | try: |
355 | - for path in [('src_path', 'r'), ('dest_path', 'w'), ('report_path', 'w')]: |
356 | - import_obj.path_is_accessible(job.import_id[path[0]], path[1]) |
357 | + if self._name != 'manual.import.job': |
358 | + for path in [('src_path', 'r'), ('dest_path', 'w'), ('report_path', 'w')]: |
359 | + import_obj.path_is_accessible(job.import_id[path[0]], path[1]) |
360 | except osv.except_osv as e: |
361 | error = str(e) |
362 | # In case of manual processing, raise the error |
363 | @@ -215,11 +229,9 @@ |
364 | }, context=context) |
365 | continue |
366 | else: |
367 | - oldest_file = open(os.path.join(job.import_id.src_path, job.filename), 'wb+') |
368 | - oldest_file.write(base64.decodestring(job.file_to_import)) |
369 | - oldest_file.close() |
370 | md5 = hashlib.md5(job.file_to_import).hexdigest() |
371 | |
372 | +<<<<<<< TREE |
373 | if job.file_sum != md5: |
374 | if self.search_exist(cr, uid, [('file_sum', '=', md5), ('id', '!=', job.id)], context=context): |
375 | self.write(cr, uid, [job.id], {'file_sum': md5}, context=context) |
376 | @@ -235,13 +247,46 @@ |
377 | } |
378 | |
379 | oldest_file = os.path.join(job.import_id.src_path, job.filename) |
380 | +======= |
381 | + if self._name != 'manual.import.job': |
382 | + oldest_file = open(os.path.join(job.import_id.src_path, job.filename), 'wb+') |
383 | + oldest_file.write(base64.decodestring(job.file_to_import)) |
384 | + oldest_file.close() |
385 | + oldest_file = os.path.join(job.import_id.src_path, job.filename) |
386 | + |
387 | + if job.file_sum != md5: |
388 | + if self.search(cr, uid, [('file_sum', '=', md5), ('id', '!=', job.id)], limit=1, order='NO_ORDER', context=context): |
389 | + self.write(cr, uid, [job.id], {'file_sum': md5}, context=context) |
390 | + return { |
391 | + 'type': 'ir.actions.act_window', |
392 | + 'res_model': self._name, |
393 | + 'res_id': ids[0], |
394 | + 'view_type': 'form', |
395 | + 'view_mode': 'form,tree', |
396 | + 'target': 'new', |
397 | + 'view_id': [data_obj.get_object_reference(cr, uid, 'msf_tools', 'automated_import_job_file_view')[1]], |
398 | + 'context': context, |
399 | + } |
400 | + |
401 | + else: |
402 | + temp_file = NamedTemporaryFile('w', suffix='.xml') |
403 | + temp_file.write(base64.decodestring(job.file_to_import)) |
404 | + temp_file.flush() |
405 | + oldest_file = temp_file.name # temp file path |
406 | + |
407 | +>>>>>>> MERGE-SOURCE |
408 | filename = job.filename |
409 | data64 = base64.encodestring(job.file_to_import) |
410 | |
411 | # Process import |
412 | +<<<<<<< TREE |
413 | error_message = [] |
414 | state = 'done' |
415 | +======= |
416 | + nb_processed, nb_rejected = 0, 0 |
417 | +>>>>>>> MERGE-SOURCE |
418 | try: |
419 | +<<<<<<< TREE |
420 | processed, rejected, headers = getattr( |
421 | self.pool.get(job.import_id.function_id.model_id.model), |
422 | job.import_id.function_id.method_to_call |
423 | @@ -256,6 +301,63 @@ |
424 | line_message = _('Line %s: ' % resjected_line[0]) |
425 | line_message += resjected_line[2] |
426 | error_message.append(line_message) |
427 | +======= |
428 | + if self._name == 'manual.import.job': |
429 | + self.write(cr, uid, [job.id], {'state': 'in_progress'}, context=context) |
430 | + if context.get('import_in_bg'): |
431 | + cr.commit() |
432 | + processed, rejected, headers = getattr( |
433 | + self.pool.get(job.function_id.model_id.model), |
434 | + job.function_id.method_to_call |
435 | + )(cr, uid, oldest_file) |
436 | + |
437 | + # create a report that resume rejected lines, so user can |
438 | + # modify his input file according to errors : |
439 | + report_name = job.filename[0:job.filename.rfind('.')] + '.csv' if job.filename.rfind('.') != -1 else job.filename + '.csv' |
440 | + report_name = "report_" + report_name |
441 | + report_content = "" |
442 | + if rejected: |
443 | + temp_report = NamedTemporaryFile() |
444 | + csv_writer = csv.writer(temp_report, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL) |
445 | + headers_row = [_('Line number')] + headers + [_('Error')] |
446 | + csv_writer.writerow(headers_row) |
447 | + for pl in rejected: |
448 | + pl_row = [pl[0]] + pl[1] + [pl[2]] |
449 | + csv_writer.writerow(pl_row) |
450 | + temp_report.seek(0) |
451 | + report_content = temp_report.read() |
452 | + temp_report.close() |
453 | + else: |
454 | + report_content = _('All records have been successfully processed') |
455 | + |
456 | + self.pool.get('ir.attachment').create(cr, uid, { |
457 | + 'name': report_name, |
458 | + 'datas_fname': filename, |
459 | + 'description': '%s Lines' % (rejected and _('Rejected') or _('Processed')), |
460 | + 'res_model': self._name, |
461 | + 'res_id': job.id, |
462 | + 'datas': base64.encodestring(report_content), |
463 | + }) |
464 | + |
465 | + nb_processed, nb_rejected = len(processed), len(rejected) |
466 | + if nb_processed == 0 and nb_rejected == 0: |
467 | + raise Exception(_('The input file doesn\'t contain any record')) |
468 | + elif nb_processed == 0: |
469 | + raise Exception(_('All entries have been rejected , bad file format ? See the import report in attachment for further informations')) |
470 | + elif nb_rejected > 0: |
471 | + nb_rejected += nb_processed |
472 | + nb_processed = 0 |
473 | + raise Exception(_('Some lines has been rejected, so we did not import anything. See the import report in attachment for further informations')) |
474 | + else: |
475 | + processed, rejected, headers = getattr( |
476 | + self.pool.get(job.import_id.function_id.model_id.model), |
477 | + job.import_id.function_id.method_to_call |
478 | + )(cr, uid, oldest_file) |
479 | + if processed: |
480 | + nb_processed = self.generate_file_report(cr, uid, job, processed, headers) |
481 | + if rejected: |
482 | + nb_rejected = self.generate_file_report(cr, uid, job, rejected, headers, rejected=True) |
483 | +>>>>>>> MERGE-SOURCE |
484 | |
485 | self.write(cr, uid, [job.id], { |
486 | 'filename': filename, |
487 | @@ -272,18 +374,26 @@ |
488 | self.write(cr, uid, [job.id], { |
489 | 'filename': False, |
490 | 'start_time': start_time, |
491 | +<<<<<<< TREE |
492 | 'end_time': time.strftime('%Y-%m-%d %H:%M:%S'), |
493 | 'nb_processed_records': 0, |
494 | 'nb_rejected_records': 0, |
495 | 'comment': str(e), |
496 | +======= |
497 | + 'end_time': time.strftime('%Y-%m-%d'), |
498 | + 'nb_processed_records': nb_processed, |
499 | + 'nb_rejected_records': nb_rejected, |
500 | + 'comment': ustr(e), |
501 | +>>>>>>> MERGE-SOURCE |
502 | 'file_sum': md5, |
503 | 'file_to_import': data64, |
504 | 'state': 'error', |
505 | }, context=context) |
506 | finally: |
507 | - move_to_process_path(filename, job.import_id.src_path, job.import_id.dest_path) |
508 | + if self._name != 'manual.import.job': |
509 | + move_to_process_path(filename, job.import_id.src_path, job.import_id.dest_path) |
510 | |
511 | - return { |
512 | + res = { |
513 | 'type': 'ir.actions.act_window', |
514 | 'res_model': self._name, |
515 | 'res_id': ids[0], |
516 | @@ -293,6 +403,19 @@ |
517 | 'context': context, |
518 | } |
519 | |
520 | + if self._name == 'manual.import.job': |
521 | + res.update({ |
522 | + 'view_id': [data_obj.get_object_reference(cr, uid, 'msf_tools', 'manual_import_job_form_view')[1]], |
523 | + 'target': 'same', |
524 | + }) |
525 | + |
526 | + if context.get('import_in_bg'): |
527 | + cr.commit() |
528 | + cr.close(True) |
529 | + return |
530 | + |
531 | + return res |
532 | + |
533 | |
534 | def generate_file_report(self, cr, uid, job_brw, data_lines, headers, rejected=False): |
535 | """ |
536 | @@ -334,7 +457,7 @@ |
537 | 'name': filename, |
538 | 'datas_fname': filename, |
539 | 'description': '%s Lines' % (rejected and _('Rejected') or _('Processed')), |
540 | - 'res_model': 'automated.import.job', |
541 | + 'res_model': self._name, |
542 | 'res_id': job_brw.id, |
543 | 'datas': base64.encodestring(csvfile.read()) |
544 | }) |
545 | |
546 | === added file 'bin/addons/msf_tools/manual_import_job.py' |
547 | --- bin/addons/msf_tools/manual_import_job.py 1970-01-01 00:00:00 +0000 |
548 | +++ bin/addons/msf_tools/manual_import_job.py 2016-11-22 13:43:46 +0000 |
549 | @@ -0,0 +1,101 @@ |
550 | +# -*- coding: utf-8 -*- |
551 | +############################################################################## |
552 | +# |
553 | +# OpenERP, Open Source Management Solution |
554 | +# Copyright (C) 2016 TeMPO Consulting, MSF |
555 | +# |
556 | +# This program is free software: you can redistribute it and/or modify |
557 | +# it under the terms of the GNU Affero General Public License as |
558 | +# published by the Free Software Foundation, either version 3 of the |
559 | +# License, or (at your option) any later version. |
560 | +# |
561 | +# This program is distributed in the hope that it will be useful, |
562 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
563 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
564 | +# GNU Affero General Public License for more details. |
565 | +# |
566 | +# You should have received a copy of the GNU Affero General Public License |
567 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
568 | +# |
569 | +############################################################################## |
570 | + |
571 | +from osv import osv |
572 | +from osv import fields |
573 | +import threading |
574 | + |
575 | +from tools.translate import _ |
576 | +from automated_import_job import all_files_under, move_to_process_path |
577 | + |
578 | + |
579 | +class manual_import_job(osv.osv): |
580 | + _name = 'manual.import.job' |
581 | + _inherit = 'automated.import.job' |
582 | + |
583 | + _columns = { |
584 | + 'import_id': fields.many2one( |
585 | + 'automated.import', |
586 | + string='Automated import', |
587 | + readonly=True, |
588 | + required=False, |
589 | + ), |
590 | + 'file_to_import': fields.binary( |
591 | + string='File to import', |
592 | + required=True, |
593 | + ), |
594 | + 'function_id': fields.many2one( |
595 | + 'automated.import.function', |
596 | + string='Functionality', |
597 | + required=True, |
598 | + ), |
599 | + } |
600 | + |
601 | + _order = "name desc" |
602 | + |
603 | + |
604 | + def unlink(self, cr, uid, ids, context=None): |
605 | + ''' |
606 | + method called when user wants to delete import |
607 | + ''' |
608 | + # do not delete a job which is in progress: |
609 | + for job_id in ids: |
610 | + job_state = self.read(cr, uid, [job_id], ['state'], context=context)[0]['state'] |
611 | + if job_state == 'in_progress': |
612 | + raise osv.except_osv(_('Error'), _('You cannot delete an import job which is in progress')) |
613 | + |
614 | + return super(manual_import_job, self).unlink(cr, uid, ids, context=context) |
615 | + |
616 | + |
617 | + def process_import_bg(self, cr, uid, ids, context=None): |
618 | + """ |
619 | + Method called when user click on button 'import in background' in Manual imports |
620 | + Create a new thread that process import in background |
621 | + """ |
622 | + data_obj = self.pool.get('ir.model.data') |
623 | + |
624 | + if context is None: |
625 | + context = {} |
626 | + |
627 | + context.update({'import_in_bg': True}) |
628 | + |
629 | + cr.commit() |
630 | + new_thread = threading.Thread( |
631 | + target=self.process_import, |
632 | + args=(cr, uid, ids, context) |
633 | + ) |
634 | + new_thread.start() |
635 | + |
636 | + res = { |
637 | + 'type': 'ir.actions.act_window', |
638 | + 'res_model': self._name, |
639 | + 'res_id': ids[0], |
640 | + 'view_type': 'form', |
641 | + 'view_mode': 'form,tree', |
642 | + 'view_id': [data_obj.get_object_reference(cr, uid, 'msf_tools', 'manual_import_job_info_view')[1]], |
643 | + 'target': 'same', |
644 | + 'context': context, |
645 | + } |
646 | + |
647 | + return res |
648 | + |
649 | + |
650 | +manual_import_job() |
651 | \ No newline at end of file |
652 | |
653 | === added file 'bin/addons/msf_tools/views/manual_import_job_view.xml' |
654 | --- bin/addons/msf_tools/views/manual_import_job_view.xml 1970-01-01 00:00:00 +0000 |
655 | +++ bin/addons/msf_tools/views/manual_import_job_view.xml 2016-11-22 13:43:46 +0000 |
656 | @@ -0,0 +1,99 @@ |
657 | +<?xml version="1.0" encoding="utf-8" ?> |
658 | +<openerp> |
659 | + <data> |
660 | + |
661 | + <record id="manual_import_job_search_view" model="ir.ui.view"> |
662 | + <field name="name">manual.import.job.search.view</field> |
663 | + <field name="model">manual.import.job</field> |
664 | + <field name="type">search</field> |
665 | + <field name="arch" type="xml"> |
666 | + <search string="Import job requests"> |
667 | + <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state', '=', 'draft')]" help="Draft jobs" /> |
668 | + <filter icon="terp-gnome-cpu-frequency-applet+" string="In progress" name="in_progress" domain="[('state', '=', 'in_progress')]" help="In progress jobs" /> |
669 | + <filter icon="terp-dialog-close" string="Done" name="done" domain="[('state', '=', 'done')]" help="Done jobs" /> |
670 | + <filter icon="terp-emblem-important" string="Exception" name="exceptions" domain="[('state', '=', 'error')]" help="Jobs with error" /> |
671 | + <separator orientation="vertical" /> |
672 | + <field name="name" /> |
673 | + <field name="function_id" /> |
674 | + </search> |
675 | + </field> |
676 | + </record> |
677 | + |
678 | + <record id="manual_import_job_tree_view" model="ir.ui.view"> |
679 | + <field name="name">manual.import.job.tree.view</field> |
680 | + <field name="model">manual.import.job</field> |
681 | + <field name="type">tree</field> |
682 | + <field name="arch" type="xml"> |
683 | + <tree string="Import job reports"> |
684 | + <field name="name" /> |
685 | + <field name="function_id" /> |
686 | + <field name="state" /> |
687 | + </tree> |
688 | + </field> |
689 | + </record> |
690 | + |
691 | + <record id="manual_import_job_form_view" model="ir.ui.view"> |
692 | + <field name="name">manual.import.job.form.view</field> |
693 | + <field name="model">manual.import.job</field> |
694 | + <field name="type">form</field> |
695 | + <field name="arch" type="xml"> |
696 | + <form string="Import job report"> |
697 | + <separator colspan="4" string="Import file" /> |
698 | + <field name="file_to_import" filename="filename" required="1" /> |
699 | + <field name="function_id" required="1" widget="selection" attrs="{'readonly': [('state', 'in', ['done', 'error'])]}" /> |
700 | + <field name="filename" invisible="1" /> |
701 | + <group colspan="4" states='done,error'> |
702 | + <separator colspan="4" string="Import results" /> |
703 | + <field name="nb_processed_records" /> |
704 | + <field name="nb_rejected_records" /> |
705 | + <field name="start_time" /> |
706 | + <field name="end_time" /> |
707 | + <field name="comment" colspan="4" /> |
708 | + <separator colspan="4" string="States" /> |
709 | + </group> |
710 | + <field name="state" /> |
711 | + <button name="process_import" type="object" states="draft" string="Process import" icon="gtk-execute" /> |
712 | + <button name="process_import_bg" type="object" states="draft" string="Process in background" icon="gtk-execute" /> |
713 | + </form> |
714 | + </field> |
715 | + </record> |
716 | + |
717 | + <record id="manual_import_job_info_view" model="ir.ui.view"> |
718 | + <field name="name">manual.import.job.info.view</field> |
719 | + <field name="model">manual.import.job</field> |
720 | + <field name="type">form</field> |
721 | + <field name="priority" eval="99" /> |
722 | + <field name="arch" type="xml"> |
723 | + <form string="Status of the import" hide_new_button="1" hide_delete_button="1"> |
724 | + <label> </label> |
725 | + <group colspan="2" col="2"> |
726 | + <html> |
727 | + <div style="align: center"> |
728 | + <p style="font-size:14px;align:center"> |
729 | + Your import demand will be treated quickly.<br /> |
730 | + </p> |
731 | + <p style="font-size:14px;align:center"> |
732 | + You can check the state of your import in menu TOOLS > Manual imports.<br /> |
733 | + </p> |
734 | + </div> |
735 | + </html> |
736 | + </group> |
737 | + <label> </label> |
738 | + </form> |
739 | + </field> |
740 | + </record> |
741 | + |
742 | + <record id="manual_import_job_action" model="ir.actions.act_window"> |
743 | + <field name="name">Manual imports</field> |
744 | + <field name="res_model">manual.import.job</field> |
745 | + <field name="view_type">form</field> |
746 | + <field name="view_mode">tree,form</field> |
747 | + </record> |
748 | + |
749 | + <menuitem |
750 | + id="manual_import_job_menu" |
751 | + action="manual_import_job_action" |
752 | + parent="object_query.menu_preferences" /> |
753 | + |
754 | + </data> |
755 | +</openerp> |