Merge lp:~openerp-dev/openobject-addons/trunk-product-variants-ref-chm into lp:openobject-addons

Proposed by Christophe Matthieu (OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-product-variants-ref-chm
Merge into: lp:openobject-addons
Diff against target: 12892 lines (+2771/-5884)
123 files modified
account/product_view.xml (+25/-30)
account_anglo_saxon/product_view.xml (+4/-15)
event_sale/event_sale_view.xml (+10/-23)
hr_expense/hr_expense.py (+2/-2)
hr_expense/hr_expense_view.xml (+7/-5)
membership/membership.py (+1/-1)
membership/membership_view.xml (+16/-21)
mrp/mrp.py (+216/-175)
mrp/mrp_demo.xml (+101/-142)
mrp/mrp_view.xml (+90/-85)
mrp/procurement.py (+4/-2)
mrp/product.py (+43/-11)
mrp/report/price.py (+2/-2)
mrp/security/ir.model.access.csv (+4/-0)
mrp/stock.py (+6/-5)
mrp/test/bom_with_service_type_product.yml (+7/-7)
mrp/test/order_demo.yml (+2/-2)
mrp/views/report_mrpbomstructure.xml (+1/-2)
mrp/wizard/change_production_qty.py (+2/-2)
mrp_byproduct/test/mrp_byproduct.yml (+2/-2)
point_of_sale/point_of_sale.py (+68/-18)
point_of_sale/point_of_sale_demo.xml (+160/-159)
point_of_sale/point_of_sale_view.xml (+61/-9)
point_of_sale/security/ir.model.access.csv (+2/-2)
point_of_sale/static/src/js/db.js (+1/-1)
point_of_sale/static/src/js/models.js (+2/-2)
point_of_sale/static/src/js/widgets.js (+1/-1)
product/pricelist.py (+22/-7)
product/product.py (+332/-209)
product/product_data.xml (+0/-5)
product/product_demo.xml (+136/-422)
product/product_view.xml (+336/-575)
product/report/product_label.xml (+1/-1)
product/security/ir.model.access.csv (+8/-2)
product/security/product_security.xml (+0/-15)
product/test/product_pricelist.yml (+8/-8)
product_email_template/views/product_view.xml (+5/-5)
product_expiry/product_expiry.py (+1/-1)
product_expiry/product_expiry_view.xml (+3/-3)
product_extended/product_extended.py (+5/-5)
product_manufacturer/__init__.py (+0/-24)
product_manufacturer/__openerp__.py (+0/-46)
product_manufacturer/i18n/ar.po (+0/-75)
product_manufacturer/i18n/bg.po (+0/-81)
product_manufacturer/i18n/bs.po (+0/-72)
product_manufacturer/i18n/ca.po (+0/-82)
product_manufacturer/i18n/cs.po (+0/-72)
product_manufacturer/i18n/da.po (+0/-72)
product_manufacturer/i18n/de.po (+0/-83)
product_manufacturer/i18n/el.po (+0/-75)
product_manufacturer/i18n/es.po (+0/-83)
product_manufacturer/i18n/es_CR.po (+0/-84)
product_manufacturer/i18n/es_EC.po (+0/-79)
product_manufacturer/i18n/es_MX.po (+0/-89)
product_manufacturer/i18n/es_VE.po (+0/-89)
product_manufacturer/i18n/et.po (+0/-72)
product_manufacturer/i18n/fi.po (+0/-81)
product_manufacturer/i18n/fr.po (+0/-82)
product_manufacturer/i18n/gl.po (+0/-82)
product_manufacturer/i18n/hr.po (+0/-78)
product_manufacturer/i18n/hu.po (+0/-77)
product_manufacturer/i18n/it.po (+0/-81)
product_manufacturer/i18n/ja.po (+0/-75)
product_manufacturer/i18n/lt.po (+0/-72)
product_manufacturer/i18n/lv.po (+0/-72)
product_manufacturer/i18n/mk.po (+0/-72)
product_manufacturer/i18n/mn.po (+0/-83)
product_manufacturer/i18n/nb.po (+0/-75)
product_manufacturer/i18n/nl.po (+0/-82)
product_manufacturer/i18n/pl.po (+0/-81)
product_manufacturer/i18n/product_manufacturer.pot (+0/-71)
product_manufacturer/i18n/pt.po (+0/-81)
product_manufacturer/i18n/pt_BR.po (+0/-81)
product_manufacturer/i18n/ro.po (+0/-82)
product_manufacturer/i18n/ru.po (+0/-81)
product_manufacturer/i18n/sl.po (+0/-72)
product_manufacturer/i18n/sr.po (+0/-78)
product_manufacturer/i18n/sr@latin.po (+0/-72)
product_manufacturer/i18n/sv.po (+0/-78)
product_manufacturer/i18n/tr.po (+0/-81)
product_manufacturer/i18n/zh_CN.po (+0/-81)
product_manufacturer/i18n/zh_TW.po (+0/-72)
product_manufacturer/product_manufacturer.py (+0/-41)
product_manufacturer/product_manufacturer_view.xml (+0/-53)
product_manufacturer/security/ir.model.access.csv (+0/-2)
project_mrp/project_mrp.py (+1/-1)
project_mrp/project_mrp_view.xml (+4/-4)
purchase/purchase.py (+6/-0)
purchase/purchase_view.xml (+42/-39)
purchase_requisition/purchase_requisition.py (+2/-2)
purchase_requisition/purchase_requisition_view.xml (+4/-4)
report_intrastat/report_intrastat_view.xml (+1/-1)
sale/res_config.py (+0/-30)
sale/res_config_view.xml (+0/-4)
sale/sale.py (+1/-1)
sale_mrp/test/cancellation_propagated.yml (+6/-5)
sale_mrp/test/sale_mrp.yml (+1/-1)
sale_mrp/tests/test_move_explode.py (+2/-2)
stock/product.py (+77/-20)
stock/product_view.xml (+130/-62)
stock/stock_view.xml (+3/-116)
stock_account/product_view.xml (+3/-13)
stock_account/stock_account.py (+0/-2)
stock_landed_costs/product.py (+2/-2)
stock_landed_costs/product_view.xml (+10/-8)
stock_landed_costs/stock_landed_costs_view.xml (+7/-14)
warning/warning.py (+1/-30)
warning/warning_view.xml (+2/-2)
website_quote/data/website_quotation_demo.xml (+0/-3)
website_sale/controllers/main.py (+24/-7)
website_sale/data/data.xml (+4/-5)
website_sale/data/demo.xml (+257/-2)
website_sale/models/__init__.py (+0/-1)
website_sale/models/product.py (+90/-30)
website_sale/models/res_config.py (+0/-15)
website_sale/security/ir.model.access.csv (+6/-4)
website_sale/static/src/css/website_sale.css (+20/-0)
website_sale/static/src/css/website_sale.sass (+15/-0)
website_sale/static/src/js/website.tour.sale.js (+39/-4)
website_sale/static/src/js/website_sale.js (+59/-47)
website_sale/tests/test_sale_process.py (+1/-0)
website_sale/views/templates.xml (+176/-52)
website_sale/views/views.xml (+78/-70)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-product-variants-ref-chm
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+217190@code.launchpad.net
To post a comment you must log in.
9368. By Christophe Matthieu (OpenERP)

[WIP]

9369. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

9370. By Christophe Matthieu (OpenERP)

[IMP] product: remove group_product_variant and group_product_mono

9371. By Christophe Matthieu (OpenERP)

[WIP]

9372. By Christophe Matthieu (OpenERP)

[WIP] product: move membership to product template

9373. By Christophe Matthieu (OpenERP)

[IMP] product: merge variants and information vue

9374. By Christophe Matthieu (OpenERP)

[IMP] product: create funcion field to sum product variant qty and move field xml to product template

9375. By Christophe Matthieu (OpenERP)

[IMP] product: remove is_only_child field and add is_product_variant field; add related field

9376. By Christophe Matthieu (OpenERP)

[WIP]

9377. By Christophe Matthieu (OpenERP)

[FIX] product product_available

9378. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

9379. By Christophe Matthieu (OpenERP)

[FIX] product views

9380. By Christophe Matthieu (OpenERP)

[FIX] views mode primary of inherit

9381. By Christophe Matthieu (OpenERP)

[FIX] views mode primary of inherit

9382. By Christophe Matthieu (OpenERP)

[IMP] stock: move valuation field from product.product to product template

9383. By Christophe Matthieu (OpenERP)

[IMP] purshase add purchase_count function field on product.template

9384. By Christophe Matthieu (OpenERP)

[FIX] product views

9385. By Christophe Matthieu (OpenERP)

[FIX] product views

9386. By Christophe Matthieu (OpenERP)

[FIX] product views

9387. By Christophe Matthieu (OpenERP)

[FIX] product views

9388. By Christophe Matthieu (OpenERP)

[FIX] product views

9389. By Christophe Matthieu (OpenERP)

[FIX] product views

9390. By Christophe Matthieu (OpenERP)

[FIX] product views

9391. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

9392. By Christophe Matthieu (OpenERP)

[FIX] website_sale: variant searches and search bare

9393. By Christophe Matthieu (OpenERP)

[IMP] website_sale: search with default_code, description_sale

9394. By Christophe Matthieu (OpenERP)

[FIX] stock: product views

9395. By Christophe Matthieu (OpenERP)

[FIX] product_expiry: product view

9396. By Christophe Matthieu (OpenERP)

[FIX] mrp: product view

9397. By Christophe Matthieu (OpenERP)

[IMP] product: search product template function of attribute and product.product

9398. By Christophe Matthieu (OpenERP)

[FIX] product: views

9399. By Christophe Matthieu (OpenERP)

[IMP] product: button layout

9400. By Christophe Matthieu (OpenERP)

[IMP] stock: display qty on hand (sum of variants) on product template

9401. By Christophe Matthieu (OpenERP)

[IMP] product: display qty on product template

9402. By Christophe Matthieu (OpenERP)

[FIX] purchase: product view

9403. By Christophe Matthieu (OpenERP)

[FIX] purchase: remove wrong product view

9404. By Christophe Matthieu (OpenERP)

[IMP] stock: product view

9405. By Christophe Matthieu (OpenERP)

[FIX] product view

9406. By Christophe Matthieu (OpenERP)

[FIX] product view

9407. By Christophe Matthieu (OpenERP)

[IMP] product view

9408. By Christophe Matthieu (OpenERP)

[IMP] product view

9409. By Christophe Matthieu (OpenERP)

[IMP] product view

9410. By Christophe Matthieu (OpenERP)

[IMP] product view

9411. By Christophe Matthieu (OpenERP)

[IMP] product view

9412. By Christophe Matthieu (OpenERP)

[IMP] product: Creation of variants; Try to unlink with savepoint

9413. By Christophe Matthieu (OpenERP)

[FIX] product: _check_ean_key and add contition for call create_variant_ids

9414. By Christophe Matthieu (OpenERP)

[IMP] membership: membership field invisible if type is not service

9415. By Christophe Matthieu (OpenERP)

[IMP] product: move warranty to product template, imp view

9416. By Christophe Matthieu (OpenERP)

[IMP] product: move point of sale fields from product to template

9417. By Christophe Matthieu (OpenERP)

[IMP] product: move 'Can be Expensed' and 'Can constitute a landed cost' from product to template

9418. By Christophe Matthieu (OpenERP)

[IMP] stock: moves route_ids from product to template

9419. By Christophe Matthieu (OpenERP)

[WIP] mrp.bom: refactoring: split mrp.bom

9420. By Christophe Matthieu (OpenERP)

[WIP] mrp: mrp.bom refactoring

9421. By Christophe Matthieu (OpenERP)

[IMP] stock: move track fields from product to template

9422. By Christophe Matthieu (OpenERP)

[FIX] mrp: access right and demo

9423. By Christophe Matthieu (OpenERP)

[IMP] mrp: bom view

9424. By Christophe Matthieu (OpenERP)

[FIX] mrp: remove domains: bom_id = False

9425. By Christophe Matthieu (OpenERP)

[FIX] mrp: bom

9426. By Christophe Matthieu (OpenERP)

[FIX] mrp: bom and test

9427. By Christophe Matthieu (OpenERP)

[IMP] product: title view

9428. By Christophe Matthieu (OpenERP)

[IMP] product view

9429. By Christophe Matthieu (OpenERP)

[IMP] mrp: re-active report mrp.bom

9430. By Christophe Matthieu (OpenERP)

[FIX] sale_mrp: test cancelation_propagate: remove company_id and name

9431. By Christophe Matthieu (OpenERP)

[IMP] mrp: bom & bom.line views

9432. By Christophe Matthieu (OpenERP)

[FIX] mrp: mrp.bom.line editable tree view

9433. By Christophe Matthieu (OpenERP)

[IMP] mrp: add a search view for mrp.bom.line

9434. By Christophe Matthieu (OpenERP)

[FIX] mrp: bom default values and call to _bom_find

9435. By Christophe Matthieu (OpenERP)

[FIX] mrp: default value for product_uom

9436. By Christophe Matthieu (OpenERP)

[FIX] mrp: order uom by id for default values

9437. By Christophe Matthieu (OpenERP)

[FIX] website_sale: filter by attributes

9438. By Christophe Matthieu (OpenERP)

[IMP] product: split public category into website and pos

9439. By Christophe Matthieu (OpenERP)

[IMP] website_sale: add a test to customize page and use the variant filter

9440. By Christophe Matthieu (OpenERP)

[FIX] pos: pos.category

9441. By Christophe Matthieu (OpenERP)

[FIX] website_sale: category search

9442. By Christophe Matthieu (OpenERP)

[FIX] website_sale: tour

9443. By Christophe Matthieu (OpenERP)

[IMP] product: simplify product demo data

9444. By Christophe Matthieu (OpenERP)

[FIX] website_sale: tour cycling because the 'Product Attribute's Filters' template is activate.

9445. By Christophe Matthieu (OpenERP)

[FIX] mrp: view, move view_type, view_mode from view to action

9446. By Christophe Matthieu (OpenERP)

[IMP] product: price_extra is function of attributes value and product template

9447. By Christophe Matthieu (OpenERP)

[FIX] website_sale: display variant prices and text-muted

9448. By Christophe Matthieu (OpenERP)

[IMP] website_sale: add type of attributes

9449. By Christophe Matthieu (OpenERP)

[FIX] website_sale: bug to display attribute values on product detail

9450. By Christophe Matthieu (OpenERP)

[IMP] product view

9451. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

Unmerged revisions

9451. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

9450. By Christophe Matthieu (OpenERP)

[IMP] product view

9449. By Christophe Matthieu (OpenERP)

[FIX] website_sale: bug to display attribute values on product detail

9448. By Christophe Matthieu (OpenERP)

[IMP] website_sale: add type of attributes

9447. By Christophe Matthieu (OpenERP)

[FIX] website_sale: display variant prices and text-muted

9446. By Christophe Matthieu (OpenERP)

[IMP] product: price_extra is function of attributes value and product template

9445. By Christophe Matthieu (OpenERP)

[FIX] mrp: view, move view_type, view_mode from view to action

9444. By Christophe Matthieu (OpenERP)

[FIX] website_sale: tour cycling because the 'Product Attribute's Filters' template is activate.

9443. By Christophe Matthieu (OpenERP)

[IMP] product: simplify product demo data

9442. By Christophe Matthieu (OpenERP)

[FIX] website_sale: tour

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account/product_view.xml'
2--- account/product_view.xml 2014-01-22 09:58:26 +0000
3+++ account/product_view.xml 2014-05-26 16:10:21 +0000
4@@ -1,57 +1,52 @@
5 <?xml version="1.0" encoding="utf-8"?>
6 <openerp>
7 <data>
8- <record id="product_normal_form_view" model="ir.ui.view">
9- <field name="name">product.normal.form.inherit</field>
10- <field name="model">product.product</field>
11+ <record id="product_template_form_view" model="ir.ui.view">
12+ <field name="name">product.template.form.inherit</field>
13+ <field name="model">product.template</field>
14 <field name="priority">5</field>
15- <field name="inherit_id" ref="product.product_normal_form_view"/>
16+ <field name="inherit_id" ref="product.product_template_form_view"/>
17 <field name="arch" type="xml">
18- <notebook position="inside">
19+ <page string="Sales" position="after">
20 <page string="Accounting" groups="account.group_account_invoice">
21+ <group>
22+ <label for="categ_id" string="Internal Category"/>
23+ <div><field name="categ_id" colspan="3" nolabel="1"/></div>
24+ </group>
25 <group name="properties">
26 <group>
27 <field name="property_account_income" domain="[('type','=','other')]" groups="account.group_account_user"
28- attrs="{'readonly': [('is_only_child', '=', False)]}"/>
29+ attrs="{'readonly': [('is_product_variant', '=', True)]}"/>
30 <field name="taxes_id" colspan="2" widget="many2many_tags"
31- attrs="{'readonly':[ '|', ('sale_ok','=',0), ('is_only_child', '=', False)]}"/>
32+ attrs="{'readonly':[ '|', ('sale_ok','=',0), ('is_product_variant', '=', True)]}"/>
33 </group>
34 <group>
35 <field name="property_account_expense" domain="[('type','=','other')]" groups="account.group_account_user"
36- attrs="{'readonly': [('is_only_child', '=', False)]}"/>
37+ attrs="{'readonly': [('is_product_variant', '=', True)]}"/>
38 <field name="supplier_taxes_id" colspan="2" widget="many2many_tags"
39- attrs="{'readonly': [('is_only_child', '=', False)]}"/>
40+ attrs="{'readonly': [('is_product_variant', '=', True)]}"/>
41 </group>
42 </group>
43 </page>
44- </notebook>
45+ </page>
46 </field>
47 </record>
48
49- <record id="product_template_form_view" model="ir.ui.view">
50- <field name="name">product.template.product.form.inherit</field>
51+ <record id="product_template_search_view" model="ir.ui.view">
52+ <field name="name">product.template.search</field>
53 <field name="model">product.template</field>
54- <field name="inherit_id" ref="product.product_template_form_view"/>
55+ <field name="mode">primary</field>
56+ <field name="inherit_id" ref="product.product_template_search_view"/>
57 <field name="arch" type="xml">
58- <notebook position="inside">
59- <page string="Accounting">
60- <group name="properties">
61- <group>
62- <field name="property_account_income" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
63- <field name="taxes_id" colspan="2" widget="many2many_tags"/>
64- </group>
65- <group>
66- <field name="property_account_expense" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
67- <field name="supplier_taxes_id" colspan="2" widget="many2many_tags"/>
68- </group>
69- </group>
70- </page>
71- </notebook>
72- </field>
73+ <field name="product_variant_ids" position="after">
74+ <field name="categ_id"/>
75+ </field>
76+ <xpath expr="//group[@string='Group by...']" position="inside">
77+ <filter string='Category' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'categ_id'}"/>
78+ </xpath>
79+ </field>
80 </record>
81
82-
83-
84 <record id="view_category_property_form" model="ir.ui.view">
85 <field name="name">product.category.property.form.inherit</field>
86 <field name="model">product.category</field>
87
88=== modified file 'account_anglo_saxon/product_view.xml'
89--- account_anglo_saxon/product_view.xml 2013-11-22 05:48:50 +0000
90+++ account_anglo_saxon/product_view.xml 2014-05-26 16:10:21 +0000
91@@ -1,29 +1,18 @@
92 <?xml version="1.0"?>
93 <openerp>
94 <data>
95- <record id="product_normal_form_view" model="ir.ui.view">
96+ <record id="product_template_form_view" model="ir.ui.view">
97 <field name="name">product.normal.form.inherit.stock</field>
98- <field name="model">product.product</field>
99- <field name="inherit_id" ref="account.product_normal_form_view"/>
100- <field name="arch" type="xml">
101- <field name="property_account_expense" position="after">
102- <label string="" colspan="2"/>
103- <field name="property_account_creditor_price_difference" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]" attrs="{'readonly':[('purchase_ok','=',0)]}" />
104- <newline/>
105- </field>
106- </field>
107- </record>
108-
109- <record id="product_template_form_view" model="ir.ui.view">
110- <field name="name">product.template.product.form.inherit</field>
111 <field name="model">product.template</field>
112 <field name="inherit_id" ref="account.product_template_form_view"/>
113 <field name="arch" type="xml">
114 <field name="property_account_expense" position="after">
115+ <label string="" colspan="2"/>
116+ <field name="purchase_ok" invisible="1"/>
117 <field name="property_account_creditor_price_difference" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]" attrs="{'readonly':[('purchase_ok','=',0)]}" />
118 <newline/>
119 </field>
120- </field>
121+ </field>
122 </record>
123
124 <record id="view_category_property_form" model="ir.ui.view">
125
126=== modified file 'event_sale/event_sale_view.xml'
127--- event_sale/event_sale_view.xml 2014-05-12 05:01:53 +0000
128+++ event_sale/event_sale_view.xml 2014-05-26 16:10:21 +0000
129@@ -1,18 +1,19 @@
130 <?xml version="1.0"?>
131 <openerp>
132 <data>
133- <record model="ir.ui.view" id="event_sale_product_form">
134- <field name="model">product.product</field>
135- <field name="inherit_id" ref="product.product_normal_form_view" />
136+
137+ <record model="ir.ui.view" id="event_sale_product_template_form">
138+ <field name="model">product.template</field>
139+ <field name="inherit_id" ref="product.product_template_form_view" />
140 <field name="arch" type="xml">
141- <div name="options" position="after">
142- <field name="event_ok" on_change="onchange_event_ok(type, event_ok, context)"
143- attrs="{'readonly': [('is_only_child', '=', False)]}"/>
144- <label for="event_ok"/>
145+ <div name="options" position="inside">
146+ <div>
147+ <field name="event_ok" on_change="onchange_event_ok(type, event_ok, context)"/>
148+ <label for="event_ok"/>
149+ </div>
150 </div>
151 <field name='type' position="after">
152- <field name="event_type_id" attrs="{'invisible': [('event_ok', '=', False)],
153- 'readonly': [('is_only_child', '=', False)]}"/>
154+ <field name="event_type_id" attrs="{'invisible': [('event_ok', '=', False)]}"/>
155 </field>
156 </field>
157 </record>
158@@ -50,20 +51,6 @@
159 </field>
160 </record>
161
162- <record model="ir.ui.view" id="event_sale_product_template_form">
163- <field name="model">product.template</field>
164- <field name="inherit_id" ref="product.product_template_form_view" />
165- <field name="arch" type="xml">
166- <div name="options" position="inside">
167- <field name="event_ok" on_change="onchange_event_ok(type, event_ok, context)"/>
168- <label for="event_ok"/>
169- </div>
170- <field name='company_id' position="after">
171- <field name="event_type_id" attrs="{'invisible': [('event_ok', '=', False)]}"/>
172- </field>
173- </field>
174- </record>
175-
176 <record model="ir.ui.view" id="event_order_line">
177 <field name="name">event.sale.order</field>
178 <field name="model">sale.order</field>
179
180=== modified file 'hr_expense/hr_expense.py'
181--- hr_expense/hr_expense.py 2014-03-10 14:36:00 +0000
182+++ hr_expense/hr_expense.py 2014-05-26 16:10:21 +0000
183@@ -392,8 +392,8 @@
184 return result
185
186
187-class product_product(osv.osv):
188- _inherit = "product.product"
189+class product_template(osv.osv):
190+ _inherit = "product.template"
191 _columns = {
192 'hr_expense_ok': fields.boolean('Can be Expensed', help="Specify if the product can be selected in an HR expense line."),
193 }
194
195=== modified file 'hr_expense/hr_expense_view.xml'
196--- hr_expense/hr_expense_view.xml 2014-04-11 13:18:42 +0000
197+++ hr_expense/hr_expense_view.xml 2014-05-26 16:10:21 +0000
198@@ -191,13 +191,15 @@
199
200
201 <record id="view_product_hr_expense_form" model="ir.ui.view">
202- <field name="name">product.product.expense.form</field>
203- <field name="model">product.product</field>
204- <field name="inherit_id" ref="product.product_normal_form_view"/>
205+ <field name="name">product.template.expense.form</field>
206+ <field name="model">product.template</field>
207+ <field name="inherit_id" ref="product.product_template_form_view"/>
208 <field name="arch" type="xml">
209 <div name="options" position="inside">
210- <field name="hr_expense_ok"/>
211- <label for="hr_expense_ok"/>
212+ <div>
213+ <field name="hr_expense_ok"/>
214+ <label for="hr_expense_ok"/>
215+ </div>
216 </div>
217 </field>
218 </record>
219
220=== modified file 'membership/membership.py'
221--- membership/membership.py 2013-10-27 12:31:04 +0000
222+++ membership/membership.py 2014-05-26 16:10:21 +0000
223@@ -462,7 +462,7 @@
224 return super(Product,self).fields_view_get(cr, user, view_id, view_type, context, toolbar, submenu)
225
226 '''Product'''
227- _inherit = 'product.product'
228+ _inherit = 'product.template'
229 _columns = {
230 'membership': fields.boolean('Membership', help='Check if the product is eligible for membership.'),
231 'membership_date_from': fields.date('Membership Start Date', help='Date from which membership becomes active.'),
232
233=== modified file 'membership/membership_view.xml'
234--- membership/membership_view.xml 2013-10-27 12:31:04 +0000
235+++ membership/membership_view.xml 2014-05-26 16:10:21 +0000
236@@ -8,7 +8,7 @@
237
238 <record model="ir.ui.view" id="membership_product_search_form_view">
239 <field name="name">membership.product.search.form</field>
240- <field name="model">product.product</field>
241+ <field name="model">product.template</field>
242 <field name="arch" type="xml">
243 <search string="Membership Products">
244 <field name="name" filter_domain="['|',('name','ilike',self),('code','ilike',self)]" string="Membership Product"/>
245@@ -24,10 +24,9 @@
246
247 <record model="ir.ui.view" id="membership_products_tree">
248 <field name="name">Membership products</field>
249- <field name="model">product.product</field>
250+ <field name="model">product.template</field>
251 <field name="arch" type="xml">
252 <tree string="Membership products">
253- <field name="code"/>
254 <field name="name"/>
255 <field name="membership_date_from"/>
256 <field name="membership_date_to"/>
257@@ -41,7 +40,7 @@
258
259 <record model="ir.ui.view" id="membership_products_form">
260 <field name="name">Membership Products</field>
261- <field name="model">product.product</field>
262+ <field name="model">product.template</field>
263 <field name="arch" type="xml">
264 <form string="Membership products" version="7.0">
265 <sheet>
266@@ -81,31 +80,27 @@
267 </field>
268 </record>
269
270- <record model="ir.ui.view" id="product_normal_form_view">
271+ <record model="ir.ui.view" id="product_template_form_view">
272 <field name="name">Membership Products</field>
273- <field name="model">product.product</field>
274+ <field name="model">product.template</field>
275 <field name="priority">6</field>
276- <field name="inherit_id" ref="product.product_normal_form_view"/>
277+ <field name="inherit_id" ref="product.product_template_form_view"/>
278 <field name="arch" type="xml">
279- <page string="Accounting" position="after">
280- <page string="Membership">
281- <group col="1">
282- <group>
283- <field name="membership" readonly="0"/>
284- </group>
285- <group attrs="{'invisible':[('membership','=',False)]}">
286- <field name="membership_date_from" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
287- <field name="membership_date_to" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
288- </group>
289- </group>
290- </page>
291- </page>
292+ <field name="type" position="after">
293+ <field name="membership" readonly="0" attrs="{'invisible': [('type', '!=', 'service')]}"/>
294+ </field>
295+ <field name="description" position="before">
296+ <group attrs="{'invisible':[('membership','=',False)]}">
297+ <field name="membership_date_from" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
298+ <field name="membership_date_to" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
299+ </group>
300+ </field>
301 </field>
302 </record>
303
304 <record model="ir.actions.act_window" id="action_membership_products">
305 <field name="name">Membership Products</field>
306- <field name="res_model">product.product</field>
307+ <field name="res_model">product.template</field>
308 <field name="domain">[('membership','=',True), ('type', '=', 'service')]</field>
309 <field name="context">{'membership':True, 'type':'service', 'default_membership': True, 'default_type': 'service'}</field>
310 <field name="search_view_id" ref="membership_product_search_form_view"/>
311
312=== modified file 'mrp/mrp.py'
313--- mrp/mrp.py 2014-05-08 11:59:17 +0000
314+++ mrp/mrp.py 2014-05-26 16:10:21 +0000
315@@ -178,207 +178,266 @@
316 bom_parent = bom_obj.browse(cr, uid, bom_id, context=context)
317 for bom in self.browse(cr, uid, ids, context=context):
318 if (bom_parent) or (bom.id == bom_id):
319- result[bom.id] = map(lambda x: x.id, bom.bom_lines)
320+ result[bom.id] = map(lambda x: x.id, bom.bom_line_ids)
321 else:
322 result[bom.id] = []
323- if bom.bom_lines:
324+ if bom.bom_line_ids:
325 continue
326 ok = ((name=='child_complete_ids'))
327 if (bom.type=='phantom' or ok):
328- sids = bom_obj.search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
329+ sids = bom_obj.search(cr, uid, [('product_tmpl_id','=',bom.product_tmpl_id.id)])
330 if sids:
331 bom2 = bom_obj.browse(cr, uid, sids[0], context=context)
332- result[bom.id] += map(lambda x: x.id, bom2.bom_lines)
333-
334+ result[bom.id] += map(lambda x: x.id, bom2.bom_line_ids)
335 return result
336
337 _columns = {
338 'name': fields.char('Name', size=64),
339 'code': fields.char('Reference', size=16),
340 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the bills of material without removing it."),
341- 'type': fields.selection([('normal', 'Normal BoM'), ('phantom', 'Sets / Phantom')], 'BoM Type', required=True,
342- help= "If a by-product is used in several products, it can be useful to create its own BoM. "\
343- "Though if you don't want separated production orders for this by-product, select Set/Phantom as BoM type. "\
344- "If a Phantom BoM is used for a root product, it will be sold and shipped as a set of components, instead of being produced."),
345- 'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."),
346- 'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."),
347- 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bills of material."),
348+ 'type': fields.selection([('normal', 'Normal'), ('phantom', 'Set')], 'BoM Type', required=True,
349+ help= "Set: When processing a sales order for this product, the delivery order will contain the raw materials, instead of the finished product."),
350 'position': fields.char('Internal Reference', size=64, help="Reference to a position in an external plan."),
351- 'product_id': fields.many2one('product.product', 'Product', required=True),
352- 'product_uos_qty': fields.float('Product UOS Qty'),
353- 'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
354+ 'product_tmpl_id': fields.many2one('product.template', 'Product', required=True),
355+ 'product_id': fields.many2one('product.product', 'Product Variant',
356+ domain="[('product_tmpl_id','=',product_tmpl_id)]",
357+ help="If a product variant is defined the BOM is available only for this product."),
358+ 'bom_line_ids': fields.one2many('mrp.bom.line', 'bom_id', 'BoM Lines'),
359+
360 'product_qty': fields.float('Product Quantity', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
361 'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True, help="Unit of Measure (Unit of Measure) is the unit of measurement for the inventory control"),
362+ 'date_start': fields.date('Valid From', help="Validity of this BoM. Keep empty if it's always valid."),
363+ 'date_stop': fields.date('Valid Until', help="Validity of this BoM. Keep empty if it's always valid."),
364+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bills of material."),
365+ 'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of work centers) to produce the finished product. "\
366+ "The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production planning."),
367 'product_rounding': fields.float('Product Rounding', help="Rounding applied on the product quantity."),
368- 'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% within the production process."),
369- 'bom_lines': fields.one2many('mrp.bom', 'bom_id', 'BoM Lines'),
370- 'bom_id': fields.many2one('mrp.bom', 'Parent BoM', ondelete='cascade', select=True),
371- 'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of work centers) to produce the finished product. The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production planning."),
372- 'property_ids': fields.many2many('mrp.property', 'mrp_bom_property_rel', 'bom_id', 'property_id', 'Properties'),
373+ 'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% during the production process."),
374+ 'property_ids': fields.many2many('mrp.property', string='Properties'),
375 'child_complete_ids': fields.function(_child_compute, relation='mrp.bom', string="BoM Hierarchy", type='many2many'),
376 'company_id': fields.many2one('res.company', 'Company', required=True),
377 }
378+
379+ def _get_uom_id(self, cr, uid, *args):
380+ return self.pool["product.uom"].search(cr, uid, [], limit=1, order='id')[0]
381 _defaults = {
382 'active': lambda *a: 1,
383+ 'product_qty': lambda *a: 1.0,
384 'product_efficiency': lambda *a: 1.0,
385- 'product_qty': lambda *a: 1.0,
386 'product_rounding': lambda *a: 0.0,
387 'type': lambda *a: 'normal',
388+ 'product_uom': _get_uom_id,
389 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.bom', context=c),
390 }
391 _order = "sequence"
392- _parent_name = "bom_id"
393- _sql_constraints = [
394- ('bom_qty_zero', 'CHECK (product_qty>0)', 'All product quantities must be greater than 0.\n' \
395- 'You should install the mrp_byproduct module if you want to manage extra products on BoMs !'),
396- ]
397-
398- def _check_recursion(self, cr, uid, ids, context=None):
399- level = 100
400- while len(ids):
401- cr.execute('select distinct bom_id from mrp_bom where id IN %s', (tuple(ids),))
402- ids = filter(None, map(lambda x: x[0], cr.fetchall()))
403- if not level:
404- return False
405- level -= 1
406- return True
407-
408- def _check_product(self, cr, uid, ids, context=None):
409- all_prod = []
410- boms = self.browse(cr, uid, ids, context=context)
411- def check_bom(boms):
412- res = True
413- for bom in boms:
414- if bom.product_id.id in all_prod:
415- res = res and False
416- all_prod.append(bom.product_id.id)
417- lines = bom.bom_lines
418- if lines:
419- res = res and check_bom([bom_id for bom_id in lines if bom_id not in boms])
420- return res
421- return check_bom(boms)
422-
423- _constraints = [
424- (_check_recursion, 'Error ! You cannot create recursive BoM.', ['parent_id']),
425- (_check_product, 'BoM line product should not be same as BoM product.', ['product_id']),
426- ]
427-
428- def onchange_product_id(self, cr, uid, ids, product_id, name, product_qty=0, context=None):
429- """ Changes UoM and name if product_id changes.
430- @param name: Name of the field
431- @param product_id: Changed product_id
432- @return: Dictionary of changed values
433- """
434- res = {}
435- if product_id:
436- prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
437- res['value'] = {'name': prod.name, 'product_uom': prod.uom_id.id, 'product_uos_qty': 0, 'product_uos': False}
438- if prod.uos_id.id:
439- res['value']['product_uos_qty'] = product_qty * prod.uos_coeff
440- res['value']['product_uos'] = prod.uos_id.id
441- return res
442-
443- def onchange_uom(self, cr, uid, ids, product_id, product_uom, context=None):
444- res = {'value': {}}
445- if not product_uom or not product_id:
446- return res
447- product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
448- uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
449- if uom.category_id.id != product.uom_id.category_id.id:
450- res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
451- res['value'].update({'product_uom': product.uom_id.id})
452- return res
453-
454- def _bom_find(self, cr, uid, product_id, product_uom, properties=None):
455+
456+ def _bom_find(self, cr, uid, product_uom, product_tmpl_id=None, product_id=None, properties=None):
457 """ Finds BoM for particular product and product uom.
458- @param product_id: Selected product.
459+ @param product_tmpl_id: Selected product.
460 @param product_uom: Unit of measure of a product.
461 @param properties: List of related properties.
462 @return: False or BoM id.
463 """
464 if properties is None:
465 properties = []
466- domain = [('product_id', '=', product_id), ('bom_id', '=', False),
467- '|', ('date_start', '=', False), ('date_start', '<=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
468- '|', ('date_stop', '=', False), ('date_stop', '>=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
469+ domain = None
470+ if product_id:
471+ domain = ['|',('product_id', '=', product_id),('product_tmpl_id.product_variant_ids', '=', product_id)]
472+ else:
473+ domain = [('product_id', '=', False), ('product_tmpl_id', '=', product_tmpl_id)]
474+ if product_uom:
475+ domain += [('product_uom','=',product_uom)]
476+ domain = domain + [ '|', ('date_start', '=', False), ('date_start', '<=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
477+ '|', ('date_stop', '=', False), ('date_stop', '>=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
478 ids = self.search(cr, uid, domain)
479- max_prop = 0
480- result = False
481 for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
482- prop = 0
483- for prop_id in bom.property_ids:
484- if prop_id.id in properties:
485- prop += 1
486- if (prop > max_prop) or ((max_prop == 0) and not result):
487- result = bom.id
488- max_prop = prop
489- return result
490+ if not set(map(int,bom.property_ids or [])) - set(properties or []):
491+ return bom.id
492+ return False
493
494- def _bom_explode(self, cr, uid, bom, factor, properties=None, addthis=False, level=0, routing_id=False):
495+ def _bom_explode(self, cr, uid, bom, product, factor, properties=None, level=0, routing_id=False, previous_products=None, master_bom=None):
496 """ Finds Products and Work Centers for related BoM for manufacturing order.
497- @param bom: BoM of particular product.
498+ @param bom: BoM of particular product template.
499+ @param product: Select a particular variant of the BoM. If False use BoM without variants.
500 @param factor: Factor of product UoM.
501 @param properties: A List of properties Ids.
502- @param addthis: If BoM found then True else False.
503 @param level: Depth level to find BoM lines starts from 10.
504+ @param previous_products: List of product previously use by bom explore to avoid recursion
505+ @param master_bom: When recursion, used to display the name of the master bom
506 @return: result: List of dictionaries containing product details.
507 result2: List of dictionaries containing Work Center details.
508 """
509 routing_obj = self.pool.get('mrp.routing')
510- factor = factor / (bom.product_efficiency or 1.0)
511- factor = _common.ceiling(factor, bom.product_rounding)
512- if factor < bom.product_rounding:
513- factor = bom.product_rounding
514+ all_prod = [] + (previous_products or [])
515+ master_bom = master_bom or bom
516+
517+ def _factor(factor, product_efficiency, product_rounding):
518+ factor = factor / (product_efficiency or 1.0)
519+ factor = _common.ceiling(factor, product_rounding)
520+ if factor < product_rounding:
521+ factor = product_rounding
522+ return factor
523+
524+ factor = _factor(factor, bom.product_efficiency, bom.product_rounding)
525+
526 result = []
527 result2 = []
528- phantom = False
529- if bom.type == 'phantom' and not bom.bom_lines:
530- newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
531-
532- if newbom:
533- res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor * bom.product_qty, properties, addthis=True, level=level + 10)
534- result = result + res[0]
535- result2 = result2 + res[1]
536- phantom = True
537- else:
538- phantom = False
539- if not phantom:
540- if addthis and not bom.bom_lines:
541+
542+ routing = (routing_id and routing_obj.browse(cr, uid, routing_id)) or bom.routing_id or False
543+ if routing:
544+ for wc_use in routing.workcenter_lines:
545+ wc = wc_use.workcenter_id
546+ d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
547+ mult = (d + (m and 1.0 or 0.0))
548+ cycle = mult * wc_use.cycle_nbr
549+ result2.append({
550+ 'name': tools.ustr(wc_use.name) + ' - ' + tools.ustr(bom.product_tmpl_id.name_get()[0][1]),
551+ 'workcenter_id': wc.id,
552+ 'sequence': level + (wc_use.sequence or 0),
553+ 'cycle': cycle,
554+ 'hour': float(wc_use.hour_nbr * mult + ((wc.time_start or 0.0) + (wc.time_stop or 0.0) + cycle * (wc.time_cycle or 0.0)) * (wc.time_efficiency or 1.0)),
555+ })
556+
557+ for bom_line_id in bom.bom_line_ids:
558+ if bom_line_id.date_start and bom_line_id.date_start > time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) or \
559+ bom_line_id.date_stop and bom_line_id.date_stop > time.strftime(DEFAULT_SERVER_DATETIME_FORMAT):
560+ continue
561+ # check properties
562+ if set(map(int,bom_line_id.property_ids or [])) - set(properties or []):
563+ continue
564+ # all bom_line_id variant values must be in the product
565+ if bom_line_id.variants_ids:
566+ if not product or (set(map(int,bom_line_id.variants_ids or [])) - set(map(int,product.variant_ids))):
567+ continue
568+
569+ if bom_line_id.product_id.id in all_prod:
570+ raise osv.except_osv(_('Invalid Action!'), _('BoM "%s" contains a BoM line with a product recursion: "%s".') % (master_bom.name,bom_line_id.product_id.name_get()[0][1]))
571+ all_prod.append(bom_line_id.product_id.id)
572+
573+ if bom_line_id.type != "phantom":
574 result.append({
575- 'name': bom.product_id.name,
576- 'product_id': bom.product_id.id,
577- 'product_qty': bom.product_qty * factor,
578- 'product_uom': bom.product_uom.id,
579- 'product_uos_qty': bom.product_uos and bom.product_uos_qty * factor or False,
580- 'product_uos': bom.product_uos and bom.product_uos.id or False,
581+ 'name': bom_line_id.product_id.name,
582+ 'product_id': bom_line_id.product_id.id,
583+ 'product_qty': _factor(bom_line_id.product_qty * factor, bom_line_id.product_efficiency, bom_line_id.product_rounding),
584+ 'product_uom': bom_line_id.product_uom.id,
585+ 'product_uos_qty': bom_line_id.product_uos and bom_line_id.product_uos_qty * factor or False,
586+ 'product_uos': bom_line_id.product_uos and bom_line_id.product_uos.id or False,
587 })
588- routing = (routing_id and routing_obj.browse(cr, uid, routing_id)) or bom.routing_id or False
589- if routing:
590- for wc_use in routing.workcenter_lines:
591- wc = wc_use.workcenter_id
592- d, m = divmod(factor, wc_use.workcenter_id.capacity_per_cycle)
593- mult = (d + (m and 1.0 or 0.0))
594- cycle = mult * wc_use.cycle_nbr
595- result2.append({
596- 'name': tools.ustr(wc_use.name) + ' - ' + tools.ustr(bom.product_id.name),
597- 'workcenter_id': wc.id,
598- 'sequence': level + (wc_use.sequence or 0),
599- 'cycle': cycle,
600- 'hour': float(wc_use.hour_nbr * mult + ((wc.time_start or 0.0) + (wc.time_stop or 0.0) + cycle * (wc.time_cycle or 0.0)) * (wc.time_efficiency or 1.0)),
601- })
602- for bom2 in bom.bom_lines:
603- res = self._bom_explode(cr, uid, bom2, factor, properties, addthis=True, level=level + 10)
604- result = result + res[0]
605- result2 = result2 + res[1]
606+ else:
607+ bom_id = self._bom_find(cr, uid, bom_line_id.product_uom.id, product_id=bom_line_id.product_id.id, properties=properties)
608+ bom2 = self.browse(cr, uid, bom_id)
609+ if bom2:
610+ res = self._bom_explode(cr, uid, bom2, bom_line_id.product_id, factor,
611+ properties=properties, level=level + 10, previous_products=all_prod, master_bom=master_bom)
612+ result = result + res[0]
613+ result2 = result2 + res[1]
614+ else:
615+ raise osv.except_osv(_('Invalid Action!'), _('BoM "%s" contains a phantom BoM line but the product "%s" don\'t have any BoM defined.') % (master_bom.name,bom_line_id.product_id.name_get()[0][1]))
616+
617 return result, result2
618
619 def copy_data(self, cr, uid, id, default=None, context=None):
620 if default is None:
621 default = {}
622 bom_data = self.read(cr, uid, id, [], context=context)
623- default.update(name=_("%s (copy)") % (bom_data['name']), bom_id=False)
624+ default.update(name=_("%s (copy)") % (bom_data['name']))
625 return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
626
627+ def onchange_uom(self, cr, uid, ids, product_tmpl_id, product_uom, context=None):
628+ res = {'value': {}}
629+ if not product_uom or not product_tmpl_id:
630+ return res
631+ product = self.pool.get('product.template').browse(cr, uid, product_tmpl_id, context=context)
632+ uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
633+ if uom.category_id.id != product.uom_id.category_id.id:
634+ res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
635+ res['value'].update({'product_uom': product.uom_id.id})
636+ return res
637+
638+ def onchange_product_tmpl_id(self, cr, uid, ids, product_tmpl_id, product_qty=0, context=None):
639+ """ Changes UoM and name if product_id changes.
640+ @param product_id: Changed product_id
641+ @return: Dictionary of changed values
642+ """
643+ res = {}
644+ if product_tmpl_id:
645+ prod = self.pool.get('product.template').browse(cr, uid, product_tmpl_id, context=context)
646+ res['value'] = {
647+ 'name': prod.name,
648+ 'product_uom': prod.uom_id.id,
649+ }
650+ return res
651+
652+class mrp_bom_line(osv.osv):
653+ _name = 'mrp.bom.line'
654+ _order = "sequence"
655+
656+ _columns = {
657+ 'type': fields.selection([('normal', 'Normal'), ('phantom', 'Phantom')], 'BoM Line Type', required=True,
658+ help="Phantom: this product line will not appear in the raw materials of manufacturing orders,"
659+ "it will be directly replaced by the raw materials of its own BoM, without triggering"
660+ "an extra manufacturing order."),
661+ 'product_id': fields.many2one('product.product', 'Product', required=True),
662+ 'product_uos_qty': fields.float('Product UOS Qty'),
663+ 'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
664+ 'product_qty': fields.float('Product Quantity', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
665+ 'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True,
666+ help="Unit of Measure (Unit of Measure) is the unit of measurement for the inventory control"),
667+
668+ 'date_start': fields.date('Valid From', help="Validity of component. Keep empty if it's always valid."),
669+ 'date_stop': fields.date('Valid Until', help="Validity of component. Keep empty if it's always valid."),
670+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying."),
671+ 'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of work centers) to produce the finished product. The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production planning."),
672+ 'product_rounding': fields.float('Product Rounding', help="Rounding applied on the product quantity."),
673+ 'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% within the production process."),
674+ 'property_ids': fields.many2many('mrp.property', string='Properties'),
675+
676+ 'bom_id': fields.many2one('mrp.bom', 'Parent BoM', ondelete='cascade', select=True, required=True),
677+ 'variants_ids': fields.many2many('product.attribute.value', string='Variants', help="BOM Product Variants needed form apply this line."),
678+ }
679+
680+ def _get_uom_id(self, cr, uid, *args):
681+ return self.pool["product.uom"].search(cr, uid, [], limit=1, order='id')[0]
682+ _defaults = {
683+ 'product_qty': lambda *a: 1.0,
684+ 'product_efficiency': lambda *a: 1.0,
685+ 'product_rounding': lambda *a: 0.0,
686+ 'type': lambda *a: 'normal',
687+ 'product_uom': _get_uom_id,
688+ }
689+ _sql_constraints = [
690+ ('bom_qty_zero', 'CHECK (product_qty>0)', 'All product quantities must be greater than 0.\n' \
691+ 'You should install the mrp_byproduct module if you want to manage extra products on BoMs !'),
692+ ]
693+
694+ def onchange_uom(self, cr, uid, ids, product_id, product_uom, context=None):
695+ res = {'value': {}}
696+ if not product_uom or not product_id:
697+ return res
698+ product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
699+ uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
700+ if uom.category_id.id != product.uom_id.category_id.id:
701+ res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
702+ res['value'].update({'product_uom': product.uom_id.id})
703+ return res
704+
705+ def onchange_product_id(self, cr, uid, ids, product_id, product_qty=0, context=None):
706+ """ Changes UoM if product_id changes.
707+ @param product_id: Changed product_id
708+ @return: Dictionary of changed values
709+ """
710+ res = {}
711+ if product_id:
712+ prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
713+ res['value'] = {
714+ 'product_uom': prod.uom_id.id,
715+ 'product_uos_qty': 0,
716+ 'product_uos': False
717+ }
718+ if prod.uos_id.id:
719+ res['value']['product_uos_qty'] = product_qty * prod.uos_coeff
720+ res['value']['product_uos'] = prod.uos_id.id
721+ return res
722
723 class mrp_production(osv.osv):
724 """
725@@ -475,7 +534,7 @@
726 'date_planned': fields.datetime('Scheduled Date', required=True, select=1, readonly=True, states={'draft': [('readonly', False)]}),
727 'date_start': fields.datetime('Start Date', select=True, readonly=True),
728 'date_finished': fields.datetime('End Date', select=True, readonly=True),
729- 'bom_id': fields.many2one('mrp.bom', 'Bill of Material', domain=[('bom_id', '=', False)], readonly=True, states={'draft': [('readonly', False)]},
730+ 'bom_id': fields.many2one('mrp.bom', 'Bill of Material', readonly=True, states={'draft': [('readonly', False)]},
731 help="Bill of Materials allow you to define the list of required raw materials to make a finished product."),
732 'routing_id': fields.many2one('mrp.routing', string='Routing', on_delete='set null', readonly=True, states={'draft': [('readonly', False)]},
733 help="The list of operations (list of work centers) to produce the finished product. The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production plannification."),
734@@ -586,7 +645,7 @@
735 }}
736 bom_obj = self.pool.get('mrp.bom')
737 product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
738- bom_id = bom_obj._bom_find(cr, uid, product.id, product.uom_id and product.uom_id.id, [])
739+ bom_id = bom_obj._bom_find(cr, uid, product.uom_id and product.uom_id.id, product_id=product.id, properties=[])
740 routing_id = False
741 if bom_id:
742 bom_point = bom_obj.browse(cr, uid, bom_id, context=context)
743@@ -635,7 +694,7 @@
744 bom_point = production.bom_id
745 bom_id = production.bom_id.id
746 if not bom_point:
747- bom_id = bom_obj._bom_find(cr, uid, production.product_id.id, production.product_uom.id, properties)
748+ bom_id = bom_obj._bom_find(cr, uid, production.product_uom.id, product_id=production.product_id.id, properties=properties)
749 if bom_id:
750 bom_point = bom_obj.browse(cr, uid, bom_id)
751 routing_id = bom_point.routing_id.id or False
752@@ -646,9 +705,8 @@
753
754 # get components and workcenter_lines from BoM structure
755 factor = uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, bom_point.product_uom.id)
756- res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id)
757- results = res[0] # product_lines
758- results2 = res[1] # workcenter_lines
759+ # product_lines, workcenter_lines
760+ results, results2 = bom_obj._bom_explode(cr, uid, bom_point, production.product_id, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id)
761 # reset product_lines in production order
762 for line in results:
763 line['production_id'] = production.id
764@@ -777,15 +835,18 @@
765 dicts = {}
766 # Find product qty to be consumed and consume it
767 for scheduled in production.product_lines:
768- consumed_qty = consumed_data.get(scheduled.product_id.id, 0.0)
769+ product_id = scheduled.product_id.id
770+
771+ consumed_qty = consumed_data.get(product_id, 0.0)
772+
773 # qty available for consume and produce
774 qty_avail = scheduled.product_qty - consumed_qty
775 if qty_avail <= 0.0:
776 # there will be nothing to consume for this raw material
777 continue
778
779- if not dicts.get(scheduled.product_id.id):
780- dicts[scheduled.product_id.id] = {}
781+ if not dicts.get(product_id):
782+ dicts[product_id] = {}
783
784 # total qty of consumed product we need after this consumption
785 total_consume = ((product_qty + produced_qty) * scheduled.product_qty / production.product_qty)
786@@ -795,9 +856,8 @@
787 for move in production.move_lines:
788 if qty <= 0.0:
789 break
790- if move.product_id.id != scheduled.product_id.id:
791+ if move.product_id.id != product_id:
792 continue
793- product_id = scheduled.product_id.id
794
795 q = min(move.product_qty, qty)
796 quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, scheduled.product_id, q, domain=[('qty', '>', 0.0)],
797@@ -895,7 +955,8 @@
798 #consumed more in wizard than previously planned
799 product = self.pool.get('product.product').browse(cr, uid, consume['product_id'], context=context)
800 extra_move_id = self._make_consume_line_from_data(cr, uid, production, product, product.uom_id.id, remaining_qty, False, 0, context=context)
801- stock_mov_obj.action_done(cr, uid, [extra_move_id], context=context)
802+ if extra_move_id:
803+ stock_mov_obj.action_done(cr, uid, [extra_move_id], context=context)
804
805 self.message_post(cr, uid, production_id, body=_("%s produced") % self._description, context=context)
806 self.signal_button_produce_done(cr, uid, [production_id])
807@@ -1111,24 +1172,4 @@
808 'production_id': fields.many2one('mrp.production', 'Production Order', select=True),
809 }
810
811-class product_product(osv.osv):
812- _inherit = "product.product"
813- def _bom_orders_count(self, cr, uid, ids, field_name, arg, context=None):
814- Bom = self.pool('mrp.bom')
815- Production = self.pool('mrp.production')
816- return {
817- product_id: {
818- 'bom_count': Bom.search_count(cr, uid, [('product_id', '=', product_id), ('bom_id', '=', False)], context=context),
819- 'mo_count': Production.search_count(cr,uid, [('product_id', '=', product_id)], context=context),
820- 'bom_strct': Bom.search_count(cr, uid, [('product_id', '=', product_id), ('bom_id', '=', False)], context=context),
821- }
822- for product_id in ids
823- }
824- _columns = {
825- 'bom_ids': fields.one2many('mrp.bom', 'product_id', 'Bill of Materials'),
826- 'bom_count': fields.function(_bom_orders_count, string='# Bill of Material', type='integer', multi="_bom_order_count"),
827- 'bom_strct': fields.function(_bom_orders_count, string='# Bill of Material Structure', type='integer', multi="_bom_order_count"),
828- 'mo_count': fields.function(_bom_orders_count, string='# Manufacturing Orders', type='integer', multi="_bom_order_count"),
829- }
830-
831 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
832
833=== modified file 'mrp/mrp_demo.xml'
834--- mrp/mrp_demo.xml 2014-01-20 14:42:43 +0000
835+++ mrp/mrp_demo.xml 2014-05-26 16:10:21 +0000
836@@ -245,407 +245,366 @@
837
838 <record id="mrp_bom_1" model="mrp.bom">
839 <field name="name">HDD 500GB</field>
840- <field name="product_id" ref="product.product_product_18"/>
841- <field name="product_qty">1</field>
842+ <field name="product_tmpl_id" ref="product.product_product_18_product_template"/>
843 <field name="product_uom" ref="product.product_uom_unit"/>
844 <field name="sequence">5</field>
845 <field name="routing_id" ref="mrp_routing_0"/>
846 <field name="type">normal</field>
847 </record>
848
849+ <record id="mrp_bom_line_1" model="mrp.bom.line">
850+ <field name="product_id" ref="product.product_product_17"/>
851+ <field name="product_qty">2</field>
852+ <field name="product_uom" ref="product.product_uom_unit"/>
853+ <field name="sequence">5</field>
854+ <field name="type">normal</field>
855+ <field name="bom_id" ref="mrp_bom_1"/>
856+ </record>
857+
858 <record id="mrp_bom_2" model="mrp.bom">
859- <field name="name">320GB HDD</field>
860- <field name="product_id" ref="product.product_product_17"/>
861- <field name="product_qty">2</field>
862- <field name="product_uom" ref="product.product_uom_unit"/>
863- <field name="sequence">5</field>
864- <field name="type">normal</field>
865- <field name="bom_id" ref="mrp_bom_1"/>
866- </record>
867-
868- <record id="mrp_bom_3" model="mrp.bom">
869 <field name="name">HDD 2TB on Demand</field>
870- <field name="product_id" ref="product.product_product_19"/>
871- <field name="product_qty">1</field>
872+ <field name="product_tmpl_id" ref="product.product_product_19_product_template"/>
873 <field name="product_uom" ref="product.product_uom_unit"/>
874 <field name="sequence">5</field>
875 <field name="routing_id" ref="mrp_routing_1"/>
876 <field name="type">normal</field>
877 </record>
878
879- <record id="mrp_bom_4" model="mrp.bom">
880- <field name="name">HDD 500GB</field>
881+ <record id="mrp_bom_line_2" model="mrp.bom.line">
882 <field name="product_id" ref="product.product_product_18"/>
883 <field name="product_qty">4</field>
884 <field name="product_uom" ref="product.product_uom_unit"/>
885 <field name="sequence">5</field>
886 <field name="type">normal</field>
887+ <field name="bom_id" ref="mrp_bom_2"/>
888+ </record>
889+
890+ <record id="mrp_bom_3" model="mrp.bom">
891+ <field name="name">HDD on Demand</field>
892+ <field name="product_tmpl_id" ref="product.product_product_19_product_template"/>
893+ <field name="product_uom" ref="product.product_uom_unit"/>
894+ <field name="sequence">10</field>
895+ <field name="type">normal</field>
896+ </record>
897+
898+ <record id="mrp_bom_line_3" model="mrp.bom.line">
899+ <field name="product_id" ref="product.product_product_17"/>
900+ <field name="product_qty">1</field>
901+ <field name="product_uom" ref="product.product_uom_unit"/>
902+ <field name="sequence">5</field>
903+ <field name="type">normal</field>
904 <field name="bom_id" ref="mrp_bom_3"/>
905 </record>
906
907- <record id="mrp_bom_5" model="mrp.bom">
908- <field name="name">HDD on Demand</field>
909- <field name="product_id" ref="product.product_product_19"/>
910- <field name="product_qty">1</field>
911- <field name="product_uom" ref="product.product_uom_unit"/>
912- <field name="sequence">10</field>
913- <field name="type">normal</field>
914- </record>
915-
916- <record id="mrp_bom_6" model="mrp.bom">
917- <field name="name">320GB HDD</field>
918- <field name="product_id" ref="product.product_product_17"/>
919- <field name="product_qty">1</field>
920- <field name="product_uom" ref="product.product_uom_unit"/>
921- <field name="sequence">5</field>
922- <field name="type">normal</field>
923- <field name="bom_id" ref="mrp_bom_5"/>
924- </record>
925-
926- <record id="mrp_bom_7" model="mrp.bom">
927+ <record id="mrp_bom_4" model="mrp.bom">
928 <field name="name">Laptop Customized</field>
929- <field name="product_id" ref="product.product_product_27"/>
930- <field name="product_qty">1</field>
931+ <field name="product_tmpl_id" ref="product.product_product_27_product_template"/>
932 <field name="product_uom" ref="product.product_uom_unit"/>
933 <field name="sequence">5</field>
934 <field name="routing_id" ref="mrp_routing_1"/>
935 <field name="type">normal</field>
936 </record>
937
938- <record id="mrp_bom_8" model="mrp.bom">
939- <field name="name">Windows 7 Professional</field>
940+ <record id="mrp_bom_line_4" model="mrp.bom.line">
941 <field name="product_id" ref="product.product_product_40"/>
942 <field name="product_qty">1</field>
943 <field name="product_uom" ref="product.product_uom_unit"/>
944 <field name="sequence">2</field>
945 <field name="type">normal</field>
946- <field name="bom_id" ref="mrp_bom_7"/>
947+ <field name="bom_id" ref="mrp_bom_4"/>
948 </record>
949
950- <record id="mrp_bom_9" model="mrp.bom">
951- <field name="name">USB Keyboard, QWERTY</field>
952+ <record id="mrp_bom_line_5" model="mrp.bom.line">
953 <field name="product_id" ref="product.product_product_8"/>
954 <field name="product_qty">1</field>
955 <field name="product_uom" ref="product.product_uom_unit"/>
956 <field name="sequence">4</field>
957 <field name="type">normal</field>
958- <field name="bom_id" ref="mrp_bom_7"/>
959+ <field name="bom_id" ref="mrp_bom_4"/>
960 </record>
961
962- <record id="mrp_bom_10" model="mrp.bom">
963- <field name="name">Mouse, Wireless</field>
964+ <record id="mrp_bom_line_6" model="mrp.bom.line">
965 <field name="product_id" ref="product.product_product_12"/>
966 <field name="product_qty">1</field>
967 <field name="product_uom" ref="product.product_uom_unit"/>
968 <field name="sequence">6</field>
969 <field name="type">normal</field>
970- <field name="bom_id" ref="mrp_bom_7"/>
971+ <field name="bom_id" ref="mrp_bom_4"/>
972 </record>
973
974- <record id="mrp_bom_11" model="mrp.bom">
975+ <record id="mrp_bom_5" model="mrp.bom">
976 <field name="name">Laptop Customized + Azerty</field>
977- <field name="product_id" ref="product.product_product_27"/>
978- <field name="product_qty">1</field>
979+ <field name="product_tmpl_id" ref="product.product_product_27_product_template"/>
980 <field name="product_uom" ref="product.product_uom_unit"/>
981 <field name="sequence">10</field>
982 <field name="type">normal</field>
983 </record>
984
985- <record id="mrp_bom_12" model="mrp.bom">
986- <field name="name">Windows 7 Professional</field>
987+ <record id="mrp_bom_line_7" model="mrp.bom.line">
988 <field name="product_id" ref="product.product_product_40"/>
989 <field name="product_qty">1</field>
990 <field name="product_uom" ref="product.product_uom_unit"/>
991 <field name="sequence">2</field>
992 <field name="type">normal</field>
993- <field name="bom_id" ref="mrp_bom_11"/>
994+ <field name="bom_id" ref="mrp_bom_5"/>
995 </record>
996
997- <record id="mrp_bom_13" model="mrp.bom">
998- <field name="name">USB Keyboard, AZERTY</field>
999+ <record id="mrp_bom_line_8" model="mrp.bom.line">
1000 <field name="product_id" ref="product.product_product_9"/>
1001 <field name="product_qty">1</field>
1002 <field name="product_uom" ref="product.product_uom_unit"/>
1003 <field name="sequence">4</field>
1004 <field name="type">normal</field>
1005- <field name="bom_id" ref="mrp_bom_11"/>
1006+ <field name="bom_id" ref="mrp_bom_5"/>
1007 </record>
1008
1009- <record id="mrp_bom_14" model="mrp.bom">
1010- <field name="name">Mouse, Laser</field>
1011+ <record id="mrp_bom_line_9" model="mrp.bom.line">
1012 <field name="product_id" ref="product.product_product_11"/>
1013 <field name="product_qty">1</field>
1014 <field name="product_uom" ref="product.product_uom_unit"/>
1015 <field name="sequence">6</field>
1016 <field name="type">normal</field>
1017- <field name="bom_id" ref="mrp_bom_11"/>
1018+ <field name="bom_id" ref="mrp_bom_5"/>
1019 </record>
1020
1021- <record id="mrp_bom_15" model="mrp.bom">
1022+ <record id="mrp_bom_6" model="mrp.bom">
1023 <field name="name">Computer Case-1</field>
1024- <field name="product_id" ref="product.product_product_16"/>
1025- <field name="product_qty">1</field>
1026+ <field name="product_tmpl_id" ref="product.product_product_16_product_template"/>
1027 <field name="product_uom" ref="product.product_uom_unit"/>
1028 <field name="sequence">5</field>
1029 <field name="type">normal</field>
1030 </record>
1031
1032- <record id="mrp_bom_16" model="mrp.bom">
1033- <field name="name">Processesor AMD 8-Core</field>
1034+ <record id="mrp_bom_line_10" model="mrp.bom.line">
1035 <field name="product_id" ref="product.product_product_23"/>
1036 <field name="product_qty">1</field>
1037 <field name="product_uom" ref="product.product_uom_unit"/>
1038 <field name="sequence">4</field>
1039 <field name="type">normal</field>
1040- <field name="bom_id" ref="mrp_bom_15"/>
1041+ <field name="bom_id" ref="mrp_bom_6"/>
1042 </record>
1043
1044- <record id="mrp_bom_17" model="mrp.bom">
1045- <field name="name">Motherboard I9P57</field>
1046+ <record id="mrp_bom_line_11" model="mrp.bom.line">
1047 <field name="product_id" ref="product.product_product_20"/>
1048 <field name="product_qty">1</field>
1049 <field name="product_uom" ref="product.product_uom_unit"/>
1050 <field name="sequence">6</field>
1051 <field name="type">normal</field>
1052- <field name="bom_id" ref="mrp_bom_15"/>
1053+ <field name="bom_id" ref="mrp_bom_6"/>
1054 </record>
1055
1056- <record id="mrp_bom_18" model="mrp.bom">
1057- <field name="name">HDD 320GB</field>
1058+ <record id="mrp_bom_line_12" model="mrp.bom.line">
1059 <field name="product_id" ref="product.product_product_17"/>
1060 <field name="product_qty">1</field>
1061 <field name="product_uom" ref="product.product_uom_unit"/>
1062 <field name="sequence">8</field>
1063 <field name="type">normal</field>
1064- <field name="bom_id" ref="mrp_bom_15"/>
1065+ <field name="bom_id" ref="mrp_bom_6"/>
1066 </record>
1067
1068- <record id="mrp_bom_19" model="mrp.bom">
1069+ <record id="mrp_bom_7" model="mrp.bom">
1070 <field name="name">Computer Case-2</field>
1071- <field name="product_id" ref="product.product_product_16"/>
1072- <field name="product_qty">1</field>
1073+ <field name="product_tmpl_id" ref="product.product_product_16_product_template"/>
1074 <field name="product_uom" ref="product.product_uom_unit"/>
1075 <field name="sequence">10</field>
1076 <field name="type">normal</field>
1077 </record>
1078
1079- <record id="mrp_bom_20" model="mrp.bom">
1080- <field name="name">Processor Core i5 2.70 Ghz</field>
1081+ <record id="mrp_bom_line_13" model="mrp.bom.line">
1082 <field name="product_id" ref="product.product_product_22"/>
1083 <field name="product_qty">1</field>
1084 <field name="product_uom" ref="product.product_uom_unit"/>
1085 <field name="sequence">2</field>
1086 <field name="type">normal</field>
1087- <field name="bom_id" ref="mrp_bom_19"/>
1088+ <field name="bom_id" ref="mrp_bom_7"/>
1089 </record>
1090
1091- <record id="mrp_bom_21" model="mrp.bom">
1092- <field name="name">Motherboard A20Z7</field>
1093+ <record id="mrp_bom_line_14" model="mrp.bom.line">
1094 <field name="product_id" ref="product.product_product_21"/>
1095 <field name="product_qty">1</field>
1096 <field name="product_uom" ref="product.product_uom_unit"/>
1097 <field name="sequence">4</field>
1098 <field name="type">normal</field>
1099- <field name="bom_id" ref="mrp_bom_19"/>
1100+ <field name="bom_id" ref="mrp_bom_7"/>
1101 </record>
1102
1103- <record id="mrp_bom_22" model="mrp.bom">
1104- <field name="name">HDD 500GB</field>
1105+ <record id="mrp_bom_line_15" model="mrp.bom.line">
1106 <field name="product_id" ref="product.product_product_18"/>
1107 <field name="product_qty">1</field>
1108 <field name="product_uom" ref="product.product_uom_unit"/>
1109 <field name="sequence">6</field>
1110 <field name="type">normal</field>
1111- <field name="bom_id" ref="mrp_bom_19"/>
1112+ <field name="bom_id" ref="mrp_bom_7"/>
1113 </record>
1114
1115- <record id="mrp_bom_23" model="mrp.bom">
1116- <field name="name">Graphics Card</field>
1117+ <record id="mrp_bom_line_16" model="mrp.bom.line">
1118 <field name="product_id" ref="product.product_product_24"/>
1119 <field name="product_qty">1</field>
1120 <field name="product_uom" ref="product.product_uom_unit"/>
1121 <field name="sequence">10</field>
1122 <field name="type">normal</field>
1123- <field name="bom_id" ref="mrp_bom_19"/>
1124+ <field name="bom_id" ref="mrp_bom_7"/>
1125 </record>
1126
1127- <record id="mrp_bom_24" model="mrp.bom">
1128+ <record id="mrp_bom_8" model="mrp.bom">
1129 <field name="name">PC Assemble + 2GB RAM</field>
1130- <field name="product_id" ref="product.product_product_4"/>
1131- <field name="product_qty">1</field>
1132+ <field name="product_tmpl_id" ref="product.product_product_4_product_template"/>
1133 <field name="product_uom" ref="product.product_uom_unit"/>
1134 <field name="sequence">5</field>
1135 <field name="type">phantom</field>
1136 </record>
1137
1138- <record id="mrp_bom_25" model="mrp.bom">
1139- <field name="name">15" LCD Monitor </field>
1140+ <record id="mrp_bom_line_17" model="mrp.bom.line">
1141 <field name="product_id" ref="product.product_product_6"/>
1142 <field name="product_qty">1</field>
1143 <field name="product_uom" ref="product.product_uom_unit"/>
1144 <field name="sequence">2</field>
1145 <field name="type">normal</field>
1146- <field name="bom_id" ref="mrp_bom_24"/>
1147+ <field name="bom_id" ref="mrp_bom_8"/>
1148 </record>
1149
1150- <record id="mrp_bom_26" model="mrp.bom">
1151- <field name="name">Computer Case-1</field>
1152+ <record id="mrp_bom_line_18" model="mrp.bom.line">
1153 <field name="product_id" ref="product.product_product_16"/>
1154 <field name="product_qty">1</field>
1155 <field name="product_uom" ref="product.product_uom_unit"/>
1156 <field name="sequence">4</field>
1157 <field name="type">normal</field>
1158- <field name="bom_id" ref="mrp_bom_24"/>
1159+ <field name="bom_id" ref="mrp_bom_8"/>
1160 </record>
1161
1162- <record id="mrp_bom_27" model="mrp.bom">
1163- <field name="name">Mouse, Laser</field>
1164+ <record id="mrp_bom_line_19" model="mrp.bom.line">
1165 <field name="product_id" ref="product.product_product_11"/>
1166 <field name="product_qty">1</field>
1167 <field name="product_uom" ref="product.product_uom_unit"/>
1168 <field name="sequence">6</field>
1169 <field name="type">normal</field>
1170- <field name="bom_id" ref="mrp_bom_24"/>
1171+ <field name="bom_id" ref="mrp_bom_8"/>
1172 </record>
1173
1174- <record id="mrp_bom_28" model="mrp.bom">
1175- <field name="name">USB Keyboard, QWERTY</field>
1176+ <record id="mrp_bom_line_20" model="mrp.bom.line">
1177 <field name="product_id" ref="product.product_product_8"/>
1178 <field name="product_qty">1</field>
1179 <field name="product_uom" ref="product.product_uom_unit"/>
1180 <field name="sequence">8</field>
1181 <field name="type">normal</field>
1182- <field name="bom_id" ref="mrp_bom_24"/>
1183+ <field name="bom_id" ref="mrp_bom_8"/>
1184 </record>
1185
1186- <record id="mrp_bom_29" model="mrp.bom">
1187- <field name="name">RAM DDR2 1GB</field>
1188+ <record id="mrp_bom_line_21" model="mrp.bom.line">
1189 <field name="product_id" ref="product.product_product_15"/>
1190 <field name="product_qty">2</field>
1191 <field name="product_uom" ref="product.product_uom_unit"/>
1192 <field name="sequence">10</field>
1193 <field name="type">normal</field>
1194- <field name="bom_id" ref="mrp_bom_24"/>
1195+ <field name="bom_id" ref="mrp_bom_8"/>
1196 </record>
1197
1198- <record id="mrp_bom_30" model="mrp.bom">
1199+ <record id="mrp_bom_9" model="mrp.bom">
1200 <field name="name">PC Assemble + 512MB RAM</field>
1201- <field name="product_id" ref="product.product_product_3"/>
1202- <field name="product_qty">1</field>
1203+ <field name="product_tmpl_id" ref="product.product_product_3_product_template"/>
1204 <field name="product_uom" ref="product.product_uom_unit"/>
1205 <field name="sequence">5</field>
1206 <field name="routing_id" ref="mrp_routing_2"/>
1207 <field name="type">phantom</field>
1208 </record>
1209
1210- <record id="mrp_bom_31" model="mrp.bom">
1211- <field name="name">17" LCD Monitor</field>
1212+ <record id="mrp_bom_line_22" model="mrp.bom.line">
1213 <field name="product_id" ref="product.product_product_7"/>
1214 <field name="product_qty">1</field>
1215 <field name="product_uom" ref="product.product_uom_unit"/>
1216 <field name="sequence">2</field>
1217 <field name="type">normal</field>
1218- <field name="bom_id" ref="mrp_bom_30"/>
1219+ <field name="bom_id" ref="mrp_bom_9"/>
1220 </record>
1221
1222- <record id="mrp_bom_32" model="mrp.bom">
1223- <field name="name">Computer Case-2</field>
1224+ <record id="mrp_bom_line_23" model="mrp.bom.line">
1225 <field name="product_id" ref="product.product_product_16"/>
1226 <field name="product_qty">1</field>
1227 <field name="product_uom" ref="product.product_uom_unit"/>
1228 <field name="sequence">4</field>
1229 <field name="type">normal</field>
1230- <field name="bom_id" ref="mrp_bom_30"/>
1231+ <field name="bom_id" ref="mrp_bom_9"/>
1232 </record>
1233
1234- <record id="mrp_bom_33" model="mrp.bom">
1235- <field name="name">Mouse, Laser</field>
1236+ <record id="mrp_bom_line_24" model="mrp.bom.line">
1237 <field name="product_id" ref="product.product_product_11"/>
1238 <field name="product_qty">1</field>
1239 <field name="product_uom" ref="product.product_uom_unit"/>
1240 <field name="sequence">6</field>
1241 <field name="type">normal</field>
1242- <field name="bom_id" ref="mrp_bom_30"/>
1243+ <field name="bom_id" ref="mrp_bom_9"/>
1244 </record>
1245
1246- <record id="mrp_bom_34" model="mrp.bom">
1247- <field name="name">USB Keyboard, QWERTY</field>
1248+ <record id="mrp_bom_line_25" model="mrp.bom.line">
1249 <field name="product_id" ref="product.product_product_8"/>
1250 <field name="product_qty">1</field>
1251 <field name="product_uom" ref="product.product_uom_unit"/>
1252 <field name="sequence">8</field>
1253 <field name="type">normal</field>
1254- <field name="bom_id" ref="mrp_bom_30"/>
1255+ <field name="bom_id" ref="mrp_bom_9"/>
1256 </record>
1257
1258- <record id="mrp_bom_35" model="mrp.bom">
1259- <field name="name">RAM DDR 512MB</field>
1260+ <record id="mrp_bom_line_26" model="mrp.bom.line">
1261 <field name="product_id" ref="product.product_product_13"/>
1262 <field name="product_qty">1</field>
1263 <field name="product_uom" ref="product.product_uom_unit"/>
1264 <field name="sequence">10</field>
1265 <field name="type">normal</field>
1266- <field name="bom_id" ref="mrp_bom_30"/>
1267+ <field name="bom_id" ref="mrp_bom_9"/>
1268 </record>
1269
1270- <record id="mrp_bom_36" model="mrp.bom">
1271+ <record id="mrp_bom_10" model="mrp.bom">
1272 <field name="name">PC Assemble + Custom RAM (PC on Demand)</field>
1273- <field name="product_id" ref="product.product_product_5"/>
1274- <field name="product_qty">1</field>
1275+ <field name="product_tmpl_id" ref="product.product_product_5_product_template"/>
1276 <field name="product_uom" ref="product.product_uom_unit"/>
1277 <field name="sequence">5</field>
1278 <field name="routing_id" ref="mrp_routing_2"/>
1279 <field name="type">phantom</field>
1280 </record>
1281
1282- <record id="mrp_bom_37" model="mrp.bom">
1283- <field name="name">15" LCD Monitor </field>
1284+ <record id="mrp_bom_line_27" model="mrp.bom.line">
1285 <field name="product_id" ref="product.product_product_6"/>
1286 <field name="product_qty">1</field>
1287 <field name="product_uom" ref="product.product_uom_unit"/>
1288 <field name="sequence">2</field>
1289 <field name="type">normal</field>
1290- <field name="bom_id" ref="mrp_bom_36"/>
1291+ <field name="bom_id" ref="mrp_bom_10"/>
1292 </record>
1293
1294- <record id="mrp_bom_38" model="mrp.bom">
1295- <field name="name">Computer Case-1</field>
1296+ <record id="mrp_bom_line_28" model="mrp.bom.line">
1297 <field name="product_id" ref="product.product_product_16"/>
1298 <field name="product_qty">1</field>
1299 <field name="product_uom" ref="product.product_uom_unit"/>
1300 <field name="sequence">4</field>
1301 <field name="type">normal</field>
1302- <field name="bom_id" ref="mrp_bom_36"/>
1303+ <field name="bom_id" ref="mrp_bom_10"/>
1304 </record>
1305
1306- <record id="mrp_bom_39" model="mrp.bom">
1307- <field name="name">RAM DDR 512MB</field>
1308+ <record id="mrp_bom_line_29" model="mrp.bom.line">
1309 <field name="product_id" ref="product.product_product_13"/>
1310 <field name="product_qty">1</field>
1311 <field name="product_uom" ref="product.product_uom_unit"/>
1312 <field name="sequence">6</field>
1313 <field name="type">normal</field>
1314- <field name="bom_id" ref="mrp_bom_36"/>
1315+ <field name="bom_id" ref="mrp_bom_10"/>
1316 </record>
1317
1318- <record id="mrp_bom_40" model="mrp.bom">
1319- <field name="name">Mouse, Laser</field>
1320+ <record id="mrp_bom_line_30" model="mrp.bom.line">
1321 <field name="product_id" ref="product.product_product_11"/>
1322 <field name="product_qty">1</field>
1323 <field name="product_uom" ref="product.product_uom_unit"/>
1324 <field name="sequence">8</field>
1325 <field name="type">normal</field>
1326- <field name="bom_id" ref="mrp_bom_36"/>
1327+ <field name="bom_id" ref="mrp_bom_10"/>
1328 </record>
1329
1330- <record id="mrp_bom_41" model="mrp.bom">
1331- <field name="name">USB Keyboard, QWERTY</field>
1332+ <record id="mrp_bom_line_31" model="mrp.bom.line">
1333 <field name="product_id" ref="product.product_product_8"/>
1334 <field name="product_qty">1</field>
1335 <field name="product_uom" ref="product.product_uom_unit"/>
1336 <field name="sequence">10</field>
1337 <field name="type">normal</field>
1338- <field name="bom_id" ref="mrp_bom_36"/>
1339+ <field name="bom_id" ref="mrp_bom_10"/>
1340 </record>
1341
1342 <record id="mrp_production_1" model="mrp.production">
1343@@ -654,7 +613,7 @@
1344 <field name="product_qty">3</field>
1345 <field name="location_src_id" ref="stock.stock_location_stock"/>
1346 <field name="location_dest_id" ref="stock.stock_location_output"/>
1347- <field name="bom_id" ref="mrp_bom_24"/>
1348+ <field name="bom_id" ref="mrp_bom_8"/>
1349 <field name="routing_id" ref="mrp.mrp_routing_2"/>
1350 </record>
1351
1352@@ -663,7 +622,7 @@
1353 <field name="product_uom" ref="product.product_uom_unit"/>
1354 <field name="location_src_id" ref="stock.stock_location_stock"/>
1355 <field name="location_dest_id" ref="stock.stock_location_output"/>
1356- <field name="bom_id" ref="mrp.mrp_bom_7"/>
1357+ <field name="bom_id" ref="mrp.mrp_bom_4"/>
1358 <field name="routing_id" ref="mrp.mrp_routing_1"/>
1359 </record>
1360 <workflow action="button_confirm" model="mrp.production" ref="mrp_production_1"/>
1361
1362=== modified file 'mrp/mrp_view.xml'
1363--- mrp/mrp_view.xml 2014-05-07 18:29:17 +0000
1364+++ mrp/mrp_view.xml 2014-05-26 16:10:21 +0000
1365@@ -347,22 +347,17 @@
1366 <form string="Bill of Material" version="7.0">
1367 <group>
1368 <group>
1369- <field name="product_id" on_change="onchange_product_id(product_id, name, product_qty, context)" class="oe_inline"/>
1370+ <field name="product_tmpl_id" on_change="onchange_product_tmpl_id(product_tmpl_id, product_qty, context)"/>
1371+ <field name="product_id"/>
1372+ <field name="product_uom" class="oe_inline" on_change="onchange_uom(product_tmpl_id, product_uom)" groups="product.group_uom"/>
1373 <label for="product_qty" string="Quantity"/>
1374 <div>
1375- <field name="product_qty" class="oe_inline" on_change="onchange_product_id(product_id, name, product_qty, context)"/>
1376- <field name="product_uom" class="oe_inline" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
1377- </div>
1378- <label for="product_uos_qty" groups="product.group_uos"/>
1379- <div groups="product.group_uos" >
1380- <field name="product_uos_qty"
1381- class="oe_inline"/>
1382- <label string="-" attrs="{'invisible':[('product_uos','=',False)]}" class="oe_inline"/>
1383- <field name="product_uos" class="oe_inline"/>
1384+ <field name="product_qty" class="oe_inline" on_change="onchange_product_tmpl_id(product_tmpl_id, product_qty, context)"/>
1385+ <field name="product_uom" class="oe_inline" on_change="onchange_uom(product_tmpl_id, product_uom)" groups="product.group_uom"/>
1386 </div>
1387 <label for="routing_id" class="oe_inline" groups="mrp.group_mrp_routings"/>
1388 <div groups="mrp.group_mrp_routings">
1389- <field name="routing_id" class="oe_inline"/>
1390+ <field name="routing_id" class="oe_inline"/>
1391 </div>
1392 </group>
1393 <group>
1394@@ -378,14 +373,19 @@
1395 </group>
1396 <notebook>
1397 <page string="Components">
1398- <field name="bom_lines" widget="one2many_list">
1399+ <field name="bom_line_ids" widget="one2many_list">
1400 <tree string="Components" editable="bottom">
1401- <field name="product_id" on_change="onchange_product_id(product_id, name)"/>
1402+ <field name="sequence" widget="handle"/>
1403+ <field name="product_id" on_change="onchange_product_id(product_id, product_qty)"/>
1404+ <field name="type"/>
1405 <field name="product_qty"/>
1406+ <field name="product_rounding"/>
1407+ <field name="product_efficiency"/>
1408 <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
1409- <field name="name" invisible="1"/>
1410 <field name="date_start"/>
1411 <field name="date_stop"/>
1412+ <field name="routing_id"/>
1413+ <field name="variants_ids" widget="many2many_tags"/>
1414 </tree>
1415 </field>
1416 </page>
1417@@ -393,7 +393,6 @@
1418 <group>
1419 <group>
1420 <field name="position"/>
1421- <field name="bom_id"/>
1422 <field name="sequence"/>
1423 <field name="active"/>
1424 </group>
1425@@ -422,11 +421,11 @@
1426 <field name="arch" type="xml">
1427 <search string="Search Bill Of Material">
1428 <field name="name" string="Bill Of Material" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
1429- <field name="bom_lines" string="Components"/>
1430- <field name="product_id"/>
1431+ <field name="bom_line_ids" string="Components"/>
1432+ <field name="product_tmpl_id"/>
1433 <field name="company_id" groups="base.group_multi_company"/>
1434 <group expand="0" string="Group By...">
1435- <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
1436+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_tmpl_id'}"/>
1437 <filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'product_uom'}"/>
1438 <filter string="Routing" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'routing_id'}"/>
1439 <filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
1440@@ -439,13 +438,13 @@
1441 <record id="mrp_bom_tree_view" model="ir.ui.view">
1442 <field name="name">mrp.bom.tree</field>
1443 <field name="model">mrp.bom</field>
1444- <field name="field_parent">child_complete_ids</field>
1445+ <!--field name="field_parent">child_complete_ids</field-->
1446 <field name="arch" type="xml">
1447 <tree string="Bill of Materials">
1448 <field name="sequence" invisible="1"/>
1449 <field name="name" invisible="1"/>
1450+ <field name="product_tmpl_id"/>
1451 <field name="product_id"/>
1452- <field name="product_qty"/>
1453 <field name="product_uom" groups="product.group_uom"/>
1454 <field name="code"/>
1455 <field name="type"/>
1456@@ -455,32 +454,12 @@
1457 </tree>
1458 </field>
1459 </record>
1460- <record id="mrp_bom_component_tree_view" model="ir.ui.view">
1461- <field name="name">mrp.bom.component.tree</field>
1462- <field name="model">mrp.bom</field>
1463- <field name="field_parent">child_complete_ids</field>
1464- <field name="arch" type="xml">
1465- <tree string="BoM Structure">
1466- <field name="sequence" invisible="1"/>
1467- <field name="name" groups="base.group_no_one"/>
1468- <field name="code"/>
1469- <field name="product_id"/>
1470- <field name="bom_id" groups="product.group_mrp_properties"/>
1471- <field name="product_qty"/>
1472- <field name="product_uom" groups="product.group_uom"/>
1473- <field name="type"/>
1474- <field name="routing_id" groups="mrp.group_mrp_routings"/>
1475- <field name="date_start" groups="product.group_mrp_properties"/>
1476- <field name="date_stop" groups="product.group_mrp_properties"/>
1477- </tree>
1478- </field>
1479- </record>
1480+
1481 <record id="mrp_bom_form_action" model="ir.actions.act_window">
1482 <field name="name">Bill of Materials</field>
1483 <field name="type">ir.actions.act_window</field>
1484 <field name="res_model">mrp.bom</field>
1485 <field name="view_type">form</field>
1486- <field name="domain">[('bom_id','=',False)]</field>
1487 <field name="search_view_id" ref="view_mrp_bom_filter"/>
1488 <field name="help" type="html">
1489 <p class="oe_view_nocontent_create">
1490@@ -495,13 +474,56 @@
1491 </p>
1492 </field>
1493 </record>
1494+
1495+ <record id="mrp_bom_component_tree_view" model="ir.ui.view">
1496+ <field name="name">mrp.bom.component.tree</field>
1497+ <field name="model">mrp.bom.line</field>
1498+ <field name="arch" type="xml">
1499+ <tree string="Components" editable="top">
1500+ <field name="sequence" widget="handle"/>
1501+ <field name="bom_id"/>
1502+ <field name="product_id" on_change="onchange_product_id(product_id)"/>
1503+ <field name="type"/>
1504+ <field name="product_qty"/>
1505+ <field name="product_rounding"/>
1506+ <field name="product_efficiency"/>
1507+ <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
1508+ <field name="product_uos_qty" groups="product.group_uos"/>
1509+ <field name="product_uos" groups="product.group_uos"/>
1510+ <field name="date_start"/>
1511+ <field name="date_stop"/>
1512+ <field name="routing_id"/>
1513+ <field name="variants_ids" widget="many2many_tags"/>
1514+ <field name="property_ids" widget="many2many_tags"/>
1515+ </tree>
1516+ </field>
1517+ </record>
1518+
1519+ <record id="view_mrp_bom_line_filter" model="ir.ui.view">
1520+ <field name="name">mrp.bom.line.select</field>
1521+ <field name="model">mrp.bom.line</field>
1522+ <field name="arch" type="xml">
1523+ <search string="Search Bill Of Material Components">
1524+ <field name="bom_id"/>
1525+ <field name="product_id"/>
1526+ <group expand="0" string="Group By...">
1527+ <filter string="Bill Of Material" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'bom_id'}"/>
1528+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
1529+ <filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'product_uom'}"/>
1530+ <filter string="Routing" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'routing_id'}"/>
1531+ <filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
1532+ <filter string=" Valid From Month" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}" help="Valid From Date by Month"/>
1533+ </group>
1534+ </search>
1535+ </field>
1536+ </record>
1537+
1538 <record id="mrp_bom_form_action2" model="ir.actions.act_window">
1539 <field name="name">Bill of Material Components</field>
1540 <field name="type">ir.actions.act_window</field>
1541- <field name="res_model">mrp.bom</field>
1542- <field name="view_type">form</field>
1543- <field name="view_id" ref="mrp_bom_component_tree_view"/>
1544- <field name="domain">[]</field>
1545+ <field name="res_model">mrp.bom.line</field>
1546+ <field name="view_type">tree</field>
1547+ <field name="view_mode">tree</field>
1548 <field name="help" type="html">
1549 <p class="oe_view_nocontent_create">
1550 Click to add a component to a bill of material.
1551@@ -512,47 +534,32 @@
1552 </p>
1553 </field>
1554 </record>
1555- <record id="product_search_form_view_procurment" model="ir.ui.view">
1556- <field name="name">product.search.bom</field>
1557- <field name="model">product.product</field>
1558- <field name="inherit_id" ref="product.product_search_form_view"/>
1559+
1560+ <record id="product_template_search_view_procurment" model="ir.ui.view">
1561+ <field name="name">product.template.search.bom</field>
1562+ <field name="model">product.template</field>
1563+ <field name="inherit_id" ref="product.product_template_search_view"/>
1564 <field name="arch" type="xml">
1565 <xpath expr="//filter[@string='Consumable']" position="after">
1566 <separator/>
1567- <filter string="Components" name="components" icon="terp-accessories-archiver" domain="[('bom_ids','not in',[]),('bom_ids.bom_id','!=',False)]"/>
1568+ <filter string="Components" name="components" icon="terp-accessories-archiver" domain="[('bom_ids','not in',[])]"/>
1569 </xpath>
1570 </field>
1571 </record>
1572
1573 <record id="product_template_form_view_inherit" model="ir.ui.view">
1574- <field name="name">product.template.form.view.inherited</field>
1575+ <field name="name">product.product.form.view.inherited</field>
1576 <field name="model">product.product</field>
1577- <field name="inherit_id" ref="product.product_template_form_view"/>
1578+ <field name="inherit_id" ref="product.product_normal_form_view"/>
1579 <field name="arch" type="xml">
1580- <xpath expr="//field[@name='warranty']" position="before">
1581- <label for="produce_delay"/>
1582- <div>
1583+ <group name="sale_condition" position="inside">
1584+ <label for="produce_delay" attrs="{'invisible':[('type','=','service')]}"/>
1585+ <div attrs="{'invisible':[('type','=','service')]}">
1586 <field name="produce_delay" class="oe_inline"/> days
1587 </div>
1588- </xpath>
1589+ </group>
1590 </field>
1591 </record>
1592-
1593- <record id="view_normal_procurement_locations_form_inherited" model="ir.ui.view">
1594- <field name="name">product.normal.procurement.locations.inherited</field>
1595- <field name="model">product.product</field>
1596- <field name="inherit_id" ref="product.product_normal_form_view"/>
1597- <field name="arch" type="xml">
1598- <xpath expr="//group[@name='procurement_uom']" position="after">
1599- <group name="delay" string="Delays" attrs="{'invisible':[('type','=','service')]}">
1600- <label for="produce_delay" />
1601- <div attrs="{'invisible':[('type','=','service')]}">
1602- <field name="produce_delay" class="oe_inline" style="vertical-align:baseline"/> days
1603- </div>
1604- </group>
1605- </xpath>
1606- </field>
1607- </record>
1608
1609 <record id="view_mrp_product_form_inherited" model="ir.ui.view">
1610 <field name="name">product.form.mrp.inherited</field>
1611@@ -686,7 +693,7 @@
1612 </div>
1613 <group>
1614 <group>
1615- <field name="product_id" on_change="product_id_change(product_id, product_qty)" domain="[('bom_ids','!=',False),('bom_ids.bom_id','=',False),('bom_ids.type','!=','phantom')]" class="oe_inline" context='{"default_type": "product"}'/>
1616+ <field name="product_id" on_change="product_id_change(product_id, product_qty)" domain="[('bom_ids','!=',False),('bom_ids.type','!=','phantom')]" class="oe_inline" context='{"default_type": "product"}'/>
1617 <label for="product_qty"/>
1618 <div>
1619 <field name="product_qty" class="oe_inline" on_change="product_id_change(product_id, product_qty)"/>
1620@@ -980,7 +987,7 @@
1621 <field name="arch" type="xml">
1622 <data>
1623 <xpath expr="//field[@name='origin']" position="before">
1624- <field name="bom_id" domain="[('product_id','=',product_id),('bom_id','=',False)]"/>
1625+ <field name="bom_id" domain="[('product_id','=',product_id)]"/>
1626 <field name="production_id" attrs="{'invisible': [('production_id','=',False)]}"/>
1627 </xpath>
1628 <xpath expr="//field[@name='origin']" position="after">
1629@@ -992,7 +999,6 @@
1630 </field>
1631 </record>
1632
1633-
1634 <!-- Menu for Resource for MRP-->
1635
1636 <record id="mrp_workcenter_action" model="ir.actions.act_window">
1637@@ -1029,14 +1035,13 @@
1638
1639 <record id="act_product_mrp_bom_open" model="ir.actions.act_window">
1640 <field name="name">BoM Structure</field>
1641- <field name="context">{'default_product_id': active_id}</field>
1642- <field name="domain">[('product_id', 'in', active_ids),('bom_id','=',False)]</field>
1643+ <field name="context">{'default_product_tmpl_id': active_id}</field>
1644+ <field name="domain">[('product_tmpl_id', 'in', active_ids)]</field>
1645 <field name="res_model">mrp.bom</field>
1646 </record>
1647 <record model="ir.actions.act_window" id="product_open_bom">
1648- <field name="context">{'default_product_id': active_id, 'search_default_product_id': active_id}</field>
1649+ <field name="context">{'default_product_tmpl_id': active_id, 'search_default_product_tmpl_id': active_id}</field>
1650 <field name="name">Bill of Materials</field>
1651- <field name="domain">[('bom_id','=',False)]</field>
1652 <field name="res_model">mrp.bom</field>
1653 <field name="view_type">form</field>
1654 </record>
1655@@ -1046,12 +1051,12 @@
1656 <field name="res_model">mrp.production</field>
1657 <field name="view_id" ref="mrp_production_tree_view"/>
1658 </record>
1659- <record model="ir.ui.view" id="product_form_view_bom_button">
1660- <field name="name">product.product.procurement</field>
1661- <field name="model">product.product</field>
1662- <field name="inherit_id" ref="product.product_normal_form_view"/>
1663+ <record model="ir.ui.view" id="product_template_form_view_bom_button">
1664+ <field name="name">product.template.procurement</field>
1665+ <field name="model">product.template</field>
1666+ <field name="inherit_id" ref="product.product_template_form_view"/>
1667 <field name="arch" type="xml">
1668- <xpath expr="//div[@name='buttons']" position="inside">
1669+ <div name="buttons" position="inside">
1670 <button class="oe_inline oe_stat_button" name="%(product_open_bom)d" type="action"
1671 groups="mrp.group_mrp_user" attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-flask">
1672 <field string="Bill of Materials" name="bom_count" widget="statinfo" />
1673@@ -1064,7 +1069,7 @@
1674 groups="mrp.group_mrp_user" attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-list-alt">
1675 <field string="Manufacturing" name="mo_count" widget="statinfo" />
1676 </button>
1677- </xpath>
1678+ </div>
1679 </field>
1680 </record>
1681
1682
1683=== modified file 'mrp/procurement.py'
1684--- mrp/procurement.py 2014-05-07 17:14:31 +0000
1685+++ mrp/procurement.py 2014-05-26 16:10:21 +0000
1686@@ -62,7 +62,8 @@
1687 """
1688 for procurement in self.browse(cr, uid, ids, context=context):
1689 properties = [x.id for x in procurement.property_ids]
1690- bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, procurement.product_id.id, procurement.product_uom.id, properties)
1691+ bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, procurement.product_uom.id,
1692+ product_id=procurement.product_id.id, properties=properties)
1693 if not bom_id:
1694 return False
1695 return True
1696@@ -83,7 +84,8 @@
1697 routing_id = procurement.bom_id.routing_id.id
1698 else:
1699 properties = [x.id for x in procurement.property_ids]
1700- bom_id = bom_obj._bom_find(cr, uid, procurement.product_id.id, procurement.product_uom.id, properties)
1701+ bom_id = bom_obj._bom_find(cr, uid, procurement.product_uom.id,
1702+ product_id=procurement.product_id.id, properties=properties)
1703 bom = bom_obj.browse(cr, uid, bom_id, context=context)
1704 routing_id = bom.routing_id.id
1705
1706
1707=== modified file 'mrp/product.py'
1708--- mrp/product.py 2014-01-07 10:39:15 +0000
1709+++ mrp/product.py 2014-05-26 16:10:21 +0000
1710@@ -20,27 +20,59 @@
1711 ##############################################################################
1712
1713 from openerp.osv import fields, osv
1714-from openerp.tools.translate import _
1715-
1716+
1717+
1718+class product_template(osv.osv):
1719+ _inherit = "product.template"
1720+ def _bom_orders_count(self, cr, uid, ids, field_name, arg, context=None):
1721+ Bom = self.pool('mrp.bom')
1722+ res = {}
1723+ for product_tmpl_id in ids:
1724+ nb = Bom.search_count(cr, uid, [('product_tmpl_id', '=', product_tmpl_id)], context=context)
1725+ res[product_tmpl_id] = {
1726+ 'bom_count': nb,
1727+ 'bom_strct': nb,
1728+ }
1729+ return res
1730+
1731+ def _bom_orders_count_mo(self, cr, uid, ids, name, arg, context=None):
1732+ res = {}
1733+ for product_tmpl_id in self.browse(cr, uid, ids):
1734+ res[product_tmpl_id.id] = sum([p.mo_count for p in product_tmpl_id.product_variant_ids])
1735+ return res
1736+
1737+ _columns = {
1738+ "bom_ids": fields.one2many('mrp.bom', 'product_tmpl_id','Bill of Materials'),
1739+ 'bom_count': fields.function(_bom_orders_count, string='# Bill of Material', type='integer', multi="_bom_order_count"),
1740+ 'bom_strct': fields.function(_bom_orders_count, string='# Bill of Material Structure', type='integer', multi="_bom_order_count"),
1741+ 'mo_count': fields.function(_bom_orders_count_mo, string='# Manufacturing Orders', type='integer'),
1742+ }
1743+ def copy(self, cr, uid, id, default=None, context=None):
1744+ if not default:
1745+ default = {}
1746+ default.update({
1747+ 'bom_ids': []
1748+ })
1749+ return super(product_template, self).copy(cr, uid, id, default, context=context)
1750
1751 class product_product(osv.osv):
1752- _inherit = "product.product"
1753+ _inherit = "product.product"
1754+ def _bom_orders_count(self, cr, uid, ids, field_name, arg, context=None):
1755+ Production = self.pool('mrp.production')
1756+ res = {}
1757+ for product_id in ids:
1758+ res[product_id] = Production.search_count(cr,uid, [('product_id', '=', product_id)], context=context)
1759+ return res
1760+
1761 _columns = {
1762- "bom_ids": fields.one2many('mrp.bom', 'product_id','Bill of Materials', domain=[('bom_id','=',False)]),
1763 "produce_delay": fields.float('Manufacturing Lead Time', help="Average delay in days to produce this product. In the case of multi-level BOM, the manufacturing lead times of the components will be added."),
1764 'track_production': fields.boolean('Track Manufacturing Lots', help="Forces to specify a Serial Number for all moves containing this product and generated by a Manufacturing Order"),
1765+ 'mo_count': fields.function(_bom_orders_count, string='# Manufacturing Orders', type='integer'),
1766 }
1767
1768 _defaults = {
1769 "produce_delay": 1,
1770 }
1771- def copy(self, cr, uid, id, default=None, context=None):
1772- if not default:
1773- default = {}
1774- default.update({
1775- 'bom_ids': []
1776- })
1777- return super(product_product, self).copy(cr, uid, id, default, context=context)
1778
1779
1780
1781
1782=== modified file 'mrp/report/price.py'
1783--- mrp/report/price.py 2014-01-06 13:57:00 +0000
1784+++ mrp/report/price.py 2014-05-26 16:10:21 +0000
1785@@ -144,7 +144,7 @@
1786
1787 for product in product_pool.browse(cr, uid, ids, context=context):
1788 product_uom_name = to_xml(product.uom_id.name)
1789- bom_id = bom_pool._bom_find(cr, uid, product.id, product.uom_id.id)
1790+ bom_id = bom_pool._bom_find(cr, uid, product.uom_id.id, product_id=product.id)
1791 title = "<title>%s</title>" %(_("Cost Structure"))
1792 title += "<title>%s</title>" % (to_xml(product.name))
1793 xml += "<lines style='header'>" + title + prod_header + "</lines>"
1794@@ -168,7 +168,7 @@
1795 else:
1796 bom = bom_pool.browse(cr, uid, bom_id, context=context)
1797 factor = number * product.uom_id.factor / bom.product_uom.factor
1798- sub_boms = bom_pool._bom_explode(cr, uid, bom, factor / bom.product_qty)
1799+ sub_boms = bom_pool._bom_explode(cr, uid, bom, product, factor / bom.product_qty)
1800 total = 0
1801 total_strd = 0
1802 parent_bom = {
1803
1804=== modified file 'mrp/security/ir.model.access.csv'
1805--- mrp/security/ir.model.access.csv 2014-05-02 13:03:52 +0000
1806+++ mrp/security/ir.model.access.csv 2014-05-26 16:10:21 +0000
1807@@ -4,6 +4,7 @@
1808 access_mrp_routing,mrp.routing,model_mrp_routing,mrp.group_mrp_user,1,0,0,0
1809 access_mrp_routing_workcenter,mrp.routing.workcenter,model_mrp_routing_workcenter,mrp.group_mrp_user,1,0,0,0
1810 access_mrp_bom,mrp.bom,model_mrp_bom,group_mrp_user,1,0,0,0
1811+access_mrp_bom_line,mrp.bom.line,model_mrp_bom_line,group_mrp_user,1,0,0,0
1812 access_mrp_production,mrp.production user,model_mrp_production,mrp.group_mrp_user,1,1,1,1
1813 access_mrp_production_salesman,mrp.production salesman,model_mrp_production,base.group_sale_salesman,1,1,1,0
1814 access_mrp_production_product_line_salesman,mrp.production.product.line salesman,model_mrp_production_product_line,base.group_sale_salesman,1,0,1,0
1815@@ -14,6 +15,7 @@
1816 access_mrp_routing_manager,mrp.routing.manager,model_mrp_routing,mrp.group_mrp_manager,1,1,1,1
1817 access_mrp_routing_workcenter_manager,mrp.routing.workcenter.manager,model_mrp_routing_workcenter,mrp.group_mrp_manager,1,1,1,1
1818 access_mrp_bom_manager,mrp.bom.manager,model_mrp_bom,mrp.group_mrp_manager,1,1,1,1
1819+access_mrp_bom_line_manager,mrp.bom.line.manager,model_mrp_bom_line,mrp.group_mrp_manager,1,1,1,1
1820 access_stock_location_mrp_worker,stock.location mrp_worker,stock.model_stock_location,mrp.group_mrp_user,1,0,0,0
1821 access_stock_move_mrp_worker,stock.move mrp_worker,stock.model_stock_move,mrp.group_mrp_user,1,1,1,0
1822 access_stock_picking_mrp_worker,stock.picking mrp_worker,stock.model_stock_picking,mrp.group_mrp_user,1,1,1,1
1823@@ -55,6 +57,8 @@
1824 access_report_workcenter_load_user,report.workcenter.load.user,model_report_workcenter_load,mrp.group_mrp_user,1,0,0,0
1825 access_mrp_bom_salesman,mrp.bom,model_mrp_bom,base.group_sale_salesman,1,0,0,0
1826 access_mrp_bom_stockuser,mrp.bom,model_mrp_bom,stock.group_stock_user,1,0,0,0
1827+access_mrp_bom_line_salesman,mrp.bom.line,model_mrp_bom_line,base.group_sale_salesman,1,0,0,0
1828+access_mrp_bom_line_stockuser,mrp.bom.line,model_mrp_bom_line,stock.group_stock_user,1,0,0,0
1829 access_product_uom_categ_mrp_manager,product.uom.categ mrp_manager,product.model_product_uom_categ,mrp.group_mrp_manager,1,1,1,1
1830 access_product_uom_mrp_manager,product.uom mrp_manager,product.model_product_uom,mrp.group_mrp_manager,1,1,1,1
1831 access_product_ul_mrp_manager,product.ul mrp_manager,product.model_product_ul,mrp.group_mrp_manager,1,1,1,1
1832
1833=== modified file 'mrp/stock.py'
1834--- mrp/stock.py 2014-05-07 17:24:46 +0000
1835+++ mrp/stock.py 2014-05-26 16:10:21 +0000
1836@@ -55,13 +55,14 @@
1837 user_company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
1838 #doing the search as SUPERUSER because a user with the permission to write on a stock move should be able to explode it
1839 #without giving him the right to read the boms.
1840- return self.pool.get('mrp.bom').search(cr, SUPERUSER_ID, [
1841- ('product_id', '=', move.product_id.id),
1842- ('bom_id', '=', False),
1843+ domain = [
1844+ '|', ('product_id', '=', move.product_id.id),
1845+ '&', ('product_id', '=', False), ('product_tmpl_id.product_variant_ids', '=', move.product_id.id),
1846 ('type', '=', 'phantom'),
1847 '|', ('date_start', '=', False), ('date_start', '<=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
1848 '|', ('date_stop', '=', False), ('date_stop', '>=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)),
1849- ('company_id', '=', user_company)], context=context)
1850+ ('company_id', '=', user_company)]
1851+ return self.pool.get('mrp.bom').search(cr, SUPERUSER_ID, domain, context=context)
1852
1853 def _action_explode(self, cr, uid, move, context=None):
1854 """ Explodes pickings.
1855@@ -76,7 +77,7 @@
1856 if bis:
1857 factor = move.product_qty
1858 bom_point = bom_obj.browse(cr, SUPERUSER_ID, bis[0], context=context)
1859- res = bom_obj._bom_explode(cr, SUPERUSER_ID, bom_point, factor, [])
1860+ res = bom_obj._bom_explode(cr, SUPERUSER_ID, bom_point, move.product_id, factor, [])
1861 state = 'confirmed'
1862 if move.state == 'assigned':
1863 state = 'assigned'
1864
1865=== modified file 'mrp/test/bom_with_service_type_product.yml'
1866--- mrp/test/bom_with_service_type_product.yml 2014-02-05 09:34:11 +0000
1867+++ mrp/test/bom_with_service_type_product.yml 2014-05-26 16:10:21 +0000
1868@@ -4,17 +4,17 @@
1869 !record {model: mrp.bom, id: mrp_bom_test1}:
1870 company_id: base.main_company
1871 name: PC Assemble SC234
1872+ product_tmpl_id: product.product_product_3_product_template
1873 product_id: product.product_product_3
1874+ product_uom: product.product_uom_unit
1875 product_qty: 1.0
1876 type: normal
1877- bom_lines:
1878- - company_id: base.main_company
1879- name: On Site Assistance
1880- product_id: product.product_product_2
1881+ bom_line_ids:
1882+ - product_id: product.product_product_2
1883+ product_uom: product.product_uom_unit
1884 product_qty: 1.0
1885- - company_id: base.main_company
1886- name: GrapWorks Software
1887- product_id: product.product_product_44
1888+ - product_id: product.product_product_44
1889+ product_uom: product.product_uom_unit
1890 product_qty: 1.0
1891 -
1892 I make the production order using BoM having one service type product and one consumable product.
1893
1894=== modified file 'mrp/test/order_demo.yml'
1895--- mrp/test/order_demo.yml 2014-04-04 16:17:13 +0000
1896+++ mrp/test/order_demo.yml 2014-05-26 16:10:21 +0000
1897@@ -7,11 +7,11 @@
1898 I create Production Order of PC Assemble SC349 to produce 5.0 Unit.
1899 -
1900 !record {model: mrp.production, id: mrp_production_test1}:
1901- product_id: product.product_product_4
1902+ product_id: product.product_product_3
1903 product_qty: 5.0
1904 location_src_id: stock.stock_location_14
1905 location_dest_id: stock.stock_location_output
1906- bom_id: mrp_bom_24
1907+ bom_id: mrp_bom_9
1908 routing_id: mrp.mrp_routing_1
1909
1910
1911
1912=== modified file 'mrp/views/report_mrpbomstructure.xml'
1913--- mrp/views/report_mrpbomstructure.xml 2014-02-24 10:34:53 +0000
1914+++ mrp/views/report_mrpbomstructure.xml 2014-05-26 16:10:21 +0000
1915@@ -27,10 +27,9 @@
1916 </td>
1917 <td><span t-field="o.code"/></td>
1918 </tr>
1919- <tr t-foreach="get_children(o.bom_lines)" t-as="l">
1920+ <tr t-foreach="get_children(o.bom_line_ids)" t-as="l">
1921 <td>
1922 <span style="color: white;" t-esc="'... '*(l['level'])"/>
1923- - <span t-esc="l['name']"/>
1924 </td>
1925 <td>
1926 [ <span t-esc="l['pcode']"/> ]
1927
1928=== modified file 'mrp/wizard/change_production_qty.py'
1929--- mrp/wizard/change_production_qty.py 2013-11-29 16:56:44 +0000
1930+++ mrp/wizard/change_production_qty.py 2014-05-26 16:10:21 +0000
1931@@ -78,7 +78,7 @@
1932 bom_point = prod.bom_id
1933 bom_id = prod.bom_id.id
1934 if not bom_point:
1935- bom_id = bom_obj._bom_find(cr, uid, prod.product_id.id, prod.product_uom.id)
1936+ bom_id = bom_obj._bom_find(cr, uid, prod.product_uom.id, product_id=prod.product_id.id)
1937 if not bom_id:
1938 raise osv.except_osv(_('Error!'), _("Cannot find bill of material for this product."))
1939 prod_obj.write(cr, uid, [prod.id], {'bom_id': bom_id})
1940@@ -89,7 +89,7 @@
1941
1942 factor = prod.product_qty * prod.product_uom.factor / bom_point.product_uom.factor
1943 product_details, workcenter_details = \
1944- bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, [])
1945+ bom_obj._bom_explode(cr, uid, bom_point, prod.product_id, factor / bom_point.product_qty, [])
1946 for r in product_details:
1947 if r['product_id'] == move.product_id.id:
1948 move_obj.write(cr, uid, [move.id], {'product_uom_qty': r['product_qty']})
1949
1950=== modified file 'mrp_byproduct/test/mrp_byproduct.yml'
1951--- mrp_byproduct/test/mrp_byproduct.yml 2014-01-22 12:52:11 +0000
1952+++ mrp_byproduct/test/mrp_byproduct.yml 2014-05-26 16:10:21 +0000
1953@@ -4,7 +4,7 @@
1954 -
1955 I add a sub product in Bill of material for product External Hard Disk.
1956 -
1957- !record {model: mrp.bom, id: mrp.mrp_bom_24}:
1958+ !record {model: mrp.bom, id: mrp.mrp_bom_9}:
1959 product_id: product.product_product_28
1960 name: External Hard Disk + Subproduct
1961 product_uom: product.product_uom_unit
1962@@ -20,7 +20,7 @@
1963 product_id: product.product_product_28
1964 product_qty: 2.0
1965 product_uom: product.product_uom_unit
1966- bom_id: mrp.mrp_bom_24
1967+ bom_id: mrp.mrp_bom_9
1968 location_src_id: stock.stock_location_stock
1969 -
1970 I compute the data of production order.
1971
1972=== modified file 'point_of_sale/point_of_sale.py'
1973--- point_of_sale/point_of_sale.py 2014-05-08 14:39:40 +0000
1974+++ point_of_sale/point_of_sale.py 2014-05-26 16:10:21 +0000
1975@@ -1318,30 +1318,80 @@
1976 self.pool[m].write(cr,uid,[m_id],{'ean13':ean13})
1977 return { 'type' : 'ir.actions.act_window_close' }
1978
1979-class product_product(osv.osv):
1980- _inherit = 'product.product'
1981-
1982-
1983- #def _get_small_image(self, cr, uid, ids, prop, unknow_none, context=None):
1984- # result = {}
1985- # for obj in self.browse(cr, uid, ids, context=context):
1986- # if not obj.product_image:
1987- # result[obj.id] = False
1988- # continue
1989-
1990- # image_stream = io.BytesIO(obj.product_image.decode('base64'))
1991- # img = Image.open(image_stream)
1992- # img.thumbnail((120, 100), Image.ANTIALIAS)
1993- # img_stream = StringIO.StringIO()
1994- # img.save(img_stream, "JPEG")
1995- # result[obj.id] = img_stream.getvalue().encode('base64')
1996- # return result
1997+class pos_category(osv.osv):
1998+ _name = "pos.category"
1999+ _description = "Public Category"
2000+ _order = "sequence, name"
2001+
2002+ _constraints = [
2003+ (osv.osv._check_recursion, 'Error ! You cannot create recursive categories.', ['parent_id'])
2004+ ]
2005+
2006+ def name_get(self, cr, uid, ids, context=None):
2007+ if not len(ids):
2008+ return []
2009+ reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)
2010+ res = []
2011+ for record in reads:
2012+ name = record['name']
2013+ if record['parent_id']:
2014+ name = record['parent_id'][1]+' / '+name
2015+ res.append((record['id'], name))
2016+ return res
2017+
2018+ def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
2019+ res = self.name_get(cr, uid, ids, context=context)
2020+ return dict(res)
2021+
2022+ def _get_image(self, cr, uid, ids, name, args, context=None):
2023+ result = dict.fromkeys(ids, False)
2024+ for obj in self.browse(cr, uid, ids, context=context):
2025+ result[obj.id] = tools.image_get_resized_images(obj.image)
2026+ return result
2027+
2028+ def _set_image(self, cr, uid, id, name, value, args, context=None):
2029+ return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
2030+
2031+ _columns = {
2032+ 'name': fields.char('Name', required=True, translate=True),
2033+ 'complete_name': fields.function(_name_get_fnc, type="char", string='Name'),
2034+ 'parent_id': fields.many2one('product.public.category','Parent Category', select=True),
2035+ 'child_id': fields.one2many('product.public.category', 'parent_id', string='Children Categories'),
2036+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
2037+
2038+ # NOTE: there is no 'default image', because by default we don't show thumbnails for categories. However if we have a thumbnail
2039+ # for at least one category, then we display a default image on the other, so that the buttons have consistent styling.
2040+ # In this case, the default image is set by the js code.
2041+ # NOTE2: image: all image fields are base64 encoded and PIL-supported
2042+ 'image': fields.binary("Image",
2043+ help="This field holds the image used as image for the cateogry, limited to 1024x1024px."),
2044+ 'image_medium': fields.function(_get_image, fnct_inv=_set_image,
2045+ string="Medium-sized image", type="binary", multi="_get_image",
2046+ store={
2047+ 'product.public.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
2048+ },
2049+ help="Medium-sized image of the category. It is automatically "\
2050+ "resized as a 128x128px image, with aspect ratio preserved. "\
2051+ "Use this field in form views or some kanban views."),
2052+ 'image_small': fields.function(_get_image, fnct_inv=_set_image,
2053+ string="Smal-sized image", type="binary", multi="_get_image",
2054+ store={
2055+ 'product.public.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
2056+ },
2057+ help="Small-sized image of the category. It is automatically "\
2058+ "resized as a 64x64px image, with aspect ratio preserved. "\
2059+ "Use this field anywhere a small image is required."),
2060+ }
2061+
2062+class product_template(osv.osv):
2063+ _inherit = 'product.template'
2064
2065 _columns = {
2066 'income_pdt': fields.boolean('Point of Sale Cash In', help="Check if, this is a product you can use to put cash into a statement for the point of sale backend."),
2067 'expense_pdt': fields.boolean('Point of Sale Cash Out', help="Check if, this is a product you can use to take cash from a statement for the point of sale backend, example: money lost, transfer to bank, etc."),
2068 'available_in_pos': fields.boolean('Available in the Point of Sale', help='Check if you want this product to appear in the Point of Sale'),
2069 'to_weight' : fields.boolean('To Weigh', help="Check if the product should be weighted (mainly used with self check-out interface)."),
2070+ 'pos_categ_id': fields.many2one('pos.category','Point of Sale Category', help="Those categories are used to group similar products for point of sale."),
2071 }
2072
2073 _defaults = {
2074
2075=== modified file 'point_of_sale/point_of_sale_demo.xml'
2076--- point_of_sale/point_of_sale_demo.xml 2014-01-27 17:21:21 +0000
2077+++ point_of_sale/point_of_sale_demo.xml 2014-05-26 16:10:21 +0000
2078@@ -39,145 +39,146 @@
2079 <field name="journal_ids" eval="[(6, 0, [ref('account.cash_journal'), ref('account.bank_journal'), ref('account.check_journal')])]" />
2080 </record>
2081
2082- <!-- Resource: product.public.category -->
2083+ <!-- Resource: pos.category -->
2084
2085- <record id="product.computers" model="product.public.category">
2086+ <record id="computers" model="pos.category">
2087+ <field name="name">Computers</field>
2088 <field name="image" type="base64" file="point_of_sale/static/img/computer.png"/>
2089 </record>
2090
2091- <record id="beverage" model="product.public.category">
2092+ <record id="beverage" model="pos.category">
2093 <field name="name">Beverages</field>
2094 <field name="image" type="base64" file="point_of_sale/static/img/beverage-image.jpg"/>
2095 </record>
2096
2097- <record id="water" model="product.public.category">
2098+ <record id="water" model="pos.category">
2099 <field name="parent_id" ref="beverage"/>
2100 <field name="name">Water</field>
2101 <field name="image" type="base64" file="point_of_sale/static/img/water-image.jpg"/>
2102 </record>
2103- <record id="plain_water" model="product.public.category">
2104+ <record id="plain_water" model="pos.category">
2105 <field name="parent_id" ref="water"/>
2106 <field name="name">Plain Water</field>
2107 <field name="image" type="base64" file="point_of_sale/static/img/plain_water-image.jpg"/>
2108 </record>
2109- <record id="sparkling_water" model="product.public.category">
2110+ <record id="sparkling_water" model="pos.category">
2111 <field name="parent_id" ref="water"/>
2112 <field name="name">Sparkling Water</field>
2113 <field name="image" type="base64" file="point_of_sale/static/img/sparkling_water-image.jpg"/>
2114 </record>
2115- <record id="soda" model="product.public.category">
2116+ <record id="soda" model="pos.category">
2117 <field name="parent_id" ref="beverage"/>
2118 <field name="name">Soda</field>
2119 <field name="image" type="base64" file="point_of_sale/static/img/soda-image.jpg"/>
2120 </record>
2121- <record id="coke" model="product.public.category">
2122+ <record id="coke" model="pos.category">
2123 <field name="parent_id" ref="soda"/>
2124 <field name="name">Coke</field>
2125 <field name="image" type="base64" file="point_of_sale/static/img/coke-image.jpg"/>
2126 </record>
2127- <record id="soda_orange" model="product.public.category">
2128+ <record id="soda_orange" model="pos.category">
2129 <field name="parent_id" ref="soda"/>
2130 <field name="name">Orange</field>
2131 <field name="image" type="base64" file="point_of_sale/static/img/soda_orange-image.jpg"/>
2132 </record>
2133- <record id="beers" model="product.public.category">
2134+ <record id="beers" model="pos.category">
2135 <field name="parent_id" ref="beverage"/>
2136 <field name="name">Beers</field>
2137 <field name="image" type="base64" file="point_of_sale/static/img/beers-image.jpg"/>
2138 </record>
2139- <record id="pils" model="product.public.category">
2140+ <record id="pils" model="pos.category">
2141 <field name="parent_id" ref="beers"/>
2142 <field name="name">Pils</field>
2143 <field name="image" type="base64" file="point_of_sale/static/img/pils-image.jpg"/>
2144 </record>
2145- <record id="fruity_beers" model="product.public.category">
2146+ <record id="fruity_beers" model="pos.category">
2147 <field name="parent_id" ref="beers"/>
2148 <field name="name">Fruity Beers</field>
2149 <field name="image" type="base64" file="point_of_sale/static/img/fruity_beers-image.jpg"/>
2150 </record>
2151- <record id="special_beers" model="product.public.category">
2152+ <record id="special_beers" model="pos.category">
2153 <field name="parent_id" ref="beers"/>
2154 <field name="name">Special Beers</field>
2155 <field name="image" type="base64" file="point_of_sale/static/img/special_beers-image.jpg"/>
2156 </record>
2157- <record id="food" model="product.public.category">
2158+ <record id="food" model="pos.category">
2159 <field name="name">Food</field>
2160 <field name="image" type="base64" file="point_of_sale/static/img/food-image.jpg"/>
2161 </record>
2162- <record id="pizza" model="product.public.category">
2163+ <record id="pizza" model="pos.category">
2164 <field name="parent_id" ref="food"/>
2165 <field name="name">Pizza</field>
2166 <field name="image" type="base64" file="point_of_sale/static/img/pizza-image.jpg"/>
2167 </record>
2168- <record id="ice_cream" model="product.public.category">
2169+ <record id="ice_cream" model="pos.category">
2170 <field name="parent_id" ref="food"/>
2171 <field name="name">Ice Cream</field>
2172 <field name="image" type="base64" file="point_of_sale/static/img/ice_cream-image.jpg"/>
2173 </record>
2174- <record id="chips" model="product.public.category">
2175+ <record id="chips" model="pos.category">
2176 <field name="parent_id" ref="food"/>
2177 <field name="name">Chips</field>
2178 <field name="image" type="base64" file="point_of_sale/static/img/chips-image.jpg"/>
2179 </record>
2180- <record id="fruits" model="product.public.category">
2181+ <record id="fruits" model="pos.category">
2182 <field name="name">Fresh Fruits</field>
2183 <field name="image" type="base64" file="point_of_sale/static/img/fruits-image.jpg"/>
2184 </record>
2185- <record id="oranges" model="product.public.category">
2186+ <record id="oranges" model="pos.category">
2187 <field name="parent_id" ref="fruits"/>
2188 <field name="name">Oranges</field>
2189 <field name="image" type="base64" file="point_of_sale/static/img/oranges-image.jpg"/>
2190 </record>
2191- <record id="pomme" model="product.public.category">
2192+ <record id="pomme" model="pos.category">
2193 <field name="parent_id" ref="fruits"/>
2194 <field name="name">Apples</field>
2195 <field name="image" type="base64" file="point_of_sale/static/img/pomme-image.jpg"/>
2196 </record>
2197- <record id="autres_agrumes" model="product.public.category">
2198+ <record id="autres_agrumes" model="pos.category">
2199 <field name="parent_id" ref="fruits"/>
2200 <field name="name">Other Citrus</field>
2201 <field name="image" type="base64" file="point_of_sale/static/img/autres_agrumes-image.jpg"/>
2202 </record>
2203- <record id="poire" model="product.public.category">
2204+ <record id="poire" model="pos.category">
2205 <field name="parent_id" ref="fruits"/>
2206 <field name="name">Pears</field>
2207 <field name="image" type="base64" file="point_of_sale/static/img/poire-image.jpg"/>
2208 </record>
2209- <record id="rouges_noyau_fruits" model="product.public.category">
2210+ <record id="rouges_noyau_fruits" model="pos.category">
2211 <field name="parent_id" ref="fruits"/>
2212 <field name="name">Berries</field>
2213 <field name="image" type="base64" file="point_of_sale/static/img/rouges_noyau_fruits-image.jpg"/>
2214 </record>
2215- <record id="raisins" model="product.public.category">
2216+ <record id="raisins" model="pos.category">
2217 <field name="parent_id" ref="fruits"/>
2218 <field name="name">Grapes</field>
2219 <field name="image" type="base64" file="point_of_sale/static/img/raisins-image.jpg"/>
2220 </record>
2221- <record id="legumes" model="product.public.category">
2222+ <record id="legumes" model="pos.category">
2223 <field name="name">Fresh vegetables</field>
2224 <field name="image" type="base64" file="point_of_sale/static/img/legumes-image.jpg"/>
2225 </record>
2226- <record id="pommes_de_terre" model="product.public.category">
2227+ <record id="pommes_de_terre" model="pos.category">
2228 <field name="parent_id" ref="legumes"/>
2229 <field name="name">Potatoes</field>
2230 <field name="image" type="base64" file="point_of_sale/static/img/pommes_de_terre-image.jpg"/>
2231 </record>
2232- <record id="legumes_racine" model="product.public.category">
2233+ <record id="legumes_racine" model="pos.category">
2234 <field name="parent_id" ref="legumes"/>
2235 <field name="name">Root vegetables</field>
2236 <field name="image" type="base64" file="point_of_sale/static/img/legumes_racine-image.jpg"/>
2237 </record>
2238- <record id="tomates" model="product.public.category">
2239+ <record id="tomates" model="pos.category">
2240 <field name="parent_id" ref="legumes"/>
2241 <field name="name">Tomatos</field>
2242 <field name="image" type="base64" file="point_of_sale/static/img/tomates-image.jpg"/>
2243 </record>
2244- <record id="oignons_ail_echalotes" model="product.public.category">
2245+ <record id="oignons_ail_echalotes" model="pos.category">
2246 <field name="parent_id" ref="legumes"/>
2247 <field name="name">Onions / Garlic / Shallots</field>
2248 <field name="image" type="base64" file="point_of_sale/static/img/oignons_ail_echalotes-image.jpg"/>
2249 </record>
2250- <record id="autres_legumes_frais" model="product.public.category">
2251+ <record id="autres_legumes_frais" model="pos.category">
2252 <field name="parent_id" ref="legumes"/>
2253 <field name="name">Other fresh vegetables</field>
2254 <field name="image" type="base64" file="point_of_sale/static/img/autres_legumes_frais-image.jpg"/>
2255@@ -191,7 +192,7 @@
2256 <field name="name">Boni Oranges</field>
2257 <field name="to_weight">True</field>
2258 <field name="ean13">2100002000003</field>
2259- <field name="public_categ_id" ref="oranges"/>
2260+ <field name="pos_categ_id" ref="oranges"/>
2261 <field name="uom_id" ref="product.product_uom_kgm" />
2262 <field name="uom_po_id" ref="product.product_uom_kgm" />
2263 <field name="image" type="base64" file="point_of_sale/static/img/boni_orange-image.jpg"/>
2264@@ -200,7 +201,7 @@
2265 <field name="available_in_pos">True</field>
2266 <field name="list_price">2.83</field>
2267 <field name="name">Orange Butterfly</field>
2268- <field name="public_categ_id" ref="oranges"/>
2269+ <field name="pos_categ_id" ref="oranges"/>
2270 <field name="to_weight">True</field>
2271 <field name="uom_id" ref="product.product_uom_kgm" />
2272 <field name="uom_po_id" ref="product.product_uom_kgm" />
2273@@ -213,7 +214,7 @@
2274 <field name="name">Lemon</field>
2275 <field name="ean13">2301000000006</field>
2276 <field name="to_weight">True</field>
2277- <field name="public_categ_id" ref="autres_agrumes"/>
2278+ <field name="pos_categ_id" ref="autres_agrumes"/>
2279 <field name="uom_id" ref="product.product_uom_kgm" />
2280 <field name="uom_po_id" ref="product.product_uom_kgm" />
2281 <field name="image" type="base64" file="point_of_sale/static/img/citron-image.jpg"/>
2282@@ -223,7 +224,7 @@
2283 <field name="list_price">3.19</field>
2284 <field name="name">Stringers</field>
2285 <field name="to_weight">True</field>
2286- <field name="public_categ_id" ref="autres_agrumes"/>
2287+ <field name="pos_categ_id" ref="autres_agrumes"/>
2288 <field name="uom_id" ref="product.product_uom_kgm" />
2289 <field name="uom_po_id" ref="product.product_uom_kgm" />
2290 <field name="image" type="base64" file="point_of_sale/static/img/limon-image.jpg"/>
2291@@ -233,7 +234,7 @@
2292 <field name="list_price">1.98</field>
2293 <field name="name">Red grapefruit</field>
2294 <field name="to_weight">True</field>
2295- <field name="public_categ_id" ref="autres_agrumes"/>
2296+ <field name="pos_categ_id" ref="autres_agrumes"/>
2297 <field name="uom_id" ref="product.product_uom_kgm" />
2298 <field name="uom_po_id" ref="product.product_uom_kgm" />
2299 <field name="image" type="base64" file="point_of_sale/static/img/pamplemousse_rouge_pamplemousse-image.jpg"/>
2300@@ -244,7 +245,7 @@
2301 <field name="list_price">2.09</field>
2302 <field name="name">Granny Smith apples</field>
2303 <field name="to_weight">True</field>
2304- <field name="public_categ_id" ref="pomme"/>
2305+ <field name="pos_categ_id" ref="pomme"/>
2306 <field name="uom_id" ref="product.product_uom_kgm" />
2307 <field name="uom_po_id" ref="product.product_uom_kgm" />
2308 <field name="image" type="base64" file="point_of_sale/static/img/pomme_granny_smith-image.jpg"/>
2309@@ -254,7 +255,7 @@
2310 <field name="list_price">1.10</field>
2311 <field name="name">Jonagold apples</field>
2312 <field name="to_weight">True</field>
2313- <field name="public_categ_id" ref="pomme"/>
2314+ <field name="pos_categ_id" ref="pomme"/>
2315 <field name="uom_id" ref="product.product_uom_kgm" />
2316 <field name="uom_po_id" ref="product.product_uom_kgm" />
2317 <field name="image" type="base64" file="point_of_sale/static/img/pomme_jonagold-image.jpg"/>
2318@@ -264,7 +265,7 @@
2319 <field name="list_price">1.69</field>
2320 <field name="name">Golden Apples Perlim</field>
2321 <field name="to_weight">True</field>
2322- <field name="public_categ_id" ref="pomme"/>
2323+ <field name="pos_categ_id" ref="pomme"/>
2324 <field name="uom_id" ref="product.product_uom_kgm" />
2325 <field name="uom_po_id" ref="product.product_uom_kgm" />
2326 <field name="image" type="base64" file="point_of_sale/static/img/pomme_golden_perlim-image.jpg"/>
2327@@ -275,7 +276,7 @@
2328 <field name="list_price">1.70</field>
2329 <field name="name">Conference pears</field>
2330 <field name="to_weight">True</field>
2331- <field name="public_categ_id" ref="poire"/>
2332+ <field name="pos_categ_id" ref="poire"/>
2333 <field name="uom_id" ref="product.product_uom_kgm" />
2334 <field name="uom_po_id" ref="product.product_uom_kgm" />
2335 <field name="image" type="base64" file="point_of_sale/static/img/poire_conference-image.jpg"/>
2336@@ -286,7 +287,7 @@
2337 <field name="list_price">5.70</field>
2338 <field name="name">Peach</field>
2339 <field name="to_weight">True</field>
2340- <field name="public_categ_id" ref="rouges_noyau_fruits"/>
2341+ <field name="pos_categ_id" ref="rouges_noyau_fruits"/>
2342 <field name="uom_id" ref="product.product_uom_kgm" />
2343 <field name="uom_po_id" ref="product.product_uom_kgm" />
2344 <field name="image" type="base64" file="point_of_sale/static/img/nectarine-image.jpg"/>
2345@@ -297,7 +298,7 @@
2346 <field name="name">Peaches</field>
2347 <field name="to_weight">True</field>
2348 <field name="ean13">2300001000008</field>
2349- <field name="public_categ_id" ref="rouges_noyau_fruits"/>
2350+ <field name="pos_categ_id" ref="rouges_noyau_fruits"/>
2351 <field name="uom_id" ref="product.product_uom_kgm" />
2352 <field name="uom_po_id" ref="product.product_uom_kgm" />
2353 <field name="image" type="base64" file="point_of_sale/static/img/peche-image.jpg"/>
2354@@ -308,7 +309,7 @@
2355 <field name="list_price">4.80</field>
2356 <field name="name">Black Grapes</field>
2357 <field name="to_weight">True</field>
2358- <field name="public_categ_id" ref="raisins"/>
2359+ <field name="pos_categ_id" ref="raisins"/>
2360 <field name="uom_id" ref="product.product_uom_kgm" />
2361 <field name="uom_po_id" ref="product.product_uom_kgm" />
2362 <field name="image" type="base64" file="point_of_sale/static/img/raisins_noir-image.jpg"/>
2363@@ -319,7 +320,7 @@
2364 <field name="list_price">1.39</field>
2365 <field name="name">Potatoes</field>
2366 <field name="to_weight">True</field>
2367- <field name="public_categ_id" ref="pommes_de_terre"/>
2368+ <field name="pos_categ_id" ref="pommes_de_terre"/>
2369 <field name="uom_id" ref="product.product_uom_kgm" />
2370 <field name="uom_po_id" ref="product.product_uom_kgm" />
2371 <field name="image" type="base64" file="point_of_sale/static/img/pomme_de_terre-image.jpg"/>
2372@@ -330,7 +331,7 @@
2373 <field name="list_price">2.20</field>
2374 <field name="name">Extra Flandria chicory</field>
2375 <field name="to_weight">True</field>
2376- <field name="public_categ_id" ref="legumes_racine"/>
2377+ <field name="pos_categ_id" ref="legumes_racine"/>
2378 <field name="uom_id" ref="product.product_uom_kgm" />
2379 <field name="uom_po_id" ref="product.product_uom_kgm" />
2380 <field name="image" type="base64" file="point_of_sale/static/img/chicon_flandria_extra-image.jpg"/>
2381@@ -340,7 +341,7 @@
2382 <field name="list_price">0.90</field>
2383 <field name="name">Carrots</field>
2384 <field name="to_weight">True</field>
2385- <field name="public_categ_id" ref="legumes_racine"/>
2386+ <field name="pos_categ_id" ref="legumes_racine"/>
2387 <field name="uom_id" ref="product.product_uom_kgm" />
2388 <field name="uom_po_id" ref="product.product_uom_kgm" />
2389 <field name="image" type="base64" file="point_of_sale/static/img/carotte-image.jpg"/>
2390@@ -350,7 +351,7 @@
2391 <field name="list_price">2.10</field>
2392 <field name="name">Fennel</field>
2393 <field name="to_weight">True</field>
2394- <field name="public_categ_id" ref="legumes_racine"/>
2395+ <field name="pos_categ_id" ref="legumes_racine"/>
2396 <field name="uom_id" ref="product.product_uom_kgm" />
2397 <field name="uom_po_id" ref="product.product_uom_kgm" />
2398 <field name="image" type="base64" file="point_of_sale/static/img/fenouil_fenouil-image.jpg"/>
2399@@ -361,7 +362,7 @@
2400 <field name="list_price">1.90</field>
2401 <field name="name">In Cluster Tomatoes</field>
2402 <field name="to_weight">True</field>
2403- <field name="public_categ_id" ref="tomates"/>
2404+ <field name="pos_categ_id" ref="tomates"/>
2405 <field name="uom_id" ref="product.product_uom_kgm" />
2406 <field name="uom_po_id" ref="product.product_uom_kgm" />
2407 <field name="image" type="base64" file="point_of_sale/static/img/tomate_en_grappe-image.jpg"/>
2408@@ -373,7 +374,7 @@
2409 <field name="name">Onions</field>
2410 <field name="to_weight">True</field>
2411 <field name="ean13">2100001000004</field>
2412- <field name="public_categ_id" ref="oignons_ail_echalotes"/>
2413+ <field name="pos_categ_id" ref="oignons_ail_echalotes"/>
2414 <field name="uom_id" ref="product.product_uom_kgm" />
2415 <field name="uom_po_id" ref="product.product_uom_kgm" />
2416 <field name="image" type="base64" file="point_of_sale/static/img/Onions-image.jpg"/>
2417@@ -384,7 +385,7 @@
2418 <field name="list_price">3.10</field>
2419 <field name="name">Red Pepper</field>
2420 <field name="to_weight">True</field>
2421- <field name="public_categ_id" ref="autres_legumes_frais"/>
2422+ <field name="pos_categ_id" ref="autres_legumes_frais"/>
2423 <field name="uom_id" ref="product.product_uom_kgm" />
2424 <field name="uom_po_id" ref="product.product_uom_kgm" />
2425 <field name="image" type="base64" file="point_of_sale/static/img/poivron_rouges-image.jpg"/>
2426@@ -394,7 +395,7 @@
2427 <field name="list_price">3.00</field>
2428 <field name="name">Green Peppers</field>
2429 <field name="to_weight">True</field>
2430- <field name="public_categ_id" ref="autres_legumes_frais"/>
2431+ <field name="pos_categ_id" ref="autres_legumes_frais"/>
2432 <field name="uom_id" ref="product.product_uom_kgm" />
2433 <field name="uom_po_id" ref="product.product_uom_kgm" />
2434 <field name="image" type="base64" file="point_of_sale/static/img/poivron_verts-image.jpg"/>
2435@@ -404,7 +405,7 @@
2436 <field name="list_price">2.70</field>
2437 <field name="name">Yellow Peppers</field>
2438 <field name="to_weight">True</field>
2439- <field name="public_categ_id" ref="autres_legumes_frais"/>
2440+ <field name="pos_categ_id" ref="autres_legumes_frais"/>
2441 <field name="uom_id" ref="product.product_uom_kgm" />
2442 <field name="uom_po_id" ref="product.product_uom_kgm" />
2443 <field name="image" type="base64" file="point_of_sale/static/img/poivron_jaunes-image.jpg"/>
2444@@ -414,7 +415,7 @@
2445 <field name="list_price">2.29</field>
2446 <field name="name">Leeks</field>
2447 <field name="to_weight">True</field>
2448- <field name="public_categ_id" ref="autres_legumes_frais"/>
2449+ <field name="pos_categ_id" ref="autres_legumes_frais"/>
2450 <field name="uom_id" ref="product.product_uom_kgm" />
2451 <field name="uom_po_id" ref="product.product_uom_kgm" />
2452 <field name="image" type="base64" file="point_of_sale/static/img/poireaux_poireaux-image.jpg"/>
2453@@ -424,7 +425,7 @@
2454 <field name="list_price">1.20</field>
2455 <field name="name">Zucchini</field>
2456 <field name="to_weight">True</field>
2457- <field name="public_categ_id" ref="autres_legumes_frais"/>
2458+ <field name="pos_categ_id" ref="autres_legumes_frais"/>
2459 <field name="uom_id" ref="product.product_uom_kgm" />
2460 <field name="uom_po_id" ref="product.product_uom_kgm" />
2461 <field name="image" type="base64" file="point_of_sale/static/img/courgette-image.jpg"/>
2462@@ -435,21 +436,21 @@
2463 <field name="list_price">1.49</field>
2464 <field name="name">Coca-Cola Regular 1L</field>
2465 <field name="ean13">5449000054227</field>
2466- <field name="public_categ_id" ref="coke"/>
2467+ <field name="pos_categ_id" ref="coke"/>
2468 <field name="image" type="base64" file="point_of_sale/static/img/coca_regular_1l-image.jpg"/>
2469 </record>
2470 <record id="coca_regular_2l" model="product.product">
2471 <field name="available_in_pos">True</field>
2472 <field name="list_price">2.38</field>
2473 <field name="name">Coca-Cola Regular 2L</field>
2474- <field name="public_categ_id" ref="coke"/>
2475+ <field name="pos_categ_id" ref="coke"/>
2476 <field name="image" type="base64" file="point_of_sale/static/img/coca_regular_2l-image.jpg"/>
2477 </record>
2478 <record id="coca_regular_50cl" model="product.product">
2479 <field name="available_in_pos">True</field>
2480 <field name="list_price">0.97</field>
2481 <field name="name">Coca-Cola Regular 50cl</field>
2482- <field name="public_categ_id" ref="coke"/>
2483+ <field name="pos_categ_id" ref="coke"/>
2484 <field name="image" type="base64" file="point_of_sale/static/img/coca_regular_50cl-image.jpg"/>
2485 </record>
2486 <record id="coca_regular_33cl" model="product.product">
2487@@ -457,7 +458,7 @@
2488 <field name="list_price">0.51</field>
2489 <field name="name">Coca-Cola Regular 33cl</field>
2490 <field name="ean13">5449000000996</field>
2491- <field name="public_categ_id" ref="coke"/>
2492+ <field name="pos_categ_id" ref="coke"/>
2493 <field name="image" type="base64" file="point_of_sale/static/img/coca_regular_33cl-image.jpg"/>
2494 </record>
2495
2496@@ -465,35 +466,35 @@
2497 <field name="available_in_pos">True</field>
2498 <field name="list_price">1.49</field>
2499 <field name="name">Coca-Cola Light 1L</field>
2500- <field name="public_categ_id" ref="coke"/>
2501+ <field name="pos_categ_id" ref="coke"/>
2502 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_1l-image.jpg"/>
2503 </record>
2504 <record id="coca_light_2l" model="product.product">
2505 <field name="available_in_pos">True</field>
2506 <field name="list_price">2.38</field>
2507 <field name="name">Coca-Cola Light 2L</field>
2508- <field name="public_categ_id" ref="coke"/>
2509+ <field name="pos_categ_id" ref="coke"/>
2510 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_2l-image.jpg"/>
2511 </record>
2512 <record id="coca_light_50cl" model="product.product">
2513 <field name="available_in_pos">True</field>
2514 <field name="list_price">0.97</field>
2515 <field name="name">Coca-Cola Light 50cl</field>
2516- <field name="public_categ_id" ref="coke"/>
2517+ <field name="pos_categ_id" ref="coke"/>
2518 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_50cl-image.jpg"/>
2519 </record>
2520 <record id="coca_light_33cl" model="product.product">
2521 <field name="available_in_pos">True</field>
2522 <field name="list_price">0.51</field>
2523 <field name="name">Coca-Cola Light 33cl</field>
2524- <field name="public_categ_id" ref="coke"/>
2525+ <field name="pos_categ_id" ref="coke"/>
2526 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_33cl-image.jpg"/>
2527 </record>
2528 <record id="coca_light_decaf_33cl" model="product.product">
2529 <field name="available_in_pos">True</field>
2530 <field name="list_price">0.53</field>
2531 <field name="name">Coca-Cola Light 33cl Decaf</field>
2532- <field name="public_categ_id" ref="coke"/>
2533+ <field name="pos_categ_id" ref="coke"/>
2534 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_decaf_33cl-image.jpg"/>
2535 </record>
2536
2537@@ -501,35 +502,35 @@
2538 <field name="available_in_pos">True</field>
2539 <field name="list_price">1.49</field>
2540 <field name="name">Coca-Cola Zero 1L</field>
2541- <field name="public_categ_id" ref="coke"/>
2542+ <field name="pos_categ_id" ref="coke"/>
2543 <field name="image" type="base64" file="point_of_sale/static/img/coca_zero_1l-image.jpg"/>
2544 </record>
2545 <record id="coca_zero_2l" model="product.product">
2546 <field name="available_in_pos">True</field>
2547 <field name="list_price">2.38</field>
2548 <field name="name">Coca-Cola Zero 2L</field>
2549- <field name="public_categ_id" ref="coke"/>
2550+ <field name="pos_categ_id" ref="coke"/>
2551 <field name="image" type="base64" file="point_of_sale/static/img/coca_zero_2l-image.jpg"/>
2552 </record>
2553 <record id="coca_zero_50cl" model="product.product">
2554 <field name="available_in_pos">True</field>
2555 <field name="list_price">0.97</field>
2556 <field name="name">Coca-Cola Zero 50cl</field>
2557- <field name="public_categ_id" ref="coke"/>
2558+ <field name="pos_categ_id" ref="coke"/>
2559 <field name="image" type="base64" file="point_of_sale/static/img/coca_zero_50cl-image.jpg"/>
2560 </record>
2561 <record id="coca_zero_33cl" model="product.product">
2562 <field name="available_in_pos">True</field>
2563 <field name="list_price">0.51</field>
2564 <field name="name">Coca-Cola Zero 33cl</field>
2565- <field name="public_categ_id" ref="coke"/>
2566+ <field name="pos_categ_id" ref="coke"/>
2567 <field name="image" type="base64" file="point_of_sale/static/img/coca_zero_33cl-image.jpg"/>
2568 </record>
2569 <record id="coca_zero_decaf_33cl" model="product.product">
2570 <field name="available_in_pos">True</field>
2571 <field name="list_price">0.67</field>
2572 <field name="name">Coca-Cola Zero Decaf 33cl</field>
2573- <field name="public_categ_id" ref="coke"/>
2574+ <field name="pos_categ_id" ref="coke"/>
2575 <field name="image" type="base64" file="point_of_sale/static/img/coca_zero_decaf_33cl-image.jpg"/>
2576 </record>
2577
2578@@ -537,21 +538,21 @@
2579 <field name="available_in_pos">True</field>
2580 <field name="list_price">2.83</field>
2581 <field name="name">Coca-Cola Light Lemon 2L</field>
2582- <field name="public_categ_id" ref="coke"/>
2583+ <field name="pos_categ_id" ref="coke"/>
2584 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_lemon_2l-image.jpg"/>
2585 </record>
2586 <record id="coca_light_lemon_50cl" model="product.product">
2587 <field name="available_in_pos">True</field>
2588 <field name="list_price">1.16</field>
2589 <field name="name">Coca-Cola Light Lemon 50cl</field>
2590- <field name="public_categ_id" ref="coke"/>
2591+ <field name="pos_categ_id" ref="coke"/>
2592 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_lemon_50cl-image.jpg"/>
2593 </record>
2594 <record id="coca_light_lemon_33cl" model="product.product">
2595 <field name="available_in_pos">True</field>
2596 <field name="list_price">0.53</field>
2597 <field name="name">Coca-Cola Light Lemon 33cl</field>
2598- <field name="public_categ_id" ref="coke"/>
2599+ <field name="pos_categ_id" ref="coke"/>
2600 <field name="image" type="base64" file="point_of_sale/static/img/coca_light_lemon_33cl-image.jpg"/>
2601 </record>
2602
2603@@ -559,42 +560,42 @@
2604 <field name="available_in_pos">True</field>
2605 <field name="list_price">1.70</field>
2606 <field name="name">Pepsi 2L</field>
2607- <field name="public_categ_id" ref="coke"/>
2608+ <field name="pos_categ_id" ref="coke"/>
2609 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_2l-image.jpg"/>
2610 </record>
2611 <record id="pepsi_33cl" model="product.product">
2612 <field name="available_in_pos">True</field>
2613 <field name="list_price">0.43</field>
2614 <field name="name">Pepsi 33cl</field>
2615- <field name="public_categ_id" ref="coke"/>
2616+ <field name="pos_categ_id" ref="coke"/>
2617 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_33cl-image.jpg"/>
2618 </record>
2619 <record id="pepsi_max_2l" model="product.product">
2620 <field name="available_in_pos">True</field>
2621 <field name="list_price">1.71</field>
2622 <field name="name">Pepsi Max 2L</field>
2623- <field name="public_categ_id" ref="coke"/>
2624+ <field name="pos_categ_id" ref="coke"/>
2625 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_max_2l-image.jpg"/>
2626 </record>
2627 <record id="pepsi_max_33cl" model="product.product">
2628 <field name="available_in_pos">True</field>
2629 <field name="list_price">0.40</field>
2630 <field name="name">Pepsi Max 33cl</field>
2631- <field name="public_categ_id" ref="coke"/>
2632+ <field name="pos_categ_id" ref="coke"/>
2633 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_max_33cl-image.jpg"/>
2634 </record>
2635 <record id="pepsi_max_50cl" model="product.product">
2636 <field name="available_in_pos">True</field>
2637 <field name="list_price">0.61</field>
2638 <field name="name">Pepsi Max 50cl</field>
2639- <field name="public_categ_id" ref="coke"/>
2640+ <field name="pos_categ_id" ref="coke"/>
2641 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_max_50cl-image.jpg"/>
2642 </record>
2643 <record id="pepsi_max_lemon_33cl" model="product.product">
2644 <field name="available_in_pos">True</field>
2645 <field name="list_price">0.40</field>
2646 <field name="name">Pepsi Max Cool Lemon 33cl</field>
2647- <field name="public_categ_id" ref="coke"/>
2648+ <field name="pos_categ_id" ref="coke"/>
2649 <field name="image" type="base64" file="point_of_sale/static/img/pepsi_max_lemon_33cl-image.jpg"/>
2650 </record>
2651
2652@@ -602,63 +603,63 @@
2653 <field name="available_in_pos">True</field>
2654 <field name="list_price">0.75</field>
2655 <field name="name">Spa Fruit and Orange 50cl</field>
2656- <field name="public_categ_id" ref="soda_orange"/>
2657+ <field name="pos_categ_id" ref="soda_orange"/>
2658 <field name="image" type="base64" file="point_of_sale/static/img/spa_et_fruit_50cl-image.jpg"/>
2659 </record>
2660 <record id="orangina_33cl" model="product.product">
2661 <field name="available_in_pos">True</field>
2662 <field name="list_price">0.72</field>
2663 <field name="name">Orangina 33cl</field>
2664- <field name="public_categ_id" ref="soda_orange"/>
2665+ <field name="pos_categ_id" ref="soda_orange"/>
2666 <field name="image" type="base64" file="point_of_sale/static/img/orangina_33cl-image.jpg"/>
2667 </record>
2668 <record id="orangina_1,5l" model="product.product">
2669 <field name="available_in_pos">True</field>
2670 <field name="list_price">2.42</field>
2671 <field name="name">Orangina 1.5L</field>
2672- <field name="public_categ_id" ref="soda_orange"/>
2673+ <field name="pos_categ_id" ref="soda_orange"/>
2674 <field name="image" type="base64" file="point_of_sale/static/img/orangina_1,5l-image.jpg"/>
2675 </record>
2676 <record id="fanta_orange_50cl" model="product.product">
2677 <field name="available_in_pos">True</field>
2678 <field name="list_price">0.98</field>
2679 <field name="name">Fanta Orange 50cl</field>
2680- <field name="public_categ_id" ref="soda_orange"/>
2681+ <field name="pos_categ_id" ref="soda_orange"/>
2682 <field name="image" type="base64" file="point_of_sale/static/img/fanta_orange_50cl-image.jpg"/>
2683 </record>
2684 <record id="fanta_orange_2l" model="product.product">
2685 <field name="available_in_pos">True</field>
2686 <field name="list_price">2.28</field>
2687 <field name="name">Fanta Orange 2L</field>
2688- <field name="public_categ_id" ref="soda_orange"/>
2689+ <field name="pos_categ_id" ref="soda_orange"/>
2690 <field name="image" type="base64" file="point_of_sale/static/img/fanta_orange_2l-image.jpg"/>
2691 </record>
2692 <record id="fanta_orange_33cl" model="product.product">
2693 <field name="available_in_pos">True</field>
2694 <field name="list_price">0.51</field>
2695 <field name="name">Fanta Orange 33cl</field>
2696- <field name="public_categ_id" ref="soda_orange"/>
2697+ <field name="pos_categ_id" ref="soda_orange"/>
2698 <field name="image" type="base64" file="point_of_sale/static/img/fanta_orange_33cl-image.jpg"/>
2699 </record>
2700 <record id="fanta_orange_25cl" model="product.product">
2701 <field name="available_in_pos">True</field>
2702 <field name="list_price">0.84</field>
2703 <field name="name">Fanta Orange 25cl</field>
2704- <field name="public_categ_id" ref="soda_orange"/>
2705+ <field name="pos_categ_id" ref="soda_orange"/>
2706 <field name="image" type="base64" file="point_of_sale/static/img/fanta_orange_25cl-image.jpg"/>
2707 </record>
2708 <record id="fanta_zero_orange_1,5l" model="product.product">
2709 <field name="available_in_pos">True</field>
2710 <field name="list_price">2.08</field>
2711 <field name="name">Fanta Orange Zero 1.5L</field>
2712- <field name="public_categ_id" ref="soda_orange"/>
2713+ <field name="pos_categ_id" ref="soda_orange"/>
2714 <field name="image" type="base64" file="point_of_sale/static/img/fanta_zero_orange_1,5l-image.jpg"/>
2715 </record>
2716 <record id="fanta_zero_orange_33cl" model="product.product">
2717 <field name="available_in_pos">True</field>
2718 <field name="list_price">0.53</field>
2719 <field name="name">Fanta Zero Orange 33cl</field>
2720- <field name="public_categ_id" ref="soda_orange"/>
2721+ <field name="pos_categ_id" ref="soda_orange"/>
2722 <field name="image" type="base64" file="point_of_sale/static/img/fanta_zero_orange_33cl-image.jpg"/>
2723 </record>
2724
2725@@ -666,56 +667,56 @@
2726 <field name="available_in_pos">True</field>
2727 <field name="list_price">0.52</field>
2728 <field name="name">Evian 50cl</field>
2729- <field name="public_categ_id" ref="plain_water"/>
2730+ <field name="pos_categ_id" ref="plain_water"/>
2731 <field name="image" type="base64" file="point_of_sale/static/img/evian_50cl-image.jpg"/>
2732 </record>
2733 <record id="evian_1l" model="product.product">
2734 <field name="available_in_pos">True</field>
2735 <field name="list_price">0.70</field>
2736 <field name="name">Evian 1L</field>
2737- <field name="public_categ_id" ref="plain_water"/>
2738+ <field name="pos_categ_id" ref="plain_water"/>
2739 <field name="image" type="base64" file="point_of_sale/static/img/evian_1l-image.jpg"/>
2740 </record>
2741 <record id="evian_2l" model="product.product">
2742 <field name="available_in_pos">True</field>
2743 <field name="list_price">1.26</field>
2744 <field name="name">2L Evian</field>
2745- <field name="public_categ_id" ref="plain_water"/>
2746+ <field name="pos_categ_id" ref="plain_water"/>
2747 <field name="image" type="base64" file="point_of_sale/static/img/evian_2l-image.jpg"/>
2748 </record>
2749 <record id="spa_33cl" model="product.product">
2750 <field name="available_in_pos">True</field>
2751 <field name="list_price">0.40</field>
2752 <field name="name">Spa Reine 33cl</field>
2753- <field name="public_categ_id" ref="plain_water"/>
2754+ <field name="pos_categ_id" ref="plain_water"/>
2755 <field name="image" type="base64" file="point_of_sale/static/img/spa_33cl-image.jpg"/>
2756 </record>
2757 <record id="spa_50cl" model="product.product">
2758 <field name="available_in_pos">True</field>
2759 <field name="list_price">0.46</field>
2760 <field name="name">Spa Reine 50cl</field>
2761- <field name="public_categ_id" ref="plain_water"/>
2762+ <field name="pos_categ_id" ref="plain_water"/>
2763 <field name="image" type="base64" file="point_of_sale/static/img/spa_50cl-image.jpg"/>
2764 </record>
2765 <record id="spa_1l" model="product.product">
2766 <field name="available_in_pos">True</field>
2767 <field name="list_price">0.65</field>
2768 <field name="name">Spa Reine 1L</field>
2769- <field name="public_categ_id" ref="plain_water"/>
2770+ <field name="pos_categ_id" ref="plain_water"/>
2771 <field name="image" type="base64" file="point_of_sale/static/img/spa_1l-image.jpg"/>
2772 </record>
2773 <record id="spa_2l" model="product.product">
2774 <field name="available_in_pos">True</field>
2775 <field name="list_price">1.30</field>
2776 <field name="name">Spa Reine 2L</field>
2777- <field name="public_categ_id" ref="plain_water"/>
2778+ <field name="pos_categ_id" ref="plain_water"/>
2779 <field name="image" type="base64" file="point_of_sale/static/img/spa_2l-image.jpg"/>
2780 </record>
2781 <record id="chaudfontaine_33cl" model="product.product">
2782 <field name="available_in_pos">True</field>
2783 <field name="list_price">0.34</field>
2784 <field name="name">Chaudfontaine 33cl</field>
2785- <field name="public_categ_id" ref="plain_water"/>
2786+ <field name="pos_categ_id" ref="plain_water"/>
2787 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_33cl-image.jpg"/>
2788 </record>
2789 <record id="chaudfontaine_50cl" model="product.product">
2790@@ -723,14 +724,14 @@
2791 <field name="list_price">0.44</field>
2792 <field name="ean13">5449000111715</field>
2793 <field name="name">Chaudfontaine 50cl</field>
2794- <field name="public_categ_id" ref="plain_water"/>
2795+ <field name="pos_categ_id" ref="plain_water"/>
2796 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_50cl-image.jpg"/>
2797 </record>
2798 <record id="chaudfontaine_1,5l" model="product.product">
2799 <field name="available_in_pos">True</field>
2800 <field name="list_price">0.86</field>
2801 <field name="name">Chaudfontaine 1.5l</field>
2802- <field name="public_categ_id" ref="plain_water"/>
2803+ <field name="pos_categ_id" ref="plain_water"/>
2804 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_1,5l-image.jpg"/>
2805 </record>
2806
2807@@ -738,63 +739,63 @@
2808 <field name="available_in_pos">True</field>
2809 <field name="list_price">0.38</field>
2810 <field name="name">Spa Barisart 33cl</field>
2811- <field name="public_categ_id" ref="sparkling_water"/>
2812+ <field name="pos_categ_id" ref="sparkling_water"/>
2813 <field name="image" type="base64" file="point_of_sale/static/img/spa_gazeuse_33cl-image.jpg"/>
2814 </record>
2815 <record id="spa_gazeuse_50cl" model="product.product">
2816 <field name="available_in_pos">True</field>
2817 <field name="list_price">0.49</field>
2818 <field name="name">Spa Barisart 50cl</field>
2819- <field name="public_categ_id" ref="sparkling_water"/>
2820+ <field name="pos_categ_id" ref="sparkling_water"/>
2821 <field name="image" type="base64" file="point_of_sale/static/img/spa_gazeuse_50cl-image.jpg"/>
2822 </record>
2823 <record id="spa_gazeuse_1,5l" model="product.product">
2824 <field name="available_in_pos">True</field>
2825 <field name="list_price">1.00</field>
2826 <field name="name">Spa Barisart 1.5l</field>
2827- <field name="public_categ_id" ref="sparkling_water"/>
2828+ <field name="pos_categ_id" ref="sparkling_water"/>
2829 <field name="image" type="base64" file="point_of_sale/static/img/spa_gazeuse_1,5l-image.jpg"/>
2830 </record>
2831 <record id="chaudfontaine_petillante_33cl" model="product.product">
2832 <field name="available_in_pos">True</field>
2833 <field name="list_price">0.41</field>
2834 <field name="name">Chaudfontaine Petillante 33cl</field>
2835- <field name="public_categ_id" ref="sparkling_water"/>
2836+ <field name="pos_categ_id" ref="sparkling_water"/>
2837 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_petillante_33cl-image.jpg"/>
2838 </record>
2839 <record id="chaudfontaine_petillante_50cl" model="product.product">
2840 <field name="available_in_pos">True</field>
2841 <field name="list_price">0.57</field>
2842 <field name="name">Chaudfontaine Petillante 50cl</field>
2843- <field name="public_categ_id" ref="sparkling_water"/>
2844+ <field name="pos_categ_id" ref="sparkling_water"/>
2845 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_petillante_50cl-image.jpg"/>
2846 </record>
2847 <record id="chaudfontaine_petillante_1,5l" model="product.product">
2848 <field name="available_in_pos">True</field>
2849 <field name="list_price">0.98</field>
2850 <field name="name">Chaudfontaine Petillante 1.5l</field>
2851- <field name="public_categ_id" ref="sparkling_water"/>
2852+ <field name="pos_categ_id" ref="sparkling_water"/>
2853 <field name="image" type="base64" file="point_of_sale/static/img/chaudfontaine_petillante_1,5l-image.jpg"/>
2854 </record>
2855 <record id="perrier_50cl" model="product.product">
2856 <field name="available_in_pos">True</field>
2857 <field name="list_price">0.71</field>
2858 <field name="name">50cl Perrier</field>
2859- <field name="public_categ_id" ref="sparkling_water"/>
2860+ <field name="pos_categ_id" ref="sparkling_water"/>
2861 <field name="image" type="base64" file="point_of_sale/static/img/perrier_50cl-image.jpg"/>
2862 </record>
2863 <record id="perrier_1l" model="product.product">
2864 <field name="available_in_pos">True</field>
2865 <field name="list_price">0.96</field>
2866 <field name="name">Perrier 1L</field>
2867- <field name="public_categ_id" ref="sparkling_water"/>
2868+ <field name="pos_categ_id" ref="sparkling_water"/>
2869 <field name="image" type="base64" file="point_of_sale/static/img/perrier_1l-image.jpg"/>
2870 </record>
2871 <record id="san_pellegrino_1l" model="product.product">
2872 <field name="available_in_pos">True</field>
2873 <field name="list_price">0.98</field>
2874 <field name="name">San Pellegrino 1L</field>
2875- <field name="public_categ_id" ref="sparkling_water"/>
2876+ <field name="pos_categ_id" ref="sparkling_water"/>
2877 <field name="image" type="base64" file="point_of_sale/static/img/san_pellegrino_1l-image.jpg"/>
2878 </record>
2879
2880@@ -802,35 +803,35 @@
2881 <field name="available_in_pos">True</field>
2882 <field name="list_price">1.19</field>
2883 <field name="name">Stella Artois 50cl</field>
2884- <field name="public_categ_id" ref="pils"/>
2885+ <field name="pos_categ_id" ref="pils"/>
2886 <field name="image" type="base64" file="point_of_sale/static/img/stella_50cl-image.jpg"/>
2887 </record>
2888 <record id="stella_33cl" model="product.product">
2889 <field name="available_in_pos">True</field>
2890 <field name="list_price">0.82</field>
2891 <field name="name">Stella Artois 33cl</field>
2892- <field name="public_categ_id" ref="pils"/>
2893+ <field name="pos_categ_id" ref="pils"/>
2894 <field name="image" type="base64" file="point_of_sale/static/img/stella_33cl-image.jpg"/>
2895 </record>
2896 <record id="maes_50cl" model="product.product">
2897 <field name="available_in_pos">True</field>
2898 <field name="list_price">0.95</field>
2899 <field name="name">Maes 50cl</field>
2900- <field name="public_categ_id" ref="pils"/>
2901+ <field name="pos_categ_id" ref="pils"/>
2902 <field name="image" type="base64" file="point_of_sale/static/img/maes_50cl-image.jpg"/>
2903 </record>
2904 <record id="maes_33cl" model="product.product">
2905 <field name="available_in_pos">True</field>
2906 <field name="list_price">0.77</field>
2907 <field name="name">Maes 33cl</field>
2908- <field name="public_categ_id" ref="pils"/>
2909+ <field name="pos_categ_id" ref="pils"/>
2910 <field name="image" type="base64" file="point_of_sale/static/img/maes_33cl-image.jpg"/>
2911 </record>
2912 <record id="jupiler_50cl" model="product.product">
2913 <field name="available_in_pos">True</field>
2914 <field name="list_price">0.97</field>
2915 <field name="name">Jupiler 50cl</field>
2916- <field name="public_categ_id" ref="pils"/>
2917+ <field name="pos_categ_id" ref="pils"/>
2918 <field name="image" type="base64" file="point_of_sale/static/img/jupiler_50cl-image.jpg"/>
2919 </record>
2920 <record id="jupiler_33cl" model="product.product">
2921@@ -838,7 +839,7 @@
2922 <field name="list_price">0.77</field>
2923 <field name="ean13">5410228142027</field>
2924 <field name="name">Jupiler 33cl</field>
2925- <field name="public_categ_id" ref="pils"/>
2926+ <field name="pos_categ_id" ref="pils"/>
2927 <field name="image" type="base64" file="point_of_sale/static/img/jupiler_33cl-image.jpg"/>
2928 </record>
2929
2930@@ -846,49 +847,49 @@
2931 <field name="available_in_pos">True</field>
2932 <field name="list_price">2.53</field>
2933 <field name="name">Boon Framboise 37.5cl</field>
2934- <field name="public_categ_id" ref="fruity_beers"/>
2935+ <field name="pos_categ_id" ref="fruity_beers"/>
2936 <field name="image" type="base64" file="point_of_sale/static/img/boon_framboise_37,5cl-image.jpg"/>
2937 </record>
2938 <record id="timmermans_geuze_37,5cl" model="product.product">
2939 <field name="available_in_pos">True</field>
2940 <field name="list_price">1.54</field>
2941 <field name="name">Timmermans Geuze 37.5cl</field>
2942- <field name="public_categ_id" ref="fruity_beers"/>
2943+ <field name="pos_categ_id" ref="fruity_beers"/>
2944 <field name="image" type="base64" file="point_of_sale/static/img/timmermans_geuze_37,5cl-image.jpg"/>
2945 </record>
2946 <record id="timmermans_kriek_37,5cl" model="product.product">
2947 <field name="available_in_pos">True</field>
2948 <field name="list_price">1.7</field>
2949 <field name="name">Timmermans Kriek 37.5cl</field>
2950- <field name="public_categ_id" ref="fruity_beers"/>
2951+ <field name="pos_categ_id" ref="fruity_beers"/>
2952 <field name="image" type="base64" file="point_of_sale/static/img/timmermans_kriek_37,5cl-image.jpg"/>
2953 </record>
2954 <record id="timmermans_faro_37,5cl" model="product.product">
2955 <field name="available_in_pos">True</field>
2956 <field name="list_price">1.56</field>
2957 <field name="name">Timmermans Faro 37.5cl</field>
2958- <field name="public_categ_id" ref="fruity_beers"/>
2959+ <field name="pos_categ_id" ref="fruity_beers"/>
2960 <field name="image" type="base64" file="point_of_sale/static/img/timmermans_faro_37,5cl-image.jpg"/>
2961 </record>
2962 <record id="lindemans_pecheresse_37,,5cl" model="product.product">
2963 <field name="available_in_pos">True</field>
2964 <field name="list_price">1.94</field>
2965 <field name="name">Lindemans sinful 37.5cl</field>
2966- <field name="public_categ_id" ref="fruity_beers"/>
2967+ <field name="pos_categ_id" ref="fruity_beers"/>
2968 <field name="image" type="base64" file="point_of_sale/static/img/lindemans_pecheresse_37,,5cl-image.jpg"/>
2969 </record>
2970 <record id="lindemans_kriek_37,5cl" model="product.product">
2971 <field name="available_in_pos">True</field>
2972 <field name="list_price">1.51</field>
2973 <field name="name">Lindemans Kriek 37.5cl</field>
2974- <field name="public_categ_id" ref="fruity_beers"/>
2975+ <field name="pos_categ_id" ref="fruity_beers"/>
2976 <field name="image" type="base64" file="point_of_sale/static/img/lindemans_kriek_37,5cl-image.jpg"/>
2977 </record>
2978 <record id="grisette_cerise_25cl" model="product.product">
2979 <field name="available_in_pos">True</field>
2980 <field name="list_price">1.04</field>
2981 <field name="name">Grisette Cherry 25cl</field>
2982- <field name="public_categ_id" ref="fruity_beers"/>
2983+ <field name="pos_categ_id" ref="fruity_beers"/>
2984 <field name="image" type="base64" file="point_of_sale/static/img/grisette_cerise_25cl-image.jpg"/>
2985 </record>
2986 <record id="belle_vue_kriek_25cl" model="product.product">
2987@@ -896,7 +897,7 @@
2988 <field name="list_price">0.83</field>
2989 <field name="name">Belle-Vue Kriek 25cl</field>
2990 <field name='ean13'>5410228193449</field>
2991- <field name="public_categ_id" ref="fruity_beers"/>
2992+ <field name="pos_categ_id" ref="fruity_beers"/>
2993 <field name="image" type="base64" file="point_of_sale/static/img/belle_vue_kriek_25cl-image.jpg"/>
2994 </record>
2995
2996@@ -905,7 +906,7 @@
2997 <field name="list_price">1.00</field>
2998 <field name="name">Leffe Brune 33cl</field>
2999 <field name='ean13'>5410228142164</field>
3000- <field name="public_categ_id" ref="special_beers"/>
3001+ <field name="pos_categ_id" ref="special_beers"/>
3002 <field name="image" type="base64" file="point_of_sale/static/img/leffe_brune_33cl-image.jpg"/>
3003 </record>
3004 <record id="leffe_blonde_33cl" model="product.product">
3005@@ -913,49 +914,49 @@
3006 <field name="list_price">1.00</field>
3007 <field name="name">Leffe Blonde 33cl</field>
3008 <field name='ean13'>5410228142218</field>
3009- <field name="public_categ_id" ref="special_beers"/>
3010+ <field name="pos_categ_id" ref="special_beers"/>
3011 <field name="image" type="base64" file="point_of_sale/static/img/leffe_blonde_33cl-image.jpg"/>
3012 </record>
3013 <record id="leffe_9_33cl" model="product.product">
3014 <field name="available_in_pos">True</field>
3015 <field name="list_price">1.16</field>
3016 <field name="name">Leffe Brune "9" 33cl</field>
3017- <field name="public_categ_id" ref="special_beers"/>
3018+ <field name="pos_categ_id" ref="special_beers"/>
3019 <field name="image" type="base64" file="point_of_sale/static/img/leffe_9_33cl-image.jpg"/>
3020 </record>
3021 <record id="orval_33cl" model="product.product">
3022 <field name="available_in_pos">True</field>
3023 <field name="list_price">1.59</field>
3024 <field name="name">Orval 33cl</field>
3025- <field name="public_categ_id" ref="special_beers"/>
3026+ <field name="pos_categ_id" ref="special_beers"/>
3027 <field name="image" type="base64" file="point_of_sale/static/img/orval_33cl-image.jpg"/>
3028 </record>
3029 <record id="rochefort_8_33cl" model="product.product">
3030 <field name="available_in_pos">True</field>
3031 <field name="list_price">1.75</field>
3032 <field name="name">Rochefort "8" 33cl</field>
3033- <field name="public_categ_id" ref="special_beers"/>
3034+ <field name="pos_categ_id" ref="special_beers"/>
3035 <field name="image" type="base64" file="point_of_sale/static/img/rochefort_8_33cl-image.jpg"/>
3036 </record>
3037 <record id="chimay_bleu_33cl" model="product.product">
3038 <field name="available_in_pos">True</field>
3039 <field name="list_price">1.46</field>
3040 <field name="name">Chimay Bleu 33cl</field>
3041- <field name="public_categ_id" ref="special_beers"/>
3042+ <field name="pos_categ_id" ref="special_beers"/>
3043 <field name="image" type="base64" file="point_of_sale/static/img/chimay_bleu_33cl-image.jpg"/>
3044 </record>
3045 <record id="chimay_bleu_75cl" model="product.product">
3046 <field name="available_in_pos">True</field>
3047 <field name="list_price">3.57</field>
3048 <field name="name">Chimay Bleu 75cl</field>
3049- <field name="public_categ_id" ref="special_beers"/>
3050+ <field name="pos_categ_id" ref="special_beers"/>
3051 <field name="image" type="base64" file="point_of_sale/static/img/chimay_bleu_75cl-image.jpg"/>
3052 </record>
3053 <record id="chimay_rouge_33cl" model="product.product">
3054 <field name="available_in_pos">True</field>
3055 <field name="list_price">1.02</field>
3056 <field name="name">Chimay Red 33cl</field>
3057- <field name="public_categ_id" ref="special_beers"/>
3058+ <field name="pos_categ_id" ref="special_beers"/>
3059 <field name="image" type="base64" file="point_of_sale/static/img/chimay_rouge_33cl-image.jpg"/>
3060 </record>
3061
3062@@ -963,84 +964,84 @@
3063 <field name="available_in_pos">True</field>
3064 <field name="list_price">2.86</field>
3065 <field name="name">Dr. Oetker Ristorante Mozzarella</field>
3066- <field name="public_categ_id" ref="pizza"/>
3067+ <field name="pos_categ_id" ref="pizza"/>
3068 <field name="image" type="base64" file="point_of_sale/static/img/oetker_mozzarella-image.jpg"/>
3069 </record>
3070 <record id="oetker_bolognese" model="product.product">
3071 <field name="available_in_pos">True</field>
3072 <field name="list_price">2.86</field>
3073 <field name="name">Dr. Oetker Ristorante Bolognese</field>
3074- <field name="public_categ_id" ref="pizza"/>
3075+ <field name="pos_categ_id" ref="pizza"/>
3076 <field name="image" type="base64" file="point_of_sale/static/img/oetker_bolognese-image.jpg"/>
3077 </record>
3078 <record id="oetker_funghi" model="product.product">
3079 <field name="available_in_pos">True</field>
3080 <field name="list_price">2.86</field>
3081 <field name="name">Dr. Oetker Ristorante Funghi</field>
3082- <field name="public_categ_id" ref="pizza"/>
3083+ <field name="pos_categ_id" ref="pizza"/>
3084 <field name="image" type="base64" file="point_of_sale/static/img/oetker_funghi-image.jpg"/>
3085 </record>
3086 <record id="oetker_hawaii" model="product.product">
3087 <field name="available_in_pos">True</field>
3088 <field name="list_price">2.86</field>
3089 <field name="name">Dr. Oetker Ristorante Hawaii</field>
3090- <field name="public_categ_id" ref="pizza"/>
3091+ <field name="pos_categ_id" ref="pizza"/>
3092 <field name="image" type="base64" file="point_of_sale/static/img/oetker_hawaii-image.jpg"/>
3093 </record>
3094 <record id="oetker_pollo" model="product.product">
3095 <field name="available_in_pos">True</field>
3096 <field name="list_price">2.86</field>
3097 <field name="name">Dr. Oetker Ristorante Pollo</field>
3098- <field name="public_categ_id" ref="pizza"/>
3099+ <field name="pos_categ_id" ref="pizza"/>
3100 <field name="image" type="base64" file="point_of_sale/static/img/oetker_pollo-image.jpg"/>
3101 </record>
3102 <record id="oetker_prosciutto" model="product.product">
3103 <field name="available_in_pos">True</field>
3104 <field name="list_price">2.86</field>
3105 <field name="name">Dr. Oetker Ristorante Prosciutto</field>
3106- <field name="public_categ_id" ref="pizza"/>
3107+ <field name="pos_categ_id" ref="pizza"/>
3108 <field name="image" type="base64" file="point_of_sale/static/img/oetker_prosciutto-image.jpg"/>
3109 </record>
3110 <record id="oetker_4formaggi" model="product.product">
3111 <field name="available_in_pos">True</field>
3112 <field name="list_price">2.86</field>
3113 <field name="name">Dr. Oetker Ristorante Quattro Formaggi</field>
3114- <field name="public_categ_id" ref="pizza"/>
3115+ <field name="pos_categ_id" ref="pizza"/>
3116 <field name="image" type="base64" file="point_of_sale/static/img/oetker_4formaggi-image.jpg"/>
3117 </record>
3118 <record id="oetker_speciale" model="product.product">
3119 <field name="available_in_pos">True</field>
3120 <field name="list_price">2.86</field>
3121 <field name="name">Dr. Oetker Ristorante Speciale</field>
3122- <field name="public_categ_id" ref="pizza"/>
3123+ <field name="pos_categ_id" ref="pizza"/>
3124 <field name="image" type="base64" file="point_of_sale/static/img/oetker_speciale-image.jpg"/>
3125 </record>
3126 <record id="oetker_spinaci" model="product.product">
3127 <field name="available_in_pos">True</field>
3128 <field name="list_price">2.86</field>
3129 <field name="name">Dr. Oetker Ristorante Spinaci</field>
3130- <field name="public_categ_id" ref="pizza"/>
3131+ <field name="pos_categ_id" ref="pizza"/>
3132 <field name="image" type="base64" file="point_of_sale/static/img/oetker_spinaci-image.jpg"/>
3133 </record>
3134 <record id="oetker_tonno" model="product.product">
3135 <field name="available_in_pos">True</field>
3136 <field name="list_price">2.86</field>
3137 <field name="name">Dr. Oetker Ristorante Tonno</field>
3138- <field name="public_categ_id" ref="pizza"/>
3139+ <field name="pos_categ_id" ref="pizza"/>
3140 <field name="image" type="base64" file="point_of_sale/static/img/oetker_tonno-image.jpg"/>
3141 </record>
3142 <record id="oetker_vegetale" model="product.product">
3143 <field name="available_in_pos">True</field>
3144 <field name="list_price">2.86</field>
3145 <field name="name">Dr. Oetker Ristorante Vegetable</field>
3146- <field name="public_categ_id" ref="pizza"/>
3147+ <field name="pos_categ_id" ref="pizza"/>
3148 <field name="image" type="base64" file="point_of_sale/static/img/oetker_vegetale-image.jpg"/>
3149 </record>
3150 <record id="oetker_margherita" model="product.product">
3151 <field name="available_in_pos">True</field>
3152 <field name="list_price">2.67</field>
3153 <field name="name">Dr. Oetker La Margherita</field>
3154- <field name="public_categ_id" ref="pizza"/>
3155+ <field name="pos_categ_id" ref="pizza"/>
3156 <field name="image" type="base64" file="point_of_sale/static/img/oetker_margherita-image.jpg"/>
3157 </record>
3158
3159@@ -1048,42 +1049,42 @@
3160 <field name="available_in_pos">True</field>
3161 <field name="list_price">0.33</field>
3162 <field name="name">Croky Paprika 45g</field>
3163- <field name="public_categ_id" ref="chips"/>
3164+ <field name="pos_categ_id" ref="chips"/>
3165 <field name="image" type="base64" file="point_of_sale/static/img/croky_paprika_45g-image.jpg"/>
3166 </record>
3167 <record id="croky_naturel_45g" model="product.product">
3168 <field name="available_in_pos">True</field>
3169 <field name="list_price">0.39</field>
3170 <field name="name">Croky Natural 45g</field>
3171- <field name="public_categ_id" ref="chips"/>
3172+ <field name="pos_categ_id" ref="chips"/>
3173 <field name="image" type="base64" file="point_of_sale/static/img/croky_naturel_45g-image.jpg"/>
3174 </record>
3175 <record id="croky_bolognaise_250g" model="product.product">
3176 <field name="available_in_pos">True</field>
3177 <field name="list_price">1.78</field>
3178 <field name="name">Croky Bolognese 250g</field>
3179- <field name="public_categ_id" ref="chips"/>
3180+ <field name="pos_categ_id" ref="chips"/>
3181 <field name="image" type="base64" file="point_of_sale/static/img/croky_bolognaise_250g-image.jpg"/>
3182 </record>
3183 <record id="lays_pickles_250g" model="product.product">
3184 <field name="available_in_pos">True</field>
3185 <field name="list_price">1.48</field>
3186 <field name="name">250g Lays Pickels</field>
3187- <field name="public_categ_id" ref="chips"/>
3188+ <field name="pos_categ_id" ref="chips"/>
3189 <field name="image" type="base64" file="point_of_sale/static/img/lays_pickles_250g-image.jpg"/>
3190 </record>
3191 <record id="lays_ketchup_250g" model="product.product">
3192 <field name="available_in_pos">True</field>
3193 <field name="list_price">1.48</field>
3194 <field name="name">Lays Ketchup 250g</field>
3195- <field name="public_categ_id" ref="chips"/>
3196+ <field name="pos_categ_id" ref="chips"/>
3197 <field name="image" type="base64" file="point_of_sale/static/img/lays_ketchup_250g-image.jpg"/>
3198 </record>
3199 <record id="lays_poivre_sel_oven_150g" model="product.product">
3200 <field name="available_in_pos">True</field>
3201 <field name="list_price">1.58</field>
3202 <field name="name">Lays Salt and Pepper Oven Baked 150g</field>
3203- <field name="public_categ_id" ref="chips"/>
3204+ <field name="pos_categ_id" ref="chips"/>
3205 <field name="image" type="base64" file="point_of_sale/static/img/lays_poivre_sel_oven_150g-image.jpg"/>
3206 </record>
3207
3208@@ -1091,35 +1092,35 @@
3209 <field name="available_in_pos">True</field>
3210 <field name="list_price">1.54</field>
3211 <field name="name">Oven Baked Lays Paprika 150g</field>
3212- <field name="public_categ_id" ref="chips"/>
3213+ <field name="pos_categ_id" ref="chips"/>
3214 <field name="image" type="base64" file="point_of_sale/static/img/lays_paprika_oven_150g-image.jpg"/>
3215 </record>
3216 <record id="lays_paprika_300g" model="product.product">
3217 <field name="available_in_pos">True</field>
3218 <field name="list_price">1.55</field>
3219 <field name="name">Lays Paprika XXL 300g</field>
3220- <field name="public_categ_id" ref="chips"/>
3221+ <field name="pos_categ_id" ref="chips"/>
3222 <field name="image" type="base64" file="point_of_sale/static/img/lays_paprika_300g-image.jpg"/>
3223 </record>
3224 <record id="lays_paprika_170g" model="product.product">
3225 <field name="available_in_pos">True</field>
3226 <field name="list_price">1.48</field>
3227 <field name="name">Lays Light Paprika 170g</field>
3228- <field name="public_categ_id" ref="chips"/>
3229+ <field name="pos_categ_id" ref="chips"/>
3230 <field name="image" type="base64" file="point_of_sale/static/img/lays_paprika_170g-image.jpg"/>
3231 </record>
3232 <record id="lays_light_paprika_170g" model="product.product">
3233 <field name="available_in_pos">True</field>
3234 <field name="list_price">1.48</field>
3235 <field name="name">Lays Light Paprika 170g</field>
3236- <field name="public_categ_id" ref="chips"/>
3237+ <field name="pos_categ_id" ref="chips"/>
3238 <field name="image" type="base64" file="point_of_sale/static/img/lays_light_paprika_170g-image.jpg"/>
3239 </record>
3240 <record id="lays_paprika_45g" model="product.product">
3241 <field name="available_in_pos">True</field>
3242 <field name="list_price">0.39</field>
3243 <field name="name">Lays Paprika 45g</field>
3244- <field name="public_categ_id" ref="chips"/>
3245+ <field name="pos_categ_id" ref="chips"/>
3246 <field name="image" type="base64" file="point_of_sale/static/img/lays_paprika_45g-image.jpg"/>
3247 </record>
3248
3249@@ -1127,35 +1128,35 @@
3250 <field name="available_in_pos">True</field>
3251 <field name="list_price">1.54</field>
3252 <field name="name">Oven Baked Lays Natural 150g</field>
3253- <field name="public_categ_id" ref="chips"/>
3254+ <field name="pos_categ_id" ref="chips"/>
3255 <field name="image" type="base64" file="point_of_sale/static/img/lays_naturel_oven_150g-image.jpg"/>
3256 </record>
3257 <record id="lays_naturel_300g" model="product.product">
3258 <field name="available_in_pos">True</field>
3259 <field name="list_price">1.55</field>
3260 <field name="name">Lays Natural XXL 300g</field>
3261- <field name="public_categ_id" ref="chips"/>
3262+ <field name="pos_categ_id" ref="chips"/>
3263 <field name="image" type="base64" file="point_of_sale/static/img/lays_naturel_300g-image.jpg"/>
3264 </record>
3265 <record id="lays_naturel_170g" model="product.product">
3266 <field name="available_in_pos">True</field>
3267 <field name="list_price">1.48</field>
3268 <field name="name">Lays Natural Light 170g</field>
3269- <field name="public_categ_id" ref="chips"/>
3270+ <field name="pos_categ_id" ref="chips"/>
3271 <field name="image" type="base64" file="point_of_sale/static/img/lays_naturel_170g-image.jpg"/>
3272 </record>
3273 <record id="lays_light_naturel_170g" model="product.product">
3274 <field name="available_in_pos">True</field>
3275 <field name="list_price">1.48</field>
3276 <field name="name">Lays Natural Light 170g</field>
3277- <field name="public_categ_id" ref="chips"/>
3278+ <field name="pos_categ_id" ref="chips"/>
3279 <field name="image" type="base64" file="point_of_sale/static/img/lays_light_naturel_170g-image.jpg"/>
3280 </record>
3281 <record id="lays_naturel_45g" model="product.product">
3282 <field name="available_in_pos">True</field>
3283 <field name="list_price">0.39</field>
3284 <field name="name">Lays Natural 45g</field>
3285- <field name="public_categ_id" ref="chips"/>
3286+ <field name="pos_categ_id" ref="chips"/>
3287 <field name="image" type="base64" file="point_of_sale/static/img/lays_naturel_45g-image.jpg"/>
3288 </record>
3289
3290@@ -1163,35 +1164,35 @@
3291 <field name="available_in_pos">True</field>
3292 <field name="list_price">7.60</field>
3293 <field name="name">IJsboerke Chocolat 2.5L</field>
3294- <field name="public_categ_id" ref="ice_cream"/>
3295+ <field name="pos_categ_id" ref="ice_cream"/>
3296 <field name="image" type="base64" file="point_of_sale/static/img/ijsboerke_chocolat_2,5l-image.jpg"/>
3297 </record>
3298 <record id="ijsboerke_moka_2,5l" model="product.product">
3299 <field name="available_in_pos">True</field>
3300 <field name="list_price">7.60</field>
3301 <field name="name">IJsboerke Mocha 2.5L</field>
3302- <field name="public_categ_id" ref="ice_cream"/>
3303+ <field name="pos_categ_id" ref="ice_cream"/>
3304 <field name="image" type="base64" file="point_of_sale/static/img/ijsboerke_moka_2,5l-image.jpg"/>
3305 </record>
3306 <record id="ijsboerke_vanille_2,5l" model="product.product">
3307 <field name="available_in_pos">True</field>
3308 <field name="list_price">7.40</field>
3309 <field name="name">IJsboerke Vanilla 2.5L</field>
3310- <field name="public_categ_id" ref="ice_cream"/>
3311+ <field name="pos_categ_id" ref="ice_cream"/>
3312 <field name="image" type="base64" file="point_of_sale/static/img/ijsboerke_vanille_2,5l-image.jpg"/>
3313 </record>
3314 <record id="ijsboerke_stracciatella_2,5l" model="product.product">
3315 <field name="available_in_pos">True</field>
3316 <field name="list_price">8.40</field>
3317 <field name="name">IJsboerke Stracciatella 2.5L</field>
3318- <field name="public_categ_id" ref="ice_cream"/>
3319+ <field name="pos_categ_id" ref="ice_cream"/>
3320 <field name="image" type="base64" file="point_of_sale/static/img/ijsboerke_stracciatella_2,5l-image.jpg"/>
3321 </record>
3322 <record id="ijsboerke_dame_blanche_2,5l" model="product.product">
3323 <field name="available_in_pos">True</field>
3324 <field name="list_price">7.60</field>
3325 <field name="name">IJsboerke 2.5L White Lady</field>
3326- <field name="public_categ_id" ref="ice_cream"/>
3327+ <field name="pos_categ_id" ref="ice_cream"/>
3328 <field name="image" type="base64" file="point_of_sale/static/img/ijsboerke_dame_blanche_2,5l-image.jpg"/>
3329 </record>
3330
3331
3332=== modified file 'point_of_sale/point_of_sale_view.xml'
3333--- point_of_sale/point_of_sale_view.xml 2014-05-07 18:29:17 +0000
3334+++ point_of_sale/point_of_sale_view.xml 2014-05-26 16:10:21 +0000
3335@@ -477,13 +477,68 @@
3336
3337
3338
3339- <record id="product_normal_form_view" model="ir.ui.view">
3340- <field name="name">product.normal.form.inherit</field>
3341- <field name="model">product.product</field>
3342- <field name="inherit_id" ref="stock.view_normal_procurement_locations_form"/>
3343- <field name="arch" type="xml">
3344- <group name="sale" position="inside">
3345+ <!-- Product Public Categories -->
3346+ <record id="product_pos_category_form_view" model="ir.ui.view">
3347+ <field name="name">pos.category.form</field>
3348+ <field name="model">pos.category</field>
3349+ <field name="arch" type="xml">
3350+ <form string="Pos Categories" version="7.0">
3351+ <sheet>
3352+ <field name="image_medium" widget='image' class="oe_avatar oe_right"/>
3353+ <div class="oe_left">
3354+ <group>
3355+ <field name="name"/>
3356+ <field name="parent_id"/>
3357+ <field name="sequence"/>
3358+ </group>
3359+ </div>
3360+ </sheet>
3361+ </form>
3362+ </field>
3363+ </record>
3364+ <record id="product_pos_category_tree_view" model="ir.ui.view">
3365+ <field name="name">pos.category.tree</field>
3366+ <field name="model">pos.category</field>
3367+ <field name="field_parent" eval="False"/>
3368+ <field name="arch" type="xml">
3369+ <tree string="Product Product Categories">
3370+ <field name="sequence" invisible="1"/>
3371+ <field name="complete_name"/>
3372+ </tree>
3373+ </field>
3374+ </record>
3375+ <record id="product_pos_category_action" model="ir.actions.act_window">
3376+ <field name="name">Pos Product Categories</field>
3377+ <field name="type">ir.actions.act_window</field>
3378+ <field name="res_model">pos.category</field>
3379+ <field name="view_type">form</field>
3380+ <field name="view_mode">tree,form</field>
3381+ <field name="view_id" eval="False"/>
3382+ <field name="help" type="html">
3383+ <p class="oe_view_nocontent_create">
3384+ Click to define a new category.
3385+ </p><p>
3386+ Categories are used to browse your products through the
3387+ touchscreen interface.
3388+ </p><p>
3389+ If you put a photo on the category, the layout of the
3390+ touchscreen interface will automatically. We suggest not to put
3391+ a photo on categories for small (1024x768) screens.
3392+ </p>
3393+ </field>
3394+ </record>
3395+ <menuitem action="product_pos_category_action" id="menu_product_pos_category" parent="menu_point_of_sale_product" sequence="0" />
3396+ <!-- END -->
3397+
3398+
3399+ <record id="product_template_form_view" model="ir.ui.view">
3400+ <field name="name">product.template.form.inherit</field>
3401+ <field name="model">product.template</field>
3402+ <field name="inherit_id" ref="product.product_template_form_view"/>
3403+ <field name="arch" type="xml">
3404+ <group name="website_and_pos" position="inside">
3405 <group name="pos" string="Point of Sale">
3406+ <field name="pos_categ_id"/>
3407 <field name="available_in_pos"/>
3408 <field name="to_weight" />
3409 <field name="income_pdt"/>
3410@@ -495,9 +550,6 @@
3411 </field>
3412 </field>
3413 </record>
3414-
3415- <!-- Categories tree view -->
3416- <menuitem action="product.product_public_category_action" id="menu_product_public_category" parent="menu_point_of_sale_product" sequence="0" />
3417 <!-- END -->
3418
3419 <menuitem name="Configuration" parent="menu_point_root"
3420
3421=== modified file 'point_of_sale/security/ir.model.access.csv'
3422--- point_of_sale/security/ir.model.access.csv 2014-02-03 17:30:00 +0000
3423+++ point_of_sale/security/ir.model.access.csv 2014-05-26 16:10:21 +0000
3424@@ -57,5 +57,5 @@
3425 access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0
3426 access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0
3427 access_ir_sequence_manager,ir.sequence manager,base.model_ir_sequence,group_pos_manager,1,1,1,1
3428-access_product_category_pos_manager,product.public.category manager,product.model_product_public_category,group_pos_manager,1,1,1,1
3429-access_product_category_pos_user,product.public.category user,product.model_product_public_category,group_pos_user,1,0,0,0
3430+access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1
3431+access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0
3432
3433=== modified file 'point_of_sale/static/src/js/db.js'
3434--- point_of_sale/static/src/js/db.js 2014-01-27 16:10:05 +0000
3435+++ point_of_sale/static/src/js/db.js 2014-05-26 16:10:21 +0000
3436@@ -145,7 +145,7 @@
3437 for(var i = 0, len = products.length; i < len; i++){
3438 var product = products[i];
3439 var search_string = this._product_search_string(product);
3440- var categ_id = product.public_categ_id ? product.public_categ_id[0] : this.root_category_id;
3441+ var categ_id = product.pos_categ_id ? product.pos_categ_id[0] : this.root_category_id;
3442 if(!stored_categories[categ_id]){
3443 stored_categories[categ_id] = [];
3444 }
3445
3446=== modified file 'point_of_sale/static/src/js/models.js'
3447--- point_of_sale/static/src/js/models.js 2014-03-28 14:57:10 +0000
3448+++ point_of_sale/static/src/js/models.js 2014-05-26 16:10:21 +0000
3449@@ -208,13 +208,13 @@
3450 }).then(function(packagings){
3451 self.db.add_packagings(packagings);
3452
3453- return self.fetch('product.public.category', ['id','name','parent_id','child_id','image'])
3454+ return self.fetch('pos.category', ['id','name','parent_id','child_id','image'])
3455 }).then(function(categories){
3456 self.db.add_categories(categories);
3457
3458 return self.fetch(
3459 'product.product',
3460- ['name', 'list_price','price','public_categ_id', 'taxes_id', 'ean13', 'default_code',
3461+ ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code',
3462 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'],
3463 [['sale_ok','=',true],['available_in_pos','=',true]],
3464 {pricelist: self.pricelist.id} // context for price
3465
3466=== modified file 'point_of_sale/static/src/js/widgets.js'
3467--- point_of_sale/static/src/js/widgets.js 2014-04-25 12:22:20 +0000
3468+++ point_of_sale/static/src/js/widgets.js 2014-05-26 16:10:21 +0000
3469@@ -436,7 +436,7 @@
3470 },
3471
3472 get_image_url: function(category){
3473- return window.location.origin + '/web/binary/image?model=product.public.category&field=image_medium&id='+category.id;
3474+ return window.location.origin + '/web/binary/image?model=pos.category&field=image_medium&id='+category.id;
3475 },
3476
3477 render_category: function( category, with_image ){
3478
3479=== modified file 'product/pricelist.py'
3480--- product/pricelist.py 2014-03-17 12:01:26 +0000
3481+++ product/pricelist.py 2014-05-26 16:10:21 +0000
3482@@ -188,10 +188,13 @@
3483
3484 products = map(lambda x: x[0], products_by_qty_by_partner)
3485 currency_obj = self.pool.get('res.currency')
3486- product_obj = self.pool.get('product.product')
3487+ product_obj = self.pool.get('product.template')
3488 product_uom_obj = self.pool.get('product.uom')
3489 price_type_obj = self.pool.get('product.price.type')
3490
3491+ if not products:
3492+ return {}
3493+
3494 version = False
3495 for v in pricelist.version_id:
3496 if ((v.date_start is False) or (v.date_start <= date)) and ((v.date_end is False) or (v.date_end >= date)):
3497@@ -207,8 +210,13 @@
3498 categ = categ.parent_id
3499 categ_ids = categ_ids.keys()
3500
3501- prod_ids = [x.id for x in products]
3502- prod_tmpl_ids = [x.product_tmpl_id.id for x in products]
3503+ is_product_template = products[0]._name == "product.template"
3504+ if is_product_template:
3505+ prod_tmpl_ids = [tmpl.id for tmpl in products]
3506+ prod_ids = [product.id for product in tmpl.product_variant_ids for tmpl in products]
3507+ else:
3508+ prod_ids = [product.id for product in products]
3509+ prod_tmpl_ids = [product.product_tmpl_id.id for product in products]
3510
3511 # Load all rules
3512 cr.execute(
3513@@ -234,10 +242,17 @@
3514 for rule in items:
3515 if rule.min_quantity and qty<rule.min_quantity:
3516 continue
3517- if rule.product_tmpl_id and product.product_tmpl_id.id<>rule.product_tmpl_id.id:
3518- continue
3519- if rule.product_id and product.id<>rule.product_id.id:
3520- continue
3521+ if is_product_template:
3522+ if rule.product_tmpl_id and product.id<>rule.product_tmpl_id.id:
3523+ continue
3524+ if rule.product_id:
3525+ continue
3526+ else:
3527+ if rule.product_tmpl_id and product.product_tmpl_id.id<>rule.product_tmpl_id.id:
3528+ continue
3529+ if rule.product_id and product.id<>rule.product_id.id:
3530+ continue
3531+
3532 if rule.categ_id:
3533 cat = product.categ_id
3534 while cat:
3535
3536=== modified file 'product/product.py'
3537--- product/product.py 2014-05-09 07:33:15 +0000
3538+++ product/product.py 2014-05-26 16:10:21 +0000
3539@@ -29,6 +29,7 @@
3540 from openerp.osv import osv, fields
3541 from openerp.tools.translate import _
3542 from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
3543+import psycopg2
3544
3545 import openerp.addons.decimal_precision as dp
3546
3547@@ -316,69 +317,78 @@
3548 }
3549
3550
3551-class product_public_category(osv.osv):
3552- _name = "product.public.category"
3553- _description = "Public Category"
3554- _order = "sequence, name"
3555-
3556- _constraints = [
3557- (osv.osv._check_recursion, 'Error ! You cannot create recursive categories.', ['parent_id'])
3558- ]
3559-
3560- def name_get(self, cr, uid, ids, context=None):
3561- if not len(ids):
3562- return []
3563- reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)
3564- res = []
3565- for record in reads:
3566- name = record['name']
3567- if record['parent_id']:
3568- name = record['parent_id'][1]+' / '+name
3569- res.append((record['id'], name))
3570- return res
3571-
3572- def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
3573- res = self.name_get(cr, uid, ids, context=context)
3574- return dict(res)
3575-
3576- def _get_image(self, cr, uid, ids, name, args, context=None):
3577- result = dict.fromkeys(ids, False)
3578+#----------------------------------------------------------
3579+# Attributes / Variants
3580+#----------------------------------------------------------
3581+class product_attribute(osv.osv):
3582+ _name = "product.attribute"
3583+ _description = "Product Attribute"
3584+ _columns = {
3585+ 'name': fields.char('Name', translate=True, required=True),
3586+ 'value_ids': fields.one2many('product.attribute.value', 'attribute_id', 'Values'),
3587+ }
3588+
3589+class product_attribute_value(osv.osv):
3590+ _name = "product.attribute.value"
3591+ _order = 'sequence'
3592+ def _get_price_extra(self, cr, uid, ids, name, args, context=None):
3593+ result = dict.fromkeys(ids, 0)
3594+ if not context.get('active_id'):
3595+ return result
3596+
3597 for obj in self.browse(cr, uid, ids, context=context):
3598- result[obj.id] = tools.image_get_resized_images(obj.image)
3599+ for price_id in obj.price_ids:
3600+ if price_id.product_tmpl_id.id == context.get('active_id'):
3601+ result[obj.id] = price_id.price_extra
3602+ break
3603 return result
3604-
3605- def _set_image(self, cr, uid, id, name, value, args, context=None):
3606- return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
3607-
3608- _columns = {
3609- 'name': fields.char('Name', required=True, translate=True),
3610- 'complete_name': fields.function(_name_get_fnc, type="char", string='Name'),
3611- 'parent_id': fields.many2one('product.public.category','Parent Category', select=True),
3612- 'child_id': fields.one2many('product.public.category', 'parent_id', string='Children Categories'),
3613- 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
3614-
3615- # NOTE: there is no 'default image', because by default we don't show thumbnails for categories. However if we have a thumbnail
3616- # for at least one category, then we display a default image on the other, so that the buttons have consistent styling.
3617- # In this case, the default image is set by the js code.
3618- # NOTE2: image: all image fields are base64 encoded and PIL-supported
3619- 'image': fields.binary("Image",
3620- help="This field holds the image used as image for the cateogry, limited to 1024x1024px."),
3621- 'image_medium': fields.function(_get_image, fnct_inv=_set_image,
3622- string="Medium-sized image", type="binary", multi="_get_image",
3623- store={
3624- 'product.public.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
3625- },
3626- help="Medium-sized image of the category. It is automatically "\
3627- "resized as a 128x128px image, with aspect ratio preserved. "\
3628- "Use this field in form views or some kanban views."),
3629- 'image_small': fields.function(_get_image, fnct_inv=_set_image,
3630- string="Smal-sized image", type="binary", multi="_get_image",
3631- store={
3632- 'product.public.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
3633- },
3634- help="Small-sized image of the category. It is automatically "\
3635- "resized as a 64x64px image, with aspect ratio preserved. "\
3636- "Use this field anywhere a small image is required."),
3637+
3638+ def _set_price_extra(self, cr, uid, id, name, value, args, context=None):
3639+ if 'active_id' not in context:
3640+ return None
3641+ p_obj = self.pool['product.attribute.price']
3642+ p_ids = p_obj.search(cr, uid, [('value_id', '=', id), ('product_tmpl_id', '=', context['active_id'])], context=context)
3643+ if p_ids:
3644+ p_obj.write(cr, uid, p_ids, {'price_extra': value}, context=context)
3645+ else:
3646+ p_obj.create(cr, uid, p_ids, {
3647+ 'product_tmpl_id': context['active_id'],
3648+ 'value_id': id,
3649+ 'price_extra': value,
3650+ }, context=context)
3651+
3652+ _columns = {
3653+ 'sequence': fields.integer('Sequence', help="Determine the display order"),
3654+ 'name': fields.char('Value', translate=True, required=True),
3655+ 'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
3656+ 'product_ids': fields.many2many('product.product', id1='att_id', id2='prod_id', string='Variants', readonly=True),
3657+ 'price_extra': fields.function(_get_price_extra, type='float', string='Variant Price Extra',
3658+ fnct_inv=_set_price_extra,
3659+ digits_compute=dp.get_precision('Product Price'),
3660+ help="Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200."),
3661+ 'price_ids': fields.one2many('product.attribute.price', 'value_id', string='Variant Prices', readonly=True),
3662+ }
3663+ _sql_constraints = [
3664+ ('value_company_uniq', 'unique (name,attribute_id)', 'This attribute value already exists !')
3665+ ]
3666+ _defaults = {
3667+ 'price_extra': lambda *a: 0.0,
3668+ }
3669+
3670+class product_attribute_price(osv.osv):
3671+ _name = "product.attribute.price"
3672+ _columns = {
3673+ 'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True),
3674+ 'value_id': fields.many2one('product.attribute.value', 'Product Attribute Value', required=True),
3675+ 'price_extra': fields.float('Price Extra', digits_compute=dp.get_precision('Product Price')),
3676+ }
3677+
3678+class product_attribute_line(osv.osv):
3679+ _name = "product.attribute.line"
3680+ _columns = {
3681+ 'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True),
3682+ 'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
3683+ 'value_ids': fields.many2many('product.attribute.value', id1='line_id', id2='val_id', string='Product Attribute Value'),
3684 }
3685
3686
3687@@ -399,6 +409,38 @@
3688 def _set_image(self, cr, uid, id, name, value, args, context=None):
3689 return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
3690
3691+ def _is_product_variant(self, cr, uid, ids, name, arg, context=None):
3692+ prod = self.pool.get('product.product')
3693+ res = dict.fromkeys(ids, False)
3694+ ctx = dict(context, active_test=True)
3695+ for product in self.browse(cr, uid, ids, context=context):
3696+ res[product.id] = prod.search(cr, uid, [('product_tmpl_id','=',product.id)], context=ctx, count=True) == 1
3697+ return res
3698+
3699+ def _product_template_price(self, cr, uid, ids, name, arg, context=None):
3700+ plobj = self.pool.get('product.pricelist')
3701+ res = {}
3702+ quantity = context.get('quantity') or 1.0
3703+ pricelist = context.get('pricelist', False)
3704+ partner = context.get('partner', False)
3705+ if pricelist:
3706+ # Support context pricelists specified as display_name or ID for compatibility
3707+ if isinstance(pricelist, basestring):
3708+ pricelist_ids = plobj.name_search(
3709+ cr, uid, pricelist, operator='=', context=context, limit=1)
3710+ pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
3711+
3712+ if isinstance(pricelist, (int, long)):
3713+ products = self.browse(cr, uid, ids, context=context)
3714+ qtys = map(lambda x: (x, quantity, partner), products)
3715+ pl = plobj.browse(cr, uid, pricelist, context=context)
3716+ price = plobj._price_get_multi(cr,uid, pl, qtys, context=context)
3717+ for id in ids:
3718+ res[id] = price.get(id, 0.0)
3719+ for id in ids:
3720+ res.setdefault(id, 0.0)
3721+ return res
3722+
3723 def get_history_price(self, cr, uid, product_tmpl, company_id, date=None, context=None):
3724 if context is None:
3725 context = {}
3726@@ -421,6 +463,12 @@
3727 'company_id': company_id,
3728 }, context=context)
3729
3730+ def _get_product_variant_count(self, cr, uid, ids, name, arg, context=None):
3731+ res = {}
3732+ for product in self.browse(cr, uid, ids):
3733+ res[product.id] = len(product.product_variant_ids)
3734+ return res
3735+
3736 _columns = {
3737 'name': fields.char('Name', required=True, translate=True, select=True),
3738 'product_manager': fields.many2one('res.users','Product Manager'),
3739@@ -434,9 +482,10 @@
3740 "This description will be copied to every Sale Order, Delivery Order and Customer Invoice/Refund"),
3741 'type': fields.selection([('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Consumable are product where you don't manage stock, a service is a non-material product provided by a company or an individual."),
3742 'rental': fields.boolean('Can be Rent'),
3743- 'categ_id': fields.many2one('product.category','Category', required=True, change_default=True, domain="[('type','=','normal')]" ,help="Select category for the current product"),
3744- 'public_categ_id': fields.many2one('product.public.category','Public Category', help="Those categories are used to group similar products for public sales (eg.: point of sale, e-commerce)."),
3745+ 'categ_id': fields.many2one('product.category','Internal Category', required=True, change_default=True, domain="[('type','=','normal')]" ,help="Select category for the current product"),
3746+ 'price': fields.function(_product_template_price, type='float', string='Price', digits_compute=dp.get_precision('Product Price')),
3747 'list_price': fields.float('Sale Price', digits_compute=dp.get_precision('Product Price'), help="Base price to compute the customer price. Sometimes called the catalog price."),
3748+ 'lst_price' : fields.related('list_price', type="float", string='Public Price', digits_compute=dp.get_precision('Product Price')),
3749 'standard_price': fields.property(type = 'float', digits_compute=dp.get_precision('Product Price'),
3750 help="Cost price of the product template used for standard stock valuation in accounting and used as a base price on purchase orders.",
3751 groups="base.group_user", string="Cost Price"),
3752@@ -445,6 +494,7 @@
3753 'weight_net': fields.float('Net Weight', digits_compute=dp.get_precision('Stock Weight'), help="The net weight in Kg."),
3754 'warranty': fields.float('Warranty'),
3755 'sale_ok': fields.boolean('Can be Sold', help="Specify if the product can be selected in a sales order line."),
3756+ 'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'),
3757 'state': fields.selection([('',''),
3758 ('draft', 'In Development'),
3759 ('sellable','Normal'),
3760@@ -458,13 +508,12 @@
3761 help='Coefficient to convert default Unit of Measure to Unit of Sale\n'
3762 ' uos = uom * coeff'),
3763 'mes_type': fields.selection((('fixed', 'Fixed'), ('variable', 'Variable')), 'Measure Type'),
3764- 'seller_ids': fields.one2many('product.supplierinfo', 'product_tmpl_id', 'Supplier'),
3765 'company_id': fields.many2one('res.company', 'Company', select=1),
3766 # image: all image fields are base64 encoded and PIL-supported
3767 'image': fields.binary("Image",
3768 help="This field holds the image used as image for the product, limited to 1024x1024px."),
3769 'image_medium': fields.function(_get_image, fnct_inv=_set_image,
3770- string="Medium-sized image", type="binary", multi="_get_image",
3771+ string="Medium-sized image", type="binary", multi="_get_image",
3772 store={
3773 'product.template': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
3774 },
3775@@ -479,13 +528,64 @@
3776 help="Small-sized image of the product. It is automatically "\
3777 "resized as a 64x64px image, with aspect ratio preserved. "\
3778 "Use this field anywhere a small image is required."),
3779- 'product_variant_ids': fields.one2many('product.product', 'product_tmpl_id', 'Product Variants', required=True),
3780+
3781+ 'packaging' : fields.one2many('product.packaging', 'product_id', 'Logistical Units',
3782+ help="Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module."),
3783+
3784+ 'seller_ids': fields.one2many('product.supplierinfo', 'product_tmpl_id', 'Supplier'),
3785+ 'seller_delay': fields.related('seller_ids','delay', type='integer', string='Supplier Lead Time',
3786+ help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
3787+ 'seller_qty': fields.related('seller_ids','qty', type='float', string='Supplier Quantity',
3788+ help="This is minimum quantity to purchase from Main Supplier."),
3789+ 'seller_id': fields.related('seller_ids','name', type='many2one', relation='res.partner', string='Main Supplier',
3790+ help="Main Supplier who has highest priority in Supplier List."),
3791+
3792+ 'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the product without removing it."),
3793+ 'color': fields.integer('Color Index'),
3794+ 'is_product_variant': fields.function( _is_product_variant, type='boolean', string='Only one product variant'),
3795+
3796+ 'variant_ids': fields.one2many('product.attribute.line', 'product_tmpl_id', 'Product Variants'),
3797+ 'product_variant_ids': fields.one2many('product.product', 'product_tmpl_id', 'Products', required=True),
3798+ 'product_variant_count': fields.function( _get_product_variant_count, type='integer', string='Product Variant Number'),
3799+
3800+ # related to display product product information if is_product_variant
3801+ 'ean13': fields.related('product_variant_ids', 'ean13', type='char', string='EAN13 Barcode'),
3802+ 'default_code': fields.related('product_variant_ids', 'default_code', type='char', string='Internal Reference'),
3803 }
3804
3805+ def _price_get_list_price(self, product):
3806+ return 0.0
3807+
3808+ def _price_get(self, cr, uid, products, ptype='list_price', context=None):
3809+ if context is None:
3810+ context = {}
3811+
3812+ if 'currency_id' in context:
3813+ pricetype_obj = self.pool.get('product.price.type')
3814+ price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
3815+ price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
3816+
3817+ res = {}
3818+ product_uom_obj = self.pool.get('product.uom')
3819+ for product in products:
3820+ res[product.id] = product[ptype] or 0.0
3821+ if ptype == 'list_price':
3822+ res[product.id] += product._name == "product.product" and product.price_extra or 0.0
3823+ if 'uom' in context:
3824+ uom = product.uom_id or product.uos_id
3825+ res[product.id] = product_uom_obj._compute_price(cr, uid,
3826+ uom.id, res[product.id], context['uom'])
3827+ # Convert from price_type currency to asked one
3828+ if 'currency_id' in context:
3829+ # Take the price_type currency from the product field
3830+ # This is right cause a field cannot be in more than one currency
3831+ res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id,
3832+ context['currency_id'], res[product.id],context=context)
3833+
3834+ return res
3835+
3836 def _get_uom_id(self, cr, uid, *args):
3837- cr.execute('select id from product_uom order by id limit 1')
3838- res = cr.fetchone()
3839- return res and res[0] or False
3840+ return self.pool["product.uom"].search(cr, uid, [], limit=1, order='id')[0]
3841
3842 def _default_category(self, cr, uid, context=None):
3843 if context is None:
3844@@ -505,9 +605,65 @@
3845 return {'value': {'uom_po_id': uom_id}}
3846 return {}
3847
3848+ def create_variant_ids(self, cr, uid, ids, context=None):
3849+ product_obj = self.pool.get("product.product")
3850+ ctx = context and context.copy() or {}
3851+
3852+ if ctx.get("create_product_variant"):
3853+ return None
3854+
3855+ ctx.update(active_test=False, create_product_variant=True)
3856+
3857+ tmpl_ids = self.browse(cr, uid, ids, context=ctx)
3858+ for tmpl_id in tmpl_ids:
3859+
3860+ # list of values combination
3861+ all_variants = [[]]
3862+ for variant_id in tmpl_id.variant_ids:
3863+ if len(variant_id.value_ids) > 1:
3864+ temp_variants = []
3865+ for value_id in variant_id.value_ids:
3866+ for variant in all_variants:
3867+ temp_variants.append(variant + [int(value_id)])
3868+ all_variants = temp_variants
3869+
3870+ # check product
3871+ variants_active_ids = []
3872+ variants_inactive = []
3873+ for product_id in tmpl_id.product_variant_ids:
3874+ variants = map(int,product_id.variant_ids)
3875+ if variants in all_variants:
3876+ variants_active_ids.append(product_id.id)
3877+ all_variants.pop(all_variants.index(variants))
3878+ # TODO all write in same time
3879+ if product_id.active:
3880+ product_id.write({'active': True}, context=ctx)
3881+ else:
3882+ variants_inactive.append(product_id)
3883+
3884+ # create new product
3885+ for variant_ids in all_variants:
3886+ values = {
3887+ 'product_tmpl_id': tmpl_id.id,
3888+ 'variant_ids': [(6, 0, variant_ids)]
3889+ }
3890+ id = product_obj.create(cr, uid, values, context=ctx)
3891+ variants_active_ids.append(id)
3892+
3893+ # unlink or inactive product
3894+ for variant_id in map(int,variants_inactive):
3895+ try:
3896+ with cr.savepoint():
3897+ product_obj.unlink(cr, uid, [variant_id], context=ctx)
3898+ except (psycopg2.Error, osv.except_osv):
3899+ product_obj.write(cr, uid, [variant_id], {'active': False}, context=ctx)
3900+ pass
3901+ return True
3902+
3903 def create(self, cr, uid, vals, context=None):
3904 ''' Store the initial standard price in order to be able to retrieve the cost of a product template for a given date'''
3905 product_template_id = super(product_template, self).create(cr, uid, vals, context=context)
3906+ self.create_variant_ids(cr, uid, [product_template_id], context=context)
3907 self._set_standard_price(cr, uid, product_template_id, vals.get('standard_price', 0.0), context=context)
3908 return product_template_id
3909
3910@@ -524,7 +680,15 @@
3911 if 'standard_price' in vals:
3912 for prod_template_id in ids:
3913 self._set_standard_price(cr, uid, prod_template_id, vals['standard_price'], context=context)
3914- return super(product_template, self).write(cr, uid, ids, vals, context=context)
3915+ if 'active' in vals:
3916+ product_ids = []
3917+ for product in self.browse(cr, uid, ids, context=context):
3918+ product_ids = map(int, product.product_variant_ids)
3919+ self.write(cr, uid, product_ids, {'active': vals.get('active')}, context=context)
3920+ res = super(product_template, self).write(cr, uid, ids, vals, context=context)
3921+ if 'variant_ids' in vals:
3922+ self.create_variant_ids(cr, uid, ids, context=context)
3923+ return res
3924
3925 def copy(self, cr, uid, id, default=None, context=None):
3926 if default is None:
3927@@ -544,6 +708,7 @@
3928 'mes_type': 'fixed',
3929 'categ_id' : _default_category,
3930 'type' : 'consu',
3931+ 'active': lambda *a: 1,
3932 }
3933
3934 def _check_uom(self, cursor, user, ids, context=None):
3935@@ -579,6 +744,32 @@
3936 _inherit = ['mail.thread']
3937 _order = 'default_code,name_template'
3938
3939+ def _product_price(self, cr, uid, ids, name, arg, context=None):
3940+ plobj = self.pool.get('product.pricelist')
3941+ res = {}
3942+ if context is None:
3943+ context = {}
3944+ quantity = context.get('quantity') or 1.0
3945+ pricelist = context.get('pricelist', False)
3946+ partner = context.get('partner', False)
3947+ if pricelist:
3948+ # Support context pricelists specified as display_name or ID for compatibility
3949+ if isinstance(pricelist, basestring):
3950+ pricelist_ids = plobj.name_search(
3951+ cr, uid, pricelist, operator='=', context=context, limit=1)
3952+ pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
3953+
3954+ if isinstance(pricelist, (int, long)):
3955+ products = self.browse(cr, uid, ids, context=context)
3956+ qtys = map(lambda x: (x, quantity, partner), products)
3957+ pl = plobj.browse(cr, uid, pricelist, context=context)
3958+ price = plobj._price_get_multi(cr,uid, pl, qtys, context=context)
3959+ for id in ids:
3960+ res[id] = price.get(id, 0.0)
3961+ for id in ids:
3962+ res.setdefault(id, 0.0)
3963+ return res
3964+
3965 def view_header_get(self, cr, uid, view_id, view_type, context=None):
3966 if context is None:
3967 context = {}
3968@@ -587,37 +778,11 @@
3969 return _('Products: ') + self.pool.get('product.category').browse(cr, uid, context['categ_id'], context=context).name
3970 return res
3971
3972- def _product_price(self, cr, uid, ids, name, arg, context=None):
3973- plobj = self.pool.get('product.pricelist')
3974- res = {}
3975- if context is None:
3976- context = {}
3977- quantity = context.get('quantity') or 1.0
3978- pricelist = context.get('pricelist', False)
3979- partner = context.get('partner', False)
3980- if pricelist:
3981- # Support context pricelists specified as display_name or ID for compatibility
3982- if isinstance(pricelist, basestring):
3983- pricelist_ids = plobj.name_search(
3984- cr, uid, pricelist, operator='=', context=context, limit=1)
3985- pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
3986-
3987- if isinstance(pricelist, (int, long)):
3988- products = self.browse(cr, uid, ids, context=context)
3989- qtys = map(lambda x: (x, quantity, partner), products)
3990- pl = plobj.browse(cr, uid, pricelist, context=context)
3991- price = plobj._price_get_multi(cr,uid, pl, qtys, context=context)
3992- for id in ids:
3993- res[id] = price.get(id, 0.0)
3994- for id in ids:
3995- res.setdefault(id, 0.0)
3996- return res
3997-
3998 def _product_lst_price(self, cr, uid, ids, name, arg, context=None):
3999 res = {}
4000 product_uom_obj = self.pool.get('product.uom')
4001- for id in ids:
4002- res.setdefault(id, 0.0)
4003+ res = dict.fromkeys(ids, 0.0)
4004+
4005 for product in self.browse(cr, uid, ids, context=context):
4006 if 'uom' in context:
4007 uom = product.uos_id or product.uom_id
4008@@ -625,20 +790,17 @@
4009 uom.id, product.list_price, context['uom'])
4010 else:
4011 res[product.id] = product.list_price
4012- res[product.id] = (res[product.id] or 0.0) * (product.price_margin or 1.0) + product.price_extra
4013+ price_extra = 0.0
4014+ for variant_id in product.variant_ids:
4015+ price_extra += variant_id.price_extra
4016+ res[product.id] = (res[product.id] or 0.0) + price_extra
4017 return res
4018
4019- def _save_product_lst_price(self, cr, uid, product_id, field_name, field_value, arg, context=None):
4020- field_value = field_value or 0.0
4021- product = self.browse(cr, uid, product_id, context=context)
4022- list_price = (field_value - product.price_extra) / (product.price_margin or 1.0)
4023- return self.write(cr, uid, [product_id], {'list_price': list_price}, context=context)
4024-
4025 def _get_partner_code_name(self, cr, uid, ids, product, partner_id, context=None):
4026 for supinfo in product.seller_ids:
4027 if supinfo.name.id == partner_id:
4028- return {'code': supinfo.product_code or product.default_code, 'name': supinfo.product_name or product.name, 'variants': ''}
4029- res = {'code': product.default_code, 'name': product.name, 'variants': product.variants}
4030+ return {'code': supinfo.product_code or product.default_code, 'name': supinfo.product_name or product.name}
4031+ res = {'code': product.default_code, 'name': product.name}
4032 return res
4033
4034 def _product_code(self, cr, uid, ids, name, arg, context=None):
4035@@ -655,48 +817,15 @@
4036 context = {}
4037 for p in self.browse(cr, uid, ids, context=context):
4038 data = self._get_partner_code_name(cr, uid, [], p, context.get('partner_id', None), context=context)
4039- if not data['variants']:
4040- data['variants'] = p.variants
4041 if not data['code']:
4042 data['code'] = p.code
4043 if not data['name']:
4044 data['name'] = p.name
4045- res[p.id] = (data['code'] and ('['+data['code']+'] ') or '') + \
4046- (data['name'] or '') + (data['variants'] and (' - '+data['variants']) or '')
4047- return res
4048-
4049- def _is_only_child(self, cr, uid, ids, name, arg, context=None):
4050- res = dict.fromkeys(ids, True)
4051- for product in self.browse(cr, uid, ids, context=context):
4052- if product.product_tmpl_id and len(product.product_tmpl_id.product_variant_ids) > 1:
4053- res[product.id] = False
4054- return res
4055-
4056- def _get_main_product_supplier(self, cr, uid, product, context=None):
4057- """Determines the main (best) product supplier for ``product``,
4058- returning the corresponding ``supplierinfo`` record, or False
4059- if none were found. The default strategy is to select the
4060- supplier with the highest priority (i.e. smallest sequence).
4061-
4062- :param browse_record product: product to supply
4063- :rtype: product.supplierinfo browse_record or False
4064- """
4065- sellers = [(seller_info.sequence, seller_info)
4066- for seller_info in product.seller_ids or []
4067- if seller_info and isinstance(seller_info.sequence, (int, long))]
4068- return sellers and sellers[0][1] or False
4069-
4070- def _calc_seller(self, cr, uid, ids, fields, arg, context=None):
4071- result = {}
4072- for product in self.browse(cr, uid, ids, context=context):
4073- main_supplier = self._get_main_product_supplier(cr, uid, product, context=context)
4074- result[product.id] = {
4075- 'seller_info_id': main_supplier and main_supplier.id or False,
4076- 'seller_delay': main_supplier.delay if main_supplier else 1,
4077- 'seller_qty': main_supplier and main_supplier.qty or 0.0,
4078- 'seller_id': main_supplier and main_supplier.name.id or False
4079- }
4080- return result
4081+ res[p.id] = (data['code'] and ('['+data['code']+'] ') or '') + (data['name'] or '')
4082+ return res
4083+
4084+ def _is_product_variant(self, cr, uid, ids, name, arg, context=None):
4085+ return dict.fromkeys(ids, True)
4086
4087 def _get_name_template_ids(self, cr, uid, ids, context=None):
4088 result = set()
4089@@ -705,39 +834,69 @@
4090 result.add(el)
4091 return list(result)
4092
4093+ def _get_image_variant(self, cr, uid, ids, name, args, context=None):
4094+ result = dict.fromkeys(ids, False)
4095+ for obj in self.browse(cr, uid, ids, context=context):
4096+ result[obj.id] = obj.image_variant or getattr(obj.product_tmpl_id, name)
4097+ return result
4098+
4099+ def _set_image_variant(self, cr, uid, id, name, value, args, context=None):
4100+ image = tools.image_resize_image_big(value)
4101+ res = self.write(cr, uid, [id], {'image_variant': image}, context=context)
4102+ product = self.browse(cr, uid, id, context=context)
4103+ if not product.product_tmpl_id.image:
4104+ product.write({'image_variant': None}, context=context)
4105+ product.product_tmpl_id.write({'image': image}, context=context)
4106+ return res
4107+
4108+ def _get_price_extra(self, cr, uid, ids, name, args, context=None):
4109+ result = dict.fromkeys(ids, False)
4110+ for product in self.browse(cr, uid, ids, context=context):
4111+ price_extra = 0.0
4112+ for variant_id in product.variant_ids:
4113+ for price_id in variant_id.price_ids:
4114+ if price_id.product_tmpl_id.id == product.product_tmpl_id.id:
4115+ price_extra += price_id.price_extra
4116+ result[product.id] = price_extra
4117+ return result
4118+
4119 _columns = {
4120- 'price': fields.function(_product_price, fnct_inv=_save_product_lst_price, type='float', string='Price', digits_compute=dp.get_precision('Product Price')),
4121- 'lst_price' : fields.function(_product_lst_price, fnct_inv=_save_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Product Price')),
4122+ 'price': fields.function(_product_price, type='float', string='Price', digits_compute=dp.get_precision('Product Price')),
4123+ 'price_extra': fields.function(_get_price_extra, type='float', string='Sum of Variant Price Extra'),
4124+ 'lst_price': fields.function(_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Product Price')),
4125 'code': fields.function(_product_code, type='char', string='Internal Reference'),
4126 'partner_ref' : fields.function(_product_partner_ref, type='char', string='Customer ref'),
4127 'default_code' : fields.char('Internal Reference', select=True),
4128 'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the product without removing it."),
4129- 'variants': fields.char('Variants', translate=True),
4130 'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade", select=True),
4131- 'is_only_child': fields.function(
4132- _is_only_child, type='boolean', string='Sole child of the parent template'),
4133 'ean13': fields.char('EAN13 Barcode', size=13, help="International Article Number used for product identification."),
4134+ 'is_product_variant': fields.function( _is_product_variant, type='boolean', string='Only one product variant'),
4135 'packaging': fields.one2many('product.packaging', 'product_id', 'Packaging', help="Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module."),
4136- 'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price'), help="Price Extra: Extra price for the variant on sale price. eg. 200 price extra, 1000 + 200 = 1200."),
4137- 'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Product Price'), help="Price Margin: Margin in percentage amount on sale price for the variant. eg. 10 price margin, 1000 * 1.1 = 1100."),
4138- 'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'),
4139 'name_template': fields.related('product_tmpl_id', 'name', string="Template Name", type='char', store={
4140 'product.template': (_get_name_template_ids, ['name'], 10),
4141 'product.product': (lambda self, cr, uid, ids, c=None: ids, [], 10),
4142 }, select=True),
4143- 'color': fields.integer('Color Index'),
4144- 'seller_info_id': fields.function(_calc_seller, type='many2one', relation="product.supplierinfo", string="Supplier Info", multi="seller_info"),
4145- 'seller_delay': fields.function(_calc_seller, type='integer', string='Supplier Lead Time', multi="seller_info", help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
4146- 'seller_qty': fields.function(_calc_seller, type='float', string='Supplier Quantity', multi="seller_info", help="This is minimum quantity to purchase from Main Supplier."),
4147- 'seller_id': fields.function(_calc_seller, type='many2one', relation="res.partner", string='Main Supplier', help="Main Supplier who has highest priority in Supplier List.", multi="seller_info"),
4148+ 'variant_ids': fields.many2many('product.attribute.value', id1='prod_id', id2='att_id', string='Variants', readonly=True),
4149+
4150+ # image: all image fields are base64 encoded and PIL-supported
4151+ 'image_variant': fields.binary("Variant Image",
4152+ help="This field holds the image used as image for the product variant, limited to 1024x1024px."),
4153+
4154+ 'image': fields.function(_get_image_variant, fnct_inv=_set_image_variant,
4155+ string="Big-sized image", type="binary",
4156+ help="Image of the product variant (Big-sized image of product template if false). It is automatically "\
4157+ "resized as a 1024x1024px image, with aspect ratio preserved."),
4158+ 'image_small': fields.function(_get_image_variant, fnct_inv=_set_image_variant,
4159+ string="Small-sized image", type="binary",
4160+ help="Image of the product variant (Small-sized image of product template if false)."),
4161+ 'image_medium': fields.function(_get_image_variant, fnct_inv=_set_image_variant,
4162+ string="Medium-sized image", type="binary",
4163+ help="Image of the product variant (Medium-sized image of product template if false)."),
4164 }
4165
4166 _defaults = {
4167 'active': lambda *a: 1,
4168- 'price_extra': lambda *a: 0.0,
4169- 'price_margin': lambda *a: 1.0,
4170 'color': 0,
4171- 'is_only_child': True,
4172 }
4173
4174 def unlink(self, cr, uid, ids, context=None):
4175@@ -767,8 +926,9 @@
4176
4177 def _check_ean_key(self, cr, uid, ids, context=None):
4178 for product in self.read(cr, uid, ids, ['ean13'], context=context):
4179- res = check_ean(product['ean13'])
4180- return res
4181+ if not check_ean(product['ean13']):
4182+ return False
4183+ return True
4184
4185 _constraints = [(_check_ean_key, 'You provided an invalid "EAN13 Barcode" reference. You may use the "Internal Reference" field instead.', ['ean13'])]
4186
4187@@ -782,13 +942,12 @@
4188 ids = [ids]
4189 if not len(ids):
4190 return []
4191+
4192 def _name_get(d):
4193 name = d.get('name','')
4194 code = d.get('default_code',False)
4195 if code:
4196 name = '[%s] %s' % (code,name)
4197- if d.get('variants'):
4198- name = name + ' - %s' % (d['variants'],)
4199 return (d['id'], name)
4200
4201 partner_id = context.get('partner_id', False)
4202@@ -800,6 +959,8 @@
4203
4204 result = []
4205 for product in self.browse(cr, SUPERUSER_ID, ids, context=context):
4206+ variant = ", ".join([v.name for v in product.variant_ids])
4207+ name = variant and "%s (%s)" % (product.name, variant) or product.name
4208 sellers = []
4209 if partner_id:
4210 sellers = filter(lambda x: x.name.id == partner_id, product.seller_ids)
4211@@ -807,17 +968,15 @@
4212 for s in sellers:
4213 mydict = {
4214 'id': product.id,
4215- 'name': s.product_name or product.name,
4216+ 'name': s.product_name or name,
4217 'default_code': s.product_code or product.default_code,
4218- 'variants': product.variants
4219 }
4220 result.append(_name_get(mydict))
4221 else:
4222 mydict = {
4223 'id': product.id,
4224- 'name': product.name,
4225+ 'name': name,
4226 'default_code': product.default_code,
4227- 'variants': product.variants
4228 }
4229 result.append(_name_get(mydict))
4230 return result
4231@@ -855,44 +1014,7 @@
4232 #
4233 def price_get(self, cr, uid, ids, ptype='list_price', context=None):
4234 products = self.browse(cr, uid, ids, context=context)
4235- return self._price_get(cr, uid, products, ptype=ptype, context=context)
4236-
4237- def _price_get(self, cr, uid, products, ptype='list_price', context=None):
4238- if context is None:
4239- context = {}
4240-
4241- if 'currency_id' in context:
4242- pricetype_obj = self.pool.get('product.price.type')
4243- price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
4244- price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
4245-
4246- res = {}
4247- # standard_price field can only be seen by users in base.group_user
4248- # Thus, in order to compute the sale price from the cost price for users not in this group
4249- # We fetch the standard price as the superuser
4250- for product in products:
4251- if ptype != 'standard_price':
4252- res[product.id] = product[ptype] or 0.0
4253- else:
4254- res[product.id] = self.read(cr, SUPERUSER_ID, product.id, [ptype], context=context)[ptype] or 0.0
4255-
4256- product_uom_obj = self.pool.get('product.uom')
4257- for product in products:
4258- if ptype == 'list_price':
4259- res[product.id] = (res[product.id] * (product.price_margin or 1.0)) + \
4260- product.price_extra
4261- if 'uom' in context:
4262- uom = product.uom_id or product.uos_id
4263- res[product.id] = product_uom_obj._compute_price(cr, uid,
4264- uom.id, res[product.id], context['uom'])
4265- # Convert from price_type currency to asked one
4266- if 'currency_id' in context:
4267- # Take the price_type currency from the product field
4268- # This is right cause a field cannot be in more than one currency
4269- res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id,
4270- context['currency_id'], res[product.id],context=context)
4271-
4272- return res
4273+ return self.pool.get("product.template")._price_get(cr, uid, products, ptype=ptype, context=context)
4274
4275 def copy(self, cr, uid, id, default=None, context=None):
4276 context = context or {}
4277@@ -952,8 +1074,9 @@
4278
4279 def _check_ean_key(self, cr, uid, ids, context=None):
4280 for pack in self.browse(cr, uid, ids, context=context):
4281- res = check_ean(pack.ean)
4282- return res
4283+ if not check_ean(pack.ean):
4284+ return False
4285+ return True
4286
4287 _constraints = [(_check_ean_key, 'Error: Invalid ean code', ['ean'])]
4288
4289
4290=== modified file 'product/product_data.xml'
4291--- product/product_data.xml 2014-05-02 13:03:52 +0000
4292+++ product/product_data.xml 2014-05-26 16:10:21 +0000
4293@@ -255,10 +255,5 @@
4294 <field name="type">service</field>
4295 <field name="sale_ok" eval="False"/>
4296 </record>
4297-
4298- <!-- Product Public Categories -->
4299- <record id="categ_others" model="product.public.category">
4300- <field name="name">Others</field>
4301- </record>
4302 </data>
4303 </openerp>
4304
4305=== modified file 'product/product_demo.xml'
4306--- product/product_demo.xml 2014-01-28 12:53:40 +0000
4307+++ product/product_demo.xml 2014-05-26 16:10:21 +0000
4308@@ -56,127 +56,6 @@
4309 <field name="type">box</field>
4310 </record>
4311
4312-
4313- <!-- product.public.category -->
4314-
4315- <record id="computers" model="product.public.category">
4316- <field name="name">Computers</field>
4317- </record>
4318-
4319- <record id="Components" model="product.public.category">
4320- <field name="parent_id" ref="computers"/>
4321- <field name="name">Components</field>
4322- </record>
4323-
4324- <record id="case" model="product.public.category">
4325- <field name="parent_id" ref="Components"/>
4326- <field name="name">Case</field>
4327- </record>
4328- <record id="HDD" model="product.public.category">
4329- <field name="parent_id" ref="Components"/>
4330- <field name="name">Hard Drive</field>
4331- </record>
4332- <record id="motherboard" model="product.public.category">
4333- <field name="parent_id" ref="Components"/>
4334- <field name="name">Motherboard</field>
4335- </record>
4336- <record id="graphics_card" model="product.public.category">
4337- <field name="parent_id" ref="Components"/>
4338- <field name="name">Graphics Card</field>
4339- </record>
4340- <record id="Memory" model="product.public.category">
4341- <field name="parent_id" ref="Components"/>
4342- <field name="name">Memory</field>
4343- </record>
4344- <record id="processor" model="product.public.category">
4345- <field name="parent_id" ref="Components"/>
4346- <field name="name">Processor</field>
4347- </record>
4348- <record id="video_acquisition" model="product.public.category">
4349- <field name="parent_id" ref="Components"/>
4350- <field name="name">Video Acquisition</field>
4351- </record>
4352-
4353- <record id="devices" model="product.public.category">
4354- <field name="parent_id" ref="computers"/>
4355- <field name="name">Devices</field>
4356- </record>
4357-
4358- <record id="Screen" model="product.public.category">
4359- <field name="parent_id" ref="devices"/>
4360- <field name="name">Screen</field>
4361- </record>
4362- <record id="Pen_Drive" model="product.public.category">
4363- <field name="parent_id" ref="devices"/>
4364- <field name="name">Pen Drive</field>
4365- </record>
4366- <record id="External_Hard_Drive" model="product.public.category">
4367- <field name="parent_id" ref="devices"/>
4368- <field name="name">External Hard Drive</field>
4369- </record>
4370- <record id="Keyboard_Mouse" model="product.public.category">
4371- <field name="parent_id" ref="devices"/>
4372- <field name="name">Keyboard / Mouse</field>
4373- </record>
4374- <record id="printer" model="product.public.category">
4375- <field name="parent_id" ref="devices"/>
4376- <field name="name">Printer</field>
4377- </record>
4378- <record id="Speakers" model="product.public.category">
4379- <field name="parent_id" ref="devices"/>
4380- <field name="name">Speakers</field>
4381- </record>
4382- <record id="Headset" model="product.public.category">
4383- <field name="parent_id" ref="devices"/>
4384- <field name="name">Headset</field>
4385- </record>
4386- <record id="Software" model="product.public.category">
4387- <field name="parent_id" ref="devices"/>
4388- <field name="name">Software</field>
4389- </record>
4390-
4391- <record id="laptops" model="product.public.category">
4392- <field name="parent_id" ref="computers"/>
4393- <field name="name">Laptops</field>
4394- </record>
4395-
4396- <record id="sub_computers" model="product.public.category">
4397- <field name="parent_id" ref="computers"/>
4398- <field name="name">Computers</field>
4399- </record>
4400-
4401- <record id="Computer_all_in_one" model="product.public.category">
4402- <field name="parent_id" ref="sub_computers"/>
4403- <field name="name">Computer all-in-one</field>
4404- </record>
4405- <record id="server" model="product.public.category">
4406- <field name="parent_id" ref="sub_computers"/>
4407- <field name="name">Server</field>
4408- </record>
4409-
4410- <record id="network" model="product.public.category">
4411- <field name="parent_id" ref="computers"/>
4412- <field name="name">Network</field>
4413- </record>
4414-
4415- <record id="Switch" model="product.public.category">
4416- <field name="parent_id" ref="network"/>
4417- <field name="name">Switch</field>
4418- </record>
4419- <record id="Modem_Router" model="product.public.category">
4420- <field name="parent_id" ref="network"/>
4421- <field name="name">Modem &amp; Router</field>
4422- </record>
4423- <record id="Switch" model="product.public.category">
4424- <field name="parent_id" ref="network"/>
4425- <field name="name">Switch</field>
4426- </record>
4427-
4428- <record id="services" model="product.public.category">
4429- <field name="parent_id" ref="computers"/>
4430- <field name="name">Services</field>
4431- </record>
4432-
4433 <!-- Apple Products -->
4434 <record id="apple" model="product.category">
4435 <field name="name">Apple Products</field>
4436@@ -210,10 +89,9 @@
4437 <field name="sale_ok" eval="True"/>
4438 </record>
4439
4440- <record id="product_template_1" model="product.template">
4441+ <record id="product_product_1" model="product.product">
4442 <field name="name">On Site Monitoring</field>
4443 <field name="categ_id" ref="product_category_5"/>
4444- <field name="public_categ_id" ref="services"/>
4445 <field name="standard_price">20.5</field>
4446 <field name="list_price">30.75</field>
4447 <field name="type">service</field>
4448@@ -222,15 +100,11 @@
4449 <field name="description">This type of service include basic monitoring of products.</field>
4450 <field name="description_sale">This type of service include basic monitoring of products.</field>
4451 </record>
4452- <record id="product_product_1" model="product.product">
4453- <field name="product_tmpl_id" ref="product_template_1"/>
4454- </record>
4455-
4456-
4457- <record id="product_template_2" model="product.template">
4458+
4459+
4460+ <record id="product_product_2" model="product.product">
4461 <field name="name">On Site Assistance</field>
4462 <field name="categ_id" ref="product_category_5"/>
4463- <field name="public_categ_id" ref="services"/>
4464 <field name="standard_price">25.5</field>
4465 <field name="list_price">38.25</field>
4466 <field name="type">service</field>
4467@@ -238,15 +112,11 @@
4468 <field name="uom_po_id" ref="product_uom_hour"/>
4469 <field name="description">This type of service include assistance for security questions, system configuration requirements, implementation or special needs.</field>
4470 </record>
4471- <record id="product_product_2" model="product.product">
4472- <field name="product_tmpl_id" ref="product_template_2"/>
4473- </record>
4474-
4475-
4476- <record id="product_template_3" model="product.template">
4477+
4478+
4479+ <record id="product_product_3" model="product.product">
4480 <field name="name">PC Assemble SC234</field>
4481 <field name="categ_id" ref="product_category_4"/>
4482- <field name="public_categ_id" ref="Computer_all_in_one"/>
4483 <field name="list_price">450.0</field>
4484 <field name="standard_price">300.0</field>
4485 <field name="type">consu</field>
4486@@ -256,17 +126,13 @@
4487 Processor AMD 8-Core
4488 512MB RAM
4489 HDD SH-1</field>
4490- </record>
4491- <record id="product_product_3" model="product.product">
4492- <field name="product_tmpl_id" ref="product_template_3"/>
4493 <field name="default_code">PCSC234</field>
4494 </record>
4495
4496
4497- <record id="product_template_4" model="product.template">
4498+ <record id="product_product_4" model="product.product">
4499 <field name="name">iPad Retina Display</field>
4500 <field name="categ_id" ref="ipad"/>
4501- <field name="public_categ_id" ref="Computer_all_in_one"/>
4502 <field name="standard_price">500.0</field>
4503 <field name="list_price">750.0</field>
4504 <field name="type">consu</field>
4505@@ -275,17 +141,13 @@
4506 <field name="description_sale">7.9‑inch (diagonal) LED-backlit, 128Gb
4507 Dual-core A5 with quad-core graphics
4508 FaceTime HD Camera, 1.2 MP Photos</field>
4509- </record>
4510- <record id="product_product_4" model="product.product">
4511- <field name="product_tmpl_id" ref="product_template_4"/>
4512 <field name="default_code">A2323</field>
4513 </record>
4514
4515
4516- <record id="product_template_5" model="product.template">
4517+ <record id="product_product_5" model="product.product">
4518 <field name="name">Bose Mini Bluetooth Speaker</field>
4519 <field name="categ_id" ref="accessories"/>
4520- <field name="public_categ_id" ref="Speakers"/>
4521 <field name="standard_price">600.0</field>
4522 <field name="list_price">147.0</field>
4523 <field name="type">consu</field>
4524@@ -293,44 +155,33 @@
4525 <field name="uom_po_id" ref="product_uom_unit"/>
4526 <field name="description">Custom computer assembled on order based on customer's requirement.</field>
4527 <field name="description_sale">Bose's smallest portable Bluetooth speaker</field>
4528- </record>
4529- <record id="product_product_5" model="product.product">
4530- <field name="product_tmpl_id" ref="product_template_5"/>
4531 <field name="default_code">B3423</field>
4532 </record>
4533
4534
4535- <record id="product_template_6" model="product.template">
4536+ <record id="product_product_6" model="product.product">
4537 <field name="name">iPad Mini</field>
4538 <field name="categ_id" ref="ipad"/>
4539- <field name="public_categ_id" ref="Screen"/>
4540 <field name="standard_price">800.0</field>
4541 <field name="list_price">320.0</field>
4542 <field name="type">consu</field>
4543 <field name="uom_id" ref="product_uom_unit"/>
4544 <field name="uom_po_id" ref="product_uom_unit"/>
4545- </record>
4546- <record id="product_product_6" model="product.product">
4547- <field name="product_tmpl_id" ref="product_template_6"/>
4548 <field name="default_code">A1232</field>
4549 </record>
4550
4551- <record id="product_template_7" model="product.template">
4552+ <record id="product_product_7" model="product.product">
4553 <field name="name">Apple In-Ear Headphones</field>
4554 <field name="categ_id" ref="accessories"/>
4555- <field name="public_categ_id" ref="Screen"/>
4556 <field name="standard_price">70.0</field>
4557 <field name="list_price">79.0</field>
4558 <field name="type">consu</field>
4559 <field name="uom_id" ref="product_uom_unit"/>
4560 <field name="uom_po_id" ref="product_uom_unit"/>
4561- </record>
4562- <record id="product_product_7" model="product.product">
4563- <field name="product_tmpl_id" ref="product_template_7"/>
4564 <field name="default_code">A8767</field>
4565 </record>
4566
4567- <record id="product_template_8" model="product.template">
4568+ <record id="product_product_8" model="product.product">
4569 <field name="name">iMac</field>
4570 <field name="categ_id" ref="imac"/>
4571 <field name="standard_price">1299.0</field>
4572@@ -338,272 +189,227 @@
4573 <field name="type">consu</field>
4574 <field name="uom_id" ref="product_uom_unit"/>
4575 <field name="uom_po_id" ref="product_uom_unit"/>
4576- </record>
4577- <record id="product_product_8" model="product.product">
4578- <field name="product_tmpl_id" ref="product_template_8"/>
4579 <field name="default_code">A1090</field>
4580 </record>
4581
4582- <record id="product_template_9" model="product.template">
4583+ <record id="product_product_9" model="product.product">
4584 <field name="name">Apple Wireless Keyboard</field>
4585 <field name="categ_id" ref="accessories"/>
4586- <field name="public_categ_id" ref="Keyboard_Mouse"/>
4587 <field name="standard_price">10.0</field>
4588 <field name="list_price">47.0</field>
4589 <field name="type">consu</field>
4590 <field name="uom_id" ref="product_uom_unit"/>
4591 <field name="uom_po_id" ref="product_uom_unit"/>
4592- </record>
4593- <record id="product_product_9" model="product.product">
4594- <field name="product_tmpl_id" ref="product_template_9"/>
4595 <field name="default_code">AK789</field>
4596 </record>
4597
4598- <record id="product_template_10" model="product.template">
4599+ <record id="product_product_10" model="product.product">
4600 <field name="name">Mouse, Optical</field>
4601 <field name="categ_id" ref="product_category_8"/>
4602- <field name="public_categ_id" ref="Keyboard_Mouse"/>
4603 <field name="standard_price">12.50</field>
4604 <field name="list_price">14</field>
4605 <field name="type">consu</field>
4606 <field name="uom_id" ref="product_uom_unit"/>
4607 <field name="uom_po_id" ref="product_uom_unit"/>
4608- </record>
4609- <record id="product_product_10" model="product.product">
4610- <field name="product_tmpl_id" ref="product_template_10"/>
4611 <field name="default_code">M-Opt</field>
4612 </record>
4613
4614- <record id="product_template_11" model="product.template">
4615- <field name="name">iPod</field>
4616- <field name="categ_id" ref="ipod"/>
4617- <field name="public_categ_id" ref="Keyboard_Mouse"/>
4618- <field name="standard_price">14</field>
4619- <field name="list_price">16.50</field>
4620- <field name="type">consu</field>
4621- <field name="uom_id" ref="product_uom_unit"/>
4622- <field name="uom_po_id" ref="product_uom_unit"/>
4623- </record>
4624+ <!-- -->
4625+
4626+ <record id="product_attribute_1" model="product.attribute">
4627+ <field name="name">Memory</field>
4628+ </record>
4629+ <record id="product_attribute_value_1" model="product.attribute.value">
4630+ <field name="name">16 Go</field>
4631+ <field name="attribute_id" ref="product_attribute_1"/>
4632+ </record>
4633+ <record id="product_attribute_value_2" model="product.attribute.value">
4634+ <field name="name">32 Go</field>
4635+ <field name="attribute_id" ref="product_attribute_1"/>
4636+ </record>
4637+
4638 <record id="product_product_11" model="product.product">
4639 <field name="name">iPod</field>
4640- <field name="variants">16 Gb</field>
4641- <field name="default_code">A6678</field>
4642 <field name="categ_id" ref="ipod"/>
4643- <field name="public_categ_id" ref="Keyboard_Mouse"/>
4644 <field name="standard_price">14</field>
4645 <field name="list_price">16.50</field>
4646 <field name="type">consu</field>
4647 <field name="uom_id" ref="product_uom_unit"/>
4648 <field name="uom_po_id" ref="product_uom_unit"/>
4649- <field name="product_tmpl_id" ref="product_template_11"/>
4650 <field name="default_code">A6678</field>
4651- </record>
4652- <record id="product_product_11_b" model="product.product">
4653- <field name="variants">32 Gb</field>
4654- <field name="price_extra">12</field>
4655- <field name="product_tmpl_id" ref="product_template_11"/>
4656- </record>
4657-
4658- <record id="product_template_12" model="product.template">
4659+ <field name="variant_ids" eval="[(6,0,[ref('product.product_attribute_value_1')])]"/>
4660+ </record>
4661+ <record id="product_product_11b" model="product.product">
4662+ <field name="default_code">A6679</field>
4663+ <field name="product_tmpl_id" ref="product_product_11_product_template"/>
4664+ <field name="variant_ids" eval="[(6,0,[ref('product.product_attribute_value_2')])]"/>
4665+ </record>
4666+
4667+ <record id="product_attribute_line_1" model="product.attribute.line">
4668+ <field name="product_tmpl_id" ref="product_product_11_product_template"/>
4669+ <field name="attribute_id" ref="product_attribute_1"/>
4670+ <field name="value_ids" eval="[(6,0,[ref('product.product_attribute_value_1'), ref('product.product_attribute_value_2')])]"/>
4671+ </record>
4672+
4673+ <record id="product_product_11_product_template" model="product.template">
4674+ <field name="variant_ids" eval="[(6,0,[ref('product.product_attribute_line_1')])]"/>
4675+ </record>
4676+
4677+ <record id="product_attribute_price_1" model="product.attribute.price">
4678+ <field name="product_tmpl_id" ref="product_product_11_product_template"/>
4679+ <field name="value_id" ref="product_attribute_value_2"/>
4680+ <field name="price_extra">6.40</field>
4681+ </record>
4682+
4683+ <!-- -->
4684+
4685+ <record id="product_product_12" model="product.product">
4686 <field name="name">Mouse, Wireless</field>
4687 <field name="categ_id" ref="product_category_8"/>
4688- <field name="public_categ_id" ref="Keyboard_Mouse"/>
4689 <field name="standard_price">18</field>
4690 <field name="list_price">12.50</field>
4691 <field name="type">consu</field>
4692 <field name="uom_id" ref="product_uom_unit"/>
4693 <field name="uom_po_id" ref="product_uom_unit"/>
4694- </record>
4695- <record id="product_product_12" model="product.product">
4696- <field name="product_tmpl_id" ref="product_template_12"/>
4697 <field name="default_code">M-Wir</field>
4698 </record>
4699
4700- <record id="product_template_13" model="product.template">
4701+ <record id="product_product_13" model="product.product">
4702 <field name="name">RAM SR5</field>
4703 <field name="categ_id" ref="product_category_8"/>
4704- <field name="public_categ_id" ref="Memory"/>
4705 <field name="standard_price">78.0</field>
4706 <field name="list_price">85.0</field>
4707 <field name="type">consu</field>
4708 <field name="uom_id" ref="product_uom_unit"/>
4709 <field name="uom_po_id" ref="product_uom_unit"/>
4710- </record>
4711- <record id="product_product_13" model="product.product">
4712- <field name="product_tmpl_id" ref="product_template_13"/>
4713 <field name="default_code">RAM-SR5</field>
4714 </record>
4715
4716- <record id="product_template_14" model="product.template">
4717+ <record id="product_product_14" model="product.product">
4718 <field name="name">RAM SR2</field>
4719 <field name="categ_id" ref="product_category_8"/>
4720- <field name="public_categ_id" ref="Memory"/>
4721 <field name="standard_price">87.0</field>
4722 <field name="list_price">95.0</field>
4723 <field name="type">consu</field>
4724 <field name="uom_id" ref="product_uom_unit"/>
4725 <field name="uom_po_id" ref="product_uom_unit"/>
4726- </record>
4727- <record id="product_product_14" model="product.product">
4728- <field name="product_tmpl_id" ref="product_template_14"/>
4729 <field name="default_code">RAM-SR2</field>
4730 </record>
4731
4732- <record id="product_template_15" model="product.template">
4733+ <record id="product_product_15" model="product.product">
4734 <field name="name">RAM SR3</field>
4735 <field name="categ_id" ref="product_category_8"/>
4736- <field name="public_categ_id" ref="Memory"/>
4737 <field name="standard_price">80.0</field>
4738 <field name="list_price">85.0</field>
4739 <field name="type">consu</field>
4740 <field name="uom_id" ref="product_uom_unit"/>
4741 <field name="uom_po_id" ref="product_uom_unit"/>
4742- </record>
4743- <record id="product_product_15" model="product.product">
4744- <field name="product_tmpl_id" ref="product_template_15"/>
4745 <field name="default_code">RAM-SR3</field>
4746 </record>
4747
4748- <record id="product_template_16" model="product.template">
4749+ <record id="product_product_16" model="product.product">
4750 <field name="name">Computer Case</field>
4751 <field name="categ_id" ref="product_category_8"/>
4752- <field name="public_categ_id" ref="case"/>
4753 <field name="standard_price">20.0</field>
4754 <field name="list_price">25.0</field>
4755 <field name="type">consu</field>
4756 <field name="uom_id" ref="product_uom_unit"/>
4757 <field name="uom_po_id" ref="product_uom_unit"/>
4758- </record>
4759- <record id="product_product_16" model="product.product">
4760- <field name="product_tmpl_id" ref="product_template_16"/>
4761 <field name="default_code">C-Case</field>
4762 </record>
4763
4764- <record id="product_template_17" model="product.template">
4765+ <record id="product_product_17" model="product.product">
4766 <field name="name">HDD SH-1</field>
4767 <field name="categ_id" ref="product_category_8"/>
4768- <field name="public_categ_id" ref="HDD"/>
4769 <field name="standard_price">860.0</field>
4770 <field name="list_price">975.0</field>
4771 <field name="type">consu</field>
4772 <field name="uom_id" ref="product_uom_unit"/>
4773 <field name="uom_po_id" ref="product_uom_unit"/>
4774- </record>
4775- <record id="product_product_17" model="product.product">
4776- <field name="product_tmpl_id" ref="product_template_17"/>
4777 <field name="default_code">HDD-SH1</field>
4778 </record>
4779
4780- <record id="product_template_18" model="product.template">
4781+ <record id="product_product_18" model="product.product">
4782 <field name="name">HDD SH-2</field>
4783 <field name="categ_id" ref="product_category_8"/>
4784- <field name="public_categ_id" ref="HDD"/>
4785 <field name="standard_price">1020.0</field>
4786 <field name="list_price">1150.0</field>
4787 <field name="type">consu</field>
4788 <field name="uom_id" ref="product_uom_unit"/>
4789 <field name="uom_po_id" ref="product_uom_unit"/>
4790- </record>
4791- <record id="product_product_18" model="product.product">
4792- <field name="product_tmpl_id" ref="product_template_18"/>
4793 <field name="default_code">HDD-SH2</field>
4794 </record>
4795
4796- <record id="product_template_19" model="product.template">
4797+ <record id="product_product_19" model="product.product">
4798 <field name="name">HDD on Demand</field>
4799 <field name="categ_id" ref="product_category_8"/>
4800- <field name="public_categ_id" ref="HDD"/>
4801 <field name="standard_price">1100.0</field>
4802 <field name="list_price">1250.0</field>
4803 <field name="type">consu</field>
4804 <field name="uom_id" ref="product_uom_unit"/>
4805 <field name="uom_po_id" ref="product_uom_unit"/>
4806 <field name="description">On demand hard-disk having capacity based on requirement.</field>
4807- </record>
4808- <record id="product_product_19" model="product.product">
4809- <field name="product_tmpl_id" ref="product_template_19"/>
4810 <field name="default_code">HDD-DEM</field>
4811 </record>
4812
4813- <record id="product_template_20" model="product.template">
4814+ <record id="product_product_20" model="product.product">
4815 <field name="name">Motherboard I9P57</field>
4816 <field name="categ_id" ref="product_category_8"/>
4817- <field name="public_categ_id" ref="motherboard"/>
4818 <field name="standard_price">1700.0</field>
4819 <field name="list_price">1950.0</field>
4820 <field name="type">consu</field>
4821 <field name="uom_id" ref="product_uom_unit"/>
4822 <field name="uom_po_id" ref="product_uom_unit"/>
4823- </record>
4824- <record id="product_product_20" model="product.product">
4825- <field name="product_tmpl_id" ref="product_template_20"/>
4826 <field name="default_code">MBi9</field>
4827 </record>
4828
4829- <record id="product_template_21" model="product.template">
4830+ <record id="product_product_21" model="product.product">
4831 <field name="name">Motherboard A20Z7</field>
4832 <field name="categ_id" ref="product_category_8"/>
4833- <field name="public_categ_id" ref="motherboard"/>
4834 <field name="standard_price">1790.0</field>
4835 <field name="list_price">2000.0</field>
4836 <field name="type">consu</field>
4837 <field name="uom_id" ref="product_uom_unit"/>
4838 <field name="uom_po_id" ref="product_uom_unit"/>
4839- </record>
4840- <record id="product_product_21" model="product.product">
4841- <field name="product_tmpl_id" ref="product_template_21"/>
4842 <field name="default_code">MBa20</field>
4843 </record>
4844
4845- <record id="product_template_22" model="product.template">
4846+ <record id="product_product_22" model="product.product">
4847 <field name="name">Processor Core i5 2.70 Ghz</field>
4848 <field name="categ_id" ref="product_category_8"/>
4849- <field name="public_categ_id" ref="processor"/>
4850 <field name="standard_price">2010.0</field>
4851 <field name="list_price">2100.0</field>
4852 <field name="type">consu</field>
4853 <field name="uom_id" ref="product_uom_unit"/>
4854 <field name="uom_po_id" ref="product_uom_unit"/>
4855- </record>
4856- <record id="product_product_22" model="product.product">
4857- <field name="product_tmpl_id" ref="product_template_22"/>
4858 <field name="default_code">CPUi5</field>
4859 </record>
4860
4861- <record id="product_template_23" model="product.template">
4862+ <record id="product_product_23" model="product.product">
4863 <field name="name">Processor AMD 8-Core</field>
4864 <field name="categ_id" ref="product_category_8"/>
4865- <field name="public_categ_id" ref="processor"/>
4866 <field name="standard_price">1910.0</field>
4867 <field name="list_price">1980.0</field>
4868 <field name="type">consu</field>
4869 <field name="uom_id" ref="product_uom_unit"/>
4870 <field name="uom_po_id" ref="product_uom_unit"/>
4871- </record>
4872- <record id="product_product_23" model="product.product">
4873- <field name="product_tmpl_id" ref="product_template_23"/>
4874 <field name="default_code">CPUa8</field>
4875 </record>
4876
4877- <record id="product_template_24" model="product.template">
4878+ <record id="product_product_24" model="product.product">
4879 <field name="name">Graphics Card</field>
4880 <field name="categ_id" ref="product_category_8"/>
4881- <field name="public_categ_id" ref="graphics_card"/>
4882 <field name="standard_price">876.0</field>
4883 <field name="list_price">885.0</field>
4884 <field name="type">consu</field>
4885 <field name="uom_id" ref="product_uom_unit"/>
4886 <field name="uom_po_id" ref="product_uom_unit"/>
4887- </record>
4888- <record id="product_product_24" model="product.product">
4889- <field name="product_tmpl_id" ref="product_template_24"/>
4890 <field name="default_code">CARD</field>
4891 </record>
4892
4893- <record id="product_template_25" model="product.template">
4894+ <record id="product_product_25" model="product.product">
4895 <field name="name">Laptop E5023</field>
4896 <field name="categ_id" ref="product_category_4"/>
4897- <field name="public_categ_id" ref="laptops"/>
4898 <field name="standard_price">2870.0</field>
4899 <field name="list_price">2950.0</field>
4900 <field name="type">consu</field>
4901@@ -613,16 +419,12 @@
4902 4GB RAM
4903 Standard-1294P Processor
4904 QWERTY keyboard</field>
4905- </record>
4906- <record id="product_product_25" model="product.product">
4907- <field name="product_tmpl_id" ref="product_template_25"/>
4908 <field name="default_code">LAP-E5</field>
4909 </record>
4910
4911- <record id="product_template_26" model="product.template">
4912+ <record id="product_product_26" model="product.product">
4913 <field name="name">Laptop S3450</field>
4914 <field name="categ_id" ref="product_category_4"/>
4915- <field name="public_categ_id" ref="laptops"/>
4916 <field name="standard_price">3000.0</field>
4917 <field name="list_price">3245.0</field>
4918 <field name="type">consu</field>
4919@@ -632,141 +434,106 @@
4920 6GB RAM
4921 Hi-Speed 234Q Processor
4922 QWERTY keyboard</field>
4923- </record>
4924- <record id="product_product_26" model="product.product">
4925- <field name="product_tmpl_id" ref="product_template_26"/>
4926 <field name="default_code">LAP-S3</field>
4927 </record>
4928
4929- <record id="product_template_27" model="product.template">
4930+ <record id="product_product_27" model="product.product">
4931 <field name="name">Laptop Customized</field>
4932 <field name="categ_id" ref="product_category_4"/>
4933- <field name="public_categ_id" ref="laptops"/>
4934 <field name="standard_price">3300.0</field>
4935 <field name="list_price">3645.0</field>
4936 <field name="type">consu</field>
4937 <field name="uom_id" ref="product_uom_unit"/>
4938 <field name="uom_po_id" ref="product_uom_unit"/>
4939 <field name="description">Custom Laptop based on customer's requirement.</field>
4940- </record>
4941- <record id="product_product_27" model="product.product">
4942- <field name="product_tmpl_id" ref="product_template_27"/>
4943 <field name="default_code">LAP-CUS</field>
4944 </record>
4945
4946- <record id="product_template_28" model="product.template">
4947+ <record id="product_product_28" model="product.product">
4948 <field name="name">External Hard disk</field>
4949 <field name="categ_id" ref="product_category_6"/>
4950- <field name="public_categ_id" ref="External_Hard_Drive"/>
4951 <field name="standard_price">390.0</field>
4952 <field name="list_price">405.0</field>
4953 <field name="type">consu</field>
4954 <field name="uom_id" ref="product_uom_unit"/>
4955 <field name="uom_po_id" ref="product_uom_unit"/>
4956- </record>
4957- <record id="product_product_28" model="product.product">
4958- <field name="product_tmpl_id" ref="product_template_28"/>
4959 <field name="default_code">EXT-HDD</field>
4960 </record>
4961
4962
4963- <record id="product_template_29" model="product.template">
4964+ <record id="product_product_29" model="product.product">
4965 <field name="name">Pen drive, SP-2</field>
4966 <field name="categ_id" ref="product_category_7"/>
4967- <field name="public_categ_id" ref="Pen_Drive"/>
4968 <field name="standard_price">90.0</field>
4969 <field name="list_price">100.0</field>
4970 <field name="type">consu</field>
4971 <field name="uom_id" ref="product_uom_unit"/>
4972 <field name="uom_po_id" ref="product_uom_unit"/>
4973- </record>
4974- <record id="product_product_29" model="product.product">
4975- <field name="product_tmpl_id" ref="product_template_29"/>
4976 <field name="default_code">PD-SP2</field>
4977 </record>
4978
4979
4980- <record id="product_template_30" model="product.template">
4981+ <record id="product_product_30" model="product.product">
4982 <field name="name">Pen drive, SP-4</field>
4983 <field name="categ_id" ref="product_category_7"/>
4984- <field name="public_categ_id" ref="Pen_Drive"/>
4985 <field name="standard_price">126.0</field>
4986 <field name="list_price">145.0</field>
4987 <field name="type">consu</field>
4988 <field name="uom_id" ref="product_uom_unit"/>
4989 <field name="uom_po_id" ref="product_uom_unit"/>
4990- </record>
4991- <record id="product_product_30" model="product.product">
4992- <field name="product_tmpl_id" ref="product_template_30"/>
4993 <field name="default_code">PD-SP4</field>
4994 </record>
4995
4996- <record id="product_template_31" model="product.template">
4997+ <record id="product_product_31" model="product.product">
4998 <field name="name">Multimedia Speakers</field>
4999 <field name="categ_id" ref="product_category_7"/>
5000- <field name="public_categ_id" ref="Speakers"/>
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: