Merge lp:~camptocamp/sale-wkfl/product_procurement_type into lp:~sale-core-editors/sale-wkfl/7.0

Proposed by Alexandre Fayolle - camptocamp
Status: Rejected
Rejected by: Leonardo Pistone
Proposed branch: lp:~camptocamp/sale-wkfl/product_procurement_type
Merge into: lp:~sale-core-editors/sale-wkfl/7.0
Diff against target: 617 lines (+563/-0)
10 files modified
product_procurement_type/__init__.py (+22/-0)
product_procurement_type/__openerp__.py (+52/-0)
product_procurement_type/product.py (+139/-0)
product_procurement_type/product_view.xml (+42/-0)
product_procurement_type/test/test_onchange_procurement_type.yml (+56/-0)
product_procurement_type_dropshipping/__init__.py (+22/-0)
product_procurement_type_dropshipping/__openerp__.py (+46/-0)
product_procurement_type_dropshipping/product.py (+115/-0)
product_procurement_type_dropshipping/product_view.xml (+17/-0)
product_procurement_type_dropshipping/test/test_onchange_procurement_type.yml (+52/-0)
To merge this branch: bzr merge lp:~camptocamp/sale-wkfl/product_procurement_type
Reviewer Review Type Date Requested Status
Pedro Manuel Baeza Needs Resubmitting
Lorenzo Battistini (community) code review Needs Fixing
Yannick Vaucher @ Camptocamp code review, no tests Pending
Leonardo Pistone code review Pending
Stefan Rijnhart (Opener) Pending
Alexandre Fayolle - camptocamp code review, test Pending
Joël Grand-Guillaume @ camptocamp code review + no tests Pending
Review via email: mp+222111@code.launchpad.net

This proposal supersedes a proposal from 2014-03-03.

Description of the change

Here are two new addons who brings a simple field to manage several combinations
for two procurements fields : procure_method & supply_method :
First addon adds:
- Normal: MTS + buy
- Bill of Materials: MTO + produce
Second addon depends of sale_dropshipping addon and adds:
- Dropshipping: MTO + buy

I'm not sure if it's the right community branch to propose it, if you think about a better
place, let me know.

To post a comment you must log in.
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : Posted in a previous version of this proposal

LGTM for the code

However, I don't think we have a proper branch to extend procurement.

Shall we create one?

review: Approve (code review, no tests)
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

> LGTM for the code
>
> However, I don't think we have a proper branch to extend procurement.
>
> Shall we create one?

Since this is mainly affecting sales, I think this branch is correct.

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

need to set the value of the attribute from current product configuration when the module is installed.

setting status to "Work in progress" until this is resolved

review: Needs Fixing
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

> > LGTM for the code
> >
> > However, I don't think we have a proper branch to extend procurement.
> >
> > Shall we create one?
>
> Since this is mainly affecting sales, I think this branch is correct.

However I'm not sure this is not too customer specific to get in OCA. What do other think?

review: Needs Information
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

> need to set the value of the attribute from current product configuration when
> the module is installed.
>
> setting status to "Work in progress" until this is resolved

dons

Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : Posted in a previous version of this proposal

LGTM, and I agree about adding this module here. Thanks

review: Approve (code review, no tests)
Revision history for this message
Leonardo Pistone (lepistone) wrote : Posted in a previous version of this proposal

I approve the code.

I share Alexandre's question if there is interest to have that in OCA. If not, being it approved technically, we can quickly merge it to a specific branch.

review: Approve (code review)
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote : Posted in a previous version of this proposal

I don't see a problem having these modules here. About the code: there is a migration script, and I think its purpose is to update existing products upon installation of the module. However, I don't think the script is run at module installation time. Are you sure that this is the case?

Otherwise, you will need to put it in the model's _auto_init() method. It will run every time the module is upgraded (or installed) but that should not hurt. What you can do is check if column 'procurement_type' exists, call super() and run the migration queries only if the column did not exist when you checked. This indicates the installation of the module.

review: Needs Information
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

> I don't see a problem having these modules here. About the code: there is a
> migration script, and I think its purpose is to update existing products upon
> installation of the module. However, I don't think the script is run at module
> installation time. Are you sure that this is the case?

Yes it is run at installation time, I checked for this.

> Otherwise, you will need to put it in the model's _auto_init() method. It will
> run every time the module is upgraded (or installed) but that should not hurt.
> What you can do is check if column 'procurement_type' exists, call super() and
> run the migration queries only if the column did not exist when you checked.
> This indicates the installation of the module.

Not sure what the cleanest way is. Do you have an opinion about the cleanness of either options, and what we should aim for in OCA modules?

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote : Posted in a previous version of this proposal

Great, that means that we have the pre- and post-installation scripts that I always wanted after all! Much better solution than the _auto_init one.

review: Approve
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal

I found an issue (possibly a framework bug) which prevents the new attribute from being imported from a CSV file.

review: Needs Resubmitting (test)
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : Posted in a previous version of this proposal
review: Approve (code review, test)
Revision history for this message
Lorenzo Battistini (elbati) wrote : Posted in a previous version of this proposal

Hello Alexandre,

line 223: if vals['type'] == 'service', should we run _compute_procurement_vals anyway?

lines 585 and 597: as 'product_procurement_type_dropshipping' depends on 'product_procurement_type', why do the write and create methods call the '_compute_procurement_vals' method, already called by 'product_procurement_type'?

Thanks!

review: Needs Information
Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : Posted in a previous version of this proposal

Hi,

Regarding Lorenzo's comments:

 * L223 : IMO think that's not necessary
 * L585 : I agree with Lorenzo's opinion here, you should remove the write and create override in the product_procurement_type_dropshipping module. Already made in the product_procurement_type one.

Thanks !

review: Needs Fixing (code review + no tests)
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

I've fixed Lorenzo's remarks, and moved the migration script to an init method as the migration script may not be executed on initial installation

46. By Romain Deheele - Camptocamp

[UPD] update manifest according to selection values

47. By Romain Deheele - Camptocamp

replace ValueError exception with False value that will be refused because a value is required : avoid ugly traceback

48. By Romain Deheele - Camptocamp

[UPD] update manifest description

Revision history for this message
Romain Deheele - Camptocamp (romaindeheele) wrote :

After several various changes, I think it's time to review it again.

Thanks,

Romain

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Hello Romain and Alexandre,

diff comments + some PEP8 remarks

product_procurement_type/product.py:27:1: E302 expected 2 blank lines, found 1
product_procurement_type/product.py:34:1: E302 expected 2 blank lines, found 1
product_procurement_type/product.py:99:13: E123 closing bracket does not match indentation of opening bracket's line

product_procurement_type/product.py:42:80: E501 line too long (95 > 79 characters)

product_procurement_type_dropshipping/product.py:28:1: E302 expected 2 blank lines, found 0
product_procurement_type_dropshipping/product.py:33:1: E302 expected 2 blank lines, found 1
product_procurement_type_dropshipping/product.py:52:5: E303 too many blank lines (2)
product_procurement_type_dropshipping/product.py:111:17: E123 closing bracket does not match indentation of opening bracket's line
product_procurement_type_dropshipping/product.py:115:1: W391 blank line at end of file

product_procurement_type_dropshipping/product.py:25:80: E501 line too long (90 > 79 characters)
product_procurement_type_dropshipping/product.py:46:80: E501 line too long (116 > 79 characters)
product_procurement_type_dropshipping/product.py:64:80: E501 line too long (80 > 79 characters)

review: Needs Fixing (code review)
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

This project is now hosted on https://github.com/OCA/sale-workflow. Please move your proposal there. This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

review: Needs Resubmitting
Revision history for this message
Leonardo Pistone (lepistone) wrote :

Unmerged revisions

48. By Romain Deheele - Camptocamp

[UPD] update manifest description

47. By Romain Deheele - Camptocamp

replace ValueError exception with False value that will be refused because a value is required : avoid ugly traceback

46. By Romain Deheele - Camptocamp

[UPD] update manifest according to selection values

45. By Alexandre Fayolle - camptocamp

the migration scripts are not longer called on installation -> move to init method

44. By Alexandre Fayolle - camptocamp

[IMP] remove unnecessary code pointed out by lpistone

43. By Alexandre Fayolle - camptocamp

[FIX] issue when importing products from CSV with procurement_type attribute

There is an issue in the framework (I think) which will break the previous
version of the code in CSV imports: the get_product_procurement_type method (in
product_template) is called with an instance of product_product for self, and
the call to super() crashed. This redesign works around the issue by extracting
get_product_procurement_type to a function and thus avoiding self altogether.

42. By Alexandre Fayolle - camptocamp

[FIX] tests

41. By Alexandre Fayolle - camptocamp

[ADD] migration script to ensure that the new attribute is populated

40. By Alexandre Fayolle - camptocamp

[FIX] values of procurement_type in dispatch method + help string + module version number

39. By Alexandre Fayolle - camptocamp

[IMP] follow changes in product_procurement_type_dropshipping

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'product_procurement_type'
=== added file 'product_procurement_type/__init__.py'
--- product_procurement_type/__init__.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type/__init__.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,22 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from . import product
023
=== added file 'product_procurement_type/__openerp__.py'
--- product_procurement_type/__openerp__.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type/__openerp__.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,52 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 "name": "Product Procurement Types",
24 "version": "0.1",
25 "author": "Camptocamp",
26 "license": "AGPL-3",
27 "category": "Sales",
28 "description":
29 """
30 Add a procurement type selection on products.
31 Let create products as :
32 - On stock, buy
33 - On stock, produce
34 - On order, buy
35 - On order, produce
36
37 Choose "On stock, buy" changes automatically
38 procurement method as "make to stock" and supply method as "buy".
39 Choose "On demand, produce" changes automatically
40 procurement method as "make to order" and supply method as "produce".
41
42 """,
43 "website": "http://camptocamp.com",
44 "depends": ['sale',
45 'procurement',
46 'mrp'],
47 "data": ['product_view.xml'],
48 "demo": [],
49 "test": ['test/test_onchange_procurement_type.yml'],
50 "active": False,
51 "installable": True,
52}
053
=== added file 'product_procurement_type/product.py'
--- product_procurement_type/product.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type/product.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,139 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21import logging
22
23from openerp.osv import orm, fields
24
25_logger = logging.getLogger('openerp.upgrade')
26
27def get_procurement_type_selection():
28 return [('buy_stock', 'On stock, buy'),
29 ('buy_demand', 'On demand, buy'),
30 ('produce_demand', 'On demand, produce'),
31 ('produce_stock', 'On stock, produce'),
32 ]
33
34class product_template(orm.Model):
35
36 _inherit = 'product.template'
37
38 def init(self, cr):
39 _logger.info('Migrating product_procurement_type')
40 query = ("UPDATE product_template pt "
41 "SET procurement_type=%(procurement_type)s "
42 "WHERE procure_method=%(procure_method)s and supply_method=%(supply_method)s")
43 fixes = [{'procurement_type': 'buy_stock',
44 'procure_method': 'make_to_stock',
45 'supply_method': 'buy'},
46 {'procurement_type': 'buy_demand',
47 'procure_method': 'make_to_order',
48 'supply_method': 'buy'},
49 {'procurement_type': 'produce_stock',
50 'procure_method': 'make_to_stock',
51 'supply_method': 'produce'},
52 {'procurement_type': 'produce_demand',
53 'procure_method': 'make_to_order',
54 'supply_method': 'produce'},
55 ]
56 for fix in fixes:
57 cr.execute(query, fix)
58
59 def get_procurement_type_selection(self, cr, uid, context=None):
60 """
61 Has to be inherited to add procurement type
62 """
63 return get_procurement_type_selection()
64
65 def _compute_procurement_vals(self, vals):
66 if vals['procurement_type'] == 'buy_stock':
67 vals.update({'procure_method': 'make_to_stock',
68 'supply_method': 'buy',
69 })
70 elif vals['procurement_type'] == 'produce_demand':
71 vals.update({'procure_method': 'make_to_order',
72 'supply_method': 'produce',
73 })
74 elif vals['procurement_type'] == 'buy_demand':
75 vals.update({'procure_method': 'make_to_order',
76 'supply_method': 'buy',
77 })
78 elif vals['procurement_type'] == 'produce_stock':
79 vals.update({'procure_method': 'make_to_stock',
80 'supply_method': 'produce',
81 })
82 else:
83 vals['procurement_type'] = False
84 return vals
85
86 _columns = {
87 'procurement_type': fields.selection(
88 get_procurement_type_selection,
89 'Procurement Type',
90 required=True,
91 help='On stock, buy: Procurement Method: Make to Stock, '
92 'Supply Method: Buy.\n'
93 'On stock, produce: Procurement Method: Make to Stock, '
94 'Supply Method: Produce.\n'
95 'On order, buy: Procurement Method: Make to Order, '
96 'Supply Method: Buy.\n'
97 'On order, produce: Procurement Method: Make to Order, '
98 'Supply Method: Produce.\n'
99 ),
100 }
101
102 _defaults = {
103 'procurement_type': 'buy_stock',
104 }
105
106 def onchange_procurement_type(self, cr, uid, ids, type, procurement_type,
107 context=None):
108 vals = {'procurement_type': procurement_type}
109 if type != 'service':
110 vals = self._compute_procurement_vals(vals)
111 return {'value': vals}
112
113 def write(self, cr, uid, ids, vals, context=None):
114 for product in self.read(cr, uid, ids, ['type'], context=context):
115 if product['type'] != 'service' and \
116 vals.get('procurement_type'):
117 vals = self._compute_procurement_vals(vals)
118 res = super(product_template, self).write(cr, uid, ids, vals,
119 context=context)
120 return res
121
122 def create(self, cr, uid, vals, context=None):
123 if vals['type'] != 'service' and vals.get('procurement_type'):
124 vals = self._compute_procurement_vals(vals)
125 return super(product_template, self).create(cr, uid, vals,
126 context=context)
127
128
129class product_product(orm.Model):
130
131 _inherit = 'product.product'
132
133 def onchange_procurement_type(self, cr, uid, ids, type, procurement_type,
134 context=None):
135 tmpl_obj = self.pool['product.template']
136 res = tmpl_obj.onchange_procurement_type(cr, uid, ids, type,
137 procurement_type,
138 context=context)
139 return {'value': res['value']}
0140
=== added file 'product_procurement_type/product_view.xml'
--- product_procurement_type/product_view.xml 1970-01-01 00:00:00 +0000
+++ product_procurement_type/product_view.xml 2014-06-10 15:36:28 +0000
@@ -0,0 +1,42 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="product_normal_form_view_procurement_type" model="ir.ui.view">
5 <field name="name">product.product.procurement_type</field>
6 <field name="model">product.product</field>
7 <field name="inherit_id" ref="procurement.product_form_view_procurement_button"/>
8 <field name="arch" type="xml">
9 <data>
10 <field name="procure_method" position="before">
11 <field name="procurement_type" on_change="onchange_procurement_type(type, procurement_type)" attrs="{'invisible':[('type','=','service')]}"/>
12 </field>
13 <field name="supply_method" position="attributes">
14 <attribute name="attrs">{'invisible':[('type','!=','service')]}</attribute>
15 </field>
16 <field name="procure_method" position="attributes">
17 <attribute name="attrs">{'invisible':[('type','!=','service')]}</attribute>
18 </field>
19 </data>
20 </field>
21 </record>
22
23 <record model="ir.ui.view" id="product_template_form_view_procurement_type">
24 <field name="name">product.template.procurement_type</field>
25 <field name="model">product.template</field>
26 <field name="inherit_id" ref="procurement.product_template_form_view_procurement"/>
27 <field name="arch" type="xml">
28 <data>
29 <field name="procure_method" position="before">
30 <field name="procurement_type" on_change="onchange_procurement_type(type, procurement_type)" attrs="{'invisible':[('type','=','service')]}"/>
31 </field>
32 <field name="procure_method" position="attributes">
33 <attribute name="invisible">{'invisible':[('type','!=','service')]}</attribute>
34 </field>
35 <field name="supply_method" position="attributes">
36 <attribute name="invisible">{'invisible':[('type','!=','service')]}</attribute>
37 </field>
38 </data>
39 </field>
40 </record>
41 </data>
42</openerp>
043
=== added directory 'product_procurement_type/test'
=== added file 'product_procurement_type/test/test_onchange_procurement_type.yml'
--- product_procurement_type/test/test_onchange_procurement_type.yml 1970-01-01 00:00:00 +0000
+++ product_procurement_type/test/test_onchange_procurement_type.yml 2014-06-10 15:36:28 +0000
@@ -0,0 +1,56 @@
1-
2 Testing change of procurement type on product
3-
4 I create a product "Store" with type buy_stock
5-
6 !record {model: product.product, id: product1}:
7 name: Store
8 type: product
9 procurement_type: buy_stock
10-
11 I check if the product is MTS + buy
12-
13 !assert {model: product.product, id: product1}:
14 - procure_method == 'make_to_stock'
15 - supply_method == 'buy'
16-
17 I create a product "Curtain" with type produce_demand
18-
19 !record {model: product.product, id: product2}:
20 name: Curtain
21 type: product
22 procurement_type: produce_demand
23-
24 I check if the product is MTO + produce
25-
26 !assert {model: product.product, id: product2}:
27 - procure_method == 'make_to_order'
28 - supply_method == 'produce'
29
30-
31 I create a product "Curtain2" with type produce_stock
32-
33 !record {model: product.product, id: product3}:
34 name: Curtain2
35 type: product
36 procurement_type: produce_stock
37-
38 I check if the product is MTS + produce
39-
40 !assert {model: product.product, id: product3}:
41 - procure_method == 'make_to_stock'
42 - supply_method == 'produce'
43
44-
45 I create a product "Store2" with type buy_demand
46-
47 !record {model: product.product, id: product4}:
48 name: Store2
49 type: product
50 procurement_type: buy_demand
51-
52 I check if the product is MTO + buy
53-
54 !assert {model: product.product, id: product4}:
55 - procure_method == 'make_to_order'
56 - supply_method == 'buy'
057
=== added directory 'product_procurement_type_dropshipping'
=== added file 'product_procurement_type_dropshipping/__init__.py'
--- product_procurement_type_dropshipping/__init__.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type_dropshipping/__init__.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,22 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from . import product
023
=== added file 'product_procurement_type_dropshipping/__openerp__.py'
--- product_procurement_type_dropshipping/__openerp__.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type_dropshipping/__openerp__.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22{
23 "name": "Product Procurement Type Dropshipping",
24 "version": "0.1",
25 "author": "Camptocamp",
26 "license": "AGPL-3",
27 "category": "Sales",
28 "description":
29 """
30 Add a choice named 'dropshipping' in procurement_type selection
31 introduced by product_procurement_type addon.
32 Choose "Dropshipping" changes automatically
33 procurement method as "make to order" and supply method as "buy".
34 It checks if at least one supplier is associated on supplier list
35 in product form.
36
37 """,
38 "website": "http://camptocamp.com",
39 "depends": ['product_procurement_type',
40 'sale_dropshipping'],
41 "data": ['product_view.xml'],
42 "demo": [],
43 "test": ['test/test_onchange_procurement_type.yml'],
44 "active": False,
45 "installable": True,
46}
047
=== added file 'product_procurement_type_dropshipping/product.py'
--- product_procurement_type_dropshipping/product.py 1970-01-01 00:00:00 +0000
+++ product_procurement_type_dropshipping/product.py 2014-06-10 15:36:28 +0000
@@ -0,0 +1,115 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Romain Deheele
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21import logging
22
23from openerp.osv import orm, fields
24from openerp.tools.translate import _
25from openerp.addons.product_procurement_type.product import get_procurement_type_selection
26
27_logger = logging.getLogger(__name__)
28def get_procurement_type_selection_with_dropshipping():
29 selections = get_procurement_type_selection()
30 selections.append(('direct_delivery', 'Drop Shipping'))
31 return selections
32
33class product_template(orm.Model):
34
35 _inherit = 'product.template'
36
37 def init(self, cr):
38 _logger.info('Migrating product_procurement_type_dropshipping')
39 query = ("UPDATE product_template AS pt "
40 "SET procurement_type=%(procurement_type)s "
41 "FROM product_supplierinfo AS psi "
42 "WHERE procure_method=%(procure_method)s "
43 " AND supply_method=%(supply_method)s "
44 " AND psi.product_id = pt.id "
45 " AND psi.direct_delivery_flag = true")
46 fixes = [{'procurement_type': 'direct_delivery', 'procure_method': 'make_to_order', 'supply_method': 'buy'},
47 ]
48 for fix in fixes:
49 cr.execute(query, fix)
50
51
52 def get_procurement_type_selection(self, cr, uid, context=None):
53 """
54 Adds type dropshipping in procurement_type selection
55 """
56 return get_procurement_type_selection_with_dropshipping()
57
58 def _compute_procurement_vals(self, vals):
59 if vals['procurement_type'] == 'direct_delivery':
60 vals.update({'procure_method': 'make_to_order',
61 'supply_method': 'buy',
62 })
63 else:
64 vals = super(product_template, self)._compute_procurement_vals(vals)
65 return vals
66
67 def _check_sellers(self, cr, uid, ids, procurement_type, context=None):
68 dd_flag = procurement_type == 'direct_delivery'
69 seller_pool = self.pool['product.supplierinfo']
70 seller_ids = seller_pool.search(cr, uid, [('product_id', 'in', ids)],
71 context=context)
72 if seller_ids:
73 seller_pool.write(cr, uid, seller_ids,
74 {'direct_delivery_flag': dd_flag},
75 context=context)
76 else:
77 if dd_flag:
78 raise orm.except_orm(
79 _('Warning'),
80 _('No suppliers defined'))
81
82 _columns = {
83 'procurement_type': fields.selection(
84 get_procurement_type_selection,
85 'Procurement Type',
86 required=True,
87 help='On stock, buy: Procurement Method: Make to Stock, '
88 'Supply Method: Buy.\n'
89 'On stock, produce: Procurement Method: Make to Stock, '
90 'Supply Method: Produce.\n'
91 'On order, buy: Procurement Method: Make to Order, '
92 'Supply Method: Buy.\n'
93 'On order, produce: Procurement Method: Make to Order, '
94 'Supply Method: Produce.\n'
95 'DropShipping: Procurement Method: Make to Order, '
96 'Supply Method: Buy + supplier does drop shipping'),
97 }
98
99 def onchange_procurement_type(self, cr, uid, ids, type,
100 procurement_type, context=None):
101 res = super(product_template, self).\
102 onchange_procurement_type(cr,
103 uid,
104 ids,
105 type,
106 procurement_type)
107 if type != 'service':
108 res['value'].update(
109 self._compute_procurement_vals(
110 {'procurement_type': procurement_type})
111 )
112 self._check_sellers(cr, uid, ids, procurement_type,
113 context=context)
114 return res
115
0116
=== added file 'product_procurement_type_dropshipping/product_view.xml'
--- product_procurement_type_dropshipping/product_view.xml 1970-01-01 00:00:00 +0000
+++ product_procurement_type_dropshipping/product_view.xml 2014-06-10 15:36:28 +0000
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="view_product_supplier_context_dropshipping" model="ir.ui.view">
5 <field name="name">product.supplier.context.dropshipping</field>
6 <field name="model">product.product</field>
7 <field name="inherit_id" ref="purchase.view_product_supplier_inherit"/>
8 <field name="arch" type="xml">
9 <data>
10 <field name="seller_ids" position="attributes">
11 <attribute name="context">{'uom_id': uom_id, 'default_direct_delivery_flag': procurement_type == 'direct_delivery'}</attribute>
12 </field>
13 </data>
14 </field>
15 </record>
16 </data>
17</openerp>
018
=== added directory 'product_procurement_type_dropshipping/test'
=== added file 'product_procurement_type_dropshipping/test/test_onchange_procurement_type.yml'
--- product_procurement_type_dropshipping/test/test_onchange_procurement_type.yml 1970-01-01 00:00:00 +0000
+++ product_procurement_type_dropshipping/test/test_onchange_procurement_type.yml 2014-06-10 15:36:28 +0000
@@ -0,0 +1,52 @@
1-
2 Testing change of procurement type on product
3-
4 I create a product "Jalousie"
5-
6 !record {model: product.product, id: product3}:
7 name: Jalousie
8 type: product
9-
10 I define the product with dropshipping
11 but it fails because the product has no suppliers defined.
12-
13 !python {model: product.product}: |
14 from openerp.osv import orm
15 product3_id = ref("product3")
16 try:
17 self.write(cr, uid, [product3_id], {'procurement_type': 'direct_delivery'})
18 except orm.except_orm as err:
19 assert 'Error Expected'
20-
21 I create a supplier "Dupont"
22-
23 !record {model: res.partner, id: partner1}:
24 name: Dupont
25 supplier: True
26-
27 I set this supplier on the product "Jalousie"
28-
29 !record {model: product.supplierinfo, id: psupinfo1}:
30 name: partner1
31 product_id: product3
32 min_qty: 1.0
33-
34 I define dropshipping on the product.
35-
36 !python {model: product.product}: |
37 product3_id = ref("product3")
38 try:
39 values = self.onchange_procurement_type(cr, uid, [product3_id], 'product', 'direct_delivery')
40 self.write(cr, uid, [product3_id], values['value'])
41 except:
42 raise AssertionError('Expected no error')
43-
44 I check if the product is now made to order
45-
46 !assert {model: product.product, id: product3}:
47 - procure_method == 'make_to_order'
48-
49 I check if supplier is checked as doing dropshipping
50-
51 !assert {model: product.supplierinfo, id: psupinfo1}:
52 - direct_delivery_flag == 1
0\ No newline at end of file53\ No newline at end of file

Subscribers

People subscribed via source and target branches