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
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2017-12-01 14:57:12 +0000
@@ -0,0 +1,3 @@
1.project
2.pydevproject
3.settings
04
=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added directory 'asperience_account_invoice_sale_sources'
=== added file 'asperience_account_invoice_sale_sources/README'
--- asperience_account_invoice_sale_sources/README 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/README 2017-12-01 14:57:12 +0000
@@ -0,0 +1,2 @@
1This module is "production grade".
2In case of problems, please contact maintenance_asperpgi@asperience.fr
0\ No newline at end of file3\ No newline at end of file
14
=== added file 'asperience_account_invoice_sale_sources/__init__.py'
--- asperience_account_invoice_sale_sources/__init__.py 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/__init__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,24 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22import account_invoice
23
24# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file25\ No newline at end of file
126
=== added file 'asperience_account_invoice_sale_sources/__openerp__.py'
--- asperience_account_invoice_sale_sources/__openerp__.py 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/__openerp__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,54 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22{
23 "name": "ASPerience Invoice Sale sources",
24 "version": "8.0",
25 "author": "ASPerience",
26 "website": "https://www.asperience.fr",
27 "sequence": 0,
28 "certificate": "",
29 "license": "",
30 "depends": [
31 "account","sale","asperience_account_invoice_sources"
32 ],
33 "category": "Accounting & Finance",
34 "complexity": "easy",
35 "description": """
36Links between invoices and sales
37 """,
38 "data": [
39 "account_invoice_view.xml",
40 ],
41 "demo": [
42 ],
43 "test": [
44 ],
45 "images": [
46 "images/asperience.png",
47 "images/grouped_invoice.png",
48 ],
49 "auto_install": False,
50 "installable": True,
51 "application": False,
52
53}
54# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file55\ No newline at end of file
156
=== added file 'asperience_account_invoice_sale_sources/account_invoice.py'
--- asperience_account_invoice_sale_sources/account_invoice.py 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/account_invoice.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,38 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields, osv
23
24class account_invoice(osv.osv):
25 _inherit = "account.invoice"
26 _columns = {
27 'sale_ids': fields.many2many('sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale orders'),
28 }
29account_invoice()
30
31class account_invoice_line(osv.osv):
32 _inherit = "account.invoice.line"
33
34 _columns = {
35 'sale_line_ids': fields.many2many('sale.order.line', 'sale_order_line_invoice_rel', 'invoice_id', 'order_line_id', 'Sale Lines', readonly=True),
36 }
37account_invoice_line()
38# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file39\ No newline at end of file
140
=== added file 'asperience_account_invoice_sale_sources/account_invoice_view.xml'
--- asperience_account_invoice_sale_sources/account_invoice_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/account_invoice_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,32 @@
1<?xml version="1.0"?>
2<openerp>
3 <data>
4
5 <record id="invoice_form_asperience_sources" model="ir.ui.view">
6 <field name="name">account.invoice.form.asperience.sources</field>
7 <field name="model">account.invoice</field>
8 <field name="type">form</field>
9 <field name="priority">20</field>
10 <field name="inherit_id" ref="account.invoice_form"/>
11 <field name="arch" type="xml">
12 <page string="Source" position="inside">
13 <field colspan="4" name="sale_ids" nolabel="1"/>
14 </page>
15 </field>
16 </record>
17 <record id="invoice_line_form_asperience_sources" model="ir.ui.view">
18 <field name="name">account.invoice.line.form.asperience.sources</field>
19 <field name="model">account.invoice.line</field>
20 <field name="type">form</field>
21 <field name="priority">20</field>
22 <field name="inherit_id" ref="account.view_invoice_line_form"/>
23 <field name="arch" type="xml">
24 <field name="invoice_line_tax_id" position="after">
25 <separator colspan="4" string="Source Order Lines"/>
26 <field colspan="4" name="sale_line_ids" nolabel="1"/>
27 </field>
28 </field>
29 </record>
30
31 </data>
32</openerp>
0\ No newline at end of file33\ No newline at end of file
134
=== added directory 'asperience_account_invoice_sale_sources/i18n'
=== added file 'asperience_account_invoice_sale_sources/i18n/fr.po'
--- asperience_account_invoice_sale_sources/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sale_sources/i18n/fr.po 2017-12-01 14:57:12 +0000
@@ -0,0 +1,51 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * asperience_sale_invoice_sources
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 6.1\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-11-06 21:04+0000\n"
10"PO-Revision-Date: 2013-11-06 21:04+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: asperience_sale_invoice_sources
19#: view:account.invoice.line:0
20msgid "Source Order Lines"
21msgstr "Source lignes de commandes"
22
23#. module: asperience_sale_invoice_sources
24#: sql_constraint:account.invoice:0
25msgid "Invoice Number must be unique per Company!"
26msgstr "Le numĆ©ro de facture doit ĆŖtre unique par sociĆ©tĆ© !"
27
28#. module: asperience_sale_invoice_sources
29#: view:account.invoice:0
30msgid "Source"
31msgstr "Source"
32
33#. module: asperience_sale_invoice_sources
34#: model:ir.actions.act_window,name:asperience_sale_invoice_sources.action_invoice_open
35msgid "Invoices"
36msgstr "Factures"
37
38#. module: asperience_sale_invoice_sources
39#: model:ir.model,name:asperience_sale_invoice_sources.model_account_invoice_line
40msgid "Invoice line"
41msgstr "Ligne de facture"
42
43#. module: asperience_sale_invoice_sources
44#: constraint:account.invoice:0
45msgid "Error msg is in raise"
46msgstr "Error msg is in raise"
47
48#. module: asperience_sale_invoice_sources
49#: model:ir.model,name:asperience_sale_invoice_sources.model_account_invoice
50msgid "Invoice"
51msgstr "Facture"
052
=== added directory 'asperience_account_invoice_sale_sources/images'
=== added file 'asperience_account_invoice_sale_sources/images/asperience.png'
1Binary 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 differ53Binary 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
=== added file 'asperience_account_invoice_sale_sources/images/grouped_invoice.png'
2Binary 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 differ54Binary 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
=== added directory 'asperience_account_invoice_sources'
=== added file 'asperience_account_invoice_sources/README'
--- asperience_account_invoice_sources/README 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sources/README 2017-12-01 14:57:12 +0000
@@ -0,0 +1,2 @@
1This module is "production grade".
2In case of problems, please contact maintenance_asperpgi@asperience.fr
0\ No newline at end of file3\ No newline at end of file
14
=== added file 'asperience_account_invoice_sources/__init__.py'
--- asperience_account_invoice_sources/__init__.py 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sources/__init__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,24 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22
23
24# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file25\ No newline at end of file
126
=== added file 'asperience_account_invoice_sources/__openerp__.py'
--- asperience_account_invoice_sources/__openerp__.py 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sources/__openerp__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,54 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-TODAY ASPerience SARL (<https://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22{
23 "name": "ASPerience Account Invoice Sources",
24 "version": "8.0",
25 "author": "ASPerience",
26 "website": "https://www.asperience.fr",
27 "sequence": 0,
28 "certificate": "",
29 "license": "",
30 "depends": [
31 "account"
32 ],
33 "category": "Accounting & Finance",
34 "complexity": "easy",
35 "description": """
36Adds view panel for displaying sources (sales, purchases, stocks)
37 """,
38 "data": [
39 'account_invoice_view.xml',
40 ],
41 "demo": [
42 ],
43 "test": [
44 ],
45 "images": [
46 "images/asperience.png",
47 "images/group_invoice_view.png"
48 ],
49 "auto_install": False,
50 "installable": True,
51 "application": False,
52
53}
54# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
055
=== added file 'asperience_account_invoice_sources/account_invoice_view.xml'
--- asperience_account_invoice_sources/account_invoice_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sources/account_invoice_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,32 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="invoice_supplier_form_asperience_1" model="ir.ui.view">
6 <field name="name">account.invoice.supplier.form.asperience.1</field>
7 <field name="model">account.invoice</field>
8 <field name="type">form</field>
9 <field name="inherit_id" ref="account.invoice_supplier_form"/>
10 <field name="arch" type="xml">
11 <page string="Payments" position="after">
12 <page string="Source" groups="base.group_user">
13 </page>
14 </page>
15 </field>
16 </record>
17
18 <record id="invoice_form_asperience_1" model="ir.ui.view">
19 <field name="name">account.invoice.form.asperience.1</field>
20 <field name="model">account.invoice</field>
21 <field name="type">form</field>
22 <field name="inherit_id" ref="account.invoice_form"/>
23 <field name="arch" type="xml">
24 <page string="Payments" position="after">
25 <page string="Source" groups="base.group_user">
26 </page>
27 </page>
28 </field>
29 </record>
30
31 </data>
32</openerp>
0\ No newline at end of file33\ No newline at end of file
134
=== added directory 'asperience_account_invoice_sources/i18n'
=== added file 'asperience_account_invoice_sources/i18n/fr.po'
--- asperience_account_invoice_sources/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ asperience_account_invoice_sources/i18n/fr.po 2017-12-01 14:57:12 +0000
@@ -0,0 +1,26 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * asperience_account_invoice_sources
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 6.1\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-05-26 19:23+0000\n"
10"PO-Revision-Date: 2013-05-26 19:23+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: asperience_account_invoice_sources
19#: view:account.invoice:0
20msgid "Source"
21msgstr "Source"
22
23#. module: asperience_account_invoice_sources
24#: view:account.invoice:0
25msgid "Payments"
26msgstr "RĆØglements"
027
=== added directory 'asperience_account_invoice_sources/images'
=== added file 'asperience_account_invoice_sources/images/asperience.png'
1Binary 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 differ28Binary 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
=== added file 'asperience_account_invoice_sources/images/group_invoice_view.png'
2Binary 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 differ29Binary 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
=== added directory 'asperience_configurator_mrp'
=== added file 'asperience_configurator_mrp/Copy of mrp.py'
--- asperience_configurator_mrp/Copy of mrp.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/Copy of mrp.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,463 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2011 ASPerience SARL (<http://www.asperience.fr>). All Rights Reserved
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import fields,osv
23import openerp.netsvc
24
25import time
26import datetime
27from mx import DateTime
28from openerp.tools.translate import _
29from tools import ustr
30
31class mrp_workcenter_technology(osv.osv):
32 _name = 'mrp.workcenter.technology'
33 _columns = {
34 'name': fields.char('Description', size=256, required=True),
35 }
36 _defaults = {
37 }
38mrp_workcenter_technology()
39
40class mrp_workcenter(osv.osv):
41 _inherit = 'mrp.workcenter'
42
43 def _get_type(self, cr, uid, ids, field_name, arg, context={}):
44 res = {}
45 for id in ids:
46 res[id] = {'type_re': '', 'type_pc': '', 'type_cc': ''}
47 for workcenter in self.browse(cr, uid, ids):
48 if workcenter.type_workcenter == 're':
49 res[id]['type_re'] = workcenter.type
50 elif workcenter.type_workcenter == 'pc':
51 res[id]['type_pc'] = workcenter.type
52 elif workcenter.type_workcenter == 'cc':
53 res[id]['type_cc'] = workcenter.type
54 return res
55
56 def _set_type(self, cr, uid, ids, name, value, arg, context):
57 if not value:
58 return False
59 if isinstance(ids, (int, long)):
60 ids = [ids]
61 for workcenter in self.browse(cr, uid, ids, context):
62 self.write(cr, uid, ids, {'type': value})
63 return True
64
65 def onchange_type(self, cr, uid, id, type=''):
66 res = {'value':{'type': type}}
67 return res
68
69 def onchange_type_workcenter(self, cr, uid, id, type_workcenter):
70 res = {'value':{'type_re': '','type_pc': '', 'type_cc': '', 'type': ''}}
71 if type_workcenter == 're' or type_workcenter == 'pc':
72 res['value']['type_re'] = 'machine'
73 elif type_workcenter == 'cc':
74 res['value']['type_re'] = 'machine_hr'
75 res['value']['type'] = res['value']['type_re']
76 return res
77
78 _columns = {
79 'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool'),('machine_hr','Machine and HR'),('line','Line'),('energy','Energy')], 'Type', required=True),
80 'type_re': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('tool',_('Tool')),('energy',_('Energy'))],
81 multi="type",method=True, store=False, type='selection', string='Type'),
82 'type_pc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('machine_hr',_('Machine and HR')),('line',_('Line'))],
83 multi="type",method=True, store=False, type='selection', string='Type'),
84 'type_cc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine_hr',_('Machine and HR')),('line',_('Line'))],
85 multi="type",method=True, store=False, type='selection', string='Type'),
86 'type_workcenter': fields.selection([('re',_('Elementary resource')),('pc',_('Work center')),('cc',_('Work line'))], 'Type workcenter', required=True, size=2),
87 'parent_id': fields.many2one('mrp.workcenter', "Parent"),
88 'child_ids': fields.one2many('mrp.workcenter', 'parent_id','Childs'),
89 'technology': fields.many2one('mrp.workcenter.technology', "Technology"),
90 'external': fields.boolean('External workcenter'),
91 'fixed_capacity': fields.boolean('Fixed capacity'),
92 'capacity' : fields.float('Capacity'),
93 'critical': fields.boolean('Critical'),
94 'property_ids': fields.many2many('mrp.property', 'mrp_workcenter_property_rel','workcenter_id', 'property_id', 'Properties'),
95 'warehouse_id': fields.many2one('stock.warehouse', 'Sector', required=True),
96 'finite_capacity': fields.boolean('Finite Capacity'),
97 'finite_capacity_qty' : fields.float('Finite Capacity Qty'),
98 'scheduling': fields.selection([('machine','Machine'),('hr','Human Resource'),('machine_hr','Machine and HR'),('pg','the greatest')], 'Scheduling'),
99 }
100 _defaults = {
101 'time_start': lambda *a: 0,
102 'time_stop': lambda *a: 0,
103 'time_cycle': lambda *a: 0,
104 'type_workcenter': lambda *a: "pc",
105 }
106
107 def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=80):
108 if args:
109 if args[0][0] == 'type':
110 for val in args[0][2]:
111 if val:
112 if val in ['line', 'machine_hr']:
113 args = [('type', '=', 'line')]
114 break
115 elif val == 'machine':
116 args = [('type', 'in', ['line','machine_hr','machine'])]
117 break
118 elif val in ['energy', 'hr', 'tool']:
119 args = [('type', 'in', ['line','machine_hr','machine','hr'])]
120 break
121
122 return super(mrp_workcenter, self).name_search(cr, uid, name, args, operator, context, limit)
123
124mrp_workcenter()
125
126class mrp_bom_component_mode(osv.osv):
127 _name = 'mrp.bom.component.mode'
128 _description = 'mrp.bom.component.mode'
129 _columns = {
130 'name': fields.char('Description', size=256, required=True),
131 'dx': fields.text('Dx'),
132 'dy': fields.text('Dy'),
133 'dz': fields.text('Dz'),
134 'dd': fields.text('Dd'),
135 }
136 _defaults = {
137 }
138
139mrp_bom_component_mode()
140
141class mrp_bom_component_rel(osv.osv):
142 _name = 'mrp.bom.component.rel'
143 _description = 'mrp.bom.component.rel'
144 _columns = {
145 'bom_id': fields.many2one('mrp.bom', 'Bom', required=True, ondelete='cascade'),
146 'component_id': fields.many2one('mrp.bom', 'Component', required=True, ondelete='cascade'),
147# 'product_component_id': fields.related('component_id','product_id',type='many2one', relation="product.product", string="Product"),
148 'qty': fields.float('Quantity', required=True),
149 'mode': fields.many2one('mrp.bom.component.mode', 'Mode'),
150 }
151
152 def compute_size(self, cr, uid, ids, context={}):
153 logger = netsvc.Logger()
154 if not ids :
155 return False
156 result = {}
157 for i in self.browse(cr,uid,ids,context):
158 space = {}
159 space["x"] = context.get("size_x",0.0)
160 space["y"] = context.get("size_y",0.0)
161 space["z"] = context.get("size_z",0.0)
162 space["d"] = context.get("diameter",0.0)
163 space["Dx"] = context.get("size_x_specific_delta",0.0)
164 space["Dy"] = context.get("size_y_specific_delta",0.0)
165 space["Dz"] = context.get("size_z_specific_delta",0.0)
166 space["Dd"] = context.get("diameter_specific_delta",0.0)
167
168
169 result[i.id] = {
170 "size_x_specific_delta":0.0,
171 "size_y_specific_delta":0.0,
172 "size_z_specific_delta":0.0,
173 "diameter_specific_delta":0.0,
174 "size_x_specific":context.get("size_x",0.0),
175 "size_y_specific":context.get("size_y",0.0),
176 "size_z_specific":context.get("size_z",0.0),
177 "diameter_specific":context.get("diameter",0.0),
178 }
179
180 try:
181 result[i.id]["size_x_specific_delta"] = eval(i.mode.dx,space)
182 result[i.id]["size_x_specific"] = result[i.id]["size_x_specific"] - result[i.id]["size_x_specific_delta"]
183 except Exception, e:
184 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
185 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform x "+str(i.mode.dx))
186 try:
187 result[i.id]["size_y_specific_delta"] = eval(i.mode.dy,space)
188 result[i.id]["size_y_specific"] = result[i.id]["size_y_specific"] - result[i.id]["size_y_specific_delta"]
189 except Exception, e:
190 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
191 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform y "+str(i.mode.dy))
192 try:
193 result[i.id]["size_z_specific_delta"] = eval(i.mode.dz,space)
194 result[i.id]["size_z_specific"] = result[i.id]["size_z_specific"] - result[i.id]["size_z_specific_delta"]
195 except Exception, e:
196 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
197 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform z "+str(i.mode.dz))
198 try:
199 result[i.id]["diameter_specific_delta"] = eval(i.mode.dd,space)
200 result[i.id]["diameter_specific"] = result[i.id]["diameter_specific"] - result[i.id]["diameter_specific_delta"]
201 except Exception, e:
202 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
203 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform d "+str(i.mode.dd))
204
205 return result
206
207 _defaults = {
208 }
209mrp_bom_component_rel()
210
211def rounding(f, r):
212 if not r:
213 return f
214 return round(f / r) * r
215
216class mrp_bom(osv.osv):
217 _inherit = 'mrp.bom'
218
219# def __init__(self, pool, cr):
220# super(mrp_bom,self).__init__(pool,cr)
221# cr.execute('select count(*) from mrp_bom_childs_rel')
222# nb1 = cr.dictfetchall()[0]['count']
223# cr.execute('select count(*) from mrp_bom_component_rel')
224# nb2 = cr.dictfetchall()[0]['count']
225# if nb1 and not nb2 :
226# cr.execute('insert into mrp_bom_component_rel\
227# (bom_id,component_id,qty)\
228# select a.bom_id, a.child_id, b.product_qty\
229# from mrp_bom_childs_rel a join mrp_bom b on a.bom_id = b.id')
230#
231# map_mode = {
232# 'bottom':['.DES.'],
233# 'top':['PLATEAU'],
234# 'back':['.DER.'],
235# 'front':['.FACE.'],
236# 'side':['.COT.'],
237# }
238# for i in map_mode:
239# for j in map_mode[i]:
240# cr.execute("update mrp_bom_component_rel\
241# set mode = ( select id\
242# from mrp_bom_component_mode\
243# where name = '"+ustr(i)+"')\
244# where id in (\
245# select a.id\
246# 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\
247# where c.default_code like '%"+ustr(j)+"%');")
248
249
250 def _child_compute(self, cr, uid, ids, name, arg, context={}):
251 result = {}
252 for bom in self.browse(cr, uid, ids, context=context):
253 result[bom.id] = map(lambda x: x.component_id.id, bom.bom_components)
254 if bom.bom_components:
255 continue
256 ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
257 if bom.type=='phantom' or ok:
258 sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
259 if sids:
260 bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context)
261 result[bom.id] += map(lambda x: x.component_id.id, bom2.bom_components)
262 return result
263
264 def _compute_type(self, cr, uid, ids, field_name, arg, context):
265 res = dict(map(lambda x: (x,''), ids))
266 for line in self.browse(cr, uid, ids):
267 if line.type=='phantom' and not line.bom_id:
268 res[line.id] = 'set'
269 continue
270 if line.bom_lines or line.bom_components or line.type=='phantom':
271 continue
272 if line.product_id.supply_method=='produce':
273 if line.product_id.procure_method=='make_to_stock':
274 res[line.id] = 'stock'
275 else:
276 res[line.id] = 'order'
277 return res
278
279 _columns = {
280 'bom_type': fields.selection([('ass','Assemble'),('exp','Disassemble'),('cut','Cutting'),('cutinput','Cutting Input'),('picking','Picking'),('delay','Delay'),('control','Quality control')], 'BOM Type', required=True ),
281 'bom_lines_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'bom_id', 'child_id', 'Child BoMs'),
282 'bom_parent_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'child_id', 'bom_id', 'Parent BoMs'),
283 'bom_components': fields.one2many('mrp.bom.component.rel', 'bom_id', 'Components'),
284 'bom_components_parent': fields.one2many('mrp.bom.component.rel', 'component_id', 'Parent Components'),
285 'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
286 '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"),
287 'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hyerarchy", type='many2many'),
288# '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"),
289 'sub_product_ids': fields.many2many('mrp.subproduct', 'mrp_bom_subproduct_rel','bom_id', 'sub_id', 'Sub products'),
290 }
291 _defaults = {
292 'bom_type': lambda *a: 'ass'
293 }
294
295mrp_bom()
296
297class mrp_production(osv.osv):
298 _inherit = 'mrp.production'
299
300 def _size(self, cr, uid, ids, field_name, arg, context):
301 res = {}
302 for proc in self.browse(cr, uid, ids):
303 res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 , 'diameter': 0.0}
304 if proc.product_id:
305 res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
306 res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
307 res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
308 res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
309 return res
310
311 _columns = {
312 'procurement_ids': fields.one2many('procurement.order', 'production_id', 'Procurements'),
313 'specific_production':fields.boolean('Specific Production'),
314 'note_production':fields.text('Production Note'),
315 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
316 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
317 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
318 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
319 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True),
320 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
321 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
322 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
323 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
324 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
325 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
326 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
327 'uom_s_size_specific' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
328 }
329 _order = 'id desc'
330
331 def action_production_end(self, cr, uid, ids):
332# move_ids = []
333 for production in self.browse(cr, uid, ids):
334 for res in production.move_lines:
335 for move in production.move_created_ids:
336 #XXX must use the orm
337# cr.execute('INSERT INTO stock_move_history_ids \
338# (parent_id, child_id) VALUES (%s,%s)',
339# (res.id, move.id))
340 #ASPerience: test des valeurs pour Ʃviter les erreurs de rƩƩcriture
341 cr.execute('select parent_id,child_id from stock_move_history_ids where parent_id=%s and child_id=%s', (res.id, move.id))
342 if len(cr.fetchall()) == 0:
343 cr.execute('insert into stock_move_history_ids (parent_id,child_id) values (%s,%s)', (res.id, move.id))
344 else:
345 logger = netsvc.Logger()
346 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)))
347 #Fin ASPerience
348# move_ids.append(res.id)
349 vals= {'state':'confirmed'}
350 new_moves = [x.id for x in production.move_created_ids]
351 self.pool.get('stock.move').write(cr, uid, new_moves, vals)
352 if not production.date_finnished:
353 self.write(cr, uid, [production.id],
354 {'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
355 self.pool.get('stock.move').check_assign(cr, uid, new_moves)
356 self.pool.get('stock.move').action_done(cr, uid, new_moves)
357 self._costs_generate(cr, uid, production)
358# self.pool.get('stock.move').action_done(cr, uid, move_ids)
359 self.write(cr, uid, ids, {'state': 'done'})
360 return True
361
362mrp_production()
363
364class mrp_production_product_line(osv.osv):
365 _inherit = 'mrp.production.product.line'
366
367 _columns = {
368 'property_ids': fields.many2many('mrp.property', 'mrp_production_product_line_property_rel', 'line_id','property_id', 'Properties'),
369 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_line_group_property_rel','production_line_id', 'group_id', 'Product Property Group Rel '),
370 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
371 'option_ids': fields.many2many('product.links', 'mrp_production_product_line_options_rel','line_id', 'links_id', 'Option'),
372 'bom_id': fields.many2one('mrp.bom', 'Bom'),
373 'specific_production':fields.boolean('Specific Production'),
374 'note_production':fields.text('Production Note'),
375 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
376 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
377 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
378 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
379 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
380 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
381 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
382 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
383 'uom_s_size_specific' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
384 }
385mrp_production_product_line()
386
387class stock_production_lot(osv.osv):
388 _inherit = 'stock.production.lot'
389
390 def search_specific(self,cr,uid,vals,delay):
391 filter = [('product_id','=',vals['product_id'])]
392 filter_key = ['density','diameter','shape','size_x','size_y','size_z','weight']
393 for key in filter_key:
394 if vals[key]:
395 filter.append((key,'=',vals[key]))
396
397 today=datetime.datetime.today()
398 if delay:
399 limit = (today-datetime.timedelta(days=delay)).strftime('%Y-%m-%d %H:%M:%S')
400 filter.append(('date','>',limit))
401
402 result = self.search(cr,uid,filter)
403 set_property_ids = set(vals['property_ids'][0][2])
404 set_group_property_ids = set(vals['group_property_ids'][0][2])
405 set_option_ids = set(vals['option_ids'][0][2])
406 for lot_id in result:
407 lot = self.browse(cr,uid,lot_id)
408 lot_property_ids = set([i.id for i in lot.property_ids])
409 lot_group_property_ids = set([i.id for i in lot.group_property_ids])
410 lot_option_ids = set([i.id for i in lot.option_ids])
411 if lot_property_ids == set_property_ids and lot_group_property_ids == set_group_property_ids and lot_option_ids == set_option_ids :
412 return lot.id
413 return False
414
415 _columns = {
416 'property_ids': fields.many2many('mrp.property', 'mrp_production_lot_property_rel', 'lot_id','property_id', 'Properties'),
417 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_lot_group_property_rel','production_lot_id', 'group_id', 'Product Property Group Rel '),
418 'option_ids': fields.many2many('product.links', 'mrp_production_lot_options_rel','production_lot_id', 'links_id', 'Options'),
419 }
420
421 _defaults = {
422 }
423stock_production_lot()
424
425class mrp_routing(osv.osv):
426 _inherit = 'mrp.routing'
427 _columns = {
428 'technical_data': fields.char('Technical Data', size=128),
429 }
430 _defaults = {
431 'active': lambda *a: 1,
432 }
433mrp_routing()
434
435class mrp_routing_workcenter_subproduct(osv.osv):
436 _name = 'mrp.routing.workcenter.subproduct'
437 _description = 'mrp.routing.workcenter.subproduct'
438 _columns = {
439 'name': fields.float('Percent', required=True),
440 'subproduct_id': fields.many2one('mrp.subproduct', 'Subproduct', required=True),
441 'workcenter_line_id': fields.many2one('mrp.routing.workcenter', 'Routing Workcenter', required=True),
442 }
443mrp_routing_workcenter_subproduct()
444
445class mrp_routing_workcenter(osv.osv):
446 _inherit = 'mrp.routing.workcenter'
447 _columns = {
448 'sub_ids': fields.one2many('mrp.routing.workcenter.subproduct', 'workcenter_line_id', 'Sub Product'),
449 'bom_ids': fields.many2many('mrp.bom', 'routing_workcenter_mrp_bom_rel', 'workcenter_line_id', 'bom_id', 'Components'),
450 }
451 _defaults = {
452 }
453mrp_routing_workcenter()
454
455class mrp_production_workcenter_line(osv.osv):
456 _inherit = 'mrp.production.workcenter.line'
457 _columns = {
458 'move_ids' : fields.many2many('stock.move', 'mrp_production_workcenter_line_stock_move_rel', 'line_id', 'move_id', 'Moves'),
459 }
460 _defaults = {
461 }
462mrp_production_workcenter_line()
463# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file464\ No newline at end of file
1465
=== added file 'asperience_configurator_mrp/__init__.py'
--- asperience_configurator_mrp/__init__.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/__init__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,34 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22import company
23import product
24import stock
25import stock_production
26import procurement
27import mrp_property
28import mrp_bom
29import mrp_subproduct
30import mrp_workcenter
31import mrp_routing
32import mrp_production
33#import report
34# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file35\ No newline at end of file
136
=== added file 'asperience_configurator_mrp/__openerp__.py'
--- asperience_configurator_mrp/__openerp__.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/__openerp__.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,76 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22{
23 "name": "ASPerience - MRP",
24 "version": "8.0",
25 "author": "ASPerience",
26 "website": "http://www.asperience.fr",
27 "sequence": 0,
28 "certificate": "",
29 "license": "",
30 "depends": [
31 "mrp",
32 "mrp_byproduct",
33 "mrp_operations",
34 "product",
35 "stock",
36 "asperience_product_attributes",
37 ],
38 "category": "Generic Modules/ASPerience",
39 "complexity": "easy",
40 "description": """
41BOM tree management, trees of supplies from the configurator and trees production.
42Filtering system of nomenclature by properties, from supplies.
43Management of product properties.
44 """,
45 "data": [
46 "security/ir.model.access.csv",
47 "company_view.xml",
48 "product_view.xml",
49 "procurement_view.xml",
50 "mrp_view.xml",
51 "stock_production_view.xml",
52 "mrp_workflow.xml",
53 "mrp_report.xml",
54 "mrp_subproduct_view.xml",
55 "mrp_data.xml",
56 ],
57 "demo": [
58 ],
59 "test": [
60 ],
61 "js": [
62 ],
63 "css": [
64 ],
65 "qweb": [
66 ],
67 "demo_xml": [
68 ],
69 "images": [
70 ],
71 "auto_install": False,
72 "installable": True,
73 "application": False,
74
75}
76# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file77\ No newline at end of file
178
=== added file 'asperience_configurator_mrp/bom_graph.pyc'
2Binary 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 differ79Binary 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
=== added file 'asperience_configurator_mrp/company.py'
--- asperience_configurator_mrp/company.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/company.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,32 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import osv, fields
23
24class res_company(osv.osv):
25 _inherit = 'res.company'
26
27 _columns = {
28 'tracking_production_delay':fields.integer('Tracking production delay'),
29 }
30
31res_company()
32# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file33\ No newline at end of file
134
=== added file 'asperience_configurator_mrp/company_view.xml'
--- asperience_configurator_mrp/company_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/company_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,16 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="view_company_form_asperience_mrp" model="ir.ui.view">
5 <field name="name">res.company.form.asperience.mrp</field>
6 <field name="model">res.company</field>
7 <field name="priority">25</field>
8 <field name="inherit_id" ref="base.view_company_form"/>
9 <field name="arch" type="xml">
10 <field name="manufacturing_lead" position="after">
11 <field name="tracking_production_delay"/>
12 </field>
13 </field>
14 </record>
15 </data>
16</openerp>
017
=== added directory 'asperience_configurator_mrp/i18n'
=== added file 'asperience_configurator_mrp/i18n/fr_FR.po'
--- asperience_configurator_mrp/i18n/fr_FR.po 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/i18n/fr_FR.po 2017-12-01 14:57:12 +0000
@@ -0,0 +1,274 @@
1# Translation of ASPerPGI.
2# This file contains the translation of the following modules:
3# * asperience_mrp
4# * report_mrp
5# * mrp
6#
7msgid ""
8msgstr ""
9"Project-Id-Version: ASPerPGI 5.0.10\n"
10"Report-Msgid-Bugs-To: support@openerp.com\n"
11"POT-Creation-Date: 2010-11-10 08:50:02+0000\n"
12"PO-Revision-Date: 2010-11-10 08:50:02+0000\n"
13"Last-Translator: <>\n"
14"Language-Team: \n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: \n"
18"Plural-Forms: \n"
19
20#. module: mrp
21#: view:mrp.production:0
22msgid "Consumed Products"
23msgstr "Produits ConsommƩs"
24
25#. module: asperience_mrp
26#: field:procurement.order,specific_production:0
27#: field:mrp.production,specific_production:0
28msgid "Specific Production"
29msgstr "Production spƩcifique"
30
31#. module: mrp
32#: model:ir.actions.wizard,name:mrp.product_procurement_wizard
33msgid "Procurement Request"
34msgstr "Demande d'approvisionnement"
35
36#. module: asperience_mrp
37#: field:product.category.property,categ_id:0
38msgid "Category"
39msgstr "Categorie"
40
41#. module: asperience_mrp
42#: model:ir.module.module,shortdesc:asperience_mrp.module_meta_information
43msgid "ASPerience - MRP"
44msgstr ""
45
46#. module: asperience_mrp
47#: field:mrp.property,size_y_tmpl:0
48msgid "Length"
49msgstr "Largeur"
50
51#. module: asperience_mrp
52#: field:mrp.workcenter,capacity:0
53msgid "Capacity"
54msgstr "CapacitƩ"
55
56#. module: asperience_mrp
57#: code:addons/asperience_mrp/mrp.py:0
58#: selection:mrp.workcenter,type_workcenter:0
59#, python-format
60msgid "Work line"
61msgstr "Ligne de production"
62
63#. module: asperience_mrp
64#: field:mrp.property,size_z_tmpl:0
65msgid "Thickness"
66msgstr "Hauteur"
67
68#. module: asperience_mrp
69#: field:mrp.property.group.option,type_group_id:0
70#: field:product.category.property,type_group:0
71#: field:product.property,type_group:0
72msgid "Group By"
73msgstr "Grouper par"
74
75#. module: asperience_mrp
76#: view:product.product:0
77msgid "Generate BoM"
78msgstr "GƩnƩrer le BoM"
79
80
81#. module: asperience_mrp
82#: field:product.product,bom:0
83msgid "BoM Generated"
84msgstr "BoM gƩnƩrƩ"
85
86#. module: asperience_mrp
87#: view:product.product:0
88msgid "Generate"
89msgstr "GƩnƩrer"
90
91#. module: asperience_mrp
92#: field:mrp.property,uom_s_size_tmpl:0
93msgid "Size Uom"
94msgstr "Udm taille"
95
96#. module: asperience_mrp
97#: field:mrp.property,price:0
98msgid "Price"
99msgstr "Prix"
100
101#. module: asperience_mrp
102#: field:mrp.production.product.line,property_ids:0
103#: field:mrp.property.group,property_ids:0
104#: field:mrp.property.group.option,property_id:0
105#: field:mrp.workcenter,property_ids:0
106msgid "Properties"
107msgstr "PropriƩtƩs"
108
109#. module: asperience_mrp
110#: field:mrp.property,size_x_tmpl:0
111msgid "Width"
112msgstr "Profondeur"
113
114#. module: asperience_mrp
115#: field:mrp.workcenter,external:0
116msgid "External workcenter"
117msgstr ""
118
119#. module: asperience_mrp
120#: field:mrp.workcenter,critical:0
121msgid "Critical"
122msgstr ""
123
124#. module: asperience_mrp
125#: selection:product.category.property,type:0
126msgid "Template"
127msgstr "ModĆØle"
128
129#. module: asperience_mrp
130#: constraint:ir.model:0
131msgid "The Object name must start with x_ and not contain any special character !"
132msgstr "Le nom de l'objet doit commencer avec x_ et ne pas contenir de charactĆØres spĆ©ciaux !"
133
134#. module: asperience_mrp
135#: view:product.property:0
136msgid "Product Properties Product"
137msgstr "Options de Configuration PropriƩtƩs du Produit"
138
139#. module: asperience_mrp
140#: field:product.category.property,type:0
141msgid "Type"
142msgstr ""
143
144#. module: asperience_mrp
145#: model:ir.model,name:asperience_mrp.model_mrp_workcenter_technology
146msgid "mrp.workcenter.technology"
147msgstr "Famille technologique"
148
149#. module: asperience_mrp
150#: selection:product.category.property,type:0
151#: field:product.property,product_id:0
152#: field:product.property,template_id:0
153msgid "Product"
154msgstr "Produit"
155
156#. module: asperience_mrp
157#: field:product.property,used:0
158msgid "Used"
159msgstr "Actif"
160
161#. module: asperience_mrp
162#: field:mrp.workcenter.technology,name:0
163#: view:product.category:0
164#: field:product.category,description:0
165#: field:product.category.property,name:0
166#: field:product.property,name:0
167msgid "Description"
168msgstr ""
169
170#. module: asperience_mrp
171#: field:product.category,linked_product_ids:0
172msgid "Linked products"
173msgstr ""
174
175#. module: asperience_mrp
176#: code:addons/asperience_mrp/mrp.py:0
177#: selection:mrp.workcenter,type_workcenter:0
178#, python-format
179msgid "Elementary resource"
180msgstr "Ressource ƩlƩmentaire"
181
182#. module: asperience_mrp
183#: model:ir.model,name:asperience_mrp.model_product_property
184msgid "product.property"
185msgstr "PropriƩtƩs"
186
187#. module: asperience_mrp
188#: field:mrp.workcenter,type_workcenter:0
189msgid "Type workcenter"
190msgstr "Type de centre de travail"
191
192#. module: asperience_mrp
193#: view:product.product.property:0
194msgid "Properties"
195msgstr "PropriƩtƩs"
196
197#. module: asperience_mrp
198#: code:addons/asperience_mrp/mrp.py:0
199#: selection:mrp.workcenter,type_workcenter:0
200#, python-format
201msgid "Work center"
202msgstr "Machine"
203
204#. module: asperience_mrp
205#: constraint:ir.ui.view:0
206msgid "Invalid XML for View Architecture!"
207msgstr "XML non valide pour l'architecture de la vue"
208
209#. module: asperience_mrp
210#: field:mrp.workcenter,fixed_capacity:0
211msgid "Fixed capacity"
212msgstr ""
213
214#. module: asperience_mrp
215#: field:mrp.property.group,required:0
216msgid "Required"
217msgstr "Requis"
218
219#. module: asperience_mrp
220#: view:product.category.property:0
221msgid "Product Property"
222msgstr "PropriƩtƩs"
223
224#. module: asperience_mrp
225#: field:mrp.property,code:0
226msgid "Code"
227msgstr ""
228
229#. module: asperience_mrp
230#: field:product.category,property_ids:0
231#: field:product.category.property,property_id:0
232#: field:product.property,property_id:0
233msgid "Property"
234msgstr "PropriƩtƩ"
235
236#. module: asperience_mrp
237#: field:mrp.workcenter,child_ids:0
238msgid "Childs"
239msgstr "Enfants"
240
241#. module: asperience_mrp
242#: field:mrp.workcenter,parent_id:0
243msgid "Parent"
244msgstr ""
245
246#. module: asperience_mrp
247#: field:product.template,property_tmpl_ids:0
248msgid "Property Template"
249msgstr ""
250
251#. module: asperience_mrp
252#: field:product.template,linked_product_tmpl_ids:0
253msgid "Linked products template"
254msgstr "Options de Configuration Option du ModĆØle"
255
256#. module: asperience_mrp
257#: view:product.property:0
258msgid "Product Properties Template"
259msgstr "Options de Configuration PropriĆ©tĆ©s du ModĆØle"
260
261#. module: asperience_mrp
262#: model:ir.model,name:asperience_mrp.model_product_category_property
263msgid "product.category.property"
264msgstr ""
265
266#. module: asperience_mrp
267#: field:mrp.workcenter,technology:0
268msgid "Technology"
269msgstr "Famille technologique"
270
271#. module: report_mrp
272#: field:report.mrp.inout,value:0
273msgid "Stock value"
274msgstr "Valeur de stock"
0275
=== added file 'asperience_configurator_mrp/mrp.pyc'
1Binary 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 differ276Binary 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
=== added file 'asperience_configurator_mrp/mrp_bom.py'
--- asperience_configurator_mrp/mrp_bom.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_bom.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,843 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23#import openerp.netsvc
24#from openerp.tools.translate import _
25#from openerp.tools import ustr
26import logging
27_logger = logging.getLogger(__name__)
28
29class mrp_bom_component_mode(osv.osv):
30 _name = 'mrp.bom.component.mode'
31 _description = 'mrp.bom.component.mode'
32 _columns = {
33 'name': fields.char('Description', size=256, required=True),
34 'dx': fields.text('Dx'),
35 'dy': fields.text('Dy'),
36 'dz': fields.text('Dz'),
37 'dd': fields.text('Dd'),
38 }
39 _defaults = {
40 }
41
42mrp_bom_component_mode()
43
44class mrp_bom_component_rel(osv.osv):
45 _name = 'mrp.bom.component.rel'
46 _description = 'mrp.bom.component.rel'
47 _columns = {
48 'bom_id': fields.many2one('mrp.bom', 'Bom', required=True, ondelete='cascade'),
49 'component_id': fields.many2one('mrp.bom', 'Component', required=True, ondelete='cascade'),
50# 'product_component_id': fields.related('component_id','product_id',type='many2one', relation="product.product", string="Product"),
51 'qty': fields.float('Quantity', required=True),
52 'mode': fields.many2one('mrp.bom.component.mode', 'Mode'),
53 }
54
55 def compute_size(self, cr, uid, ids, context={}):
56 logger = netsvc.Logger()
57 if not ids :
58 return False
59 result = {}
60 for i in self.browse(cr,uid,ids,context):
61 space = {}
62 space["x"] = context.get("size_x",0.0)
63 space["y"] = context.get("size_y",0.0)
64 space["z"] = context.get("size_z",0.0)
65 space["d"] = context.get("diameter",0.0)
66 space["Dx"] = context.get("size_x_specific_delta",0.0)
67 space["Dy"] = context.get("size_y_specific_delta",0.0)
68 space["Dz"] = context.get("size_z_specific_delta",0.0)
69 space["Dd"] = context.get("diameter_specific_delta",0.0)
70
71
72 result[i.id] = {
73 "size_x_specific_delta":0.0,
74 "size_y_specific_delta":0.0,
75 "size_z_specific_delta":0.0,
76 "diameter_specific_delta":0.0,
77 "size_x_specific":context.get("size_x",0.0),
78 "size_y_specific":context.get("size_y",0.0),
79 "size_z_specific":context.get("size_z",0.0),
80 "diameter_specific":context.get("diameter",0.0),
81 }
82
83 try:
84 result[i.id]["size_x_specific_delta"] = eval(i.mode.dx,space)
85 result[i.id]["size_x_specific"] = result[i.id]["size_x_specific"] - result[i.id]["size_x_specific_delta"]
86 except Exception, e:
87 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
88 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform x "+str(i.mode.dx))
89 try:
90 result[i.id]["size_y_specific_delta"] = eval(i.mode.dy,space)
91 result[i.id]["size_y_specific"] = result[i.id]["size_y_specific"] - result[i.id]["size_y_specific_delta"]
92 except Exception, e:
93 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
94 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform y "+str(i.mode.dy))
95 try:
96 result[i.id]["size_z_specific_delta"] = eval(i.mode.dz,space)
97 result[i.id]["size_z_specific"] = result[i.id]["size_z_specific"] - result[i.id]["size_z_specific_delta"]
98 except Exception, e:
99 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
100 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform z "+str(i.mode.dz))
101 try:
102 result[i.id]["diameter_specific_delta"] = eval(i.mode.dd,space)
103 result[i.id]["diameter_specific"] = result[i.id]["diameter_specific"] - result[i.id]["diameter_specific_delta"]
104 except Exception, e:
105 logger.notifyChannel('eval size', netsvc.LOG_WARNING, e)
106 logger.notifyChannel('eval size', netsvc.LOG_WARNING, "transform d "+str(i.mode.dd))
107
108 return result
109
110 _defaults = {
111 }
112mrp_bom_component_rel()
113
114def rounding(f, r):
115 if not r:
116 return f
117 return round(f / r) * r
118
119class mrp_bom(osv.osv):
120 _inherit = 'mrp.bom'
121
122# def __init__(self, pool, cr):
123# super(mrp_bom,self).__init__(pool,cr)
124# cr.execute('select count(*) from mrp_bom_childs_rel')
125# nb1 = cr.dictfetchall()[0]['count']
126# cr.execute('select count(*) from mrp_bom_component_rel')
127# nb2 = cr.dictfetchall()[0]['count']
128# if nb1 and not nb2 :
129# cr.execute('insert into mrp_bom_component_rel\
130# (bom_id,component_id,qty)\
131# select a.bom_id, a.child_id, b.product_qty\
132# from mrp_bom_childs_rel a join mrp_bom b on a.bom_id = b.id')
133#
134# map_mode = {
135# 'bottom':['.DES.'],
136# 'top':['PLATEAU'],
137# 'back':['.DER.'],
138# 'front':['.FACE.'],
139# 'side':['.COT.'],
140# }
141# for i in map_mode:
142# for j in map_mode[i]:
143# cr.execute("update mrp_bom_component_rel\
144# set mode = ( select id\
145# from mrp_bom_component_mode\
146# where name = '"+ustr(i)+"')\
147# where id in (\
148# select a.id\
149# 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\
150# where c.default_code like '%"+ustr(j)+"%');")
151
152
153 def _child_compute(self, cr, uid, ids, name, arg, context={}):
154 result = {}
155 for bom in self.browse(cr, uid, ids, context=context):
156 result[bom.id] = map(lambda x: x.component_id.id, bom.bom_components)
157 if bom.bom_components:
158 continue
159 ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
160 if bom.type=='phantom' or ok:
161 sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
162 if sids:
163 bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context)
164 result[bom.id] += map(lambda x: x.component_id.id, bom2.bom_components)
165 return result
166
167 def _compute_type(self, cr, uid, ids, field_name, arg, context):
168 res = dict(map(lambda x: (x,''), ids))
169 for line in self.browse(cr, uid, ids):
170 if line.type=='phantom' and not line.bom_id:
171 res[line.id] = 'set'
172 continue
173 if line.bom_lines or line.bom_components or line.type=='phantom':
174 continue
175 if line.product_id.supply_method=='produce':
176 if line.product_id.procure_method=='make_to_stock':
177 res[line.id] = 'stock'
178 else:
179 res[line.id] = 'order'
180 return res
181
182 _columns = {
183 #Dimensions
184 'size_x': fields.float('Width', digits=(16, 5)),
185 'size_y': fields.float('Length', digits=(16, 5)),
186 'size_z': fields.float('Thickness', digits=(16, 5)),
187 'density': fields.float('Density', digits=(16, 5)),
188 'shape' : fields.selection([('quadrangular', 'Quadrangular'), ('cylindrical', 'Cylindrical'), ('other', 'Other')], 'Shape', required=True),
189 'diameter' : fields.float('Diameter', digits=(16, 5)),
190 'weight': fields.float('Weight', digits=(16, 5)),
191 #Production
192 'bom_type': fields.selection([('ass','Assemble'),('exp','Disassemble'),('cut','Cutting'),('cutinput','Cutting Input'),('picking','Picking'),('delay','Delay'),('control','Quality control')], 'BOM Type', required=True ),
193 'bom_lines_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'bom_id', 'child_id', 'Child BoMs'),
194 'bom_parent_multi': fields.many2many('mrp.bom', 'mrp_bom_childs_rel', 'child_id', 'bom_id', 'Parent BoMs'),
195 'bom_components': fields.one2many('mrp.bom.component.rel', 'bom_id', 'Components'),
196 'bom_components_parent': fields.one2many('mrp.bom.component.rel', 'component_id', 'Parent Components'),
197 'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
198 '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"),
199 'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hyerarchy", type='many2many'),
200# '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"),
201 'sub_product_ids': fields.many2many('mrp.subproduct', 'mrp_bom_subproduct_rel','bom_id', 'sub_id', 'Sub products'),
202 }
203 _defaults = {
204 'bom_type': lambda *a: 'ass'
205 }
206
207 def compute_weight(self, cr, uid, id, product_id, size_x, size_y, size_z, shape, density, diameter):
208 if product_id:
209 product = self.pool.get('product.product').browse(cr, uid, product_id, context='')
210 factor1 = product.uom_d_weight.factor
211 factor2 = product.uom_id.factor
212 factor3 = product.uom_d_size.factor
213 factor4 = product.uom_s_size.factor
214 return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter)}
215
216 def onchange_product_id(self, cr, uid, ids, product_id, name, id, context={}):
217 if product_id:
218 w = self.pool.get('product.product').browse(cr, uid, [product_id], context)[0]
219 factor1 = w.uom_d_weight.factor
220 factor2 = w.uom_id.factor
221 factor3 = w.uom_d_size.factor
222 factor4 = w.uom_s_size.factor
223 v = {
224 'product_uom':w.uom_id.id,
225 'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id,
226 'size_x':w.size_x or w.size_x_tmpl,
227 'size_y':w.size_y or w.size_y_tmpl,
228 'size_z':w.size_z or w.size_z_tmpl,
229 'density':w.density or w.density_tmpl,
230 'shape':w.shape,
231 'diameter':w.diameter or w.diameter_tmpl,
232 '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'],
233 'name' : w.name,
234 }
235 if id :
236 v['bom_id'] = id
237 return {'value': v}
238 return {}
239
240 def button_quality_control(self,cr,uid,ids,context={}):
241 revision_obj = self.pool.get('stock.production.lot.revision')
242 attachment_obj = self.pool.get('ir.attachment')
243 for i in ids:
244 lot = self.browse(cr,uid,i)
245 if not lot.production_date:
246 raise osv.except_osv(_('Error :"'),_("Missing production date"))
247
248 if lot.revisions:
249 indice = (max([eval(revision.indice) for revision in lot.revisions]) or 0) + 1
250 else:
251 indice = 1
252 vals = {
253 'name': _("certificate"),
254 'description': _("Conformity certificate generation"),
255 'indice': str(indice),
256 'date': datetime.datetime.now(),
257 'author_id': uid,
258 'lot_id': i,
259 }
260 revision_obj.create(cr,uid,vals)
261 report = "stock.production.lot.conformity.certificate"
262 ir_obj = self.pool.get('ir.actions.report.xml')
263 report_xml_ids = ir_obj.search(cr, uid,[('report_name', '=', report)])
264 if report_xml_ids:
265 report_xml = ir_obj.browse(cr, uid, report_xml_ids[0])
266 service = netsvc.LocalService("report."+report)
267 (r, format) = service.create(cr, uid, [i], {}, {})
268 report_file = report_xml.name+'.'+format
269 report_datas = base64.encodestring(r)
270 data_attach = {
271 'name': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice),
272 'datas':report_datas,
273 'datas_fname': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice)+".pdf",
274 'description': _('Conformity_certificate_')+(lot.name or '')+"_V"+str(indice)+".pdf",
275 'res_model': 'stock.production.lot',
276 'res_id': i
277 }
278 attachment_obj.create(cr,uid, data_attach)
279 self.write(cr,uid,ids,{'quality_control':True})
280
281 return True
282
283 def _bom_find(self, cr, uid, product_id, product_uom, properties=[], group_properties_filter=[], bom_type='ass', level=0):
284 level_str = "-"*level
285 print_tab(level,"*"*50)
286 print_tab(level,"_bom_find",product_id)
287 print_tab(level,"_bom_find properties",properties)
288 print_tab(level,"_bom_find group_properties_filter",group_properties_filter)
289 pre = level_str+"_bom_find "
290 print_tab(level,"_"*50)
291 bom_result = False
292 # Why searching on BoM without parent ?
293 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))
294 ids = map(lambda x: x[0], cr.fetchall())
295
296 if not ids :
297 print_tab(pre+"generate all")
298 self.pool.get('product.product').generate_bom(cr,uid,[product_id])
299 print_tab(pre+"return bom_find after generate")
300 print_tab("9"*50)
301 return self._bom_find(cr, uid, product_id, product_uom, properties, group_properties_filter,level=level+1)
302
303 max_prop = 0
304 result = False
305
306 if not properties and not group_properties_filter:
307 #Produit configurable: recherche du BOM principal
308 print_tab(pre+"Produit configurable: recherche du BOM principal",product_id)
309 for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
310 not_filter = True
311 for group_id in bom.type_group_ids:
312# print pre+"group_id ",group_id.id
313 if group_id.execution_filter :
314# print pre+"group_id filter "
315 not_filter = False
316 if not_filter:
317 result = bom.id
318 break
319 if not result :
320 self.pool.get('product.product').generate_bom(cr,uid,[product_id])
321 return self._bom_find(cr, uid, product_id, product_uom, [], [],level=level+1)
322 elif group_properties_filter :
323 #Produit configurable: recherche du BOM liƩ au groupe de propriƩtƩ
324 print_tab(pre+"Produit configurable: recherche du BOM liƩ au groupe de propriƩtƩ",product_id)
325# group_properties_filter = [i.type_group_id.id for i in self.pool.get('mrp.property.group.option').browse(cr, uid, group_properties_filter)]
326 for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
327 for group_id in bom.type_group_ids:
328 print_tab(pre+"group_id ",group_id.id,group_id.name,group_id.execution_filter)
329 print_tab(group_properties_filter)
330 if group_id.execution_filter and group_id.id in group_properties_filter:
331 result = bom.id
332 break
333 if not result :
334 parent = self._bom_find(cr, uid, product_id, product_uom,level=level+1)
335 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]
336 print_tab(pre+"return bom_find")
337# # CA NE FONCTIONNE PAS AVEC CA MAIS CE N4EST PAS NORMAL
338 print_tab("8"*50)
339 return self._bom_find(cr, uid, product_id, product_uom, properties, group_properties_filter,level=level+1)
340 else:
341 #Produit avec configuration mrp originale
342 print pre+"Produit avec configuration mrp originale"
343 for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
344 prop = 0
345 for prop_id in bom.property_ids:
346 if prop_id.id in properties:
347 prop+=1
348 if (prop>max_prop) or ((max_prop==0) and not result):
349 result = bom.id
350 max_prop = prop
351
352 print_tab(pre+"return result",result)
353 print_tab("-"*50)
354 return result
355
356 def _bom_explode(self, cr, uid, bom, factor, properties, addthis=False, level=1, group_properties=[], procurement_id=False, context={}):
357 level_str = "-"*level
358 print_tab(level,"_bom_explode")
359 print_tab(level,"procurement_id",procurement_id)
360 print_tab(level,"bom.id",bom.id)
361 factor = factor / (bom.product_efficiency or 1.0)
362 factor = rounding(factor, bom.product_rounding)
363 if factor<bom.product_rounding:
364 factor = bom.product_rounding
365 result = []
366 result2 = []
367 phantom=False
368 if "bom_tree" not in context:
369 context["bom_tree"] = []
370 proc_obj = self.pool.get('procurement.order')
371 bom_obj = self.pool.get('mrp.bom')
372 proc_ptr = False
373 if procurement_id:
374 proc_ptr = proc_obj.browse(cr,uid,procurement_id)
375 #=======================================================================
376 # Filtres
377 #=======================================================================
378 filter = []
379 no_filter = []
380 property_group = []
381 for i in bom.type_group_ids :
382 if i.execution_filter :
383 filter.append(i.id)
384 else:
385 no_filter.append(i.id)
386
387 #=======================================================================
388 # Phantom
389 #=======================================================================
390 if bom.type=='phantom' :#and not bom.bom_lines and not bom.bom_components:
391# print_tab(level,"phantom : product search :",bom.product_id.default_code,bom.product_id.name)
392# newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
393# 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)
394# if newbom:
395# if bom.id not in context["bom_tree"]:
396# context["bom_tree"].append(bom.id)
397#
398# 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)
399# result = result + res[0]
400# result2 = result2 + res[1]
401# phantom=True
402# else:
403 phantom=False
404 #=======================================================================
405 # Not phantom
406 #=======================================================================
407 if not phantom:
408 print_tab(level,"not phantom : product :",bom.product_id.name)
409 #===================================================================
410 # Bom without filter
411 #===================================================================
412 if not filter :
413 print_tab(level,"nomenclature sans filtre",context)
414 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)
415 print addthis,bom.bom_lines,bom.bom_components,bom.bom_type
416 if addthis and ((not bom.bom_lines and not bom.bom_components) or bom.bom_type in ('cutinput')):
417 print_tab(level,"*****ajout",bom.product_id.name)
418 proc_property_group = proc_ptr and [i.type_group_id.id for i in proc_ptr.group_property_ids] or []
419 property_group = list(set(proc_property_group) & set(no_filter))
420 bom_property_ids = []
421 for bom_ptr in bom_obj.browse(cr,uid,context["bom_tree"]+[bom.id]):
422 bom_property_ids.extend([i.id for i in bom_ptr.property_ids])
423 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 []
424 property_ids = proc_ptr and [i.id for i in proc_ptr.property_ids] or []
425 property_ids = list(set(proc_property_ids) & set(property_ids))
426 property_ids += bom_property_ids
427 property_ids = list(set(property_ids))
428 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 []
429 vals = {
430 'name': bom.product_id.name,
431 'product_id': bom.product_id.id,
432 'product_qty': bom.product_qty * factor,
433 'product_uom': bom.product_uom.id,
434 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
435 'product_uos': bom.product_uos and bom.product_uos.id or False,
436 'property_ids': [(6,0,property_ids)],
437 'group_property_ids': [(6,0,group_property_ids)],
438 'density':bom.density,
439 'diameter':bom.diameter,
440 'shape':bom.shape,
441 'size_x':bom.size_x,
442 'size_y':bom.size_y,
443 'size_z':bom.size_z,
444 'diameter':bom.diameter,
445 'weight':bom.weight,
446 'bom_id':bom.id,
447 }
448
449 print_tab(level,"++++++++++++++++++++++",)
450 if "bom_line" in context :
451 print_tab(level,"bom_line",context["bom_line"].bom_id.bom_type,context["bom_line"].bom_id.name)
452 if context["bom_line"].bom_id.bom_type not in ('cutinput') :
453 value_size = {
454 'size_x':bom.size_x,
455 'size_y':bom.size_y,
456 'size_z':bom.size_z,
457 'diameter':bom.diameter,
458 'specific_production': proc_ptr and proc_ptr.specific_production,
459 'note_production': proc_ptr and proc_ptr.note_production,
460 'size_x_specific': proc_ptr and proc_ptr.size_x_specific,
461 'size_y_specific': proc_ptr and proc_ptr.size_y_specific,
462 'size_z_specific': proc_ptr and proc_ptr.size_z_specific,
463 'diameter_specific': proc_ptr and proc_ptr.diameter_specific,
464 'size_x_specific_delta': proc_ptr and proc_ptr.size_x_specific_delta,
465 'size_y_specific_delta': proc_ptr and proc_ptr.size_y_specific_delta,
466 'size_z_specific_delta': proc_ptr and proc_ptr.size_z_specific_delta,
467 'diameter_specific_delta': proc_ptr and proc_ptr.diameter_specific_delta,
468 }
469 vals.update(context["bom_line"].compute_size(value_size)[context["bom_line"].id])
470 vals.update({
471 'shape':bom.shape,
472 'specific_production': proc_ptr and proc_ptr.specific_production,
473 'note_production': proc_ptr and proc_ptr.note_production,
474 })
475 else:
476 if proc_ptr:
477 value_size = {
478 'size_x':proc_ptr.size_x,
479 'size_y':proc_ptr.size_y,
480 'size_z':proc_ptr.size_z,
481 'diameter':proc_ptr.diameter,
482 'specific_production': proc_ptr.specific_production,
483 'note_production': proc_ptr.note_production,
484 'size_x_specific': proc_ptr.size_x_specific,
485 'size_y_specific': proc_ptr.size_y_specific,
486 'size_z_specific': proc_ptr.size_z_specific,
487 'diameter_specific': proc_ptr.diameter_specific,
488 'size_x_specific_delta': proc_ptr.size_x_specific_delta,
489 'size_y_specific_delta': proc_ptr.size_y_specific_delta,
490 'size_z_specific_delta': proc_ptr.size_z_specific_delta,
491 'diameter_specific_delta': proc_ptr.diameter_specific_delta,
492 }
493 vals.update(value_size)
494
495 result.append(vals)
496 else:
497 print_tab(level,"*****rec")
498 if bom.id not in context["bom_tree"]:
499 context["bom_tree"].append(bom.id)
500 for bom2 in bom.bom_lines:
501 print_tab(level,"\\"*50)
502 res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id, context=context)
503 print_tab(level,"/"*50)
504 result = result + res[0]
505 result2 = result2 + res[1]
506 for bom2 in bom.bom_components:
507 print_tab(level,"\\"*50)
508 context_child = context.copy()
509 context_child.update({'bom_line':bom2})
510 if bom2.component_id.id not in context["bom_tree"]:
511 print_tab(level,"explode")
512 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)
513 result = result + res[0]
514 result2 = result2 + res[1]
515 print_tab(level,"/"*50)
516 #===================================================================
517 # Bom with filter
518 #===================================================================
519 if filter :
520 print_tab(level,"nomenclature avec filtre")
521 match = False
522 table_match = {}
523 for child in proc_ptr.procurement_line:
524 print_tab(level,"check procuremnt")
525 print_tab(level,"filter",filter)
526 print_tab(level,"child.parent_option_id.type_group.id",child.parent_option_id.type_group.id)
527 print_tab(level,"child.parent_option_id.product_id",child.parent_option_id.product_id.id,child.parent_option_id.product_id.name)
528 print_tab(level,"bom.product_id",bom.product_id.id,bom.product_id.name)
529
530
531 if child.parent_option_id.type_group.id in filter and child.parent_option_id.product_id == bom.product_id:
532 print_tab(level,"ok")
533 if addthis or(not bom.bom_lines and not bom.bom_components):
534 print_tab(level,"*****ajout avec proc",bom.product_id.name)
535 bom_property_ids = []
536 for bom_ptr in bom_obj.browse(cr,uid,context["bom_tree"]+[bom.id]):
537 bom_property_ids.extend([i.id for i in bom_ptr.property_ids])
538 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 []
539 property_ids = child and [i.id for i in child.property_ids] or []
540 property_ids = list(set(proc_property_ids) & set(property_ids))
541 property_ids += bom_property_ids
542 property_ids = list(set(property_ids))
543 result.append(
544 {
545 'name': bom.product_id.name,
546 'product_id': bom.product_id.id,
547 'product_qty': bom.product_qty * factor,
548 'product_uom': bom.product_uom.id,
549 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
550 'product_uos': bom.product_uos and bom.product_uos.id or False,
551 'property_ids': property_ids,
552 'group_property_ids': proc_property_ids,
553 'option_ids': [(6,0,[child.parent_option_id.id])],
554 'procurement_id': child.id,
555 'density':bom.density,
556 'shape':bom.shape,
557 'size_x':child.size_x_specific or bom.size_x,
558 'size_y':child.size_y_specific or bom.size_y,
559 'size_z':child.size_z_specific or bom.size_z,
560 'diameter':child.diameter_specific or bom.diameter,
561 'weight':bom.weight,
562 })
563 else:
564 print_tab(level,"*****rec", "addthis or(not bom.bom_lines and not bom.bom_components)",addthis,not bom.bom_lines,not bom.bom_components)
565 for bom2 in bom.bom_lines:
566 res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=child.id, context=context)
567 result = result + res[0]
568 result2 = result2 + res[1]
569 for bom2 in bom.bom_components:
570 context_child = context.copy()
571 context_child.update({'bom_line':bom2})
572 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)
573 result = result + res[0]
574 result2 = result2 + res[1]
575 else:
576 print_tab(level,"!ok",child.parent_option_id.type_group.id , filter,child.parent_option_id.product_id,bom.product_id)
577 else:
578 #===================================================================
579 # Add routing of bom phantom
580 #===================================================================
581 if bom.routing_id:
582 for wc_use in bom.routing_id.workcenter_lines:
583 wc = wc_use.workcenter_id
584 d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
585 mult = (d + (m and 1.0 or 0.0))
586 cycle = mult * wc_use.cycle_nbr
587 result2.append({
588 'name': bom.routing_id.name,
589 'workcenter_id': wc.id,
590 'sequence': level+(wc_use.sequence or 0),
591 'cycle': cycle,
592 'hour': float(wc_use.hour_nbr*mult + (wc.time_start+wc.time_stop+cycle*wc.time_cycle) * (wc.time_efficiency or 1.0)),
593 })
594 return result, result2
595
596# level_ = "-----------"+("-"*level)
597# if level == 50 : raise
598# print "*"*50
599# 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
600# production_obj = self.pool.get('mrp.production')
601# procurement_obj = self.pool.get('procurement.order')
602#
603# procurement = False
604# production = False
605# if procurement_id:
606# procurement = procurement_obj.browse(cr,uid,procurement_id)
607# if procurement.production_id:
608# production = procurement.production_id
609#
610# factor = factor / (bom.product_efficiency or 1.0)
611# factor = rounding(factor, bom.product_rounding)
612# if factor<bom.product_rounding:
613# factor = bom.product_rounding
614# result = []
615# result2 = []
616# result3 = []
617# phantom=False
618# match = False
619# no_rec = False
620# if bom.type=='phantom':
621# print level_+"phantom"
622# for bom2 in bom.bom_lines:
623# res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
624# result = result + res[0]
625# result2 = result2 + res[1]
626# for bom2 in bom.bom_components:
627# res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
628# result = result + res[0]
629# result2 = result2 + res[1]
630# else:
631# print level_+"not phantom",procurement,bom,bom.type_group_ids
632# filter = []
633# for i in bom.type_group_ids :
634# print i,i.name,i.execution_filter
635# if i.execution_filter :
636# filter.append(i.id)
637# if filter :
638# if procurement and procurement.parent_option_id and procurement.parent_option_id.type_group :
639# print level_+"proc group ",procurement.parent_option_id.type_group.id
640# print level_+"filter ",filter
641# if procurement and procurement.parent_option_id and procurement.parent_option_id.type_group and procurement.parent_option_id.type_group.id in filter:
642# result.append(
643# {
644# 'name': bom.product_id.name,
645# 'product_id': bom.product_id.id,
646# 'product_qty': bom.product_qty * factor,
647# 'product_uom': bom.product_uom.id,
648# 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
649# 'product_uos': bom.product_uos and bom.product_uos.id or False,
650# 'property_ids': [(6,0,[i.id for i in procurement.property_ids])],
651# 'group_property_ids': [(6,0,[i.id for i in procurement.group_property_ids])],
652# 'procurement_ids': [(4,procurement_id)],
653# })
654# no_rec = True
655# else:
656# if procurement :
657# result.append(
658# {
659# 'name': bom.product_id.name,
660# 'product_id': bom.product_id.id,
661# 'product_qty': bom.product_qty * factor,
662# 'product_uom': bom.product_uom.id,
663# 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
664# 'product_uos': bom.product_uos and bom.product_uos.id or False,
665# 'property_ids': [(6,0,[i.id for i in procurement.property_ids])],
666# 'group_property_ids': [(6,0,[i.id for i in procurement.group_property_ids])],
667# 'procurement_ids': [(4,procurement_id)],
668# })
669# no_rec = True
670## for bom2 in bom.bom_lines:
671## if bom2.product_id.supply_method in ('produce'):
672## if production:
673## vals = {
674## 'name':'PROD2:'+production.name,
675## 'date_planned': production.date_planned,
676## 'product_id': bom2.product_id.id,
677## 'product_qty': bom2.product_qty,
678## 'product_uom': bom2.product_uom.id,
679## 'product_uos_qty': bom2.product_uos and line.product_uos_qty or False,
680## 'product_uos': bom2.product_uos and line.product_uos.id or False,
681## 'location_id': production.location_src_id.id,
682## 'location_dest_id': bom2.product_id.product_tmpl_id.property_stock_production.id,
683### 'move_dest_id': res_final_id,
684## 'state': 'waiting',
685### 'prodlot_id': line_prodlot_id,
686## }
687## result3.append(vals)
688## for bom2 in bom.bom_components:
689## bom2=bom2.component_id
690## if bom2.product_id.supply_method in ('produce'):
691## if production:
692## vals = {
693## 'name':'PROD2:'+production.name,
694## 'date_planned': production.date_planned,
695## 'product_id': bom2.product_id.id,
696## 'product_qty': bom2.product_qty,
697## 'product_uom': bom2.product_uom.id,
698## 'product_uos_qty': bom2.product_uos and line.product_uos_qty or False,
699## 'product_uos': bom2.product_uos and line.product_uos.id or False,
700## 'location_id': production.location_src_id.id,
701## 'location_dest_id': bom2.product_id.product_tmpl_id.property_stock_production.id,
702### 'move_dest_id': res_final_id,
703## 'state': 'waiting',
704### 'prodlot_id': line_prodlot_id,
705## }
706## result3.append(vals)
707# if not no_rec:
708# for bom2 in bom.bom_lines:
709# res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level+10)
710# result = result + res[0]
711# result2 = result2 + res[1]
712# for bom2 in bom.bom_components:
713# res = self._bom_explode(cr, uid, bom2.component_id, factor, properties, addthis=True, level=level+10, group_properties=group_properties, procurement_id=procurement_id)
714# result = result + res[0]
715# result2 = result2 + res[1]
716# print level_+"result ---------> ",result
717#
718# return result, result2, []
719
720 def gen_graph(self,cr,uid,ids,context):
721 bom_node = []
722 bom_link = []
723 gen_graph_tab = []
724 gen_graph_desc_tab = []
725 gen_graph_asc_tab = []
726 def gen_graph(bom):
727# print "gen_graph"
728 result = ""
729 if bom.id not in gen_graph_tab:
730 gen_graph_tab.append(bom.id)
731 result+=rec_gen_graph_desc(bom)
732 result+=rec_gen_graph_asc(bom)
733 return result
734
735 def rec_gen_graph_desc(bom):
736# print "rec_gen_graph_desc"
737 result = ""
738 if bom.id not in bom_node:
739 bom_node.append(bom.id)
740 result += str(bom.id)+" [label=\""+bom.name+"\"] "+";\n"
741 for line in bom.bom_components:
742 if str(bom.id)+"_"+str(line.component_id.id) not in bom_link:
743 bom_link.append(str(bom.id)+"_"+str(line.component_id.id))
744 result += str(bom.id)+" -> "+str(line.component_id.id)+";\n"
745 result += rec_gen_graph_desc(line.component_id)
746 result += gen_graph(line.component_id)
747 return result
748
749 def rec_gen_graph_asc(bom):
750# print "rec_gen_graph_asc"
751 result = ""
752 if bom.id not in bom_node:
753 bom_node.append(bom.id)
754 result += str(bom.id)+" [label=\""+bom.name+"\"] "+";\n"
755 for line in bom.bom_components_parent:
756 if str(line.bom_id.id)+"_"+str(bom.id) not in bom_link:
757 bom_link.append(str(line.id)+"_"+str(bom.id))
758 result += str(line.bom_id.id)+" -> "+str(bom.id)+";\n"
759 result += rec_gen_graph_asc(line.bom_id)
760 result += gen_graph(line.bom_id)
761 return result
762
763 #print "digraph G {"
764 #for bom in self.browse(cr,uid,ids,context):
765 # print gen_graph(bom)
766 #print "}"
767 return True
768
769 def gen_graph_dot(self,cr,uid,ids,context={}):
770
771 try:
772 import pydot
773 except Exception,e:
774 _logger.notifyChannel('workflow', netsvc.LOG_WARNING,
775 'Import Error for pydot, you will not be able to render workflows\n'
776 'Consider Installing PyDot or dependencies: http://dkbza.org/pydot.html')
777 raise e
778
779 self.done = False
780
781 graph = pydot.Dot(fontsize='16', label="""\\\n\\nBOM: """,
782 size='10.7, 7.3', center='1', ratio='auto', rotate='90', rankdir='LR'
783 )
784
785 bom_node = []
786 bom_link = []
787 gen_graph_tab = []
788 gen_graph_desc_tab = []
789 gen_graph_asc_tab = []
790 def gen_graph(bom):
791 result = ""
792 if bom.id not in gen_graph_tab:
793 gen_graph_tab.append(bom.id)
794 result+=rec_gen_graph_desc(bom)
795# result+=rec_gen_graph_asc(bom)
796 return result
797
798 def rec_gen_graph_desc(bom):
799 result = ""
800 if bom.id not in bom_node:
801 bom_node.append(bom.id)
802 args = {'label':bom.product_id and bom.product_id.default_code or "E"}
803 graph.add_node(pydot.Node(str(bom.id), **args))
804 for line in bom.bom_components:
805 if str(bom.id)+"_"+str(line.component_id.id) not in bom_link:
806 bom_link.append(str(bom.id)+"_"+str(line.component_id.id))
807 label = "|"
808 for i in bom.type_group_ids :
809 if i.execution_filter:
810 if label :
811 label+= "|"
812 label+= i.name
813 args = {'label':label}
814 graph.add_edge(pydot.Edge( str(bom.id) ,str(line.component_id.id), fontsize='10', **args))
815 result += rec_gen_graph_desc(line.component_id)
816# result += gen_graph(line)
817 return result
818
819 def rec_gen_graph_asc(bom):
820 result = ""
821 if bom.id not in bom_node:
822 bom_node.append(bom.id)
823 args = {'label':bom.product_id and bom.product_id.default_code or "E"}
824 graph.add_node(pydot.Node(str(bom.id), **args))
825 for line in bom.bom_components_parent:
826 if str(line.bom_id.id)+"_"+str(bom.id) not in bom_link:
827 bom_link.append(str(line.bom_id.id)+"_"+str(bom.id))
828 args = {'label':''}
829 graph.add_edge(pydot.Edge( str(line.bom_id.id) ,str(bom.id), fontsize='10', **args))
830 result += rec_gen_graph_asc(line.bom_id)
831# result += gen_graph(line)
832 return result
833
834
835 for bom in self.browse(cr,uid,ids,context):
836 gen_graph(bom)
837
838 return graph
839
840
841
842mrp_bom()
843# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file844\ No newline at end of file
1845
=== added file 'asperience_configurator_mrp/mrp_data.xml'
--- asperience_configurator_mrp/mrp_data.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_data.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,85 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="0">
4
5 <!--
6 Description Dx Dy Dz Dd
7 [Modifier] side Dz Dx [Supprimer]
8 [Modifier] top Dy Dx [Supprimer]
9 [Modifier] bottom Dy Dx [Supprimer]
10 [Modifier] back Dy Dz [Supprimer]
11 [Modifier] front Dy Dz-->
12 <record id="mode_side" model="mrp.bom.component.mode">
13 <field name="name" >side</field>
14 <field name="dx" eval="'Dy'" />
15 <field name="dy" eval="'Dz'" />
16 <field name="dz" eval="''" />
17 <field name="dd" eval="''" />
18 </record>
19 <record id="mode_top" model="mrp.bom.component.mode">
20 <field name="name">top</field>
21 <field name="dx" eval="'Dx'" />
22 <field name="dy" eval="'Dy'" />
23 <field name="dz" eval="''" />
24 <field name="dd" eval="''" />
25 </record>
26 <record id="mode_bottom" model="mrp.bom.component.mode">
27 <field name="name" >bottom</field>
28 <field name="dx" eval="'Dx'" />
29 <field name="dy" eval="'Dy'" />
30 <field name="dz" eval="''" />
31 <field name="dd" eval="''" />
32 </record>
33 <record id="mode_back" model="mrp.bom.component.mode">
34 <field name="name" >back</field>
35 <field name="dx" eval="'Dx'" />
36 <field name="dy" eval="'Dz'" />
37 <field name="dz" eval="''" />
38 <field name="dd" eval="''" />
39 </record>
40 <record id="mode_front" model="mrp.bom.component.mode">
41 <field name="name" >front</field>
42 <field name="dx" eval="'Dx'" />
43 <field name="dy" eval="'Dz'" />
44 <field name="dz" eval="''" />
45 <field name="dd" eval="''" />
46 </record>
47 <!--
48 <record id="mode_side" model="mrp.bom.component.mode">
49 <field name="name" >side</field>
50 <field name="dx" eval="'Dy'" />
51 <field name="dy" eval="''" />
52 <field name="dz" eval="''" />
53 <field name="dd" eval="''" />
54 </record>
55 <record id="mode_top" model="mrp.bom.component.mode">
56 <field name="name">top</field>
57 <field name="dx" eval="'Dx'" />
58 <field name="dy" eval="'Dy'" />
59 <field name="dz" eval="'Dz'" />
60 <field name="dd" eval="''" />
61 </record>
62 <record id="mode_bottom" model="mrp.bom.component.mode">
63 <field name="name" >bottom</field>
64 <field name="dx" eval="'Dx'" />
65 <field name="dy" eval="'Dy'" />
66 <field name="dz" eval="'Dz'" />
67 <field name="dd" eval="''" />
68 </record>
69 <record id="mode_back" model="mrp.bom.component.mode">
70 <field name="name" >back</field>
71 <field name="dx" eval="''" />
72 <field name="dy" eval="'Dx'" />
73 <field name="dz" eval="''" />
74 <field name="dd" eval="''" />
75 </record>
76 <record id="mode_front" model="mrp.bom.component.mode">
77 <field name="name" >front</field>
78 <field name="dx" eval="''" />
79 <field name="dy" eval="'Dx'" />
80 <field name="dz" eval="''" />
81 <field name="dd" eval="''" />
82 </record>
83 -->
84 </data>
85</openerp>
086
=== added file 'asperience_configurator_mrp/mrp_procurement.pyc'
1Binary 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 differ87Binary 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
=== added file 'asperience_configurator_mrp/mrp_production.py'
--- asperience_configurator_mrp/mrp_production.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_production.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,593 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23import inspect
24
25class mrp_production(osv.osv):
26 _inherit = 'mrp.production'
27
28 def _size(self, cr, uid, ids, field_name, arg, context):
29 res = {}
30 for proc in self.browse(cr, uid, ids):
31 res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 , 'diameter': 0.0}
32 if proc.product_id:
33 res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
34 res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
35 res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
36 res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
37 return res
38
39 def action_compute(self, cr, uid, ids, context={}):
40 print "action_compute",ids,context
41 results = []
42 for production in self.browse(cr, uid, ids):
43 cr.execute('delete from mrp_production_product_line where production_id=%s', (production.id,))
44 cr.execute('delete from mrp_production_workcenter_line where production_id=%s', (production.id,))
45 bom_point = production.bom_id
46 bom_id = production.bom_id.id
47 filter = []
48 properties = []
49 group_properties = []
50
51 #Lors de la crƩation du mrp.production, il faut s'assurer que tous les procurements sommƩs sur la production
52 #ont les mĆŖmes propriĆ©tĆ©s et les mĆŖmes groupes de propriĆ©tĆ©s
53 if production and production.procurement_ids and production.procurement_ids[0].parent_option_id and production.procurement_ids[0].parent_option_id.type_group :
54 filter.append(production.procurement_ids[0].parent_option_id.type_group.id)
55 group_properties = [i.id for i in production.procurement_ids[0].group_property_ids]
56# #===============================================================
57# # CrƩation des lignes de production
58# #===============================================================
59# for procurement in production.procurement_ids:
60# if procurement.bom_id and procurement.bom_id.bom_type in ('cut'):
61# vals = {
62# 'production_id': production.id,
63# 'procurement_id': procurement.id,
64# 'bom_id':procurement.move_id.prodlot_id.mrp_production_id.bom_id.id,
65#
66# 'name': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_id.name,
67# 'product_id': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_id.id,
68# 'product_qty': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_qty,
69# 'product_uom': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uom.id,
70# 'product_uos_qty': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uos and bom.product_uos_qty * factor or False,
71# 'product_uos': procurement.move_id.prodlot_id.mrp_production_id.bom_id.product_uos and bom.product_uos.id or False,
72# 'property_ids': [i.id for i in procurement.property_ids],
73# 'group_property_ids': [i.id for i in procurement.group_property_ids],
74# 'density':procurement.move_id.prodlot_id.mrp_production_id.bom_id.density,
75# 'diameter':procurement.move_id.prodlot_id.mrp_production_id.bom_id.diameter,
76# 'shape':procurement.move_id.prodlot_id.mrp_production_id.bom_id.shape,
77# 'weight':procurement.move_id.prodlot_id.mrp_production_id.bom_id.weight,
78# 'size_x':procurement.size_x,
79# 'size_y':procurement.size_y,
80# 'size_z':procurement.size_z,
81# 'diameter':procurement.diameter,
82# 'specific_production': procurement.specific_production,
83# 'note_production': procurement.note_production,
84# 'size_x_specific': procurement.size_x_specific,
85# 'size_y_specific': procurement.size_y_specific,
86# 'size_z_specific': procurement.size_z_specific,
87# 'diameter_specific': procurement.diameter_specific,
88# 'size_x_specific_delta': procurement.size_x_specific_delta,
89# 'size_y_specific_delta': procurement.size_y_specific_delta,
90# 'size_z_specific_delta': procurement.size_z_specific_delta,
91# 'diameter_specific_delta': procurement.diameter_specific_delta,
92# }
93# self.pool.get('mrp.production.product.line').create(cr,uid,vals)
94# procurement.move_id.write({'production_id':production.id})
95
96 if not bom_point:
97 bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, production.product_id.id, production.product_uom.id, properties, filter)
98 if bom_id:
99 bom_point = self.pool.get('mrp.bom').browse(cr, uid, bom_id)
100 routing_id = bom_point.routing_id.id or False
101 self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})
102
103 if not bom_id:
104 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)) ) )
105
106 #if bom_point.routing_id and bom_point.routing_id.location_id:
107 # self.write(cr, uid, [production.id], {'location_src_id': bom_point.routing_id.location_id.id})
108
109 factor = production.product_qty * production.product_uom.factor / bom_point.product_uom.factor
110 print "production.procurement_ids[0]",production.procurement_ids[0]
111 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)
112 results = res[0]
113 results2 = res[1]
114 print "1111111111"
115 for line in results:
116 print line
117 line['production_id'] = production.id
118 self.pool.get('mrp.production.product.line').create(cr, uid, line)
119 print "2222222222"
120 for line in results2:
121 print line
122 line['production_id'] = production.id
123 self.pool.get('mrp.production.workcenter.line').create(cr, uid, line)
124 return len(results)
125
126 def action_confirm(self, cr, uid, ids):
127# print "action_confirm stock.production"
128 lot_obj = self.pool.get('stock.production.lot')
129 picking_obj = self.pool.get('stock.picking')
130 move_obj = self.pool.get('stock.move')
131
132 picking_id=False
133 proc_ids = []
134 for production in self.browse(cr, uid, ids):
135 #===================================================================
136 # Test production dƩjƠ confirmƩ
137 #===================================================================
138 if production.state in ('confirmed'):
139 picking_id = production.picking_id.id
140 continue
141 #===================================================================
142 # Compute si pas dƩjƠ fait
143 #===================================================================
144 if not production.product_lines:
145 self.action_compute(cr, uid, [production.id])
146 production = self.browse(cr, uid, [production.id])[0]
147 #===================================================================
148 # Init des variables
149 #===================================================================
150 moves = []
151 routing_loc = None
152 pick_type = 'internal'
153 address_id = False
154 company = self.pool.get('res.users').browse(cr, uid, uid).company_id
155 source = production.product_id.product_tmpl_id.property_stock_production.id
156 if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
157 routing_loc = production.bom_id.routing_id.location_id
158 if routing_loc.usage<>'internal':
159 pick_type = 'out'
160 address_id = routing_loc.address_id and routing_loc.address_id.id or False
161 routing_loc = routing_loc.id
162
163 #===================================================================
164 # Creation du picking de sortie
165 #===================================================================
166 vals = {
167 'origin': (production.origin or '').split(':')[0] +':'+production.name,
168 'type': pick_type,
169 'move_type': 'one',
170 'state': 'auto',
171 'address_id': address_id,
172 'partner_shipping_id':address_id,
173 'auto_picking': self._get_auto_picking(cr, uid, production),
174 }
175 picking_id = picking_obj.create(cr, uid, vals)
176 print_tab("*"*50)
177 print_tab("Creation du picking de sortie")
178 print_tab(vals)
179 #===================================================================
180 # Rehcherche du lot + Creation du lot s'il n'Ć©xiste pas
181 #===================================================================
182 vals = {
183 'product_id': production.product_id.id,
184 'date': datetime.datetime.now(),
185 'mrp_production_id': production.id,
186 'property_ids': production.procurement_ids and [(6,0,[i.id for i in production.procurement_ids[0].property_ids])] or [(6,0,[])],
187 'group_property_ids': production.procurement_ids and [(6,0,[i.id for i in production.procurement_ids[0].group_property_ids])] or [(6,0,[])],
188 '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,[])],
189 'density': production.bom_id.density,
190 'diameter': production.bom_id.diameter,
191 'shape': production.bom_id.shape,
192 'size_x': production.procurement_ids[0].size_x_specific or production.bom_id.size_x,
193 'size_y': production.procurement_ids[0].size_y_specific or production.bom_id.size_y,
194 'size_z': production.procurement_ids[0].size_z_specific or production.bom_id.size_z,
195 'weight': production.bom_id.weight,
196 }
197 prodlot_id = lot_obj.search_specific(cr,uid,vals,company.tracking_production_delay)
198 if not prodlot_id:
199 vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.lot.serial')
200 prodlot_id = lot_obj.create(cr, uid, vals)
201 revision_id = self.pool.get('stock.production.lot.revision').create(cr, uid, {
202 'name': (production.origin or '').split(':')[0] +':'+production.name,
203 'description': (production.origin or '').split(':')[0] +':'+production.name,
204 'date': datetime.datetime.now(),
205 'author_id': uid,
206 'lot_id': prodlot_id,
207 })
208 #===================================================================
209 # Update des moves
210 #===================================================================
211 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], {
212 'prodlot_id': prodlot_id,
213 })
214
215
216 print_tab("*"*50)
217 print_tab("production",production)
218 print_tab("production",production.procurement_ids)
219 print_tab("*"*50)
220# raise
221
222 #===================================================================
223 # Creation des lignes de workcenter
224 #===================================================================
225 if production.bom_id and production.bom_id.routing_id:
226 print production.bom_id
227 for wc_use in production.bom_id.routing_id.workcenter_lines:
228 wc = wc_use.workcenter_id
229 factor = production.product_qty * production.product_uom.factor / production.bom_id.product_uom.factor
230 d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
231 mult = (d + (m and 1.0 or 0.0))
232 cycle = mult * wc_use.cycle_nbr
233 move_ids = []
234
235 self.pool.get('mrp.production.workcenter.line').create(cr,uid,{
236 'production_id': production.id,
237 'name': production.bom_id.routing_id.name,
238 'workcenter_id': wc.id,
239 'sequence': wc_use.sequence or 0,
240 'cycle': cycle,
241 'hour': float(wc_use.hour_nbr*mult + (wc.time_start+wc.time_stop+cycle*wc.time_cycle) * (wc.time_efficiency or 1.0)),
242 'move_ids': [(6,0,move_ids)],
243 })
244
245 #===================================================================
246 # Creation du mouvement de sortie
247 #===================================================================
248 # TODO : voir pourquoi le picking il n'est pas reliƩ au picking de sortie crƩƩ plus haut
249
250 res_final_id = False
251 if production.bom_id.bom_type in ('cut'):
252 for proc in production.procurement_ids:
253 if proc.move_id.id:
254 res_final_id = proc.move_id.id
255 vals = {
256 'production_id':production.id,
257 }
258 move_obj.write(cr, uid, res_final_id, vals)
259 else:
260 vals = {
261 'name':'PROD1:'+production.name,
262 'date_planned': production.date_planned,
263 'product_id': production.product_id.id,
264 'product_qty': production.product_qty,
265 'product_uom': production.product_uom.id,
266 'product_uos_qty': production.product_uos and production.product_uos_qty or False,
267 'product_uos': production.product_uos and production.product_uos.id or False,
268 'location_id': source,
269 'location_dest_id': production.location_dest_id.id,
270 'move_dest_id': production.move_prod_id.id,
271 'state': 'waiting',
272 'prodlot_id': prodlot_id,
273 'production_id':production.id,
274 }
275 res_final_id = move_obj.create(cr, uid, vals)
276 print_tab("*"*50)
277 print_tab("Creation du mouvement de sortie")
278 print_tab(vals)
279
280# self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
281
282 #===================================================================
283 # Parcours des ligne de production
284 #===================================================================
285 for line in production.product_lines:
286 move_id = False
287 line_prodlot_id = False
288# production_id = False
289 #===============================================================
290 # Test if bom is assemble or disassemble
291 #===============================================================
292 print "--------------",line.bom_id.bom_type
293 if production.bom_id.bom_type in ('cutinput'):
294 product_id = production.product_id.id
295 else:
296 product_id = line.product_id.id
297
298 if line.product_id.type in ('product', 'consu'):
299 #===========================================================
300 # Recherche du lot, crƩation d'il n'Ʃxiste pas
301 #===========================================================
302 vals = {
303 'product_id': product_id,
304 'date': datetime.datetime.now(),
305 'mrp_production_id': production.id,
306 'property_ids': [(6,0,[i.id for i in line.property_ids])] or [(6,0,[])],
307 'group_property_ids': [(6,0,[i.id for i in line.group_property_ids])] or [(6,0,[])],
308 'option_ids': [(6,0,[i.id for i in line.option_ids])] or [(6,0,[])],
309 'density':line.density,
310 'diameter':line.specific_production and line.diameter_specific or line.diameter,
311 'shape':line.shape,
312 'size_x': line.specific_production and line.size_x_specific or line.size_x,
313 'size_y': line.specific_production and line.size_y_specific or line.size_y,
314 'size_z': line.specific_production and line.size_z_specific or line.size_z,
315 'weight':line.weight,
316 }
317 if line.procurement_id :
318 line_prodlot_id = line.procurement_id.move_id.prodlot_id.id
319 if not line_prodlot_id:
320 vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.lot.serial')
321 line_prodlot_id = lot_obj.search_specific(cr,uid,vals,company.tracking_production_delay)
322 if not line_prodlot_id:
323 line_prodlot_id = lot_obj.create(cr, uid, vals)
324 revision_id = self.pool.get('stock.production.lot.revision').create(cr, uid, {
325 'name': (production.origin or '').split(':')[0] +':'+production.name,
326 'description': (production.origin or '').split(':')[0] +':'+production.name,
327 'date': datetime.datetime.now(),
328 'author_id': uid,
329 'lot_id': line_prodlot_id,
330 })
331
332# #===========================================================
333# # Recuperation de la production en cours associƩ au lot
334# #===========================================================
335# if line_prodlot_id and line.bom_id.bom_type in ('cut'):
336# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',line_prodlot_id),('production_id','!=',False),('production_id.state','=','confirmed')])
337# if move_ids:
338# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
339 #===========================================================
340 # Recherche ou creation du move de sortie + enregistrement sur la production en entrƩe
341 #===========================================================
342 if not line.procurement_id :
343 vals = {
344 'name':'PROD22:'+production.name,
345 'date_planned': production.date_planned,
346 'product_id': product_id,
347 'product_qty': line.product_qty,
348 'product_uom': line.product_uom.id,
349 'product_uos_qty': line.product_uos and line.product_uos_qty or False,
350 'product_uos': line.product_uos and line.product_uos.id or False,
351 'location_id': routing_loc or production.location_src_id.id,
352 'location_dest_id': source,
353 'move_dest_id': res_final_id,
354 'state': 'waiting',
355 'prodlot_id': line_prodlot_id,
356 }
357 res_dest_id = self.pool.get('stock.move').create(cr, uid, vals)
358 moves.append(res_dest_id)
359 print_tab("/"*50)
360 print_tab("creation du move de sortie de ligne")
361 print_tab(vals)
362 else:
363 res_dest_id = line.procurement_id.move_id.id
364 self.write(cr, uid, [production.id], {'move_lines': [(4,res_dest_id)]})
365 #===========================================================
366 # CrƩation du move suivant le move de production
367 #===========================================================
368 vals = {
369 'name':'PROD3:'+production.name,
370 'picking_id':picking_id,
371 'product_id': product_id,
372 'product_qty': line.product_qty,
373 'product_uom': line.product_uom.id,
374 'product_uos_qty': line.product_uos and line.product_uos_qty or False,
375 'product_uos': line.product_uos and line.product_uos.id or False,
376 'date_planned': production.date_planned,
377 'move_dest_id': res_dest_id,
378 'location_id': production.location_src_id.id,
379 'location_dest_id': routing_loc or production.location_src_id.id,
380 'state': 'waiting',
381 'prodlot_id': line_prodlot_id,
382# 'production_id': production_id,
383 }
384 print_tab("CrƩation du move suivant le move de sortie")
385 print_tab(vals)
386 move_id = self.pool.get('stock.move').create(cr, uid, vals)
387 #===============================================================
388 # CrƩation du procurement pour la ligne s'il n'Ʃxiste pas + update de la ligne
389 #===============================================================
390 if not line.procurement_id :
391# production_id = False
392 vals = {
393 'name': (production.origin or '').split(':')[0] + ':' + production.name,
394 'origin': (production.origin or '').split(':')[0] + ':' + production.name,
395 'date_planned': production.date_planned,
396 'product_id': line.product_id.id,
397 'product_qty': line.product_qty,
398 'product_uom': line.product_uom.id,
399 'product_uos_qty': line.product_uos and line.product_qty or False,
400 'product_uos': line.product_uos and line.product_uos.id or False,
401 'property_ids': [(6,0,[i.id for i in line.property_ids])],
402 'group_property_ids': [(6,0,[i.id for i in line.group_property_ids])],
403 'option_ids': [(6,0,[i.id for i in line.option_ids])],
404 'size_x':line.size_x,
405 'size_y':line.size_y,
406 'size_z':line.size_z,
407 'diameter':line.diameter,
408 'specific_production': line.specific_production,
409 'note_production': line.note_production,
410 'size_x_specific': line.size_x_specific,
411 'size_y_specific': line.size_y_specific,
412 'size_z_specific': line.size_z_specific,
413 'diameter_specific': line.diameter_specific,
414 'size_x_specific_delta': line.size_x_specific_delta,
415 'size_y_specific_delta': line.size_y_specific_delta,
416 'size_z_specific_delta': line.size_z_specific_delta,
417 'diameter_specific_delta': line.diameter_specific_delta,
418 'location_id': production.location_src_id.id,
419 'procure_method': line.product_id.procure_method,
420 'move_id': move_id,
421 'bom_id': line.bom_id and line.bom_id.id or False,
422# 'production_id':production_id,
423 }
424 proc_id = self.pool.get('procurement.order').create(cr, uid, vals)
425 print_tab("CrƩation du procurement")
426 print_tab(vals)
427 self.pool.get('mrp.production.product.line').write(cr, uid, line.id, {'procurement_id':proc_id})
428 #===========================================================
429 # Validation du procurement
430 #===========================================================
431 wf_service = netsvc.LocalService("workflow")
432 wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
433 proc_ids.append(proc_id)
434 #===================================================================
435 # Validation du picking de sortie
436 #===================================================================
437 wf_service = netsvc.LocalService("workflow")
438 wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
439 self.write(cr, uid, [production.id], {'picking_id':picking_id, 'state':'confirmed'})
440# raise
441 return picking_id
442
443 _columns = {
444 'procurement_ids': fields.one2many('procurement.order', 'production_id', 'Procurements'),
445 'specific_production':fields.boolean('Specific Production'),
446 'note_production':fields.text('Production Note'),
447 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
448 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
449 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
450 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
451 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True),
452 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
453 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
454 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
455 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
456 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
457 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
458 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
459 }
460 _order = 'id desc'
461
462 def action_production_end(self, cr, uid, ids):
463# move_ids = []
464 for production in self.browse(cr, uid, ids):
465 for res in production.move_lines:
466 for move in production.move_created_ids:
467 #XXX must use the orm
468# cr.execute('INSERT INTO stock_move_history_ids \
469# (parent_id, child_id) VALUES (%s,%s)',
470# (res.id, move.id))
471 #ASPerience: test des valeurs pour Ʃviter les erreurs de rƩƩcriture
472 cr.execute('select parent_id,child_id from stock_move_history_ids where parent_id=%s and child_id=%s', (res.id, move.id))
473 if len(cr.fetchall()) == 0:
474 cr.execute('insert into stock_move_history_ids (parent_id,child_id) values (%s,%s)', (res.id, move.id))
475 else:
476 logger = netsvc.Logger()
477 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)))
478 #Fin ASPerience
479# move_ids.append(res.id)
480 vals= {'state':'confirmed'}
481 new_moves = [x.id for x in production.move_created_ids]
482 self.pool.get('stock.move').write(cr, uid, new_moves, vals)
483 if not production.date_finnished:
484 self.write(cr, uid, [production.id],
485 {'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
486 self.pool.get('stock.move').check_assign(cr, uid, new_moves)
487 self.pool.get('stock.move').action_done(cr, uid, new_moves)
488 self._costs_generate(cr, uid, production)
489# self.pool.get('stock.move').action_done(cr, uid, move_ids)
490 self.write(cr, uid, ids, {'state': 'done'})
491 return True
492
493mrp_production()
494
495class mrp_production_product_line(osv.osv):
496 _inherit = 'mrp.production.product.line'
497
498 _columns = {
499 #Properties
500 'property_ids': fields.many2many('mrp.property', 'mrp_production_product_line_property_rel', 'line_id','property_id', 'Properties'),
501 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_production_line_group_property_rel','production_line_id', 'group_id', 'Product Property Group Rel '),
502 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
503 'option_ids': fields.many2many('product.links', 'mrp_production_product_line_options_rel','line_id', 'links_id', 'Option'),
504 'bom_id': fields.many2one('mrp.bom', 'Bom'),
505 #Dimensions
506 'size_x': fields.float('Width', digits=(16, 5)),
507 'size_y': fields.float('Lenght', digits=(16, 5)),
508 'size_z': fields.float('Thickness', digits=(16, 5)),
509 'density': fields.float('Density', digits=(16, 5)),
510 'shape' : fields.selection([('quadrangular', 'Quadrangular'), ('cylindrical', 'Cylindrical'), ('other', 'Other')], 'Shape', required=True),
511 'diameter' : fields.float('Diameter', digits=(16, 5)),
512 'weight': fields.float('Weight', digits=(16, 5)),
513 'specific_production':fields.boolean('Specific Production'),
514 'note_production':fields.text('Production Note'),
515 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
516 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
517 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
518 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
519 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
520 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
521 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
522 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
523
524 'uom_d_size' : fields.related('product_id', 'uom_d_size', help="Default united of measure density used for operations size to cube"),
525 'uom_d_weight': fields.related('product_id', 'uom_d_weight', help="Default united of measure density used for operations weight"),
526 'uom_s_size' : fields.related('product_id', 'uom_s_size', help="Default united of measure used for operations size"),
527 }
528 _defaults = {
529 'shape': lambda * a: 'other',
530 }
531
532 def onchange_product_id(self, cr, uid, ids, product_id, context={}):
533 if product_id:
534 w = self.pool.get('product.product').browse(cr, uid, product_id, context)
535 factor1 = w.uom_d_weight.factor
536 factor2 = w.uom_id.factor
537 factor3 = w.uom_d_size.factor
538 factor4 = w.uom_s_size.factor
539 v = {
540 'product_uom':w.uom_id.id,
541 'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id,
542 'size_x':w.size_x or w.size_x_tmpl,
543 'size_y':w.size_y or w.size_y_tmpl,
544 'size_z':w.size_z or w.size_z_tmpl,
545 'density':w.density or w.density_tmpl,
546 'shape':w.shape,
547 'diameter':w.diameter or w.diameter_tmpl,
548 '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']
549 }
550 return {'value': v}
551 return {}
552
553 def compute_weight(self, cr, uid, id, product_id, size_x, size_y, size_z, shape, density, diameter):
554 if product_id:
555 product = self.pool.get('product.product').browse(cr, uid, product_id, context='')
556 factor1 = product.uom_d_weight.factor
557 factor2 = product.uom_id.factor
558 factor3 = product.uom_d_size.factor
559 factor4 = product.uom_s_size.factor
560 return {'value': compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter)}
561
562mrp_production_product_line()
563
564class mrp_production_workcenter_line(osv.osv):
565 _inherit = 'mrp.production.workcenter.line'
566 _columns = {
567 'move_ids' : fields.many2many('stock.move', 'mrp_production_workcenter_line_stock_move_rel', 'line_id', 'move_id', 'Moves'),
568 }
569 _defaults = {
570 }
571mrp_production_workcenter_line()
572
573def print_tab(*args):
574 cc = 0
575 try:
576 tmp = inspect.stack()[1]
577 for i in tmp[4][0]:
578 if i == ' ':
579 cc+=1
580 else:
581 break
582
583 if isinstance(args[0],int):
584 print "-"*args[0],
585 args = args[1:]
586 print str(tmp[2]).ljust(4),
587 print " "*cc,
588 except:
589 pass
590 for i in args:
591 print i,
592 print
593# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file594\ No newline at end of file
1595
=== added file 'asperience_configurator_mrp/mrp_property.py'
--- asperience_configurator_mrp/mrp_property.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_property.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,99 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23#import openerp.netsvc
24#import time
25#import datetime
26#from mx import DateTime
27#from openerp.tools.translate import _
28#from openerp.tools import ustr
29
30class mrp_property_group_option(osv.osv):
31 _name = 'mrp.property.group.option'
32 _description = 'GOP / Property'
33 _columns = {
34 'name': fields.char('Name', size=256, required=True),
35 'type_group_id': fields.many2one('product.type.property.option', 'GOP', required=True),
36 'property_id': fields.many2one('mrp.property', 'Property', required=True),
37 }
38 _defaults = {
39 }
40
41 def onchange_group_property(self, cr, uid, id, type_group_id, property_id):
42 res = {'value':{}}
43 if type_group_id and not property_id :
44 type_group = self.pool.get("product.type.property.option").browse(cr,uid,type_group_id)
45 res['value']['name'] = type_group.name+"[X]"
46 elif not type_group_id and property_id :
47 property = self.pool.get("mrp.property").browse(cr,uid,property_id)
48 res['value']['name'] = "X["+property.name+"]"
49 elif type_group_id and property_id :
50 type_group = self.pool.get("product.type.property.option").browse(cr,uid,type_group_id)
51 property = self.pool.get("mrp.property").browse(cr,uid,property_id)
52 res['value']['name'] = type_group.name+"["+property.name+"]"
53 return res
54
55mrp_property_group_option()
56
57class mrp_property_group(osv.osv):
58 _inherit = 'mrp.property.group'
59 _columns = {
60 'property_ids': fields.one2many('mrp.property', 'group_id', 'Properties'),
61 }
62 _defaults = {
63 }
64mrp_property_group()
65
66class mrp_property(osv.osv):
67 _inherit = 'mrp.property'
68
69 def name_get(self, cr, uid, ids, context=None):
70 if not ids:
71 return []
72 reads = self.read(cr, uid, ids, ['name','code'], context)
73 res = []
74 for record in reads:
75 name = "[%s] %s" % (record['code'],record['name'])
76 res.append((record['id'], name))
77 return res
78
79 _columns = {
80 'code': fields.char('Code', size=64, required=True),
81 'price': fields.float('Price'),
82 'size_x_tmpl': fields.float('Width', digits=(16, 5)),
83 'size_y_tmpl': fields.float('Length', digits=(16, 5)),
84 'size_z_tmpl': fields.float('Thickness', digits=(16, 5)),
85 'diameter_tmpl': fields.float('Diameter', digits=(16, 5)),
86 'uom_s_size_tmpl' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size"),
87 }
88 _defaults = {
89 'code': lambda *a: 'XXX',
90 'price': lambda *a: 0.0,
91 'size_x_tmpl': lambda *a: 0,
92 'size_y_tmpl': lambda *a: 0,
93 'size_z_tmpl': lambda *a: 0,
94 'diameter_tmpl': lambda *a: 0,
95 'composition': lambda *a: 'plus',
96 }
97mrp_property()
98
99# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file100\ No newline at end of file
1101
=== added file 'asperience_configurator_mrp/mrp_report.xml'
--- asperience_configurator_mrp/mrp_report.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_report.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,20 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <report auto="False"
5 header="False"
6 id="report_bom"
7 model="mrp.bom"
8 name="bom"
9 string="BOM Graph"/>
10
11 <report auto="True"
12 header="False"
13 id="mrp.report_bom_structure"
14 model="mrp.bom"
15 name="bom.structure"
16 rml="asperience_mrp/report/bom_structure.rml"
17 string="BOM Structure"/>
18
19 </data>
20</openerp>
021
=== added file 'asperience_configurator_mrp/mrp_routing.py'
--- asperience_configurator_mrp/mrp_routing.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_routing.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,54 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23
24class mrp_routing(osv.osv):
25 _inherit = 'mrp.routing'
26 _columns = {
27 'technical_data': fields.char('Technical Data', size=128),
28 }
29 _defaults = {
30 'active': lambda *a: 1,
31 }
32mrp_routing()
33
34class mrp_routing_workcenter_subproduct(osv.osv):
35 _name = 'mrp.routing.workcenter.subproduct'
36 _description = 'mrp.routing.workcenter.subproduct'
37 _columns = {
38 'name': fields.float('Percent', required=True),
39 'subproduct_id': fields.many2one('mrp.subproduct', 'Subproduct', required=True),
40 'workcenter_line_id': fields.many2one('mrp.routing.workcenter', 'Routing Workcenter', required=True),
41 }
42mrp_routing_workcenter_subproduct()
43
44class mrp_routing_workcenter(osv.osv):
45 _inherit = 'mrp.routing.workcenter'
46 _columns = {
47 'sub_ids': fields.one2many('mrp.routing.workcenter.subproduct', 'workcenter_line_id', 'Sub Product'),
48 'bom_ids': fields.many2many('mrp.bom', 'routing_workcenter_mrp_bom_rel', 'workcenter_line_id', 'bom_id', 'Components'),
49 }
50 _defaults = {
51 }
52mrp_routing_workcenter()
53
54# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file55\ No newline at end of file
156
=== added file 'asperience_configurator_mrp/mrp_subproduct.py'
--- asperience_configurator_mrp/mrp_subproduct.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_subproduct.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,37 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23
24class mrp_subproduct(osv.osv):
25 _inherit = 'mrp.subproduct'
26 _columns={
27 'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% within the production process."),
28 '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" ),
29 '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"),
30 }
31 _defaults={
32 'product_efficiency' : lambda *a : 1,
33 'efficiency_rounding' : lambda *a : 2,
34 }
35mrp_subproduct()
36
37# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file38\ No newline at end of file
139
=== added file 'asperience_configurator_mrp/mrp_subproduct_view.xml'
--- asperience_configurator_mrp/mrp_subproduct_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_subproduct_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,33 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="mrp_subproduct_view_tree" model="ir.ui.view">
5 <field name="name">mrp.subproduct.tree</field>
6 <field name="model">mrp.subproduct</field>
7 <field name="type">tree</field>
8 <field name="arch" type="xml">
9 <tree string="Sub products" editable="top">
10 <field name="product_id" on_change="onchange_product_id(product_id)"/>
11 <field name="product_uom"/>
12 <field name="product_qty"/>
13 <field name="subproduct_type"/>
14 </tree>
15 </field>
16 </record>
17
18 <record id="mrp_subproduct_view_form" model="ir.ui.view">
19 <field name="name">mrp.subproduct.form</field>
20 <field name="model">mrp.subproduct</field>
21 <field name="type">form</field>
22 <field name="arch" type="xml">
23 <form string="Sub products">
24 <field name="product_id" on_change="onchange_product_id(product_id)"/>
25 <field name="product_uom"/>
26 <field name="product_qty"/>
27 <field name="subproduct_type"/>
28 </form>
29 </field>
30 </record>
31
32 </data>
33</openerp>
034
=== added file 'asperience_configurator_mrp/mrp_view.xml'
--- asperience_configurator_mrp/mrp_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,735 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 ###################################### PROPERTY #######################################
5 <record id="mrp_property_group_tree_view_asperience_mrp" model="ir.ui.view">
6 <field name="name">mrp.property.group.tree.asperience_mrp</field>
7 <field name="model">mrp.property.group</field>
8 <field name="arch" type="xml">
9 <form string="Properties categories">
10 <separator colspan="4" string="General Information"/>
11 <field colspan="4" name="name"/>
12 <field colspan="4" name="description"/>
13 <field name="property_ids" nolabel="1" colspan="4"/>
14 </form>
15 </field>
16 </record>
17
18 <record id="mrp_property_tree_view_asperience_mrp" model="ir.ui.view">
19 <field name="name">mrp.property.tree.asperience_mrp</field>
20 <field name="model">mrp.property</field>
21 <field name="inherit_id" ref="mrp.mrp_property_tree_view" />
22 <field name="arch" type="xml">
23 <field name="name" position="before">
24 <field name="code"/>
25 <field name="price"/>
26 <field name="uom_s_size_tmpl"/>
27 <field name="size_x_tmpl"/>
28 <field name="size_y_tmpl"/>
29 <field name="size_z_tmpl"/>
30 <field name="diameter_tmpl"/>
31 </field>
32 <field name="composition" position="replace"/>
33 </field>
34 </record>
35 <record id="mrp_property_form_view_asperience_mrp" model="ir.ui.view">
36 <field name="name">mrp.property.form.asperience_mrp</field>
37 <field name="model">mrp.property</field>
38 <field name="type">form</field>
39 <field name="inherit_id" ref="mrp.mrp_property_form_view" />
40 <field name="arch" type="xml">
41 <field name="name" position="before">
42 <field name="code"/>
43 </field>
44 <field name="name" position="after">
45 <newline/>
46 <field name="price"/>
47 <newline/>
48 <field name="size_x_tmpl"/>
49 <field name="size_y_tmpl"/>
50 <field name="size_z_tmpl"/>
51 <field name="diameter_tmpl"/>
52 <field name="uom_s_size_tmpl"/>
53 <newline/>
54 </field>
55 <field name="composition" position="replace"/>
56 </field>
57 </record>
58
59 ###################################### WORKCENTER #######################################
60 <record id="mrp_workcenter_tree_view_asperience_mrp" model="ir.ui.view">
61 <field name="name">mrp.workcenter.tree.asperience.mrp</field>
62 <field name="model">mrp.workcenter</field>
63 <field name="inherit_id" ref="mrp.mrp_workcenter_tree_view"/>
64 <field name="arch" type="xml">
65 <field name="code" position="before">
66 <field name="sequence"/>
67 </field>
68 </field>
69 </record>
70
71 <record id="mrp_workcenter_view_asperience_mrp" model="ir.ui.view">
72 <field name="name">mrp.workcenter.form.asperience.mrp</field>
73 <field name="model">mrp.workcenter</field>
74 <field name="inherit_id" ref="mrp.mrp_workcenter_view"/>
75 <field name="arch" type="xml">
76 <notebook position="inside">
77 <page string="Properties">
78 <field name="property_ids" nolabel="1" colspan="4"/>
79 </page>
80 <page string="Hierarchy">
81 <field name="parent_id" domain="[('type','in', [type_re, type_pc, type_cc])]"/>
82 <field colspan="4" name="child_ids"/>
83 </page>
84 </notebook>
85 <!-- <field name="timesheet_id" position="replace"/> -->
86 <field name="time_start" position="attributes">
87 <attribute name="attrs">{'invisible': [('type', '!=', 'machine')]}</attribute>
88 </field>
89 <field name="time_stop" position="attributes">
90 <attribute name="attrs">{'invisible': [('type', '!=', 'machine')]}</attribute>
91 </field>
92 <field name="code" position="before">
93 <field name="sequence"/>
94 </field>
95 <field name="resource_type" position="before">
96 <field name="warehouse_id"/>
97 </field>
98 <field name="resource_type" position="after">
99 <field name="type_workcenter" on_change="onchange_type_workcenter(type_workcenter)"/>
100 <field name="type" invisible="True"/>
101 <newline/>
102 <field name="type_re" on_change="onchange_type(type_re)" attrs="{'invisible':[('type_workcenter','!=', 're')]}"/>
103 <newline/>
104 <field name="type_pc" on_change="onchange_type(type_pc)" attrs="{'invisible':[('type_workcenter','!=', 'pc')]}"/>
105 <newline/>
106 <field name="type_cc" on_change="onchange_type(type_cc)" attrs="{'invisible':[('type_workcenter','!=', 'cc')]}"/>
107 <newline/>
108 <field name="technology" attrs="{'invisible':[('type','not in',['tool', 'machine', 'machine_hr', 'line'])]}"/>
109 <newline/>
110 <field name="scheduling" attrs="{'invisible':[('type','in',['hr','line'])]}"/>
111 <newline/>
112 </field>
113 <field name="capacity_per_cycle" position="after">
114 <group col="6" attrs="{'invisible':[('type','=', 'hr')]}" groups="analytic.group_analytic_accounting">
115 <field name="fixed_capacity"/>
116 <field name="external"/>
117 <field name="critical"/>
118 <field name="finite_capacity_qty"/>
119 <field name="finite_capacity"/>
120 </group>
121 </field>
122 </field>
123 </record>
124
125 ###################################### BOM #######################################
126
127 <record id="mrp_bom_form_view_asperience_mrp" model="ir.ui.view">
128 <field name="name">mrp.bom.form.asperience.mrp</field>
129 <field name="model">mrp.bom</field>
130 <field name="inherit_id" ref="mrp.mrp_bom_form_view"/>
131 <field name="arch" type="xml">
132 <field name="property_ids" position="replace" >
133 <field name="property_ids" nolabel="1" colspan="4" />
134 <field name="type_group_ids" nolabel="1" colspan="4" />
135 </field>
136 <field name="bom_line_ids" position="after" >
137 <button name="gen_graph" string="Graph" type="object" />
138 <separator colspan="4" string="Components"/>
139 <!-- <field name="bom_lines_multi" nolabel="1" colspan="4" /> -->
140 <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'}" />
141 <separator colspan="4" string="Is used in"/>
142 <!-- <field name="bom_parent_multi" nolabel="1" colspan="4" /> -->
143 <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'}" />
144 </field>
145 <field name="type" position="after" >
146 <field name="bom_type" />
147 </field>
148 </field>
149 </record>
150
151 ###################################### PROD LINE #######################################
152 <record id="mrp.mrp_production_product_form_view" model="ir.ui.view">
153 <field name="name">mrp.production.product.line.form.asperience.mrp</field>
154 <field name="model">mrp.production.product.line</field>
155 <field name="priority">15</field>
156 <field name="arch" type="xml">
157 <form string="Scheduled Products">
158 <field name="name" />
159 <field name="product_id" on_change="onchange_product_id(product_id)" />
160 <field name="product_qty" />
161 <field name="product_uom" />
162 <field name="product_uos_qty" />
163 <field name="product_uos" />
164 <field name='specific_production' colspan="4" />
165 <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
166 <group colspan="4">
167 <field name="shape"
168 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
169
170 <field name="density"
171 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
172
173 <field name="diameter" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" attrs="{'invisible':[('shape','in',['quadrangular','other'])]}"/>
174 <field name="weight" />
175 </group>
176 <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
177 <group colspan="2">
178 <field name='size_x' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
179 <field name='size_y' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
180 <field name='size_z' colspan="2" on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
181 </group>
182 <group colspan="2">
183 <label string='-' colspan="4"/>
184 <label string='-' colspan="4"/>
185 <label string='-' colspan="4"/>
186 </group>
187 <group colspan="2">
188 <field name='size_x_specific_delta' colspan="2" />
189 <field name='size_y_specific_delta' colspan="2" />
190 <field name='size_z_specific_delta' colspan="2" />
191 </group>
192 <group colspan="2">
193 <label string='=' colspan="4"/>
194 <label string='=' colspan="4"/>
195 <label string='=' colspan="4"/>
196 </group>
197 <group colspan="2">
198 <field name='size_x_specific' colspan="2" />
199 <field name='size_y_specific' colspan="2" />
200 <field name='size_z_specific' colspan="2" />
201 </group>
202 </group>
203
204 <field name="property_ids" colspan="4" nolabel="1"/>
205 <field name="group_property_ids" colspan="4" nolabel="1" />
206 <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
207 <field name="procurement_id" />
208 <field name="bom_id" />
209 </form>
210 </field>
211 </record>
212
213 <record id="mrp_production_product_tree_view_asperience_mrp" model="ir.ui.view">
214 <field name="name">mrp.production.product.line.tree.asperience.mrp</field>
215 <field name="model">mrp.production.product.line</field>
216 <field name="inherit_id" ref="mrp.mrp_production_product_tree_view"/>
217 <field name="arch" type="xml">
218 <field name="product_uos" position="after">
219 <field name="density" />
220 <field name="shape" />
221 <field name="diameter" />
222 <field name="size_x" />
223 <field name="size_y" />
224 <field name="size_z" />
225 <field name="weight" />
226 <field name="property_ids"/>
227 <field name="group_property_ids" />
228 <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
229 <field name="procurement_id" />
230 <field name="bom_id" />
231 </field>
232 <field name="product_id" position="before">
233 <field name="name" />
234 </field>
235 </field>
236 </record>
237
238 ###################################### WORKCENTER TECHNOLOGY #######################################
239 <record id="mrp_workcenter_technology_form_view" model="ir.ui.view">
240 <field name="name">mrp.workcenter.technology.form.view.1</field>
241 <field name="model">mrp.workcenter.technology</field>
242 <field name="type">form</field>
243 <field name="arch" type="xml">
244 <form string="Workcenter Technology">
245 <group col="6" colspan="4">
246 <group col="3" colspan="2">
247 <field name="name" />
248 </group>
249 </group>
250 </form>
251 </field>
252 </record>
253 <record id="mrp_workcenter_technology_tree_view" model="ir.ui.view">
254 <field name="name">mrp.workcenter.technology.tree.view.1</field>
255 <field name="model">mrp.workcenter.technology</field>
256 <field name="type">tree</field>
257 <field name="arch" type="xml">
258 <tree string="Workcenter Technology">
259 <field name="name" />
260 </tree>
261 </field>
262 </record>
263
264 <record model="ir.actions.act_window" id="mrp_workcenter_technology_all_action">
265 <field name="name">Workcenter Technology</field>
266 <field name="res_model">mrp.workcenter.technology</field>
267 <field name="view_mode">tree,form</field>
268 <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_tree_view"/>
269 </record>
270 <record model="ir.actions.act_window.view" id="mrp_workcenter_technology_tree_action">
271 <field name="sequence" eval="1"/>
272 <field name="view_mode">tree</field>
273 <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_tree_view"/>
274 <field name="act_window_id" ref="mrp_workcenter_technology_all_action"/>
275 </record>
276 <record model="ir.actions.act_window.view" id="mrp_workcenter_technology_form_action">
277 <field name="sequence" eval="2"/>
278 <field name="view_mode">form</field>
279 <field name="view_id" ref="asperience_configurator_mrp.mrp_workcenter_technology_form_view"/>
280 <field name="act_window_id" ref="mrp_workcenter_technology_all_action"/>
281 </record>
282 <menuitem action="mrp_workcenter_technology_all_action" id="menu_mrp_workcenter_technology_all_action" parent="mrp.menu_mrp_configuration" sequence="22"/>
283
284 ###################################### PRODUCTION #######################################
285 <record id="mrp_production_form_view_asperience_mrp" model="ir.ui.view">
286 <field name="name">mrp.production.form.asperience.mrp</field>
287 <field name="model">mrp.production</field>
288 <field name="inherit_id" ref="mrp.mrp_production_form_view"/>
289 <field name="arch" type="xml">
290 <field name="workcenter_lines" position="replace" >
291 <field colspan="4" name="workcenter_lines" nolabel="1" >
292 <form string="Production Workcenters">
293 <field colspan="4" name="name"/>
294 <field colspan="4" name="workcenter_id" />
295 <separator/>
296 <field name="sequence"/>
297 <field name="cycle"/>
298 <field name="hour"/>
299 </form>
300 <tree string="Production Workcenters" >
301 <field name="sequence"/>
302 <field name="name"/>
303 <field name="workcenter_id"/>
304 <field name="cycle"/>
305 <field name="hour"/>
306 </tree>
307 </field>
308 </field>
309 <page string="Extra Information" position="after" >
310 <page string="Procurements">
311 <field name="procurement_ids"/>
312 </page>
313 </page>
314 <field name="move_prod_id" position="after" >
315 <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
316 <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
317 <group colspan="2">
318 <field name='size_x' colspan="2"/>
319 <field name='size_y' colspan="2"/>
320 <field name='size_z' colspan="2"/>
321 <field name='diameter' colspan="2"/>
322 </group>
323 <group colspan="2">
324 <label string='-' colspan="4"/>
325 <label string='-' colspan="4"/>
326 <label string='-' colspan="4"/>
327 <label string='-' colspan="4"/>
328 </group>
329 <group colspan="2">
330 <field name='size_x_specific_delta' colspan="2" />
331 <field name='size_y_specific_delta' colspan="2" />
332 <field name='size_z_specific_delta' colspan="2" />
333 <field name='diameter_specific_delta' colspan="2" />
334 </group>
335 <group colspan="2">
336 <label string='=' colspan="4"/>
337 <label string='=' colspan="4"/>
338 <label string='=' colspan="4"/>
339 <label string='=' colspan="4"/>
340 </group>
341 <group colspan="2">
342 <field name='size_x_specific' colspan="2" />
343 <field name='size_y_specific' colspan="2" />
344 <field name='size_z_specific' colspan="2" />
345 <field name='diameter_specific' colspan="2" />
346 </group>
347 </group>
348 <field name='specific_production' colspan="4" />
349 <separator string="Production" colspan="4" />
350 </field>
351 <button name="action_compute" position="after" >
352 <button name="action_compute" string="Compute Data" type="object" />
353 <button name="button_draft" string="Draft" />
354 </button>
355 </field>
356 </record>
357
358 ###################################### GROUP OPTION #######################################
359 <record id="mrp_property_group_option_form_view_asperience_mrp_1" model="ir.ui.view">
360 <field name="name">mrp.property.group.option.form.asperience.mrp.1</field>
361 <field name="model">mrp.property.group.option</field>
362 <field name="type">form</field>
363 <field name="arch" type="xml">
364 <form string="GOP / Property">
365 <field colspan="4" name="name"/>
366 <field colspan="4" name="type_group_id" on_change="onchange_group_property(type_group_id,property_id)"/>
367 <field colspan="4" name="property_id" on_change="onchange_group_property(type_group_id,property_id)"/>
368 </form>
369 </field>
370 </record>
371 <record id="mrp_property_group_option_tree_view_asperience_mrp_1" model="ir.ui.view">
372 <field name="name">mrp.property.group.option.tree.asperience.mrp.1</field>
373 <field name="model">mrp.property.group.option</field>
374 <field name="type">tree</field>
375 <field name="arch" type="xml">
376 <tree string="GOP / Property" editable="top">
377 <field colspan="4" name="name"/>
378 <field colspan="4" name="type_group_id" on_change="onchange_group_property(type_group_id,property_id)"/>
379 <field colspan="4" name="property_id" on_change="onchange_group_property(type_group_id,property_id)"/>
380 </tree>
381 </field>
382 </record>
383
384 ###################################### GROUP OPTION #######################################
385 <record id="mrp_routing_form_view_asperience_mrp_1" model="ir.ui.view">
386 <field name="name">mrp.routing.form.asperience.mrp.1</field>
387 <field name="model">mrp.routing</field>
388 <field name="inherit_id" ref="mrp.mrp_routing_form_view"/>
389 <field name="type">form</field>
390 <field name="arch" type="xml">
391 <field name="active" position="after">
392 <field name="technical_data" colspan="4"/>
393 </field>
394 </field>
395 </record>
396 <record id="mrp_routing_tree_view_asperience_mrp_1" model="ir.ui.view">
397 <field name="name">mrp.routing.tree.asperience.mrp.1</field>
398 <field name="model">mrp.routing</field>
399 <field name="inherit_id" ref="mrp.mrp_routing_tree_view"/>
400 <field name="type">tree</field>
401 <field name="arch" type="xml">
402 <field name="name" position="after">
403 <field name="technical_data" />
404 </field>
405 </field>
406 </record>
407
408 ###################################### SUBPRODUCT #######################################
409 <record id="mrp_byproduct.mrp_subproduct_view" model="ir.ui.view">
410 <field name="name">mrp.bom.sub.product.asperience.mrp.1</field>
411 <field name="model">mrp.bom</field>
412 <field name="inherit_id" ref="mrp.mrp_bom_form_view"/>
413 <field name="arch" type="xml">
414 <field name="product_id" position="replace">
415 <field name="product_id" on_change="onchange_product_id(product_id, name,False)"/>
416 </field>
417 <field name="type" position="after">
418 <group colspan="4">
419 <field name="shape"
420 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
421
422 <field name="density"
423 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
424
425 </group>
426
427 <group colspan="4">
428 <group attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
429 <field name="size_x"
430 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
431 <field name="size_y"
432 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
433 </group>
434
435 <group attrs="{'invisible':[('shape','in',['quadrangular','other'])]}">
436 <field name="diameter"
437 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
438 </group>
439
440 <group attrs="{'invisible':[('shape','in',['other'])]}">
441 <field name="size_z"
442 on_change="compute_weight(product_id,size_x, size_y, size_z, shape, density, diameter)" />
443 </group>
444
445
446 </group>
447 <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
448 <field name="weight" />
449
450 </group>
451 </field>
452 <notebook position="inside">
453 <page string="Byproducts" position="inside">
454 <field name="sub_products">
455 <tree string="Byproducts" editable="top">
456 <field name="product_id" on_change="onchange_product_id(product_id)"/>
457 <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
458 <field name="product_qty"/>
459 <field name="product_efficiency"/>
460 <field name="efficiency_rounding"/>
461 <field name="subproduct_type"/>
462 <field name="type_group_ids"/>
463 </tree>
464 <form string="Byproducts">
465 <field name="product_id" on_change="onchange_product_id(product_id)"/>
466 <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
467 <field name="product_qty"/>
468 <field name="product_efficiency"/>
469 <field name="efficiency_rounding"/>
470 <field name="subproduct_type"/>
471 <field name="type_group_ids"/>
472 </form>
473 </field>
474 </page>
475 </notebook>
476 </field>
477 </record>
478
479 <record id="mrp_bom_tree_view_asperience_mrp" model="ir.ui.view">
480 <field name="name">mrp.bom.tree.asperience.mrp</field>
481 <field name="model">mrp.bom</field>
482 <field name="inherit_id" ref="mrp.mrp_bom_tree_view" />
483 <field name="field_parent">child_complete_ids</field>
484 <field name="arch" type="xml">
485 <field name="product_uom" position="after">
486 <field name="density" />
487 <field name="shape" />
488 <field name="diameter" />
489 <field name="size_x" />
490 <field name="size_y" />
491 <field name="size_z" />
492 <field name="weight" />
493 </field>
494 </field>
495 </record>
496
497 <record id="mrp_routing_workcenter_subproduct_form_view" model="ir.ui.view">
498 <field name="name">mrp.routing.workcenter.subproduct</field>
499 <field name="model">mrp.routing.workcenter.subproduct</field>
500 <field name="type">form</field>
501 <field name="arch" type="xml">
502 <form string="Subproduct" >
503 <field name="name" colspan="4"/>
504 <field name="workcenter_line_id" colspan="4"/>
505 <field name="subproduct_id" colspan="4"/>
506 </form>
507 </field>
508 </record>
509
510 <record id="mrp_routing_workcenter_subproduct_tree_view" model="ir.ui.view">
511 <field name="name">mrp.routing.workcenter.subproduct</field>
512 <field name="model">mrp.routing.workcenter.subproduct</field>
513 <field name="type">tree</field>
514 <field name="arch" type="xml">
515 <tree string="Subproduct" >
516 <field name="name" />
517 <field name="workcenter_line_id" />
518 <field name="subproduct_id" />
519 </tree>
520 </field>
521 </record>
522
523 ###################################### GROUP ROUTING #######################################
524 <record id="mrp_routing_workcenter_tree_view_asperience_mrp_1" model="ir.ui.view">
525 <field name="name">mrp.routing.workcenter.tree.asperience.mrp.1</field>
526 <field name="model">mrp.routing.workcenter</field>
527 <field name="inherit_id" ref="mrp.mrp_routing_workcenter_tree_view"/>
528 <field name="type">tree</field>
529 <field name="arch" type="xml">
530 <field name="hour_nbr" position="after">
531 <field name="bom_ids"/>
532 <field name="sub_ids">
533 <form string="Subproduct" >
534 <field name="name" colspan="4"/>
535 <field name="workcenter_line_id" colspan="4"/>
536 <field name="subproduct_id" colspan="4"/>
537 </form>
538 <tree string="Subproduct" >
539 <field name="name" />
540 <field name="workcenter_line_id" />
541 <field name="subproduct_id" />
542 </tree>
543 </field>
544 </field>
545 </field>
546 </record>
547
548 <record id="mrp_routing_workcenter_form_view_asperience_mrp_1" model="ir.ui.view">
549 <field name="name">mrp.routing.workcenter.form.asperience.mrp.1</field>
550 <field name="model">mrp.routing.workcenter</field>
551 <field name="inherit_id" ref="mrp.mrp_routing_workcenter_form_view"/>
552 <field name="type">form</field>
553 <field name="arch" type="xml">
554 <field name="hour_nbr" position="after">
555 <field name="bom_ids" colspan="4"/>
556 <field name="sub_ids" colspan="4">
557 <form string="Subproduct" >
558 <field name="name" colspan="4"/>
559 <field name="subproduct_id" colspan="4"/>
560 </form>
561 <tree string="Subproduct" >
562 <field name="name" />
563 <field name="subproduct_id" />
564 </tree>
565 </field>
566 </field>
567 </field>
568 </record>
569
570
571 ###################################### WORKCENTER LINE #######################################
572 <record id="mrp_production_form_view_asperience_mrp_5" model="ir.ui.view">
573 <field name="name">mrp.production.form.asperience.mrp.5</field>
574 <field name="model">mrp.production</field>
575 <field name="inherit_id" ref="mrp.mrp_production_form_view"/>
576 <field name="type">form</field>
577 <field name="arch" type="xml">
578 <field name="workcenter_lines" position="replace">
579 <field colspan="4" name="workcenter_lines" nolabel="1">
580 <form string="Production Workcenters">
581 <field colspan="4" name="name"/>
582 <field colspan="4" name="workcenter_id"/>
583 <field name="sequence"/>
584 <field name="cycle"/>
585 <field name="hour"/>
586 <newline/>
587 <field name="move_ids"/>
588 </form>
589 <tree string="Production Workcenters">
590 <field name="sequence"/>
591 <field name="name"/>
592 <field name="workcenter_id"/>
593 <field name="cycle"/>
594 <field name="hour"/>
595 <field name="move_ids"/>
596 </tree>
597 </field>
598 </field>
599 </field>
600 </record>
601
602 <record model="ir.ui.view" id="mrp_production_workcenter_tree_view_inherit_asperience_mrp_1">
603 <field name="name">mrp.production.workcenter.line.tree.asperience.mrp.1</field>
604 <field name="model">mrp.production.workcenter.line</field>
605 <field name="type">tree</field>
606 <field name="inherit_id" ref="mrp_operations.mrp_production_workcenter_tree_view_inherit"/>
607 <field name="arch" type="xml">
608 <field name="workcenter_id" position="after">
609 <field name="move_ids"/>
610 </field>
611 </field>
612 </record>
613
614 <record model="ir.ui.view" id="mrp_production_workcenter_form_view_inherit_asperience_mrp_1">
615 <field name="name">mrp.production.workcenter.line.form.asperience.mrp.1</field>
616 <field name="model">mrp.production.workcenter.line</field>
617 <field name="type">form</field>
618 <field name="inherit_id" ref="mrp_operations.mrp_production_workcenter_form_view_inherit"/>
619 <field name="arch" type="xml">
620 <page string="Information" position="after">
621 <page string="Moves">
622 <field name="move_ids"/>
623 </page>
624 </page>
625 </field>
626 </record>
627
628 ###################################### BOM REL #######################################
629 <record id="mrp_bom_component_rel_form_view_component" model="ir.ui.view">
630 <field name="name">mrp.bom.component.rel.form.view</field>
631 <field name="model">mrp.bom.component.rel</field>
632 <field name="type">form</field>
633 <field name="arch" type="xml">
634 <form string="Components">
635 <field name="component_id" />
636 <!-- <field name="product_component_id" /> -->
637 <field name="qty" />
638 <field name="mode" />
639 </form>
640 </field>
641 </record>
642
643 <record id="mrp_bom_component_rel_tree_view_component" model="ir.ui.view">
644 <field name="name">mrp.bom.component.rel.tree.view</field>
645 <field name="model">mrp.bom.component.rel</field>
646 <field name="type">tree</field>
647 <field name="arch" type="xml">
648 <tree string="Components" editable="top">
649 <field name="component_id" />
650 <!-- <field name="product_component_id" />-->
651 <field name="qty" />
652 <field name="mode" />
653 </tree>
654 </field>
655 </record>
656
657 <record id="mrp_bom_component_rel_form_view_parent" model="ir.ui.view">
658 <field name="name">mrp.bom.component.rel.form.view</field>
659 <field name="model">mrp.bom.component.rel</field>
660 <field name="type">form</field>
661 <field name="arch" type="xml">
662 <form string="Used in">
663 <field name="bom_id" />
664 <field name="qty" />
665 <field name="mode" />
666 </form>
667 </field>
668 </record>
669
670 <record id="mrp_bom_component_rel_tree_view_parent" model="ir.ui.view">
671 <field name="name">mrp.bom.component.rel.tree.view</field>
672 <field name="model">mrp.bom.component.rel</field>
673 <field name="type">tree</field>
674 <field name="arch" type="xml">
675 <tree string="Used in" editable="top">
676 <field name="bom_id" />
677 <field name="qty" />
678 <field name="mode" />
679 </tree>
680 </field>
681 </record>
682
683 ###################################### BOM COMPONENTS #######################################
684 <record id="mrp_bom_component_mode_form_view" model="ir.ui.view">
685 <field name="name">mrp.bom.component.mode.form.view</field>
686 <field name="model">mrp.bom.component.mode</field>
687 <field name="type">form</field>
688 <field name="arch" type="xml">
689 <form string="Mode">
690 <field name="name"/>
691 <field name="dx"/>
692 <field name="dy"/>
693 <field name="dz"/>
694 <field name="dd"/>
695 </form>
696 </field>
697 </record>
698
699 <record id="mrp_bom_component_mode_tree_view" model="ir.ui.view">
700 <field name="name">mrp.bom.component.mode.tree.view</field>
701 <field name="model">mrp.bom.component.mode</field>
702 <field name="type">tree</field>
703 <field name="arch" type="xml">
704 <tree string="Mode">
705 <field name="name" />
706 <field name="dx" />
707 <field name="dy" />
708 <field name="dz" />
709 <field name="dd" />
710 </tree>
711 </field>
712 </record>
713
714 <record model="ir.actions.act_window" id="mrp_bom_component_mode_all_action">
715 <field name="name">Bom Modes</field>
716 <field name="res_model">mrp.bom.component.mode</field>
717 <field name="view_mode">tree,form</field>
718 <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_tree_view"/>
719 </record>
720 <record model="ir.actions.act_window.view" id="mrp_bom_component_mode_tree_action">
721 <field name="sequence" eval="1"/>
722 <field name="view_mode">tree</field>
723 <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_tree_view"/>
724 <field name="act_window_id" ref="mrp_bom_component_mode_all_action"/>
725 </record>
726 <record model="ir.actions.act_window.view" id="mrp_bom_component_mode_form_action">
727 <field name="sequence" eval="2"/>
728 <field name="view_mode">form</field>
729 <field name="view_id" ref="asperience_configurator_mrp.mrp_bom_component_mode_form_view"/>
730 <field name="act_window_id" ref="mrp_bom_component_mode_all_action"/>
731 </record>
732 <menuitem action="mrp_bom_component_mode_all_action" id="menu_mrp_bom_component_mode_all_action" parent="mrp.menu_mrp_configuration"/>
733
734 </data>
735</openerp>
0736
=== added file 'asperience_configurator_mrp/mrp_workcenter.py'
--- asperience_configurator_mrp/mrp_workcenter.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_workcenter.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,130 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23from openerp.tools.translate import _
24#import openerp.netsvc
25
26class mrp_workcenter_technology(osv.osv):
27 _name = 'mrp.workcenter.technology'
28 _columns = {
29 'name': fields.char('Description', size=256, required=True),
30 }
31 _defaults = {
32 }
33mrp_workcenter_technology()
34
35class mrp_workcenter(osv.osv):
36 _inherit = 'mrp.workcenter'
37
38 def _get_type(self, cr, uid, ids, field_name, arg, context={}):
39 res = {}
40 for id in ids:
41 res[id] = {'type_re': '', 'type_pc': '', 'type_cc': ''}
42 for workcenter in self.browse(cr, uid, ids):
43 if workcenter.type_workcenter == 're':
44 res[id]['type_re'] = workcenter.type
45 elif workcenter.type_workcenter == 'pc':
46 res[id]['type_pc'] = workcenter.type
47 elif workcenter.type_workcenter == 'cc':
48 res[id]['type_cc'] = workcenter.type
49 return res
50
51 def _set_type(self, cr, uid, ids, name, value, arg, context):
52 if not value:
53 return False
54 if isinstance(ids, (int, long)):
55 ids = [ids]
56 for workcenter in self.browse(cr, uid, ids, context):
57 self.write(cr, uid, ids, {'type': value})
58 return True
59
60 def onchange_type(self, cr, uid, id, type=''):
61 res = {'value':{'type': type}}
62 return res
63
64 def onchange_type_workcenter(self, cr, uid, id, type_workcenter):
65 res = {'value':{'type_re': '','type_pc': '', 'type_cc': '', 'type': ''}}
66 if type_workcenter == 're' or type_workcenter == 'pc':
67 res['value']['type_re'] = 'machine'
68 elif type_workcenter == 'cc':
69 res['value']['type_re'] = 'machine_hr'
70 res['value']['type'] = res['value']['type_re']
71 return res
72
73 _columns = {
74 'sequence': fields.integer('Sequence'),
75 'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool'),('machine_hr','Machine and HR'),('line','Line'),('energy','Energy')], 'Type', required=True),
76 'type_re': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('tool',_('Tool')),('energy',_('Energy'))],
77 multi="type",method=True, store=False, type='selection', string='Type'),
78 'type_pc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine',_('Machine')),('hr',_('Human Resource')),('machine_hr',_('Machine and HR')),('line',_('Line'))],
79 multi="type",method=True, store=False, type='selection', string='Type'),
80 'type_cc': fields.function(_get_type, fnct_inv=_set_type, selection=[('machine_hr',_('Machine and HR')),('line',_('Line'))],
81 multi="type",method=True, store=False, type='selection', string='Type'),
82 'type_workcenter': fields.selection([('re',_('Elementary resource')),('pc',_('Work center')),('cc',_('Work line'))], 'Type workcenter', required=True, size=2),
83 'scheduling': fields.selection([('machine','Machine'),('hr','Human Resource'),('machine_hr','Machine and HR'),('pg','The greatest')], 'Scheduling'),
84 'parent_id': fields.many2one('mrp.workcenter', 'Parent'),
85 'child_ids': fields.one2many('mrp.workcenter', 'parent_id','Childs'),
86 'technology': fields.many2one('mrp.workcenter.technology', 'Technology'),
87 'warehouse_id': fields.many2one('stock.warehouse', 'Sector', required=True),
88 'property_ids': fields.many2many('mrp.property', 'mrp_workcenter_property_rel','workcenter_id', 'property_id', 'Properties'),
89 #A redƩfinir
90 'external': fields.boolean('External workcenter'),
91 'fixed_capacity': fields.boolean('Fixed capacity'),
92 #'capacity_qty' : fields.float('Capacity'),
93 'critical': fields.boolean('Critical'),
94 'finite_capacity': fields.boolean('Finite Capacity'),
95 'finite_capacity_qty' : fields.float('Finite Capacity Qty'),
96 }
97 _defaults = {
98 'sequence': lambda *a: 0,
99 'time_start': lambda *a: 0,
100 'time_stop': lambda *a: 0,
101 'time_cycle': lambda *a: 0,
102 'type_workcenter': lambda *a: 'pc',
103 }
104
105 def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=80):
106 print "name:",name
107 print "args:",args
108 print "operator:",operator
109 print "context:",context
110 print "limit:",limit
111 if args:
112 if args[0][0] == 'type':
113 for val in args[0][2]:
114 if val:
115 if val in ['line', 'machine_hr']:
116 args = [('type', '=', 'line')]
117 break
118 elif val == 'machine':
119 args = [('type', 'in', ['line','machine_hr','machine'])]
120 break
121 elif val in ['energy', 'hr', 'tool']:
122 args = [('type', 'in', ['line','machine_hr','machine','hr'])]
123 break
124
125 print "args:",args
126 return super(mrp_workcenter, self).name_search(cr, uid, name, args=args, operator=operator, context=context, limit=limit)
127
128mrp_workcenter()
129
130# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file131\ No newline at end of file
1132
=== added file 'asperience_configurator_mrp/mrp_workflow.xml'
--- asperience_configurator_mrp/mrp_workflow.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/mrp_workflow.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,26 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="mrp.prod_act_ready" model="workflow.activity">
5 <field name="wkf_id" ref="mrp.wkf_prod"/>
6 <field name="name">ready</field>
7 <field name="kind">function</field>
8 <field name="action">action_confirm() and action_ready()</field>
9 </record>
10
11 <record id="mrp.prod_act_cancel" model="workflow.activity">
12 <field name="wkf_id" ref="mrp.wkf_prod"/>
13 <field name="flow_stop">False</field>
14 <field name="name">cancel</field>
15 <field name="kind">function</field>
16 <field name="action">action_cancel()</field>
17 </record>
18
19 <record id="prod_trans_cancel_draft" model="workflow.transition">
20 <field name="act_from" ref="mrp.prod_act_cancel"/>
21 <field name="act_to" ref="mrp.prod_act_draft"/>
22 <field name="signal">button_draft</field>
23 </record>
24
25 </data>
26</openerp>
027
=== added file 'asperience_configurator_mrp/procurement.py'
--- asperience_configurator_mrp/procurement.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/procurement.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,193 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22from openerp.osv import fields,osv
23#import openerp.netsvc
24#import time
25#import datetime
26#from mx import DateTime
27#from openerp.tools.translate import _
28#from openerp.tools import ustr
29
30class procurement_order(osv.osv):
31 _inherit = 'procurement.order'
32
33 def _size(self, cr, uid, ids, field_name, arg, context):
34 res = {}
35 for proc in self.browse(cr, uid, ids):
36 res[proc.id] = {'size_x': 0.0, 'size_y': 0.0, 'size_z': 0.0 ,'diameter': 0.0}
37 if proc.product_id:
38 res[proc.id]['size_x'] = proc.product_id.size_x or proc.product_id.product_tmpl_id.size_x_tmpl or 0.0
39 res[proc.id]['size_y'] = proc.product_id.size_y or proc.product_id.product_tmpl_id.size_y_tmpl or 0.0
40 res[proc.id]['size_z'] = proc.product_id.size_z or proc.product_id.product_tmpl_id.size_z_tmpl or 0.0
41 res[proc.id]['diameter'] = proc.product_id.diameter or proc.product_id.product_tmpl_id.diameter_tmpl or 0.0
42 return res
43
44 def get_production(self, cr, uid, ids, context={}):
45 production_obj = self.pool.get('mrp.production')
46 move_obj = self.pool.get('stock.move')
47 result = {}
48 for procurement in self.browse(cr, uid, ids):
49 result[procurement.id] = False
50 if procurement.bom_id and procurement.bom_id.bom_type in ('cut'):
51 print "procurement.bom_id",procurement.bom_id,procurement.bom_id.bom_type
52 production_id = production_obj.search(cr,uid,[('bom_id','=',procurement.bom_id.id),('state','=','draft')])
53
54 if production_id:
55 result[procurement.id] = production_id[0]
56 self.write(cr,uid,procurement.id,{'production_id':result[procurement.id]})
57 move_obj.write(cr,uid,procurement.move_id.id,{'production_id':result[procurement.id]})
58
59# if procurement.move_id.prodlot_id:
60# print procurement.move_id.prodlot_id
61# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',procurement.move_id.prodlot_id.id),('production_id','!=',False),('production_id.state','=','confirmed')])
62# print move_ids
63# if move_ids:
64# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
65# result[procurement.id] = production_id
66# print "ok"
67# self.write(cr,uid,procurement.id,{'production_id':production_id})
68
69# property_ids = [i.id for i in procurement.property_ids]
70# property_ids.sort()
71# production_ids = production_obj.search(cr,uid,[('state','=','draft'),('product_id','=',procurement.product_id.id),('bom_id.bom_type','=','cut')])
72# if production_ids:
73# production_ptr = production_obj.browse(cr,uid,production_ids,context)
74# print "",production_ptr.name
75# print "",production_ptr.move_ids
76# result[procurement.id] =
77
78# if line_prodlot_id and line.bom_id.bom_type in ('cut'):
79# move_ids = move_obj.search(cr,uid,[('prodlot_id','=',line_prodlot_id),('production_id','!=',False),('production_id.state','=','confirmed')])
80# if move_ids:
81# production_id = move_obj.read(cr,uid,move_ids)[0]['production_id'][0]
82 return result
83
84 def action_produce_assign_product(self, cr, uid, ids, context={}):
85 print "action_produce_assign_product nouveau"
86 wf_service = netsvc.LocalService("workflow")
87 move_obj = self.pool.get('stock.move')
88 produce_id = False
89 company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
90 result = {}
91 production_ids = self.get_production(cr,uid,ids,context)
92 for procurement in self.browse(cr, uid, ids):
93 res_id = procurement.move_id.id
94 loc_id = procurement.location_id.id
95 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)
96 newdate = newdate - DateTime.RelativeDateTime(days=company.manufacturing_lead)
97 print production_ids[procurement.id]
98 if production_ids[procurement.id]:
99 result[procurement.id] = production_ids[procurement.id]
100 else:
101# if not procurement.production_id:
102 result[procurement.id] = self.pool.get('mrp.production').create(cr, uid, {
103 'origin': procurement.origin,
104 'product_id': procurement.product_id.id,
105 'product_qty': procurement.product_qty,
106 'product_uom': procurement.product_uom.id,
107 'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
108 'product_uos': procurement.product_uos and procurement.product_uos.id or False,
109 'location_src_id': procurement.location_id.id,
110 'location_dest_id': procurement.move_id.location_id.id,
111 'bom_id': procurement.bom_id and procurement.bom_id.id or False,
112 'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
113 'move_prod_id': res_id,
114 'procurement_id': procurement.id,
115 'specific_production': procurement.specific_production,
116 'note_production': procurement.note_production,
117 'size_x_specific': procurement.size_x_specific,
118 'size_y_specific': procurement.size_y_specific,
119 'size_z_specific': procurement.size_z_specific,
120 'diameter_specific': procurement.diameter_specific,
121 'size_x_specific_delta': procurement.size_x_specific_delta,
122 'size_y_specific_delta': procurement.size_y_specific_delta,
123 'size_z_specific_delta': procurement.size_z_specific_delta,
124 'diameter_specific_delta': procurement.diameter_specific_delta,
125 })
126# else:
127# result[procurement.id] = procurement.production_id.id
128 produce_id = result[procurement.id]
129 self.write(cr, uid, [procurement.id], {'state':'running', 'production_id':result[procurement.id]})
130 childs = [line.id for line in procurement.procurement_line]
131 #self.action_produce_assign_product(cr, uid, childs)
132 for child in childs:
133 wf_service.trg_validate(uid, 'procurement.order',child, 'button_confirm', cr)
134
135# bom_result = self.pool.get('mrp.production').action_compute(cr, uid,[result[procurement.id]], context)
136
137 #================================================
138 # Confirmation des productions OU Ajout
139 #================================================
140 if not procurement.bom_id or not procurement.bom_id.bom_type in ('cut'):
141 wf_service.trg_validate(uid, 'mrp.production', result[procurement.id], 'button_confirm', cr)
142 else:
143 move_obj.write(cr,uid,procurement.move_id.id,{'production_id':result[procurement.id]})
144 procurement = self.browse(cr,uid,procurement.id,context)
145 print "okokok"
146 #===================================================================
147 # transfere de la sortie des procurement enfant dans l'entrƩe de la production
148 #===================================================================
149 moves = []
150 for line in procurement.procurement_line:
151 print "line",line,line.production_id
152 print "line",line,line.purchase_id
153 if line.production_id:
154 moves.extend([i.id for i in line.production_id.move_created_ids])
155 for i in moves:
156 if i not in [j.id for j in self.pool.get('mrp.production').browse(cr,uid,result[procurement.id]).move_lines]:
157 self.pool.get('mrp.production').write(cr, uid, result[procurement.id], {'move_lines': [(4,i)]})
158 return produce_id
159
160 _columns = {
161 'procurement_id': fields.many2one('procurement.order', 'Procurement Ref', ondelete='cascade', select=True, readonly=True, states={'draft':[('readonly',False)]}),
162 'procurement_line': fields.one2many('procurement.order', 'procurement_id', 'Procurement Lines', readonly=True, states={'draft': [('readonly', False)]}),
163 'group_property_ids': fields.many2many('mrp.property.group.option', 'mrp_procurement_group_property_rel','procurement_id', 'group_id', 'Product Property Group Rel '),
164 'parent_option_id': fields.many2one('product.links', 'Parent Option'),
165 'option_ids': fields.many2many('product.links', 'mrp_procurement_options_rel','procurement_id', 'links_id', 'Option'),
166 'specific_production':fields.boolean('Specific Production'),
167 'note_production':fields.text('Production Note'),
168 'size_x': fields.function(_size, multi="size", method=True, string='Width', digits=(16, 5), type='float'),
169 'size_y': fields.function(_size, multi="size", method=True, string='Length', digits=(16, 5), type='float'),
170 'size_z': fields.function(_size, multi="size", method=True, string='Thickness', digits=(16, 5), type='float'),
171 'diameter': fields.function(_size, multi="size", method=True, string='Diameter', digits=(16, 5), type='float'),
172 'size_x_specific': fields.float('Width specific', digits=(16, 5), readonly=True ),
173 'size_y_specific': fields.float('Length specific', digits=(16, 5), readonly=True),
174 'size_z_specific': fields.float('Thickness specific', digits=(16, 5), readonly=True),
175 'diameter_specific': fields.float('Diameter specific', digits=(16, 5), readonly=True),
176 'size_x_specific_delta': fields.float('Width specific delta', digits=(16, 5), readonly=True),
177 'size_y_specific_delta': fields.float('Length specific delta', digits=(16, 5), readonly=True),
178 'size_z_specific_delta': fields.float('Thickness specific delta', digits=(16, 5), readonly=True),
179 'diameter_specific_delta': fields.float('Diameter specific delta', digits=(16, 5), readonly=True),
180 'production_id': fields.many2one('mrp.production', 'Production', select=True),
181 }
182 _defaults = {
183 }
184 _order = 'id desc'
185
186 def check_wkf(self, cr, uid, ids, context={}):
187 wf_service = netsvc.LocalService("workflow")
188 for i in ids :
189 wf_service.trg_write(uid, 'procurement.order', i, cr)
190 return True
191
192procurement_order()
193# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file194\ No newline at end of file
1195
=== added file 'asperience_configurator_mrp/procurement_view.xml'
--- asperience_configurator_mrp/procurement_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/procurement_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,155 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 ###################################### PROCUREMENT #######################################
6 <record id="mrp_procurement_tree_view_asperience_mrp" model="ir.ui.view">
7 <field name="name">procurement.order.tree.asperience.mrp</field>
8 <field name="model">procurement.order</field>
9 <field name="inherit_id" ref="procurement.procurement_tree_view"/>
10 <field name="arch" type="xml">
11 <field name="state" position="after">
12 <field name="production_id"/>
13 <button name="button_confirm" states="draft" string="Confirm"/>
14 <button name="button_check" states="confirmed" string="Run procurement"/>
15 </field>
16 </field>
17 </record>
18
19 <record id="mrp_procurement_form_view_asperience_mrp" model="ir.ui.view">
20 <field name="name">procurement.order.form.asperience.mrp</field>
21 <field name="model">procurement.order</field>
22 <field name="type">form</field>
23 <field name="inherit_id" ref="procurement.procurement_form_view"/>
24 <field name="arch" type="xml">
25 <page string="Notes" position="after">
26 <page string="Advanced informations">
27 <separator string="Hierarchy" colspan="4" />
28 <field name="procurement_id" />
29 <field name="procurement_line" nolabel="1" colspan="4" widget="one2many_list"/>
30 <separator string="Properties" colspan="4" />
31 <field name="parent_option_id" colspan="4"/>
32 <field name="option_ids" nolabel="1" colspan="4" widget="one2many_list"/>
33 <field name="group_property_ids" nolabel="1" colspan="4" widget="one2many_list"/>
34 <separator string="Production" colspan="4" />
35 <field name="production_id" />
36 <field name='specific_production' colspan="4" />
37 <field name='note_production' colspan="4" attrs="{'invisible':[('specific_production','=',False)]}"/>
38 <group colspan="6" col="10" attrs="{'invisible':[('specific_production','=',False)]}">
39 <group colspan="2">
40 <field name='size_x' colspan="2"/>
41 <field name='size_y' colspan="2"/>
42 <field name='size_z' colspan="2"/>
43 <field name='diameter' colspan="2"/>
44 </group>
45 <group colspan="2">
46 <label string='-' colspan="4"/>
47 <label string='-' colspan="4"/>
48 <label string='-' colspan="4"/>
49 <label string='-' colspan="4"/>
50 </group>
51 <group colspan="2">
52 <field name='size_x_specific_delta' colspan="2" />
53 <field name='size_y_specific_delta' colspan="2" />
54 <field name='size_z_specific_delta' colspan="2" />
55 <field name='diameter_specific_delta' colspan="2"/>
56 </group>
57 <group colspan="2">
58 <label string='=' colspan="4"/>
59 <label string='=' colspan="4"/>
60 <label string='=' colspan="4"/>
61 <label string='=' colspan="4"/>
62 </group>
63 <group colspan="2">
64 <field name='size_x_specific' colspan="2" />
65 <field name='size_y_specific' colspan="2" />
66 <field name='size_z_specific' colspan="2" />
67 <field name='diameter_specific' colspan="2" />
68 </group>
69 </group>
70 </page>
71 </page>
72 <field name="state" position="before" >
73 <button name="check_wkf" string="Check" type="object" />
74 </field>
75 </field>
76 </record>
77
78 <record id="procurement.do_view_procurements" model="ir.actions.act_window">
79 <field name="name">Group's Procurements</field>
80 <field name="res_model">procurement.order</field>
81 <field name="view_type">form</field>
82 <field name="view_mode">tree,form</field>
83 <field name="domain">[('group_id','=',active_id),('procurement_id','=',False)]</field>
84 </record>
85
86 <record id="procurement.procurement_action5" model="ir.actions.act_window">
87 <field name="name">Procurement Exceptions</field>
88 <field name="type">ir.actions.act_window</field>
89 <field name="res_model">procurement.order</field>
90 <field name="view_type">form</field>
91 <field name="view_mode">tree,form</field>
92 <field name="domain">[('state','=','exception'),('procurement_id','=',False)]</field>
93 </record>
94
95 <!--
96 <record id="mrp_procurement_form_view" model="ir.ui.view">
97 <field name="name">procurement.order.form</field>
98 <field name="model">procurement.order</field>
99 <field name="type">form</field>
100 <field name="arch" type="xml">
101 <form string="Procurement">
102 <group col="2" colspan="2">
103 <separator colspan="2" string="References"/>
104 <field name="name" select="1" string="Procurement Reason"/>
105 <field name="origin" select="2"/>
106 </group>
107 <group col="2" colspan="2">
108 <separator colspan="2" string="Planification"/>
109 <field name="date_planned" select="1"/>
110 <field name="procure_method" select="2"/>
111 <field name="priority" groups="base.group_extended"/>
112 </group>
113 <notebook colspan="4">
114 <page string="Procurement Details">
115 <separator colspan="4" string="Product &amp; Location"/>
116 <field name="product_id" select="1" on_change="onchange_product_id(product_id)"/>
117 <field name="location_id" select="2"/>
118 <field name="product_qty"/>
119 <field name="product_uom"/>
120
121 <field name="product_uos_qty" groups="product.group_uos"/>
122 <field name="product_uos" groups="product.group_uos"/>
123
124 <separator colspan="4" string="Status"/>
125 <field colspan="4" name="message" readonly="1"/>
126 <field name="state" readonly="1" select="2"/>
127 <group col="7" colspan="2">
128 <button name="button_confirm" states="draft" string="Confirm"/>
129 <button name="button_restart" states="exception" string="Retry"/>
130 <button name="button_cancel" states="draft,exception,waiting" string="Cancel"/>
131 <button name="button_check" states="confirmed" string="Run procurement"/>
132 </group>
133 </page>
134 <page string="Extra Information">
135 <separator colspan="4" string="Details"/>
136 <field name="bom_id" select="2" domain="[('product_id','=',product_id),('bom_id','=',False)]"/>
137 <field name="move_id" groups="base.group_extended"/>
138 <field name="date_close" select="2"/>
139 <field name="close_move" groups="base.group_extended"/>
140 <field name="purchase_id"/>
141 <separator colspan="4" string="Properties"/>
142 <field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/>
143 </page>
144 <page string="Notes">
145 <separator colspan="4" string="Note" />
146 <field name="note" colspan="4" nolabel="1"/>
147 </page>
148 </notebook>
149 </form>
150 </field>
151 </record>
152 -->
153
154 </data>
155</openerp>
0156
=== added file 'asperience_configurator_mrp/product.py'
--- asperience_configurator_mrp/product.py 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/product.py 2017-12-01 14:57:12 +0000
@@ -0,0 +1,375 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2007-2014 ASPerience SARL (<http://www.asperience.fr>).
6# All Rights Reserved
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22#import openerp.netsvc
23from openerp.osv import fields, osv
24#from openerp.tools import ustr
25#from openerp.tools.translate import _
26#import datetime
27#from sets import *
28
29def name_serial(x, y, z, p, f, d):
30
31 lote = '_'
32 if (f == 'quadrangular'):
33 lote = (str(x) + 'x' + str(y) + 'x' + str(z) + '_' + str(p))
34 elif (f == 'cylindrical'):
35 lote = (str(d) + 'x' + str(z) + '_' + str(p))
36
37 return lote
38
39def compute_w(cr, uid, factor1, factor2, factor3, factor4, size_x, size_y, size_z, shape, density, diameter):
40 resu = {}
41
42 size_x = size_x or 0
43 size_y = size_y or 0
44 size_z = size_z or 0
45 density = density or 1
46 diameter = diameter or 0
47
48 weight = 0
49 if shape == 'quadrangular':
50 weight = ((size_x * size_y * size_z) * density * factor2 * (math.pow(factor3, 3))) / (factor1 * (math.pow(factor4, 3)))
51 diameter = 0
52 volume = size_x * size_y * size_z
53 elif shape == 'cylindrical':
54 radius = diameter / 2.0
55 weight = ((math.pow(radius, 2) * math.pi * size_z) * density * factor2 * (math.pow(factor3, 3))) / (factor1 * (math.pow(factor4, 3)))
56 volume = math.pow(radius, 2) * math.pi * size_z
57 size_x = 0
58 size_y = 0
59 else:
60 weight = 0
61 volume = 0
62 size_x = 0
63 size_y = 0
64 size_z = 0
65
66
67 v = { 'weight':weight,
68 'volume':volume,
69 'size_x':size_x,
70 'size_y':size_y,
71 'size_z':size_z,
72 'diameter':diameter,
73 'density':density,
74 }
75 return v
76
77class product_template(osv.osv):
78 _inherit ='product.template'
79 _columns = {
80 'size_x_tmpl': fields.float('Width', digits=(16, 5)),
81 'size_y_tmpl': fields.float('Length', digits=(16, 5)),
82 'size_z_tmpl': fields.float('Thickness', digits=(16, 5)),
83 'density_tmpl': fields.float('Density', digits=(16, 5), help='Density unit= (uom of weight/(uom of size)^3)'),
84 '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),
85 'diameter_tmpl': fields.float('Diameter', digits=(16, 5)),
86 '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),
87 'uom_d_weight': fields.many2one('product.uom', 'Weight density Uom', help="Default united of measure density used for operations weight", required=True, readonly=True),
88 'uom_s_size' : fields.many2one('product.uom', 'Size Uom', help="Default united of measure used for operations size", required=True, readonly=True),
89 }
90 def _get_uom_d_size(self, cr, uid, *args):
91 return self.pool.get('ir.property').get(cr, uid, 'uom_d_size', 'product.template')
92
93 def _get_uom_d_weight(self, cr, uid, *args):
94 return self.pool.get('ir.property').get(cr, uid, 'uom_d_weight', 'product.template')
95
96 def _get_uom_s_size(self, cr, uid, *args):
97 return self.pool.get('ir.property').get(cr, uid, 'uom_s_size', 'product.template')
98
99 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):
100 value = {}
101
102 if (not uom_id) or (not uom_d_weight) or(not uom_d_size) or (not uom_s_size):
103 return 0
104 if (shape):
105 factor1 = self.pool.get('product.uom').browse(cr, uid, uom_d_weight, context='').factor
106 factor2 = self.pool.get('product.uom').browse(cr, uid, uom_id, context='').factor
107 factor3 = self.pool.get('product.uom').browse(cr, uid, uom_d_size, context='').factor
108 factor4 = self.pool.get('product.uom').browse(cr, uid, uom_s_size, context='').factor
109 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)}
110
111 _defaults = {
112 'size_x_tmpl': lambda * a: 0.0,
113 'size_y_tmpl': lambda * a: 0.0,
114 'size_z_tmpl': lambda * a: 0.0,
115 'density_tmpl': lambda * a: 0.0,
116 'shape': lambda * a: 'other',
117 'diameter_tmpl': lambda * a: 0.0,
118 'uom_d_size': _get_uom_d_size,
119 'uom_d_weight' : _get_uom_d_weight,
120 'uom_s_size' : _get_uom_s_size,
121 }
122product_template()
123
124class product_product(osv.osv):
125 _inherit ='product.product'
0126
127 def generate_bom(self,cr,uid,ids,context={}):
128 print "generate_bom",ids,context
129 pre = "generate_bom "
130 result = {}
131 if "product_qty" not in context :
132 context["product_qty"]=1
133 if "options" not in context :
134 context["options"]=[]
135 if "rec" not in context :
136 context["rec"]=0
137 if "bom_parent" not in context :
138 context["bom_parent"]=[]
139 product_qty = context["product_qty"]
140
141 for product in self.browse(cr,uid,ids,context):
142 print pre+"product ",product.name
143 result[product.id] = False
144 option_name = ""
145 bom_components_parent = []
146 bom_components = []
147
148 if product.bom_ids and context["options"]:
149 self.generate_bom(cr,uid,[product.id])
150 context["bom_parent"] = self.pool.get('mrp.bom')._bom_find(cr, uid, product.id, product.uom_id.id, [], [])
151 bom_components_parent = [(0, 0, {'qty':product_qty, 'bom_id':context["bom_parent"]})]
152 if context["options"]:
153 option_name = "."
154 option_name += ".".join([i.shortcut for i in self.pool.get('product.type.property.option').browse(cr,uid,context["options"])])
155 property_ids = [],
156 # A MODIFIER
157 self.pool.get('product.type.property.option').write(cr,uid,context["options"],{'execution_filter':True})
158 # /A MODIFIER
159 type_group_ids = [(6, 1, context["options"])]
160 if not context["bom_parent"]:
161 raise
162 else:
163 # Probable bug
164# bom_components = [(0, 0, {'bom_id':context["bom_parent"]})]
165 bom_components_parent = [(0, 0, {'qty':context["product_qty"], 'bom_id':context["bom_parent"]})]
166 type = 'phantom'
167 else:
168 property_ids = [(6, 1, [i.id for i in product.bom_property_ids])],
169 type_group_ids = [(6, 1, [i.id for i in product.bom_type_group_ids])],
170 type = 'normal'
171 vals ={
172 'name': product.code+" ["+option_name+"("+"-".join([i.code for i in product.bom_property_ids])+")]",
173 'code': product.code,
174 'active': True,
175 'type': 'normal',
176 'date_start': datetime.datetime.now(),
177 'product_id': product.id,
178 'product_uos_qty': product_qty,
179 'product_uos': product.uos_id.id,
180 'product_qty': product_qty,
181 'product_uom': product.uom_id.id,
182 'product_rounding': 1,
183 'product_efficiency': 1,
184 'shape': product.shape,
185 'property_ids': property_ids,
186 'type_group_ids': type_group_ids,
187 'size_x': product.size_x,
188 'size_y': product.size_y,
189 'size_z': product.size_z,
190 'density': product.density,
191 'shape' : product.shape,
192 'diameter' : product.diameter,
193 'weight': product.weight,
194 'bom_components': bom_components,
195 'bom_components_parent' :bom_components_parent,
196 'type': type,
197 }
198 result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
199 ########################################################################################################################################
200 #INTEGRATION DES LIGNES EN bundle_base
201 bom_components = []
202 print pre+"bom_components avant",bom_components
203 if not context["bom_parent"]:
204 for i in product.linked_product_ids:
205 if not i.used :
206 continue
207 elif i.link_type in ('bundle_base') :
208 if i.product_id.id == product.id :
209 s = result[product.id]
210 else:
211 s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
212 else:
213 continue
214 if s not in bom_components:
215 bom_components.append(s)
216 for i in product.linked_product_tmpl_ids:
217 if not i.used :
218 continue
219 elif i.link_type in ('bundle_base') :
220 if i.product_id.id == product.id :
221 s = result[product.id]
222 else:
223 s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
224 else:
225 continue
226 if s not in bom_components:
227 bom_components.append(s)
228 print pre+"bom_components apres bundle",bom_components
229 ########################################################################################################################################
230 ########################################################################################################################################
231 #CREATION DES BOM OPTION
232 if not context["bom_parent"]:
233 nb = 0
234 for i in product.linked_product_ids:
235# if nb == 10 : break
236 nb+=1
237 s = None
238 if not i.used :
239 continue
240 if i.product_id.id == product.id :
241 if context["options"] and i.type_group.id in context["options"] :
242 s = result[product.id]
243 if not s and i.link_type in ('option') :
244 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 [])
245 else:
246 continue
247 if s not in bom_components:
248 bom_components.append(s)
249 nb = 0
250 for i in product.linked_product_tmpl_ids:
251# if nb == 10 : break
252 nb+=1
253 s = None
254 if not i.used :
255 continue
256 if i.product_id.id == product.id :
257 if context["options"] and i.type_group.id in context["options"] :
258 s = result[product.id]
259 if not s and i.link_type in ('option') :
260 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 [])
261 else:
262 continue
263 if s not in bom_components:
264 bom_components.append(s)
265 # else:
266 # bom_lines_multi.append(context["bom_parent"])
267 print pre+"bom_components apres options",bom_components
268 if bom_components:
269 for i in bom_components:
270 vals = {
271 "bom_id":result[product.id],
272 "component_id":i,
273 "qty":product_qty,
274 }
275 self.pool.get('mrp.bom.component.rel').create(cr,uid,vals)
276# self.pool.get('mrp.bom').write(cr,uid,result[product.id],{'bom_components':[(6,1,bom_components)]})
277 ########################################################################################################################################
278
279 #
280 # 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']
281 # match_criterias = [(a,'=',vals[a]) for a in match_criterias_field]
282 # match_ids = self.pool.get('mrp.bom').search(cr,uid,match_criterias)
283 # for match_bom in self.pool.get('mrp.bom').browse(cr,uid,match_ids):
284 # if not Set([i.id for i in match_bom.property_ids]) == Set(vals['property_ids'][0][2]) :
285 # match_ids.remove(match_bom.id)
286 # continue
287 # if not Set([i.id for i in match_bom.type_group_ids]) == Set(vals['type_group_ids'][0][2]) :
288 # match_ids.remove(match_bom.id)
289 # continue
290 # if match_ids :
291 # result[product.id] = match_ids[0]
292 # elif context["options"] :
293 # result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
294 # else:
295 # result[product.id] = self.pool.get('mrp.bom').create(cr,uid,vals)
296 # bom_option_ids = []
297 # for i in product.linked_product_ids:
298 # if not i.used :
299 # continue
300 # # if i.product_id.id == product.id :
301 # # continue
302 # if i.link_type in ('option') :
303 # 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]
304 # elif i.link_type in ('bundle_base') :
305 # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
306 # else:
307 # continue
308 # if s not in bom_option_ids:
309 # bom_option_ids.append(s)
310 # for i in product.linked_product_tmpl_ids:
311 # if not i.used :
312 # continue
313 # # if i.product_id.id == product.id :
314 # # continue
315 # if i.link_type in ('option') :
316 # 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]
317 # elif i.link_type in ('bundle_base') :
318 # s = self.generate_bom(cr,uid,[i.product_id.id],{"rec":context['rec']+1,"product_qty":i.product_qty,"options":[]})[i.product_id.id]
319 # else:
320 # continue
321 # if s not in bom_option_ids:
322 # bom_option_ids.append(s)
323 # if bom_option_ids:
324 # vals ={
325 # 'bom_components': [(6, 1, bom_option_ids)],
326 # }
327 # self.pool.get('mrp.bom').write(cr,uid,result[product.id],vals)
328 #
329 # vals = {
330 # 'bom' : True,
331 # }
332 # self.write(cr,uid,ids,vals)
333 if context['rec']==0 :
334 return True
335 cr.commit()
336 return result
337
338 _columns = {
339 #Dimensions
340 'size_x': fields.float('Width'),
341 'size_y': fields.float('Length'),
342 'size_z': fields.float('Thickness'),
343 'density': fields.float('Density', help='Density unit= (uom of weight/(uom of size)^3)'),
344 'diameter' : fields.float('Diameter'),
345 #Production
346 'bom': fields.boolean('BoM Generated'),
347 'opp': fields.boolean('Rupture assembly'),
348 'bom_ids': fields.one2many('mrp.bom', 'product_id', 'BoM'),
349 'bom_sub_ids': fields.one2many('mrp.subproduct', 'product_id', 'Sub products'),
350 'bom_type_group_ids': fields.many2many('product.type.property.option', 'product_product_group_option_rel', 'product_id','group_id', 'Bom (GOP or GOO)'),
351 'bom_property_ids': fields.many2many('mrp.property', 'product_product_property_rel', 'product_id','property_id', 'Bom Properties'),
352 }
353 _defaults = {
354 'bom': lambda *a: False,
355 'size_x': lambda * a: 0.0,
356 'size_y': lambda * a: 0.0,
357 'size_z': lambda * a: 0.0,
358 'density': lambda * a: 0.0,
359 'diameter': lambda * a: 0.0,
360 }
361
362 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):
363 value = {}
364
365 if (not uom_id) or (not uom_d_weight) or(not uom_d_size) or (not uom_s_size):
366 return 0
367 if (shape):
368 factor1 = self.pool.get('product.uom').browse(cr, uid, uom_d_weight, context='').factor
369 factor2 = self.pool.get('product.uom').browse(cr, uid, uom_id, context='').factor
370 factor3 = self.pool.get('product.uom').browse(cr, uid, uom_d_size, context='').factor
371 factor4 = self.pool.get('product.uom').browse(cr, uid, uom_s_size, context='').factor
372 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)}
373
374product_product()
375
376# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1\ No newline at end of file377\ No newline at end of file
2378
=== added file 'asperience_configurator_mrp/product_view.xml'
--- asperience_configurator_mrp/product_view.xml 1970-01-01 00:00:00 +0000
+++ asperience_configurator_mrp/product_view.xml 2017-12-01 14:57:12 +0000
@@ -0,0 +1,207 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 ######################################### Product variant ############################################
5 <record id="product_variant_form_view_asperience_mrp" model="ir.ui.view">
6 <field name="name">product.variant.form.asperience.mrp</field>
7 <field name="model">product.product</field>
8 <field name="inherit_id" ref="asperience_product_attributes.product_product_form_view_attributes_variant_1" />
9 <field name="arch" type="xml">
10 <field name="linked_product_ids" position="after" >
11 <button icon="gtk-ok" name="reinit_links" string="Reinit Links and Properties with Category" type="object" />
12 <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'}"/>
13 <separator string="BOM"/>
14 <group col="6" colspan="4" string="Generate">
15 <button name="generate_bom" type="object" string="Generate BoM"/>
16 <field name="bom" readonly="1"/>
17 <field name="opp"/>
18 <field name="bom_type_group_ids" nolabel="1" colspan="6"/>
19 <field name="bom_property_ids" nolabel="1" colspan="6"/>
20 <field name="bom_ids" nolabel="1" colspan="6"/>
21 <field name="bom_sub_ids" nolabel="1" colspan="6" readonly="True"/>
22 </group>
23 </field>
24 </field>
25 </record>
26
27 ######################################### Product normal ############################################
28 <record id="product_product_normal_form_view_asperience_mrp" model="ir.ui.view">
29 <field name="name">product.normal.form.asperience.mrp</field>
30 <field name="model">product.product</field>
31 <field name="inherit_id" ref="asperience_product_attributes.product_product_normal_form_view_attributes" />
32 <field name="arch" type="xml">
33 <field name="uom_id" position="replace">
34 <field name="uom_id"
35 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)" />
36 </field>
37 <field name="linked_product_ids" position="after" >
38 <button icon="gtk-ok" name="reinit_links" string="Reinit Links and Properties with Category" type="object" />
39 <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'}"/>
40 <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'}"/>
41 </field>
42 <page string="Attributes and Options" position="after" >
43 <page string="BoM">
44 <group col="6" colspan="6" string="Generate">
45 <button name="generate_bom" type="object" string="Generate BoM"/>
46 <field name="bom" readonly="1"/>
47 <field name="opp"/>
48 </group>
49 <group col="2" colspan="6">
50 <field name="bom_type_group_ids" nolabel="1" colspan="6"/>
51 <field name="bom_property_ids" nolabel="1" colspan="6"/>
52 </group>
53 <group col="2" colspan="6">
54 <field name="bom_ids" nolabel="1" colspan="6"/>
55 <field name="bom_sub_ids" nolabel="1" colspan="6" readonly="True"/>
56 </group>
57 </page>
58 <page string="Dimensions">
59 <group colspan="4">
60 <group colspan="2">
61 <separator colspan="2" string="Shape type" />
62 <field colspan="2" name="shape" select="2"
63 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)" />
64 </group>
65 </group>
66
67 <separator colspan="4" string="Variables" />
68 <group colspan="4">
69
70 <group colspan="2">
71 <separator colspan="4" string="Density" />
72 <group colspan="6" col="6">
73 <group colspan="2">
74 <field name="density" nolabel="1"
75 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)" />
76 </group>
77 <group colspan="2">
78 <field name='uom_d_weight' string="Weight"
79 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)" />
80 </group>
81 <group colspan="2">
82 <field name='uom_d_size' string="SizeĀ³"
83 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)" />
84 </group>
85 </group>
86 </group>
87
88 <group colspan="2">
89 <separator colspan="4" string="Size" />
90 <group colspan="2">
91 <group colspan="4"
92 attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
93 <field name="size_x"
94 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)" />
95 </group>
96 <group colspan="4"
97 attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
98 <field name="size_y"
99 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)" />
100 </group>
101 <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
102 <field name="size_z"
103 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)" />
104 </group>
105 <group colspan="4"
106 attrs="{'invisible':[('shape','in',['quadrangular','other'])]}">
107 <field name="diameter"
108 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)" />
109 </group>
110 <group colspan="4">
111 <field name="uom_s_size" string="Size"
112 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)" />
113 </group>
114
115 </group>
116
117 </group>
118 </group>
119
120 </page>
121 </page>
122 </field>
123 </record>
124
125 ######################################### Product template ############################################
126 <record id="product_template_form_view_asperience_mrp" model="ir.ui.view">
127 <field name="name">product.template.product.form.asperience.mrp</field>
128 <field name="model">product.template</field>
129 <field name="type">form</field>
130 <field name="inherit_id" ref="asperience_product_attributes.product_template_only_form_view_attributes" />
131 <field name="arch" type="xml">
132 <field name="linked_product_tmpl_ids" position="after" >
133 <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'}"/>
134 </field>
135 <page string="Variants" position="after" >
136 <page string="Dimensions">
137 <group colspan="4">
138 <group colspan="2">
139 <separator colspan="2" string="Shape type" />
140 <field colspan="2" name="shape" select="2"
141 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)" />
142 </group>
143 </group>
144
145 <separator colspan="4" string="Variables" />
146 <group colspan="4">
147
148 <group colspan="2">
149 <separator colspan="4" string="Density" />
150 <group colspan="6" col="6">
151 <group colspan="2">
152 <field name="density_tmpl" nolabel="1"/>
153 </group>
154 <group colspan="2">
155 <field name='uom_d_weight' string="Weight"/>
156 </group>
157 <group colspan="2">
158 <field name='uom_d_size' string="SizeĀ³"/>
159 </group>
160 </group>
161 </group>
162
163 <group colspan="2">
164 <separator colspan="4" string="Size" />
165 <group colspan="2">
166 <group colspan="4"
167 attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
168 <field name="size_x_tmpl"/>
169 </group>
170 <group colspan="4"
171 attrs="{'invisible':[('shape','in',['cylindrical','other'])]}">
172 <field name="size_y_tmpl"/>
173 </group>
174 <group colspan="4" attrs="{'invisible':[('shape','in',['other'])]}">
175 <field name="size_z_tmpl"/>
176 </group>
177 <group colspan="4"
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches