Merge lp:asperience-openerp-addons/8.0 into lp:asperience-openerp-addons

Proposed by hedererjs
Status: Approved
Approved by: hedererjs
Approved revision: 6
Proposed branch: lp:asperience-openerp-addons/8.0
Merge into: lp:asperience-openerp-addons
Diff against target: 63237 lines (has conflicts)
Conflict adding file .bzrignore.  Moved existing file to .bzrignore.moved.
Conflict adding file asperience_edi.  Moved existing file to asperience_edi.moved.
Conflict adding file asperience_sale_invoice_rate.  Moved existing file to asperience_sale_invoice_rate.moved.
To merge this branch: bzr merge lp:asperience-openerp-addons/8.0
Reviewer Review Type Date Requested Status
hedererjs Approve
Review via email: mp+239695@code.launchpad.net
To post a comment you must log in.
Revision history for this message
hedererjs (hedererjs) :
review: Approve
lp:asperience-openerp-addons/8.0 updated
13. By JS Hederer

Split, comments, images

14. By hedererjs

correction odoo v8.0 production

15. By hedererjs

logo + version update

16. By hedererjs

verification production 8.0

17. By hedererjs

sale_invoice_rate commit

18. By hedererjs

import account_invoice_sources

19. By hedererjs

Production grade tag

20. By hedererjs

Production grade tag

21. By hedererjs

Production grade tag

22. By hedererjs

asperience_account_invoice_sale_sources import production grade

23. By hedererjs

form update

24. By hedererjs

view page groups="base.group_extended"

25. By hedererjs

correction groups view

26. By hedererjs

correction groups

27. By hedererjs

asperience_sale_history import production grade

28. By hedererjs

images

29. By hedererjs

asperience_sale_picking_history production_grade

30. By hedererjs

__openerp__.py files reformat

31. By hedererjs

import asperience_sale_base production_grade

32. By hedererjs

asperience_sale_invoice_rate import production tag

33. By hedererjs

category correction

34. By hedererjs

category correction

35. By hedererjs

category correction

36. By hedererjs

purge log instructions

37. By JS HEDERER

Review asperience_product_base module

38. By JS HEDERER

Review asperience_product_base

39. By JS HEDERER

Review asperience_product_date_touch

40. By JS HEDERER

Review asperience_product_base

41. By JS HEDERER

Import asperience_edi for V8 migration

42. By JS HEDERER

mail address incorrect

43. By JS HEDERER

incorrect mail address

44. By JS HEDERER

copyrights

45. By JS HEDERER

copyrights

Unmerged revisions

45. By JS HEDERER

copyrights

44. By JS HEDERER

copyrights

43. By JS HEDERER

incorrect mail address

42. By JS HEDERER

mail address incorrect

41. By JS HEDERER

Import asperience_edi for V8 migration

40. By JS HEDERER

Review asperience_product_base

39. By JS HEDERER

Review asperience_product_date_touch

38. By JS HEDERER

Review asperience_product_base

37. By JS HEDERER

Review asperience_product_base module

36. By hedererjs

purge log instructions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2017-12-01 14:57:12 +0000
4@@ -0,0 +1,3 @@
5+.project
6+.pydevproject
7+.settings
8
9=== renamed file '.bzrignore' => '.bzrignore.moved'
10=== added directory 'asperience_account_invoice_sale_sources'
11=== added file 'asperience_account_invoice_sale_sources/README'
12--- asperience_account_invoice_sale_sources/README 1970-01-01 00:00:00 +0000
13+++ asperience_account_invoice_sale_sources/README 2017-12-01 14:57:12 +0000
14@@ -0,0 +1,2 @@
15+This module is "production grade".
16+In case of problems, please contact maintenance_asperpgi@asperience.fr
17\ No newline at end of file
18
19=== added file 'asperience_account_invoice_sale_sources/__init__.py'
20--- asperience_account_invoice_sale_sources/__init__.py 1970-01-01 00:00:00 +0000
21+++ asperience_account_invoice_sale_sources/__init__.py 2017-12-01 14:57:12 +0000
22@@ -0,0 +1,24 @@
23+# -*- encoding: utf-8 -*-
24+##############################################################################
25+#
26+# OpenERP, Open Source Management Solution
27+# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
28+# All Rights Reserved
29+#
30+# This program is free software: you can redistribute it and/or modify
31+# it under the terms of the GNU General Public License as published by
32+# the Free Software Foundation, either version 3 of the License, or
33+# (at your option) any later version.
34+#
35+# This program is distributed in the hope that it will be useful,
36+# but WITHOUT ANY WARRANTY; without even the implied warranty of
37+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+# GNU General Public License for more details.
39+#
40+# You should have received a copy of the GNU General Public License
41+# along with this program. If not, see <http://www.gnu.org/licenses/>.
42+#
43+##############################################################################
44+import account_invoice
45+
46+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
47\ No newline at end of file
48
49=== added file 'asperience_account_invoice_sale_sources/__openerp__.py'
50--- asperience_account_invoice_sale_sources/__openerp__.py 1970-01-01 00:00:00 +0000
51+++ asperience_account_invoice_sale_sources/__openerp__.py 2017-12-01 14:57:12 +0000
52@@ -0,0 +1,54 @@
53+# -*- encoding: utf-8 -*-
54+##############################################################################
55+#
56+# OpenERP, Open Source Management Solution
57+# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
58+# All Rights Reserved
59+#
60+# This program is free software: you can redistribute it and/or modify
61+# it under the terms of the GNU General Public License as published by
62+# the Free Software Foundation, either version 3 of the License, or
63+# (at your option) any later version.
64+#
65+# This program is distributed in the hope that it will be useful,
66+# but WITHOUT ANY WARRANTY; without even the implied warranty of
67+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68+# GNU General Public License for more details.
69+#
70+# You should have received a copy of the GNU General Public License
71+# along with this program. If not, see <http://www.gnu.org/licenses/>.
72+#
73+##############################################################################
74+{
75+ "name": "ASPerience Invoice Sale sources",
76+ "version": "8.0",
77+ "author": "ASPerience",
78+ "website": "https://www.asperience.fr",
79+ "sequence": 0,
80+ "certificate": "",
81+ "license": "",
82+ "depends": [
83+ "account","sale","asperience_account_invoice_sources"
84+ ],
85+ "category": "Accounting & Finance",
86+ "complexity": "easy",
87+ "description": """
88+Links between invoices and sales
89+ """,
90+ "data": [
91+ "account_invoice_view.xml",
92+ ],
93+ "demo": [
94+ ],
95+ "test": [
96+ ],
97+ "images": [
98+ "images/asperience.png",
99+ "images/grouped_invoice.png",
100+ ],
101+ "auto_install": False,
102+ "installable": True,
103+ "application": False,
104+
105+}
106+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
107\ No newline at end of file
108
109=== added file 'asperience_account_invoice_sale_sources/account_invoice.py'
110--- asperience_account_invoice_sale_sources/account_invoice.py 1970-01-01 00:00:00 +0000
111+++ asperience_account_invoice_sale_sources/account_invoice.py 2017-12-01 14:57:12 +0000
112@@ -0,0 +1,38 @@
113+# -*- encoding: utf-8 -*-
114+##############################################################################
115+#
116+# OpenERP, Open Source Management Solution
117+# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
118+# All Rights Reserved
119+#
120+# This program is free software: you can redistribute it and/or modify
121+# it under the terms of the GNU General Public License as published by
122+# the Free Software Foundation, either version 3 of the License, or
123+# (at your option) any later version.
124+#
125+# This program is distributed in the hope that it will be useful,
126+# but WITHOUT ANY WARRANTY; without even the implied warranty of
127+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128+# GNU General Public License for more details.
129+#
130+# You should have received a copy of the GNU General Public License
131+# along with this program. If not, see <http://www.gnu.org/licenses/>.
132+#
133+##############################################################################
134+from openerp.osv import fields, osv
135+
136+class account_invoice(osv.osv):
137+ _inherit = "account.invoice"
138+ _columns = {
139+ 'sale_ids': fields.many2many('sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale orders'),
140+ }
141+account_invoice()
142+
143+class account_invoice_line(osv.osv):
144+ _inherit = "account.invoice.line"
145+
146+ _columns = {
147+ 'sale_line_ids': fields.many2many('sale.order.line', 'sale_order_line_invoice_rel', 'invoice_id', 'order_line_id', 'Sale Lines', readonly=True),
148+ }
149+account_invoice_line()
150+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
151\ No newline at end of file
152
153=== added file 'asperience_account_invoice_sale_sources/account_invoice_view.xml'
154--- asperience_account_invoice_sale_sources/account_invoice_view.xml 1970-01-01 00:00:00 +0000
155+++ asperience_account_invoice_sale_sources/account_invoice_view.xml 2017-12-01 14:57:12 +0000
156@@ -0,0 +1,32 @@
157+<?xml version="1.0"?>
158+<openerp>
159+ <data>
160+
161+ <record id="invoice_form_asperience_sources" model="ir.ui.view">
162+ <field name="name">account.invoice.form.asperience.sources</field>
163+ <field name="model">account.invoice</field>
164+ <field name="type">form</field>
165+ <field name="priority">20</field>
166+ <field name="inherit_id" ref="account.invoice_form"/>
167+ <field name="arch" type="xml">
168+ <page string="Source" position="inside">
169+ <field colspan="4" name="sale_ids" nolabel="1"/>
170+ </page>
171+ </field>
172+ </record>
173+ <record id="invoice_line_form_asperience_sources" model="ir.ui.view">
174+ <field name="name">account.invoice.line.form.asperience.sources</field>
175+ <field name="model">account.invoice.line</field>
176+ <field name="type">form</field>
177+ <field name="priority">20</field>
178+ <field name="inherit_id" ref="account.view_invoice_line_form"/>
179+ <field name="arch" type="xml">
180+ <field name="invoice_line_tax_id" position="after">
181+ <separator colspan="4" string="Source Order Lines"/>
182+ <field colspan="4" name="sale_line_ids" nolabel="1"/>
183+ </field>
184+ </field>
185+ </record>
186+
187+ </data>
188+</openerp>
189\ No newline at end of file
190
191=== added directory 'asperience_account_invoice_sale_sources/i18n'
192=== added file 'asperience_account_invoice_sale_sources/i18n/fr.po'
193--- asperience_account_invoice_sale_sources/i18n/fr.po 1970-01-01 00:00:00 +0000
194+++ asperience_account_invoice_sale_sources/i18n/fr.po 2017-12-01 14:57:12 +0000
195@@ -0,0 +1,51 @@
196+# Translation of OpenERP Server.
197+# This file contains the translation of the following modules:
198+# * asperience_sale_invoice_sources
199+#
200+msgid ""
201+msgstr ""
202+"Project-Id-Version: OpenERP Server 6.1\n"
203+"Report-Msgid-Bugs-To: \n"
204+"POT-Creation-Date: 2013-11-06 21:04+0000\n"
205+"PO-Revision-Date: 2013-11-06 21:04+0000\n"
206+"Last-Translator: <>\n"
207+"Language-Team: \n"
208+"MIME-Version: 1.0\n"
209+"Content-Type: text/plain; charset=UTF-8\n"
210+"Content-Transfer-Encoding: \n"
211+"Plural-Forms: \n"
212+
213+#. module: asperience_sale_invoice_sources
214+#: view:account.invoice.line:0
215+msgid "Source Order Lines"
216+msgstr "Source lignes de commandes"
217+
218+#. module: asperience_sale_invoice_sources
219+#: sql_constraint:account.invoice:0
220+msgid "Invoice Number must be unique per Company!"
221+msgstr "Le numĆ©ro de facture doit ĆŖtre unique par sociĆ©tĆ© !"
222+
223+#. module: asperience_sale_invoice_sources
224+#: view:account.invoice:0
225+msgid "Source"
226+msgstr "Source"
227+
228+#. module: asperience_sale_invoice_sources
229+#: model:ir.actions.act_window,name:asperience_sale_invoice_sources.action_invoice_open
230+msgid "Invoices"
231+msgstr "Factures"
232+
233+#. module: asperience_sale_invoice_sources
234+#: model:ir.model,name:asperience_sale_invoice_sources.model_account_invoice_line
235+msgid "Invoice line"
236+msgstr "Ligne de facture"
237+
238+#. module: asperience_sale_invoice_sources
239+#: constraint:account.invoice:0
240+msgid "Error msg is in raise"
241+msgstr "Error msg is in raise"
242+
243+#. module: asperience_sale_invoice_sources
244+#: model:ir.model,name:asperience_sale_invoice_sources.model_account_invoice
245+msgid "Invoice"
246+msgstr "Facture"
247
248=== added directory 'asperience_account_invoice_sale_sources/images'
249=== added file 'asperience_account_invoice_sale_sources/images/asperience.png'
250Binary files asperience_account_invoice_sale_sources/images/asperience.png 1970-01-01 00:00:00 +0000 and asperience_account_invoice_sale_sources/images/asperience.png 2017-12-01 14:57:12 +0000 differ
251=== added file 'asperience_account_invoice_sale_sources/images/grouped_invoice.png'
252Binary files asperience_account_invoice_sale_sources/images/grouped_invoice.png 1970-01-01 00:00:00 +0000 and asperience_account_invoice_sale_sources/images/grouped_invoice.png 2017-12-01 14:57:12 +0000 differ
253=== added directory 'asperience_account_invoice_sources'
254=== added file 'asperience_account_invoice_sources/README'
255--- asperience_account_invoice_sources/README 1970-01-01 00:00:00 +0000
256+++ asperience_account_invoice_sources/README 2017-12-01 14:57:12 +0000
257@@ -0,0 +1,2 @@
258+This module is "production grade".
259+In case of problems, please contact maintenance_asperpgi@asperience.fr
260\ No newline at end of file
261
262=== added file 'asperience_account_invoice_sources/__init__.py'
263--- asperience_account_invoice_sources/__init__.py 1970-01-01 00:00:00 +0000
264+++ asperience_account_invoice_sources/__init__.py 2017-12-01 14:57:12 +0000
265@@ -0,0 +1,24 @@
266+# -*- encoding: utf-8 -*-
267+##############################################################################
268+#
269+# OpenERP, Open Source Management Solution
270+# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
271+# All Rights Reserved
272+#
273+# This program is free software: you can redistribute it and/or modify
274+# it under the terms of the GNU Affero General Public License as published by
275+# the Free Software Foundation, either version 3 of the License, or
276+# (at your option) any later version.
277+#
278+# This program is distributed in the hope that it will be useful,
279+# but WITHOUT ANY WARRANTY; without even the implied warranty of
280+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
281+# GNU Affero General Public License for more details.
282+#
283+# You should have received a copy of the GNU Affero General Public License
284+# along with this program. If not, see <http://www.gnu.org/licenses/>.
285+#
286+##############################################################################
287+
288+
289+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
290\ No newline at end of file
291
292=== added file 'asperience_account_invoice_sources/__openerp__.py'
293--- asperience_account_invoice_sources/__openerp__.py 1970-01-01 00:00:00 +0000
294+++ asperience_account_invoice_sources/__openerp__.py 2017-12-01 14:57:12 +0000
295@@ -0,0 +1,54 @@
296+# -*- encoding: utf-8 -*-
297+##############################################################################
298+#
299+# OpenERP, Open Source Management Solution
300+# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
301+# All Rights Reserved
302+#
303+# This program is free software: you can redistribute it and/or modify
304+# it under the terms of the GNU Affero General Public License as published by
305+# the Free Software Foundation, either version 3 of the License, or
306+# (at your option) any later version.
307+#
308+# This program is distributed in the hope that it will be useful,
309+# but WITHOUT ANY WARRANTY; without even the implied warranty of
310+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
311+# GNU Affero General Public License for more details.
312+#
313+# You should have received a copy of the GNU Affero General Public License
314+# along with this program. If not, see <http://www.gnu.org/licenses/>.
315+#
316+##############################################################################
317+{
318+ "name": "ASPerience Account Invoice Sources",
319+ "version": "8.0",
320+ "author": "ASPerience",
321+ "website": "https://www.asperience.fr",
322+ "sequence": 0,
323+ "certificate": "",
324+ "license": "",
325+ "depends": [
326+ "account"
327+ ],
328+ "category": "Accounting & Finance",
329+ "complexity": "easy",
330+ "description": """
331+Adds view panel for displaying sources (sales, purchases, stocks)
332+ """,
333+ "data": [
334+ 'account_invoice_view.xml',
335+ ],
336+ "demo": [
337+ ],
338+ "test": [
339+ ],
340+ "images": [
341+ "images/asperience.png",
342+ "images/group_invoice_view.png"
343+ ],
344+ "auto_install": False,
345+ "installable": True,
346+ "application": False,
347+
348+}
349+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
350
351=== added file 'asperience_account_invoice_sources/account_invoice_view.xml'
352--- asperience_account_invoice_sources/account_invoice_view.xml 1970-01-01 00:00:00 +0000
353+++ asperience_account_invoice_sources/account_invoice_view.xml 2017-12-01 14:57:12 +0000
354@@ -0,0 +1,32 @@
355+<?xml version="1.0" encoding="utf-8"?>
356+<openerp>
357+ <data>
358+
359+ <record id="invoice_supplier_form_asperience_1" model="ir.ui.view">
360+ <field name="name">account.invoice.supplier.form.asperience.1</field>
361+ <field name="model">account.invoice</field>
362+ <field name="type">form</field>
363+ <field name="inherit_id" ref="account.invoice_supplier_form"/>
364+ <field name="arch" type="xml">
365+ <page string="Payments" position="after">
366+ <page string="Source" groups="base.group_user">
367+ </page>
368+ </page>
369+ </field>
370+ </record>
371+
372+ <record id="invoice_form_asperience_1" model="ir.ui.view">
373+ <field name="name">account.invoice.form.asperience.1</field>
374+ <field name="model">account.invoice</field>
375+ <field name="type">form</field>
376+ <field name="inherit_id" ref="account.invoice_form"/>
377+ <field name="arch" type="xml">
378+ <page string="Payments" position="after">
379+ <page string="Source" groups="base.group_user">
380+ </page>
381+ </page>
382+ </field>
383+ </record>
384+
385+ </data>
386+</openerp>
387\ No newline at end of file
388
389=== added directory 'asperience_account_invoice_sources/i18n'
390=== added file 'asperience_account_invoice_sources/i18n/fr.po'
391--- asperience_account_invoice_sources/i18n/fr.po 1970-01-01 00:00:00 +0000
392+++ asperience_account_invoice_sources/i18n/fr.po 2017-12-01 14:57:12 +0000
393@@ -0,0 +1,26 @@
394+# Translation of OpenERP Server.
395+# This file contains the translation of the following modules:
396+# * asperience_account_invoice_sources
397+#
398+msgid ""
399+msgstr ""
400+"Project-Id-Version: OpenERP Server 6.1\n"
401+"Report-Msgid-Bugs-To: \n"
402+"POT-Creation-Date: 2013-05-26 19:23+0000\n"
403+"PO-Revision-Date: 2013-05-26 19:23+0000\n"
404+"Last-Translator: <>\n"
405+"Language-Team: \n"
406+"MIME-Version: 1.0\n"
407+"Content-Type: text/plain; charset=UTF-8\n"
408+"Content-Transfer-Encoding: \n"
409+"Plural-Forms: \n"
410+
411+#. module: asperience_account_invoice_sources
412+#: view:account.invoice:0
413+msgid "Source"
414+msgstr "Source"
415+
416+#. module: asperience_account_invoice_sources
417+#: view:account.invoice:0
418+msgid "Payments"
419+msgstr "RĆØglements"
420
421=== added directory 'asperience_account_invoice_sources/images'
422=== added file 'asperience_account_invoice_sources/images/asperience.png'
423Binary files asperience_account_invoice_sources/images/asperience.png 1970-01-01 00:00:00 +0000 and asperience_account_invoice_sources/images/asperience.png 2017-12-01 14:57:12 +0000 differ
424=== added file 'asperience_account_invoice_sources/images/group_invoice_view.png'
425Binary files asperience_account_invoice_sources/images/group_invoice_view.png 1970-01-01 00:00:00 +0000 and asperience_account_invoice_sources/images/group_invoice_view.png 2017-12-01 14:57:12 +0000 differ
426=== added directory 'asperience_configurator_mrp'
427=== added file 'asperience_configurator_mrp/Copy of mrp.py'
428--- asperience_configurator_mrp/Copy of mrp.py 1970-01-01 00:00:00 +0000
429+++ asperience_configurator_mrp/Copy of mrp.py 2017-12-01 14:57:12 +0000
430@@ -0,0 +1,463 @@
431+# -*- encoding: utf-8 -*-
432+##############################################################################
433+#
434+# OpenERP, Open Source Management Solution
435+# Copyright (C) 2011 ASPerience SARL (<http://www.asperience.fr>). All Rights Reserved
436+#
437+# This program is free software: you can redistribute it and/or modify
438+# it under the terms of the GNU General Public License as published by
439+# the Free Software Foundation, either version 3 of the License, or
440+# (at your option) any later version.
441+#
442+# This program is distributed in the hope that it will be useful,
443+# but WITHOUT ANY WARRANTY; without even the implied warranty of
444+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
445+# GNU General Public License for more details.
446+#
447+# You should have received a copy of the GNU General Public License
448+# along with this program. If not, see <http://www.gnu.org/licenses/>.
449+#
450+##############################################################################
451+
452+from openerp.osv import fields,osv
453+import openerp.netsvc
454+
455+import time
456+import datetime
457+from mx import DateTime
458+from openerp.tools.translate import _
459+from tools import ustr
460+
461+class mrp_workcenter_technology(osv.osv):
462+ _name = 'mrp.workcenter.technology'
463+ _columns = {
464+ 'name': fields.char('Description', size=256, required=True),
465+ }
466+ _defaults = {
467+ }
468+mrp_workcenter_technology()
469+
470+class mrp_workcenter(osv.osv):
471+ _inherit = 'mrp.workcenter'
472+
473+ def _get_type(self, cr, uid, ids, field_name, arg, context={}):
474+ res = {}
475+ for id in ids:
476+ res[id] = {'type_re': '', 'type_pc': '', 'type_cc': ''}
477+ for workcenter in self.browse(cr, uid, ids):
478+ if workcenter.type_workcenter == 're':
479+ res[id]['type_re'] = workcenter.type
480+ elif workcenter.type_workcenter == 'pc':
481+ res[id]['type_pc'] = workcenter.type
482+ elif workcenter.type_workcenter == 'cc':
483+ res[id]['type_cc'] = workcenter.type
484+ return res
485+
486+ def _set_type(self, cr, uid, ids, name, value, arg, context):
487+ if not value:
488+ return False
489+ if isinstance(ids, (int, long)):
490+ ids = [ids]
491+ for workcenter in self.browse(cr, uid, ids, context):
492+ self.write(cr, uid, ids, {'type': value})
493+ return True
494+
495+ def onchange_type(self, cr, uid, id, type=''):
496+ res = {'value':{'type': type}}
497+ return res
498+
499+ def onchange_type_workcenter(self, cr, uid, id, type_workcenter):
500+ res = {'value':{'type_re': '','type_pc': '', 'type_cc': '', 'type': ''}}
501+ if type_workcenter == 're' or type_workcenter == 'pc':
502+ res['value']['type_re'] = 'machine'
503+ elif type_workcenter == 'cc':
504+ res['value']['type_re'] = 'machine_hr'
505+ res['value']['type'] = res['value']['type_re']
506+ return res
507+
508+ _columns = {
509+ 'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool'),('machine_hr','Machine and HR'),('line','Line'),('energy','Energy')], 'Type', required=True),
510+ 'type_re': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('tool',_('Tool')),('energy',_('Energy'))],
511+ multi="type",method=True, store=False, type='selection', string='Type'),
512+ 'type_pc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('machine_hr',_('Machine and HR')),('line',_('Line'))],
513+ multi="type",method=True, store=False, type='selection', string='Type'),
514+ 'type_cc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine_hr',_('Machine and HR')),('line',_('Line'))],
515+ multi="type",method=True, store=False, type='selection', string='Type'),
516+ 'type_workcenter': fields.selection([('re',_('Elementary resource')),('pc',_('Work center')),('cc',_('Work line'))], 'Type workcenter', required=True, size=2),
517+ 'parent_id': fields.many2one('mrp.workcenter', "Parent"),
518+ 'child_ids': fields.one2many('mrp.workcenter', 'parent_id','Childs'),
519+ 'technology': fields.many2one('mrp.workcenter.technology', "Technology"),
520+ 'external': fields.boolean('External workcenter'),
521+ 'fixed_capacity': fields.boolean('Fixed capacity'),
522+ 'capacity' : fields.float('Capacity'),
523+ 'critical': fields.boolean('Critical'),
524+ 'property_ids': fields.many2many('mrp.property', 'mrp_workcenter_property_rel','workcenter_id', 'property_id', 'Properties'),
525+ 'warehouse_id': fields.many2one('stock.warehouse', 'Sector', required=True),
526+ 'finite_capacity': fields.boolean('Finite Capacity'),
527+ 'finite_capacity_qty' : fields.float('Finite Capacity Qty'),
528+ 'scheduling': fields.selection([('machine','Machine'),('hr','Human Resource'),('machine_hr','Machine and HR'),('pg','the greatest')], 'Scheduling'),
529+ }
530+ _defaults = {
531+ 'time_start': lambda *a: 0,
532+ 'time_stop': lambda *a: 0,
533+ 'time_cycle': lambda *a: 0,
534+ 'type_workcenter': lambda *a: "pc",
535+ }
536+
537+ def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=80):
538+ if args:
539+ if args[0][0] == 'type':
540+ for val in args[0][2]:
541+ if val:
542+ if val in ['line', 'machine_hr']:
543+ args = [('type', '=', 'line')]
544+ break
545+ elif val == 'machine':
546+ args = [('type', 'in', ['line','machine_hr','machine'])]
547+ break
548+ elif val in ['energy', 'hr', 'tool']:
549+ args = [('type', 'in', ['line','machine_hr','machine','hr'])]
550+ break
551+
552+ return super(mrp_workcenter, self).name_search(cr, uid, name, args, operator, context, limit)
553+
554+mrp_workcenter()
555+
556+class mrp_bom_component_mode(osv.osv):
557+ _name = 'mrp.bom.component.mode'
558+ _description = 'mrp.bom.component.mode'
559+ _columns = {
560+ 'name': fields.char('Description', size=256, required=True),
561+ 'dx': fields.text('Dx'),
562+ 'dy': fields.text('Dy'),
563+ 'dz': fields.text('Dz'),
564+ 'dd': fields.text('Dd'),
565+ }
566+ _defaults = {
567+ }
568+
569+mrp_bom_component_mode()
570+
571+class mrp_bom_component_rel(osv.osv):
572+ _name = 'mrp.bom.component.rel'
573+ _description = 'mrp.bom.component.rel'
574+ _columns = {
575+ 'bom_id': fields.many2one('mrp.bom', 'Bom', required=True, ondelete='cascade'),
576+ 'component_id': fields.many2one('mrp.bom', 'Component', required=True, ondelete='cascade'),
577+# 'product_component_id': fields.related('component_id','product_id',type='many2one', relation="product.product", string="Product"),
578+ 'qty': fields.float('Quantity', required=True),
579+ 'mode': fields.many2one('mrp.bom.component.mode', 'Mode'),
580+ }
581+
582+ def compute_size(self, cr, uid, ids, context={}):
583+ logger = netsvc.Logger()
584+ if not ids :
585+ return False
586+ result = {}
587+ for i in self.browse(cr,uid,ids,context):
588+ space = {}
589+ space["x"] = context.get("size_x",0.0)
590+ space["y"] = context.get("size_y",0.0)
591+ space["z"] = context.get("size_z",0.0)
592+ space["d"] = context.get("diameter",0.0)
593+ space["Dx"] = context.get("size_x_specific_delta",0.0)
594+ space["Dy"] = context.get("size_y_specific_delta",0.0)
595+ space["Dz"] = context.get("size_z_specific_delta",0.0)
596+ space["Dd"] = context.get("diameter_specific_delta",0.0)
597+
598+
599+ result[i.id] = {
600+ "size_x_specific_delta":0.0,
601+ "size_y_specific_delta":0.0,
602+ "size_z_specific_delta":0.0,
603+ "diameter_specific_delta":0.0,
604+ "size_x_specific":context.get("size_x",0.0),
605+ "size_y_specific":context.get("size_y",0.0),
606+ "size_z_specific":context.get("size_z",0.0),
607+ "diameter_specific":context.get("diameter",0.0),
608+ }
609+
610+ try:
611+ result[i.id]["size_x_specific_delta"] = eval(i.mode.dx,space)
612+ result[i.id]["size_x_specific"] = result[i.id]["size_x_specific"] - result[i.id]["size_x_specific_delta"]
613+ except Exception, e:
614+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
615+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform x "+str(i.mode.dx))
616+ try:
617+ result[i.id]["size_y_specific_delta"] = eval(i.mode.dy,space)
618+ result[i.id]["size_y_specific"] = result[i.id]["size_y_specific"] - result[i.id]["size_y_specific_delta"]
619+ except Exception, e:
620+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
621+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform y "+str(i.mode.dy))
622+ try:
623+ result[i.id]["size_z_specific_delta"] = eval(i.mode.dz,space)
624+ result[i.id]["size_z_specific"] = result[i.id]["size_z_specific"] - result[i.id]["size_z_specific_delta"]
625+ except Exception, e:
626+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
627+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform z "+str(i.mode.dz))
628+ try:
629+ result[i.id]["diameter_specific_delta"] = eval(i.mode.dd,space)
630+ result[i.id]["diameter_specific"] = result[i.id]["diameter_specific"] - result[i.id]["diameter_specific_delta"]
631+ except Exception, e:
632+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
633+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform d "+str(i.mode.dd))
634+
635+ return result
636+
637+ _defaults = {
638+ }
639+mrp_bom_component_rel()
640+
641+def rounding(f, r):
642+ if not r:
643+ return f
644+ return round(f / r) * r
645+
646+class mrp_bom(osv.osv):
647+ _inherit = 'mrp.bom'
648+
649+# def __init__(self, pool, cr):
650+# super(mrp_bom,self).__init__(pool,cr)
651+# cr.execute('select count(*) from mrp_bom_childs_rel')
652+# nb1 = cr.dictfetchall()[0]['count']
653+# cr.execute('select count(*) from mrp_bom_component_rel')
654+# nb2 = cr.dictfetchall()[0]['count']
655+# if nb1 and not nb2 :
656+# cr.execute('insert into mrp_bom_component_rel\
657+# (bom_id,component_id,qty)\
658+# select a.bom_id, a.child_id, b.product_qty\
659+# from mrp_bom_childs_rel a join mrp_bom b on a.bom_id = b.id')
660+#
661+# map_mode = {
662+# 'bottom':['.DES.'],
663+# 'top':['PLATEAU'],
664+# 'back':['.DER.'],
665+# 'front':['.FACE.'],
666+# 'side':['.COT.'],
667+# }
668+# for i in map_mode:
669+# for j in map_mode[i]:
670+# cr.execute("update mrp_bom_component_rel\
671+# set mode = ( select id\
672+# from mrp_bom_component_mode\
673+# where name = '"+ustr(i)+"')\
674+# where id in (\
675+# select a.id\
676+# from mrp_bom_component_rel a join mrp_bom b on a.component_id = b.id join product_product c on b.product_id = c.id join product_template d on c.product_tmpl_id = d.id\
677+# where c.default_code like '%"+ustr(j)+"%');")
678+
679+
680+ def _child_compute(self, cr, uid, ids, name, arg, context={}):
681+ result = {}
682+ for bom in self.browse(cr, uid, ids, context=context):
683+ result[bom.id] = map(lambda x: x.component_id.id, bom.bom_components)
684+ if bom.bom_components:
685+ continue
686+ ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
687+ if bom.type=='phantom' or ok:
688+ sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
689+ if sids:
690+ bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context)
691+ result[bom.id] += map(lambda x: x.component_id.id, bom2.bom_components)
692+ return result
693+
694+ def _compute_type(self, cr, uid, ids, field_name, arg, context):
695+ res = dict(map(lambda x: (x,''), ids))
696+ for line in self.browse(cr, uid, ids):
697+ if line.type=='phantom' and not line.bom_id:
698+ res[line.id] = 'set'
699+ continue
700+ if line.bom_lines or line.bom_components or line.type=='phantom':
701+ continue
702+ if line.product_id.supply_method=='produce':
703+ if line.product_id.procure_method=='make_to_stock':
704+ res[line.id] = 'stock'
705+ else:
706+ res[line.id] = 'order'
707+ return res
708+
709+ _columns = {
710+ 'bom_type': fields.selection([('ass','Assemble'),('exp','Disassemble'),('cut','Cutting'),('cutinput','Cutting Input'),('picking','Picking'),('delay','Delay'),('control','Quality control')], 'BOM Type', required=True ),
711+ 'bom_lines_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'bom_id', 'child_id', 'Child BoMs'),
712+ 'bom_parent_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'child_id', 'bom_id', 'Parent BoMs'),
713+ 'bom_components': fields.one2many('mrp.bom.component.rel', 'bom_id', 'Components'),
714+ 'bom_components_parent': fields.one2many('mrp.bom.component.rel', 'component_id', 'Parent Components'),
715+ 'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
716+ 'type_group_ids': fields.many2many('product.type.property.option', 'mrp_bom_options_rel', 'bom_id', 'type_id', 'GOO',help="Used to map which property option is taken from previous product in assembly chain, or pushed to in dissambly chain"),
717+ 'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hyerarchy", type='many2many'),
718+# 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_bom_group_property_rel','bom_id', 'group_id', 'BOM Property Group Rel', help="Used to produce with properties not defined in sale order"),
719+ 'sub_product_ids': fields.many2many('mrp.subproduct', 'mrp_bom_subproduct_rel','bom_id', 'sub_id', 'Sub products'),
720+ }
721+ _defaults = {
722+ 'bom_type': lambda *a: 'ass'
723+ }
724+
725+mrp_bom()
726+
727+class mrp_production(osv.osv):
728+ _inherit = 'mrp.production'
729+
730+ def _size(self, cr, uid, ids, field_name, arg, context):
731+ res = {}
732+ for proc in self.browse(cr, uid, ids):
733+ res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 , 'diameter': 0.0}
734+ if proc.product_id:
735+ res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
736+ res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
737+ res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
738+ res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
739+ return res
740+
741+ _columns = {
742+ 'procurement_ids': fields.one2many('procurement.order', 'production_id', 'Procurements'),
743+ 'specific_production':fields.boolean('Specific Production'),
744+ 'note_production':fields.text('Production Note'),
745+ 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
746+ 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
747+ 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
748+ 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
749+ 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True),
750+ 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
751+ 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
752+ 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
753+ 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
754+ 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
755+ 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
756+ 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
757+ 'uom_s_size_specific' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
758+ }
759+ _order = 'id desc'
760+
761+ def action_production_end(self, cr, uid, ids):
762+# move_ids = []
763+ for production in self.browse(cr, uid, ids):
764+ for res in production.move_lines:
765+ for move in production.move_created_ids:
766+ #XXX must use the orm
767+# cr.execute('INSERT INTO stock_move_history_ids \
768+# (parent_id, child_id) VALUES (%s,%s)',
769+# (res.id, move.id))
770+ #ASPerience: test des valeurs pour Ʃviter les erreurs de rƩƩcriture
771+ cr.execute('select parent_id,child_id from stock_move_history_ids where parent_id=%s and child_id=%s', (res.id, move.id))
772+ if len(cr.fetchall()) == 0:
773+ cr.execute('insert into stock_move_history_ids (parent_id,child_id) values (%s,%s)', (res.id, move.id))
774+ else:
775+ logger = netsvc.Logger()
776+ logger.notifyChannel("warning", netsvc.LOG_WARNING," ERROR insert into stock_move_history_ids parent_id=%s and child_id=%s'." % (str(move.id), str(move.move_dest_id.id)))
777+ #Fin ASPerience
778+# move_ids.append(res.id)
779+ vals= {'state':'confirmed'}
780+ new_moves = [x.id for x in production.move_created_ids]
781+ self.pool.get('stock.move').write(cr, uid, new_moves, vals)
782+ if not production.date_finnished:
783+ self.write(cr, uid, [production.id],
784+ {'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
785+ self.pool.get('stock.move').check_assign(cr, uid, new_moves)
786+ self.pool.get('stock.move').action_done(cr, uid, new_moves)
787+ self._costs_generate(cr, uid, production)
788+# self.pool.get('stock.move').action_done(cr, uid, move_ids)
789+ self.write(cr, uid, ids, {'state': 'done'})
790+ return True
791+
792+mrp_production()
793+
794+class mrp_production_product_line(osv.osv):
795+ _inherit = 'mrp.production.product.line'
796+
797+ _columns = {
798+ 'property_ids': fields.many2many('mrp.property', 'mrp_production_product_line_property_rel', 'line_id','property_id', 'Properties'),
799+ 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_line_group_property_rel','production_line_id', 'group_id', 'Product Property Group Rel '),
800+ 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
801+ 'option_ids': fields.many2many('product.links', 'mrp_production_product_line_options_rel','line_id', 'links_id', 'Option'),
802+ 'bom_id': fields.many2one('mrp.bom', 'Bom'),
803+ 'specific_production':fields.boolean('Specific Production'),
804+ 'note_production':fields.text('Production Note'),
805+ 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
806+ 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
807+ 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
808+ 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
809+ 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
810+ 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
811+ 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
812+ 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
813+ 'uom_s_size_specific' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
814+ }
815+mrp_production_product_line()
816+
817+class stock_production_lot(osv.osv):
818+ _inherit = 'stock.production.lot'
819+
820+ def search_specific(self,cr,uid,vals,delay):
821+ filter = [('product_id','=',vals['product_id'])]
822+ filter_key = ['density','diameter','shape','size_x','size_y','size_z','weight']
823+ for key in filter_key:
824+ if vals[key]:
825+ filter.append((key,'=',vals[key]))
826+
827+ today=datetime.datetime.today()
828+ if delay:
829+ limit = (today-datetime.timedelta(days=delay)).strftime('%Y-%m-%d %H:%M:%S')
830+ filter.append(('date','>',limit))
831+
832+ result = self.search(cr,uid,filter)
833+ set_property_ids = set(vals['property_ids'][0][2])
834+ set_group_property_ids = set(vals['group_property_ids'][0][2])
835+ set_option_ids = set(vals['option_ids'][0][2])
836+ for lot_id in result:
837+ lot = self.browse(cr,uid,lot_id)
838+ lot_property_ids = set([i.id for i in lot.property_ids])
839+ lot_group_property_ids = set([i.id for i in lot.group_property_ids])
840+ lot_option_ids = set([i.id for i in lot.option_ids])
841+ if lot_property_ids == set_property_ids and lot_group_property_ids == set_group_property_ids and lot_option_ids == set_option_ids :
842+ return lot.id
843+ return False
844+
845+ _columns = {
846+ 'property_ids': fields.many2many('mrp.property', 'mrp_production_lot_property_rel', 'lot_id','property_id', 'Properties'),
847+ 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_lot_group_property_rel','production_lot_id', 'group_id', 'Product Property Group Rel '),
848+ 'option_ids': fields.many2many('product.links', 'mrp_production_lot_options_rel','production_lot_id', 'links_id', 'Options'),
849+ }
850+
851+ _defaults = {
852+ }
853+stock_production_lot()
854+
855+class mrp_routing(osv.osv):
856+ _inherit = 'mrp.routing'
857+ _columns = {
858+ 'technical_data': fields.char('Technical Data', size=128),
859+ }
860+ _defaults = {
861+ 'active': lambda *a: 1,
862+ }
863+mrp_routing()
864+
865+class mrp_routing_workcenter_subproduct(osv.osv):
866+ _name = 'mrp.routing.workcenter.subproduct'
867+ _description = 'mrp.routing.workcenter.subproduct'
868+ _columns = {
869+ 'name': fields.float('Percent', required=True),
870+ 'subproduct_id': fields.many2one('mrp.subproduct', 'Subproduct', required=True),
871+ 'workcenter_line_id': fields.many2one('mrp.routing.workcenter', 'Routing Workcenter', required=True),
872+ }
873+mrp_routing_workcenter_subproduct()
874+
875+class mrp_routing_workcenter(osv.osv):
876+ _inherit = 'mrp.routing.workcenter'
877+ _columns = {
878+ 'sub_ids': fields.one2many('mrp.routing.workcenter.subproduct', 'workcenter_line_id', 'Sub Product'),
879+ 'bom_ids': fields.many2many('mrp.bom', 'routing_workcenter_mrp_bom_rel', 'workcenter_line_id', 'bom_id', 'Components'),
880+ }
881+ _defaults = {
882+ }
883+mrp_routing_workcenter()
884+
885+class mrp_production_workcenter_line(osv.osv):
886+ _inherit = 'mrp.production.workcenter.line'
887+ _columns = {
888+ 'move_ids' : fields.many2many('stock.move', 'mrp_production_workcenter_line_stock_move_rel', 'line_id', 'move_id', 'Moves'),
889+ }
890+ _defaults = {
891+ }
892+mrp_production_workcenter_line()
893+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
894\ No newline at end of file
895
896=== added file 'asperience_configurator_mrp/__init__.py'
897--- asperience_configurator_mrp/__init__.py 1970-01-01 00:00:00 +0000
898+++ asperience_configurator_mrp/__init__.py 2017-12-01 14:57:12 +0000
899@@ -0,0 +1,34 @@
900+# -*- encoding: utf-8 -*-
901+##############################################################################
902+#
903+# OpenERP, Open Source Management Solution
904+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
905+# All Rights Reserved
906+#
907+# This program is free software: you can redistribute it and/or modify
908+# it under the terms of the GNU General Public License as published by
909+# the Free Software Foundation, either version 3 of the License, or
910+# (at your option) any later version.
911+#
912+# This program is distributed in the hope that it will be useful,
913+# but WITHOUT ANY WARRANTY; without even the implied warranty of
914+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
915+# GNU General Public License for more details.
916+#
917+# You should have received a copy of the GNU General Public License
918+# along with this program. If not, see <http://www.gnu.org/licenses/>.
919+#
920+##############################################################################
921+import company
922+import product
923+import stock
924+import stock_production
925+import procurement
926+import mrp_property
927+import mrp_bom
928+import mrp_subproduct
929+import mrp_workcenter
930+import mrp_routing
931+import mrp_production
932+#import report
933+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
934\ No newline at end of file
935
936=== added file 'asperience_configurator_mrp/__openerp__.py'
937--- asperience_configurator_mrp/__openerp__.py 1970-01-01 00:00:00 +0000
938+++ asperience_configurator_mrp/__openerp__.py 2017-12-01 14:57:12 +0000
939@@ -0,0 +1,76 @@
940+# -*- encoding: utf-8 -*-
941+##############################################################################
942+#
943+# OpenERP, Open Source Management Solution
944+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
945+# All Rights Reserved
946+#
947+# This program is free software: you can redistribute it and/or modify
948+# it under the terms of the GNU General Public License as published by
949+# the Free Software Foundation, either version 3 of the License, or
950+# (at your option) any later version.
951+#
952+# This program is distributed in the hope that it will be useful,
953+# but WITHOUT ANY WARRANTY; without even the implied warranty of
954+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
955+# GNU General Public License for more details.
956+#
957+# You should have received a copy of the GNU General Public License
958+# along with this program. If not, see <http://www.gnu.org/licenses/>.
959+#
960+##############################################################################
961+{
962+ "name": "ASPerience - MRP",
963+ "version": "8.0",
964+ "author": "ASPerience",
965+ "website": "http://www.asperience.fr",
966+ "sequence": 0,
967+ "certificate": "",
968+ "license": "",
969+ "depends": [
970+ "mrp",
971+ "mrp_byproduct",
972+ "mrp_operations",
973+ "product",
974+ "stock",
975+ "asperience_product_attributes",
976+ ],
977+ "category": "Generic Modules/ASPerience",
978+ "complexity": "easy",
979+ "description": """
980+BOM tree management, trees of supplies from the configurator and trees production.
981+Filtering system of nomenclature by properties, from supplies.
982+Management of product properties.
983+ """,
984+ "data": [
985+ "security/ir.model.access.csv",
986+ "company_view.xml",
987+ "product_view.xml",
988+ "procurement_view.xml",
989+ "mrp_view.xml",
990+ "stock_production_view.xml",
991+ "mrp_workflow.xml",
992+ "mrp_report.xml",
993+ "mrp_subproduct_view.xml",
994+ "mrp_data.xml",
995+ ],
996+ "demo": [
997+ ],
998+ "test": [
999+ ],
1000+ "js": [
1001+ ],
1002+ "css": [
1003+ ],
1004+ "qweb": [
1005+ ],
1006+ "demo_xml": [
1007+ ],
1008+ "images": [
1009+ ],
1010+ "auto_install": False,
1011+ "installable": True,
1012+ "application": False,
1013+
1014+}
1015+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1016\ No newline at end of file
1017
1018=== added file 'asperience_configurator_mrp/bom_graph.pyc'
1019Binary files asperience_configurator_mrp/bom_graph.pyc 1970-01-01 00:00:00 +0000 and asperience_configurator_mrp/bom_graph.pyc 2017-12-01 14:57:12 +0000 differ
1020=== added file 'asperience_configurator_mrp/company.py'
1021--- asperience_configurator_mrp/company.py 1970-01-01 00:00:00 +0000
1022+++ asperience_configurator_mrp/company.py 2017-12-01 14:57:12 +0000
1023@@ -0,0 +1,32 @@
1024+# -*- encoding: utf-8 -*-
1025+##############################################################################
1026+#
1027+# OpenERP, Open Source Management Solution
1028+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
1029+# All Rights Reserved
1030+#
1031+# This program is free software: you can redistribute it and/or modify
1032+# it under the terms of the GNU General Public License as published by
1033+# the Free Software Foundation, either version 3 of the License, or
1034+# (at your option) any later version.
1035+#
1036+# This program is distributed in the hope that it will be useful,
1037+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1038+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1039+# GNU General Public License for more details.
1040+#
1041+# You should have received a copy of the GNU General Public License
1042+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1043+#
1044+##############################################################################
1045+from openerp.osv import osv, fields
1046+
1047+class res_company(osv.osv):
1048+ _inherit = 'res.company'
1049+
1050+ _columns = {
1051+ 'tracking_production_delay':fields.integer('Tracking production delay'),
1052+ }
1053+
1054+res_company()
1055+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1056\ No newline at end of file
1057
1058=== added file 'asperience_configurator_mrp/company_view.xml'
1059--- asperience_configurator_mrp/company_view.xml 1970-01-01 00:00:00 +0000
1060+++ asperience_configurator_mrp/company_view.xml 2017-12-01 14:57:12 +0000
1061@@ -0,0 +1,16 @@
1062+<?xml version="1.0" encoding="utf-8"?>
1063+<openerp>
1064+ <data>
1065+ <record id="view_company_form_asperience_mrp" model="ir.ui.view">
1066+ <field name="name">res.company.form.asperience.mrp</field>
1067+ <field name="model">res.company</field>
1068+ <field name="priority">25</field>
1069+ <field name="inherit_id" ref="base.view_company_form"/>
1070+ <field name="arch" type="xml">
1071+ <field name="manufacturing_lead" position="after">
1072+ <field name="tracking_production_delay"/>
1073+ </field>
1074+ </field>
1075+ </record>
1076+ </data>
1077+</openerp>
1078
1079=== added directory 'asperience_configurator_mrp/i18n'
1080=== added file 'asperience_configurator_mrp/i18n/fr_FR.po'
1081--- asperience_configurator_mrp/i18n/fr_FR.po 1970-01-01 00:00:00 +0000
1082+++ asperience_configurator_mrp/i18n/fr_FR.po 2017-12-01 14:57:12 +0000
1083@@ -0,0 +1,274 @@
1084+# Translation of ASPerPGI.
1085+# This file contains the translation of the following modules:
1086+# * asperience_mrp
1087+# * report_mrp
1088+# * mrp
1089+#
1090+msgid ""
1091+msgstr ""
1092+"Project-Id-Version: ASPerPGI 5.0.10\n"
1093+"Report-Msgid-Bugs-To: support@openerp.com\n"
1094+"POT-Creation-Date: 2010-11-10 08:50:02+0000\n"
1095+"PO-Revision-Date: 2010-11-10 08:50:02+0000\n"
1096+"Last-Translator: <>\n"
1097+"Language-Team: \n"
1098+"MIME-Version: 1.0\n"
1099+"Content-Type: text/plain; charset=UTF-8\n"
1100+"Content-Transfer-Encoding: \n"
1101+"Plural-Forms: \n"
1102+
1103+#. module: mrp
1104+#: view:mrp.production:0
1105+msgid "Consumed Products"
1106+msgstr "Produits ConsommƩs"
1107+
1108+#. module: asperience_mrp
1109+#: field:procurement.order,specific_production:0
1110+#: field:mrp.production,specific_production:0
1111+msgid "Specific Production"
1112+msgstr "Production spƩcifique"
1113+
1114+#. module: mrp
1115+#: model:ir.actions.wizard,name:mrp.product_procurement_wizard
1116+msgid "Procurement Request"
1117+msgstr "Demande d'approvisionnement"
1118+
1119+#. module: asperience_mrp
1120+#: field:product.category.property,categ_id:0
1121+msgid "Category"
1122+msgstr "Categorie"
1123+
1124+#. module: asperience_mrp
1125+#: model:ir.module.module,shortdesc:asperience_mrp.module_meta_information
1126+msgid "ASPerience - MRP"
1127+msgstr ""
1128+
1129+#. module: asperience_mrp
1130+#: field:mrp.property,size_y_tmpl:0
1131+msgid "Length"
1132+msgstr "Largeur"
1133+
1134+#. module: asperience_mrp
1135+#: field:mrp.workcenter,capacity:0
1136+msgid "Capacity"
1137+msgstr "CapacitƩ"
1138+
1139+#. module: asperience_mrp
1140+#: code:addons/asperience_mrp/mrp.py:0
1141+#: selection:mrp.workcenter,type_workcenter:0
1142+#, python-format
1143+msgid "Work line"
1144+msgstr "Ligne de production"
1145+
1146+#. module: asperience_mrp
1147+#: field:mrp.property,size_z_tmpl:0
1148+msgid "Thickness"
1149+msgstr "Hauteur"
1150+
1151+#. module: asperience_mrp
1152+#: field:mrp.property.group.option,type_group_id:0
1153+#: field:product.category.property,type_group:0
1154+#: field:product.property,type_group:0
1155+msgid "Group By"
1156+msgstr "Grouper par"
1157+
1158+#. module: asperience_mrp
1159+#: view:product.product:0
1160+msgid "Generate BoM"
1161+msgstr "GƩnƩrer le BoM"
1162+
1163+
1164+#. module: asperience_mrp
1165+#: field:product.product,bom:0
1166+msgid "BoM Generated"
1167+msgstr "BoM gƩnƩrƩ"
1168+
1169+#. module: asperience_mrp
1170+#: view:product.product:0
1171+msgid "Generate"
1172+msgstr "GƩnƩrer"
1173+
1174+#. module: asperience_mrp
1175+#: field:mrp.property,uom_s_size_tmpl:0
1176+msgid "Size Uom"
1177+msgstr "Udm taille"
1178+
1179+#. module: asperience_mrp
1180+#: field:mrp.property,price:0
1181+msgid "Price"
1182+msgstr "Prix"
1183+
1184+#. module: asperience_mrp
1185+#: field:mrp.production.product.line,property_ids:0
1186+#: field:mrp.property.group,property_ids:0
1187+#: field:mrp.property.group.option,property_id:0
1188+#: field:mrp.workcenter,property_ids:0
1189+msgid "Properties"
1190+msgstr "PropriƩtƩs"
1191+
1192+#. module: asperience_mrp
1193+#: field:mrp.property,size_x_tmpl:0
1194+msgid "Width"
1195+msgstr "Profondeur"
1196+
1197+#. module: asperience_mrp
1198+#: field:mrp.workcenter,external:0
1199+msgid "External workcenter"
1200+msgstr ""
1201+
1202+#. module: asperience_mrp
1203+#: field:mrp.workcenter,critical:0
1204+msgid "Critical"
1205+msgstr ""
1206+
1207+#. module: asperience_mrp
1208+#: selection:product.category.property,type:0
1209+msgid "Template"
1210+msgstr "ModĆØle"
1211+
1212+#. module: asperience_mrp
1213+#: constraint:ir.model:0
1214+msgid "The Object name must start with x_ and not contain any special character !"
1215+msgstr "Le nom de l'objet doit commencer avec x_ et ne pas contenir de charactĆØres spĆ©ciaux !"
1216+
1217+#. module: asperience_mrp
1218+#: view:product.property:0
1219+msgid "Product Properties Product"
1220+msgstr "Options de Configuration PropriƩtƩs du Produit"
1221+
1222+#. module: asperience_mrp
1223+#: field:product.category.property,type:0
1224+msgid "Type"
1225+msgstr ""
1226+
1227+#. module: asperience_mrp
1228+#: model:ir.model,name:asperience_mrp.model_mrp_workcenter_technology
1229+msgid "mrp.workcenter.technology"
1230+msgstr "Famille technologique"
1231+
1232+#. module: asperience_mrp
1233+#: selection:product.category.property,type:0
1234+#: field:product.property,product_id:0
1235+#: field:product.property,template_id:0
1236+msgid "Product"
1237+msgstr "Produit"
1238+
1239+#. module: asperience_mrp
1240+#: field:product.property,used:0
1241+msgid "Used"
1242+msgstr "Actif"
1243+
1244+#. module: asperience_mrp
1245+#: field:mrp.workcenter.technology,name:0
1246+#: view:product.category:0
1247+#: field:product.category,description:0
1248+#: field:product.category.property,name:0
1249+#: field:product.property,name:0
1250+msgid "Description"
1251+msgstr ""
1252+
1253+#. module: asperience_mrp
1254+#: field:product.category,linked_product_ids:0
1255+msgid "Linked products"
1256+msgstr ""
1257+
1258+#. module: asperience_mrp
1259+#: code:addons/asperience_mrp/mrp.py:0
1260+#: selection:mrp.workcenter,type_workcenter:0
1261+#, python-format
1262+msgid "Elementary resource"
1263+msgstr "Ressource ƩlƩmentaire"
1264+
1265+#. module: asperience_mrp
1266+#: model:ir.model,name:asperience_mrp.model_product_property
1267+msgid "product.property"
1268+msgstr "PropriƩtƩs"
1269+
1270+#. module: asperience_mrp
1271+#: field:mrp.workcenter,type_workcenter:0
1272+msgid "Type workcenter"
1273+msgstr "Type de centre de travail"
1274+
1275+#. module: asperience_mrp
1276+#: view:product.product.property:0
1277+msgid "Properties"
1278+msgstr "PropriƩtƩs"
1279+
1280+#. module: asperience_mrp
1281+#: code:addons/asperience_mrp/mrp.py:0
1282+#: selection:mrp.workcenter,type_workcenter:0
1283+#, python-format
1284+msgid "Work center"
1285+msgstr "Machine"
1286+
1287+#. module: asperience_mrp
1288+#: constraint:ir.ui.view:0
1289+msgid "Invalid XML for View Architecture!"
1290+msgstr "XML non valide pour l'architecture de la vue"
1291+
1292+#. module: asperience_mrp
1293+#: field:mrp.workcenter,fixed_capacity:0
1294+msgid "Fixed capacity"
1295+msgstr ""
1296+
1297+#. module: asperience_mrp
1298+#: field:mrp.property.group,required:0
1299+msgid "Required"
1300+msgstr "Requis"
1301+
1302+#. module: asperience_mrp
1303+#: view:product.category.property:0
1304+msgid "Product Property"
1305+msgstr "PropriƩtƩs"
1306+
1307+#. module: asperience_mrp
1308+#: field:mrp.property,code:0
1309+msgid "Code"
1310+msgstr ""
1311+
1312+#. module: asperience_mrp
1313+#: field:product.category,property_ids:0
1314+#: field:product.category.property,property_id:0
1315+#: field:product.property,property_id:0
1316+msgid "Property"
1317+msgstr "PropriƩtƩ"
1318+
1319+#. module: asperience_mrp
1320+#: field:mrp.workcenter,child_ids:0
1321+msgid "Childs"
1322+msgstr "Enfants"
1323+
1324+#. module: asperience_mrp
1325+#: field:mrp.workcenter,parent_id:0
1326+msgid "Parent"
1327+msgstr ""
1328+
1329+#. module: asperience_mrp
1330+#: field:product.template,property_tmpl_ids:0
1331+msgid "Property Template"
1332+msgstr ""
1333+
1334+#. module: asperience_mrp
1335+#: field:product.template,linked_product_tmpl_ids:0
1336+msgid "Linked products template"
1337+msgstr "Options de Configuration Option du ModĆØle"
1338+
1339+#. module: asperience_mrp
1340+#: view:product.property:0
1341+msgid "Product Properties Template"
1342+msgstr "Options de Configuration PropriĆ©tĆ©s du ModĆØle"
1343+
1344+#. module: asperience_mrp
1345+#: model:ir.model,name:asperience_mrp.model_product_category_property
1346+msgid "product.category.property"
1347+msgstr ""
1348+
1349+#. module: asperience_mrp
1350+#: field:mrp.workcenter,technology:0
1351+msgid "Technology"
1352+msgstr "Famille technologique"
1353+
1354+#. module: report_mrp
1355+#: field:report.mrp.inout,value:0
1356+msgid "Stock value"
1357+msgstr "Valeur de stock"
1358
1359=== added file 'asperience_configurator_mrp/mrp.pyc'
1360Binary files asperience_configurator_mrp/mrp.pyc 1970-01-01 00:00:00 +0000 and asperience_configurator_mrp/mrp.pyc 2017-12-01 14:57:12 +0000 differ
1361=== added file 'asperience_configurator_mrp/mrp_bom.py'
1362--- asperience_configurator_mrp/mrp_bom.py 1970-01-01 00:00:00 +0000
1363+++ asperience_configurator_mrp/mrp_bom.py 2017-12-01 14:57:12 +0000
1364@@ -0,0 +1,843 @@
1365+# -*- encoding: utf-8 -*-
1366+##############################################################################
1367+#
1368+# OpenERP, Open Source Management Solution
1369+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
1370+# All Rights Reserved
1371+#
1372+# This program is free software: you can redistribute it and/or modify
1373+# it under the terms of the GNU General Public License as published by
1374+# the Free Software Foundation, either version 3 of the License, or
1375+# (at your option) any later version.
1376+#
1377+# This program is distributed in the hope that it will be useful,
1378+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1379+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1380+# GNU General Public License for more details.
1381+#
1382+# You should have received a copy of the GNU General Public License
1383+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1384+#
1385+##############################################################################
1386+from openerp.osv import fields,osv
1387+#import openerp.netsvc
1388+#from openerp.tools.translate import _
1389+#from openerp.tools import ustr
1390+import logging
1391+_logger = logging.getLogger(__name__)
1392+
1393+class mrp_bom_component_mode(osv.osv):
1394+ _name = 'mrp.bom.component.mode'
1395+ _description = 'mrp.bom.component.mode'
1396+ _columns = {
1397+ 'name': fields.char('Description', size=256, required=True),
1398+ 'dx': fields.text('Dx'),
1399+ 'dy': fields.text('Dy'),
1400+ 'dz': fields.text('Dz'),
1401+ 'dd': fields.text('Dd'),
1402+ }
1403+ _defaults = {
1404+ }
1405+
1406+mrp_bom_component_mode()
1407+
1408+class mrp_bom_component_rel(osv.osv):
1409+ _name = 'mrp.bom.component.rel'
1410+ _description = 'mrp.bom.component.rel'
1411+ _columns = {
1412+ 'bom_id': fields.many2one('mrp.bom', 'Bom', required=True, ondelete='cascade'),
1413+ 'component_id': fields.many2one('mrp.bom', 'Component', required=True, ondelete='cascade'),
1414+# 'product_component_id': fields.related('component_id','product_id',type='many2one', relation="product.product", string="Product"),
1415+ 'qty': fields.float('Quantity', required=True),
1416+ 'mode': fields.many2one('mrp.bom.component.mode', 'Mode'),
1417+ }
1418+
1419+ def compute_size(self, cr, uid, ids, context={}):
1420+ logger = netsvc.Logger()
1421+ if not ids :
1422+ return False
1423+ result = {}
1424+ for i in self.browse(cr,uid,ids,context):
1425+ space = {}
1426+ space["x"] = context.get("size_x",0.0)
1427+ space["y"] = context.get("size_y",0.0)
1428+ space["z"] = context.get("size_z",0.0)
1429+ space["d"] = context.get("diameter",0.0)
1430+ space["Dx"] = context.get("size_x_specific_delta",0.0)
1431+ space["Dy"] = context.get("size_y_specific_delta",0.0)
1432+ space["Dz"] = context.get("size_z_specific_delta",0.0)
1433+ space["Dd"] = context.get("diameter_specific_delta",0.0)
1434+
1435+
1436+ result[i.id] = {
1437+ "size_x_specific_delta":0.0,
1438+ "size_y_specific_delta":0.0,
1439+ "size_z_specific_delta":0.0,
1440+ "diameter_specific_delta":0.0,
1441+ "size_x_specific":context.get("size_x",0.0),
1442+ "size_y_specific":context.get("size_y",0.0),
1443+ "size_z_specific":context.get("size_z",0.0),
1444+ "diameter_specific":context.get("diameter",0.0),
1445+ }
1446+
1447+ try:
1448+ result[i.id]["size_x_specific_delta"] = eval(i.mode.dx,space)
1449+ result[i.id]["size_x_specific"] = result[i.id]["size_x_specific"] - result[i.id]["size_x_specific_delta"]
1450+ except Exception, e:
1451+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
1452+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform x "+str(i.mode.dx))
1453+ try:
1454+ result[i.id]["size_y_specific_delta"] = eval(i.mode.dy,space)
1455+ result[i.id]["size_y_specific"] = result[i.id]["size_y_specific"] - result[i.id]["size_y_specific_delta"]
1456+ except Exception, e:
1457+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
1458+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform y "+str(i.mode.dy))
1459+ try:
1460+ result[i.id]["size_z_specific_delta"] = eval(i.mode.dz,space)
1461+ result[i.id]["size_z_specific"] = result[i.id]["size_z_specific"] - result[i.id]["size_z_specific_delta"]
1462+ except Exception, e:
1463+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
1464+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform z "+str(i.mode.dz))
1465+ try:
1466+ result[i.id]["diameter_specific_delta"] = eval(i.mode.dd,space)
1467+ result[i.id]["diameter_specific"] = result[i.id]["diameter_specific"] - result[i.id]["diameter_specific_delta"]
1468+ except Exception, e:
1469+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
1470+ logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform d "+str(i.mode.dd))
1471+
1472+ return result
1473+
1474+ _defaults = {
1475+ }
1476+mrp_bom_component_rel()
1477+
1478+def rounding(f, r):
1479+ if not r:
1480+ return f
1481+ return round(f / r) * r
1482+
1483+class mrp_bom(osv.osv):
1484+ _inherit = 'mrp.bom'
1485+
1486+# def __init__(self, pool, cr):
1487+# super(mrp_bom,self).__init__(pool,cr)
1488+# cr.execute('select count(*) from mrp_bom_childs_rel')
1489+# nb1 = cr.dictfetchall()[0]['count']
1490+# cr.execute('select count(*) from mrp_bom_component_rel')
1491+# nb2 = cr.dictfetchall()[0]['count']
1492+# if nb1 and not nb2 :
1493+# cr.execute('insert into mrp_bom_component_rel\
1494+# (bom_id,component_id,qty)\
1495+# select a.bom_id, a.child_id, b.product_qty\
1496+# from mrp_bom_childs_rel a join mrp_bom b on a.bom_id = b.id')
1497+#
1498+# map_mode = {
1499+# 'bottom':['.DES.'],
1500+# 'top':['PLATEAU'],
1501+# 'back':['.DER.'],
1502+# 'front':['.FACE.'],
1503+# 'side':['.COT.'],
1504+# }
1505+# for i in map_mode:
1506+# for j in map_mode[i]:
1507+# cr.execute("update mrp_bom_component_rel\
1508+# set mode = ( select id\
1509+# from mrp_bom_component_mode\
1510+# where name = '"+ustr(i)+"')\
1511+# where id in (\
1512+# select a.id\
1513+# from mrp_bom_component_rel a join mrp_bom b on a.component_id = b.id join product_product c on b.product_id = c.id join product_template d on c.product_tmpl_id = d.id\
1514+# where c.default_code like '%"+ustr(j)+"%');")
1515+
1516+
1517+ def _child_compute(self, cr, uid, ids, name, arg, context={}):
1518+ result = {}
1519+ for bom in self.browse(cr, uid, ids, context=context):
1520+ result[bom.id] = map(lambda x: x.component_id.id, bom.bom_components)
1521+ if bom.bom_components:
1522+ continue
1523+ ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
1524+ if bom.type=='phantom' or ok:
1525+ sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
1526+ if sids:
1527+ bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context)
1528+ result[bom.id] += map(lambda x: x.component_id.id, bom2.bom_components)
1529+ return result
1530+
1531+ def _compute_type(self, cr, uid, ids, field_name, arg, context):
1532+ res = dict(map(lambda x: (x,''), ids))
1533+ for line in self.browse(cr, uid, ids):
1534+ if line.type=='phantom' and not line.bom_id:
1535+ res[line.id] = 'set'
1536+ continue
1537+ if line.bom_lines or line.bom_components or line.type=='phantom':
1538+ continue
1539+ if line.product_id.supply_method=='produce':
1540+ if line.product_id.procure_method=='make_to_stock':
1541+ res[line.id] = 'stock'
1542+ else:
1543+ res[line.id] = 'order'
1544+ return res
1545+
1546+ _columns = {
1547+ #Dimensions
1548+ 'size_x': fields.float('Width', digits=(16, 5)),
1549+ 'size_y': fields.float('Length', digits=(16, 5)),
1550+ 'size_z': fields.float('Thickness', digits=(16, 5)),
1551+ 'density': fields.float('Density', digits=(16, 5)),
1552+ 'shape' : fields.selection([('quadrangular', 'Quadrangular'), ('cylindrical', 'Cylindrical'), ('other', 'Other')], 'Shape', required=True),
1553+ 'diameter' : fields.float('Diameter', digits=(16, 5)),
1554+ 'weight': fields.float('Weight', digits=(16, 5)),
1555+ #Production
1556+ 'bom_type': fields.selection([('ass','Assemble'),('exp','Disassemble'),('cut','Cutting'),('cutinput','Cutting Input'),('picking','Picking'),('delay','Delay'),('control','Quality control')], 'BOM Type', required=True ),
1557+ 'bom_lines_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'bom_id', 'child_id', 'Child BoMs'),
1558+ 'bom_parent_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'child_id', 'bom_id', 'Parent BoMs'),
1559+ 'bom_components': fields.one2many('mrp.bom.component.rel', 'bom_id', 'Components'),
1560+ 'bom_components_parent': fields.one2many('mrp.bom.component.rel', 'component_id', 'Parent Components'),
1561+ 'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
1562+ 'type_group_ids': fields.many2many('product.type.property.option', 'mrp_bom_options_rel', 'bom_id', 'type_id', 'GOO',help="Used to map which property option is taken from previous product in assembly chain, or pushed to in dissambly chain"),
1563+ 'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hyerarchy", type='many2many'),
1564+# 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_bom_group_property_rel','bom_id', 'group_id', 'BOM Property Group Rel', help="Used to produce with properties not defined in sale order"),
1565+ 'sub_product_ids': fields.many2many('mrp.subproduct', 'mrp_bom_subproduct_rel','bom_id', 'sub_id', 'Sub products'),
1566+ }
1567+ _defaults = {
1568+ 'bom_type': lambda *a: 'ass'
1569+ }
1570+
1571+ def compute_weight(self, cr, uid, id, product_id, size_x, size_y, size_z, shape, density, diameter):
1572+ if product_id:
1573+ product = self.pool.get('product.product').browse(cr, uid, product_id, context='')
1574+ factor1 = product.uom_d_weight.factor
1575+ factor2 = product.uom_id.factor
1576+ factor3 = product.uom_d_size.factor
1577+ factor4 = product.uom_s_size.factor
1578+ return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter)}
1579+
1580+ def onchange_product_id(self, cr, uid, ids, product_id, name, id, context={}):
1581+ if product_id:
1582+ w = self.pool.get('product.product').browse(cr, uid, [product_id], context)[0]
1583+ factor1 = w.uom_d_weight.factor
1584+ factor2 = w.uom_id.factor
1585+ factor3 = w.uom_d_size.factor
1586+ factor4 = w.uom_s_size.factor
1587+ v = {
1588+ 'product_uom':w.uom_id.id,
1589+ 'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id,
1590+ 'size_x':w.size_x or w.size_x_tmpl,
1591+ 'size_y':w.size_y or w.size_y_tmpl,
1592+ 'size_z':w.size_z or w.size_z_tmpl,
1593+ 'density':w.density or w.density_tmpl,
1594+ 'shape':w.shape,
1595+ 'diameter':w.diameter or w.diameter_tmpl,
1596+ 'weight': compute_w(cr, uid, factor1, factor2, factor3, factor4, w.size_x or w.size_x_tmpl, w.size_y or w.size_y_tmpl, w.size_z or w.size_z_tmpl, w.shape, w.density or w.density_tmpl, w.diameter or w.diameter_tmpl)['weight'],
1597+ 'name' : w.name,
1598+ }
1599+ if id :
1600+ v['bom_id'] = id
1601+ return {'value': v}
1602+ return {}
1603+
1604+ def button_quality_control(self,cr,uid,ids,context={}):
1605+ revision_obj = self.pool.get('stock.production.lot.revision')
1606+ attachment_obj = self.pool.get('ir.attachment')
1607+ for i in ids:
1608+ lot = self.browse(cr,uid,i)
1609+ if not lot.production_date:
1610+ raise osv.except_osv(_('Error :"'),_("Missing production date"))
1611+
1612+ if lot.revisions:
1613+ indice = (max([eval(revision.indice) for revision in lot.revisions]) or 0) + 1
1614+ else:
1615+ indice = 1
1616+ vals = {
1617+ 'name': _("certificate"),
1618+ 'description': _("Conformity certificate generation"),
1619+ 'indice': str(indice),
1620+ 'date': datetime.datetime.now(),
1621+ 'author_id': uid,
1622+ 'lot_id': i,
1623+ }
1624+ revision_obj.create(cr,uid,vals)
1625+ report = "stock.production.lot.conformity.certificate"
1626+ ir_obj = self.pool.get('ir.actions.report.xml')
1627+ report_xml_ids = ir_obj.search(cr, uid,[('report_name', '=', report)])
1628+ if report_xml_ids:
1629+ report_xml = ir_obj.browse(cr, uid, report_xml_ids[0])
1630+ service = netsvc.LocalService("report."+report)
1631+ (r, format) = service.create(cr, uid, [i], {}, {})
1632+ report_file = report_xml.name+'.'+format
1633+ report_datas = base64.encodestring(r)
1634+ data_attach = {
1635+ 'name': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice),
1636+ 'datas':report_datas,
1637+ 'datas_fname': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice)+".pdf",
1638+ 'description': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice)+".pdf",
1639+ 'res_model': 'stock.production.lot',
1640+ 'res_id': i
1641+ }
1642+ attachment_obj.create(cr,uid, data_attach)
1643+ self.write(cr,uid,ids,{'quality_control':True})
1644+
1645+ return True
1646+
1647+ def _bom_find(self, cr, uid, product_id, product_uom, properties=[], group_properties_filter=[], bom_type='ass', level=0):
1648+ level_str = "-"*level
1649+ print_tab(level,"*"*50)
1650+ print_tab(level,"_bom_find",product_id)
1651+ print_tab(level,"_bom_find properties",properties)
1652+ print_tab(level,"_bom_find group_properties_filter",group_properties_filter)
1653+ pre = level_str+"_bom_find "
1654+ print_tab(level,"_"*50)
1655+ bom_result = False
1656+ # Why searching on BoM without parent ?
1657+ cr.execute('select id from mrp_bom where product_id=%s and bom_id is null and bom_type = %s order by sequence', (product_id,bom_type))
1658+ ids = map(lambda x: x[0], cr.fetchall())
1659+
1660+ if not ids :
1661+ print_tab(pre+"generate all")
1662+ self.pool.get('product.product').generate_bom(cr,uid,[product_id])
1663+ print_tab(pre+"return bom_find after generate")
1664+ print_tab("9"*50)
1665+ return self._bom_find(cr, uid, product_id, product_uom, properties, group_properties_filter,level=level+1)
1666+
1667+ max_prop = 0
1668+ result = False
1669+
1670+ if not properties and not group_properties_filter:
1671+ #Produit configurable: recherche du BOM principal
1672+ print_tab(pre+"Produit configurable: recherche du BOM principal",product_id)
1673+ for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
1674+ not_filter = True
1675+ for group_id in bom.type_group_ids:
1676+# print pre+"group_id ",group_id.id
1677+ if group_id.execution_filter :
1678+# print pre+"group_id filter "
1679+ not_filter = False
1680+ if not_filter:
1681+ result = bom.id
1682+ break
1683+ if not result :
1684+ self.pool.get('product.product').generate_bom(cr,uid,[product_id])
1685+ return self._bom_find(cr, uid, product_id, product_uom, [], [],level=level+1)
1686+ elif group_properties_filter :
1687+ #Produit configurable: recherche du BOM liƩ au groupe de propriƩtƩ
1688+ print_tab(pre+"Produit configurable: recherche du BOM liƩ au groupe de propriƩtƩ",product_id)
1689+# group_properties_filter = [i.type_group_id.id for i in self.pool.get('mrp.property.group.option').browse(cr, uid, group_properties_filter)]
1690+ for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
1691+ for group_id in bom.type_group_ids:
1692+ print_tab(pre+"group_id ",group_id.id,group_id.name,group_id.execution_filter)
1693+ print_tab(group_properties_filter)
1694+ if group_id.execution_filter and group_id.id in group_properties_filter:
1695+ result = bom.id
1696+ break
1697+ if not result :
1698+ parent = self._bom_find(cr, uid, product_id, product_uom,level=level+1)
1699+ self.pool.get('product.product').generate_bom(cr,uid,[product_id],{"rec":1,"product_qty":1,"options":group_properties_filter, 'bom_parent':parent})[product_id]
1700+ print_tab(pre+"return bom_find")
1701+# # CA NE FONCTIONNE PAS AVEC CA MAIS CE N4EST PAS NORMAL
1702+ print_tab("8"*50)
1703+ return self._bom_find(cr, uid, product_id, product_uom, properties, group_properties_filter,level=level+1)
1704+ else:
1705+ #Produit avec configuration mrp originale
1706+ print pre+"Produit avec configuration mrp originale"
1707+ for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
1708+ prop = 0
1709+ for prop_id in bom.property_ids:
1710+ if prop_id.id in properties:
1711+ prop+=1
1712+ if (prop>max_prop) or ((max_prop==0) and not result):
1713+ result = bom.id
1714+ max_prop = prop
1715+
1716+ print_tab(pre+"return result",result)
1717+ print_tab("-"*50)
1718+ return result
1719+
1720+ def _bom_explode(self, cr, uid, bom, factor, properties, addthis=False, level=1, group_properties=[], procurement_id=False, context={}):
1721+ level_str = "-"*level
1722+ print_tab(level,"_bom_explode")
1723+ print_tab(level,"procurement_id",procurement_id)
1724+ print_tab(level,"bom.id",bom.id)
1725+ factor = factor / (bom.product_efficiency or 1.0)
1726+ factor = rounding(factor, bom.product_rounding)
1727+ if factor<bom.product_rounding:
1728+ factor = bom.product_rounding
1729+ result = []
1730+ result2 = []
1731+ phantom=False
1732+ if "bom_tree" not in context:
1733+ context["bom_tree"] = []
1734+ proc_obj = self.pool.get('procurement.order')
1735+ bom_obj = self.pool.get('mrp.bom')
1736+ proc_ptr = False
1737+ if procurement_id:
1738+ proc_ptr = proc_obj.browse(cr,uid,procurement_id)
1739+ #=======================================================================
1740+ # Filtres
1741+ #=======================================================================
1742+ filter = []
1743+ no_filter = []
1744+ property_group = []
1745+ for i in bom.type_group_ids :
1746+ if i.execution_filter :
1747+ filter.append(i.id)
1748+ else:
1749+ no_filter.append(i.id)
1750+
1751+ #=======================================================================
1752+ # Phantom
1753+ #=======================================================================
1754+ if bom.type=='phantom' :#and not bom.bom_lines and not bom.bom_components:
1755+# print_tab(level,"phantom : product search :",bom.product_id.default_code,bom.product_id.name)
1756+# newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
1757+# print_tab(level,"phantom : product ok:",self.browse(cr, uid, [newbom])[0].product_id.default_code,self.browse(cr, uid, [newbom])[0].product_id.name)
1758+# if newbom:
1759+# if bom.id not in context["bom_tree"]:
1760+# context["bom_tree"].append(bom.id)
1761+#
1762+# res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id, context=context)
1763+# result = result + res[0]
1764+# result2 = result2 + res[1]
1765+# phantom=True
1766+# else:
1767+ phantom=False
1768+ #=======================================================================
1769+ # Not phantom
1770+ #=======================================================================
1771+ if not phantom:
1772+ print_tab(level,"not phantom : product :",bom.product_id.name)
1773+ #===================================================================
1774+ # Bom without filter
1775+ #===================================================================
1776+ if not filter :
1777+ print_tab(level,"nomenclature sans filtre",context)
1778+ print_tab(level,"addthis and ((not bom.bom_lines and not bom.bom_components) or bom.bom_type in ('cutinput'))", addthis,not bom.bom_lines,not bom.bom_components,bom.bom_type)
1779+ print addthis,bom.bom_lines,bom.bom_components,bom.bom_type
1780+ if addthis and ((not bom.bom_lines and not bom.bom_components) or bom.bom_type in ('cutinput')):
1781+ print_tab(level,"*****ajout",bom.product_id.name)
1782+ proc_property_group = proc_ptr and [i.type_group_id.id for i in proc_ptr.group_property_ids] or []
1783+ property_group = list(set(proc_property_group) & set(no_filter))
1784+ bom_property_ids = []
1785+ for bom_ptr in bom_obj.browse(cr,uid,context["bom_tree"]+[bom.id]):
1786+ bom_property_ids.extend([i.id for i in bom_ptr.property_ids])
1787+ proc_property_ids = proc_ptr and [i.property_id.id for i in proc_ptr.group_property_ids if i.type_group_id.id in property_group] or []
1788+ property_ids = proc_ptr and [i.id for i in proc_ptr.property_ids] or []
1789+ property_ids = list(set(proc_property_ids) & set(property_ids))
1790+ property_ids += bom_property_ids
1791+ property_ids = list(set(property_ids))
1792+ group_property_ids = proc_ptr and [i.id for i in proc_ptr.group_property_ids if i.type_group_id.id in property_group ] or []
1793+ vals = {
1794+ 'name': bom.product_id.name,
1795+ 'product_id': bom.product_id.id,
1796+ 'product_qty': bom.product_qty * factor,
1797+ 'product_uom': bom.product_uom.id,
1798+ 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
1799+ 'product_uos': bom.product_uos and bom.product_uos.id or False,
1800+ 'property_ids': [(6,0,property_ids)],
1801+ 'group_property_ids': [(6,0,group_property_ids)],
1802+ 'density':bom.density,
1803+ 'diameter':bom.diameter,
1804+ 'shape':bom.shape,
1805+ 'size_x':bom.size_x,
1806+ 'size_y':bom.size_y,
1807+ 'size_z':bom.size_z,
1808+ 'diameter':bom.diameter,
1809+ 'weight':bom.weight,
1810+ 'bom_id':bom.id,
1811+ }
1812+
1813+ print_tab(level,"++++++++++++++++++++++",)
1814+ if "bom_line" in context :
1815+ print_tab(level,"bom_line",context["bom_line"].bom_id.bom_type,context["bom_line"].bom_id.name)
1816+ if context["bom_line"].bom_id.bom_type not in ('cutinput') :
1817+ value_size = {
1818+ 'size_x':bom.size_x,
1819+ 'size_y':bom.size_y,
1820+ 'size_z':bom.size_z,
1821+ 'diameter':bom.diameter,
1822+ 'specific_production': proc_ptr and proc_ptr.specific_production,
1823+ 'note_production': proc_ptr and proc_ptr.note_production,
1824+ 'size_x_specific': proc_ptr and proc_ptr.size_x_specific,
1825+ 'size_y_specific': proc_ptr and proc_ptr.size_y_specific,
1826+ 'size_z_specific': proc_ptr and proc_ptr.size_z_specific,
1827+ 'diameter_specific': proc_ptr and proc_ptr.diameter_specific,
1828+ 'size_x_specific_delta': proc_ptr and proc_ptr.size_x_specific_delta,
1829+ 'size_y_specific_delta': proc_ptr and proc_ptr.size_y_specific_delta,
1830+ 'size_z_specific_delta': proc_ptr and proc_ptr.size_z_specific_delta,
1831+ 'diameter_specific_delta': proc_ptr and proc_ptr.diameter_specific_delta,
1832+ }
1833+ vals.update(context["bom_line"].compute_size(value_size)[context["bom_line"].id])
1834+ vals.update({
1835+ 'shape':bom.shape,
1836+ 'specific_production': proc_ptr and proc_ptr.specific_production,
1837+ 'note_production': proc_ptr and proc_ptr.note_production,
1838+ })
1839+ else:
1840+ if proc_ptr:
1841+ value_size = {
1842+ 'size_x':proc_ptr.size_x,
1843+ 'size_y':proc_ptr.size_y,
1844+ 'size_z':proc_ptr.size_z,
1845+ 'diameter':proc_ptr.diameter,
1846+ 'specific_production': proc_ptr.specific_production,
1847+ 'note_production': proc_ptr.note_production,
1848+ 'size_x_specific': proc_ptr.size_x_specific,
1849+ 'size_y_specific': proc_ptr.size_y_specific,
1850+ 'size_z_specific': proc_ptr.size_z_specific,
1851+ 'diameter_specific': proc_ptr.diameter_specific,
1852+ 'size_x_specific_delta': proc_ptr.size_x_specific_delta,
1853+ 'size_y_specific_delta': proc_ptr.size_y_specific_delta,
1854+ 'size_z_specific_delta': proc_ptr.size_z_specific_delta,
1855+ 'diameter_specific_delta': proc_ptr.diameter_specific_delta,
1856+ }
1857+ vals.update(value_size)
1858+
1859+ result.append(vals)
1860+ else:
1861+ print_tab(level,"*****rec")
1862+ if bom.id not in context["bom_tree"]:
1863+ context["bom_tree"].append(bom.id)
1864+ for bom2 in bom.bom_lines:
1865+ print_tab(level,"\\"*50)
1866+ res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id, context=context)
1867+ print_tab(level,"/"*50)
1868+ result = result + res[0]
1869+ result2 = result2 + res[1]
1870+ for bom2 in bom.bom_components:
1871+ print_tab(level,"\\"*50)
1872+ context_child = context.copy()
1873+ context_child.update({'bom_line':bom2})
1874+ if bom2.component_id.id not in context["bom_tree"]:
1875+ print_tab(level,"explode")
1876+ res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id, context=context_child)
1877+ result = result + res[0]
1878+ result2 = result2 + res[1]
1879+ print_tab(level,"/"*50)
1880+ #===================================================================
1881+ # Bom with filter
1882+ #===================================================================
1883+ if filter :
1884+ print_tab(level,"nomenclature avec filtre")
1885+ match = False
1886+ table_match = {}
1887+ for child in proc_ptr.procurement_line:
1888+ print_tab(level,"check procuremnt")
1889+ print_tab(level,"filter",filter)
1890+ print_tab(level,"child.parent_option_id.type_group.id",child.parent_option_id.type_group.id)
1891+ print_tab(level,"child.parent_option_id.product_id",child.parent_option_id.product_id.id,child.parent_option_id.product_id.name)
1892+ print_tab(level,"bom.product_id",bom.product_id.id,bom.product_id.name)
1893+
1894+
1895+ if child.parent_option_id.type_group.id in filter and child.parent_option_id.product_id == bom.product_id:
1896+ print_tab(level,"ok")
1897+ if addthis or(not bom.bom_lines and not bom.bom_components):
1898+ print_tab(level,"*****ajout avec proc",bom.product_id.name)
1899+ bom_property_ids = []
1900+ for bom_ptr in bom_obj.browse(cr,uid,context["bom_tree"]+[bom.id]):
1901+ bom_property_ids.extend([i.id for i in bom_ptr.property_ids])
1902+ proc_property_ids = child and [i.property_id.id for i in child.group_property_ids if i.type_group_id.id in property_group] or []
1903+ property_ids = child and [i.id for i in child.property_ids] or []
1904+ property_ids = list(set(proc_property_ids) & set(property_ids))
1905+ property_ids += bom_property_ids
1906+ property_ids = list(set(property_ids))
1907+ result.append(
1908+ {
1909+ 'name': bom.product_id.name,
1910+ 'product_id': bom.product_id.id,
1911+ 'product_qty': bom.product_qty * factor,
1912+ 'product_uom': bom.product_uom.id,
1913+ 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
1914+ 'product_uos': bom.product_uos and bom.product_uos.id or False,
1915+ 'property_ids': property_ids,
1916+ 'group_property_ids': proc_property_ids,
1917+ 'option_ids': [(6,0,[child.parent_option_id.id])],
1918+ 'procurement_id': child.id,
1919+ 'density':bom.density,
1920+ 'shape':bom.shape,
1921+ 'size_x':child.size_x_specific or bom.size_x,
1922+ 'size_y':child.size_y_specific or bom.size_y,
1923+ 'size_z':child.size_z_specific or bom.size_z,
1924+ 'diameter':child.diameter_specific or bom.diameter,
1925+ 'weight':bom.weight,
1926+ })
1927+ else:
1928+ print_tab(level,"*****rec", "addthis or(not bom.bom_lines and not bom.bom_components)",addthis,not bom.bom_lines,not bom.bom_components)
1929+ for bom2 in bom.bom_lines:
1930+ res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=child.id, context=context)
1931+ result = result + res[0]
1932+ result2 = result2 + res[1]
1933+ for bom2 in bom.bom_components:
1934+ context_child = context.copy()
1935+ context_child.update({'bom_line':bom2})
1936+ res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=child.id, context=context_child)
1937+ result = result + res[0]
1938+ result2 = result2 + res[1]
1939+ else:
1940+ print_tab(level,"!ok",child.parent_option_id.type_group.id , filter,child.parent_option_id.product_id,bom.product_id)
1941+ else:
1942+ #===================================================================
1943+ # Add routing of bom phantom
1944+ #===================================================================
1945+ if bom.routing_id:
1946+ for wc_use in bom.routing_id.workcenter_lines:
1947+ wc = wc_use.workcenter_id
1948+ d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
1949+ mult = (d + (m and 1.0 or 0.0))
1950+ cycle = mult * wc_use.cycle_nbr
1951+ result2.append({
1952+ 'name': bom.routing_id.name,
1953+ 'workcenter_id': wc.id,
1954+ 'sequence': level+(wc_use.sequence or 0),
1955+ 'cycle': cycle,
1956+ 'hour': float(wc_use.hour_nbr*mult + (wc.time_start+wc.time_stop+cycle*wc.time_cycle) * (wc.time_efficiency or 1.0)),
1957+ })
1958+ return result, result2
1959+
1960+# level_ = "-----------"+("-"*level)
1961+# if level == 50 : raise
1962+# print "*"*50
1963+# print level_+"***_bom_explode",level,bom.name,[ i.id for i in bom.bom_lines],[ i.component_id.id for i in bom.bom_components],addthis
1964+# production_obj = self.pool.get('mrp.production')
1965+# procurement_obj = self.pool.get('procurement.order')
1966+#
1967+# procurement = False
1968+# production = False
1969+# if procurement_id:
1970+# procurement = procurement_obj.browse(cr,uid,procurement_id)
1971+# if procurement.production_id:
1972+# production = procurement.production_id
1973+#
1974+# factor = factor / (bom.product_efficiency or 1.0)
1975+# factor = rounding(factor, bom.product_rounding)
1976+# if factor<bom.product_rounding:
1977+# factor = bom.product_rounding
1978+# result = []
1979+# result2 = []
1980+# result3 = []
1981+# phantom=False
1982+# match = False
1983+# no_rec = False
1984+# if bom.type=='phantom':
1985+# print level_+"phantom"
1986+# for bom2 in bom.bom_lines:
1987+# res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
1988+# result = result + res[0]
1989+# result2 = result2 + res[1]
1990+# for bom2 in bom.bom_components:
1991+# res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
1992+# result = result + res[0]
1993+# result2 = result2 + res[1]
1994+# else:
1995+# print level_+"not phantom",procurement,bom,bom.type_group_ids
1996+# filter = []
1997+# for i in bom.type_group_ids :
1998+# print i,i.name,i.execution_filter
1999+# if i.execution_filter :
2000+# filter.append(i.id)
2001+# if filter :
2002+# if procurement and procurement.parent_option_id and procurement.parent_option_id.type_group :
2003+# print level_+"proc group ",procurement.parent_option_id.type_group.id
2004+# print level_+"filter ",filter
2005+# if procurement and procurement.parent_option_id and procurement.parent_option_id.type_group and procurement.parent_option_id.type_group.id in filter:
2006+# result.append(
2007+# {
2008+# 'name': bom.product_id.name,
2009+# 'product_id': bom.product_id.id,
2010+# 'product_qty': bom.product_qty * factor,
2011+# 'product_uom': bom.product_uom.id,
2012+# 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
2013+# 'product_uos': bom.product_uos and bom.product_uos.id or False,
2014+# 'property_ids': [(6,0,[i.id for i in procurement.property_ids])],
2015+# 'group_property_ids': [(6,0,[i.id for i in procurement.group_property_ids])],
2016+# 'procurement_ids': [(4,procurement_id)],
2017+# })
2018+# no_rec = True
2019+# else:
2020+# if procurement :
2021+# result.append(
2022+# {
2023+# 'name': bom.product_id.name,
2024+# 'product_id': bom.product_id.id,
2025+# 'product_qty': bom.product_qty * factor,
2026+# 'product_uom': bom.product_uom.id,
2027+# 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
2028+# 'product_uos': bom.product_uos and bom.product_uos.id or False,
2029+# 'property_ids': [(6,0,[i.id for i in procurement.property_ids])],
2030+# 'group_property_ids': [(6,0,[i.id for i in procurement.group_property_ids])],
2031+# 'procurement_ids': [(4,procurement_id)],
2032+# })
2033+# no_rec = True
2034+## for bom2 in bom.bom_lines:
2035+## if bom2.product_id.supply_method in ('produce'):
2036+## if production:
2037+## vals = {
2038+## 'name':'PROD2:'+production.name,
2039+## 'date_planned': production.date_planned,
2040+## 'product_id': bom2.product_id.id,
2041+## 'product_qty': bom2.product_qty,
2042+## 'product_uom': bom2.product_uom.id,
2043+## 'product_uos_qty': bom2.product_uos and line.product_uos_qty or False,
2044+## 'product_uos': bom2.product_uos and line.product_uos.id or False,
2045+## 'location_id': production.location_src_id.id,
2046+## 'location_dest_id': bom2.product_id.product_tmpl_id.property_stock_production.id,
2047+### 'move_dest_id': res_final_id,
2048+## 'state': 'waiting',
2049+### 'prodlot_id': line_prodlot_id,
2050+## }
2051+## result3.append(vals)
2052+## for bom2 in bom.bom_components:
2053+## bom2=bom2.component_id
2054+## if bom2.product_id.supply_method in ('produce'):
2055+## if production:
2056+## vals = {
2057+## 'name':'PROD2:'+production.name,
2058+## 'date_planned': production.date_planned,
2059+## 'product_id': bom2.product_id.id,
2060+## 'product_qty': bom2.product_qty,
2061+## 'product_uom': bom2.product_uom.id,
2062+## 'product_uos_qty': bom2.product_uos and line.product_uos_qty or False,
2063+## 'product_uos': bom2.product_uos and line.product_uos.id or False,
2064+## 'location_id': production.location_src_id.id,
2065+## 'location_dest_id': bom2.product_id.product_tmpl_id.property_stock_production.id,
2066+### 'move_dest_id': res_final_id,
2067+## 'state': 'waiting',
2068+### 'prodlot_id': line_prodlot_id,
2069+## }
2070+## result3.append(vals)
2071+# if not no_rec:
2072+# for bom2 in bom.bom_lines:
2073+# res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10)
2074+# result = result + res[0]
2075+# result2 = result2 + res[1]
2076+# for bom2 in bom.bom_components:
2077+# res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
2078+# result = result + res[0]
2079+# result2 = result2 + res[1]
2080+# print level_+"result ---------> ",result
2081+#
2082+# return result, result2, []
2083+
2084+ def gen_graph(self,cr,uid,ids,context):
2085+ bom_node = []
2086+ bom_link = []
2087+ gen_graph_tab = []
2088+ gen_graph_desc_tab = []
2089+ gen_graph_asc_tab = []
2090+ def gen_graph(bom):
2091+# print "gen_graph"
2092+ result = ""
2093+ if bom.id not in gen_graph_tab:
2094+ gen_graph_tab.append(bom.id)
2095+ result+=rec_gen_graph_desc(bom)
2096+ result+=rec_gen_graph_asc(bom)
2097+ return result
2098+
2099+ def rec_gen_graph_desc(bom):
2100+# print "rec_gen_graph_desc"
2101+ result = ""
2102+ if bom.id not in bom_node:
2103+ bom_node.append(bom.id)
2104+ result += str(bom.id)+" [label=\""+bom.name+"\"] "+";\n"
2105+ for line in bom.bom_components:
2106+ if str(bom.id)+"_"+str(line.component_id.id) not in bom_link:
2107+ bom_link.append(str(bom.id)+"_"+str(line.component_id.id))
2108+ result += str(bom.id)+" -> "+str(line.component_id.id)+";\n"
2109+ result += rec_gen_graph_desc(line.component_id)
2110+ result += gen_graph(line.component_id)
2111+ return result
2112+
2113+ def rec_gen_graph_asc(bom):
2114+# print "rec_gen_graph_asc"
2115+ result = ""
2116+ if bom.id not in bom_node:
2117+ bom_node.append(bom.id)
2118+ result += str(bom.id)+" [label=\""+bom.name+"\"] "+";\n"
2119+ for line in bom.bom_components_parent:
2120+ if str(line.bom_id.id)+"_"+str(bom.id) not in bom_link:
2121+ bom_link.append(str(line.id)+"_"+str(bom.id))
2122+ result += str(line.bom_id.id)+" -> "+str(bom.id)+";\n"
2123+ result += rec_gen_graph_asc(line.bom_id)
2124+ result += gen_graph(line.bom_id)
2125+ return result
2126+
2127+ #print "digraph G {"
2128+ #for bom in self.browse(cr,uid,ids,context):
2129+ # print gen_graph(bom)
2130+ #print "}"
2131+ return True
2132+
2133+ def gen_graph_dot(self,cr,uid,ids,context={}):
2134+
2135+ try:
2136+ import pydot
2137+ except Exception,e:
2138+ _logger.notifyChannel('workflow', netsvc.LOG_WARNING,
2139+ 'Import Error for pydot, you will not be able to render workflows\n'
2140+ 'Consider Installing PyDot or dependencies: http://dkbza.org/pydot.html')
2141+ raise e
2142+
2143+ self.done = False
2144+
2145+ graph = pydot.Dot(fontsize='16', label="""\\\n\\nBOM: """,
2146+ size='10.7, 7.3', center='1', ratio='auto', rotate='90', rankdir='LR'
2147+ )
2148+
2149+ bom_node = []
2150+ bom_link = []
2151+ gen_graph_tab = []
2152+ gen_graph_desc_tab = []
2153+ gen_graph_asc_tab = []
2154+ def gen_graph(bom):
2155+ result = ""
2156+ if bom.id not in gen_graph_tab:
2157+ gen_graph_tab.append(bom.id)
2158+ result+=rec_gen_graph_desc(bom)
2159+# result+=rec_gen_graph_asc(bom)
2160+ return result
2161+
2162+ def rec_gen_graph_desc(bom):
2163+ result = ""
2164+ if bom.id not in bom_node:
2165+ bom_node.append(bom.id)
2166+ args = {'label':bom.product_id and bom.product_id.default_code or "E"}
2167+ graph.add_node(pydot.Node(str(bom.id), **args))
2168+ for line in bom.bom_components:
2169+ if str(bom.id)+"_"+str(line.component_id.id) not in bom_link:
2170+ bom_link.append(str(bom.id)+"_"+str(line.component_id.id))
2171+ label = "|"
2172+ for i in bom.type_group_ids :
2173+ if i.execution_filter:
2174+ if label :
2175+ label+= "|"
2176+ label+= i.name
2177+ args = {'label':label}
2178+ graph.add_edge(pydot.Edge( str(bom.id) ,str(line.component_id.id), fontsize='10', **args))
2179+ result += rec_gen_graph_desc(line.component_id)
2180+# result += gen_graph(line)
2181+ return result
2182+
2183+ def rec_gen_graph_asc(bom):
2184+ result = ""
2185+ if bom.id not in bom_node:
2186+ bom_node.append(bom.id)
2187+ args = {'label':bom.product_id and bom.product_id.default_code or "E"}
2188+ graph.add_node(pydot.Node(str(bom.id), **args))
2189+ for line in bom.bom_components_parent:
2190+ if str(line.bom_id.id)+"_"+str(bom.id) not in bom_link:
2191+ bom_link.append(str(line.bom_id.id)+"_"+str(bom.id))
2192+ args = {'label':''}
2193+ graph.add_edge(pydot.Edge( str(line.bom_id.id) ,str(bom.id), fontsize='10', **args))
2194+ result += rec_gen_graph_asc(line.bom_id)
2195+# result += gen_graph(line)
2196+ return result
2197+
2198+
2199+ for bom in self.browse(cr,uid,ids,context):
2200+ gen_graph(bom)
2201+
2202+ return graph
2203+
2204+
2205+
2206+mrp_bom()
2207+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2208\ No newline at end of file
2209
2210=== added file 'asperience_configurator_mrp/mrp_data.xml'
2211--- asperience_configurator_mrp/mrp_data.xml 1970-01-01 00:00:00 +0000
2212+++ asperience_configurator_mrp/mrp_data.xml 2017-12-01 14:57:12 +0000
2213@@ -0,0 +1,85 @@
2214+<?xml version="1.0" encoding="utf-8"?>
2215+<openerp>
2216+ <data noupdate="0">
2217+
2218+ <!--
2219+ Description Dx Dy Dz Dd
2220+ [Modifier] side Dz Dx [Supprimer]
2221+ [Modifier] top Dy Dx [Supprimer]
2222+ [Modifier] bottom Dy Dx [Supprimer]
2223+ [Modifier] back Dy Dz [Supprimer]
2224+ [Modifier] front Dy Dz-->
2225+ <record id="mode_side" model="mrp.bom.component.mode">
2226+ <field name="name" >side</field>
2227+ <field name="dx" eval="'Dy'" />
2228+ <field name="dy" eval="'Dz'" />
2229+ <field name="dz" eval="''" />
2230+ <field name="dd" eval="''" />
2231+ </record>
2232+ <record id="mode_top" model="mrp.bom.component.mode">
2233+ <field name="name">top</field>
2234+ <field name="dx" eval="'Dx'" />
2235+ <field name="dy" eval="'Dy'" />
2236+ <field name="dz" eval="''" />
2237+ <field name="dd" eval="''" />
2238+ </record>
2239+ <record id="mode_bottom" model="mrp.bom.component.mode">
2240+ <field name="name" >bottom</field>
2241+ <field name="dx" eval="'Dx'" />
2242+ <field name="dy" eval="'Dy'" />
2243+ <field name="dz" eval="''" />
2244+ <field name="dd" eval="''" />
2245+ </record>
2246+ <record id="mode_back" model="mrp.bom.component.mode">
2247+ <field name="name" >back</field>
2248+ <field name="dx" eval="'Dx'" />
2249+ <field name="dy" eval="'Dz'" />
2250+ <field name="dz" eval="''" />
2251+ <field name="dd" eval="''" />
2252+ </record>
2253+ <record id="mode_front" model="mrp.bom.component.mode">
2254+ <field name="name" >front</field>
2255+ <field name="dx" eval="'Dx'" />
2256+ <field name="dy" eval="'Dz'" />
2257+ <field name="dz" eval="''" />
2258+ <field name="dd" eval="''" />
2259+ </record>
2260+ <!--
2261+ <record id="mode_side" model="mrp.bom.component.mode">
2262+ <field name="name" >side</field>
2263+ <field name="dx" eval="'Dy'" />
2264+ <field name="dy" eval="''" />
2265+ <field name="dz" eval="''" />
2266+ <field name="dd" eval="''" />
2267+ </record>
2268+ <record id="mode_top" model="mrp.bom.component.mode">
2269+ <field name="name">top</field>
2270+ <field name="dx" eval="'Dx'" />
2271+ <field name="dy" eval="'Dy'" />
2272+ <field name="dz" eval="'Dz'" />
2273+ <field name="dd" eval="''" />
2274+ </record>
2275+ <record id="mode_bottom" model="mrp.bom.component.mode">
2276+ <field name="name" >bottom</field>
2277+ <field name="dx" eval="'Dx'" />
2278+ <field name="dy" eval="'Dy'" />
2279+ <field name="dz" eval="'Dz'" />
2280+ <field name="dd" eval="''" />
2281+ </record>
2282+ <record id="mode_back" model="mrp.bom.component.mode">
2283+ <field name="name" >back</field>
2284+ <field name="dx" eval="''" />
2285+ <field name="dy" eval="'Dx'" />
2286+ <field name="dz" eval="''" />
2287+ <field name="dd" eval="''" />
2288+ </record>
2289+ <record id="mode_front" model="mrp.bom.component.mode">
2290+ <field name="name" >front</field>
2291+ <field name="dx" eval="''" />
2292+ <field name="dy" eval="'Dx'" />
2293+ <field name="dz" eval="''" />
2294+ <field name="dd" eval="''" />
2295+ </record>
2296+ -->
2297+ </data>
2298+</openerp>
2299
2300=== added file 'asperience_configurator_mrp/mrp_procurement.pyc'
2301Binary files asperience_configurator_mrp/mrp_procurement.pyc 1970-01-01 00:00:00 +0000 and asperience_configurator_mrp/mrp_procurement.pyc 2017-12-01 14:57:12 +0000 differ
2302=== added file 'asperience_configurator_mrp/mrp_production.py'
2303--- asperience_configurator_mrp/mrp_production.py 1970-01-01 00:00:00 +0000
2304+++ asperience_configurator_mrp/mrp_production.py 2017-12-01 14:57:12 +0000
2305@@ -0,0 +1,593 @@
2306+# -*- encoding: utf-8 -*-
2307+##############################################################################
2308+#
2309+# OpenERP, Open Source Management Solution
2310+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
2311+# All Rights Reserved
2312+#
2313+# This program is free software: you can redistribute it and/or modify
2314+# it under the terms of the GNU General Public License as published by
2315+# the Free Software Foundation, either version 3 of the License, or
2316+# (at your option) any later version.
2317+#
2318+# This program is distributed in the hope that it will be useful,
2319+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2320+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2321+# GNU General Public License for more details.
2322+#
2323+# You should have received a copy of the GNU General Public License
2324+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2325+#
2326+##############################################################################
2327+from openerp.osv import fields,osv
2328+import inspect
2329+
2330+class mrp_production(osv.osv):
2331+ _inherit = 'mrp.production'
2332+
2333+ def _size(self, cr, uid, ids, field_name, arg, context):
2334+ res = {}
2335+ for proc in self.browse(cr, uid, ids):
2336+ res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 , 'diameter': 0.0}
2337+ if proc.product_id:
2338+ res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
2339+ res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
2340+ res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
2341+ res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
2342+ return res
2343+
2344+ def action_compute(self, cr, uid, ids, context={}):
2345+ print "action_compute",ids,context
2346+ results = []
2347+ for production in self.browse(cr, uid, ids):
2348+ cr.execute('delete from mrp_production_product_line where production_id=%s', (production.id,))
2349+ cr.execute('delete from mrp_production_workcenter_line where production_id=%s', (production.id,))
2350+ bom_point = production.bom_id
2351+ bom_id = production.bom_id.id
2352+ filter = []
2353+ properties = []
2354+ group_properties = []
2355+
2356+ #Lors de la crƩation du mrp.production, il faut s'assurer que tous les procurements sommƩs sur la production
2357+ #ont les mĆŖmes propriĆ©tĆ©s et les mĆŖmes groupes de propriĆ©tĆ©s
2358+ if production and production.procurement_ids and production.procurement_ids[0].parent_option_id and production.procurement_ids[0].parent_option_id.type_group :
2359+ filter.append(production.procurement_ids[0].parent_option_id.type_group.id)
2360+ group_properties = [i.id for i in production.procurement_ids[0].group_property_ids]
2361+# #===============================================================
2362+# # CrƩation des lignes de production
2363+# #===============================================================
2364+# for procurement in production.procurement_ids:
2365+# if procurement.bom_id and procurement.bom_id.bom_type in ('cut'):
2366+# vals = {
2367+# 'production_id': production.id,
2368+# 'procurement_id': procurement.id,
2369+# 'bom_id':procurement.move_id.prodlot_id.mrp_production_id.bom_id.id,
2370+#
2371+# 'name': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_id.name,
2372+# 'product_id': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_id.id,
2373+# 'product_qty': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_qty,
2374+# 'product_uom': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uom.id,
2375+# 'product_uos_qty': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uos and bom.product_uos_qty * factor or False,
2376+# 'product_uos': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uos and bom.product_uos.id or False,
2377+# 'property_ids': [i.id for i in procurement.property_ids],
2378+# 'group_property_ids': [i.id for i in procurement.group_property_ids],
2379+# 'density':procurement.move_id.prodlot_id.mrp_production_id.bom_id.density,
2380+# 'diameter':procurement.move_id.prodlot_id.mrp_production_id.bom_id.diameter,
2381+# 'shape':procurement.move_id.prodlot_id.mrp_production_id.bom_id.shape,
2382+# 'weight':procurement.move_id.prodlot_id.mrp_production_id.bom_id.weight,
2383+# 'size_x':procurement.size_x,
2384+# 'size_y':procurement.size_y,
2385+# 'size_z':procurement.size_z,
2386+# 'diameter':procurement.diameter,
2387+# 'specific_production': procurement.specific_production,
2388+# 'note_production': procurement.note_production,
2389+# 'size_x_specific': procurement.size_x_specific,
2390+# 'size_y_specific': procurement.size_y_specific,
2391+# 'size_z_specific': procurement.size_z_specific,
2392+# 'diameter_specific': procurement.diameter_specific,
2393+# 'size_x_specific_delta': procurement.size_x_specific_delta,
2394+# 'size_y_specific_delta': procurement.size_y_specific_delta,
2395+# 'size_z_specific_delta': procurement.size_z_specific_delta,
2396+# 'diameter_specific_delta': procurement.diameter_specific_delta,
2397+# }
2398+# self.pool.get('mrp.production.product.line').create(cr,uid,vals)
2399+# procurement.move_id.write({'production_id':production.id})
2400+
2401+ if not bom_point:
2402+ bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, production.product_id.id, production.product_uom.id, properties, filter)
2403+ if bom_id:
2404+ bom_point = self.pool.get('mrp.bom').browse(cr, uid, bom_id)
2405+ routing_id = bom_point.routing_id.id or False
2406+ self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})
2407+
2408+ if not bom_id:
2409+ raise osv.except_osv(_('Error'), _("Couldn't find bill of material for product %s,%s: production %s,%s" % (production.product_id.name,str(production.product_id.id),production.name,str(production.id)) ) )
2410+
2411+ #if bom_point.routing_id and bom_point.routing_id.location_id:
2412+ # self.write(cr, uid, [production.id], {'location_src_id': bom_point.routing_id.location_id.id})
2413+
2414+ factor = production.product_qty * production.product_uom.factor / bom_point.product_uom.factor
2415+ print "production.procurement_ids[0]",production.procurement_ids[0]
2416+ res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, group_properties=group_properties, procurement_id=production.procurement_ids[0].id or False)
2417+ results = res[0]
2418+ results2 = res[1]
2419+ print "1111111111"
2420+ for line in results:
2421+ print line
2422+ line['production_id'] = production.id
2423+ self.pool.get('mrp.production.product.line').create(cr, uid, line)
2424+ print "2222222222"
2425+ for line in results2:
2426+ print line
2427+ line['production_id'] = production.id
2428+ self.pool.get('mrp.production.workcenter.line').create(cr, uid, line)
2429+ return len(results)
2430+
2431+ def action_confirm(self, cr, uid, ids):
2432+# print "action_confirm stock.production"
2433+ lot_obj = self.pool.get('stock.production.lot')
2434+ picking_obj = self.pool.get('stock.picking')
2435+ move_obj = self.pool.get('stock.move')
2436+
2437+ picking_id=False
2438+ proc_ids = []
2439+ for production in self.browse(cr, uid, ids):
2440+ #===================================================================
2441+ # Test production dƩjƠ confirmƩ
2442+ #===================================================================
2443+ if production.state in ('confirmed'):
2444+ picking_id = production.picking_id.id
2445+ continue
2446+ #===================================================================
2447+ # Compute si pas dƩjƠ fait
2448+ #===================================================================
2449+ if not production.product_lines:
2450+ self.action_compute(cr, uid, [production.id])
2451+ production = self.browse(cr, uid, [production.id])[0]
2452+ #===================================================================
2453+ # Init des variables
2454+ #===================================================================
2455+ moves = []
2456+ routing_loc = None
2457+ pick_type = 'internal'
2458+ address_id = False
2459+ company = self.pool.get('res.users').browse(cr, uid, uid).company_id
2460+ source = production.product_id.product_tmpl_id.property_stock_production.id
2461+ if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
2462+ routing_loc = production.bom_id.routing_id.location_id
2463+ if routing_loc.usage<>'internal':
2464+ pick_type = 'out'
2465+ address_id = routing_loc.address_id and routing_loc.address_id.id or False
2466+ routing_loc = routing_loc.id
2467+
2468+ #===================================================================
2469+ # Creation du picking de sortie
2470+ #===================================================================
2471+ vals = {
2472+ 'origin': (production.origin or '').split(':')[0] +':'+production.name,
2473+ 'type': pick_type,
2474+ 'move_type': 'one',
2475+ 'state': 'auto',
2476+ 'address_id': address_id,
2477+ 'partner_shipping_id':address_id,
2478+ 'auto_picking': self._get_auto_picking(cr, uid, production),
2479+ }
2480+ picking_id = picking_obj.create(cr, uid, vals)
2481+ print_tab("*"*50)
2482+ print_tab("Creation du picking de sortie")
2483+ print_tab(vals)
2484+ #===================================================================
2485+ # Rehcherche du lot + Creation du lot s'il n'Ć©xiste pas
2486+ #===================================================================
2487+ vals = {
2488+ 'product_id': production.product_id.id,
2489+ 'date': datetime.datetime.now(),
2490+ 'mrp_production_id': production.id,
2491+ 'property_ids': production.procurement_ids and [(6,0,[i.id for i in production.procurement_ids[0].property_ids])] or [(6,0,[])],
2492+ 'group_property_ids': production.procurement_ids and [(6,0,[i.id for i in production.procurement_ids[0].group_property_ids])] or [(6,0,[])],
2493+ 'option_ids': production.procurement_ids and production.procurement_ids[0].parent_option_id and [(6,0,[ production.procurement_ids[0].parent_option_id.id ])] or [(6,0,[])],
2494+ 'density': production.bom_id.density,
2495+ 'diameter': production.bom_id.diameter,
2496+ 'shape': production.bom_id.shape,
2497+ 'size_x': production.procurement_ids[0].size_x_specific or production.bom_id.size_x,
2498+ 'size_y': production.procurement_ids[0].size_y_specific or production.bom_id.size_y,
2499+ 'size_z': production.procurement_ids[0].size_z_specific or production.bom_id.size_z,
2500+ 'weight': production.bom_id.weight,
2501+ }
2502+ prodlot_id = lot_obj.search_specific(cr,uid,vals,company.tracking_production_delay)
2503+ if not prodlot_id:
2504+ vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.lot.serial')
2505+ prodlot_id = lot_obj.create(cr, uid, vals)
2506+ revision_id = self.pool.get('stock.production.lot.revision').create(cr, uid, {
2507+ 'name': (production.origin or '').split(':')[0] +':'+production.name,
2508+ 'description': (production.origin or '').split(':')[0] +':'+production.name,
2509+ 'date': datetime.datetime.now(),
2510+ 'author_id': uid,
2511+ 'lot_id': prodlot_id,
2512+ })
2513+ #===================================================================
2514+ # Update des moves
2515+ #===================================================================
2516+ self.pool.get('stock.move').write(cr, uid, [i.move_id.id for i in production.procurement_ids if not i.move_id.prodlot_id], {
2517+ 'prodlot_id': prodlot_id,
2518+ })
2519+
2520+
2521+ print_tab("*"*50)
2522+ print_tab("production",production)
2523+ print_tab("production",production.procurement_ids)
2524+ print_tab("*"*50)
2525+# raise
2526+
2527+ #===================================================================
2528+ # Creation des lignes de workcenter
2529+ #===================================================================
2530+ if production.bom_id and production.bom_id.routing_id:
2531+ print production.bom_id
2532+ for wc_use in production.bom_id.routing_id.workcenter_lines:
2533+ wc = wc_use.workcenter_id
2534+ factor = production.product_qty * production.product_uom.factor / production.bom_id.product_uom.factor
2535+ d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
2536+ mult = (d + (m and 1.0 or 0.0))
2537+ cycle = mult * wc_use.cycle_nbr
2538+ move_ids = []
2539+
2540+ self.pool.get('mrp.production.workcenter.line').create(cr,uid,{
2541+ 'production_id': production.id,
2542+ 'name': production.bom_id.routing_id.name,
2543+ 'workcenter_id': wc.id,
2544+ 'sequence': wc_use.sequence or 0,
2545+ 'cycle': cycle,
2546+ 'hour': float(wc_use.hour_nbr*mult + (wc.time_start+wc.time_stop+cycle*wc.time_cycle) * (wc.time_efficiency or 1.0)),
2547+ 'move_ids': [(6,0,move_ids)],
2548+ })
2549+
2550+ #===================================================================
2551+ # Creation du mouvement de sortie
2552+ #===================================================================
2553+ # TODO : voir pourquoi le picking il n'est pas reliƩ au picking de sortie crƩƩ plus haut
2554+
2555+ res_final_id = False
2556+ if production.bom_id.bom_type in ('cut'):
2557+ for proc in production.procurement_ids:
2558+ if proc.move_id.id:
2559+ res_final_id = proc.move_id.id
2560+ vals = {
2561+ 'production_id':production.id,
2562+ }
2563+ move_obj.write(cr, uid, res_final_id, vals)
2564+ else:
2565+ vals = {
2566+ 'name':'PROD1:'+production.name,
2567+ 'date_planned': production.date_planned,
2568+ 'product_id': production.product_id.id,
2569+ 'product_qty': production.product_qty,
2570+ 'product_uom': production.product_uom.id,
2571+ 'product_uos_qty': production.product_uos and production.product_uos_qty or False,
2572+ 'product_uos': production.product_uos and production.product_uos.id or False,
2573+ 'location_id': source,
2574+ 'location_dest_id': production.location_dest_id.id,
2575+ 'move_dest_id': production.move_prod_id.id,
2576+ 'state': 'waiting',
2577+ 'prodlot_id': prodlot_id,
2578+ 'production_id':production.id,
2579+ }
2580+ res_final_id = move_obj.create(cr, uid, vals)
2581+ print_tab("*"*50)
2582+ print_tab("Creation du mouvement de sortie")
2583+ print_tab(vals)
2584+
2585+# self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
2586+
2587+ #===================================================================
2588+ # Parcours des ligne de production
2589+ #===================================================================
2590+ for line in production.product_lines:
2591+ move_id = False
2592+ line_prodlot_id = False
2593+# production_id = False
2594+ #===============================================================
2595+ # Test if bom is assemble or disassemble
2596+ #===============================================================
2597+ print "--------------",line.bom_id.bom_type
2598+ if production.bom_id.bom_type in ('cutinput'):
2599+ product_id = production.product_id.id
2600+ else:
2601+ product_id = line.product_id.id
2602+
2603+ if line.product_id.type in ('product', 'consu'):
2604+ #===========================================================
2605+ # Recherche du lot, crƩation d'il n'Ʃxiste pas
2606+ #===========================================================
2607+ vals = {
2608+ 'product_id': product_id,
2609+ 'date': datetime.datetime.now(),
2610+ 'mrp_production_id': production.id,
2611+ 'property_ids': [(6,0,[i.id for i in line.property_ids])] or [(6,0,[])],
2612+ 'group_property_ids': [(6,0,[i.id for i in line.group_property_ids])] or [(6,0,[])],
2613+ 'option_ids': [(6,0,[i.id for i in line.option_ids])] or [(6,0,[])],
2614+ 'density':line.density,
2615+ 'diameter':line.specific_production and line.diameter_specific or line.diameter,
2616+ 'shape':line.shape,
2617+ 'size_x': line.specific_production and line.size_x_specific or line.size_x,
2618+ 'size_y': line.specific_production and line.size_y_specific or line.size_y,
2619+ 'size_z': line.specific_production and line.size_z_specific or line.size_z,
2620+ 'weight':line.weight,
2621+ }
2622+ if line.procurement_id :
2623+ line_prodlot_id = line.procurement_id.move_id.prodlot_id.id
2624+ if not line_prodlot_id:
2625+ vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.lot.serial')
2626+ line_prodlot_id = lot_obj.search_specific(cr,uid,vals,company.tracking_production_delay)
2627+ if not line_prodlot_id:
2628+ line_prodlot_id = lot_obj.create(cr, uid, vals)
2629+ revision_id = self.pool.get('stock.production.lot.revision').create(cr, uid, {
2630+ 'name': (production.origin or '').split(':')[0] +':'+production.name,
2631+ 'description': (production.origin or '').split(':')[0] +':'+production.name,
2632+ 'date': datetime.datetime.now(),
2633+ 'author_id': uid,
2634+ 'lot_id': line_prodlot_id,
2635+ })
2636+
2637+# #===========================================================
2638+# # Recuperation de la production en cours associƩ au lot
2639+# #===========================================================
2640+# if line_prodlot_id and line.bom_id.bom_type in ('cut'):
2641+# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',line_prodlot_id),('production_id','!=',False),('production_id.state','=','confirmed')])
2642+# if move_ids:
2643+# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
2644+ #===========================================================
2645+ # Recherche ou creation du move de sortie + enregistrement sur la production en entrƩe
2646+ #===========================================================
2647+ if not line.procurement_id :
2648+ vals = {
2649+ 'name':'PROD22:'+production.name,
2650+ 'date_planned': production.date_planned,
2651+ 'product_id': product_id,
2652+ 'product_qty': line.product_qty,
2653+ 'product_uom': line.product_uom.id,
2654+ 'product_uos_qty': line.product_uos and line.product_uos_qty or False,
2655+ 'product_uos': line.product_uos and line.product_uos.id or False,
2656+ 'location_id': routing_loc or production.location_src_id.id,
2657+ 'location_dest_id': source,
2658+ 'move_dest_id': res_final_id,
2659+ 'state': 'waiting',
2660+ 'prodlot_id': line_prodlot_id,
2661+ }
2662+ res_dest_id = self.pool.get('stock.move').create(cr, uid, vals)
2663+ moves.append(res_dest_id)
2664+ print_tab("/"*50)
2665+ print_tab("creation du move de sortie de ligne")
2666+ print_tab(vals)
2667+ else:
2668+ res_dest_id = line.procurement_id.move_id.id
2669+ self.write(cr, uid, [production.id], {'move_lines': [(4,res_dest_id)]})
2670+ #===========================================================
2671+ # CrƩation du move suivant le move de production
2672+ #===========================================================
2673+ vals = {
2674+ 'name':'PROD3:'+production.name,
2675+ 'picking_id':picking_id,
2676+ 'product_id': product_id,
2677+ 'product_qty': line.product_qty,
2678+ 'product_uom': line.product_uom.id,
2679+ 'product_uos_qty': line.product_uos and line.product_uos_qty or False,
2680+ 'product_uos': line.product_uos and line.product_uos.id or False,
2681+ 'date_planned': production.date_planned,
2682+ 'move_dest_id': res_dest_id,
2683+ 'location_id': production.location_src_id.id,
2684+ 'location_dest_id': routing_loc or production.location_src_id.id,
2685+ 'state': 'waiting',
2686+ 'prodlot_id': line_prodlot_id,
2687+# 'production_id': production_id,
2688+ }
2689+ print_tab("CrƩation du move suivant le move de sortie")
2690+ print_tab(vals)
2691+ move_id = self.pool.get('stock.move').create(cr, uid, vals)
2692+ #===============================================================
2693+ # CrƩation du procurement pour la ligne s'il n'Ʃxiste pas + update de la ligne
2694+ #===============================================================
2695+ if not line.procurement_id :
2696+# production_id = False
2697+ vals = {
2698+ 'name': (production.origin or '').split(':')[0] + ':' + production.name,
2699+ 'origin': (production.origin or '').split(':')[0] + ':' + production.name,
2700+ 'date_planned': production.date_planned,
2701+ 'product_id': line.product_id.id,
2702+ 'product_qty': line.product_qty,
2703+ 'product_uom': line.product_uom.id,
2704+ 'product_uos_qty': line.product_uos and line.product_qty or False,
2705+ 'product_uos': line.product_uos and line.product_uos.id or False,
2706+ 'property_ids': [(6,0,[i.id for i in line.property_ids])],
2707+ 'group_property_ids': [(6,0,[i.id for i in line.group_property_ids])],
2708+ 'option_ids': [(6,0,[i.id for i in line.option_ids])],
2709+ 'size_x':line.size_x,
2710+ 'size_y':line.size_y,
2711+ 'size_z':line.size_z,
2712+ 'diameter':line.diameter,
2713+ 'specific_production': line.specific_production,
2714+ 'note_production': line.note_production,
2715+ 'size_x_specific': line.size_x_specific,
2716+ 'size_y_specific': line.size_y_specific,
2717+ 'size_z_specific': line.size_z_specific,
2718+ 'diameter_specific': line.diameter_specific,
2719+ 'size_x_specific_delta': line.size_x_specific_delta,
2720+ 'size_y_specific_delta': line.size_y_specific_delta,
2721+ 'size_z_specific_delta': line.size_z_specific_delta,
2722+ 'diameter_specific_delta': line.diameter_specific_delta,
2723+ 'location_id': production.location_src_id.id,
2724+ 'procure_method': line.product_id.procure_method,
2725+ 'move_id': move_id,
2726+ 'bom_id': line.bom_id and line.bom_id.id or False,
2727+# 'production_id':production_id,
2728+ }
2729+ proc_id = self.pool.get('procurement.order').create(cr, uid, vals)
2730+ print_tab("CrƩation du procurement")
2731+ print_tab(vals)
2732+ self.pool.get('mrp.production.product.line').write(cr, uid, line.id, {'procurement_id':proc_id})
2733+ #===========================================================
2734+ # Validation du procurement
2735+ #===========================================================
2736+ wf_service = netsvc.LocalService("workflow")
2737+ wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
2738+ proc_ids.append(proc_id)
2739+ #===================================================================
2740+ # Validation du picking de sortie
2741+ #===================================================================
2742+ wf_service = netsvc.LocalService("workflow")
2743+ wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
2744+ self.write(cr, uid, [production.id], {'picking_id':picking_id, 'state':'confirmed'})
2745+# raise
2746+ return picking_id
2747+
2748+ _columns = {
2749+ 'procurement_ids': fields.one2many('procurement.order', 'production_id', 'Procurements'),
2750+ 'specific_production':fields.boolean('Specific Production'),
2751+ 'note_production':fields.text('Production Note'),
2752+ 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
2753+ 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
2754+ 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
2755+ 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
2756+ 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True),
2757+ 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
2758+ 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
2759+ 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
2760+ 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
2761+ 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
2762+ 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
2763+ 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
2764+ }
2765+ _order = 'id desc'
2766+
2767+ def action_production_end(self, cr, uid, ids):
2768+# move_ids = []
2769+ for production in self.browse(cr, uid, ids):
2770+ for res in production.move_lines:
2771+ for move in production.move_created_ids:
2772+ #XXX must use the orm
2773+# cr.execute('INSERT INTO stock_move_history_ids \
2774+# (parent_id, child_id) VALUES (%s,%s)',
2775+# (res.id, move.id))
2776+ #ASPerience: test des valeurs pour Ʃviter les erreurs de rƩƩcriture
2777+ cr.execute('select parent_id,child_id from stock_move_history_ids where parent_id=%s and child_id=%s', (res.id, move.id))
2778+ if len(cr.fetchall()) == 0:
2779+ cr.execute('insert into stock_move_history_ids (parent_id,child_id) values (%s,%s)', (res.id, move.id))
2780+ else:
2781+ logger = netsvc.Logger()
2782+ logger.notifyChannel("warning", netsvc.LOG_WARNING," ERROR insert into stock_move_history_ids parent_id=%s and child_id=%s'." % (str(move.id), str(move.move_dest_id.id)))
2783+ #Fin ASPerience
2784+# move_ids.append(res.id)
2785+ vals= {'state':'confirmed'}
2786+ new_moves = [x.id for x in production.move_created_ids]
2787+ self.pool.get('stock.move').write(cr, uid, new_moves, vals)
2788+ if not production.date_finnished:
2789+ self.write(cr, uid, [production.id],
2790+ {'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
2791+ self.pool.get('stock.move').check_assign(cr, uid, new_moves)
2792+ self.pool.get('stock.move').action_done(cr, uid, new_moves)
2793+ self._costs_generate(cr, uid, production)
2794+# self.pool.get('stock.move').action_done(cr, uid, move_ids)
2795+ self.write(cr, uid, ids, {'state': 'done'})
2796+ return True
2797+
2798+mrp_production()
2799+
2800+class mrp_production_product_line(osv.osv):
2801+ _inherit = 'mrp.production.product.line'
2802+
2803+ _columns = {
2804+ #Properties
2805+ 'property_ids': fields.many2many('mrp.property', 'mrp_production_product_line_property_rel', 'line_id','property_id', 'Properties'),
2806+ 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_line_group_property_rel','production_line_id', 'group_id', 'Product Property Group Rel '),
2807+ 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
2808+ 'option_ids': fields.many2many('product.links', 'mrp_production_product_line_options_rel','line_id', 'links_id', 'Option'),
2809+ 'bom_id': fields.many2one('mrp.bom', 'Bom'),
2810+ #Dimensions
2811+ 'size_x': fields.float('Width', digits=(16, 5)),
2812+ 'size_y': fields.float('Lenght', digits=(16, 5)),
2813+ 'size_z': fields.float('Thickness', digits=(16, 5)),
2814+ 'density': fields.float('Density', digits=(16, 5)),
2815+ 'shape' : fields.selection([('quadrangular', 'Quadrangular'), ('cylindrical', 'Cylindrical'), ('other', 'Other')], 'Shape', required=True),
2816+ 'diameter' : fields.float('Diameter', digits=(16, 5)),
2817+ 'weight': fields.float('Weight', digits=(16, 5)),
2818+ 'specific_production':fields.boolean('Specific Production'),
2819+ 'note_production':fields.text('Production Note'),
2820+ 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
2821+ 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
2822+ 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
2823+ 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
2824+ 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
2825+ 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
2826+ 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
2827+ 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
2828+
2829+ 'uom_d_size' : fields.related('product_id', 'uom_d_size', help="Default united of measure density used for operations size to cube"),
2830+ 'uom_d_weight': fields.related('product_id', 'uom_d_weight', help="Default united of measure density used for operations weight"),
2831+ 'uom_s_size' : fields.related('product_id', 'uom_s_size', help="Default united of measure used for operations size"),
2832+ }
2833+ _defaults = {
2834+ 'shape': lambda * a: 'other',
2835+ }
2836+
2837+ def onchange_product_id(self, cr, uid, ids, product_id, context={}):
2838+ if product_id:
2839+ w = self.pool.get('product.product').browse(cr, uid, product_id, context)
2840+ factor1 = w.uom_d_weight.factor
2841+ factor2 = w.uom_id.factor
2842+ factor3 = w.uom_d_size.factor
2843+ factor4 = w.uom_s_size.factor
2844+ v = {
2845+ 'product_uom':w.uom_id.id,
2846+ 'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id,
2847+ 'size_x':w.size_x or w.size_x_tmpl,
2848+ 'size_y':w.size_y or w.size_y_tmpl,
2849+ 'size_z':w.size_z or w.size_z_tmpl,
2850+ 'density':w.density or w.density_tmpl,
2851+ 'shape':w.shape,
2852+ 'diameter':w.diameter or w.diameter_tmpl,
2853+ 'weight':compute_w(cr, uid, factor1, factor2, factor3, factor4, w.size_x or w.size_x_tmpl, w.size_y or w.size_y_tmpl, w.size_z or w.size_z_tmpl, w.shape, w.density or w.density_tmpl, w.diameter or w.diameter_tmpl)['weight']
2854+ }
2855+ return {'value': v}
2856+ return {}
2857+
2858+ def compute_weight(self, cr, uid, id, product_id, size_x, size_y, size_z, shape, density, diameter):
2859+ if product_id:
2860+ product = self.pool.get('product.product').browse(cr, uid, product_id, context='')
2861+ factor1 = product.uom_d_weight.factor
2862+ factor2 = product.uom_id.factor
2863+ factor3 = product.uom_d_size.factor
2864+ factor4 = product.uom_s_size.factor
2865+ return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter)}
2866+
2867+mrp_production_product_line()
2868+
2869+class mrp_production_workcenter_line(osv.osv):
2870+ _inherit = 'mrp.production.workcenter.line'
2871+ _columns = {
2872+ 'move_ids' : fields.many2many('stock.move', 'mrp_production_workcenter_line_stock_move_rel', 'line_id', 'move_id', 'Moves'),
2873+ }
2874+ _defaults = {
2875+ }
2876+mrp_production_workcenter_line()
2877+
2878+def print_tab(*args):
2879+ cc = 0
2880+ try:
2881+ tmp = inspect.stack()[1]
2882+ for i in tmp[4][0]:
2883+ if i == ' ':
2884+ cc+=1
2885+ else:
2886+ break
2887+
2888+ if isinstance(args[0],int):
2889+ print "-"*args[0],
2890+ args = args[1:]
2891+ print str(tmp[2]).ljust(4),
2892+ print " "*cc,
2893+ except:
2894+ pass
2895+ for i in args:
2896+ print i,
2897+ print
2898+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2899\ No newline at end of file
2900
2901=== added file 'asperience_configurator_mrp/mrp_property.py'
2902--- asperience_configurator_mrp/mrp_property.py 1970-01-01 00:00:00 +0000
2903+++ asperience_configurator_mrp/mrp_property.py 2017-12-01 14:57:12 +0000
2904@@ -0,0 +1,99 @@
2905+# -*- encoding: utf-8 -*-
2906+##############################################################################
2907+#
2908+# OpenERP, Open Source Management Solution
2909+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
2910+# All Rights Reserved
2911+#
2912+# This program is free software: you can redistribute it and/or modify
2913+# it under the terms of the GNU General Public License as published by
2914+# the Free Software Foundation, either version 3 of the License, or
2915+# (at your option) any later version.
2916+#
2917+# This program is distributed in the hope that it will be useful,
2918+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2919+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2920+# GNU General Public License for more details.
2921+#
2922+# You should have received a copy of the GNU General Public License
2923+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2924+#
2925+##############################################################################
2926+from openerp.osv import fields,osv
2927+#import openerp.netsvc
2928+#import time
2929+#import datetime
2930+#from mx import DateTime
2931+#from openerp.tools.translate import _
2932+#from openerp.tools import ustr
2933+
2934+class mrp_property_group_option(osv.osv):
2935+ _name = 'mrp.property.group.option'
2936+ _description = 'GOP / Property'
2937+ _columns = {
2938+ 'name': fields.char('Name', size=256, required=True),
2939+ 'type_group_id': fields.many2one('product.type.property.option', 'GOP', required=True),
2940+ 'property_id': fields.many2one('mrp.property', 'Property', required=True),
2941+ }
2942+ _defaults = {
2943+ }
2944+
2945+ def onchange_group_property(self, cr, uid, id, type_group_id, property_id):
2946+ res = {'value':{}}
2947+ if type_group_id and not property_id :
2948+ type_group = self.pool.get("product.type.property.option").browse(cr,uid,type_group_id)
2949+ res['value']['name'] = type_group.name+"[X]"
2950+ elif not type_group_id and property_id :
2951+ property = self.pool.get("mrp.property").browse(cr,uid,property_id)
2952+ res['value']['name'] = "X["+property.name+"]"
2953+ elif type_group_id and property_id :
2954+ type_group = self.pool.get("product.type.property.option").browse(cr,uid,type_group_id)
2955+ property = self.pool.get("mrp.property").browse(cr,uid,property_id)
2956+ res['value']['name'] = type_group.name+"["+property.name+"]"
2957+ return res
2958+
2959+mrp_property_group_option()
2960+
2961+class mrp_property_group(osv.osv):
2962+ _inherit = 'mrp.property.group'
2963+ _columns = {
2964+ 'property_ids': fields.one2many('mrp.property', 'group_id', 'Properties'),
2965+ }
2966+ _defaults = {
2967+ }
2968+mrp_property_group()
2969+
2970+class mrp_property(osv.osv):
2971+ _inherit = 'mrp.property'
2972+
2973+ def name_get(self, cr, uid, ids, context=None):
2974+ if not ids:
2975+ return []
2976+ reads = self.read(cr, uid, ids, ['name','code'], context)
2977+ res = []
2978+ for record in reads:
2979+ name = "[%s] %s" % (record['code'],record['name'])
2980+ res.append((record['id'], name))
2981+ return res
2982+
2983+ _columns = {
2984+ 'code': fields.char('Code', size=64, required=True),
2985+ 'price': fields.float('Price'),
2986+ 'size_x_tmpl': fields.float('Width', digits=(16, 5)),
2987+ 'size_y_tmpl': fields.float('Length', digits=(16, 5)),
2988+ 'size_z_tmpl': fields.float('Thickness', digits=(16, 5)),
2989+ 'diameter_tmpl': fields.float('Diameter', digits=(16, 5)),
2990+ 'uom_s_size_tmpl' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
2991+ }
2992+ _defaults = {
2993+ 'code': lambda *a: 'XXX',
2994+ 'price': lambda *a: 0.0,
2995+ 'size_x_tmpl': lambda *a: 0,
2996+ 'size_y_tmpl': lambda *a: 0,
2997+ 'size_z_tmpl': lambda *a: 0,
2998+ 'diameter_tmpl': lambda *a: 0,
2999+ 'composition': lambda *a: 'plus',
3000+ }
3001+mrp_property()
3002+
3003+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3004\ No newline at end of file
3005
3006=== added file 'asperience_configurator_mrp/mrp_report.xml'
3007--- asperience_configurator_mrp/mrp_report.xml 1970-01-01 00:00:00 +0000
3008+++ asperience_configurator_mrp/mrp_report.xml 2017-12-01 14:57:12 +0000
3009@@ -0,0 +1,20 @@
3010+<?xml version="1.0" encoding="utf-8"?>
3011+<openerp>
3012+ <data>
3013+ <report auto="False"
3014+ header="False"
3015+ id="report_bom"
3016+ model="mrp.bom"
3017+ name="bom"
3018+ string="BOM Graph"/>
3019+
3020+ <report auto="True"
3021+ header="False"
3022+ id="mrp.report_bom_structure"
3023+ model="mrp.bom"
3024+ name="bom.structure"
3025+ rml="asperience_mrp/report/bom_structure.rml"
3026+ string="BOM Structure"/>
3027+
3028+ </data>
3029+</openerp>
3030
3031=== added file 'asperience_configurator_mrp/mrp_routing.py'
3032--- asperience_configurator_mrp/mrp_routing.py 1970-01-01 00:00:00 +0000
3033+++ asperience_configurator_mrp/mrp_routing.py 2017-12-01 14:57:12 +0000
3034@@ -0,0 +1,54 @@
3035+# -*- encoding: utf-8 -*-
3036+##############################################################################
3037+#
3038+# OpenERP, Open Source Management Solution
3039+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
3040+# All Rights Reserved
3041+#
3042+# This program is free software: you can redistribute it and/or modify
3043+# it under the terms of the GNU General Public License as published by
3044+# the Free Software Foundation, either version 3 of the License, or
3045+# (at your option) any later version.
3046+#
3047+# This program is distributed in the hope that it will be useful,
3048+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3049+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3050+# GNU General Public License for more details.
3051+#
3052+# You should have received a copy of the GNU General Public License
3053+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3054+#
3055+##############################################################################
3056+from openerp.osv import fields,osv
3057+
3058+class mrp_routing(osv.osv):
3059+ _inherit = 'mrp.routing'
3060+ _columns = {
3061+ 'technical_data': fields.char('Technical Data', size=128),
3062+ }
3063+ _defaults = {
3064+ 'active': lambda *a: 1,
3065+ }
3066+mrp_routing()
3067+
3068+class mrp_routing_workcenter_subproduct(osv.osv):
3069+ _name = 'mrp.routing.workcenter.subproduct'
3070+ _description = 'mrp.routing.workcenter.subproduct'
3071+ _columns = {
3072+ 'name': fields.float('Percent', required=True),
3073+ 'subproduct_id': fields.many2one('mrp.subproduct', 'Subproduct', required=True),
3074+ 'workcenter_line_id': fields.many2one('mrp.routing.workcenter', 'Routing Workcenter', required=True),
3075+ }
3076+mrp_routing_workcenter_subproduct()
3077+
3078+class mrp_routing_workcenter(osv.osv):
3079+ _inherit = 'mrp.routing.workcenter'
3080+ _columns = {
3081+ 'sub_ids': fields.one2many('mrp.routing.workcenter.subproduct', 'workcenter_line_id', 'Sub Product'),
3082+ 'bom_ids': fields.many2many('mrp.bom', 'routing_workcenter_mrp_bom_rel', 'workcenter_line_id', 'bom_id', 'Components'),
3083+ }
3084+ _defaults = {
3085+ }
3086+mrp_routing_workcenter()
3087+
3088+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3089\ No newline at end of file
3090
3091=== added file 'asperience_configurator_mrp/mrp_subproduct.py'
3092--- asperience_configurator_mrp/mrp_subproduct.py 1970-01-01 00:00:00 +0000
3093+++ asperience_configurator_mrp/mrp_subproduct.py 2017-12-01 14:57:12 +0000
3094@@ -0,0 +1,37 @@
3095+# -*- encoding: utf-8 -*-
3096+##############################################################################
3097+#
3098+# OpenERP, Open Source Management Solution
3099+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
3100+# All Rights Reserved
3101+#
3102+# This program is free software: you can redistribute it and/or modify
3103+# it under the terms of the GNU General Public License as published by
3104+# the Free Software Foundation, either version 3 of the License, or
3105+# (at your option) any later version.
3106+#
3107+# This program is distributed in the hope that it will be useful,
3108+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3109+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3110+# GNU General Public License for more details.
3111+#
3112+# You should have received a copy of the GNU General Public License
3113+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3114+#
3115+##############################################################################
3116+from openerp.osv import fields,osv
3117+
3118+class mrp_subproduct(osv.osv):
3119+ _inherit = 'mrp.subproduct'
3120+ _columns={
3121+ 'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% within the production process."),
3122+ 'efficiency_rounding': fields.selection([(1,'1'),(2,'0.1'),(3,'0.01'),(4,'0.001'),(5,'0.0001'),(5,'0.00001')], 'Efficiency rounding', required=True, help= "todo" ),
3123+ 'type_group_ids': fields.many2many('product.type.property.option', 'mrp_subproduct_options_rel', 'subproduct_id', 'type_id', 'Group by (GOP)',help="Used to map which property option is taken from main product in dissambly chain"),
3124+ }
3125+ _defaults={
3126+ 'product_efficiency' : lambda *a : 1,
3127+ 'efficiency_rounding' : lambda *a : 2,
3128+ }
3129+mrp_subproduct()
3130+
3131+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3132\ No newline at end of file
3133
3134=== added file 'asperience_configurator_mrp/mrp_subproduct_view.xml'
3135--- asperience_configurator_mrp/mrp_subproduct_view.xml 1970-01-01 00:00:00 +0000
3136+++ asperience_configurator_mrp/mrp_subproduct_view.xml 2017-12-01 14:57:12 +0000
3137@@ -0,0 +1,33 @@
3138+<?xml version="1.0" encoding="utf-8"?>
3139+<openerp>
3140+ <data>
3141+ <record id="mrp_subproduct_view_tree" model="ir.ui.view">
3142+ <field name="name">mrp.subproduct.tree</field>
3143+ <field name="model">mrp.subproduct</field>
3144+ <field name="type">tree</field>
3145+ <field name="arch" type="xml">
3146+ <tree string="Sub products" editable="top">
3147+ <field name="product_id" on_change="onchange_product_id(product_id)"/>
3148+ <field name="product_uom"/>
3149+ <field name="product_qty"/>
3150+ <field name="subproduct_type"/>
3151+ </tree>
3152+ </field>
3153+ </record>
3154+
3155+ <record id="mrp_subproduct_view_form" model="ir.ui.view">
3156+ <field name="name">mrp.subproduct.form</field>
3157+ <field name="model">mrp.subproduct</field>
3158+ <field name="type">form</field>
3159+ <field name="arch" type="xml">
3160+ <form string="Sub products">
3161+ <field name="product_id" on_change="onchange_product_id(product_id)"/>
3162+ <field name="product_uom"/>
3163+ <field name="product_qty"/>
3164+ <field name="subproduct_type"/>
3165+ </form>
3166+ </field>
3167+ </record>
3168+
3169+ </data>
3170+</openerp>
3171
3172=== added file 'asperience_configurator_mrp/mrp_view.xml'
3173--- asperience_configurator_mrp/mrp_view.xml 1970-01-01 00:00:00 +0000
3174+++ asperience_configurator_mrp/mrp_view.xml 2017-12-01 14:57:12 +0000
3175@@ -0,0 +1,735 @@
3176+<?xml version="1.0" encoding="utf-8"?>
3177+<openerp>
3178+ <data>
3179+ ###################################### PROPERTY #######################################
3180+ <record id="mrp_property_group_tree_view_asperience_mrp" model="ir.ui.view">
3181+ <field name="name">mrp.property.group.tree.asperience_mrp</field>
3182+ <field name="model">mrp.property.group</field>
3183+ <field name="arch" type="xml">
3184+ <form string="Properties categories">
3185+ <separator colspan="4" string="General Information"/>
3186+ <field colspan="4" name="name"/>
3187+ <field colspan="4" name="description"/>
3188+ <field name="property_ids" nolabel="1" colspan="4"/>
3189+ </form>
3190+ </field>
3191+ </record>
3192+
3193+ <record id="mrp_property_tree_view_asperience_mrp" model="ir.ui.view">
3194+ <field name="name">mrp.property.tree.asperience_mrp</field>
3195+ <field name="model">mrp.property</field>
3196+ <field name="inherit_id" ref="mrp.mrp_property_tree_view" />
3197+ <field name="arch" type="xml">
3198+ <field name="name" position="before">
3199+ <field name="code"/>
3200+ <field name="price"/>
3201+ <field name="uom_s_size_tmpl"/>
3202+ <field name="size_x_tmpl"/>
3203+ <field name="size_y_tmpl"/>
3204+ <field name="size_z_tmpl"/>
3205+ <field name="diameter_tmpl"/>
3206+ </field>
3207+ <field name="composition" position="replace"/>
3208+ </field>
3209+ </record>
3210+ <record id="mrp_property_form_view_asperience_mrp" model="ir.ui.view">
3211+ <field name="name">mrp.property.form.asperience_mrp</field>
3212+ <field name="model">mrp.property</field>
3213+ <field name="type">form</field>
3214+ <field name="inherit_id" ref="mrp.mrp_property_form_view" />
3215+ <field name="arch" type="xml">
3216+ <field name="name" position="before">
3217+ <field name="code"/>
3218+ </field>
3219+ <field name="name" position="after">
3220+ <newline/>
3221+ <field name="price"/>
3222+ <newline/>
3223+ <field name="size_x_tmpl"/>
3224+ <field name="size_y_tmpl"/>
3225+ <field name="size_z_tmpl"/>
3226+ <field name="diameter_tmpl"/>
3227+ <field name="uom_s_size_tmpl"/>
3228+ <newline/>
3229+ </field>
3230+ <field name="composition" position="replace"/>
3231+ </field>
3232+ </record>
3233+
3234+ ###################################### WORKCENTER #######################################
3235+ <record id="mrp_workcenter_tree_view_asperience_mrp" model="ir.ui.view">
3236+ <field name="name">mrp.workcenter.tree.asperience.mrp</field>
3237+ <field name="model">mrp.workcenter</field>
3238+ <field name="inherit_id" ref="mrp.mrp_workcenter_tree_view"/>
3239+ <field name="arch" type="xml">
3240+ <field name="code" position="before">
3241+ <field name="sequence"/>
3242+ </field>
3243+ </field>
3244+ </record>
3245+
3246+ <record id="mrp_workcenter_view_asperience_mrp" model="ir.ui.view">
3247+ <field name="name">mrp.workcenter.form.asperience.mrp</field>
3248+ <field name="model">mrp.workcenter</field>
3249+ <field name="inherit_id" ref="mrp.mrp_workcenter_view"/>
3250+ <field name="arch" type="xml">
3251+ <notebook position="inside">
3252+ <page string="Properties">
3253+ <field name="property_ids" nolabel="1" colspan="4"/>
3254+ </page>
3255+ <page string="Hierarchy">
3256+ <field name="parent_id" domain="[('type','in', [type_re, type_pc, type_cc])]"/>
3257+ <field colspan="4" name="child_ids"/>
3258+ </page>
3259+ </notebook>
3260+ <!-- <field name="timesheet_id" position="replace"/> -->
3261+ <field name="time_start" position="attributes">
3262+ <attribute name="attrs">{'invisible': [('type', '!=', 'machine')]}</attribute>
3263+ </field>
3264+ <field name="time_stop" position="attributes">
3265+ <attribute name="attrs">{'invisible': [('type', '!=', 'machine')]}</attribute>
3266+ </field>
3267+ <field name="code" position="before">
3268+ <field name="sequence"/>
3269+ </field>
3270+ <field name="resource_type" position="before">
3271+ <field name="warehouse_id"/>
3272+ </field>
3273+ <field name="resource_type" position="after">
3274+ <field name="type_workcenter" on_change="onchange_type_workcenter(type_workcenter)"/>
3275+ <field name="type" invisible="True"/>
3276+ <newline/>
3277+ <field name="type_re" on_change="onchange_type(type_re)" attrs="{'invisible':[('type_workcenter','!=', 're')]}"/>
3278+ <newline/>
3279+ <field name="type_pc" on_change="onchange_type(type_pc)" attrs="{'invisible':[('type_workcenter','!=', 'pc')]}"/>
3280+ <newline/>
3281+ <field name="type_cc" on_change="onchange_type(type_cc)" attrs="{'invisible':[('type_workcenter','!=', 'cc')]}"/>
3282+ <newline/>
3283+ <field name="technology" attrs="{'invisible':[('type','not in',['tool', 'machine', 'machine_hr', 'line'])]}"/>
3284+ <newline/>
3285+ <field name="scheduling" attrs="{'invisible':[('type','in',['hr','line'])]}"/>
3286+ <newline/>
3287+ </field>
3288+ <field name="capacity_per_cycle" position="after">
3289+ <group col="6" attrs="{'invisible':[('type','=', 'hr')]}" groups="analytic.group_analytic_accounting">
3290+ <field name="fixed_capacity"/>
3291+ <field name="external"/>
3292+ <field name="critical"/>
3293+ <field name="finite_capacity_qty"/>
3294+ <field name="finite_capacity"/>
3295+ </group>
3296+ </field>
3297+ </field>
3298+ </record>
3299+
3300+ ###################################### BOM #######################################
3301+
3302+ <record id="mrp_bom_form_view_asperience_mrp" model="ir.ui.view">
3303+ <field name="name">mrp.bom.form.asperience.mrp</field>
3304+ <field name="model">mrp.bom</field>
3305+ <field name="inherit_id" ref="mrp.mrp_bom_form_view"/>
3306+ <field name="arch" type="xml">
3307+ <field name="property_ids" position="replace" >
3308+ <field name="property_ids" nolabel="1" colspan="4" />
3309+ <field name="type_group_ids" nolabel="1" colspan="4" />
3310+ </field>
3311+ <field name="bom_line_ids" position="after" >
3312+ <button name="gen_graph" string="Graph" type="object" />
3313+ <separator colspan="4" string="Components"/>
3314+ <!-- <field name="bom_lines_multi" nolabel="1" colspan="4" /> -->
3315+ <field name="bom_components" nolabel="1" colspan="4" context="{'tree_view_ref':'asperience_mrp.mrp_bom_component_rel_tree_view_component','form_view_ref':'asperience_mrp.mrp_bom_component_rel_form_view_component'}" />
3316+ <separator colspan="4" string="Is used in"/>
3317+ <!-- <field name="bom_parent_multi" nolabel="1" colspan="4" /> -->
3318+ <field name="bom_components_parent" nolabel="1" colspan="4" context="{'tree_view_ref':'asperience_mrp.mrp_bom_component_rel_tree_view_parent','form_view_ref':'asperience_mrp.mrp_bom_component_rel_form_view_parent'}" />
3319+ </field>
3320+ <field name="type" position="after" >
3321+ <field name="bom_type" />
3322+ </field>
3323+ </field>
3324+ </record>
3325+
3326+ ###################################### PROD LINE #######################################
3327+ <record id="mrp.mrp_production_product_form_view" model="ir.ui.view">
3328+ <field name="name">mrp.production.product.line.form.asperience.mrp</field>
3329+ <field name="model">mrp.production.product.line</field>
3330+ <field name="priority">15</field>
3331+ <field name="arch" type="xml">
3332+ <form string="Scheduled Products">
3333+ <field name="name" />
3334+ <field name="product_id" on_change="onchange_product_id(product_id)" />
3335+ <field name="product_qty" />
3336+ <field name="product_uom" />
3337+ <field name="product_uos_qty" />
3338+ <field name="product_uos" />
3339+ <field name='specific_production' colspan="4" />
3340+ <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
3341+ <group colspan="4">
3342+ <field name="shape"
3343+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3344+
3345+ <field name="density"
3346+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3347+
3348+ <field name="diameter" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" attrs="{'invisible':[('shape','in',['quadrangular','other'])]}"/>
3349+ <field name="weight" />
3350+ </group>
3351+ <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
3352+ <group colspan="2">
3353+ <field name='size_x' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3354+ <field name='size_y' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3355+ <field name='size_z' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3356+ </group>
3357+ <group colspan="2">
3358+ <label string='-' colspan="4"/>
3359+ <label string='-' colspan="4"/>
3360+ <label string='-' colspan="4"/>
3361+ </group>
3362+ <group colspan="2">
3363+ <field name='size_x_specific_delta' colspan="2" />
3364+ <field name='size_y_specific_delta' colspan="2" />
3365+ <field name='size_z_specific_delta' colspan="2" />
3366+ </group>
3367+ <group colspan="2">
3368+ <label string='=' colspan="4"/>
3369+ <label string='=' colspan="4"/>
3370+ <label string='=' colspan="4"/>
3371+ </group>
3372+ <group colspan="2">
3373+ <field name='size_x_specific' colspan="2" />
3374+ <field name='size_y_specific' colspan="2" />
3375+ <field name='size_z_specific' colspan="2" />
3376+ </group>
3377+ </group>
3378+
3379+ <field name="property_ids" colspan="4" nolabel="1"/>
3380+ <field name="group_property_ids" colspan="4" nolabel="1" />
3381+ <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
3382+ <field name="procurement_id" />
3383+ <field name="bom_id" />
3384+ </form>
3385+ </field>
3386+ </record>
3387+
3388+ <record id="mrp_production_product_tree_view_asperience_mrp" model="ir.ui.view">
3389+ <field name="name">mrp.production.product.line.tree.asperience.mrp</field>
3390+ <field name="model">mrp.production.product.line</field>
3391+ <field name="inherit_id" ref="mrp.mrp_production_product_tree_view"/>
3392+ <field name="arch" type="xml">
3393+ <field name="product_uos" position="after">
3394+ <field name="density" />
3395+ <field name="shape" />
3396+ <field name="diameter" />
3397+ <field name="size_x" />
3398+ <field name="size_y" />
3399+ <field name="size_z" />
3400+ <field name="weight" />
3401+ <field name="property_ids"/>
3402+ <field name="group_property_ids" />
3403+ <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
3404+ <field name="procurement_id" />
3405+ <field name="bom_id" />
3406+ </field>
3407+ <field name="product_id" position="before">
3408+ <field name="name" />
3409+ </field>
3410+ </field>
3411+ </record>
3412+
3413+ ###################################### WORKCENTER TECHNOLOGY #######################################
3414+ <record id="mrp_workcenter_technology_form_view" model="ir.ui.view">
3415+ <field name="name">mrp.workcenter.technology.form.view.1</field>
3416+ <field name="model">mrp.workcenter.technology</field>
3417+ <field name="type">form</field>
3418+ <field name="arch" type="xml">
3419+ <form string="Workcenter Technology">
3420+ <group col="6" colspan="4">
3421+ <group col="3" colspan="2">
3422+ <field name="name" />
3423+ </group>
3424+ </group>
3425+ </form>
3426+ </field>
3427+ </record>
3428+ <record id="mrp_workcenter_technology_tree_view" model="ir.ui.view">
3429+ <field name="name">mrp.workcenter.technology.tree.view.1</field>
3430+ <field name="model">mrp.workcenter.technology</field>
3431+ <field name="type">tree</field>
3432+ <field name="arch" type="xml">
3433+ <tree string="Workcenter Technology">
3434+ <field name="name" />
3435+ </tree>
3436+ </field>
3437+ </record>
3438+
3439+ <record model="ir.actions.act_window" id="mrp_workcenter_technology_all_action">
3440+ <field name="name">Workcenter Technology</field>
3441+ <field name="res_model">mrp.workcenter.technology</field>
3442+ <field name="view_mode">tree,form</field>
3443+ <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_tree_view"/>
3444+ </record>
3445+ <record model="ir.actions.act_window.view" id="mrp_workcenter_technology_tree_action">
3446+ <field name="sequence" eval="1"/>
3447+ <field name="view_mode">tree</field>
3448+ <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_tree_view"/>
3449+ <field name="act_window_id" ref="mrp_workcenter_technology_all_action"/>
3450+ </record>
3451+ <record model="ir.actions.act_window.view" id="mrp_workcenter_technology_form_action">
3452+ <field name="sequence" eval="2"/>
3453+ <field name="view_mode">form</field>
3454+ <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_form_view"/>
3455+ <field name="act_window_id" ref="mrp_workcenter_technology_all_action"/>
3456+ </record>
3457+ <menuitem action="mrp_workcenter_technology_all_action" id="menu_mrp_workcenter_technology_all_action" parent="mrp.menu_mrp_configuration" sequence="22"/>
3458+
3459+ ###################################### PRODUCTION #######################################
3460+ <record id="mrp_production_form_view_asperience_mrp" model="ir.ui.view">
3461+ <field name="name">mrp.production.form.asperience.mrp</field>
3462+ <field name="model">mrp.production</field>
3463+ <field name="inherit_id" ref="mrp.mrp_production_form_view"/>
3464+ <field name="arch" type="xml">
3465+ <field name="workcenter_lines" position="replace" >
3466+ <field colspan="4" name="workcenter_lines" nolabel="1" >
3467+ <form string="Production Workcenters">
3468+ <field colspan="4" name="name"/>
3469+ <field colspan="4" name="workcenter_id" />
3470+ <separator/>
3471+ <field name="sequence"/>
3472+ <field name="cycle"/>
3473+ <field name="hour"/>
3474+ </form>
3475+ <tree string="Production Workcenters" >
3476+ <field name="sequence"/>
3477+ <field name="name"/>
3478+ <field name="workcenter_id"/>
3479+ <field name="cycle"/>
3480+ <field name="hour"/>
3481+ </tree>
3482+ </field>
3483+ </field>
3484+ <page string="Extra Information" position="after" >
3485+ <page string="Procurements">
3486+ <field name="procurement_ids"/>
3487+ </page>
3488+ </page>
3489+ <field name="move_prod_id" position="after" >
3490+ <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
3491+ <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
3492+ <group colspan="2">
3493+ <field name='size_x' colspan="2"/>
3494+ <field name='size_y' colspan="2"/>
3495+ <field name='size_z' colspan="2"/>
3496+ <field name='diameter' colspan="2"/>
3497+ </group>
3498+ <group colspan="2">
3499+ <label string='-' colspan="4"/>
3500+ <label string='-' colspan="4"/>
3501+ <label string='-' colspan="4"/>
3502+ <label string='-' colspan="4"/>
3503+ </group>
3504+ <group colspan="2">
3505+ <field name='size_x_specific_delta' colspan="2" />
3506+ <field name='size_y_specific_delta' colspan="2" />
3507+ <field name='size_z_specific_delta' colspan="2" />
3508+ <field name='diameter_specific_delta' colspan="2" />
3509+ </group>
3510+ <group colspan="2">
3511+ <label string='=' colspan="4"/>
3512+ <label string='=' colspan="4"/>
3513+ <label string='=' colspan="4"/>
3514+ <label string='=' colspan="4"/>
3515+ </group>
3516+ <group colspan="2">
3517+ <field name='size_x_specific' colspan="2" />
3518+ <field name='size_y_specific' colspan="2" />
3519+ <field name='size_z_specific' colspan="2" />
3520+ <field name='diameter_specific' colspan="2" />
3521+ </group>
3522+ </group>
3523+ <field name='specific_production' colspan="4" />
3524+ <separator string="Production" colspan="4" />
3525+ </field>
3526+ <button name="action_compute" position="after" >
3527+ <button name="action_compute" string="Compute Data" type="object" />
3528+ <button name="button_draft" string="Draft" />
3529+ </button>
3530+ </field>
3531+ </record>
3532+
3533+ ###################################### GROUP OPTION #######################################
3534+ <record id="mrp_property_group_option_form_view_asperience_mrp_1" model="ir.ui.view">
3535+ <field name="name">mrp.property.group.option.form.asperience.mrp.1</field>
3536+ <field name="model">mrp.property.group.option</field>
3537+ <field name="type">form</field>
3538+ <field name="arch" type="xml">
3539+ <form string="GOP / Property">
3540+ <field colspan="4" name="name"/>
3541+ <field colspan="4" name="type_group_id" on_change="onchange_group_property(type_group_id,property_id)"/>
3542+ <field colspan="4" name="property_id" on_change="onchange_group_property(type_group_id,property_id)"/>
3543+ </form>
3544+ </field>
3545+ </record>
3546+ <record id="mrp_property_group_option_tree_view_asperience_mrp_1" model="ir.ui.view">
3547+ <field name="name">mrp.property.group.option.tree.asperience.mrp.1</field>
3548+ <field name="model">mrp.property.group.option</field>
3549+ <field name="type">tree</field>
3550+ <field name="arch" type="xml">
3551+ <tree string="GOP / Property" editable="top">
3552+ <field colspan="4" name="name"/>
3553+ <field colspan="4" name="type_group_id" on_change="onchange_group_property(type_group_id,property_id)"/>
3554+ <field colspan="4" name="property_id" on_change="onchange_group_property(type_group_id,property_id)"/>
3555+ </tree>
3556+ </field>
3557+ </record>
3558+
3559+ ###################################### GROUP OPTION #######################################
3560+ <record id="mrp_routing_form_view_asperience_mrp_1" model="ir.ui.view">
3561+ <field name="name">mrp.routing.form.asperience.mrp.1</field>
3562+ <field name="model">mrp.routing</field>
3563+ <field name="inherit_id" ref="mrp.mrp_routing_form_view"/>
3564+ <field name="type">form</field>
3565+ <field name="arch" type="xml">
3566+ <field name="active" position="after">
3567+ <field name="technical_data" colspan="4"/>
3568+ </field>
3569+ </field>
3570+ </record>
3571+ <record id="mrp_routing_tree_view_asperience_mrp_1" model="ir.ui.view">
3572+ <field name="name">mrp.routing.tree.asperience.mrp.1</field>
3573+ <field name="model">mrp.routing</field>
3574+ <field name="inherit_id" ref="mrp.mrp_routing_tree_view"/>
3575+ <field name="type">tree</field>
3576+ <field name="arch" type="xml">
3577+ <field name="name" position="after">
3578+ <field name="technical_data" />
3579+ </field>
3580+ </field>
3581+ </record>
3582+
3583+ ###################################### SUBPRODUCT #######################################
3584+ <record id="mrp_byproduct.mrp_subproduct_view" model="ir.ui.view">
3585+ <field name="name">mrp.bom.sub.product.asperience.mrp.1</field>
3586+ <field name="model">mrp.bom</field>
3587+ <field name="inherit_id" ref="mrp.mrp_bom_form_view"/>
3588+ <field name="arch" type="xml">
3589+ <field name="product_id" position="replace">
3590+ <field name="product_id" on_change="onchange_product_id(product_id, name,False)"/>
3591+ </field>
3592+ <field name="type" position="after">
3593+ <group colspan="4">
3594+ <field name="shape"
3595+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3596+
3597+ <field name="density"
3598+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3599+
3600+ </group>
3601+
3602+ <group colspan="4">
3603+ <group attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
3604+ <field name="size_x"
3605+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3606+ <field name="size_y"
3607+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3608+ </group>
3609+
3610+ <group attrs="{'invisible':[('shape','in',['quadrangular','other'])]}">
3611+ <field name="diameter"
3612+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3613+ </group>
3614+
3615+ <group attrs="{'invisible':[('shape','in',['other'])]}">
3616+ <field name="size_z"
3617+ on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
3618+ </group>
3619+
3620+
3621+ </group>
3622+ <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
3623+ <field name="weight" />
3624+
3625+ </group>
3626+ </field>
3627+ <notebook position="inside">
3628+ <page string="Byproducts" position="inside">
3629+ <field name="sub_products">
3630+ <tree string="Byproducts" editable="top">
3631+ <field name="product_id" on_change="onchange_product_id(product_id)"/>
3632+ <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
3633+ <field name="product_qty"/>
3634+ <field name="product_efficiency"/>
3635+ <field name="efficiency_rounding"/>
3636+ <field name="subproduct_type"/>
3637+ <field name="type_group_ids"/>
3638+ </tree>
3639+ <form string="Byproducts">
3640+ <field name="product_id" on_change="onchange_product_id(product_id)"/>
3641+ <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
3642+ <field name="product_qty"/>
3643+ <field name="product_efficiency"/>
3644+ <field name="efficiency_rounding"/>
3645+ <field name="subproduct_type"/>
3646+ <field name="type_group_ids"/>
3647+ </form>
3648+ </field>
3649+ </page>
3650+ </notebook>
3651+ </field>
3652+ </record>
3653+
3654+ <record id="mrp_bom_tree_view_asperience_mrp" model="ir.ui.view">
3655+ <field name="name">mrp.bom.tree.asperience.mrp</field>
3656+ <field name="model">mrp.bom</field>
3657+ <field name="inherit_id" ref="mrp.mrp_bom_tree_view" />
3658+ <field name="field_parent">child_complete_ids</field>
3659+ <field name="arch" type="xml">
3660+ <field name="product_uom" position="after">
3661+ <field name="density" />
3662+ <field name="shape" />
3663+ <field name="diameter" />
3664+ <field name="size_x" />
3665+ <field name="size_y" />
3666+ <field name="size_z" />
3667+ <field name="weight" />
3668+ </field>
3669+ </field>
3670+ </record>
3671+
3672+ <record id="mrp_routing_workcenter_subproduct_form_view" model="ir.ui.view">
3673+ <field name="name">mrp.routing.workcenter.subproduct</field>
3674+ <field name="model">mrp.routing.workcenter.subproduct</field>
3675+ <field name="type">form</field>
3676+ <field name="arch" type="xml">
3677+ <form string="Subproduct" >
3678+ <field name="name" colspan="4"/>
3679+ <field name="workcenter_line_id" colspan="4"/>
3680+ <field name="subproduct_id" colspan="4"/>
3681+ </form>
3682+ </field>
3683+ </record>
3684+
3685+ <record id="mrp_routing_workcenter_subproduct_tree_view" model="ir.ui.view">
3686+ <field name="name">mrp.routing.workcenter.subproduct</field>
3687+ <field name="model">mrp.routing.workcenter.subproduct</field>
3688+ <field name="type">tree</field>
3689+ <field name="arch" type="xml">
3690+ <tree string="Subproduct" >
3691+ <field name="name" />
3692+ <field name="workcenter_line_id" />
3693+ <field name="subproduct_id" />
3694+ </tree>
3695+ </field>
3696+ </record>
3697+
3698+ ###################################### GROUP ROUTING #######################################
3699+ <record id="mrp_routing_workcenter_tree_view_asperience_mrp_1" model="ir.ui.view">
3700+ <field name="name">mrp.routing.workcenter.tree.asperience.mrp.1</field>
3701+ <field name="model">mrp.routing.workcenter</field>
3702+ <field name="inherit_id" ref="mrp.mrp_routing_workcenter_tree_view"/>
3703+ <field name="type">tree</field>
3704+ <field name="arch" type="xml">
3705+ <field name="hour_nbr" position="after">
3706+ <field name="bom_ids"/>
3707+ <field name="sub_ids">
3708+ <form string="Subproduct" >
3709+ <field name="name" colspan="4"/>
3710+ <field name="workcenter_line_id" colspan="4"/>
3711+ <field name="subproduct_id" colspan="4"/>
3712+ </form>
3713+ <tree string="Subproduct" >
3714+ <field name="name" />
3715+ <field name="workcenter_line_id" />
3716+ <field name="subproduct_id" />
3717+ </tree>
3718+ </field>
3719+ </field>
3720+ </field>
3721+ </record>
3722+
3723+ <record id="mrp_routing_workcenter_form_view_asperience_mrp_1" model="ir.ui.view">
3724+ <field name="name">mrp.routing.workcenter.form.asperience.mrp.1</field>
3725+ <field name="model">mrp.routing.workcenter</field>
3726+ <field name="inherit_id" ref="mrp.mrp_routing_workcenter_form_view"/>
3727+ <field name="type">form</field>
3728+ <field name="arch" type="xml">
3729+ <field name="hour_nbr" position="after">
3730+ <field name="bom_ids" colspan="4"/>
3731+ <field name="sub_ids" colspan="4">
3732+ <form string="Subproduct" >
3733+ <field name="name" colspan="4"/>
3734+ <field name="subproduct_id" colspan="4"/>
3735+ </form>
3736+ <tree string="Subproduct" >
3737+ <field name="name" />
3738+ <field name="subproduct_id" />
3739+ </tree>
3740+ </field>
3741+ </field>
3742+ </field>
3743+ </record>
3744+
3745+
3746+ ###################################### WORKCENTER LINE #######################################
3747+ <record id="mrp_production_form_view_asperience_mrp_5" model="ir.ui.view">
3748+ <field name="name">mrp.production.form.asperience.mrp.5</field>
3749+ <field name="model">mrp.production</field>
3750+ <field name="inherit_id" ref="mrp.mrp_production_form_view"/>
3751+ <field name="type">form</field>
3752+ <field name="arch" type="xml">
3753+ <field name="workcenter_lines" position="replace">
3754+ <field colspan="4" name="workcenter_lines" nolabel="1">
3755+ <form string="Production Workcenters">
3756+ <field colspan="4" name="name"/>
3757+ <field colspan="4" name="workcenter_id"/>
3758+ <field name="sequence"/>
3759+ <field name="cycle"/>
3760+ <field name="hour"/>
3761+ <newline/>
3762+ <field name="move_ids"/>
3763+ </form>
3764+ <tree string="Production Workcenters">
3765+ <field name="sequence"/>
3766+ <field name="name"/>
3767+ <field name="workcenter_id"/>
3768+ <field name="cycle"/>
3769+ <field name="hour"/>
3770+ <field name="move_ids"/>
3771+ </tree>
3772+ </field>
3773+ </field>
3774+ </field>
3775+ </record>
3776+
3777+ <record model="ir.ui.view" id="mrp_production_workcenter_tree_view_inherit_asperience_mrp_1">
3778+ <field name="name">mrp.production.workcenter.line.tree.asperience.mrp.1</field>
3779+ <field name="model">mrp.production.workcenter.line</field>
3780+ <field name="type">tree</field>
3781+ <field name="inherit_id" ref="mrp_operations.mrp_production_workcenter_tree_view_inherit"/>
3782+ <field name="arch" type="xml">
3783+ <field name="workcenter_id" position="after">
3784+ <field name="move_ids"/>
3785+ </field>
3786+ </field>
3787+ </record>
3788+
3789+ <record model="ir.ui.view" id="mrp_production_workcenter_form_view_inherit_asperience_mrp_1">
3790+ <field name="name">mrp.production.workcenter.line.form.asperience.mrp.1</field>
3791+ <field name="model">mrp.production.workcenter.line</field>
3792+ <field name="type">form</field>
3793+ <field name="inherit_id" ref="mrp_operations.mrp_production_workcenter_form_view_inherit"/>
3794+ <field name="arch" type="xml">
3795+ <page string="Information" position="after">
3796+ <page string="Moves">
3797+ <field name="move_ids"/>
3798+ </page>
3799+ </page>
3800+ </field>
3801+ </record>
3802+
3803+ ###################################### BOM REL #######################################
3804+ <record id="mrp_bom_component_rel_form_view_component" model="ir.ui.view">
3805+ <field name="name">mrp.bom.component.rel.form.view</field>
3806+ <field name="model">mrp.bom.component.rel</field>
3807+ <field name="type">form</field>
3808+ <field name="arch" type="xml">
3809+ <form string="Components">
3810+ <field name="component_id" />
3811+ <!-- <field name="product_component_id" /> -->
3812+ <field name="qty" />
3813+ <field name="mode" />
3814+ </form>
3815+ </field>
3816+ </record>
3817+
3818+ <record id="mrp_bom_component_rel_tree_view_component" model="ir.ui.view">
3819+ <field name="name">mrp.bom.component.rel.tree.view</field>
3820+ <field name="model">mrp.bom.component.rel</field>
3821+ <field name="type">tree</field>
3822+ <field name="arch" type="xml">
3823+ <tree string="Components" editable="top">
3824+ <field name="component_id" />
3825+ <!-- <field name="product_component_id" />-->
3826+ <field name="qty" />
3827+ <field name="mode" />
3828+ </tree>
3829+ </field>
3830+ </record>
3831+
3832+ <record id="mrp_bom_component_rel_form_view_parent" model="ir.ui.view">
3833+ <field name="name">mrp.bom.component.rel.form.view</field>
3834+ <field name="model">mrp.bom.component.rel</field>
3835+ <field name="type">form</field>
3836+ <field name="arch" type="xml">
3837+ <form string="Used in">
3838+ <field name="bom_id" />
3839+ <field name="qty" />
3840+ <field name="mode" />
3841+ </form>
3842+ </field>
3843+ </record>
3844+
3845+ <record id="mrp_bom_component_rel_tree_view_parent" model="ir.ui.view">
3846+ <field name="name">mrp.bom.component.rel.tree.view</field>
3847+ <field name="model">mrp.bom.component.rel</field>
3848+ <field name="type">tree</field>
3849+ <field name="arch" type="xml">
3850+ <tree string="Used in" editable="top">
3851+ <field name="bom_id" />
3852+ <field name="qty" />
3853+ <field name="mode" />
3854+ </tree>
3855+ </field>
3856+ </record>
3857+
3858+ ###################################### BOM COMPONENTS #######################################
3859+ <record id="mrp_bom_component_mode_form_view" model="ir.ui.view">
3860+ <field name="name">mrp.bom.component.mode.form.view</field>
3861+ <field name="model">mrp.bom.component.mode</field>
3862+ <field name="type">form</field>
3863+ <field name="arch" type="xml">
3864+ <form string="Mode">
3865+ <field name="name"/>
3866+ <field name="dx"/>
3867+ <field name="dy"/>
3868+ <field name="dz"/>
3869+ <field name="dd"/>
3870+ </form>
3871+ </field>
3872+ </record>
3873+
3874+ <record id="mrp_bom_component_mode_tree_view" model="ir.ui.view">
3875+ <field name="name">mrp.bom.component.mode.tree.view</field>
3876+ <field name="model">mrp.bom.component.mode</field>
3877+ <field name="type">tree</field>
3878+ <field name="arch" type="xml">
3879+ <tree string="Mode">
3880+ <field name="name" />
3881+ <field name="dx" />
3882+ <field name="dy" />
3883+ <field name="dz" />
3884+ <field name="dd" />
3885+ </tree>
3886+ </field>
3887+ </record>
3888+
3889+ <record model="ir.actions.act_window" id="mrp_bom_component_mode_all_action">
3890+ <field name="name">Bom Modes</field>
3891+ <field name="res_model">mrp.bom.component.mode</field>
3892+ <field name="view_mode">tree,form</field>
3893+ <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_tree_view"/>
3894+ </record>
3895+ <record model="ir.actions.act_window.view" id="mrp_bom_component_mode_tree_action">
3896+ <field name="sequence" eval="1"/>
3897+ <field name="view_mode">tree</field>
3898+ <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_tree_view"/>
3899+ <field name="act_window_id" ref="mrp_bom_component_mode_all_action"/>
3900+ </record>
3901+ <record model="ir.actions.act_window.view" id="mrp_bom_component_mode_form_action">
3902+ <field name="sequence" eval="2"/>
3903+ <field name="view_mode">form</field>
3904+ <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_form_view"/>
3905+ <field name="act_window_id" ref="mrp_bom_component_mode_all_action"/>
3906+ </record>
3907+ <menuitem action="mrp_bom_component_mode_all_action" id="menu_mrp_bom_component_mode_all_action" parent="mrp.menu_mrp_configuration"/>
3908+
3909+ </data>
3910+</openerp>
3911
3912=== added file 'asperience_configurator_mrp/mrp_workcenter.py'
3913--- asperience_configurator_mrp/mrp_workcenter.py 1970-01-01 00:00:00 +0000
3914+++ asperience_configurator_mrp/mrp_workcenter.py 2017-12-01 14:57:12 +0000
3915@@ -0,0 +1,130 @@
3916+# -*- encoding: utf-8 -*-
3917+##############################################################################
3918+#
3919+# OpenERP, Open Source Management Solution
3920+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
3921+# All Rights Reserved
3922+#
3923+# This program is free software: you can redistribute it and/or modify
3924+# it under the terms of the GNU General Public License as published by
3925+# the Free Software Foundation, either version 3 of the License, or
3926+# (at your option) any later version.
3927+#
3928+# This program is distributed in the hope that it will be useful,
3929+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3930+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3931+# GNU General Public License for more details.
3932+#
3933+# You should have received a copy of the GNU General Public License
3934+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3935+#
3936+##############################################################################
3937+from openerp.osv import fields,osv
3938+from openerp.tools.translate import _
3939+#import openerp.netsvc
3940+
3941+class mrp_workcenter_technology(osv.osv):
3942+ _name = 'mrp.workcenter.technology'
3943+ _columns = {
3944+ 'name': fields.char('Description', size=256, required=True),
3945+ }
3946+ _defaults = {
3947+ }
3948+mrp_workcenter_technology()
3949+
3950+class mrp_workcenter(osv.osv):
3951+ _inherit = 'mrp.workcenter'
3952+
3953+ def _get_type(self, cr, uid, ids, field_name, arg, context={}):
3954+ res = {}
3955+ for id in ids:
3956+ res[id] = {'type_re': '', 'type_pc': '', 'type_cc': ''}
3957+ for workcenter in self.browse(cr, uid, ids):
3958+ if workcenter.type_workcenter == 're':
3959+ res[id]['type_re'] = workcenter.type
3960+ elif workcenter.type_workcenter == 'pc':
3961+ res[id]['type_pc'] = workcenter.type
3962+ elif workcenter.type_workcenter == 'cc':
3963+ res[id]['type_cc'] = workcenter.type
3964+ return res
3965+
3966+ def _set_type(self, cr, uid, ids, name, value, arg, context):
3967+ if not value:
3968+ return False
3969+ if isinstance(ids, (int, long)):
3970+ ids = [ids]
3971+ for workcenter in self.browse(cr, uid, ids, context):
3972+ self.write(cr, uid, ids, {'type': value})
3973+ return True
3974+
3975+ def onchange_type(self, cr, uid, id, type=''):
3976+ res = {'value':{'type': type}}
3977+ return res
3978+
3979+ def onchange_type_workcenter(self, cr, uid, id, type_workcenter):
3980+ res = {'value':{'type_re': '','type_pc': '', 'type_cc': '', 'type': ''}}
3981+ if type_workcenter == 're' or type_workcenter == 'pc':
3982+ res['value']['type_re'] = 'machine'
3983+ elif type_workcenter == 'cc':
3984+ res['value']['type_re'] = 'machine_hr'
3985+ res['value']['type'] = res['value']['type_re']
3986+ return res
3987+
3988+ _columns = {
3989+ 'sequence': fields.integer('Sequence'),
3990+ 'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool'),('machine_hr','Machine and HR'),('line','Line'),('energy','Energy')], 'Type', required=True),
3991+ 'type_re': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('tool',_('Tool')),('energy',_('Energy'))],
3992+ multi="type",method=True, store=False, type='selection', string='Type'),
3993+ 'type_pc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('machine_hr',_('Machine and HR')),('line',_('Line'))],
3994+ multi="type",method=True, store=False, type='selection', string='Type'),
3995+ 'type_cc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine_hr',_('Machine and HR')),('line',_('Line'))],
3996+ multi="type",method=True, store=False, type='selection', string='Type'),
3997+ 'type_workcenter': fields.selection([('re',_('Elementary resource')),('pc',_('Work center')),('cc',_('Work line'))], 'Type workcenter', required=True, size=2),
3998+ 'scheduling': fields.selection([('machine','Machine'),('hr','Human Resource'),('machine_hr','Machine and HR'),('pg','The greatest')], 'Scheduling'),
3999+ 'parent_id': fields.many2one('mrp.workcenter', 'Parent'),
4000+ 'child_ids': fields.one2many('mrp.workcenter', 'parent_id','Childs'),
4001+ 'technology': fields.many2one('mrp.workcenter.technology', 'Technology'),
4002+ 'warehouse_id': fields.many2one('stock.warehouse', 'Sector', required=True),
4003+ 'property_ids': fields.many2many('mrp.property', 'mrp_workcenter_property_rel','workcenter_id', 'property_id', 'Properties'),
4004+ #A redƩfinir
4005+ 'external': fields.boolean('External workcenter'),
4006+ 'fixed_capacity': fields.boolean('Fixed capacity'),
4007+ #'capacity_qty' : fields.float('Capacity'),
4008+ 'critical': fields.boolean('Critical'),
4009+ 'finite_capacity': fields.boolean('Finite Capacity'),
4010+ 'finite_capacity_qty' : fields.float('Finite Capacity Qty'),
4011+ }
4012+ _defaults = {
4013+ 'sequence': lambda *a: 0,
4014+ 'time_start': lambda *a: 0,
4015+ 'time_stop': lambda *a: 0,
4016+ 'time_cycle': lambda *a: 0,
4017+ 'type_workcenter': lambda *a: 'pc',
4018+ }
4019+
4020+ def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=80):
4021+ print "name:",name
4022+ print "args:",args
4023+ print "operator:",operator
4024+ print "context:",context
4025+ print "limit:",limit
4026+ if args:
4027+ if args[0][0] == 'type':
4028+ for val in args[0][2]:
4029+ if val:
4030+ if val in ['line', 'machine_hr']:
4031+ args = [('type', '=', 'line')]
4032+ break
4033+ elif val == 'machine':
4034+ args = [('type', 'in', ['line','machine_hr','machine'])]
4035+ break
4036+ elif val in ['energy', 'hr', 'tool']:
4037+ args = [('type', 'in', ['line','machine_hr','machine','hr'])]
4038+ break
4039+
4040+ print "args:",args
4041+ return super(mrp_workcenter, self).name_search(cr, uid, name, args=args, operator=operator, context=context, limit=limit)
4042+
4043+mrp_workcenter()
4044+
4045+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4046\ No newline at end of file
4047
4048=== added file 'asperience_configurator_mrp/mrp_workflow.xml'
4049--- asperience_configurator_mrp/mrp_workflow.xml 1970-01-01 00:00:00 +0000
4050+++ asperience_configurator_mrp/mrp_workflow.xml 2017-12-01 14:57:12 +0000
4051@@ -0,0 +1,26 @@
4052+<?xml version="1.0" encoding="utf-8"?>
4053+<openerp>
4054+ <data>
4055+ <record id="mrp.prod_act_ready" model="workflow.activity">
4056+ <field name="wkf_id" ref="mrp.wkf_prod"/>
4057+ <field name="name">ready</field>
4058+ <field name="kind">function</field>
4059+ <field name="action">action_confirm() and action_ready()</field>
4060+ </record>
4061+
4062+ <record id="mrp.prod_act_cancel" model="workflow.activity">
4063+ <field name="wkf_id" ref="mrp.wkf_prod"/>
4064+ <field name="flow_stop">False</field>
4065+ <field name="name">cancel</field>
4066+ <field name="kind">function</field>
4067+ <field name="action">action_cancel()</field>
4068+ </record>
4069+
4070+ <record id="prod_trans_cancel_draft" model="workflow.transition">
4071+ <field name="act_from" ref="mrp.prod_act_cancel"/>
4072+ <field name="act_to" ref="mrp.prod_act_draft"/>
4073+ <field name="signal">button_draft</field>
4074+ </record>
4075+
4076+ </data>
4077+</openerp>
4078
4079=== added file 'asperience_configurator_mrp/procurement.py'
4080--- asperience_configurator_mrp/procurement.py 1970-01-01 00:00:00 +0000
4081+++ asperience_configurator_mrp/procurement.py 2017-12-01 14:57:12 +0000
4082@@ -0,0 +1,193 @@
4083+# -*- encoding: utf-8 -*-
4084+##############################################################################
4085+#
4086+# OpenERP, Open Source Management Solution
4087+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
4088+# All Rights Reserved
4089+#
4090+# This program is free software: you can redistribute it and/or modify
4091+# it under the terms of the GNU General Public License as published by
4092+# the Free Software Foundation, either version 3 of the License, or
4093+# (at your option) any later version.
4094+#
4095+# This program is distributed in the hope that it will be useful,
4096+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4097+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4098+# GNU General Public License for more details.
4099+#
4100+# You should have received a copy of the GNU General Public License
4101+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4102+#
4103+##############################################################################
4104+from openerp.osv import fields,osv
4105+#import openerp.netsvc
4106+#import time
4107+#import datetime
4108+#from mx import DateTime
4109+#from openerp.tools.translate import _
4110+#from openerp.tools import ustr
4111+
4112+class procurement_order(osv.osv):
4113+ _inherit = 'procurement.order'
4114+
4115+ def _size(self, cr, uid, ids, field_name, arg, context):
4116+ res = {}
4117+ for proc in self.browse(cr, uid, ids):
4118+ res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 ,'diameter': 0.0}
4119+ if proc.product_id:
4120+ res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
4121+ res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
4122+ res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
4123+ res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
4124+ return res
4125+
4126+ def get_production(self, cr, uid, ids, context={}):
4127+ production_obj = self.pool.get('mrp.production')
4128+ move_obj = self.pool.get('stock.move')
4129+ result = {}
4130+ for procurement in self.browse(cr, uid, ids):
4131+ result[procurement.id] = False
4132+ if procurement.bom_id and procurement.bom_id.bom_type in ('cut'):
4133+ print "procurement.bom_id",procurement.bom_id,procurement.bom_id.bom_type
4134+ production_id = production_obj.search(cr,uid,[('bom_id','=',procurement.bom_id.id),('state','=','draft')])
4135+
4136+ if production_id:
4137+ result[procurement.id] = production_id[0]
4138+ self.write(cr,uid,procurement.id,{'production_id':result[procurement.id]})
4139+ move_obj.write(cr,uid,procurement.move_id.id,{'production_id':result[procurement.id]})
4140+
4141+# if procurement.move_id.prodlot_id:
4142+# print procurement.move_id.prodlot_id
4143+# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',procurement.move_id.prodlot_id.id),('production_id','!=',False),('production_id.state','=','confirmed')])
4144+# print move_ids
4145+# if move_ids:
4146+# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
4147+# result[procurement.id] = production_id
4148+# print "ok"
4149+# self.write(cr,uid,procurement.id,{'production_id':production_id})
4150+
4151+# property_ids = [i.id for i in procurement.property_ids]
4152+# property_ids.sort()
4153+# production_ids = production_obj.search(cr,uid,[('state','=','draft'),('product_id','=',procurement.product_id.id),('bom_id.bom_type','=','cut')])
4154+# if production_ids:
4155+# production_ptr = production_obj.browse(cr,uid,production_ids,context)
4156+# print "",production_ptr.name
4157+# print "",production_ptr.move_ids
4158+# result[procurement.id] =
4159+
4160+# if line_prodlot_id and line.bom_id.bom_type in ('cut'):
4161+# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',line_prodlot_id),('production_id','!=',False),('production_id.state','=','confirmed')])
4162+# if move_ids:
4163+# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
4164+ return result
4165+
4166+ def action_produce_assign_product(self, cr, uid, ids, context={}):
4167+ print "action_produce_assign_product nouveau"
4168+ wf_service = netsvc.LocalService("workflow")
4169+ move_obj = self.pool.get('stock.move')
4170+ produce_id = False
4171+ company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
4172+ result = {}
4173+ production_ids = self.get_production(cr,uid,ids,context)
4174+ for procurement in self.browse(cr, uid, ids):
4175+ res_id = procurement.move_id.id
4176+ loc_id = procurement.location_id.id
4177+ newdate = DateTime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - DateTime.RelativeDateTime(days=procurement.product_id.product_tmpl_id.produce_delay or 0.0)
4178+ newdate = newdate - DateTime.RelativeDateTime(days=company.manufacturing_lead)
4179+ print production_ids[procurement.id]
4180+ if production_ids[procurement.id]:
4181+ result[procurement.id] = production_ids[procurement.id]
4182+ else:
4183+# if not procurement.production_id:
4184+ result[procurement.id] = self.pool.get('mrp.production').create(cr, uid, {
4185+ 'origin': procurement.origin,
4186+ 'product_id': procurement.product_id.id,
4187+ 'product_qty': procurement.product_qty,
4188+ 'product_uom': procurement.product_uom.id,
4189+ 'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
4190+ 'product_uos': procurement.product_uos and procurement.product_uos.id or False,
4191+ 'location_src_id': procurement.location_id.id,
4192+ 'location_dest_id': procurement.move_id.location_id.id,
4193+ 'bom_id': procurement.bom_id and procurement.bom_id.id or False,
4194+ 'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
4195+ 'move_prod_id': res_id,
4196+ 'procurement_id': procurement.id,
4197+ 'specific_production': procurement.specific_production,
4198+ 'note_production': procurement.note_production,
4199+ 'size_x_specific': procurement.size_x_specific,
4200+ 'size_y_specific': procurement.size_y_specific,
4201+ 'size_z_specific': procurement.size_z_specific,
4202+ 'diameter_specific': procurement.diameter_specific,
4203+ 'size_x_specific_delta': procurement.size_x_specific_delta,
4204+ 'size_y_specific_delta': procurement.size_y_specific_delta,
4205+ 'size_z_specific_delta': procurement.size_z_specific_delta,
4206+ 'diameter_specific_delta': procurement.diameter_specific_delta,
4207+ })
4208+# else:
4209+# result[procurement.id] = procurement.production_id.id
4210+ produce_id = result[procurement.id]
4211+ self.write(cr, uid, [procurement.id], {'state':'running', 'production_id':result[procurement.id]})
4212+ childs = [line.id for line in procurement.procurement_line]
4213+ #self.action_produce_assign_product(cr, uid, childs)
4214+ for child in childs:
4215+ wf_service.trg_validate(uid, 'procurement.order',child, 'button_confirm', cr)
4216+
4217+# bom_result = self.pool.get('mrp.production').action_compute(cr, uid,[result[procurement.id]], context)
4218+
4219+ #================================================
4220+ # Confirmation des productions OU Ajout
4221+ #================================================
4222+ if not procurement.bom_id or not procurement.bom_id.bom_type in ('cut'):
4223+ wf_service.trg_validate(uid, 'mrp.production', result[procurement.id], 'button_confirm', cr)
4224+ else:
4225+ move_obj.write(cr,uid,procurement.move_id.id,{'production_id':result[procurement.id]})
4226+ procurement = self.browse(cr,uid,procurement.id,context)
4227+ print "okokok"
4228+ #===================================================================
4229+ # transfere de la sortie des procurement enfant dans l'entrƩe de la production
4230+ #===================================================================
4231+ moves = []
4232+ for line in procurement.procurement_line:
4233+ print "line",line,line.production_id
4234+ print "line",line,line.purchase_id
4235+ if line.production_id:
4236+ moves.extend([i.id for i in line.production_id.move_created_ids])
4237+ for i in moves:
4238+ if i not in [j.id for j in self.pool.get('mrp.production').browse(cr,uid,result[procurement.id]).move_lines]:
4239+ self.pool.get('mrp.production').write(cr, uid, result[procurement.id], {'move_lines': [(4,i)]})
4240+ return produce_id
4241+
4242+ _columns = {
4243+ 'procurement_id': fields.many2one('procurement.order', 'Procurement Ref', ondelete='cascade', select=True, readonly=True, states={'draft':[('readonly',False)]}),
4244+ 'procurement_line': fields.one2many('procurement.order', 'procurement_id', 'Procurement Lines', readonly=True, states={'draft': [('readonly', False)]}),
4245+ 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_procurement_group_property_rel','procurement_id', 'group_id', 'Product Property Group Rel '),
4246+ 'parent_option_id': fields.many2one('product.links', 'Parent Option'),
4247+ 'option_ids': fields.many2many('product.links', 'mrp_procurement_options_rel','procurement_id', 'links_id', 'Option'),
4248+ 'specific_production':fields.boolean('Specific Production'),
4249+ 'note_production':fields.text('Production Note'),
4250+ 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
4251+ 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
4252+ 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
4253+ 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
4254+ 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
4255+ 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
4256+ 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
4257+ 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
4258+ 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
4259+ 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
4260+ 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
4261+ 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
4262+ 'production_id': fields.many2one('mrp.production', 'Production', select=True),
4263+ }
4264+ _defaults = {
4265+ }
4266+ _order = 'id desc'
4267+
4268+ def check_wkf(self, cr, uid, ids, context={}):
4269+ wf_service = netsvc.LocalService("workflow")
4270+ for i in ids :
4271+ wf_service.trg_write(uid, 'procurement.order', i, cr)
4272+ return True
4273+
4274+procurement_order()
4275+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4276\ No newline at end of file
4277
4278=== added file 'asperience_configurator_mrp/procurement_view.xml'
4279--- asperience_configurator_mrp/procurement_view.xml 1970-01-01 00:00:00 +0000
4280+++ asperience_configurator_mrp/procurement_view.xml 2017-12-01 14:57:12 +0000
4281@@ -0,0 +1,155 @@
4282+<?xml version="1.0" encoding="utf-8"?>
4283+<openerp>
4284+ <data>
4285+
4286+ ###################################### PROCUREMENT #######################################
4287+ <record id="mrp_procurement_tree_view_asperience_mrp" model="ir.ui.view">
4288+ <field name="name">procurement.order.tree.asperience.mrp</field>
4289+ <field name="model">procurement.order</field>
4290+ <field name="inherit_id" ref="procurement.procurement_tree_view"/>
4291+ <field name="arch" type="xml">
4292+ <field name="state" position="after">
4293+ <field name="production_id"/>
4294+ <button name="button_confirm" states="draft" string="Confirm"/>
4295+ <button name="button_check" states="confirmed" string="Run procurement"/>
4296+ </field>
4297+ </field>
4298+ </record>
4299+
4300+ <record id="mrp_procurement_form_view_asperience_mrp" model="ir.ui.view">
4301+ <field name="name">procurement.order.form.asperience.mrp</field>
4302+ <field name="model">procurement.order</field>
4303+ <field name="type">form</field>
4304+ <field name="inherit_id" ref="procurement.procurement_form_view"/>
4305+ <field name="arch" type="xml">
4306+ <page string="Notes" position="after">
4307+ <page string="Advanced informations">
4308+ <separator string="Hierarchy" colspan="4" />
4309+ <field name="procurement_id" />
4310+ <field name="procurement_line" nolabel="1" colspan="4" widget="one2many_list"/>
4311+ <separator string="Properties" colspan="4" />
4312+ <field name="parent_option_id" colspan="4"/>
4313+ <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
4314+ <field name="group_property_ids" nolabel="1" colspan="4" widget="one2many_list"/>
4315+ <separator string="Production" colspan="4" />
4316+ <field name="production_id" />
4317+ <field name='specific_production' colspan="4" />
4318+ <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
4319+ <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
4320+ <group colspan="2">
4321+ <field name='size_x' colspan="2"/>
4322+ <field name='size_y' colspan="2"/>
4323+ <field name='size_z' colspan="2"/>
4324+ <field name='diameter' colspan="2"/>
4325+ </group>
4326+ <group colspan="2">
4327+ <label string='-' colspan="4"/>
4328+ <label string='-' colspan="4"/>
4329+ <label string='-' colspan="4"/>
4330+ <label string='-' colspan="4"/>
4331+ </group>
4332+ <group colspan="2">
4333+ <field name='size_x_specific_delta' colspan="2" />
4334+ <field name='size_y_specific_delta' colspan="2" />
4335+ <field name='size_z_specific_delta' colspan="2" />
4336+ <field name='diameter_specific_delta' colspan="2"/>
4337+ </group>
4338+ <group colspan="2">
4339+ <label string='=' colspan="4"/>
4340+ <label string='=' colspan="4"/>
4341+ <label string='=' colspan="4"/>
4342+ <label string='=' colspan="4"/>
4343+ </group>
4344+ <group colspan="2">
4345+ <field name='size_x_specific' colspan="2" />
4346+ <field name='size_y_specific' colspan="2" />
4347+ <field name='size_z_specific' colspan="2" />
4348+ <field name='diameter_specific' colspan="2" />
4349+ </group>
4350+ </group>
4351+ </page>
4352+ </page>
4353+ <field name="state" position="before" >
4354+ <button name="check_wkf" string="Check" type="object" />
4355+ </field>
4356+ </field>
4357+ </record>
4358+
4359+ <record id="procurement.do_view_procurements" model="ir.actions.act_window">
4360+ <field name="name">Group's Procurements</field>
4361+ <field name="res_model">procurement.order</field>
4362+ <field name="view_type">form</field>
4363+ <field name="view_mode">tree,form</field>
4364+ <field name="domain">[('group_id','=',active_id),('procurement_id','=',False)]</field>
4365+ </record>
4366+
4367+ <record id="procurement.procurement_action5" model="ir.actions.act_window">
4368+ <field name="name">Procurement Exceptions</field>
4369+ <field name="type">ir.actions.act_window</field>
4370+ <field name="res_model">procurement.order</field>
4371+ <field name="view_type">form</field>
4372+ <field name="view_mode">tree,form</field>
4373+ <field name="domain">[('state','=','exception'),('procurement_id','=',False)]</field>
4374+ </record>
4375+
4376+ <!--
4377+ <record id="mrp_procurement_form_view" model="ir.ui.view">
4378+ <field name="name">procurement.order.form</field>
4379+ <field name="model">procurement.order</field>
4380+ <field name="type">form</field>
4381+ <field name="arch" type="xml">
4382+ <form string="Procurement">
4383+ <group col="2" colspan="2">
4384+ <separator colspan="2" string="References"/>
4385+ <field name="name" select="1" string="Procurement Reason"/>
4386+ <field name="origin" select="2"/>
4387+ </group>
4388+ <group col="2" colspan="2">
4389+ <separator colspan="2" string="Planification"/>
4390+ <field name="date_planned" select="1"/>
4391+ <field name="procure_method" select="2"/>
4392+ <field name="priority" groups="base.group_extended"/>
4393+ </group>
4394+ <notebook colspan="4">
4395+ <page string="Procurement Details">
4396+ <separator colspan="4" string="Product &amp; Location"/>
4397+ <field name="product_id" select="1" on_change="onchange_product_id(product_id)"/>
4398+ <field name="location_id" select="2"/>
4399+ <field name="product_qty"/>
4400+ <field name="product_uom"/>
4401+
4402+ <field name="product_uos_qty" groups="product.group_uos"/>
4403+ <field name="product_uos" groups="product.group_uos"/>
4404+
4405+ <separator colspan="4" string="Status"/>
4406+ <field colspan="4" name="message" readonly="1"/>
4407+ <field name="state" readonly="1" select="2"/>
4408+ <group col="7" colspan="2">
4409+ <button name="button_confirm" states="draft" string="Confirm"/>
4410+ <button name="button_restart" states="exception" string="Retry"/>
4411+ <button name="button_cancel" states="draft,exception,waiting" string="Cancel"/>
4412+ <button name="button_check" states="confirmed" string="Run procurement"/>
4413+ </group>
4414+ </page>
4415+ <page string="Extra Information">
4416+ <separator colspan="4" string="Details"/>
4417+ <field name="bom_id" select="2" domain="[('product_id','=',product_id),('bom_id','=',False)]"/>
4418+ <field name="move_id" groups="base.group_extended"/>
4419+ <field name="date_close" select="2"/>
4420+ <field name="close_move" groups="base.group_extended"/>
4421+ <field name="purchase_id"/>
4422+ <separator colspan="4" string="Properties"/>
4423+ <field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/>
4424+ </page>
4425+ <page string="Notes">
4426+ <separator colspan="4" string="Note" />
4427+ <field name="note" colspan="4" nolabel="1"/>
4428+ </page>
4429+ </notebook>
4430+ </form>
4431+ </field>
4432+ </record>
4433+ -->
4434+
4435+ </data>
4436+</openerp>
4437
4438=== added file 'asperience_configurator_mrp/product.py'
4439--- asperience_configurator_mrp/product.py 1970-01-01 00:00:00 +0000
4440+++ asperience_configurator_mrp/product.py 2017-12-01 14:57:12 +0000
4441@@ -0,0 +1,375 @@
4442+# -*- encoding: utf-8 -*-
4443+##############################################################################
4444+#
4445+# OpenERP, Open Source Management Solution
4446+# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
4447+# All Rights Reserved
4448+#
4449+# This program is free software: you can redistribute it and/or modify
4450+# it under the terms of the GNU General Public License as published by
4451+# the Free Software Foundation, either version 3 of the License, or
4452+# (at your option) any later version.
4453+#
4454+# This program is distributed in the hope that it will be useful,
4455+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4456+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4457+# GNU General Public License for more details.
4458+#
4459+# You should have received a copy of the GNU General Public License
4460+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4461+#
4462+##############################################################################
4463+#import openerp.netsvc
4464+from openerp.osv import fields, osv
4465+#from openerp.tools import ustr
4466+#from openerp.tools.translate import _
4467+#import datetime
4468+#from sets import *
4469+
4470+def name_serial(x, y, z, p, f, d):
4471+
4472+ lote = '_'
4473+ if (f == 'quadrangular'):
4474+ lote = (str(x) + 'x' + str(y) + 'x' + str(z) + '_' + str(p))
4475+ elif (f == 'cylindrical'):
4476+ lote = (str(d) + 'x' + str(z) + '_' + str(p))
4477+
4478+ return lote
4479+
4480+def compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter):
4481+ resu = {}
4482+
4483+ size_x = size_x or 0
4484+ size_y = size_y or 0
4485+ size_z = size_z or 0
4486+ density = density or 1
4487+ diameter = diameter or 0
4488+
4489+ weight = 0
4490+ if shape == 'quadrangular':
4491+ weight = ((size_x * size_y * size_z) * density * factor2 * (math.pow(factor3, 3))) / (factor1 * (math.pow(factor4, 3)))
4492+ diameter = 0
4493+ volume = size_x * size_y * size_z
4494+ elif shape == 'cylindrical':
4495+ radius = diameter / 2.0
4496+ weight = ((math.pow(radius, 2) * math.pi * size_z) * density * factor2 * (math.pow(factor3, 3))) / (factor1 * (math.pow(factor4, 3)))
4497+ volume = math.pow(radius, 2) * math.pi * size_z
4498+ size_x = 0
4499+ size_y = 0
4500+ else:
4501+ weight = 0
4502+ volume = 0
4503+ size_x = 0
4504+ size_y = 0
4505+ size_z = 0
4506+
4507+
4508+ v = { 'weight':weight,
4509+ 'volume':volume,
4510+ 'size_x':size_x,
4511+ 'size_y':size_y,
4512+ 'size_z':size_z,
4513+ 'diameter':diameter,
4514+ 'density':density,
4515+ }
4516+ return v
4517+
4518+class product_template(osv.osv):
4519+ _inherit ='product.template'
4520+ _columns = {
4521+ 'size_x_tmpl': fields.float('Width', digits=(16, 5)),
4522+ 'size_y_tmpl': fields.float('Length', digits=(16, 5)),
4523+ 'size_z_tmpl': fields.float('Thickness', digits=(16, 5)),
4524+ 'density_tmpl': fields.float('Density', digits=(16, 5), help='Density unit= (uom of weight/(uom of size)^3)'),
4525+ 'shape' : fields.selection([('quadrangular', 'Quadrangular'), ('cylindrical', 'Cylindrical'), ('other', 'Other')], 'Shape', help="Weight Formula for Quadrangular = width*length*thickness*density \n Weight Formula for Cylindrical= (diameter/2)Ā²*pi*thickness*density", required=True),
4526+ 'diameter_tmpl': fields.float('Diameter', digits=(16, 5)),
4527+ 'uom_d_size' : fields.many2one('product.uom', 'Size density Uom Ā³', help="Default united of measure density used for operations size to cube", required=True, readonly=True),
4528+ 'uom_d_weight': fields.many2one('product.uom', 'Weight density Uom', help="Default united of measure density used for operations weight", required=True, readonly=True),
4529+ 'uom_s_size' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size", required=True, readonly=True),
4530+ }
4531+ def _get_uom_d_size(self, cr, uid, *args):
4532+ return self.pool.get('ir.property').get(cr, uid, 'uom_d_size', 'product.template')
4533+
4534+ def _get_uom_d_weight(self, cr, uid, *args):
4535+ return self.pool.get('ir.property').get(cr, uid, 'uom_d_weight', 'product.template')
4536+
4537+ def _get_uom_s_size(self, cr, uid, *args):
4538+ return self.pool.get('ir.property').get(cr, uid, 'uom_s_size', 'product.template')
4539+
4540+ def compute_weight(self, cr, uid, id, uom_d_weight, uom_id, uom_d_size, uom_s_size, size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl):
4541+ value = {}
4542+
4543+ if (not uom_id) or (not uom_d_weight) or(not uom_d_size) or (not uom_s_size):
4544+ return 0
4545+ if (shape):
4546+ factor1 = self.pool.get('product.uom').browse(cr, uid, uom_d_weight, context='').factor
4547+ factor2 = self.pool.get('product.uom').browse(cr, uid, uom_id, context='').factor
4548+ factor3 = self.pool.get('product.uom').browse(cr, uid, uom_d_size, context='').factor
4549+ factor4 = self.pool.get('product.uom').browse(cr, uid, uom_s_size, context='').factor
4550+ return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x or size_x_tmpl, size_y or size_y_tmpl, size_z or size_z_tmpl, shape, density, diameter or diameter_tmpl)}
4551+
4552+ _defaults = {
4553+ 'size_x_tmpl': lambda * a: 0.0,
4554+ 'size_y_tmpl': lambda * a: 0.0,
4555+ 'size_z_tmpl': lambda * a: 0.0,
4556+ 'density_tmpl': lambda * a: 0.0,
4557+ 'shape': lambda * a: 'other',
4558+ 'diameter_tmpl': lambda * a: 0.0,
4559+ 'uom_d_size': _get_uom_d_size,
4560+ 'uom_d_weight' : _get_uom_d_weight,
4561+ 'uom_s_size' : _get_uom_s_size,
4562+ }
4563+product_template()
4564+
4565+class product_product(osv.osv):
4566+ _inherit ='product.product'
4567
4568+ def generate_bom(self,cr,uid,ids,context={}):
4569+ print "generate_bom",ids,context
4570+ pre = "generate_bom "
4571+ result = {}
4572+ if "product_qty" not in context :
4573+ context["product_qty"]=1
4574+ if "options" not in context :
4575+ context["options"]=[]
4576+ if "rec" not in context :
4577+ context["rec"]=0
4578+ if "bom_parent" not in context :
4579+ context["bom_parent"]=[]
4580+ product_qty = context["product_qty"]
4581+
4582+ for product in self.browse(cr,uid,ids,context):
4583+ print pre+"product ",product.name
4584+ result[product.id] = False
4585+ option_name = ""
4586+ bom_components_parent = []
4587+ bom_components = []
4588+
4589+ if product.bom_ids and context["options"]:
4590+ self.generate_bom(cr,uid,[product.id])
4591+ context["bom_parent"] = self.pool.get('mrp.bom')._bom_find(cr, uid, product.id, product.uom_id.id, [], [])
4592+ bom_components_parent = [(0, 0, {'qty':product_qty, 'bom_id':context["bom_parent"]})]
4593+ if context["options"]:
4594+ option_name = "."
4595+ option_name += ".".join([i.shortcut for i in self.pool.get('product.type.property.option').browse(cr,uid,context["options"])])
4596+ property_ids = [],
4597+ # A MODIFIER
4598+ self.pool.get('product.type.property.option').write(cr,uid,context["options"],{'execution_filter':True})
4599+ # /A MODIFIER
4600+ type_group_ids = [(6, 1, context["options"])]
4601+ if not context["bom_parent"]:
4602+ raise
4603+ else:
4604+ # Probable bug
4605+# bom_components = [(0, 0, {'bom_id':context["bom_parent"]})]
4606+ bom_components_parent = [(0, 0, {'qty':context["product_qty"], 'bom_id':context["bom_parent"]})]
4607+ type = 'phantom'
4608+ else:
4609+ property_ids = [(6, 1, [i.id for i in product.bom_property_ids])],
4610+ type_group_ids = [(6, 1, [i.id for i in product.bom_type_group_ids])],
4611+ type = 'normal'
4612+ vals ={
4613+ 'name': product.code+" ["+option_name+"("+"-".join([i.code for i in product.bom_property_ids])+")]",
4614+ 'code': product.code,
4615+ 'active': True,
4616+ 'type': 'normal',
4617+ 'date_start': datetime.datetime.now(),
4618+ 'product_id': product.id,
4619+ 'product_uos_qty': product_qty,
4620+ 'product_uos': product.uos_id.id,
4621+ 'product_qty': product_qty,
4622+ 'product_uom': product.uom_id.id,
4623+ 'product_rounding': 1,
4624+ 'product_efficiency': 1,
4625+ 'shape': product.shape,
4626+ 'property_ids': property_ids,
4627+ 'type_group_ids': type_group_ids,
4628+ 'size_x': product.size_x,
4629+ 'size_y': product.size_y,
4630+ 'size_z': product.size_z,
4631+ 'density': product.density,
4632+ 'shape' : product.shape,
4633+ 'diameter' : product.diameter,
4634+ 'weight': product.weight,
4635+ 'bom_components': bom_components,
4636+ 'bom_components_parent' :bom_components_parent,
4637+ 'type': type,
4638+ }
4639+ result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
4640+ ########################################################################################################################################
4641+ #INTEGRATION DES LIGNES EN bundle_base
4642+ bom_components = []
4643+ print pre+"bom_components avant",bom_components
4644+ if not context["bom_parent"]:
4645+ for i in product.linked_product_ids:
4646+ if not i.used :
4647+ continue
4648+ elif i.link_type in ('bundle_base') :
4649+ if i.product_id.id == product.id :
4650+ s = result[product.id]
4651+ else:
4652+ s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
4653+ else:
4654+ continue
4655+ if s not in bom_components:
4656+ bom_components.append(s)
4657+ for i in product.linked_product_tmpl_ids:
4658+ if not i.used :
4659+ continue
4660+ elif i.link_type in ('bundle_base') :
4661+ if i.product_id.id == product.id :
4662+ s = result[product.id]
4663+ else:
4664+ s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
4665+ else:
4666+ continue
4667+ if s not in bom_components:
4668+ bom_components.append(s)
4669+ print pre+"bom_components apres bundle",bom_components
4670+ ########################################################################################################################################
4671+ ########################################################################################################################################
4672+ #CREATION DES BOM OPTION
4673+ if not context["bom_parent"]:
4674+ nb = 0
4675+ for i in product.linked_product_ids:
4676+# if nb == 10 : break
4677+ nb+=1
4678+ s = None
4679+ if not i.used :
4680+ continue
4681+ if i.product_id.id == product.id :
4682+ if context["options"] and i.type_group.id in context["options"] :
4683+ s = result[product.id]
4684+ if not s and i.link_type in ('option') :
4685+ s = self.pool.get('mrp.bom')._bom_find(cr, uid, i.product_id.id, i.product_id.uom_id.id, [], i.type_group and [i.type_group.id] or [])
4686+ else:
4687+ continue
4688+ if s not in bom_components:
4689+ bom_components.append(s)
4690+ nb = 0
4691+ for i in product.linked_product_tmpl_ids:
4692+# if nb == 10 : break
4693+ nb+=1
4694+ s = None
4695+ if not i.used :
4696+ continue
4697+ if i.product_id.id == product.id :
4698+ if context["options"] and i.type_group.id in context["options"] :
4699+ s = result[product.id]
4700+ if not s and i.link_type in ('option') :
4701+ s = self.pool.get('mrp.bom')._bom_find(cr, uid, i.product_id.id, i.product_id.uom_id.id, [], i.type_group and [i.type_group.id] or [])
4702+ else:
4703+ continue
4704+ if s not in bom_components:
4705+ bom_components.append(s)
4706+ # else:
4707+ # bom_lines_multi.append(context["bom_parent"])
4708+ print pre+"bom_components apres options",bom_components
4709+ if bom_components:
4710+ for i in bom_components:
4711+ vals = {
4712+ "bom_id":result[product.id],
4713+ "component_id":i,
4714+ "qty":product_qty,
4715+ }
4716+ self.pool.get('mrp.bom.component.rel').create(cr,uid,vals)
4717+# self.pool.get('mrp.bom').write(cr,uid,result[product.id],{'bom_components':[(6,1,bom_components)]})
4718+ ########################################################################################################################################
4719+
4720+ #
4721+ # match_criterias_field = ['product_id','product_uos_qty','product_uos','product_qty','product_uom','product_rounding','product_efficiency','shape','size_x','size_y','size_z','density','shape','diameter','weight']
4722+ # match_criterias = [(a,'=',vals[a]) for a in match_criterias_field]
4723+ # match_ids = self.pool.get('mrp.bom').search(cr,uid,match_criterias)
4724+ # for match_bom in self.pool.get('mrp.bom').browse(cr,uid,match_ids):
4725+ # if not Set([i.id for i in match_bom.property_ids]) == Set(vals['property_ids'][0][2]) :
4726+ # match_ids.remove(match_bom.id)
4727+ # continue
4728+ # if not Set([i.id for i in match_bom.type_group_ids]) == Set(vals['type_group_ids'][0][2]) :
4729+ # match_ids.remove(match_bom.id)
4730+ # continue
4731+ # if match_ids :
4732+ # result[product.id] = match_ids[0]
4733+ # elif context["options"] :
4734+ # result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
4735+ # else:
4736+ # result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
4737+ # bom_option_ids = []
4738+ # for i in product.linked_product_ids:
4739+ # if not i.used :
4740+ # continue
4741+ # # if i.product_id.id == product.id :
4742+ # # continue
4743+ # if i.link_type in ('option') :
4744+ # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":i.type_group and [i.type_group.id] or []})[i.product_id.id]
4745+ # elif i.link_type in ('bundle_base') :
4746+ # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
4747+ # else:
4748+ # continue
4749+ # if s not in bom_option_ids:
4750+ # bom_option_ids.append(s)
4751+ # for i in product.linked_product_tmpl_ids:
4752+ # if not i.used :
4753+ # continue
4754+ # # if i.product_id.id == product.id :
4755+ # # continue
4756+ # if i.link_type in ('option') :
4757+ # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":i.type_group and [i.type_group.id] or []})[i.product_id.id]
4758+ # elif i.link_type in ('bundle_base') :
4759+ # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
4760+ # else:
4761+ # continue
4762+ # if s not in bom_option_ids:
4763+ # bom_option_ids.append(s)
4764+ # if bom_option_ids:
4765+ # vals ={
4766+ # 'bom_components': [(6, 1, bom_option_ids)],
4767+ # }
4768+ # self.pool.get('mrp.bom').write(cr,uid,result[product.id],vals)
4769+ #
4770+ # vals = {
4771+ # 'bom' : True,
4772+ # }
4773+ # self.write(cr,uid,ids,vals)
4774+ if context['rec']==0 :
4775+ return True
4776+ cr.commit()
4777+ return result
4778+
4779+ _columns = {
4780+ #Dimensions
4781+ 'size_x': fields.float('Width'),
4782+ 'size_y': fields.float('Length'),
4783+ 'size_z': fields.float('Thickness'),
4784+ 'density': fields.float('Density', help='Density unit= (uom of weight/(uom of size)^3)'),
4785+ 'diameter' : fields.float('Diameter'),
4786+ #Production
4787+ 'bom': fields.boolean('BoM Generated'),
4788+ 'opp': fields.boolean('Rupture assembly'),
4789+ 'bom_ids': fields.one2many('mrp.bom', 'product_id', 'BoM'),
4790+ 'bom_sub_ids': fields.one2many('mrp.subproduct', 'product_id', 'Sub products'),
4791+ 'bom_type_group_ids': fields.many2many('product.type.property.option', 'product_product_group_option_rel', 'product_id','group_id', 'Bom (GOP or GOO)'),
4792+ 'bom_property_ids': fields.many2many('mrp.property', 'product_product_property_rel', 'product_id','property_id', 'Bom Properties'),
4793+ }
4794+ _defaults = {
4795+ 'bom': lambda *a: False,
4796+ 'size_x': lambda * a: 0.0,
4797+ 'size_y': lambda * a: 0.0,
4798+ 'size_z': lambda * a: 0.0,
4799+ 'density': lambda * a: 0.0,
4800+ 'diameter': lambda * a: 0.0,
4801+ }
4802+
4803+ def compute_weight(self, cr, uid, id, uom_d_weight, uom_id, uom_d_size, uom_s_size, size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl):
4804+ value = {}
4805+
4806+ if (not uom_id) or (not uom_d_weight) or(not uom_d_size) or (not uom_s_size):
4807+ return 0
4808+ if (shape):
4809+ factor1 = self.pool.get('product.uom').browse(cr, uid, uom_d_weight, context='').factor
4810+ factor2 = self.pool.get('product.uom').browse(cr, uid, uom_id, context='').factor
4811+ factor3 = self.pool.get('product.uom').browse(cr, uid, uom_d_size, context='').factor
4812+ factor4 = self.pool.get('product.uom').browse(cr, uid, uom_s_size, context='').factor
4813+ return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x or size_x_tmpl, size_y or size_y_tmpl, size_z or size_z_tmpl, shape, density, diameter or diameter_tmpl)}
4814+
4815+product_product()
4816+
4817+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4818\ No newline at end of file
4819
4820=== added file 'asperience_configurator_mrp/product_view.xml'
4821--- asperience_configurator_mrp/product_view.xml 1970-01-01 00:00:00 +0000
4822+++ asperience_configurator_mrp/product_view.xml 2017-12-01 14:57:12 +0000
4823@@ -0,0 +1,207 @@
4824+<?xml version="1.0" encoding="utf-8"?>
4825+<openerp>
4826+ <data>
4827+ ######################################### Product variant ############################################
4828+ <record id="product_variant_form_view_asperience_mrp" model="ir.ui.view">
4829+ <field name="name">product.variant.form.asperience.mrp</field>
4830+ <field name="model">product.product</field>
4831+ <field name="inherit_id" ref="asperience_product_attributes.product_product_form_view_attributes_variant_1" />
4832+ <field name="arch" type="xml">
4833+ <field name="linked_product_ids" position="after" >
4834+ <button icon="gtk-ok" name="reinit_links" string="Reinit Links and Properties with Category" type="object" />
4835+ <field name="property_ids" colspan="4" nolabel="1" context="{'tree_view_ref':'asperience_configurator_mrp.product_property_tree','form_view_ref':'asperience_configurator_mrp.product_property_form'}"/>
4836+ <separator string="BOM"/>
4837+ <group col="6" colspan="4" string="Generate">
4838+ <button name="generate_bom" type="object" string="Generate BoM"/>
4839+ <field name="bom" readonly="1"/>
4840+ <field name="opp"/>
4841+ <field name="bom_type_group_ids" nolabel="1" colspan="6"/>
4842+ <field name="bom_property_ids" nolabel="1" colspan="6"/>
4843+ <field name="bom_ids" nolabel="1" colspan="6"/>
4844+ <field name="bom_sub_ids" nolabel="1" colspan="6" readonly="True"/>
4845+ </group>
4846+ </field>
4847+ </field>
4848+ </record>
4849+
4850+ ######################################### Product normal ############################################
4851+ <record id="product_product_normal_form_view_asperience_mrp" model="ir.ui.view">
4852+ <field name="name">product.normal.form.asperience.mrp</field>
4853+ <field name="model">product.product</field>
4854+ <field name="inherit_id" ref="asperience_product_attributes.product_product_normal_form_view_attributes" />
4855+ <field name="arch" type="xml">
4856+ <field name="uom_id" position="replace">
4857+ <field name="uom_id"
4858+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4859+ </field>
4860+ <field name="linked_product_ids" position="after" >
4861+ <button icon="gtk-ok" name="reinit_links" string="Reinit Links and Properties with Category" type="object" />
4862+ <field name="property_tmpl_ids" colspan="4" nolabel="1" context="{'tree_view_ref':'asperience_configurator_mrp.product_property_tree_tmpl','form_view_ref':'asperience_configurator_mrp.product_property_form_tmpl'}"/>
4863+ <field name="property_ids" colspan="4" nolabel="1" context="{'tree_view_ref':'asperience_configurator_mrp.product_property_tree','form_view_ref':'asperience_configurator_mrp.product_property_form'}"/>
4864+ </field>
4865+ <page string="Attributes and Options" position="after" >
4866+ <page string="BoM">
4867+ <group col="6" colspan="6" string="Generate">
4868+ <button name="generate_bom" type="object" string="Generate BoM"/>
4869+ <field name="bom" readonly="1"/>
4870+ <field name="opp"/>
4871+ </group>
4872+ <group col="2" colspan="6">
4873+ <field name="bom_type_group_ids" nolabel="1" colspan="6"/>
4874+ <field name="bom_property_ids" nolabel="1" colspan="6"/>
4875+ </group>
4876+ <group col="2" colspan="6">
4877+ <field name="bom_ids" nolabel="1" colspan="6"/>
4878+ <field name="bom_sub_ids" nolabel="1" colspan="6" readonly="True"/>
4879+ </group>
4880+ </page>
4881+ <page string="Dimensions">
4882+ <group colspan="4">
4883+ <group colspan="2">
4884+ <separator colspan="2" string="Shape type" />
4885+ <field colspan="2" name="shape" select="2"
4886+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4887+ </group>
4888+ </group>
4889+
4890+ <separator colspan="4" string="Variables" />
4891+ <group colspan="4">
4892+
4893+ <group colspan="2">
4894+ <separator colspan="4" string="Density" />
4895+ <group colspan="6" col="6">
4896+ <group colspan="2">
4897+ <field name="density" nolabel="1"
4898+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4899+ </group>
4900+ <group colspan="2">
4901+ <field name='uom_d_weight' string="Weight"
4902+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4903+ </group>
4904+ <group colspan="2">
4905+ <field name='uom_d_size' string="SizeĀ³"
4906+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4907+ </group>
4908+ </group>
4909+ </group>
4910+
4911+ <group colspan="2">
4912+ <separator colspan="4" string="Size" />
4913+ <group colspan="2">
4914+ <group colspan="4"
4915+ attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
4916+ <field name="size_x"
4917+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4918+ </group>
4919+ <group colspan="4"
4920+ attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
4921+ <field name="size_y"
4922+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4923+ </group>
4924+ <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
4925+ <field name="size_z"
4926+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4927+ </group>
4928+ <group colspan="4"
4929+ attrs="{'invisible':[('shape','in',['quadrangular','other'])]}">
4930+ <field name="diameter"
4931+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4932+ </group>
4933+ <group colspan="4">
4934+ <field name="uom_s_size" string="Size"
4935+ on_change="compute_weight(uom_d_weight,uom_id,uom_d_size,uom_s_size,size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4936+ </group>
4937+
4938+ </group>
4939+
4940+ </group>
4941+ </group>
4942+
4943+ </page>
4944+ </page>
4945+ </field>
4946+ </record>
4947+
4948+ ######################################### Product template ############################################
4949+ <record id="product_template_form_view_asperience_mrp" model="ir.ui.view">
4950+ <field name="name">product.template.product.form.asperience.mrp</field>
4951+ <field name="model">product.template</field>
4952+ <field name="type">form</field>
4953+ <field name="inherit_id" ref="asperience_product_attributes.product_template_only_form_view_attributes" />
4954+ <field name="arch" type="xml">
4955+ <field name="linked_product_tmpl_ids" position="after" >
4956+ <field name="property_tmpl_ids" colspan="4" nolabel="1" context="{'tree_view_ref':'asperience_configurator_mrp.product_property_tree_tmpl','form_view_ref':'asperience_configurator_mrp.product_property_form_tmpl'}"/>
4957+ </field>
4958+ <page string="Variants" position="after" >
4959+ <page string="Dimensions">
4960+ <group colspan="4">
4961+ <group colspan="2">
4962+ <separator colspan="2" string="Shape type" />
4963+ <field colspan="2" name="shape" select="2"
4964+ on_change="compute_weight(uom_d_weight, uom_id, uom_d_size, uom_s_size, size_x, size_y, size_z, shape, density, diameter, size_x_tmpl, size_y_tmpl, size_z_tmpl, density_tmpl, diameter_tmpl)" />
4965+ </group>
4966+ </group>
4967+
4968+ <separator colspan="4" string="Variables" />
4969+ <group colspan="4">
4970+
4971+ <group colspan="2">
4972+ <separator colspan="4" string="Density" />
4973+ <group colspan="6" col="6">
4974+ <group colspan="2">
4975+ <field name="density_tmpl" nolabel="1"/>
4976+ </group>
4977+ <group colspan="2">
4978+ <field name='uom_d_weight' string="Weight"/>
4979+ </group>
4980+ <group colspan="2">
4981+ <field name='uom_d_size' string="SizeĀ³"/>
4982+ </group>
4983+ </group>
4984+ </group>
4985+
4986+ <group colspan="2">
4987+ <separator colspan="4" string="Size" />
4988+ <group colspan="2">
4989+ <group colspan="4"
4990+ attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
4991+ <field name="size_x_tmpl"/>
4992+ </group>
4993+ <group colspan="4"
4994+ attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
4995+ <field name="size_y_tmpl"/>
4996+ </group>
4997+ <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
4998+ <field name="size_z_tmpl"/>
4999+ </group>
5000+ <group colspan="4"
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches