Merge lp:~mallorymarcot/unifield-server/us-1830 into lp:unifield-server

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
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+310850@code.launchpad.net
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>

Subscribers

People subscribed via source and target branches