Merge lp:~unifield-team/unifield-server/us-1167 into lp:unifield-server

Proposed by Quentin THEURET @Amaris
Status: Merged
Merged at revision: 4191
Proposed branch: lp:~unifield-team/unifield-server/us-1167
Merge into: lp:unifield-server
Diff against target: 1246 lines (+927/-17)
12 files modified
bin/addons/mission_stock/mission_stock.py (+16/-5)
bin/addons/msf_profile/data/patches.xml (+5/-1)
bin/addons/msf_profile/i18n/fr_MF.po (+130/-9)
bin/addons/msf_profile/msf_profile.py (+49/-0)
bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv (+2/-2)
bin/addons/msf_tools/__openerp__.py (+2/-0)
bin/addons/msf_tools/report/__init__.py (+1/-0)
bin/addons/msf_tools/report/report_inconsistencies.py (+433/-0)
bin/addons/msf_tools/report/report_inconsistencies_report.xml (+20/-0)
bin/addons/msf_tools/report/report_inconsistencies_view.xml (+92/-0)
bin/addons/msf_tools/report/report_inconsistencies_xls.mako (+139/-0)
bin/addons/product_attributes/product_attributes.py (+38/-0)
To merge this branch: bzr merge lp:~unifield-team/unifield-server/us-1167
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+315900@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/mission_stock/mission_stock.py'
2--- bin/addons/mission_stock/mission_stock.py 2016-12-05 14:26:00 +0000
3+++ bin/addons/mission_stock/mission_stock.py 2017-02-03 13:54:39 +0000
4@@ -547,20 +547,25 @@
5 line_obj = self.pool.get('stock.mission.report.line')
6 for report in self.read(cr, uid, report_ids, ['local_report', 'full_view'], context=context):
7 # Create one line by product
8- cr.execute('''SELECT p.id, ps.code
9- FROM product_product p, product_template pt
10- LEFT JOIN product_status ps ON pt.state = ps.id
11+ cr.execute('''SELECT p.id, ps.code, p.active, p.state_ud, pis.code
12+ FROM product_product p, product_template pt, product_status ps, product_international_status pis
13 WHERE p.product_tmpl_id = pt.id
14+ AND pt.state = ps.id
15+ AND p.international_status = pis.id
16 AND NOT EXISTS (
17 SELECT product_id
18 FROM
19 stock_mission_report_line smrl WHERE mission_report_id = %s
20 AND p.id = smrl.product_id)
21 ''' % report['id'])
22- for product, prod_state in cr.fetchall():
23+ for product, prod_state, prod_active, prod_state_ud, prod_creator in cr.fetchall():
24 line_obj.create(cr, uid, {
25- 'product_id': product,
26+ 'product_id': product,
27 'mission_report_id': report['id'],
28+ 'product_state': prod_state,
29+ 'product_active': prod_active,
30+ 'state_ud': prod_state_ud,
31+ 'international_status_code': prod_creator,
32 'product_state': prod_state or '',
33 }, context=context)
34
35@@ -957,6 +962,9 @@
36 'stock.mission.report.line': (lambda self, cr, uid, ids, c=None: ids, ['product_id'], 10),
37 },
38 write_relate=False),
39+ 'product_active': fields.boolean(string='Active'),
40+ 'state_ud': fields.char(size=128, string='UniData status'),
41+ 'international_status_code': fields.char(size=128, string='Product Creator'),
42 'mission_report_id': fields.many2one('stock.mission.report', string='Mission Report', required=True),
43 'internal_qty': fields.float(digits=(16,2), string='Instance Stock'),
44 'internal_val': fields.function(_get_internal_val, method=True, type='float', string='Instance Stock Val.'),
45@@ -985,6 +993,7 @@
46 string='HQ Instance',
47 required=True,
48 ),
49+
50 }
51
52 @tools.cache(skiparg=2)
53@@ -1019,6 +1028,8 @@
54 'in_pipe_coor_val': 0.00,
55 'instance_id': _get_default_destination_instance_id,
56 'product_state': '',
57+ 'state_ud': '',
58+ 'international_status_code': '',
59 }
60
61 def update_full_view_line(self, cr, uid, context=None):
62
63=== modified file 'bin/addons/msf_profile/data/patches.xml'
64--- bin/addons/msf_profile/data/patches.xml 2017-01-31 16:17:06 +0000
65+++ bin/addons/msf_profile/data/patches.xml 2017-02-03 13:54:39 +0000
66@@ -150,7 +150,11 @@
67 <record id="us_1671_stopped_products" model="patch.scripts">
68 <field name="method">us_1671_stopped_products</field>
69 </record>
70-
71+
72+ <record id="us_1167_status_inconsistencies" model="patch.scripts">
73+ <field name="method">us_1167_status_inconsistencies</field>
74+ </record>
75+
76 <record id="us_2075_partner_locally_created" model="patch.scripts">
77 <field name="method">us_2075_partner_locally_created</field>
78 </record>
79
80=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
81--- bin/addons/msf_profile/i18n/fr_MF.po 2017-01-31 16:17:06 +0000
82+++ bin/addons/msf_profile/i18n/fr_MF.po 2017-02-03 13:54:39 +0000
83@@ -4658,7 +4658,7 @@
84 msgid "Search Real Kit Composition Item"
85 msgstr "Rechercher l'Article de la Composition Réelle du Kit"
86
87-#. modules: process, financing_contract, account_voucher, account_hq_entries, account_override, product_attributes, base_report_designer, msf_accrual, return_claim, account_mcdb, analytic, msf_doc_import, stock, product, msf_homere_interface, hr, register_accounting, base, procurement_report, account_invoice_split, account, msf_outgoing, msf_audittrail, sale, procurement, purchase, product_list
88+#. modules: process, financing_contract, account_voucher, account_hq_entries, account_override, product_attributes, base_report_designer, msf_accrual, return_claim, account_mcdb, analytic, msf_doc_import, stock, product, msf_homere_interface, hr, register_accounting, base, procurement_report, account_invoice_split, account, msf_outgoing, msf_audittrail, sale, procurement, purchase, product_list, msf_tools
89 #: view:account.account.type:0
90 #: field:account.account.type,note:0
91 #: view:account.analytic.account:0
92@@ -4735,6 +4735,7 @@
93 #: report:msf.report_reception_in:0
94 #: view:stock.production.lot.revision:0
95 #: field:stock.production.lot.revision,description:0
96+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:81
97 #, python-format
98 msgid "Description"
99 msgstr "Description"
100@@ -6421,6 +6422,7 @@
101 #: view:automated.import.job:0
102 #: selection:automated.import.job,state:0
103 #: selection:export.report.stopped.products,state:0
104+#: selection:export.report.inconsistencies,state:0
105 #: view:account.bank.statement:0
106 #: selection:account.bank.statement,state:0
107 #: view:account.invoice:0
108@@ -6526,6 +6528,7 @@
109 #: selection:tender,internal_state:0
110 #: selection:tender,state:0
111 #: selection:tender.line,state:0
112+#: view:automated.import.job:0
113 #, python-format
114 msgid "Draft"
115 msgstr "Brouillon"
116@@ -7368,12 +7371,13 @@
117 msgid "Earmarked"
118 msgstr "Réservé"
119
120-#. modules: mission_stock, base, msf_instance
121+#. modules: mission_stock, base, msf_instance, msf_tools
122 #: field:workflow.workitem,inst_id:0
123 #: field:stock.mission.report,instance_id:0
124 #: field:account.target.costcenter,instance_id:0
125 #: model:ir.actions.act_window,name:msf_instance.action_msf_instance_setup
126 #: field:msf.instance,instance:0
127+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:79
128 msgid "Instance"
129 msgstr "Instance"
130
131@@ -8393,10 +8397,11 @@
132 msgid "Budget Import"
133 msgstr "Budget - Importation"
134
135-#. modules: supplier_catalogue, resource, msf_instance
136+#. modules: supplier_catalogue, resource, msf_instance, msf_tools
137 #: selection:msf.instance,state:0
138 #: view:resource.resource:0
139 #: view:supplier.catalogue:0
140+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:106
141 msgid "Inactive"
142 msgstr "Inactif"
143
144@@ -10646,7 +10651,7 @@
145 msgid "The new %s Event %s has been created."
146 msgstr "Le nouveau %s Evénement %s a été créé."
147
148-#. modules: msf_budget, account, reason_types_moves, resource, product_attributes, financing_contract, res_currency_tables, msf_instance, product, sale, analytic, base, stock, analytic_distribution
149+#. modules: msf_budget, account, reason_types_moves, resource, product_attributes, financing_contract, res_currency_tables, msf_instance, product, sale, analytic, base, stock, analytic_distribution, msf_tools
150 #: field:account.account,code:0
151 #: report:account.account.balance:0
152 #: field:account.account.template,code:0
153@@ -10683,6 +10688,7 @@
154 #: field:resource.resource,code:0
155 #: report:msf.report_reception_in:0
156 #: field:stock.incoterms,code:0
157+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:80
158 msgid "Code"
159 msgstr "Code"
160
161@@ -11658,6 +11664,8 @@
162 #: selection:stock.forecast.line,state:0
163 #: view:stock.move:0
164 #: selection:sync.client.entity_manager,state:0
165+#: selection:export.report.inconsistencies,state:0
166+#: selection:export.report.stopped.products,state:0
167 msgid "Ready"
168 msgstr "Prêt"
169
170@@ -23526,7 +23534,7 @@
171 msgid "Send SMS"
172 msgstr "Envoyer SMS"
173
174-#. modules: msf_partner, stock_override, kit, account_override, product_attributes, msf_doc_import, purchase_msf, msf_profile
175+#. modules: msf_partner, stock_override, kit, account_override, product_attributes, msf_doc_import, purchase_msf, msf_profile, msf_tools
176 #: code:addons/account_override/wizard/wizard_import_mapping.py:59
177 #: code:addons/kit/kit.py:835
178 #: code:addons/kit/kit.py:840
179@@ -23604,9 +23612,22 @@
180 #: selection:wizard.import.po.simulation.screen,state:0
181 #: selection:wizard.import.po.simulation.screen.line,type_change:0
182 #: selection:wizard.simu.import.po.line,change_type:0
183+#: code:addons/msf_tools/automated_import.py:57
184+#: code:addons/msf_tools/automated_import.py:62
185+#: code:addons/msf_tools/automated_import.py:67
186+#: code:addons/msf_tools/automated_import.py:196
187+#: code:addons/msf_tools/automated_import.py:227
188+#: code:addons/msf_tools/automated_import.py:386
189+#: code:addons/msf_tools/automated_import.py:407
190+#: code:addons/msf_tools/automated_import_function.py:65
191+#: code:addons/msf_tools/automated_import_job.py:324
192+#: code:addons/msf_tools/msf_tools.py:875
193+#: code:addons/msf_tools/msf_tools.py:888
194+#: code:addons/msf_tools/report/report_inconsistencies.py:106
195+#: code:addons/msf_tools/report/report_stopped_products.py:106
196 #, python-format
197 msgid "Error"
198-msgstr "Error"
199+msgstr "Erreur"
200
201 #. modules: account_activable, analytic_distribution
202 #: code:addons/account_activable/account_activable.py:51
203@@ -32054,6 +32075,8 @@
204 #: selection:wizard.import.po,state:0
205 #: view:sourcing.line:0
206 #: selection:wizard.register.import,state:0
207+#: selection::export.report.inconsistencies,state:0
208+#: selection:export.report.stopped.products,state:0
209 #, python-format
210 msgid "In Progress"
211 msgstr "En Cours"
212@@ -42472,8 +42495,10 @@
213 msgid "Asia/Phnom_Penh"
214 msgstr "Asia/Phnom_Penh"
215
216-#. module: product_attributes
217+#. modules: product_attributes, mission_stock, msf_tools
218 #: field:product.product,international_status:0
219+#: field:stock.mission.report.line,international_status_code:0
220+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:82
221 msgid "Product Creator"
222 msgstr "Créateur produit"
223
224@@ -43961,6 +43986,9 @@
225 #: field:wizard.import.stock.warehouse.orderpoint.line,state:0
226 #: field:wizard.import.supplier.catalogue,state:0
227 #: field:wizard.import.threshold.value.line,state:0
228+#: field:automated.import.job,state:0
229+#: field:export.report.inconsistencies,state:0
230+#: field:export.report.stopped.products,state:0
231 msgid "State"
232 msgstr "État"
233
234@@ -49776,13 +49804,14 @@
235 msgid "RWANDAN FRANC"
236 msgstr "RWANDAN FRANC"
237
238-#. modules: product_attributes, purchase_override, account_hq_entries, sale
239+#. modules: product_attributes, purchase_override, account_hq_entries, sale, msf_tools
240 #: model:ir.ui.menu,name:account_hq_entries.menu_hq
241 #: selection:product.product,international_status:0
242 #: report:msf.purchase.order:0
243 #: report:msf.purchase.quotation:0
244 #: report:purchase.order.merged:0
245 #: report:msf.sale.order:0
246+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:90
247 msgid "HQ"
248 msgstr "HQ / Siège"
249
250@@ -53592,7 +53621,7 @@
251 msgid "Navajo"
252 msgstr "Navajo"
253
254-#. modules: product_nomenclature, process, financing_contract, account_override, procurement_cycle, supplier_catalogue, unifield_setup, stock, product, msf_homere_interface, hr, msf_instance, purchase_override, kit, sale_override, base, res_currency_functional, procurement_report, threshold_value, account, resource, msf_partner, procurement_auto, procurement, analytic_distribution
255+#. modules: product_nomenclature, process, financing_contract, account_override, procurement_cycle, supplier_catalogue, unifield_setup, stock, product, msf_homere_interface, hr, msf_instance, purchase_override, kit, sale_override, base, res_currency_functional, procurement_report, threshold_value, account, resource, msf_partner, procurement_auto, procurement, analytic_distribution, mission_stock, msf_tools
256 #: field:account.account,active:0
257 #: field:account.analytic.journal,active:0
258 #: field:account.journal.period,active:0
259@@ -53647,6 +53676,9 @@
260 #: field:supplier.catalogue,current:0
261 #: field:threshold.value,active:0
262 #: field:ir.ui.menu,active:0
263+#: field:stock.mission.report.line,product_active:0
264+#: field:automated.import,active:0
265+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:106
266 msgid "Active"
267 msgstr "Actif"
268
269@@ -54315,6 +54347,8 @@
270 #: code:addons/kit/wizard/substitute.py:687
271 #: code:addons/kit/wizard/substitute.py:1024
272 #: code:addons/mission_stock/mission_stock.py:71
273+#: code:addons/mission_stock/report/stock_mission_report.py:66
274+#: code:addons/mission_stock/report/stock_mission_report.py:77
275 #: code:addons/mission_stock/wizard/mission_stock_wizard.py:54
276 #: code:addons/mission_stock/wizard/mission_stock_wizard.py:88
277 #: code:addons/mission_stock/wizard/mission_stock_wizard.py:92
278@@ -76100,6 +76134,93 @@
279 msgid "A line was added to the %s %s to re-source the canceled line."
280 msgstr "Une ligne a été ajoutée a la %s %s pour 're-sourcer' la ligne annulée."
281
282+#. module: mission_stock
283+#: field:stock.mission.report.line,state_ud:0
284+msgid "UniData status"
285+msgstr "Statut UniData"
286+
287+#. module: msf_tools
288+#: field:export.report.inconsistencies,name:0
289+#: field:export.report.stopped.products,name:0
290+msgid "Generated On"
291+msgstr "Généré le"
292+
293+#. module: msf_tools
294+#: code:addons/msf_tools/report/report_inconsistencies.py:107
295+#: code:addons/msf_tools/report/report_stopped_products.py:107
296+#, python-format
297+msgid "Nothing to generate"
298+msgstr "Rien à générer"
299+
300+#. module: msf_tools
301+#: model:ir.actions.report.xml,name:msf_tools.report_inconsistencies_xls
302+msgid "Inconsistencies with HQ"
303+msgstr "Incohérences avec le HQ"
304+
305+#. module: msf_tools
306+#: model:ir.actions.act_window,name:msf_tools.export_report_inconsistencies_action
307+#: model:ir.ui.menu,name:msf_tools.export_report_inconsistencies_menu
308+msgid "Product Status Inconsistencies"
309+msgstr "Incohérences du statut des produits"
310+
311+#. module: msf_tools
312+#: view:export.report.inconsistencies:0
313+msgid "Export inconsistencies"
314+msgstr "Exporter les incohérences"
315+
316+#. module: msf_tools
317+#: view:export.report.inconsistencies:0
318+#: view:export.report.stopped.products:0
319+msgid "Request information"
320+msgstr "Demande d'informations"
321+
322+#. module: msf_tools
323+#: view:export.report.inconsistencies:0
324+#: view:export.report.stopped.products:0
325+msgid "Generate report"
326+msgstr "Générer le rapport"
327+
328+#. module: msf_tools
329+#: view:export.report.inconsistencies:0
330+#: view:export.report.stopped.products:0
331+msgid "Status of the report"
332+msgstr "État du rapport"
333+
334+#. module: msf_tools
335+#: view:export.report.inconsistencies:0
336+msgid "Your export inconsistent products demand will be treated quickly."
337+msgstr "Votre export des produits incohérents sera traité rapidement."
338+
339+#. module: msf_tools
340+#: view:export.report.inconsistencies:0
341+msgid "Due to the volume of data, your report cannot be shown immediatly"
342+msgstr "À cause du volume des données, le rapport ne peut pas être affiché immédiatement"
343+
344+#. module: msf_tools
345+#: view:export.report.inconsistencies:0
346+msgid "When the report will be ready, you can access to it by the menu Tools / Inconsistencies report"
347+msgstr "Quand le rapport sera prêt, vous pourrez y accéder depuis le menu Outils / Rapport d'incohérences"
348+
349+#. module: msf_tools
350+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:75
351+msgid "There is no inconsistencies to report"
352+msgstr "Il n'y a pas d'incohérence à reporter"
353+
354+#. module: msf_tools
355+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:85
356+msgid "Active/Inactive"
357+msgstr "Actif/Inactif"
358+
359+#. module: msf_tools
360+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:83
361+msgid "UniField Status"
362+msgstr "Statut UniField"
363+
364+#. module: msf_tools
365+#: report:addons/msf_tools/report/report_inconsistencies_xls.mako:84
366+msgid "Unidata Status"
367+msgstr "Statut UniData"
368+
369 #. modules: sale, msf_printed_documents
370 #: report:msf.consumption_report:0
371 msgid "Source Location :"
372
373=== modified file 'bin/addons/msf_profile/msf_profile.py'
374--- bin/addons/msf_profile/msf_profile.py 2017-01-31 16:17:06 +0000
375+++ bin/addons/msf_profile/msf_profile.py 2017-02-03 13:54:39 +0000
376@@ -1117,9 +1117,58 @@
377 return True
378
379
380+ def us_1167_status_inconsistencies(self, cr, uid, *a, **b):
381+ '''
382+ fill fields of stock.mission.report.line:
383+ - state_ud
384+ - product_active
385+ - international_status_code
386+ '''
387+ prod_obj = self.pool.get('product.product')
388+ smrl_obj = self.pool.get('stock.mission.report.line')
389+ context = {}
390+
391+ prod_ids = prod_obj.search(cr, uid, [('active', 'in', ['t', 'f'])], context=context)
392+ smrl_to_update = smrl_obj.search(cr, uid, [('product_id', 'in', prod_ids), ('mission_report_id.local_report', '=', True)], context=context)
393+
394+ for smrl in smrl_obj.browse(cr, uid, smrl_to_update, context=context):
395+ smrl_obj.write(cr, uid, smrl.id, {
396+ 'state_ud': smrl.product_id.state_ud,
397+ 'product_active': smrl.product_id.active,
398+ 'international_status_code': smrl.product_id.international_status.code if smrl.product_id.international_status else '',
399+ }, context=context)
400+
401+ return True
402+
403+
404+ def us_1167_status_inconsistencies(self, cr, uid, *a, **b):
405+ '''
406+ fill fields of stock.mission.report.line:
407+ - state_ud
408+ - product_active
409+ - international_status_code
410+ '''
411+ prod_obj = self.pool.get('product.product')
412+ smrl_obj = self.pool.get('stock.mission.report.line')
413+ context = {}
414+
415+ prod_ids = prod_obj.search(cr, uid, [('active', 'in', ['t', 'f'])], context=context)
416+ smrl_to_update = smrl_obj.search(cr, uid, [('product_id', 'in', prod_ids), ('mission_report_id.local_report', '=', True)], context=context)
417+
418+ for smrl in smrl_obj.browse(cr, uid, smrl_to_update, context=context):
419+ smrl_obj.write(cr, uid, smrl.id, {
420+ 'state_ud': smrl.product_id.state_ud,
421+ 'product_active': smrl.product_id.active,
422+ 'international_status_code': smrl.product_id.international_status.code if smrl.product_id.international_status else '',
423+ }, context=context)
424+
425+ return True
426+
427+
428 patch_scripts()
429
430
431+
432 class ir_model_data(osv.osv):
433 _inherit = 'ir.model.data'
434 _name = 'ir.model.data'
435
436=== modified file 'bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv'
437--- bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2017-01-25 14:57:37 +0000
438+++ bin/addons/msf_sync_data_server/data/sync_server.sync_rule.csv 2017-02-03 13:54:39 +0000
439@@ -87,8 +87,8 @@
440 msf_sync_data_server.budget_line,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('budget_id','in',('msf.budget','id',[('type','=','normal'), ('state', '!=', 'draft')]))]","['account_id/id', 'budget_id/id', 'month1', 'month2', 'month3', 'month4', 'month5', 'month6', 'month7', 'month8', 'month9', 'month10', 'month11', 'month12', 'destination_id/id', 'line_type']",OC,msf.budget.line,,Budget line,Valid,,431
441 msf_sync_data_server.budget_status,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('type','=','normal'), ('state', '!=', 'draft')]",['state'],OC,msf.budget,,Budget status,Valid,,432
442 msf_sync_data_server.mission_stock_report,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('full_view', '=', False), ('local_report', '=', True)]","['full_view', 'instance_id/id', 'last_update', 'name']",OC,stock.mission.report,,Mission Stock Report,Valid,,440
443-msf_sync_data_server.mission_stock_report_line,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('mission_report_id.full_view', '=', False), ('mission_report_id.local_report', '=', True), ('international_status','in',['Local', 'Temporary'])]","['central_qty', 'central_val', 'cross_qty', 'cross_val', 'cu_qty', 'cu_val', 'in_pipe_coor_qty', 'in_pipe_coor_val', 'in_pipe_qty', 'in_pipe_val', 'internal_qty', 'internal_val', 'mission_report_id/id', 'product_id/id', 'secondary_qty', 'secondary_val', 'stock_qty', 'stock_val', 'xmlid_code', 'product_state']",MISSION,stock.mission.report.line,,Mission Stock Report Line,Valid,,441
444-msf_sync_data_server.mission_stock_report_line_OC,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('mission_report_id.full_view', '=', False), ('mission_report_id.local_report', '=', True), ('international_status','in',['ITC', 'UniData', 'ESC', 'HQ'])]","['central_qty', 'central_val', 'cross_qty', 'cross_val', 'cu_qty', 'cu_val', 'in_pipe_coor_qty', 'in_pipe_coor_val', 'in_pipe_qty', 'in_pipe_val', 'internal_qty', 'internal_val', 'mission_report_id/id', 'product_id/id', 'secondary_qty', 'secondary_val', 'stock_qty', 'stock_val', 'xmlid_code', 'product_state']",OC,stock.mission.report.line,,Mission Stock Report Line OC,Valid,,442
445+msf_sync_data_server.mission_stock_report_line,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('mission_report_id.full_view', '=', False), ('mission_report_id.local_report', '=', True), ('international_status','in',['Local', 'Temporary'])]","['central_qty', 'central_val', 'cross_qty', 'cross_val', 'cu_qty', 'cu_val', 'in_pipe_coor_qty', 'in_pipe_coor_val', 'in_pipe_qty', 'in_pipe_val', 'internal_qty', 'internal_val', 'mission_report_id/id', 'product_id/id', 'secondary_qty', 'secondary_val', 'stock_qty', 'stock_val', 'xmlid_code', 'product_state', 'product_active', 'state_ud', 'international_status_code']",MISSION,stock.mission.report.line,,Mission Stock Report Line,Valid,,441
446+msf_sync_data_server.mission_stock_report_line_OC,TRUE,TRUE,FALSE,FALSE,bidirectional,Up,"[('mission_report_id.full_view', '=', False), ('mission_report_id.local_report', '=', True), ('international_status','in',['ITC', 'UniData', 'ESC', 'HQ'])]","['central_qty', 'central_val', 'cross_qty', 'cross_val', 'cu_qty', 'cu_val', 'in_pipe_coor_qty', 'in_pipe_coor_val', 'in_pipe_qty', 'in_pipe_val', 'internal_qty', 'internal_val', 'mission_report_id/id', 'product_id/id', 'secondary_qty', 'secondary_val', 'stock_qty', 'stock_val', 'xmlid_code', 'product_state', 'product_active', 'state_ud', 'international_status_code']",OC,stock.mission.report.line,,Mission Stock Report Line OC,Valid,,442
447 msf_sync_data_server.financing_contract_formats_fc,TRUE,TRUE,FALSE,TRUE,bidirectional,Bidirectional-Private,[],"['cost_center_ids/id', 'eligibility_from_date', 'eligibility_to_date', 'format_name', 'overhead_percentage', 'overhead_type', 'reporting_type', 'hidden_instance_id/id']",HQ + MISSION,financing.contract.format,hidden_instance_id,Financing Contract Formats FC,Valid,,450
448 msf_sync_data_server.financing_contract_formats,TRUE,TRUE,TRUE,TRUE,bidirectional,Bidirectional,"[('hidden_instance_id','=',False)]","['hidden_instance_id/id','cost_center_ids/id', 'eligibility_from_date', 'eligibility_to_date', 'format_name', 'overhead_percentage', 'overhead_type', 'reporting_type']",HQ + MISSION,financing.contract.format,,Financing Contract Formats,Valid,,451
449 msf_sync_data_server.financing_contract_format_lines,TRUE,TRUE,TRUE,TRUE,bidirectional,Bidirectional,"[('instance_id', '=', False)]","['account_destination_ids/id', 'instance_id/id','allocated_budget_value', 'allocated_real_value', 'code', 'format_id/id', 'line_type', 'name', 'overhead_percentage', 'overhead_type', 'project_budget_value', 'project_real_value', 'is_quadruplet','quadruplet_update']",HQ + MISSION,financing.contract.format.line,,Financing Contract Format Lines,Valid,,452
450
451=== modified file 'bin/addons/msf_tools/__openerp__.py'
452--- bin/addons/msf_tools/__openerp__.py 2016-10-26 16:06:31 +0000
453+++ bin/addons/msf_tools/__openerp__.py 2017-02-03 13:54:39 +0000
454@@ -41,6 +41,8 @@
455 'security/ir.model.access.csv',
456 'report/report_stopped_products_view.xml',
457 'report/report_stopped_products_report.xml',
458+ 'report/report_inconsistencies_view.xml',
459+ 'report/report_inconsistencies_report.xml',
460 'automated_import_data.xml',
461 ],
462 'demo_xml': [
463
464=== modified file 'bin/addons/msf_tools/report/__init__.py'
465--- bin/addons/msf_tools/report/__init__.py 2016-10-26 16:06:31 +0000
466+++ bin/addons/msf_tools/report/__init__.py 2017-02-03 13:54:39 +0000
467@@ -20,3 +20,4 @@
468 ##############################################################################
469
470 import report_stopped_products
471+import report_inconsistencies
472
473=== added file 'bin/addons/msf_tools/report/report_inconsistencies.py'
474--- bin/addons/msf_tools/report/report_inconsistencies.py 1970-01-01 00:00:00 +0000
475+++ bin/addons/msf_tools/report/report_inconsistencies.py 2017-02-03 13:54:39 +0000
476@@ -0,0 +1,433 @@
477+# -*- coding: utf-8 -*-
478+##############################################################################
479+#
480+# OpenERP, Open Source Management Solution
481+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
482+#
483+# This program is free software: you can redistribute it and/or modify
484+# it under the terms of the GNU Affero General Public License as
485+# published by the Free Software Foundation, either version 3 of the
486+# License, or (at your option) any later version.
487+#
488+# This program is distributed in the hope that it will be useful,
489+# but WITHOUT ANY WARRANTY; without even the implied warranty of
490+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
491+# GNU Affero General Public License for more details.
492+#
493+# You should have received a copy of the GNU Affero General Public License
494+# along with this program. If not, see <http://www.gnu.org/licenses/>.
495+#
496+##############################################################################
497+
498+
499+import time
500+import threading
501+from osv import fields
502+from osv import osv
503+from report import report_sxw
504+from spreadsheet_xml.spreadsheet_xml_write import SpreadsheetReport
505+from service.web_services import report_spool
506+from tools.translate import _
507+
508+
509+
510+class export_report_inconsistencies(osv.osv):
511+
512+ _name = 'export.report.inconsistencies'
513+ _order = 'name desc'
514+
515+ _columns = {
516+ 'name': fields.datetime(string='Generated On', readonly=True),
517+ 'state': fields.selection(
518+ [('draft', 'Draft'),
519+ ('in_progress', 'In Progress'),
520+ ('ready', 'Ready')],
521+ string='State',
522+ readonly=True,
523+ ),
524+ }
525+
526+ _defaults = {
527+ 'state': lambda *a: 'draft',
528+ }
529+
530+
531+ def generate_report(self, cr, uid, ids, context=None):
532+ '''
533+ Generate a report
534+ Method is called by button on XML view (form)
535+ '''
536+ prod_obj = self.pool.get('product.product')
537+ data_obj = self.pool.get('ir.model.data')
538+
539+ res = {}
540+ for report in self.browse(cr, uid, ids, context=context):
541+ # get ids of all non-local products :
542+ status_local_id = data_obj.get_object_reference(cr, uid, 'product_attributes', 'int_4')[1]
543+ product_ids = prod_obj.search(cr, uid, [('international_status', '!=', status_local_id)], context=context)
544+ if not product_ids:
545+ continue
546+
547+ # state of report is in progress :
548+ self.write(cr, uid, [report.id], {
549+ 'name': time.strftime('%Y-%m-%d %H:%M:%S'),
550+ 'state': 'in_progress'
551+ }, context=context)
552+
553+ datas = {
554+ 'ids': [report.id],
555+ 'lines': product_ids,
556+ }
557+
558+ cr.commit()
559+ new_thread = threading.Thread(target=self.generate_report_bkg, args=(cr, uid, report.id, datas, context))
560+ new_thread.start()
561+ new_thread.join(timeout=25.0) # join = wait until new_thread is finished but if it last more then timeout value, you can continue to work
562+
563+ res = {
564+ 'type': 'ir.actions.act_window',
565+ 'res_model': self._name,
566+ 'view_type': 'form',
567+ 'view_mode': 'form,tree',
568+ 'res_id': report.id,
569+ 'context': context,
570+ 'target': 'same',
571+ }
572+
573+ if new_thread.isAlive():
574+ view_id = data_obj.get_object_reference(
575+ cr, uid,
576+ 'msf_tools',
577+ 'report_inconsistencies_info_view')[1]
578+ res['view_id'] = [view_id]
579+
580+ if not res:
581+ raise osv.except_osv(
582+ _('Error'),
583+ _("Nothing to generate")
584+ )
585+
586+ return res
587+
588+
589+ def generate_report_bkg(self, cr, uid, report_ids, datas, context=None):
590+ '''
591+ Generate the report in background (thread)
592+ '''
593+ attachment_obj = self.pool.get('ir.attachment')
594+
595+ if context is None:
596+ context ={}
597+
598+ if isinstance(report_ids, (int, long)):
599+ report_ids = [report_ids]
600+
601+ import pooler
602+ new_cr = pooler.get_db(cr.dbname).cursor()
603+
604+ # export datas :
605+ report_name = "inconsistencies.xls"
606+ attachment_name = "inconsistencies_report_%s.xls" % time.strftime('%d-%m-%Y_%Hh%M')
607+ rp_spool = report_spool()
608+ res_export = rp_spool.exp_report(cr.dbname, uid, report_name, report_ids, datas, context)
609+ file_res = {'state': False}
610+ while not file_res.get('state'):
611+ file_res = rp_spool.exp_report_get(new_cr.dbname, uid, res_export)
612+ time.sleep(0.5)
613+
614+ # attach report to the right panel :
615+ attachment_obj.create(new_cr, uid, {
616+ 'name': attachment_name,
617+ 'datas_fname': attachment_name,
618+ 'description': "Inconsistencies with HQ",
619+ 'res_model': 'export.report.inconsistencies',
620+ 'res_id': report_ids[0],
621+ 'datas': file_res.get('result'),
622+ }, context=context)
623+
624+ # state is now 'ready' :
625+ self.write(new_cr, uid, report_ids, {'state': 'ready'}, context= context)
626+
627+ new_cr.commit()
628+ new_cr.close(True)
629+
630+ return True
631+
632+
633+export_report_inconsistencies()
634+
635+
636+
637+class parser_report_inconsistencies_xls(report_sxw.rml_parse):
638+ '''
639+ To parse our mako template for inconsistencies
640+ '''
641+ def __init__(self, cr, uid, name, context=None):
642+ super(parser_report_inconsistencies_xls, self).__init__(cr, uid, name, context=context)
643+
644+ # localcontext allows you to call methods inside mako file :
645+ self.localcontext.update({
646+ 'time': time,
647+ 'get_uf_status': self.get_uf_status,
648+ 'get_ud_status': self.get_ud_status,
649+ 'get_inconsistent_lines': self.get_inconsistent_lines,
650+ 'get_products_with_inconsistencies': self.get_products_with_inconsistencies,
651+ 'get_product_creator_name_from_code': self.get_product_creator_name_from_code,
652+ })
653+
654+ # cached data
655+ self.uf_status_cache = {}
656+ self.prod_creator_cache = {}
657+ self.inconsistent = {}
658+
659+
660+ def get_inconsistent_lines(self, prod_id=None):
661+ '''
662+ Return stock mission report lines that are inconsistent with HQ
663+ Based on the fields: product_active, state_ud and international_status_code
664+
665+ prod_id: You can get only SMRL with product_id, if you don't give this information you
666+ will get all inconsistents SMRL
667+ '''
668+ smrl_obj = self.pool.get('stock.mission.report.line')
669+ product_creator_obj = self.pool.get('product.international.status')
670+ inconsistent_id_list = []
671+
672+ intl_status_code_name = {}
673+ intl_status_ids = product_creator_obj.search(self.cr, self.uid, [])
674+ for intl_status in product_creator_obj.browse(self.cr, self.uid, intl_status_ids):
675+ intl_status_code_name.setdefault(intl_status.code, intl_status.name)
676+
677+ if not self.inconsistent:
678+ prod_obj = self.pool.get('product.product')
679+ prod_status_obj = self.pool.get('product.status')
680+
681+ smrl_ids = smrl_obj.search(self.cr, self.uid, [('full_view', '=', False)], order='NO_ORDER', context=self.localcontext)
682+
683+ # check stock mission report line for inconsistencies with HQ (our instance):
684+ self.inconsistent = {}
685+ read_smrl_result = smrl_obj.read(self.cr, self.uid, smrl_ids,
686+ ['product_id', 'product_state', 'state_ud',
687+ 'product_active', 'mission_report_id', 'default_code',
688+ 'international_status_code'],
689+ context=self.localcontext)
690+
691+ read_smrl_result_dict = {}
692+ all_product_ids = []
693+ for read_smrl in read_smrl_result:
694+ read_smrl_result_dict[read_smrl['id']] = read_smrl
695+ all_product_ids.append(read_smrl['product_id'][0])
696+ del read_smrl_result
697+
698+ # read all product informations
699+ product_result = prod_obj.read(self.cr, self.uid, all_product_ids,
700+ ['state', 'state_ud', 'active', 'name_template',
701+ 'international_status', 'default_code'],
702+ context=self.localcontext)
703+ product_dict = dict((x['id'], x) for x in product_result)
704+
705+ # get all product_status
706+ prod_status_ids = prod_status_obj.search(self.cr, self.uid, [], context=self.localcontext)
707+ prod_status_result = prod_status_obj.read(self.cr, self.uid, prod_status_ids, ['code'], context=self.localcontext)
708+ prod_status_dict = dict((x['id'], x['code']) for x in prod_status_result)
709+
710+ # get all instance id and build a level dict
711+ instance_obj = self.pool.get('msf.instance')
712+ instance_ids = instance_obj.search(self.cr, self.uid, [])
713+ instance_read_result = instance_obj.read(self.cr, self.uid, instance_ids,
714+ ['level', 'name'], context=self.localcontext)
715+ instance_level_dict = dict((x['id'], x) for x in
716+ instance_read_result)
717+
718+ # get all report id and build a instance dict
719+ smr_obj = self.pool.get('stock.mission.report')
720+ smr_ids = smr_obj.search(self.cr, self.uid, [])
721+ smr_read_result = smr_obj.read(self.cr, self.uid, smr_ids,
722+ ['instance_id'], context=self.localcontext)
723+ smr_instance_dict = dict((x['id'], x) for x in
724+ smr_read_result)
725+
726+ # get all uf_status codes
727+ uf_status_obj = self.pool.get('product.status')
728+ uf_status_code_ids = uf_status_obj.search(self.cr, self.uid, [], context=self.localcontext)
729+ uf_status_code_read_result = uf_status_obj.read(self.cr, self.uid,
730+ uf_status_code_ids, ['code', 'name'], context=self.localcontext)
731+ uf_status_code_dict = dict((x['code'], x) for x in
732+ uf_status_code_read_result)
733+
734+ product_result_dict = {}
735+ state_ud_dict = {}
736+ for product in product_result[0:100]:
737+ inconsistent_id_list = []
738+ # get the lines matching this product
739+ smrl_ids = smrl_obj.search(self.cr, self.uid,
740+ [('full_view', '=', False),
741+ ('product_id', '=', product['id'])],
742+ order='NO_ORDER', context=self.localcontext)
743+
744+ # get the inconsistent related lines
745+ for smrl_id in smrl_ids:
746+ smrl = read_smrl_result_dict[smrl_id]
747+ product = product_dict[smrl['product_id'][0]]
748+ # in product_product state is False when empty
749+ # in smrl product_state is '' when empty:
750+ if not product['state'] and not smrl['product_state']:
751+ pass
752+ elif not product['state'] and smrl['product_state']:
753+ inconsistent_id_list.append(smrl['id'])
754+ continue
755+ elif product['state'] and not smrl['product_state']:
756+ inconsistent_id_list.append(smrl['id'])
757+ continue
758+ elif product['state'] and product['state'] in prod_status_dict:
759+ state_code = prod_status_dict[product['state'][0]]
760+ if state_code != smrl['product_state']:
761+ inconsistent_id_list.append(smrl['id'])
762+ continue
763+
764+ if not product['state_ud'] and not smrl['state_ud']:
765+ pass
766+ elif product['state_ud'] != smrl['state_ud']:
767+ inconsistent_id_list.append(smrl['id'])
768+ continue
769+
770+ if product['active'] != smrl['product_active']: # if null in DB smrl.product_active = False ....
771+ inconsistent_id_list.append(smrl['id'])
772+ continue
773+
774+ if inconsistent_id_list:
775+ product_result_dict[product['id']] = {}
776+ current_prod = product_result_dict[product['id']]
777+ current_prod['smrl_list'] = []
778+ prod_state_ud = ''
779+ if product['state_ud']:
780+ if product['state_ud'] not in state_ud_dict:
781+ product_browse_obj = prod_obj.browse(self.cr, self.uid, product['id'], context=self.localcontext)
782+ state_ud_name = self.pool.get('ir.model.fields').get_browse_selection(self.cr, self.uid, product_browse_obj, 'state_ud', self.localcontext)
783+ state_ud_dict[product['state_ud']] = state_ud_name
784+ prod_state_ud = state_ud_dict[product['state_ud']]
785+ current_prod.update({
786+ 'prod_default_code': product['default_code'],
787+ 'prod_name_template': product['name_template'],
788+ 'prod_international_status': product['international_status'] and product['international_status'][1] or '',
789+ 'prod_state': product['state'] and product['state'][1] or '',
790+ 'prod_state_ud': prod_state_ud,
791+ 'prod_active': product['active'],
792+ })
793+
794+ # build the result list dict
795+ for smrl_id in inconsistent_id_list:
796+ smrl = read_smrl_result_dict[smrl_id]
797+ instance_id = smr_instance_dict[smrl['mission_report_id'][0]]['instance_id'][0]
798+
799+ smrl_dict = {
800+ 'instance_name': instance_level_dict[instance_id]['name'],
801+ 'smrl_default_code': smrl['default_code'],
802+ 'smrl_name_template': product['name_template'],
803+ 'internationnal_status_code_name': smrl['international_status_code'] and intl_status_code_name.get(smrl['international_status_code'], '') or '',
804+ 'uf_status_code': smrl['product_state'] and uf_status_code_dict[smrl['product_state']]['name'] or '',
805+ 'ud_status_code': self.get_ud_status(smrl['state_ud']),
806+ 'active': smrl['product_active'],
807+ 'instance_level': instance_level_dict[instance_id]['level'],
808+ }
809+ product_result_dict[product['id']]['smrl_list'].append(smrl_dict)
810+ product_result_dict[product['id']]['smrl_list'].sort(key=lambda smrl: smrl['instance_level'])
811+ self.inconsistent[product['id']] = product_result_dict[product['id']]
812+
813+ if prod_id:
814+ return self.inconsistent[prod_id]
815+ else:
816+ return self.inconsistent
817+
818+
819+ def get_products_with_inconsistencies(self):
820+ '''
821+ return a browse record list of inconsistent product_product
822+ '''
823+ if not self.inconsistent:
824+ self.inconsistent = self.get_inconsistent_lines()
825+
826+ prod_ids = self.inconsistent.keys()
827+
828+ # order product id by default code
829+ prod_obj = self.pool.get('product.product')
830+ prod_result = prod_obj.read(self.cr, self.uid, prod_ids, ['default_code'], self.localcontext)
831+ prod_result.sort(key=lambda prod: prod['default_code'])
832+ ordered_ids = [x['id'] for x in prod_result]
833+
834+ # order self.inconsistent according with this ids
835+ final_result = [self.inconsistent[x] for x in ordered_ids]
836+ return final_result
837+
838+
839+ def get_uf_status(self, code):
840+ '''
841+ Return the name of the unifield status with the given code
842+ '''
843+ if code in self.uf_status_cache:
844+ return self.uf_status_cache[code]
845+
846+ status_obj = self.pool.get('product.status')
847+ code_ids = status_obj.search(self.cr, self.uid, [('code', '=', code)], context=self.localcontext)
848+ res = ""
849+ if code_ids:
850+ res = status_obj.read(self.cr, self.uid, code_ids, ['name'])[0]['name']
851+
852+ self.uf_status_cache[code] = res
853+
854+ return res
855+
856+
857+ def get_ud_status(self, code):
858+ '''
859+ Return the name of the unidata status with the given code
860+ '''
861+ if not code or not isinstance(code, (str, unicode)):
862+ return ''
863+ return code.capitalize().replace('_', ' ')
864+
865+
866+ def get_product_creator_name_from_code(self, code):
867+ '''
868+ return the name of the product creator with the given code
869+ '''
870+ if code in self.prod_creator_cache:
871+ return self.prod_creator_cache[code]
872+
873+ prodstat_obj = self.pool.get('product.international.status')
874+ prodstat_ids = prodstat_obj.search(self.cr, self.uid, [('code', '=', code)], context=self.localcontext)
875+ if not prodstat_ids:
876+ return code
877+
878+ name = prodstat_obj.read(self.cr, self.uid, prodstat_ids, ['name'], context=self.localcontext)[0]['name']
879+ self.prod_creator_cache[code] = name
880+
881+ return name
882+
883+
884+
885+class report_inconsistencies_xls(SpreadsheetReport):
886+
887+ def __init(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
888+ super(report_inconsistencies_xls, self).__init__(
889+ name,
890+ table,
891+ rml=rml,
892+ parser=parser,
893+ header=header,
894+ store=store
895+ )
896+
897+ def create(self, cr, uid, ids, data, context=None):
898+ a = super(report_inconsistencies_xls, self).create(cr, uid, ids, data, context=context)
899+ return (a[0], 'xls')
900+
901+
902+
903+report_inconsistencies_xls(
904+ 'report.inconsistencies.xls',
905+ 'export.report.inconsistencies',
906+ 'addons/msf_tools/report/report_inconsistencies_xls.mako',
907+ parser=parser_report_inconsistencies_xls,
908+ header='internal',
909+)
910
911=== added file 'bin/addons/msf_tools/report/report_inconsistencies_report.xml'
912--- bin/addons/msf_tools/report/report_inconsistencies_report.xml 1970-01-01 00:00:00 +0000
913+++ bin/addons/msf_tools/report/report_inconsistencies_report.xml 2017-02-03 13:54:39 +0000
914@@ -0,0 +1,20 @@
915+<?xml version="1.0" encoding="utf-8"?>
916+<openerp>
917+ <data>
918+
919+
920+ <report
921+ id="report_inconsistencies_xls"
922+ string="Inconsistencies with HQ"
923+ model="export.report.inconsistencies"
924+ name="inconsistencies.xls"
925+ file="msf_tools/report/report_inconsistencies_xls.mako"
926+ report_type="webkit"
927+ header="False"
928+ auto="False"
929+ menu="False"
930+ />
931+
932+
933+ </data>
934+</openerp>
935\ No newline at end of file
936
937=== added file 'bin/addons/msf_tools/report/report_inconsistencies_view.xml'
938--- bin/addons/msf_tools/report/report_inconsistencies_view.xml 1970-01-01 00:00:00 +0000
939+++ bin/addons/msf_tools/report/report_inconsistencies_view.xml 2017-02-03 13:54:39 +0000
940@@ -0,0 +1,92 @@
941+<?xml version="1.0" encoding="utf-8"?>
942+<openerp>
943+ <data>
944+
945+
946+ <record id="export_report_inconsistencies_form_view" model="ir.ui.view">
947+ <field name="name">export.report.inconsistencies.form.view</field>
948+ <field name="model">export.report.inconsistencies</field>
949+ <field name="type">form</field>
950+ <field name="arch" type="xml">
951+ <form string="Export inconsistencies">
952+ <separator colspan="4" string="Request information" />
953+ <field name="name" />
954+ <field name="state" />
955+ <button name="generate_report" type="object" string="Generate report"
956+ icon="gtk-execute" states='draft' />
957+ </form>
958+ </field>
959+ </record>
960+
961+
962+ <record id="export_report_inconsistencies_tree_view" model="ir.ui.view">
963+ <field name="name">export.report.inconsistencies.tree.view</field>
964+ <field name="model">export.report.inconsistencies</field>
965+ <field name="type">tree</field>
966+ <field name="arch" type="xml">
967+ <tree string="Export inconsistencies">
968+ <field name="name" />
969+ <field name="state" />
970+ </tree>
971+ </field>
972+ </record>
973+
974+
975+ <record id="report_inconsistencies_search_view" model="ir.ui.view">
976+ <field name="name">export.report.inconsistencies.search.view</field>
977+ <field name="model">export.report.inconsistencies</field> <!-- _name of openERP object -->
978+ <field name="type">search</field>
979+ <field name="arch" type="xml">
980+ <search string="Export inconsistencies">
981+ <field name="name" />
982+ <field name="state" />
983+ </search>
984+ </field>
985+ </record>
986+
987+
988+ <record id="report_inconsistencies_info_view" model="ir.ui.view">
989+ <field name="name">export.report.inconsistencies.info.view</field>
990+ <field name="model">export.report.inconsistencies</field>
991+ <field name="type">form</field>
992+ <field name="priority" eval="99" />
993+ <field name="arch" type="xml">
994+ <form string="Status of the report" hide_new_button="1" hide_delete_button="1">
995+ <label> </label>
996+ <group colspan="2" col="2">
997+ <html>
998+ <div style="align: center">
999+ <p style="font-size:14px;align:center">
1000+ Your export inconsistent products demand will be treated quickly.<br />
1001+ </p>
1002+ <p style="font-size:14px;align:center">
1003+ Due to the volume of data, your report cannot be shown immediatly.<br />
1004+ </p>
1005+ <p style="font-size:14px;align:center">
1006+ When the report will be ready, you can access to it by the menu Tools / Inconsistencies report<br />
1007+ </p>
1008+ </div>
1009+ </html>
1010+ </group>
1011+ <label> </label>
1012+ </form>
1013+ </field>
1014+ </record>
1015+
1016+
1017+ <record id="export_report_inconsistencies_action" model="ir.actions.act_window">
1018+ <field name="name">Product Status Inconsistencies</field>
1019+ <field name="res_model">export.report.inconsistencies</field>
1020+ <field name="view_type">form</field>
1021+ <field name="view_mode">tree,form</field>
1022+ </record>
1023+
1024+
1025+ <menuitem
1026+ id="export_report_inconsistencies_menu"
1027+ action="export_report_inconsistencies_action"
1028+ parent="object_query.menu_preferences"
1029+ sequence="51" />
1030+
1031+ </data>
1032+</openerp>
1033
1034=== added file 'bin/addons/msf_tools/report/report_inconsistencies_xls.mako'
1035--- bin/addons/msf_tools/report/report_inconsistencies_xls.mako 1970-01-01 00:00:00 +0000
1036+++ bin/addons/msf_tools/report/report_inconsistencies_xls.mako 2017-02-03 13:54:39 +0000
1037@@ -0,0 +1,139 @@
1038+<?xml version="1.0"?>
1039+<?mso-application progid="Excel.Sheet"?>
1040+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
1041+ xmlns:o="urn:schemas-microsoft-com:office:office"
1042+ xmlns:x="urn:schemas-microsoft-com:office:excel"
1043+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
1044+ xmlns:html="http://www.w3.org/TR/REC-html40">
1045+ <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
1046+ <Author>MSFUser</Author>
1047+ <LastAuthor>MSFUser</LastAuthor>
1048+ <Created>2012-06-18T15:46:09Z</Created>
1049+ <Company>Medecins Sans Frontieres</Company>
1050+ <Version>11.9999</Version>
1051+</DocumentProperties>
1052+<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
1053+ <WindowHeight>13170</WindowHeight>
1054+ <WindowWidth>19020</WindowWidth>
1055+ <WindowTopX>120</WindowTopX>
1056+ <WindowTopY>60</WindowTopY>
1057+ <ProtectStructure>False</ProtectStructure>
1058+ <ProtectWindows>False</ProtectWindows>
1059+</ExcelWorkbook>
1060+
1061+<Styles>
1062+ <Style ss:ID="tab_header_orange">
1063+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
1064+ <Interior ss:Color="#ffcc99" ss:Pattern="Solid"/>
1065+ <Borders>
1066+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
1067+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
1068+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
1069+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
1070+ </Borders>
1071+ </Style>
1072+ <Style ss:ID="tab_header_gray">
1073+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
1074+ <Interior ss:Color="#dbdbdb" ss:Pattern="Solid"/>
1075+ <Borders>
1076+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
1077+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
1078+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
1079+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
1080+ </Borders>
1081+ </Style>
1082+ <Style ss:ID="tab_content">
1083+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
1084+ <Borders>
1085+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
1086+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
1087+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
1088+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
1089+ </Borders>
1090+ </Style>
1091+</Styles>
1092+
1093+
1094+<ss:Worksheet ss:Name="Stopped products">
1095+
1096+ <Table x:FullColumns="1" x:FullRows="1">
1097+
1098+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # instance
1099+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # code
1100+ <Columns ss:AutoFitWidth="1" ss:Width="200" /> # product description
1101+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # product creator
1102+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # unifield status
1103+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # unidata status
1104+ <Columns ss:AutoFitWidth="1" ss:Width="90" /> # active
1105+
1106+ ##### Table with all stopped products #####
1107+
1108+ % if not get_inconsistent_lines():
1109+ <Row ss:AutoFitHeight="1">
1110+ <Cell ss:StyleID="tab_content"><Data ss:Type="String"></Data></Cell>
1111+ <Cell ss:StyleID="tab_content"><Data ss:Type="String"></Data></Cell>
1112+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${_('There is no inconsistencies to report')|x}</Data></Cell>
1113+ </Row>
1114+ % else:
1115+ <Row ss:AutoFitHeight="1">
1116+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Instance')|x}</Data></Cell>
1117+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Code')|x}</Data></Cell>
1118+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Description')|x}</Data></Cell>
1119+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Product Creator')|x}</Data></Cell>
1120+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('UniField Status')|x}</Data></Cell>
1121+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Unidata Status')|x}</Data></Cell>
1122+ <Cell ss:StyleID="tab_header_orange"><Data ss:Type="String">${_('Active/Inactive')|x}</Data></Cell>
1123+ </Row>
1124+ % for prod in get_products_with_inconsistencies():
1125+ # HQ data:
1126+ <Row ss:AutoFitHeight="1">
1127+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${_('HQ')|x}</Data></Cell>
1128+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(prod['prod_default_code'])|x}</Data></Cell>
1129+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(prod['prod_name_template'])|x}</Data></Cell>
1130+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(prod['prod_international_status'] or '')|x}</Data></Cell>
1131+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(prod['prod_state'] or '')|x}</Data></Cell>
1132+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(prod['prod_state_ud'] or '')|x}</Data></Cell>
1133+ <Cell ss:StyleID="tab_header_gray"><Data ss:Type="String">${(_('Active') if prod['prod_active'] else _('Inactive'))|x}</Data></Cell>
1134+ </Row>
1135+ % for smrl in prod['smrl_list']:
1136+ <Row ss:AutoFitHeight="1">
1137+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['instance_name'])|x}</Data></Cell>
1138+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['smrl_default_code'])|x}</Data></Cell>
1139+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['smrl_name_template'])|x}</Data></Cell>
1140+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['internationnal_status_code_name'] or '')|x}</Data></Cell>
1141+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['uf_status_code'])|x}</Data></Cell>
1142+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(smrl['ud_status_code'] or '')|x}</Data></Cell>
1143+ <Cell ss:StyleID="tab_content"><Data ss:Type="String">${(_('Active') if smrl['active'] else _('Inactive'))|x}</Data></Cell>
1144+ </Row>
1145+ % endfor
1146+ % endfor
1147+ % endif
1148+
1149+
1150+ </Table>
1151+
1152+ <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
1153+ <PageSetup>
1154+ <Layout x:Orientation="Landscape"/>
1155+ <Header x:Data="&amp;C&amp;&quot;Arial,Bold&quot;&amp;14"/>
1156+ <Footer x:Data="Page &amp;P of &amp;N"/>
1157+ </PageSetup>
1158+ <Print>
1159+ <ValidPrinterInfo/>
1160+ <PaperSizeIndex>9</PaperSizeIndex>
1161+ <HorizontalResolution>600</HorizontalResolution>
1162+ <VerticalResolution>600</VerticalResolution>
1163+ </Print>
1164+ <Selected/>
1165+ <Panes>
1166+ <Pane>
1167+ <Number>3</Number>
1168+ <ActiveRow>17</ActiveRow>
1169+ </Pane>
1170+ </Panes>
1171+ <ProtectObjects>False</ProtectObjects>
1172+ <ProtectScenarios>False</ProtectScenarios>
1173+</WorksheetOptions>
1174+</ss:Worksheet>
1175+
1176+</Workbook>
1177
1178=== modified file 'bin/addons/product_attributes/product_attributes.py'
1179--- bin/addons/product_attributes/product_attributes.py 2017-01-17 13:31:02 +0000
1180+++ bin/addons/product_attributes/product_attributes.py 2017-02-03 13:54:39 +0000
1181@@ -1294,6 +1294,7 @@
1182 return True
1183 smrl_obj = self.pool.get('stock.mission.report.line')
1184 prod_status_obj = self.pool.get('product.status')
1185+ int_stat_obj = self.pool.get('product.international.status')
1186
1187 if context is None:
1188 context = {}
1189@@ -1335,6 +1336,33 @@
1190 if local_smrl_ids:
1191 smrl_obj.write(cr, uid, local_smrl_ids, {'product_state': prod_state}, context=context)
1192
1193+ if 'international_status' in vals:
1194+ intstat_code = ''
1195+ if vals['international_status']:
1196+ intstat_id = vals['international_status']
1197+ if isinstance(intstat_id, (int,long)):
1198+ intstat_id = [intstat_id]
1199+ intstat_code = int_stat_obj.read(cr, uid, intstat_id, ['code'], context=context)[0]['code']
1200+ # just update SMRL that belongs to our instance:
1201+ local_smrl_ids = smrl_obj.search(cr, uid, [
1202+ ('international_status_code', '!=', intstat_code),
1203+ ('product_id', 'in', ids),
1204+ ('full_view', '=', False),
1205+ ('mission_report_id.local_report', '=', True)
1206+ ], context=context)
1207+ if local_smrl_ids:
1208+ smrl_obj.write(cr, uid, local_smrl_ids, {'international_status_code': intstat_code or ''}, context=context)
1209+
1210+ if 'state_ud' in vals:
1211+ # just update SMRL that belongs to our instance:
1212+ local_smrl_ids = smrl_obj.search(cr, uid, [
1213+ ('product_id', 'in', ids),
1214+ ('full_view', '=', False),
1215+ ('mission_report_id.local_report', '=', True)
1216+ ], context=context)
1217+ if local_smrl_ids:
1218+ smrl_obj.write(cr, uid, local_smrl_ids, {'state_ud': vals['state_ud'] or ''}, context=context)
1219+
1220 product_uom_categ = []
1221 if 'uom_id' in vals or 'uom_po_id' in vals:
1222 if isinstance(ids, (int, long)):
1223@@ -1368,6 +1396,15 @@
1224 # 'state': phase_out_status,
1225 })
1226
1227+ if 'active' in vals:
1228+ local_smrl_ids = smrl_obj.search(cr, uid, [
1229+ ('product_id', 'in', ids),
1230+ ('full_view', '=', False),
1231+ ('mission_report_id.local_report', '=', True)
1232+ ], context=context)
1233+ if local_smrl_ids:
1234+ smrl_obj.write(cr, uid, local_smrl_ids, {'product_active': vals['active']}, context=context)
1235+
1236 if 'narcotic' in vals or 'controlled_substance' in vals:
1237 if vals.get('narcotic') == True or tools.ustr(vals.get('controlled_substance', '')) == 'True':
1238 vals['controlled_substance'] = 'True'
1239@@ -1389,6 +1426,7 @@
1240
1241 return res
1242
1243+
1244 def reactivate_product(self, cr, uid, ids, context=None):
1245 '''
1246 Re-activate product.

Subscribers

People subscribed via source and target branches

to all changes: