Merge lp:~unifield-team/unifield-server/us-1167 into lp:unifield-server
- us-1167
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+315900@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/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="&C&"Arial,Bold"&14"/> |
1156 | + <Footer x:Data="Page &P of &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. |