Merge lp:~unifield-team/unifield-addons/uf-108-default-supplier-suggestion into lp:unifield-addons
- uf-108-default-supplier-suggestion
- Merge into trunk
Proposed by
Quentin THEURET @Amaris
Status: | Rejected |
---|---|
Rejected by: | jftempo |
Proposed branch: | lp:~unifield-team/unifield-addons/uf-108-default-supplier-suggestion |
Merge into: | lp:unifield-addons |
Diff against target: |
2254 lines (+872/-1096) 27 files modified
msf_partner/__init__.py (+0/-27) msf_partner/__openerp__.py (+0/-49) msf_partner/partner.py (+0/-45) msf_partner/partner_demo.xml (+0/-46) msf_partner/partner_view.xml (+0/-56) msf_partner/product.py (+0/-38) msf_partner/product_view.xml (+0/-31) msf_partner/test/msf_partner.yml (+0/-18) procurement_list/__init__.py (+1/-0) procurement_list/__openerp__.py (+3/-0) procurement_list/partner.py (+92/-0) procurement_list/partner_view.xml (+27/-0) procurement_list/procurement_list.py (+123/-36) procurement_list/procurement_list_view.xml (+12/-4) procurement_list/security/ir.model.access.csv (+1/-1) procurement_list/test/procurement_list.yml (+312/-65) procurement_list/wizard/__init__.py (+1/-0) procurement_list/wizard/choose_supplier.py (+241/-0) procurement_list/wizard/choose_supplier_view.xml (+59/-0) stock_inventory_type/__init__.py (+0/-28) stock_inventory_type/__openerp__.py (+0/-49) stock_inventory_type/security/ir.model.access.csv (+0/-2) stock_inventory_type/stock.py (+0/-135) stock_inventory_type/stock_data.xml (+0/-23) stock_inventory_type/stock_move_report.py (+0/-130) stock_inventory_type/stock_view.xml (+0/-196) stock_inventory_type/test/adjustment_type.yml (+0/-117) |
To merge this branch: | bzr merge lp:~unifield-team/unifield-addons/uf-108-default-supplier-suggestion |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
jftempo | Needs Fixing | ||
Review via email: mp+53861@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 4473. By Quentin THEURET <quentin@tempo-quentin>
-
UF-108: [IMP] Set supplier selection on procurement.
list.line and move buttons create_rfq, create_po from procurement. choose. supplier to procurement.list
Unmerged revisions
- 4473. By Quentin THEURET <quentin@tempo-quentin>
-
UF-108: [IMP] Set supplier selection on procurement.
list.line and move buttons create_rfq, create_po from procurement. choose. supplier to procurement.list
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed directory 'msf_partner' | |||
2 | === removed file 'msf_partner/__init__.py' | |||
3 | --- msf_partner/__init__.py 2011-03-15 15:01:14 +0000 | |||
4 | +++ msf_partner/__init__.py 1970-01-01 00:00:00 +0000 | |||
5 | @@ -1,27 +0,0 @@ | |||
6 | 1 | #!/usr/bin/env python | ||
7 | 2 | # -*- encoding: utf-8 -*- | ||
8 | 3 | ############################################################################## | ||
9 | 4 | # | ||
10 | 5 | # OpenERP, Open Source Management Solution | ||
11 | 6 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
12 | 7 | # | ||
13 | 8 | # This program is free software: you can redistribute it and/or modify | ||
14 | 9 | # it under the terms of the GNU Affero General Public License as | ||
15 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
16 | 11 | # License, or (at your option) any later version. | ||
17 | 12 | # | ||
18 | 13 | # This program is distributed in the hope that it will be useful, | ||
19 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | 16 | # GNU Affero General Public License for more details. | ||
22 | 17 | # | ||
23 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
24 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
25 | 20 | # | ||
26 | 21 | ############################################################################## | ||
27 | 22 | |||
28 | 23 | import partner | ||
29 | 24 | import product | ||
30 | 25 | |||
31 | 26 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
32 | 27 | |||
33 | 28 | 0 | ||
34 | === removed file 'msf_partner/__openerp__.py' | |||
35 | --- msf_partner/__openerp__.py 2011-03-15 15:01:14 +0000 | |||
36 | +++ msf_partner/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
37 | @@ -1,49 +0,0 @@ | |||
38 | 1 | # -*- coding: utf-8 -*- | ||
39 | 2 | ############################################################################## | ||
40 | 3 | # | ||
41 | 4 | # OpenERP, Open Source Management Solution | ||
42 | 5 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
43 | 6 | # | ||
44 | 7 | # This program is free software: you can redistribute it and/or modify | ||
45 | 8 | # it under the terms of the GNU Affero General Public License as | ||
46 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
47 | 10 | # License, or (at your option) any later version. | ||
48 | 11 | # | ||
49 | 12 | # This program is distributed in the hope that it will be useful, | ||
50 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
51 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
52 | 15 | # GNU Affero General Public License for more details. | ||
53 | 16 | # | ||
54 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
55 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
56 | 19 | # | ||
57 | 20 | ############################################################################## | ||
58 | 21 | { | ||
59 | 22 | "name" : "MSF Partners", | ||
60 | 23 | "version" : "1.0", | ||
61 | 24 | "author" : "TeMPO Consulting, MSF", | ||
62 | 25 | "category": "Others", | ||
63 | 26 | "description": """ | ||
64 | 27 | This modules aims to differentiate Internal/External partners | ||
65 | 28 | It also aims to create a new type of partner: Manufacturer | ||
66 | 29 | """, | ||
67 | 30 | "website": "http://unifield.msf.org", | ||
68 | 31 | "init_xml": [ | ||
69 | 32 | ], | ||
70 | 33 | "depends" : [ | ||
71 | 34 | "base", | ||
72 | 35 | "product", | ||
73 | 36 | ], | ||
74 | 37 | "update_xml": [ | ||
75 | 38 | "partner_view.xml", | ||
76 | 39 | "product_view.xml", | ||
77 | 40 | ], | ||
78 | 41 | "demo_xml": [ | ||
79 | 42 | "partner_demo.xml", | ||
80 | 43 | ], | ||
81 | 44 | "test": [ | ||
82 | 45 | "test/msf_partner.yml", | ||
83 | 46 | ], | ||
84 | 47 | "installable": True, | ||
85 | 48 | "active": False, | ||
86 | 49 | } | ||
87 | 50 | 0 | ||
88 | === removed file 'msf_partner/partner.py' | |||
89 | --- msf_partner/partner.py 2011-03-15 15:01:14 +0000 | |||
90 | +++ msf_partner/partner.py 1970-01-01 00:00:00 +0000 | |||
91 | @@ -1,45 +0,0 @@ | |||
92 | 1 | #!/usr/bin/env python | ||
93 | 2 | # -*- encoding: utf-8 -*- | ||
94 | 3 | ############################################################################## | ||
95 | 4 | # | ||
96 | 5 | # OpenERP, Open Source Management Solution | ||
97 | 6 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
98 | 7 | # | ||
99 | 8 | # This program is free software: you can redistribute it and/or modify | ||
100 | 9 | # it under the terms of the GNU Affero General Public License as | ||
101 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
102 | 11 | # License, or (at your option) any later version. | ||
103 | 12 | # | ||
104 | 13 | # This program is distributed in the hope that it will be useful, | ||
105 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
106 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
107 | 16 | # GNU Affero General Public License for more details. | ||
108 | 17 | # | ||
109 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
110 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
111 | 20 | # | ||
112 | 21 | ############################################################################## | ||
113 | 22 | |||
114 | 23 | from osv import osv | ||
115 | 24 | from osv import fields | ||
116 | 25 | |||
117 | 26 | |||
118 | 27 | class res_partner(osv.osv): | ||
119 | 28 | _name = 'res.partner' | ||
120 | 29 | _inherit = 'res.partner' | ||
121 | 30 | |||
122 | 31 | _columns = { | ||
123 | 32 | 'manufacturer': fields.boolean(string='Manufacturer', help='Check this box if the partner is a manufacturer'), | ||
124 | 33 | 'partner_type': fields.selection([('internal', 'Internal'), ('section', 'Inter-section'), | ||
125 | 34 | ('external', 'External')], string='Partner type', required=True), | ||
126 | 35 | } | ||
127 | 36 | |||
128 | 37 | _defaults = { | ||
129 | 38 | 'manufacturer': lambda *a: False, | ||
130 | 39 | 'partner_type': lambda *a: 'internal', | ||
131 | 40 | } | ||
132 | 41 | |||
133 | 42 | res_partner() | ||
134 | 43 | |||
135 | 44 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
136 | 45 | |||
137 | 46 | 0 | ||
138 | === removed file 'msf_partner/partner_demo.xml' | |||
139 | --- msf_partner/partner_demo.xml 2011-03-15 14:05:12 +0000 | |||
140 | +++ msf_partner/partner_demo.xml 1970-01-01 00:00:00 +0000 | |||
141 | @@ -1,46 +0,0 @@ | |||
142 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
143 | 2 | <openerp> | ||
144 | 3 | <data noupdate="0"> | ||
145 | 4 | |||
146 | 5 | <record id="base.res_partner_desertic_hispafuentes" model="res.partner"> | ||
147 | 6 | <field name="manufacturer">1</field> | ||
148 | 7 | <field name="partner_type">section</field> | ||
149 | 8 | </record> | ||
150 | 9 | |||
151 | 10 | <record id="base.res_partner_tinyatwork" model="res.partner"> | ||
152 | 11 | <field name="manufacturer">1</field> | ||
153 | 12 | </record> | ||
154 | 13 | |||
155 | 14 | <record id="base.res_partner_asus" model="res.partner"> | ||
156 | 15 | <field name="partner_type">external</field> | ||
157 | 16 | </record> | ||
158 | 17 | <record id="base.res_partner_agrolait" model="res.partner"> | ||
159 | 18 | <field name="partner_type">external</field> | ||
160 | 19 | </record> | ||
161 | 20 | <record id="base.res_partner_c2c" model="res.partner"> | ||
162 | 21 | <field name="partner_type">section</field> | ||
163 | 22 | </record> | ||
164 | 23 | <record id="base.res_partner_sednacom" model="res.partner"> | ||
165 | 24 | <field name="partner_type">internal</field> | ||
166 | 25 | </record> | ||
167 | 26 | <record id="base.res_partner_thymbra" model="res.partner"> | ||
168 | 27 | <field name="partner_type">internal</field> | ||
169 | 28 | </record> | ||
170 | 29 | |||
171 | 30 | <record id="product.supplierinfo10" model="product.supplierinfo"> | ||
172 | 31 | <field name="manufacturer_id" ref="base.res_partner_tinyatwork" /> | ||
173 | 32 | </record> | ||
174 | 33 | |||
175 | 34 | <record id="product.supplierinfo11" model="product.supplierinfo"> | ||
176 | 35 | <field name="manufacturer_id" ref="base.res_partner_tinyatwork" /> | ||
177 | 36 | </record> | ||
178 | 37 | |||
179 | 38 | <record id="product.supplierinfo6" model="product.supplierinfo"> | ||
180 | 39 | <field name="manufacturer_id" ref="base.res_partner_desertic_hispafuentes" /> | ||
181 | 40 | </record> | ||
182 | 41 | |||
183 | 42 | <record id="product.supplierinfo7" model="product.supplierinfo"> | ||
184 | 43 | <field name="manufacturer_id" ref="base.res_partner_tinyatwork" /> | ||
185 | 44 | </record> | ||
186 | 45 | </data> | ||
187 | 46 | </openerp> | ||
188 | 47 | 0 | ||
189 | === removed file 'msf_partner/partner_view.xml' | |||
190 | --- msf_partner/partner_view.xml 2011-03-15 15:01:14 +0000 | |||
191 | +++ msf_partner/partner_view.xml 1970-01-01 00:00:00 +0000 | |||
192 | @@ -1,56 +0,0 @@ | |||
193 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
194 | 2 | <openerp> | ||
195 | 3 | <data> | ||
196 | 4 | |||
197 | 5 | <record id="msf_view_partner_tree" model="ir.ui.view"> | ||
198 | 6 | <field name="name">msf.view.partner.tree</field> | ||
199 | 7 | <field name="model">res.partner</field> | ||
200 | 8 | <field name="type">tree</field> | ||
201 | 9 | <field name="inherit_id" ref="base.view_partner_tree" /> | ||
202 | 10 | <field name="arch" type="xml"> | ||
203 | 11 | <xpath expr="/tree/field[@name='ref']" position="after"> | ||
204 | 12 | <field name="partner_type" /> | ||
205 | 13 | </xpath> | ||
206 | 14 | </field> | ||
207 | 15 | </record> | ||
208 | 16 | |||
209 | 17 | <record id="msf_view_partner_form" model="ir.ui.view"> | ||
210 | 18 | <field name="name">msf.view.partner.form</field> | ||
211 | 19 | <field name="model">res.partner</field> | ||
212 | 20 | <field name="type">form</field> | ||
213 | 21 | <field name="inherit_id" ref="base.view_partner_form" /> | ||
214 | 22 | <field name="arch" type="xml"> | ||
215 | 23 | <data> | ||
216 | 24 | <xpath expr="/form/group/group/field[@name='title']" position="replace"> | ||
217 | 25 | <field name="partner_type" /> | ||
218 | 26 | </xpath> | ||
219 | 27 | <xpath expr="/form/group/group[2]/field[@name='supplier']" position="after"> | ||
220 | 28 | <field name="manufacturer" /> | ||
221 | 29 | </xpath> | ||
222 | 30 | </data> | ||
223 | 31 | </field> | ||
224 | 32 | </record> | ||
225 | 33 | |||
226 | 34 | <record id="msf_view_res_partner_filter" model="ir.ui.view"> | ||
227 | 35 | <field name="name">msf.view.res.partner.filter</field> | ||
228 | 36 | <field name="model">res.partner</field> | ||
229 | 37 | <field name="type">search</field> | ||
230 | 38 | <field name="inherit_id" ref="base.view_res_partner_filter" /> | ||
231 | 39 | <field name="arch" type="xml"> | ||
232 | 40 | <data> | ||
233 | 41 | <xpath expr="/search/group/filter[@name='supplier']" position="after"> | ||
234 | 42 | <filter string="Manufacturers" name="manufacturer" icon="terp-personal" domain="[('manufacturer','=',1)]" help="Manufacturer Partners"/> | ||
235 | 43 | </xpath> | ||
236 | 44 | <xpath expr="/search/group/field[@name='name']" position="before"> | ||
237 | 45 | <filter string="Internal" name="internal" icon="gtk-leave-fullscreen" domain="[('partner_type','=','internal')]" help="Internal Partners"/> | ||
238 | 46 | <filter string="Inter-section" name="inter-section" icon="gtk-refresh" domain="[('partner_type','=','section')]" help="Inter-section Partners"/> | ||
239 | 47 | <filter string="External" name="external" icon="gtk-quit" domain="[('partner_type','=','external')]" help="External Partners"/> | ||
240 | 48 | <separator orientation="vertical" /> | ||
241 | 49 | </xpath> | ||
242 | 50 | </data> | ||
243 | 51 | </field> | ||
244 | 52 | </record> | ||
245 | 53 | |||
246 | 54 | </data> | ||
247 | 55 | </openerp> | ||
248 | 56 | |||
249 | 57 | 0 | ||
250 | === removed file 'msf_partner/product.py' | |||
251 | --- msf_partner/product.py 2011-03-15 15:01:14 +0000 | |||
252 | +++ msf_partner/product.py 1970-01-01 00:00:00 +0000 | |||
253 | @@ -1,38 +0,0 @@ | |||
254 | 1 | #!/usr/bin/env python | ||
255 | 2 | # -*- encoding: utf-8 -*- | ||
256 | 3 | ############################################################################## | ||
257 | 4 | # | ||
258 | 5 | # OpenERP, Open Source Management Solution | ||
259 | 6 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
260 | 7 | # | ||
261 | 8 | # This program is free software: you can redistribute it and/or modify | ||
262 | 9 | # it under the terms of the GNU Affero General Public License as | ||
263 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
264 | 11 | # License, or (at your option) any later version. | ||
265 | 12 | # | ||
266 | 13 | # This program is distributed in the hope that it will be useful, | ||
267 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
268 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
269 | 16 | # GNU Affero General Public License for more details. | ||
270 | 17 | # | ||
271 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
272 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
273 | 20 | # | ||
274 | 21 | ############################################################################## | ||
275 | 22 | |||
276 | 23 | from osv import osv | ||
277 | 24 | from osv import fields | ||
278 | 25 | |||
279 | 26 | |||
280 | 27 | class product_supplierinfo(osv.osv): | ||
281 | 28 | _name = 'product.supplierinfo' | ||
282 | 29 | _inherit = 'product.supplierinfo' | ||
283 | 30 | |||
284 | 31 | _columns = { | ||
285 | 32 | 'manufacturer_id': fields.many2one('res.partner', string='Manufacturer', domain=[('manufacturer', '=', 1)]), | ||
286 | 33 | } | ||
287 | 34 | |||
288 | 35 | product_supplierinfo() | ||
289 | 36 | |||
290 | 37 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
291 | 38 | |||
292 | 39 | 0 | ||
293 | === removed file 'msf_partner/product_view.xml' | |||
294 | --- msf_partner/product_view.xml 2011-03-10 09:07:17 +0000 | |||
295 | +++ msf_partner/product_view.xml 1970-01-01 00:00:00 +0000 | |||
296 | @@ -1,31 +0,0 @@ | |||
297 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
298 | 2 | <openerp> | ||
299 | 3 | <data> | ||
300 | 4 | |||
301 | 5 | <record id="manufacturer_supplierinfo_form_view" model="ir.ui.view"> | ||
302 | 6 | <field name="name">manufacture.supplierinfo.form.view</field> | ||
303 | 7 | <field name="model">product.supplierinfo</field> | ||
304 | 8 | <field name="type">form</field> | ||
305 | 9 | <field name="inherit_id" ref="product.product_supplierinfo_form_view" /> | ||
306 | 10 | <field name="arch" type="xml"> | ||
307 | 11 | <xpath expr="/form/field[@name='product_code']" position="after"> | ||
308 | 12 | <field name="manufacturer_id" /> | ||
309 | 13 | </xpath> | ||
310 | 14 | </field> | ||
311 | 15 | </record> | ||
312 | 16 | |||
313 | 17 | <record id="manufacturer_supplierinfo_tree_view" model="ir.ui.view"> | ||
314 | 18 | <field name="name">manufacturer.supplierinfo.tree.view</field> | ||
315 | 19 | <field name="model">product.supplierinfo</field> | ||
316 | 20 | <field name="type">tree</field> | ||
317 | 21 | <field name="inherit_id" ref="product.product_supplierinfo_tree_view" /> | ||
318 | 22 | <field name="arch" type="xml"> | ||
319 | 23 | <xpath expr="/tree/field[@name='min_qty']" position="after"> | ||
320 | 24 | <field name="manufacturer_id" /> | ||
321 | 25 | </xpath> | ||
322 | 26 | </field> | ||
323 | 27 | </record> | ||
324 | 28 | |||
325 | 29 | </data> | ||
326 | 30 | </openerp> | ||
327 | 31 | |||
328 | 32 | 0 | ||
329 | === removed directory 'msf_partner/test' | |||
330 | === removed file 'msf_partner/test/msf_partner.yml' | |||
331 | --- msf_partner/test/msf_partner.yml 2011-03-15 15:01:14 +0000 | |||
332 | +++ msf_partner/test/msf_partner.yml 1970-01-01 00:00:00 +0000 | |||
333 | @@ -1,18 +0,0 @@ | |||
334 | 1 | - | ||
335 | 2 | In order to test the module msf_partne, I will create a partner | ||
336 | 3 | and check that the default values are well applied. | ||
337 | 4 | - | ||
338 | 5 | I create the first partner | ||
339 | 6 | - | ||
340 | 7 | !record {model: res.partner, id: partner1}: | ||
341 | 8 | name: A | ||
342 | 9 | supplier: 1 | ||
343 | 10 | customer: 1 | ||
344 | 11 | address: | ||
345 | 12 | - name: A | ||
346 | 13 | - | ||
347 | 14 | I check if the default values are good | ||
348 | 15 | - | ||
349 | 16 | !assert {model: res.partner, id: partner1}: | ||
350 | 17 | - partner_type == 'internal', "Default value 'internal' for partner_type is not applied" | ||
351 | 18 | - manufacturer == 0, "Default value 'False' for manufacturer is not applied" | ||
352 | 19 | 0 | ||
353 | === modified file 'procurement_list/__init__.py' | |||
354 | --- procurement_list/__init__.py 2011-03-16 13:17:54 +0000 | |||
355 | +++ procurement_list/__init__.py 2011-03-24 15:56:19 +0000 | |||
356 | @@ -20,6 +20,7 @@ | |||
357 | 20 | ############################################################################## | 20 | ############################################################################## |
358 | 21 | 21 | ||
359 | 22 | import procurement_list | 22 | import procurement_list |
360 | 23 | import partner | ||
361 | 23 | import wizard | 24 | import wizard |
362 | 24 | 25 | ||
363 | 25 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | 26 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
364 | 26 | 27 | ||
365 | === modified file 'procurement_list/__openerp__.py' | |||
366 | --- procurement_list/__openerp__.py 2011-03-16 18:18:33 +0000 | |||
367 | +++ procurement_list/__openerp__.py 2011-03-24 15:56:19 +0000 | |||
368 | @@ -32,13 +32,16 @@ | |||
369 | 32 | 'init_xml': [ | 32 | 'init_xml': [ |
370 | 33 | ], | 33 | ], |
371 | 34 | 'depends' : [ | 34 | 'depends' : [ |
372 | 35 | 'base', | ||
373 | 35 | 'purchase', | 36 | 'purchase', |
374 | 36 | ], | 37 | ], |
375 | 37 | 'update_xml': [ | 38 | 'update_xml': [ |
376 | 38 | 'procurement_list_sequence.xml', | 39 | 'procurement_list_sequence.xml', |
377 | 39 | 'procurement_list_view.xml', | 40 | 'procurement_list_view.xml', |
378 | 41 | 'partner_view.xml', | ||
379 | 40 | 'procurement_list_wizard.xml', | 42 | 'procurement_list_wizard.xml', |
380 | 41 | 'wizard/wizard_import_list_view.xml', | 43 | 'wizard/wizard_import_list_view.xml', |
381 | 44 | 'wizard/choose_supplier_view.xml', | ||
382 | 42 | 'security/ir.model.access.csv', | 45 | 'security/ir.model.access.csv', |
383 | 43 | ], | 46 | ], |
384 | 44 | 'demo_xml': [ | 47 | 'demo_xml': [ |
385 | 45 | 48 | ||
386 | === added file 'procurement_list/partner.py' | |||
387 | --- procurement_list/partner.py 1970-01-01 00:00:00 +0000 | |||
388 | +++ procurement_list/partner.py 2011-03-24 15:56:19 +0000 | |||
389 | @@ -0,0 +1,92 @@ | |||
390 | 1 | #!/usr/bin/env python | ||
391 | 2 | # -*- encoding: utf-8 -*- | ||
392 | 3 | ############################################################################## | ||
393 | 4 | # | ||
394 | 5 | # OpenERP, Open Source Management Solution | ||
395 | 6 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
396 | 7 | # | ||
397 | 8 | # This program is free software: you can redistribute it and/or modify | ||
398 | 9 | # it under the terms of the GNU Affero General Public License as | ||
399 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
400 | 11 | # License, or (at your option) any later version. | ||
401 | 12 | # | ||
402 | 13 | # This program is distributed in the hope that it will be useful, | ||
403 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
404 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
405 | 16 | # GNU Affero General Public License for more details. | ||
406 | 17 | # | ||
407 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
408 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
409 | 20 | # | ||
410 | 21 | ############################################################################## | ||
411 | 22 | |||
412 | 23 | from osv import osv | ||
413 | 24 | from osv import fields | ||
414 | 25 | |||
415 | 26 | class res_partner(osv.osv): | ||
416 | 27 | _name= 'res.partner' | ||
417 | 28 | _inherit = 'res.partner' | ||
418 | 29 | |||
419 | 30 | _order = 'name' | ||
420 | 31 | |||
421 | 32 | def _set_in_product(self, cr, uid, ids, field_name, arg, context={}): | ||
422 | 33 | ''' | ||
423 | 34 | Returns according to the context if the partner is in product form | ||
424 | 35 | ''' | ||
425 | 36 | res = {} | ||
426 | 37 | |||
427 | 38 | product_obj = self.pool.get('product.product') | ||
428 | 39 | |||
429 | 40 | # If we aren't in the context of choose supplier on procurement list | ||
430 | 41 | if not context.get('product_id', False) or 'choose_supplier' not in context: | ||
431 | 42 | for i in ids: | ||
432 | 43 | res[i] = False | ||
433 | 44 | else: | ||
434 | 45 | product = product_obj.browse(cr, uid, context.get('product_id')) | ||
435 | 46 | seller_ids = [] | ||
436 | 47 | # Get all suppliers defined on product form | ||
437 | 48 | for s in product.seller_ids: | ||
438 | 49 | seller_ids.append(s.name.id) | ||
439 | 50 | # Check if the partner is in product form | ||
440 | 51 | for i in ids: | ||
441 | 52 | if i in seller_ids: | ||
442 | 53 | res[i] = True | ||
443 | 54 | else: | ||
444 | 55 | res[i] = False | ||
445 | 56 | |||
446 | 57 | return res | ||
447 | 58 | |||
448 | 59 | _columns = { | ||
449 | 60 | 'in_product': fields.function(_set_in_product, string='In product', type="boolean", readonly=True, method=True), | ||
450 | 61 | } | ||
451 | 62 | |||
452 | 63 | def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'): | ||
453 | 64 | ''' | ||
454 | 65 | Sort the supplier according to the context | ||
455 | 66 | ''' | ||
456 | 67 | res = super(res_partner, self).read(cr, uid, ids, fields, context=context, load=load) | ||
457 | 68 | # If we are in the context of choose supplier on procurement list | ||
458 | 69 | if context.get('product_id', False) and 'choose_supplier' in context: | ||
459 | 70 | # Add in_product field in read | ||
460 | 71 | if not 'in_product' in fields: | ||
461 | 72 | fields.append('in_product') | ||
462 | 73 | |||
463 | 74 | seller_ids =[] | ||
464 | 75 | not_seller_ids = [] | ||
465 | 76 | |||
466 | 77 | for r in res: | ||
467 | 78 | if r.get('in_product', False): | ||
468 | 79 | seller_ids.append(r) | ||
469 | 80 | else: | ||
470 | 81 | not_seller_ids.append(r) | ||
471 | 82 | |||
472 | 83 | result = seller_ids + not_seller_ids | ||
473 | 84 | else: | ||
474 | 85 | result = res | ||
475 | 86 | |||
476 | 87 | return result | ||
477 | 88 | |||
478 | 89 | res_partner() | ||
479 | 90 | |||
480 | 91 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
481 | 92 | |||
482 | 0 | 93 | ||
483 | === added file 'procurement_list/partner_view.xml' | |||
484 | --- procurement_list/partner_view.xml 1970-01-01 00:00:00 +0000 | |||
485 | +++ procurement_list/partner_view.xml 2011-03-24 15:56:19 +0000 | |||
486 | @@ -0,0 +1,27 @@ | |||
487 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
488 | 2 | <openerp> | ||
489 | 3 | <data> | ||
490 | 4 | |||
491 | 5 | <record id="in_product_view_partner_tree" model="ir.ui.view"> | ||
492 | 6 | <field name="name">in.product.view.partner.tree</field> | ||
493 | 7 | <field name="model">res.partner</field> | ||
494 | 8 | <field name="type">tree</field> | ||
495 | 9 | <field name="inherit_id" ref="base.view_partner_tree" /> | ||
496 | 10 | <field name="arch" type="xml"> | ||
497 | 11 | <xpath expr="/tree" position="replace"> | ||
498 | 12 | <tree string="Partners" colors="red:in_product==True"> | ||
499 | 13 | <field name="name" /> | ||
500 | 14 | <field name="ref" groups="base.group_extended" /> | ||
501 | 15 | <field name="phone" /> | ||
502 | 16 | <field name="email" /> | ||
503 | 17 | <field name="city" /> | ||
504 | 18 | <field name="country" /> | ||
505 | 19 | <field name="user_id" /> | ||
506 | 20 | <field name="in_product" invisible="1" /> | ||
507 | 21 | </tree> | ||
508 | 22 | </xpath> | ||
509 | 23 | </field> | ||
510 | 24 | </record> | ||
511 | 25 | |||
512 | 26 | </data> | ||
513 | 27 | </openerp> | ||
514 | 0 | \ No newline at end of file | 28 | \ No newline at end of file |
515 | 1 | 29 | ||
516 | === modified file 'procurement_list/procurement_list.py' | |||
517 | --- procurement_list/procurement_list.py 2011-03-16 18:05:16 +0000 | |||
518 | +++ procurement_list/procurement_list.py 2011-03-24 15:56:19 +0000 | |||
519 | @@ -43,10 +43,6 @@ | |||
520 | 43 | 'line_ids': fields.one2many('procurement.list.line', 'list_id', string='Lines', readonly=True, | 43 | 'line_ids': fields.one2many('procurement.list.line', 'list_id', string='Lines', readonly=True, |
521 | 44 | states={'draft': [('readonly', False)]}), | 44 | states={'draft': [('readonly', False)]}), |
522 | 45 | 'notes': fields.text(string='Notes'), | 45 | 'notes': fields.text(string='Notes'), |
523 | 46 | 'supplier_ids': fields.many2many('res.partner', 'procurement_list_supplier_rel', | ||
524 | 47 | 'list_id', 'supplier_id', string='Suppliers', | ||
525 | 48 | domain="[('supplier', '=', True)]", | ||
526 | 49 | states={'done': [('readonly', True)]}), | ||
527 | 50 | 'order_ids': fields.many2many('purchase.order', 'procurement_list_order_rel', | 46 | 'order_ids': fields.many2many('purchase.order', 'procurement_list_order_rel', |
528 | 51 | 'list_id', 'order_id', string='Orders', readonly=True), | 47 | 'list_id', 'order_id', string='Orders', readonly=True), |
529 | 52 | } | 48 | } |
530 | @@ -75,6 +71,82 @@ | |||
531 | 75 | self.write(cr, uid, ids, {'state': 'cancel'}) | 71 | self.write(cr, uid, ids, {'state': 'cancel'}) |
532 | 76 | 72 | ||
533 | 77 | return True | 73 | return True |
534 | 74 | |||
535 | 75 | def create_po(self, cr, uid, ids, context={}): | ||
536 | 76 | ''' | ||
537 | 77 | Creates all purchase orders according to choices on lines | ||
538 | 78 | ''' | ||
539 | 79 | if ids and isinstance(ids, (int, long)): | ||
540 | 80 | ids = [ids] | ||
541 | 81 | |||
542 | 82 | order_obj = self.pool.get('purchase.order') | ||
543 | 83 | order_line_obj = self.pool.get('purchase.order.line') | ||
544 | 84 | proc_obj = self.pool.get('procurement.list') | ||
545 | 85 | line_obj = self.pool.get('procurement.list.line') | ||
546 | 86 | prod_sup_obj = self.pool.get('product.supplierinfo') | ||
547 | 87 | |||
548 | 88 | # We search if at least one line hasn't defined supplier | ||
549 | 89 | for list in self.browse(cr, uid, ids): | ||
550 | 90 | for line in list.line_ids: | ||
551 | 91 | if not line.supplier_id: | ||
552 | 92 | raise osv.except_osv(_('Error'), _('You cannot create purchase orders while all lines haven\'t a defined supplier')) | ||
553 | 93 | |||
554 | 94 | # We search lines group by supplier_id | ||
555 | 95 | po_exists = {} | ||
556 | 96 | po_id = False | ||
557 | 97 | po_ids = [] | ||
558 | 98 | line_ids = line_obj.search(cr, uid, [('list_id', 'in', ids)], order='supplier_id') | ||
559 | 99 | for l in line_obj.browse(cr, uid, line_ids): | ||
560 | 100 | # Search if a PO already exists in the system | ||
561 | 101 | if not po_exists.get(l.supplier_id.id, False): | ||
562 | 102 | # If no PO in local memory, search in DB | ||
563 | 103 | po_exist = order_obj.search(cr, uid, [('origin', '=', l.list_id.name), ('partner_id', '=', l.supplier_id.id)]) | ||
564 | 104 | if po_exist: | ||
565 | 105 | # A PO exists in DB, set the id in local memory | ||
566 | 106 | po_exists[l.supplier_id.id] = po_exist[0] | ||
567 | 107 | else: | ||
568 | 108 | # try to create a new PO, and set its id in local memory | ||
569 | 109 | address = l.supplier_id.address_get().get('default') | ||
570 | 110 | # Returns an error when the supplier has not defined address | ||
571 | 111 | if not address: | ||
572 | 112 | raise osv.except_osv(_('Error'), _('The supplier %s has no address defined on its form' %l.supplier_id.name)) | ||
573 | 113 | # When starting or when the supplier changed, we create a Purchase Order | ||
574 | 114 | po_id = order_obj.create(cr, uid, {'partner_id': l.supplier_id.id, | ||
575 | 115 | 'partner_address_id': address, | ||
576 | 116 | 'pricelist_id': l.supplier_id.property_product_pricelist.id, | ||
577 | 117 | 'origin': l.list_id.name, | ||
578 | 118 | 'location_id': proc_obj._get_location(cr, uid, l.list_id.warehouse_id)}) | ||
579 | 119 | po_exists[l.supplier_id.id] = po_id | ||
580 | 120 | |||
581 | 121 | # Get the PO id in local memory | ||
582 | 122 | po_id = po_exists.get(l.supplier_id.id) | ||
583 | 123 | |||
584 | 124 | # We create all lines for this supplier | ||
585 | 125 | price_unit = prod_sup_obj.price_get(cr, uid, [l.supplier_id.id], l.product_id.id, l.product_qty) | ||
586 | 126 | order_line_obj.create(cr, uid, {'product_uom': l.product_uom_id.id, | ||
587 | 127 | 'product_id': l.product_id.id, | ||
588 | 128 | 'order_id': po_id, | ||
589 | 129 | 'price_unit': price_unit[l.supplier_id.id], | ||
590 | 130 | 'date_planned': l.list_id.order_date, | ||
591 | 131 | 'product_qty': l.product_qty, | ||
592 | 132 | 'name': l.product_id.name,}) | ||
593 | 133 | |||
594 | 134 | for supplier in po_exists: | ||
595 | 135 | po_ids.append(po_exists.get(supplier)) | ||
596 | 136 | |||
597 | 137 | # We confirm all created orders | ||
598 | 138 | wf_service = netsvc.LocalService("workflow") | ||
599 | 139 | for po in po_ids: | ||
600 | 140 | wf_service.trg_validate(uid, 'purchase.order', po, 'purchase_confirm', cr) | ||
601 | 141 | |||
602 | 142 | proc_obj.write(cr, uid, ids[0], {'state': 'done', 'order_ids': [(6, 0, po_ids)]}) | ||
603 | 143 | |||
604 | 144 | return {'type': 'ir.actions.act_window', | ||
605 | 145 | 'res_model': 'purchase.order', | ||
606 | 146 | 'view_type': 'form', | ||
607 | 147 | 'view_mode': 'tree,form', | ||
608 | 148 | 'domain': [('id', 'in', po_ids)], | ||
609 | 149 | } | ||
610 | 78 | 150 | ||
611 | 79 | def create_rfq(self, cr, uid, ids, context={}): | 151 | def create_rfq(self, cr, uid, ids, context={}): |
612 | 80 | ''' | 152 | ''' |
613 | @@ -86,43 +158,21 @@ | |||
614 | 86 | order_ids = [] | 158 | order_ids = [] |
615 | 87 | 159 | ||
616 | 88 | for list in self.browse(cr, uid, ids, context=context): | 160 | for list in self.browse(cr, uid, ids, context=context): |
620 | 89 | # Returns an error message if no suppliers or no products | 161 | # Returns an error message if no products defined |
618 | 90 | if not list.supplier_ids or len(list.supplier_ids) == 0: | ||
619 | 91 | raise osv.except_osv(_('Error'), _('No supplier defined for this list !')) | ||
621 | 92 | if not list.line_ids or len(list.line_ids) == 0: | 162 | if not list.line_ids or len(list.line_ids) == 0: |
622 | 93 | raise osv.except_osv(_('Error'), _('No line defined for this list !')) | 163 | raise osv.except_osv(_('Error'), _('No line defined for this list !')) |
623 | 94 | 164 | ||
624 | 95 | location_id = self._get_location(cr, uid, list.warehouse_id) | 165 | location_id = self._get_location(cr, uid, list.warehouse_id) |
649 | 96 | # Creates a RfQ for each supplier... | 166 | |
650 | 97 | for supplier in list.supplier_ids: | 167 | context['active_ids'] = ids |
651 | 98 | po_id = purchase_obj.create(cr, uid, {'partner_id': supplier.id, | 168 | context['active_id'] = ids[0] |
628 | 99 | 'partner_address_id': supplier.address_get().get('default'), | ||
629 | 100 | 'pricelist_id': supplier.property_product_pricelist.id, | ||
630 | 101 | 'origin': list.name, | ||
631 | 102 | 'location_id': location_id}) | ||
632 | 103 | order_ids.append(po_id) | ||
633 | 104 | |||
634 | 105 | # ... with all lines... | ||
635 | 106 | for line in list.line_ids: | ||
636 | 107 | # ... which aren't from stock | ||
637 | 108 | if not line.from_stock: | ||
638 | 109 | line_obj.create(cr, uid, {'product_uom': line.product_uom_id.id, | ||
639 | 110 | 'product_id': line.product_id.id, | ||
640 | 111 | 'order_id': po_id, | ||
641 | 112 | 'price_unit': 0.00, | ||
642 | 113 | 'date_planned': list.order_date, | ||
643 | 114 | 'product_qty': line.product_qty, | ||
644 | 115 | 'procurement_line_id': line.id, | ||
645 | 116 | 'name': line.product_id.name,}) | ||
646 | 117 | self.pool.get('procurement.list.line').write(cr, uid, line.id, {'latest': 'RfQ In Progress'}) | ||
647 | 118 | |||
648 | 119 | self.write(cr, uid, ids, {'state': 'done', 'order_ids': [(6, 0, order_ids)]}) | ||
652 | 120 | 169 | ||
653 | 121 | return {'type': 'ir.actions.act_window', | 170 | return {'type': 'ir.actions.act_window', |
655 | 122 | 'res_model': 'purchase.order', | 171 | 'res_model': 'procurement.choose.supplier.rfq', |
656 | 172 | 'target': 'new', | ||
657 | 123 | 'view_type': 'form', | 173 | 'view_type': 'form', |
660 | 124 | 'view_mode': 'tree,form', | 174 | 'view_mode': 'form', |
661 | 125 | 'domain': [('id', 'in', order_ids)]} | 175 | 'context': context} |
662 | 126 | 176 | ||
663 | 127 | def reset(self, cr, uid, ids, context={}): | 177 | def reset(self, cr, uid, ids, context={}): |
664 | 128 | ''' | 178 | ''' |
665 | @@ -158,6 +208,7 @@ | |||
666 | 158 | 'from_stock': fields.boolean(string='From stock ?'), | 208 | 'from_stock': fields.boolean(string='From stock ?'), |
667 | 159 | 'latest': fields.char(size=64, string='Latest document', readonly=True), | 209 | 'latest': fields.char(size=64, string='Latest document', readonly=True), |
668 | 160 | 'list_id': fields.many2one('procurement.list', string='List', required=True, ondelete='cascade'), | 210 | 'list_id': fields.many2one('procurement.list', string='List', required=True, ondelete='cascade'), |
669 | 211 | 'supplier_id': fields.many2one('res.partner', string='Supplier'), | ||
670 | 161 | } | 212 | } |
671 | 162 | 213 | ||
672 | 163 | _defaults = { | 214 | _defaults = { |
673 | @@ -183,12 +234,48 @@ | |||
674 | 183 | 234 | ||
675 | 184 | v = {} | 235 | v = {} |
676 | 185 | if not product_id: | 236 | if not product_id: |
678 | 186 | v.update({'product_uom_id': False}) | 237 | v.update({'product_uom_id': False, 'supplier_id': False}) |
679 | 187 | else: | 238 | else: |
680 | 188 | product = product_obj.browse(cr, uid, product_id, context=context) | 239 | product = product_obj.browse(cr, uid, product_id, context=context) |
682 | 189 | v.update({'product_uom_id': product.uom_id.id}) | 240 | v.update({'product_uom_id': product.uom_id.id, 'supplier_id': product.seller_id.id}) |
683 | 190 | 241 | ||
684 | 191 | return {'value': v} | 242 | return {'value': v} |
685 | 243 | |||
686 | 244 | |||
687 | 245 | def split_line(self, cr, uid, ids, context={}): | ||
688 | 246 | ''' | ||
689 | 247 | Split a line into two lines | ||
690 | 248 | ''' | ||
691 | 249 | if ids and isinstance(ids, (int, long)): | ||
692 | 250 | ids = [ids] | ||
693 | 251 | for line in self.browse(cr, uid, ids): | ||
694 | 252 | state = line.list_id.state | ||
695 | 253 | context.update({'line_id': ids[0], 'state': state}) | ||
696 | 254 | return {'type': 'ir.actions.act_window', | ||
697 | 255 | 'res_model': 'procurement.list.line.split', | ||
698 | 256 | 'target': 'new', | ||
699 | 257 | 'view_type': 'form', | ||
700 | 258 | 'view_mode': 'form', | ||
701 | 259 | 'context': context, | ||
702 | 260 | } | ||
703 | 261 | |||
704 | 262 | def merge_line(self, cr, uid, ids, context={}): | ||
705 | 263 | ''' | ||
706 | 264 | Merges two lines | ||
707 | 265 | ''' | ||
708 | 266 | if ids and isinstance(ids, (int, long)): | ||
709 | 267 | ids = [ids] | ||
710 | 268 | for line in self.browse(cr, uid, ids): | ||
711 | 269 | state = line.list_id.state | ||
712 | 270 | context.update({'line_id': ids[0], 'state': state}) | ||
713 | 271 | |||
714 | 272 | return {'type': 'ir.actions.act_window', | ||
715 | 273 | 'res_model': 'procurement.list.line.merge', | ||
716 | 274 | 'target': 'new', | ||
717 | 275 | 'view_type': 'form', | ||
718 | 276 | 'view_mode': 'form', | ||
719 | 277 | 'context': context, | ||
720 | 278 | } | ||
721 | 192 | 279 | ||
722 | 193 | procurement_list_line() | 280 | procurement_list_line() |
723 | 194 | 281 | ||
724 | 195 | 282 | ||
725 | === modified file 'procurement_list/procurement_list_view.xml' | |||
726 | --- procurement_list/procurement_list_view.xml 2011-03-15 16:28:59 +0000 | |||
727 | +++ procurement_list/procurement_list_view.xml 2011-03-24 15:56:19 +0000 | |||
728 | @@ -1,6 +1,13 @@ | |||
729 | 1 | <?xml version="1.0" encoding="utf-8" ?> | 1 | <?xml version="1.0" encoding="utf-8" ?> |
730 | 2 | <openerp> | 2 | <openerp> |
731 | 3 | <data> | 3 | <data> |
732 | 4 | |||
733 | 5 | <record id="action_choose_supplier" model="ir.actions.server"> | ||
734 | 6 | <field name="name">Choose Supplier</field> | ||
735 | 7 | <field name="model_id" ref="model_procurement_choose_supplier"/> | ||
736 | 8 | <field name="state">code</field> | ||
737 | 9 | <field name="code">action = obj.start_choose_supplier(context=context)</field> | ||
738 | 10 | </record> | ||
739 | 4 | 11 | ||
740 | 5 | <record id="procurement_list_form_view" model="ir.ui.view"> | 12 | <record id="procurement_list_form_view" model="ir.ui.view"> |
741 | 6 | <field name="name">procurement.list.form.view</field> | 13 | <field name="name">procurement.list.form.view</field> |
742 | @@ -25,18 +32,19 @@ | |||
743 | 25 | <field name="comment" /> | 32 | <field name="comment" /> |
744 | 26 | <field name="from_stock" /> | 33 | <field name="from_stock" /> |
745 | 27 | <field name="latest" /> | 34 | <field name="latest" /> |
746 | 35 | <field name="supplier_id" context="{'product_id': product_id, 'choose_supplier': True}" /> | ||
747 | 36 | <button name="split_line" type="object" string="Split Line" icon="terp-stock_effects-object-colorize" /> | ||
748 | 37 | <button name="merge_line" type="object" string="Merge Line" icon="terp-gtk-jump-to-ltr" context="{'wizard_id': active_id}" /> | ||
749 | 28 | </tree> | 38 | </tree> |
750 | 29 | </field> | 39 | </field> |
751 | 30 | <group colspan="4" col="6"> | 40 | <group colspan="4" col="6"> |
752 | 31 | <field name="state" /> | 41 | <field name="state" /> |
753 | 32 | <button name="cancel" string="Cancel" icon="gtk-cancel" type="object" states="draft"/> | 42 | <button name="cancel" string="Cancel" icon="gtk-cancel" type="object" states="draft"/> |
755 | 33 | <button name="create_rfq" string="Create RfQ" icon="gtk-execute" type="object" states="draft" /> | 43 | <button name="create_rfq" type="object" string="Create RfQ" icon="gtk-execute" states="draft" /> |
756 | 44 | <button name="create_po" type="object" string="Create PO" icon="gtk-execute" states="draft" /> | ||
757 | 34 | <button name="reset" string="Reset to Draft" icon="gtk-ok" type="object" states="cancel" /> | 45 | <button name="reset" string="Reset to Draft" icon="gtk-ok" type="object" states="cancel" /> |
758 | 35 | </group> | 46 | </group> |
759 | 36 | </page> | 47 | </page> |
760 | 37 | <page string="Suppliers"> | ||
761 | 38 | <field name="supplier_ids" nolabel="1" /> | ||
762 | 39 | </page> | ||
763 | 40 | <page string="Sourcing Documents"> | 48 | <page string="Sourcing Documents"> |
764 | 41 | <field name="order_ids" nolabel="1" colspan="4"> | 49 | <field name="order_ids" nolabel="1" colspan="4"> |
765 | 42 | <tree string="Sourcing Documents" colors="blue:state=='draft'"> | 50 | <tree string="Sourcing Documents" colors="blue:state=='draft'"> |
766 | 43 | 51 | ||
767 | === modified file 'procurement_list/security/ir.model.access.csv' | |||
768 | --- procurement_list/security/ir.model.access.csv 2011-03-09 13:24:58 +0000 | |||
769 | +++ procurement_list/security/ir.model.access.csv 2011-03-24 15:56:19 +0000 | |||
770 | @@ -1,3 +1,3 @@ | |||
771 | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
772 | 2 | "access_procurement_list_all","procurement.list all","model_procurement_list",,1,1,1,1 | 2 | "access_procurement_list_all","procurement.list all","model_procurement_list",,1,1,1,1 |
774 | 3 | "access_procurement_list_line_all","procurement.list.line all","model_procurement_list_line",,1,1,1,1 | 3 | "access_procurement_list_line_all","procurement.list.line all","model_procurement_list_line",,1,1,1,1 |
775 | 4 | \ No newline at end of file | 4 | \ No newline at end of file |
776 | 5 | 5 | ||
777 | === modified file 'procurement_list/test/procurement_list.yml' | |||
778 | --- procurement_list/test/procurement_list.yml 2011-03-16 16:38:58 +0000 | |||
779 | +++ procurement_list/test/procurement_list.yml 2011-03-24 15:56:19 +0000 | |||
780 | @@ -1,4 +1,59 @@ | |||
781 | 1 | - | 1 | - |
782 | 2 | In order to test the procurement list module, I will create 6 suppliers, | ||
783 | 3 | 5 products and 3 procurement request. | ||
784 | 4 | After, I try all possibility to test the supplier default selection | ||
785 | 5 | - | ||
786 | 6 | I create the 6 partners | ||
787 | 7 | - | ||
788 | 8 | I create supplier S1 | ||
789 | 9 | - | ||
790 | 10 | !record {model: res.partner, id: supplier1}: | ||
791 | 11 | name: S1 | ||
792 | 12 | supplier: True | ||
793 | 13 | address: | ||
794 | 14 | - name: S1 | ||
795 | 15 | - | ||
796 | 16 | I create the supplier S2 | ||
797 | 17 | - | ||
798 | 18 | !record {model: res.partner, id: supplier2}: | ||
799 | 19 | name: S2 | ||
800 | 20 | supplier: True | ||
801 | 21 | address: | ||
802 | 22 | - name: S2 | ||
803 | 23 | - | ||
804 | 24 | I create the supplier S3 | ||
805 | 25 | - | ||
806 | 26 | !record {model: res.partner, id: supplier3}: | ||
807 | 27 | name: S3 | ||
808 | 28 | supplier: True | ||
809 | 29 | address: | ||
810 | 30 | - name: S3 | ||
811 | 31 | - | ||
812 | 32 | I create the supplier S4 | ||
813 | 33 | - | ||
814 | 34 | !record {model: res.partner, id: supplier4}: | ||
815 | 35 | name: S4 | ||
816 | 36 | supplier: True | ||
817 | 37 | address: | ||
818 | 38 | - name: S4 | ||
819 | 39 | - | ||
820 | 40 | I create the supplier S5 | ||
821 | 41 | - | ||
822 | 42 | !record {model: res.partner, id: supplier5}: | ||
823 | 43 | name: S5 | ||
824 | 44 | supplier: True | ||
825 | 45 | address: | ||
826 | 46 | - name: S5 | ||
827 | 47 | - | ||
828 | 48 | I create the supplier S6 | ||
829 | 49 | - | ||
830 | 50 | !record {model: res.partner, id: supplier6}: | ||
831 | 51 | name: S6 | ||
832 | 52 | supplier: True | ||
833 | 53 | address: | ||
834 | 54 | - name: S6 | ||
835 | 55 | - | ||
836 | 56 | I create the product P1 | ||
837 | 2 | In order to test the procurement list module, I start by creating a new product category | 57 | In order to test the procurement list module, I start by creating a new product category |
838 | 3 | - | 58 | - |
839 | 4 | !record {model: product.category, id: product_cat1}: | 59 | !record {model: product.category, id: product_cat1}: |
840 | @@ -22,10 +77,20 @@ | |||
841 | 22 | type: product | 77 | type: product |
842 | 23 | uom_id: product.product_uom_unit | 78 | uom_id: product.product_uom_unit |
843 | 24 | uom_po_id: product.product_uom_unit | 79 | uom_po_id: product.product_uom_unit |
845 | 25 | volume: 0.0 | 80 | volume : 0.0 |
846 | 26 | warranty: 0.0 | 81 | warranty: 0.0 |
847 | 27 | weight: 0.0 | 82 | weight: 0.0 |
848 | 28 | weight_net: 0.0 | 83 | weight_net: 0.0 |
849 | 84 | seller_ids: | ||
850 | 85 | - sequence: 10 | ||
851 | 86 | min_qty: 0.00 | ||
852 | 87 | name: supplier1 | ||
853 | 88 | - sequence: 20 | ||
854 | 89 | min_qty: 0.00 | ||
855 | 90 | name: supplier2 | ||
856 | 91 | - sequence: 30 | ||
857 | 92 | min_qty: 0.00 | ||
858 | 93 | name: supplier3 | ||
859 | 29 | - | 94 | - |
860 | 30 | I create a second product, P2 | 95 | I create a second product, P2 |
861 | 31 | - | 96 | - |
862 | @@ -43,34 +108,106 @@ | |||
863 | 43 | standard_price: 100.0 | 108 | standard_price: 100.0 |
864 | 44 | supply_method: buy | 109 | supply_method: buy |
865 | 45 | type: product | 110 | type: product |
894 | 46 | uom_id: product.product_uom_unit | 111 | uom_id: product.product_uom_unit |
895 | 47 | uom_po_id: product.product_uom_unit | 112 | uom_po_id: product.product_uom_unit |
896 | 48 | volume: 0.0 | 113 | volume : 0.0 |
897 | 49 | warranty: 0.0 | 114 | warranty: 0.0 |
898 | 50 | weight: 0.0 | 115 | weight: 0.0 |
899 | 51 | weight_net: 0.0 | 116 | weight_net: 0.0 |
900 | 52 | - | 117 | seller_ids: |
901 | 53 | I create a partner | 118 | - sequence: 10 |
902 | 54 | - | 119 | min_qty: 0.00 |
903 | 55 | !record {model: res.partner, id: partner1}: | 120 | name: supplier2 |
904 | 56 | name: Supplier 1 | 121 | - sequence: 20 |
905 | 57 | - | 122 | min_qty: 0.00 |
906 | 58 | I create an address for this partner | 123 | name: supplier1 |
907 | 59 | - | 124 | - |
908 | 60 | !record {model: res.partner.address, id: addr1}: | 125 | I create the product P3 |
909 | 61 | partner_id: partner1 | 126 | - |
910 | 62 | name: Supplier1 | 127 | !record {model: product.product, id: product3}: |
911 | 63 | - | 128 | categ_id: product.cat0 |
912 | 64 | I create a second partner | 129 | cost_method: standard |
913 | 65 | - | 130 | mes_type: fixed |
914 | 66 | !record {model: res.partner, id: partner2}: | 131 | name: P3 |
915 | 67 | name: Supplier 2 | 132 | price_margin: 2.0 |
916 | 68 | - | 133 | procure_method: make_to_stock |
917 | 69 | I create an address for this second partner | 134 | property_stock_inventory: stock.location_inventory |
918 | 70 | - | 135 | property_stock_procurement: stock.location_procurement |
919 | 71 | !record {model: res.partner.address, id: addr2}: | 136 | property_stock_production: stock.location_production |
920 | 72 | partner_id: partner2 | 137 | seller_delay: '1' |
921 | 73 | name: Supplier2 | 138 | standard_price: 100.0 |
922 | 139 | supply_method: buy | ||
923 | 140 | type: product | ||
924 | 141 | uom_id: product.product_uom_unit | ||
925 | 142 | uom_po_id: product.product_uom_unit | ||
926 | 143 | volume : 0.0 | ||
927 | 144 | warranty: 0.0 | ||
928 | 145 | weight: 0.0 | ||
929 | 146 | weight_net: 0.0 | ||
930 | 147 | seller_ids: | ||
931 | 148 | - sequence: 10 | ||
932 | 149 | min_qty: 0.00 | ||
933 | 150 | name: supplier3 | ||
934 | 151 | - | ||
935 | 152 | I create the product P4 | ||
936 | 153 | - | ||
937 | 154 | !record {model: product.product, id: product4}: | ||
938 | 155 | categ_id: product.cat0 | ||
939 | 156 | cost_method: standard | ||
940 | 157 | mes_type: fixed | ||
941 | 158 | name: P4 | ||
942 | 159 | price_margin: 2.0 | ||
943 | 160 | procure_method: make_to_stock | ||
944 | 161 | property_stock_inventory: stock.location_inventory | ||
945 | 162 | property_stock_procurement: stock.location_procurement | ||
946 | 163 | property_stock_production: stock.location_production | ||
947 | 164 | seller_delay: '1' | ||
948 | 165 | standard_price: 100.0 | ||
949 | 166 | supply_method: buy | ||
950 | 167 | type: product | ||
951 | 168 | uom_id: product.product_uom_unit | ||
952 | 169 | uom_po_id: product.product_uom_unit | ||
953 | 170 | volume : 0.0 | ||
954 | 171 | warranty: 0.0 | ||
955 | 172 | weight: 0.0 | ||
956 | 173 | weight_net: 0.0 | ||
957 | 174 | seller_ids: | ||
958 | 175 | - sequence: 10 | ||
959 | 176 | min_qty: 0.00 | ||
960 | 177 | name: supplier3 | ||
961 | 178 | - sequence: 20 | ||
962 | 179 | min_qty: 0.00 | ||
963 | 180 | name: supplier4 | ||
964 | 181 | - | ||
965 | 182 | I create the product P5 | ||
966 | 183 | - | ||
967 | 184 | !record {model: product.product, id: product5}: | ||
968 | 185 | categ_id: product.cat0 | ||
969 | 186 | cost_method: standard | ||
970 | 187 | mes_type: fixed | ||
971 | 188 | name: P5 | ||
972 | 189 | price_margin: 2.0 | ||
973 | 190 | procure_method: make_to_stock | ||
974 | 191 | property_stock_inventory: stock.location_inventory | ||
975 | 192 | property_stock_procurement: stock.location_procurement | ||
976 | 193 | property_stock_production: stock.location_production | ||
977 | 194 | seller_delay: '1' | ||
978 | 195 | standard_price: 100.0 | ||
979 | 196 | supply_method: buy | ||
980 | 197 | type: product | ||
981 | 198 | uom_id: product.product_uom_unit | ||
982 | 199 | uom_po_id: product.product_uom_unit | ||
983 | 200 | volume : 0.0 | ||
984 | 201 | warranty: 0.0 | ||
985 | 202 | weight: 0.0 | ||
986 | 203 | weight_net: 0.0 | ||
987 | 204 | seller_ids: | ||
988 | 205 | - sequence: 10 | ||
989 | 206 | min_qty: 0.00 | ||
990 | 207 | name: supplier4 | ||
991 | 208 | - sequence: 20 | ||
992 | 209 | min_qty: 0.00 | ||
993 | 210 | name: supplier5 | ||
994 | 74 | - | 211 | - |
995 | 75 | I create a procurement list for these two products | 212 | I create a procurement list for these two products |
996 | 76 | - | 213 | - |
997 | @@ -78,28 +215,67 @@ | |||
998 | 78 | requestor: Administration | 215 | requestor: Administration |
999 | 79 | warehouse_id: stock.warehouse0 | 216 | warehouse_id: stock.warehouse0 |
1000 | 80 | origin: R 20043 | 217 | origin: R 20043 |
1001 | 81 | supplier_ids: | ||
1002 | 82 | - partner1 | ||
1003 | 83 | - partner2 | ||
1004 | 84 | - | 218 | - |
1006 | 85 | I add two lines in this procurement list | 219 | I create a Procurement Request Line 1 for list1 |
1007 | 86 | - | 220 | - |
1008 | 87 | !record {model: procurement.list.line, id: list1_line1}: | 221 | !record {model: procurement.list.line, id: list1_line1}: |
1009 | 88 | product_id: product1 | 222 | product_id: product1 |
1010 | 89 | product_uom_id: product.product_uom_unit | 223 | product_uom_id: product.product_uom_unit |
1012 | 90 | product_qty: 100.00 | 224 | product_qty: 12.0 |
1013 | 91 | comment: special comment | 225 | comment: special comment |
1014 | 92 | from_stock: False | 226 | from_stock: False |
1015 | 93 | list_id: list1 | 227 | list_id: list1 |
1016 | 228 | supplier_id: supplier1 | ||
1017 | 94 | - | 229 | - |
1019 | 95 | The second line | 230 | I create a Procurement Request Line 2 for list1 |
1020 | 96 | - | 231 | - |
1021 | 97 | !record {model: procurement.list.line, id: list1_line2}: | 232 | !record {model: procurement.list.line, id: list1_line2}: |
1022 | 98 | product_id: product2 | 233 | product_id: product2 |
1023 | 99 | product_uom_id: product.product_uom_unit | 234 | product_uom_id: product.product_uom_unit |
1025 | 100 | product_qty: 50.0 | 235 | product_qty: 10.0 |
1026 | 101 | from_stock: True | 236 | from_stock: True |
1027 | 102 | list_id: list1 | 237 | list_id: list1 |
1028 | 238 | supplier_id: supplier2 | ||
1029 | 239 | - | ||
1030 | 240 | I create a second Procurement Request | ||
1031 | 241 | - | ||
1032 | 242 | !record {model: procurement.list, id: list2}: | ||
1033 | 243 | requestor: Administration | ||
1034 | 244 | warehouse_id: stock.warehouse0 | ||
1035 | 245 | - | ||
1036 | 246 | I create Procurement Request line 1 for list2 | ||
1037 | 247 | - | ||
1038 | 248 | !record {model: procurement.list.line, id: list2_line1}: | ||
1039 | 249 | product_id: product3 | ||
1040 | 250 | product_uom_id: product.product_uom_unit | ||
1041 | 251 | product_qty: 20.0 | ||
1042 | 252 | list_id: list2 | ||
1043 | 253 | supplier_id: supplier3 | ||
1044 | 254 | - | ||
1045 | 255 | I create Procurement Request line 2 for list2 | ||
1046 | 256 | - | ||
1047 | 257 | !record {model: procurement.list.line, id: list2_line2}: | ||
1048 | 258 | product_id: product4 | ||
1049 | 259 | product_uom_id: product.product_uom_unit | ||
1050 | 260 | product_qty: 30.0 | ||
1051 | 261 | list_id: list2 | ||
1052 | 262 | supplier_id: supplier3 | ||
1053 | 263 | - | ||
1054 | 264 | I create a third Procurement Request | ||
1055 | 265 | - | ||
1056 | 266 | !record {model: procurement.list, id: list3}: | ||
1057 | 267 | requestor: Administration | ||
1058 | 268 | warehouse_id: stock.warehouse0 | ||
1059 | 269 | origin: R 20045 | ||
1060 | 270 | - | ||
1061 | 271 | I create a Procurement Request Line 1 for list3 | ||
1062 | 272 | - | ||
1063 | 273 | !record {model: procurement.list.line, id: list3_line1}: | ||
1064 | 274 | product_id: product5 | ||
1065 | 275 | product_uom_id: product.product_uom_unit | ||
1066 | 276 | product_qty: 30.0 | ||
1067 | 277 | list_id: list3 | ||
1068 | 278 | supplier_id: supplier3 | ||
1069 | 103 | - | 279 | - |
1070 | 104 | I check that the list which was initially in the draft state | 280 | I check that the list which was initially in the draft state |
1071 | 105 | - | 281 | - |
1072 | @@ -108,36 +284,107 @@ | |||
1073 | 108 | - requestor == 'Administration' | 284 | - requestor == 'Administration' |
1074 | 109 | - origin == 'R 20043' | 285 | - origin == 'R 20043' |
1075 | 110 | - | 286 | - |
1092 | 111 | I create RfQ from this list | 287 | I check if the creation of PO is ok |
1093 | 112 | - | 288 | - |
1094 | 113 | !python {model: procurement.list}: | | 289 | !python {model: procurement.list}: | |
1095 | 114 | pl_obj = self.pool.get('procurement.list') | 290 | self.create_po(cr, uid, [ref('list1')]) |
1096 | 115 | pl_id1 = pl_obj.browse(cr, uid, ref('list1')) | 291 | - |
1097 | 116 | pl_id1.create_rfq() | 292 | I check if documents in 'Sourcing' tab are filled |
1098 | 117 | - | 293 | - |
1099 | 118 | I check if the latest message in procurement line is 'RfQ In Progress' | 294 | !assert {model: procurement.list, id: list1}: |
1100 | 119 | - | 295 | - len(order_ids) == 2, "Number of sourcing documents is wrong" |
1101 | 120 | !assert {model: procurement.list.line, id: list1_line1}: | 296 | - |
1102 | 121 | - latest == 'RfQ In Progress' | 297 | I check if the creation of RfQ is ok |
1103 | 122 | - | 298 | - |
1104 | 123 | I check if only one RfQ will be created for the | 299 | !record {model: procurement.choose.supplier.rfq, id: supplier_choose2}: |
1105 | 124 | - | 300 | choose_id: list2 |
1106 | 125 | !python {model: procurement.list}: | | 301 | supplier_ids: |
1107 | 126 | pl_obj = self.pool.get('procurement.list') | 302 | - supplier3 |
1108 | 303 | - supplier4 | ||
1109 | 304 | - | ||
1110 | 305 | I confirm the creation of RfQ | ||
1111 | 306 | - | ||
1112 | 307 | !python {model: procurement.choose.supplier.rfq}: | | ||
1113 | 308 | self.create_rfq(cr, uid, [ref('supplier_choose2')]) | ||
1114 | 309 | - | ||
1115 | 310 | I check if the latest message in procurement line is 'RfQ In Progress' | ||
1116 | 311 | - | ||
1117 | 312 | !assert {model: procurement.list.line, id: list2_line1}: | ||
1118 | 313 | - latest == 'RfQ In Progress', "Rfq In Progress not applied in latest field of line" | ||
1119 | 314 | - | ||
1120 | 315 | I check if the latest message in procurement line is 'RfQ In Progress' | ||
1121 | 316 | - | ||
1122 | 317 | !assert {model: procurement.list.line, id: list2_line2}: | ||
1123 | 318 | - latest == 'RfQ In Progress', "Rfq In Progress not applied in latest field of line" | ||
1124 | 319 | - | ||
1125 | 320 | I check if documents in 'Sourcing' tab are filled | ||
1126 | 321 | - | ||
1127 | 322 | !assert {model: procurement.list, id: list2}: | ||
1128 | 323 | - len(order_ids) == 2, "Number of sourcing documents is wrong" | ||
1129 | 324 | - | ||
1130 | 325 | I check if only one RfQ will be created for the line | ||
1131 | 326 | - | ||
1132 | 327 | !python {model: procurement.list}: | | ||
1133 | 328 | list2 = self.browse(cr, uid, ref('list2')) | ||
1134 | 127 | pol_obj = self.pool.get('purchase.order.line') | 329 | pol_obj = self.pool.get('purchase.order.line') |
1135 | 128 | order_obj = self.pool.get('purchase.order') | 330 | order_obj = self.pool.get('purchase.order') |
1138 | 129 | pol_ids = pol_obj.search(cr, uid, [('product_id', '=', ref('product1'))]) | 331 | |
1139 | 130 | pl = pl_obj.browse(cr, uid, ref('list1')) | 332 | list_line_ids = [] |
1140 | 333 | for line in list2.line_ids: | ||
1141 | 334 | list_line_ids.append(line.id) | ||
1142 | 335 | |||
1143 | 336 | pol_ids = pol_obj.search(cr, uid, [('product_id', '=', ref('product3')), ('procurement_line_id', 'in', list_line_ids)]) | ||
1144 | 131 | 337 | ||
1145 | 132 | for pol in pol_obj.browse(cr, uid, pol_ids): | 338 | for pol in pol_obj.browse(cr, uid, pol_ids): |
1157 | 133 | assert pol.order_id.origin == pl.name, "Bad name for the name of the generated Purchase Order" | 339 | assert pol.order_id.origin == pl.name, "Bad origin for the generated Purchase Order" |
1158 | 134 | order_obj.wkf_confirm_order(cr, uid, [pol.order_id.id]) | 340 | order_obj.wkf_confirm_order(cr, uid, [pol.order_id.id]) |
1159 | 135 | assert pol.procurement_line_id.latest == pol.order_id.name, "Procurement line not updated" | 341 | print pol.procurement_line_id.latest, pol.order_id.name |
1160 | 136 | - | 342 | assert pol.procurement_line_id.latest == pol.order_id.name, "Procurement line not updated" |
1161 | 137 | I check that no purchase order line with P2 | 343 | - |
1162 | 138 | - | 344 | Split the line |
1163 | 139 | !python {model: procurement.list}: | | 345 | - |
1164 | 140 | pl_obj = self.pool.get('procurement.list') | 346 | !record {model: procurement.list.line.split, id: split1}: |
1165 | 141 | pol_obj = self.pool.get('purchase.order.line') | 347 | line_id: list3_line1 |
1166 | 142 | pol_ids = pol_obj.search(cr, uid, [('product_id', '=', ref('product2'))]) | 348 | qty: 20.00 |
1167 | 143 | assert len(pol_ids) == 0, "No purchase order line found !" | 349 | - |
1168 | 350 | I check if we have two lines for the product P5 now | ||
1169 | 351 | - | ||
1170 | 352 | !python {model: procurement.list.line}: | | ||
1171 | 353 | self.pool.get('procurement.list.line.split').split(cr, uid, ref('split1')) | ||
1172 | 354 | assert len(self.search(cr, uid, [('product_id', '=', ref('product5')), ('list_id', '=', ref('list3'))])) == 2, "Line isn't split" | ||
1173 | 355 | - | ||
1174 | 356 | I check if the quantity in old line is decrease of 20 PCE | ||
1175 | 357 | - | ||
1176 | 358 | !python {model: procurement.list.line}: | | ||
1177 | 359 | assert self.browse(cr, uid, ref('list3_line1')).product_qty == 10.0, "Quantity of old line isn't updated" | ||
1178 | 360 | - | ||
1179 | 361 | I check if the quantity of the new line is good | ||
1180 | 362 | - | ||
1181 | 363 | !python {model: procurement.list.line}: | | ||
1182 | 364 | line_id = self.search(cr, uid, [('product_id', '=', ref('product5')), ('list_id', '=', ref('list3'))]) | ||
1183 | 365 | for line in line_id: | ||
1184 | 366 | if line != ref('list3_line1'): | ||
1185 | 367 | assert self.browse(cr, uid, line).product_qty == 20.00, "Quantity of new line is wrong" | ||
1186 | 368 | - | ||
1187 | 369 | I change the supplier of the second line | ||
1188 | 370 | - | ||
1189 | 371 | !python {model: procurement.list.line}: | | ||
1190 | 372 | line_id = self.search(cr, uid, [('product_id', '=', ref('product5')), ('list_id', '=', ref('list3')), ('id', '!=', ref('list3_line1'))]) | ||
1191 | 373 | self.write(cr, uid, line_id, {'supplier_id': ref('supplier6')}) | ||
1192 | 374 | - | ||
1193 | 375 | I simulate a click on Create Purchase Order button | ||
1194 | 376 | - | ||
1195 | 377 | !python {model: procurement.list}: | | ||
1196 | 378 | self.create_po(cr, uid, [ref('list3')]) | ||
1197 | 379 | - | ||
1198 | 380 | I check if two purchase orders have well created | ||
1199 | 381 | - | ||
1200 | 382 | !assert {model: procurement.list, id: list3}: | ||
1201 | 383 | - len(order_ids) == 2, "Number of sourcing documents is wrong" | ||
1202 | 384 | - | ||
1203 | 385 | I check if the purchase orders have well confirmed | ||
1204 | 386 | - | ||
1205 | 387 | !python {model: procurement.list}: | | ||
1206 | 388 | for order in self.browse(cr, uid, ref('list3')).order_ids: | ||
1207 | 389 | assert order.state == 'approved', "PO state isn't confirmed" | ||
1208 | 390 | |||
1209 | 144 | \ No newline at end of file | 391 | \ No newline at end of file |
1210 | 145 | 392 | ||
1211 | === modified file 'procurement_list/wizard/__init__.py' | |||
1212 | --- procurement_list/wizard/__init__.py 2011-03-16 13:17:54 +0000 | |||
1213 | +++ procurement_list/wizard/__init__.py 2011-03-24 15:56:19 +0000 | |||
1214 | @@ -23,6 +23,7 @@ | |||
1215 | 23 | import wizard_list_to_order | 23 | import wizard_list_to_order |
1216 | 24 | import wizard_list_to_rfq | 24 | import wizard_list_to_rfq |
1217 | 25 | import wizard_import_list | 25 | import wizard_import_list |
1218 | 26 | import choose_supplier | ||
1219 | 26 | 27 | ||
1220 | 27 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | 28 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1221 | 28 | 29 | ||
1222 | 29 | 30 | ||
1223 | === added file 'procurement_list/wizard/choose_supplier.py' | |||
1224 | --- procurement_list/wizard/choose_supplier.py 1970-01-01 00:00:00 +0000 | |||
1225 | +++ procurement_list/wizard/choose_supplier.py 2011-03-24 15:56:19 +0000 | |||
1226 | @@ -0,0 +1,241 @@ | |||
1227 | 1 | #!/usr/bin/env python | ||
1228 | 2 | # -*- encoding: utf-8 -*- | ||
1229 | 3 | ############################################################################## | ||
1230 | 4 | # | ||
1231 | 5 | # OpenERP, Open Source Management Solution | ||
1232 | 6 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
1233 | 7 | # | ||
1234 | 8 | # This program is free software: you can redistribute it and/or modify | ||
1235 | 9 | # it under the terms of the GNU Affero General Public License as | ||
1236 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
1237 | 11 | # License, or (at your option) any later version. | ||
1238 | 12 | # | ||
1239 | 13 | # This program is distributed in the hope that it will be useful, | ||
1240 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1241 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1242 | 16 | # GNU Affero General Public License for more details. | ||
1243 | 17 | # | ||
1244 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
1245 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1246 | 20 | # | ||
1247 | 21 | ############################################################################## | ||
1248 | 22 | |||
1249 | 23 | from osv import osv | ||
1250 | 24 | from osv import fields | ||
1251 | 25 | |||
1252 | 26 | import netsvc | ||
1253 | 27 | import time | ||
1254 | 28 | |||
1255 | 29 | from tools.translate import _ | ||
1256 | 30 | |||
1257 | 31 | |||
1258 | 32 | class procurement_list_line_split(osv.osv_memory): | ||
1259 | 33 | _name = 'procurement.list.line.split' | ||
1260 | 34 | _description = 'Wizard to split a line into two lines' | ||
1261 | 35 | |||
1262 | 36 | _columns = { | ||
1263 | 37 | 'line_id': fields.many2one('procurement.list.line', string='Line to split'), | ||
1264 | 38 | 'qty': fields.float(digits=(16,2), string='Quantity for the new line', required=True), | ||
1265 | 39 | } | ||
1266 | 40 | |||
1267 | 41 | def default_get(self, cr, uid, fields, context={}): | ||
1268 | 42 | ''' | ||
1269 | 43 | Fills information for the wizard | ||
1270 | 44 | ''' | ||
1271 | 45 | line_obj = self.pool.get('procurement.list.line') | ||
1272 | 46 | |||
1273 | 47 | res = super(procurement_list_line_split, self).default_get(cr, uid, fields, context) | ||
1274 | 48 | line_id = context.get('line_id', False) | ||
1275 | 49 | state = context.get('state', False) | ||
1276 | 50 | |||
1277 | 51 | if not line_id: | ||
1278 | 52 | return res | ||
1279 | 53 | |||
1280 | 54 | line = line_obj.browse(cr, uid, line_id, context=context) | ||
1281 | 55 | if state == 'done': | ||
1282 | 56 | raise osv.except_osv(_('Error'), _('You cannot split a line in a Done Procurement Request')) | ||
1283 | 57 | |||
1284 | 58 | res['line_id'] = line_id | ||
1285 | 59 | |||
1286 | 60 | # Default quantity = Old quantity divided by 2 | ||
1287 | 61 | res['qty'] = line_obj.browse(cr, uid, line_id, context=context).product_qty/2 | ||
1288 | 62 | |||
1289 | 63 | return res | ||
1290 | 64 | |||
1291 | 65 | def split(self, cr, uid, ids, context={}): | ||
1292 | 66 | ''' | ||
1293 | 67 | Changes the quantity of the old line and creates a new line with the | ||
1294 | 68 | new quantity | ||
1295 | 69 | ''' | ||
1296 | 70 | if ids and isinstance(ids, (int, long)): | ||
1297 | 71 | ids = [ids] | ||
1298 | 72 | line_obj = self.pool.get('procurement.list.line') | ||
1299 | 73 | |||
1300 | 74 | for obj in self.browse(cr, uid, ids, context=context): | ||
1301 | 75 | # Returns an error if the quantity is negative | ||
1302 | 76 | if obj.qty < 0.00: | ||
1303 | 77 | raise osv.except_osv(_('Error'), _('The new quantity should be positive')) | ||
1304 | 78 | if obj.qty > obj.line_id.product_qty: | ||
1305 | 79 | raise osv.except_osv(_('Error'), _('The new quantity can\'t be superior to the quantity of initial line')) | ||
1306 | 80 | # Changes the quantity on the old line | ||
1307 | 81 | line_obj.write(cr, uid, [obj.line_id.id], {'product_qty': obj.line_id.product_qty-obj.qty}) | ||
1308 | 82 | # Creates the new line with new quantity | ||
1309 | 83 | line_obj.create(cr, uid, {'list_id': obj.line_id.list_id.id, | ||
1310 | 84 | 'product_id': obj.line_id.product_id.id, | ||
1311 | 85 | 'product_uom_id': obj.line_id.product_uom_id.id, | ||
1312 | 86 | 'product_qty': obj.qty, | ||
1313 | 87 | 'supplier_id': False,}) | ||
1314 | 88 | |||
1315 | 89 | return {'type': 'ir.actions.act_window_close'} | ||
1316 | 90 | |||
1317 | 91 | procurement_list_line_split() | ||
1318 | 92 | |||
1319 | 93 | |||
1320 | 94 | class procurement_list_line_merge(osv.osv_memory): | ||
1321 | 95 | _name = 'procurement.list.line.merge' | ||
1322 | 96 | _description = 'Merge Lines' | ||
1323 | 97 | |||
1324 | 98 | _columns = { | ||
1325 | 99 | 'line_id': fields.many2one('procurement.list.line', string='Line to merged', readonly=True), | ||
1326 | 100 | 'line_ids': fields.many2many('procurement.list.line', 'merge_line_rel', 'merge_id', 'line_id', | ||
1327 | 101 | string='Lines to merged'), | ||
1328 | 102 | } | ||
1329 | 103 | |||
1330 | 104 | def default_get(self, cr, uid, fields, context={}): | ||
1331 | 105 | ''' | ||
1332 | 106 | Initializes data with only lines with the same product and the same | ||
1333 | 107 | procurement list | ||
1334 | 108 | |||
1335 | 109 | ''' | ||
1336 | 110 | line_obj = self.pool.get('procurement.list.line') | ||
1337 | 111 | res = {} | ||
1338 | 112 | |||
1339 | 113 | line_id = context.get('line_id', False) | ||
1340 | 114 | state = context.get('state', False) | ||
1341 | 115 | if not line_id: | ||
1342 | 116 | raise osv.except_osv(_('Error'), _('No lines to merged')) | ||
1343 | 117 | |||
1344 | 118 | line = line_obj.browse(cr, uid, line_id, context=context) | ||
1345 | 119 | if state == 'done': | ||
1346 | 120 | raise osv.except_osv(_('Error'), _('You cannot merge a line in a Done Procurement Request')) | ||
1347 | 121 | product_id = line.product_id.id | ||
1348 | 122 | product_uom = line.product_uom_id.id | ||
1349 | 123 | wizard_id = line.list_id.id | ||
1350 | 124 | |||
1351 | 125 | res['line_id'] = line_id | ||
1352 | 126 | res['line_ids']= line_obj.search(cr, uid, [('list_id', '=', wizard_id), | ||
1353 | 127 | ('product_id', '=', product_id), | ||
1354 | 128 | ('product_uom_id', '=', product_uom)]) | ||
1355 | 129 | |||
1356 | 130 | if line_id in res['line_ids']: | ||
1357 | 131 | res['line_ids'].remove(line_id) | ||
1358 | 132 | |||
1359 | 133 | return res | ||
1360 | 134 | |||
1361 | 135 | def merge_confirm(self, cr, uid, ids, context={}): | ||
1362 | 136 | ''' | ||
1363 | 137 | Merged lines | ||
1364 | 138 | ''' | ||
1365 | 139 | if ids and isinstance(ids, (int, long)): | ||
1366 | 140 | ids = [ids] | ||
1367 | 141 | line_obj = self.pool.get('procurement.list.line') | ||
1368 | 142 | |||
1369 | 143 | for obj in self.browse(cr, uid, ids, context=context): | ||
1370 | 144 | # Get the supplier of the main line because if merge no lines, | ||
1371 | 145 | # the supplier shouldn't removed | ||
1372 | 146 | supplier_id = obj.line_id.supplier_id.id | ||
1373 | 147 | qty = obj.line_id.product_qty | ||
1374 | 148 | for line in obj.line_ids: | ||
1375 | 149 | qty += line.product_qty | ||
1376 | 150 | supplier_id = False | ||
1377 | 151 | line_obj.unlink(cr, uid, [line.id]) | ||
1378 | 152 | |||
1379 | 153 | line_obj.write(cr, uid, [obj.line_id.id], {'product_qty': qty, 'supplier_id': supplier_id}) | ||
1380 | 154 | |||
1381 | 155 | return {'type': 'ir.actions.act_window_close'} | ||
1382 | 156 | |||
1383 | 157 | procurement_list_line_merge() | ||
1384 | 158 | |||
1385 | 159 | |||
1386 | 160 | class procurement_choose_supplier_rfq(osv.osv_memory): | ||
1387 | 161 | _name = 'procurement.choose.supplier.rfq' | ||
1388 | 162 | _description = 'Choose Supplier tp generate RfQ' | ||
1389 | 163 | |||
1390 | 164 | _columns = { | ||
1391 | 165 | 'choose_id': fields.many2one('procurement.list', string='Wizard'), | ||
1392 | 166 | 'supplier_ids': fields.many2many('res.partner', 'supplier_rfq_rel', 'rfq_id', 'supplier_id', | ||
1393 | 167 | string='Suppliers', domain=[('supplier', '=', 1)]), | ||
1394 | 168 | } | ||
1395 | 169 | |||
1396 | 170 | def default_get(self, cr, uid, fields, context={}): | ||
1397 | 171 | ''' | ||
1398 | 172 | Fills information in the wizard | ||
1399 | 173 | ''' | ||
1400 | 174 | res = super(procurement_choose_supplier_rfq, self).default_get(cr, uid, fields, context=context) | ||
1401 | 175 | wizard_id = context.get('active_id', False) | ||
1402 | 176 | |||
1403 | 177 | if not wizard_id: | ||
1404 | 178 | return res | ||
1405 | 179 | |||
1406 | 180 | res['choose_id'] = wizard_id | ||
1407 | 181 | |||
1408 | 182 | return res | ||
1409 | 183 | |||
1410 | 184 | def create_rfq(self, cr, uid, ids, context={}): | ||
1411 | 185 | ''' | ||
1412 | 186 | Creates Requests for Quotation for each supplier with all lines | ||
1413 | 187 | ''' | ||
1414 | 188 | if ids and isinstance(ids, (int, long)): | ||
1415 | 189 | ids = [ids] | ||
1416 | 190 | order_obj = self.pool.get('purchase.order') | ||
1417 | 191 | order_line_obj = self.pool.get('purchase.order.line') | ||
1418 | 192 | proc_list_obj = self.pool.get('procurement.list') | ||
1419 | 193 | proc_line_obj = self.pool.get('procurement.list.line') | ||
1420 | 194 | |||
1421 | 195 | po_ids = [] # List of all created RfQ | ||
1422 | 196 | |||
1423 | 197 | for obj in self.browse(cr, uid, ids): | ||
1424 | 198 | origin = obj.choose_id.name | ||
1425 | 199 | location_id = proc_list_obj._get_location(cr, uid, obj.choose_id.warehouse_id) | ||
1426 | 200 | |||
1427 | 201 | lines = [] | ||
1428 | 202 | for l in obj.choose_id.line_ids: | ||
1429 | 203 | lines.append({'line_id': l.id, | ||
1430 | 204 | 'product_id': l.product_id.id, | ||
1431 | 205 | 'product_uom': l.product_uom_id.id, | ||
1432 | 206 | 'product_name': l.product_id.name, | ||
1433 | 207 | 'product_qty': l.product_qty,}) | ||
1434 | 208 | |||
1435 | 209 | # Creates one RfQ for each supplier | ||
1436 | 210 | for s in obj.supplier_ids: | ||
1437 | 211 | po_id = order_obj.create(cr, uid, {'partner_id': s.id, | ||
1438 | 212 | 'partner_address_id': s.address_get().get('default'), | ||
1439 | 213 | 'pricelist_id': s.property_product_pricelist.id, | ||
1440 | 214 | 'origin': origin, | ||
1441 | 215 | 'location_id': location_id}) | ||
1442 | 216 | po_ids.append(po_id) | ||
1443 | 217 | # Creates lines | ||
1444 | 218 | for l in lines: | ||
1445 | 219 | order_line_obj.create(cr, uid, {'product_uom': l.get('product_uom'), | ||
1446 | 220 | 'product_id': l.get('product_id'), | ||
1447 | 221 | 'order_id': po_id, | ||
1448 | 222 | 'price_unit': 0.00, | ||
1449 | 223 | 'date_planned': obj.choose_id.order_date, | ||
1450 | 224 | 'product_qty': l.get('product_qty'), | ||
1451 | 225 | 'name': l.get('product_name'), | ||
1452 | 226 | }) | ||
1453 | 227 | |||
1454 | 228 | proc_id = self.browse(cr, uid, ids[0]).choose_id.id | ||
1455 | 229 | proc_list_obj.write(cr, uid, proc_id, {'state': 'done', 'order_ids': [(6, 0, po_ids)]}) | ||
1456 | 230 | |||
1457 | 231 | return {'type': 'ir.actions.act_window', | ||
1458 | 232 | 'res_model': 'purchase.order', | ||
1459 | 233 | 'view_type': 'form', | ||
1460 | 234 | 'view_mode': 'tree,form', | ||
1461 | 235 | 'domain': [('id', 'in', po_ids)]} | ||
1462 | 236 | |||
1463 | 237 | procurement_choose_supplier_rfq() | ||
1464 | 238 | |||
1465 | 239 | |||
1466 | 240 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
1467 | 241 | |||
1468 | 0 | 242 | ||
1469 | === added file 'procurement_list/wizard/choose_supplier_view.xml' | |||
1470 | --- procurement_list/wizard/choose_supplier_view.xml 1970-01-01 00:00:00 +0000 | |||
1471 | +++ procurement_list/wizard/choose_supplier_view.xml 2011-03-24 15:56:19 +0000 | |||
1472 | @@ -0,0 +1,59 @@ | |||
1473 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
1474 | 2 | <openerp> | ||
1475 | 3 | <data> | ||
1476 | 4 | |||
1477 | 5 | <record id="choose_supplier_line_split_qty" model="ir.ui.view"> | ||
1478 | 6 | <field name="name">choose.supplier.line.split.qty</field> | ||
1479 | 7 | <field name="model">procurement.list.line.split</field> | ||
1480 | 8 | <field name="type">form</field> | ||
1481 | 9 | <field name="arch" type="xml"> | ||
1482 | 10 | <form string="Split line"> | ||
1483 | 11 | <separator colspan="4" string="New quantity" /> | ||
1484 | 12 | <field name="qty" colspan="4" /> | ||
1485 | 13 | <separator colspan="4" string="Actions" /> | ||
1486 | 14 | <button special="cancel" string="Cancel" icon="gtk-cancel" colspan="2" type="object" /> | ||
1487 | 15 | <button name="split" string="New line" icon="gtk-ok" colspan="2" type="object" /> | ||
1488 | 16 | </form> | ||
1489 | 17 | </field> | ||
1490 | 18 | </record> | ||
1491 | 19 | |||
1492 | 20 | <record id="choose_supplier_line_merge" model="ir.ui.view"> | ||
1493 | 21 | <field name="name">choose.supplier.line.merge</field> | ||
1494 | 22 | <field name="model">procurement.list.line.merge</field> | ||
1495 | 23 | <field name="type">form</field> | ||
1496 | 24 | <field name="arch" type="xml"> | ||
1497 | 25 | <form string="Merge lines"> | ||
1498 | 26 | <separator colspan="4" string="Possible lines to merge" /> | ||
1499 | 27 | <field name="line_ids" colspan="4" nolabel="1" > | ||
1500 | 28 | <tree string="Lines"> | ||
1501 | 29 | <field name="product_id" /> | ||
1502 | 30 | <field name="product_qty" /> | ||
1503 | 31 | <field name="product_uom_id" /> | ||
1504 | 32 | <field name="supplier_id" /> | ||
1505 | 33 | </tree> | ||
1506 | 34 | </field> | ||
1507 | 35 | <separator colspan="4" /> | ||
1508 | 36 | <button special="cancel" string="Cancel" icon="gtk-cancel" colspan="2" type="object" /> | ||
1509 | 37 | <button name="merge_confirm" string="Merge" icon="gtk-ok" colspan="2" type="object" /> | ||
1510 | 38 | </form> | ||
1511 | 39 | </field> | ||
1512 | 40 | </record> | ||
1513 | 41 | |||
1514 | 42 | <record id="choose_supplier_rfq_form_view" model="ir.ui.view"> | ||
1515 | 43 | <field name="name">choose.supplier.rfq.form.view</field> | ||
1516 | 44 | <field name="model">procurement.choose.supplier.rfq</field> | ||
1517 | 45 | <field name="type">form</field> | ||
1518 | 46 | <field name="arch" type="xml"> | ||
1519 | 47 | <form string="Choose Suppliers"> | ||
1520 | 48 | <separator colspan="4" string="Suppliers" /> | ||
1521 | 49 | <field name="supplier_ids" colspan="4" nolabel="1" /> | ||
1522 | 50 | <separator colspan="4" /> | ||
1523 | 51 | <button special="cancel" string="Cancel" icon="gtk-cancel" colspan="2" type="object" /> | ||
1524 | 52 | <button name="create_rfq" type="object" string="Create RfQ" icon="gtk-execute" /> | ||
1525 | 53 | </form> | ||
1526 | 54 | </field> | ||
1527 | 55 | </record> | ||
1528 | 56 | |||
1529 | 57 | </data> | ||
1530 | 58 | </openerp> | ||
1531 | 59 | |||
1532 | 0 | 60 | ||
1533 | === removed directory 'stock_inventory_type' | |||
1534 | === removed file 'stock_inventory_type/__init__.py' | |||
1535 | --- stock_inventory_type/__init__.py 2011-03-15 17:05:15 +0000 | |||
1536 | +++ stock_inventory_type/__init__.py 1970-01-01 00:00:00 +0000 | |||
1537 | @@ -1,28 +0,0 @@ | |||
1538 | 1 | #!/usr/bin/env python | ||
1539 | 2 | # -*- encoding: utf-8 -*- | ||
1540 | 3 | ############################################################################## | ||
1541 | 4 | # | ||
1542 | 5 | # OpenERP, Open Source Management Solution | ||
1543 | 6 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
1544 | 7 | # | ||
1545 | 8 | # This program is free software: you can redistribute it and/or modify | ||
1546 | 9 | # it under the terms of the GNU Affero General Public License as | ||
1547 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
1548 | 11 | # License, or (at your option) any later version. | ||
1549 | 12 | # | ||
1550 | 13 | # This program is distributed in the hope that it will be useful, | ||
1551 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1552 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1553 | 16 | # GNU Affero General Public License for more details. | ||
1554 | 17 | # | ||
1555 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
1556 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1557 | 20 | # | ||
1558 | 21 | ############################################################################## | ||
1559 | 22 | |||
1560 | 23 | |||
1561 | 24 | import stock | ||
1562 | 25 | import stock_move_report | ||
1563 | 26 | |||
1564 | 27 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
1565 | 28 | |||
1566 | 29 | 0 | ||
1567 | === removed file 'stock_inventory_type/__openerp__.py' | |||
1568 | --- stock_inventory_type/__openerp__.py 2011-03-15 17:05:15 +0000 | |||
1569 | +++ stock_inventory_type/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
1570 | @@ -1,49 +0,0 @@ | |||
1571 | 1 | # -*- coding: utf-8 -*- | ||
1572 | 2 | ############################################################################## | ||
1573 | 3 | # | ||
1574 | 4 | # OpenERP, Open Source Management Solution | ||
1575 | 5 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
1576 | 6 | # | ||
1577 | 7 | # This program is free software: you can redistribute it and/or modify | ||
1578 | 8 | # it under the terms of the GNU Affero General Public License as | ||
1579 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
1580 | 10 | # License, or (at your option) any later version. | ||
1581 | 11 | # | ||
1582 | 12 | # This program is distributed in the hope that it will be useful, | ||
1583 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1584 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1585 | 15 | # GNU Affero General Public License for more details. | ||
1586 | 16 | # | ||
1587 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
1588 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1589 | 19 | # | ||
1590 | 20 | ############################################################################## | ||
1591 | 21 | { | ||
1592 | 22 | "name" : "Stock Adjustment/Move Report", | ||
1593 | 23 | "version" : "1.0", | ||
1594 | 24 | "author" : "TeMPO Consulting, MSF", | ||
1595 | 25 | "category": "Inventory Control", | ||
1596 | 26 | "description": """ | ||
1597 | 27 | This module aims to help you to determine the type \ | ||
1598 | 28 | of your inventory adjustment and to search stock move \ | ||
1599 | 29 | by type of adjustment. | ||
1600 | 30 | """, | ||
1601 | 31 | "website": "http://unifield.msf.org", | ||
1602 | 32 | "init_xml": [ | ||
1603 | 33 | ], | ||
1604 | 34 | "depends" : [ | ||
1605 | 35 | "stock", | ||
1606 | 36 | ], | ||
1607 | 37 | "update_xml": [ | ||
1608 | 38 | "stock_view.xml", | ||
1609 | 39 | "stock_data.xml", | ||
1610 | 40 | "security/ir.model.access.csv", | ||
1611 | 41 | ], | ||
1612 | 42 | "demo_xml": [ | ||
1613 | 43 | ], | ||
1614 | 44 | "test": [ | ||
1615 | 45 | "test/adjustment_type.yml", | ||
1616 | 46 | ], | ||
1617 | 47 | "installable": True, | ||
1618 | 48 | "active": False, | ||
1619 | 49 | } | ||
1620 | 50 | 0 | ||
1621 | === removed directory 'stock_inventory_type/security' | |||
1622 | === removed file 'stock_inventory_type/security/ir.model.access.csv' | |||
1623 | --- stock_inventory_type/security/ir.model.access.csv 2011-03-09 14:54:31 +0000 | |||
1624 | +++ stock_inventory_type/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 | |||
1625 | @@ -1,2 +0,0 @@ | |||
1626 | 1 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | ||
1627 | 2 | "access_stock_adjustment_type_all","stock.adjustment.type all","model_stock_adjustment_type",,1,1,1,1 | ||
1628 | 3 | 0 | ||
1629 | === removed file 'stock_inventory_type/stock.py' | |||
1630 | --- stock_inventory_type/stock.py 2011-03-15 17:05:15 +0000 | |||
1631 | +++ stock_inventory_type/stock.py 1970-01-01 00:00:00 +0000 | |||
1632 | @@ -1,135 +0,0 @@ | |||
1633 | 1 | #!/usr/bin/env python | ||
1634 | 2 | # -*- encoding: utf-8 -*- | ||
1635 | 3 | ############################################################################## | ||
1636 | 4 | # | ||
1637 | 5 | # OpenERP, Open Source Management Solution | ||
1638 | 6 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
1639 | 7 | # | ||
1640 | 8 | # This program is free software: you can redistribute it and/or modify | ||
1641 | 9 | # it under the terms of the GNU Affero General Public License as | ||
1642 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
1643 | 11 | # License, or (at your option) any later version. | ||
1644 | 12 | # | ||
1645 | 13 | # This program is distributed in the hope that it will be useful, | ||
1646 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1647 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1648 | 16 | # GNU Affero General Public License for more details. | ||
1649 | 17 | # | ||
1650 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
1651 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1652 | 20 | # | ||
1653 | 21 | ############################################################################## | ||
1654 | 22 | |||
1655 | 23 | |||
1656 | 24 | from osv import osv | ||
1657 | 25 | from osv import fields | ||
1658 | 26 | |||
1659 | 27 | from tools.translate import _ | ||
1660 | 28 | |||
1661 | 29 | |||
1662 | 30 | class stock_adjustment_type(osv.osv): | ||
1663 | 31 | _name = 'stock.adjustment.type' | ||
1664 | 32 | _description = 'Inventory/Move Adjustment Types' | ||
1665 | 33 | |||
1666 | 34 | _columns = { | ||
1667 | 35 | 'name': fields.char(size=64, string='Name', required=True), | ||
1668 | 36 | } | ||
1669 | 37 | |||
1670 | 38 | stock_adjustment_type() | ||
1671 | 39 | |||
1672 | 40 | |||
1673 | 41 | class stock_inventory_line(osv.osv): | ||
1674 | 42 | _name = 'stock.inventory.line' | ||
1675 | 43 | _inherit = 'stock.inventory.line' | ||
1676 | 44 | |||
1677 | 45 | _columns = { | ||
1678 | 46 | 'type_id': fields.many2one('stock.adjustment.type', string='Adjustment type'), | ||
1679 | 47 | 'comment': fields.char(size=128, string='Comment'), | ||
1680 | 48 | } | ||
1681 | 49 | |||
1682 | 50 | stock_inventory_line() | ||
1683 | 51 | |||
1684 | 52 | |||
1685 | 53 | class stock_move(osv.osv): | ||
1686 | 54 | _name = 'stock.move' | ||
1687 | 55 | _inherit = 'stock.move' | ||
1688 | 56 | |||
1689 | 57 | _columns = { | ||
1690 | 58 | 'type_id': fields.many2one('stock.adjustment.type', string='Adjustment type', readonly=True), | ||
1691 | 59 | 'comment': fields.char(size=128, string='Comment'), | ||
1692 | 60 | } | ||
1693 | 61 | |||
1694 | 62 | stock_move() | ||
1695 | 63 | |||
1696 | 64 | |||
1697 | 65 | class stock_inventory(osv.osv): | ||
1698 | 66 | _name = 'stock.inventory' | ||
1699 | 67 | _inherit = 'stock.inventory' | ||
1700 | 68 | |||
1701 | 69 | def action_confirm(self, cr, uid, ids, context={}): | ||
1702 | 70 | """ Confirm the inventory and writes its finished date | ||
1703 | 71 | @return True | ||
1704 | 72 | """ | ||
1705 | 73 | # @@@override@ stock.stock_inventory.action_confirm() | ||
1706 | 74 | # to perform the correct inventory corrections we need analyze stock location by | ||
1707 | 75 | # location, never recursively, so we use a special context | ||
1708 | 76 | product_context = dict(context, compute_child=False) | ||
1709 | 77 | |||
1710 | 78 | location_obj = self.pool.get('stock.location') | ||
1711 | 79 | for inv in self.browse(cr, uid, ids, context=context): | ||
1712 | 80 | move_ids = [] | ||
1713 | 81 | for line in inv.inventory_line_id: | ||
1714 | 82 | pid = line.product_id.id | ||
1715 | 83 | product_context.update(uom=line.product_uom.id,date=inv.date) | ||
1716 | 84 | amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid] | ||
1717 | 85 | |||
1718 | 86 | change = line.product_qty - amount | ||
1719 | 87 | lot_id = line.prod_lot_id.id | ||
1720 | 88 | type_id = line.type_id.id | ||
1721 | 89 | if change: | ||
1722 | 90 | location_id = line.product_id.product_tmpl_id.property_stock_inventory.id | ||
1723 | 91 | value = { | ||
1724 | 92 | 'name': 'INV:' + str(line.inventory_id.id) + ':' + line.inventory_id.name, | ||
1725 | 93 | 'product_id': line.product_id.id, | ||
1726 | 94 | 'product_uom': line.product_uom.id, | ||
1727 | 95 | 'prodlot_id': lot_id, | ||
1728 | 96 | 'date': inv.date, | ||
1729 | 97 | # msf | ||
1730 | 98 | 'comment': line.comment, | ||
1731 | 99 | # | ||
1732 | 100 | } | ||
1733 | 101 | if change > 0: | ||
1734 | 102 | value.update( { | ||
1735 | 103 | 'product_qty': change, | ||
1736 | 104 | 'location_id': location_id, | ||
1737 | 105 | 'location_dest_id': line.location_id.id, | ||
1738 | 106 | }) | ||
1739 | 107 | else: | ||
1740 | 108 | value.update( { | ||
1741 | 109 | 'product_qty': -change, | ||
1742 | 110 | 'location_id': line.location_id.id, | ||
1743 | 111 | 'location_dest_id': location_id, | ||
1744 | 112 | }) | ||
1745 | 113 | if lot_id: | ||
1746 | 114 | value.update({ | ||
1747 | 115 | 'prodlot_id': lot_id, | ||
1748 | 116 | 'product_qty': line.product_qty | ||
1749 | 117 | }) | ||
1750 | 118 | # msf | ||
1751 | 119 | if type_id: | ||
1752 | 120 | value.update({ | ||
1753 | 121 | 'type_id': type_id, | ||
1754 | 122 | }) | ||
1755 | 123 | # | ||
1756 | 124 | move_ids.append(self._inventory_line_hook(cr, uid, line, value)) | ||
1757 | 125 | message = _('Inventory') + " '" + inv.name + "' "+ _("is done.") | ||
1758 | 126 | self.log(cr, uid, inv.id, message) | ||
1759 | 127 | self.write(cr, uid, [inv.id], {'state': 'confirm', 'move_ids': [(6, 0, move_ids)]}) | ||
1760 | 128 | |||
1761 | 129 | return True | ||
1762 | 130 | # @@@end | ||
1763 | 131 | |||
1764 | 132 | stock_inventory() | ||
1765 | 133 | |||
1766 | 134 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
1767 | 135 | |||
1768 | 136 | 0 | ||
1769 | === removed file 'stock_inventory_type/stock_data.xml' | |||
1770 | --- stock_inventory_type/stock_data.xml 2011-03-09 14:54:31 +0000 | |||
1771 | +++ stock_inventory_type/stock_data.xml 1970-01-01 00:00:00 +0000 | |||
1772 | @@ -1,23 +0,0 @@ | |||
1773 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
1774 | 2 | <openerp> | ||
1775 | 3 | <data> | ||
1776 | 4 | |||
1777 | 5 | <record id="adjustment_type_loss" model="stock.adjustment.type"> | ||
1778 | 6 | <field name="name">Loss</field> | ||
1779 | 7 | </record> | ||
1780 | 8 | |||
1781 | 9 | <record id="adjustment_type_scrap" model="stock.adjustment.type"> | ||
1782 | 10 | <field name="name">Scrap</field> | ||
1783 | 11 | </record> | ||
1784 | 12 | |||
1785 | 13 | <record id="adjustment_type_expired" model="stock.adjustment.type"> | ||
1786 | 14 | <field name="name">Expired</field> | ||
1787 | 15 | </record> | ||
1788 | 16 | |||
1789 | 17 | <record id="adjustment_type_broken" model="stock.adjustment.type"> | ||
1790 | 18 | <field name="name">Broken</field> | ||
1791 | 19 | </record> | ||
1792 | 20 | |||
1793 | 21 | </data> | ||
1794 | 22 | </openerp> | ||
1795 | 23 | |||
1796 | 24 | 0 | ||
1797 | === removed file 'stock_inventory_type/stock_move_report.py' | |||
1798 | --- stock_inventory_type/stock_move_report.py 2011-03-15 17:05:15 +0000 | |||
1799 | +++ stock_inventory_type/stock_move_report.py 1970-01-01 00:00:00 +0000 | |||
1800 | @@ -1,130 +0,0 @@ | |||
1801 | 1 | # -*- coding: utf-8 -*- | ||
1802 | 2 | ############################################################################## | ||
1803 | 3 | # | ||
1804 | 4 | # OpenERP, Open Source Management Solution | ||
1805 | 5 | # Copyright (C) 2011 TeMPO Consulting, MSF | ||
1806 | 6 | # | ||
1807 | 7 | # This program is free software: you can redistribute it and/or modify | ||
1808 | 8 | # it under the terms of the GNU Affero General Public License as | ||
1809 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
1810 | 10 | # License, or (at your option) any later version. | ||
1811 | 11 | # | ||
1812 | 12 | # This program is distributed in the hope that it will be useful, | ||
1813 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1814 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1815 | 15 | # GNU Affero General Public License for more details. | ||
1816 | 16 | # | ||
1817 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
1818 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1819 | 19 | # | ||
1820 | 20 | ############################################################################## | ||
1821 | 21 | |||
1822 | 22 | from osv import osv | ||
1823 | 23 | from osv import fields | ||
1824 | 24 | |||
1825 | 25 | from decimal_precision import decimal_precision as dp | ||
1826 | 26 | |||
1827 | 27 | import tools | ||
1828 | 28 | |||
1829 | 29 | |||
1830 | 30 | class report_stock_move(osv.osv): | ||
1831 | 31 | _name = 'report.stock.move' | ||
1832 | 32 | _inherit = 'report.stock.move' | ||
1833 | 33 | |||
1834 | 34 | _columns = { | ||
1835 | 35 | 'type_id': fields.many2one('stock.adjustment.type', string='Adjustment type'), | ||
1836 | 36 | } | ||
1837 | 37 | |||
1838 | 38 | def init(self, cr): | ||
1839 | 39 | # @@@override@ stock.report_stock_move.init | ||
1840 | 40 | tools.drop_view_if_exists(cr, 'report_stock_move') | ||
1841 | 41 | cr.execute(""" | ||
1842 | 42 | CREATE OR REPLACE view report_stock_move AS ( | ||
1843 | 43 | SELECT | ||
1844 | 44 | min(sm_id) as id, | ||
1845 | 45 | sm_type_id as type_id, | ||
1846 | 46 | date_trunc('day',al.dp) as date, | ||
1847 | 47 | al.curr_year as year, | ||
1848 | 48 | al.curr_month as month, | ||
1849 | 49 | al.curr_day as day, | ||
1850 | 50 | al.curr_day_diff as day_diff, | ||
1851 | 51 | al.curr_day_diff1 as day_diff1, | ||
1852 | 52 | al.curr_day_diff2 as day_diff2, | ||
1853 | 53 | al.location_id as location_id, | ||
1854 | 54 | al.picking_id as picking_id, | ||
1855 | 55 | al.company_id as company_id, | ||
1856 | 56 | al.location_dest_id as location_dest_id, | ||
1857 | 57 | al.product_qty, | ||
1858 | 58 | al.out_qty as product_qty_out, | ||
1859 | 59 | al.in_qty as product_qty_in, | ||
1860 | 60 | al.address_id as partner_id, | ||
1861 | 61 | al.product_id as product_id, | ||
1862 | 62 | al.state as state , | ||
1863 | 63 | al.product_uom as product_uom, | ||
1864 | 64 | al.categ_id as categ_id, | ||
1865 | 65 | coalesce(al.type, 'other') as type, | ||
1866 | 66 | al.stock_journal as stock_journal, | ||
1867 | 67 | sum(al.in_value - al.out_value) as value | ||
1868 | 68 | FROM (SELECT | ||
1869 | 69 | CASE WHEN sp.type in ('out') THEN | ||
1870 | 70 | sum(sm.product_qty * pu.factor) | ||
1871 | 71 | ELSE 0.0 | ||
1872 | 72 | END AS out_qty, | ||
1873 | 73 | CASE WHEN sp.type in ('in') THEN | ||
1874 | 74 | sum(sm.product_qty * pu.factor) | ||
1875 | 75 | ELSE 0.0 | ||
1876 | 76 | END AS in_qty, | ||
1877 | 77 | CASE WHEN sp.type in ('out') THEN | ||
1878 | 78 | sum(sm.product_qty * pu.factor) * pt.standard_price | ||
1879 | 79 | ELSE 0.0 | ||
1880 | 80 | END AS out_value, | ||
1881 | 81 | CASE WHEN sp.type in ('in') THEN | ||
1882 | 82 | sum(sm.product_qty * pu.factor) * pt.standard_price | ||
1883 | 83 | ELSE 0.0 | ||
1884 | 84 | END AS in_value, | ||
1885 | 85 | min(sm.id) as sm_id, | ||
1886 | 86 | sm.date as dp, | ||
1887 | 87 | sm.type_id as sm_type_id, | ||
1888 | 88 | to_char(date_trunc('day',sm.date), 'YYYY') as curr_year, | ||
1889 | 89 | to_char(date_trunc('day',sm.date), 'MM') as curr_month, | ||
1890 | 90 | to_char(date_trunc('day',sm.date), 'YYYY-MM-DD') as curr_day, | ||
1891 | 91 | avg(date(sm.date)-date(sm.create_date)) as curr_day_diff, | ||
1892 | 92 | avg(date(sm.date_expected)-date(sm.create_date)) as curr_day_diff1, | ||
1893 | 93 | avg(date(sm.date)-date(sm.date_expected)) as curr_day_diff2, | ||
1894 | 94 | sm.location_id as location_id, | ||
1895 | 95 | sm.location_dest_id as location_dest_id, | ||
1896 | 96 | sum(sm.product_qty) as product_qty, | ||
1897 | 97 | pt.categ_id as categ_id , | ||
1898 | 98 | sm.address_id as address_id, | ||
1899 | 99 | sm.product_id as product_id, | ||
1900 | 100 | sm.picking_id as picking_id, | ||
1901 | 101 | sm.company_id as company_id, | ||
1902 | 102 | sm.state as state, | ||
1903 | 103 | sm.product_uom as product_uom, | ||
1904 | 104 | sp.type as type, | ||
1905 | 105 | sp.stock_journal_id AS stock_journal | ||
1906 | 106 | FROM | ||
1907 | 107 | stock_move sm | ||
1908 | 108 | LEFT JOIN stock_picking sp ON (sm.picking_id=sp.id) | ||
1909 | 109 | LEFT JOIN product_product pp ON (sm.product_id=pp.id) | ||
1910 | 110 | LEFT JOIN product_uom pu ON (sm.product_uom=pu.id) | ||
1911 | 111 | LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id) | ||
1912 | 112 | LEFT JOIN stock_location sl ON (sm.location_id = sl.id) | ||
1913 | 113 | |||
1914 | 114 | GROUP BY | ||
1915 | 115 | sm.id,sp.type, sm.date,sm.address_id, sm.type_id, | ||
1916 | 116 | sm.product_id,sm.state,sm.product_uom,sm.date_expected, | ||
1917 | 117 | sm.product_id,pt.standard_price, sm.picking_id, sm.product_qty, | ||
1918 | 118 | sm.company_id,sm.product_qty, sm.location_id,sm.location_dest_id,pu.factor,pt.categ_id, sp.stock_journal_id) | ||
1919 | 119 | AS al | ||
1920 | 120 | |||
1921 | 121 | GROUP BY | ||
1922 | 122 | al.out_qty,al.in_qty,al.curr_year,al.curr_month, al.sm_type_id, | ||
1923 | 123 | al.curr_day,al.curr_day_diff,al.curr_day_diff1,al.curr_day_diff2,al.dp,al.location_id,al.location_dest_id, | ||
1924 | 124 | al.address_id,al.product_id,al.state,al.product_uom, | ||
1925 | 125 | al.picking_id,al.company_id,al.type,al.product_qty, al.categ_id, al.stock_journal | ||
1926 | 126 | ) | ||
1927 | 127 | """) | ||
1928 | 128 | # @@@end | ||
1929 | 129 | |||
1930 | 130 | report_stock_move() | ||
1931 | 131 | 0 | ||
1932 | === removed file 'stock_inventory_type/stock_view.xml' | |||
1933 | --- stock_inventory_type/stock_view.xml 2011-03-15 17:05:15 +0000 | |||
1934 | +++ stock_inventory_type/stock_view.xml 1970-01-01 00:00:00 +0000 | |||
1935 | @@ -1,196 +0,0 @@ | |||
1936 | 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
1937 | 2 | <openerp> | ||
1938 | 3 | <data> | ||
1939 | 4 | |||
1940 | 5 | <!-- Stock Adjustment Types --> | ||
1941 | 6 | |||
1942 | 7 | <record id="stock_adjustment_type_form_view" model="ir.ui.view"> | ||
1943 | 8 | <field name="name">stock.adjustment.type.form.view</field> | ||
1944 | 9 | <field name="model">stock.adjustment.type</field> | ||
1945 | 10 | <field name="type">form</field> | ||
1946 | 11 | <field name="arch" type="xml"> | ||
1947 | 12 | <form string="Adjustment Type"> | ||
1948 | 13 | <field name="name" colspan="4" select="1" /> | ||
1949 | 14 | </form> | ||
1950 | 15 | </field> | ||
1951 | 16 | </record> | ||
1952 | 17 | |||
1953 | 18 | <record id="stock_adjustment_type_tree_view" model="ir.ui.view"> | ||
1954 | 19 | <field name="name">stock.adjustment.type.tree.view</field> | ||
1955 | 20 | <field name="model">stock.adjustment.type</field> | ||
1956 | 21 | <field name="type">tree</field> | ||
1957 | 22 | <field name="arch" type="xml"> | ||
1958 | 23 | <tree string="Adjustment Types"> | ||
1959 | 24 | <field name="name" /> | ||
1960 | 25 | </tree> | ||
1961 | 26 | </field> | ||
1962 | 27 | </record> | ||
1963 | 28 | |||
1964 | 29 | <record id="action_stock_adjustment_type" model="ir.actions.act_window"> | ||
1965 | 30 | <field name="name">Stock Adjustment Types</field> | ||
1966 | 31 | <field name="res_model">stock.adjustment.type</field> | ||
1967 | 32 | <field name="view_type">form</field> | ||
1968 | 33 | <field name="view_mode">tree,form</field> | ||
1969 | 34 | </record> | ||
1970 | 35 | |||
1971 | 36 | <menuitem | ||
1972 | 37 | name="Inventory" | ||
1973 | 38 | id="menu_configuration_inventory" | ||
1974 | 39 | parent="stock.menu_stock_configuration" /> | ||
1975 | 40 | |||
1976 | 41 | <menuitem | ||
1977 | 42 | action="action_stock_adjustment_type" | ||
1978 | 43 | id="menu_stock_adjustment_type" | ||
1979 | 44 | parent="menu_configuration_inventory" /> | ||
1980 | 45 | |||
1981 | 46 | |||
1982 | 47 | <!-- Overrirde Stock Inventory Lines --> | ||
1983 | 48 | <record id="stock_inventory_line_tree_type_id" model="ir.ui.view"> | ||
1984 | 49 | <field name="name">stock.inventory.line.tree.type.id</field> | ||
1985 | 50 | <field name="model">stock.inventory.line</field> | ||
1986 | 51 | <field name="type">tree</field> | ||
1987 | 52 | <field name="inherit_id" ref="stock.stock_inventory_line_tree" /> | ||
1988 | 53 | <field name="arch" type="xml"> | ||
1989 | 54 | <xpath expr="/tree/field[@name='prodlot_id']" position="after"> | ||
1990 | 55 | <field name="type_id" widget="selection" /> | ||
1991 | 56 | <field name="comment" /> | ||
1992 | 57 | </xpath> | ||
1993 | 58 | </field> | ||
1994 | 59 | </record> | ||
1995 | 60 | |||
1996 | 61 | <record id="stock_inventory_line_form_type_id" model="ir.ui.view"> | ||
1997 | 62 | <field name="name">stock.inventory.line.form.type.id</field> | ||
1998 | 63 | <field name="model">stock.inventory.line</field> | ||
1999 | 64 | <field name="type">form</field> | ||
2000 | 65 | <field name="inherit_id" ref="stock.stock_inventory_line_tree" /> | ||
2001 | 66 | <field name="arch" type="xml"> | ||
2002 | 67 | <xpath expr="/form/field[@name='prodlot_id']" position="after"> | ||
2003 | 68 | <field name="type_id" widget="selection" /> | ||
2004 | 69 | <field name="comment" /> | ||
2005 | 70 | </xpath> | ||
2006 | 71 | </field> | ||
2007 | 72 | </record> | ||
2008 | 73 | |||
2009 | 74 | <record id="stock_inventory_form_type_id" model="ir.ui.view"> | ||
2010 | 75 | <field name="name">stock.inventory.form.type.id</field> | ||
2011 | 76 | <field name="model">stock.inventory</field> | ||
2012 | 77 | <field name="type">form</field> | ||
2013 | 78 | <field name="inherit_id" ref="stock.view_inventory_form" /> | ||
2014 | 79 | <field name="arch" type="xml"> | ||
2015 | 80 | <data> | ||
2016 | 81 | <xpath expr="/form/notebook/page/field[@name='inventory_line_id']/tree/field[@name='product_id']" position="after"> | ||
2017 | 82 | <field name="type_id" widget="selection" /> | ||
2018 | 83 | <field name="comment" /> | ||
2019 | 84 | </xpath> | ||
2020 | 85 | <xpath expr="/form/notebook/page/field[@name='inventory_line_id']/form/field[@name='product_id']" position="after"> | ||
2021 | 86 | <field name="type_id" widget="selection" /> | ||
2022 | 87 | <field name="comment" /> | ||
2023 | 88 | </xpath> | ||
2024 | 89 | <xpath expr="/form/notebook/page[@string='Posted Inventory']/field[@name='move_ids']/tree/field[@name='prodlot_id']" position="after"> | ||
2025 | 90 | <field name="type_id" widget="selection" /> | ||
2026 | 91 | </xpath> | ||
2027 | 92 | </data> | ||
2028 | 93 | </field> | ||
2029 | 94 | </record> | ||
2030 | 95 | |||
2031 | 96 | <!-- Override Stock Moves --> | ||
2032 | 97 | <record id="stock_move_tree_type_id" model="ir.ui.view"> | ||
2033 | 98 | <field name="name">stock.move.tree.type.id</field> | ||
2034 | 99 | <field name="model">stock.move</field> | ||
2035 | 100 | <field name="type">tree</field> | ||
2036 | 101 | <field name="inherit_id" ref="stock.stock_move_tree" /> | ||
2037 | 102 | <field name="arch" type="xml"> | ||
2038 | 103 | <xpath expr="/tree/field[@name='prodlot_id']" position="after"> | ||
2039 | 104 | <field name="type_id" widget="selection" /> | ||
2040 | 105 | <field name="comment" /> | ||
2041 | 106 | </xpath> | ||
2042 | 107 | </field> | ||
2043 | 108 | </record> | ||
2044 | 109 | |||
2045 | 110 | <record id="stock_move_tree2_type_id" model="ir.ui.view"> | ||
2046 | 111 | <field name="name">stock.move.tree2.type.id</field> | ||
2047 | 112 | <field name="model">stock.move</field> | ||
2048 | 113 | <field name="type">tree</field> | ||
2049 | 114 | <field name="inherit_id" ref="stock.stock_move_tree2" /> | ||
2050 | 115 | <field name="arch" type="xml"> | ||
2051 | 116 | <xpath expr="/tree/field[@name='prodlot_id']" position="after"> | ||
2052 | 117 | <field name="type_id" widget="selection" /> | ||
2053 | 118 | <field name="comment" /> | ||
2054 | 119 | </xpath> | ||
2055 | 120 | </field> | ||
2056 | 121 | </record> | ||
2057 | 122 | |||
2058 | 123 | <record id="view_move_tree_type_id" model="ir.ui.view"> | ||
2059 | 124 | <field name="name">view.move.tree.type.id</field> | ||
2060 | 125 | <field name="model">stock.move</field> | ||
2061 | 126 | <field name="type">tree</field> | ||
2062 | 127 | <field name="inherit_id" ref="stock.view_move_tree" /> | ||
2063 | 128 | <field name="arch" type="xml"> | ||
2064 | 129 | <xpath expr="/tree/field[@name='create_date']" position="after"> | ||
2065 | 130 | <field name="type_id" widget="selection" /> | ||
2066 | 131 | <field name="comment" /> | ||
2067 | 132 | </xpath> | ||
2068 | 133 | </field> | ||
2069 | 134 | </record> | ||
2070 | 135 | |||
2071 | 136 | <record id="view_move_form_type_id" model="ir.ui.view"> | ||
2072 | 137 | <field name="name">view.move.form.type.id</field> | ||
2073 | 138 | <field name="model">stock.move</field> | ||
2074 | 139 | <field name="type">form</field> | ||
2075 | 140 | <field name="inherit_id" ref="stock.view_move_form" /> | ||
2076 | 141 | <field name="arch" type="xml"> | ||
2077 | 142 | <xpath expr="/form/group/button[@string='Scrap']" position="after"> | ||
2078 | 143 | <field name="type_id" widget="selection" /> | ||
2079 | 144 | <field name="comment" /> | ||
2080 | 145 | </xpath> | ||
2081 | 146 | </field> | ||
2082 | 147 | </record> | ||
2083 | 148 | |||
2084 | 149 | <record id="view_move_search_type_id" model="ir.ui.view"> | ||
2085 | 150 | <field name="name">view.move.search.type.id</field> | ||
2086 | 151 | <field name="model">stock.move</field> | ||
2087 | 152 | <field name="type">search</field> | ||
2088 | 153 | <field name="inherit_id" ref="stock.view_move_search" /> | ||
2089 | 154 | <field name="arch" type="xml"> | ||
2090 | 155 | <xpath expr="/search/group/field[@name='product_id']" position="before"> | ||
2091 | 156 | <field name="type_id" widget="selection" /> | ||
2092 | 157 | <field name="comment" /> | ||
2093 | 158 | </xpath> | ||
2094 | 159 | </field> | ||
2095 | 160 | </record> | ||
2096 | 161 | |||
2097 | 162 | <record id="view_stock_tree_type_id" model="ir.ui.view"> | ||
2098 | 163 | <field name="name">view.stock.tree.type.id</field> | ||
2099 | 164 | <field name="model">report.stock.move</field> | ||
2100 | 165 | <field name="type">tree</field> | ||
2101 | 166 | <field name="inherit_id" ref="stock.view_stock_tree" /> | ||
2102 | 167 | <field name="arch" type="xml"> | ||
2103 | 168 | <xpath expr="/tree/field[@name='type']" position="after"> | ||
2104 | 169 | <field name="type_id" /> | ||
2105 | 170 | </xpath> | ||
2106 | 171 | </field> | ||
2107 | 172 | </record> | ||
2108 | 173 | |||
2109 | 174 | <record id="view_stock_search_type_id" model="ir.ui.view"> | ||
2110 | 175 | <field name="name">view.stock.search.type.id</field> | ||
2111 | 176 | <field name="model">report.stock.move</field> | ||
2112 | 177 | <field name="type">search</field> | ||
2113 | 178 | <field name="inherit_id" ref="stock.view_stock_search" /> | ||
2114 | 179 | <field name="arch" type="xml"> | ||
2115 | 180 | <data> | ||
2116 | 181 | <xpath expr="/search/group/separator[3]" position="after"> | ||
2117 | 182 | <field name="type_id" widget="selection" /> | ||
2118 | 183 | </xpath> | ||
2119 | 184 | <xpath expr="/search/group[@string='Group By...']/filter[@name='group_type']" position="after"> | ||
2120 | 185 | <filter string="Adjustment Type" name="group_type_id" icon="terp-stock_symbol-selection" context="{'group_by':'type_id'}" /> | ||
2121 | 186 | </xpath> | ||
2122 | 187 | <xpath expr="/search/group[@string='Group By...']/separator[5]" position="replace"> | ||
2123 | 188 | <newline /> | ||
2124 | 189 | </xpath> | ||
2125 | 190 | </data> | ||
2126 | 191 | </field> | ||
2127 | 192 | </record> | ||
2128 | 193 | |||
2129 | 194 | </data> | ||
2130 | 195 | </openerp> | ||
2131 | 196 | |||
2132 | 197 | 0 | ||
2133 | === removed directory 'stock_inventory_type/test' | |||
2134 | === removed file 'stock_inventory_type/test/adjustment_type.yml' | |||
2135 | --- stock_inventory_type/test/adjustment_type.yml 2011-03-09 16:36:19 +0000 | |||
2136 | +++ stock_inventory_type/test/adjustment_type.yml 1970-01-01 00:00:00 +0000 | |||
2137 | @@ -1,117 +0,0 @@ | |||
2138 | 1 | - | ||
2139 | 2 | In order to test the stock_inventory_type module, I will create product, | ||
2140 | 3 | create a physical inventory, fill inventory lines from location | ||
2141 | 4 | - | ||
2142 | 5 | I create a product category | ||
2143 | 6 | - | ||
2144 | 7 | !record {model: product.category, id: product_category1}: | ||
2145 | 8 | name: Categ1 | ||
2146 | 9 | - | ||
2147 | 10 | I create the first product (P1) | ||
2148 | 11 | - | ||
2149 | 12 | !record {model: product.product, id: product_p1}: | ||
2150 | 13 | valuation: manual_periodic | ||
2151 | 14 | supply_method: produce | ||
2152 | 15 | mes_type: fixed | ||
2153 | 16 | uom_id: product.product_uom_unit | ||
2154 | 17 | uom_po_id: product.product_uom_unit | ||
2155 | 18 | type: product | ||
2156 | 19 | procure_method: make_to_stock | ||
2157 | 20 | cost_method: standard | ||
2158 | 21 | categ_id: stock_inventory_type.product_category1 | ||
2159 | 22 | name: P1 | ||
2160 | 23 | standard_price: 10.0 | ||
2161 | 24 | - | ||
2162 | 25 | I create the second product (P2) | ||
2163 | 26 | - | ||
2164 | 27 | !record {model: product.product, id: product_p2}: | ||
2165 | 28 | valuation: manual_periodic | ||
2166 | 29 | supply_method: produce | ||
2167 | 30 | mes_type: fixed | ||
2168 | 31 | uom_id: product.product_uom_unit | ||
2169 | 32 | uom_po_id: product.product_uom_unit | ||
2170 | 33 | type: product | ||
2171 | 34 | procure_method: make_to_stock | ||
2172 | 35 | cost_method: standard | ||
2173 | 36 | categ_id: stock_inventory_type.product_category1 | ||
2174 | 37 | name: P2 | ||
2175 | 38 | standard_price: 20.0 | ||
2176 | 39 | - | ||
2177 | 40 | I create the third product (P3) | ||
2178 | 41 | - | ||
2179 | 42 | !record {model: product.product, id: product_p3}: | ||
2180 | 43 | valuation: manual_periodic | ||
2181 | 44 | supply_method: produce | ||
2182 | 45 | mes_type: fixed | ||
2183 | 46 | uom_id: product.product_uom_unit | ||
2184 | 47 | uom_po_id: product.product_uom_unit | ||
2185 | 48 | type: product | ||
2186 | 49 | procure_method: make_to_stock | ||
2187 | 50 | cost_method: standard | ||
2188 | 51 | categ_id: stock_inventory_type.product_category1 | ||
2189 | 52 | name: P3 | ||
2190 | 53 | standard_price: 30.0 | ||
2191 | 54 | - | ||
2192 | 55 | I create a physical inventory | ||
2193 | 56 | - | ||
2194 | 57 | !record {model: stock.inventory, id: stock_inventory1}: | ||
2195 | 58 | company_id: base.main_company | ||
2196 | 59 | date: !eval time.strftime('%Y-%m-%d %H:%M:%S') | ||
2197 | 60 | inventory_line_id: | ||
2198 | 61 | - company_id: base.main_company | ||
2199 | 62 | location_id: stock.stock_location_stock | ||
2200 | 63 | product_id: stock_inventory_type.product_p1 | ||
2201 | 64 | product_qty: 70.0 | ||
2202 | 65 | product_uom: product.product_uom_unit | ||
2203 | 66 | type_id: stock_inventory_type.adjustment_type_loss | ||
2204 | 67 | comment: Loss items | ||
2205 | 68 | - company_id: base.main_company | ||
2206 | 69 | location_id: stock.stock_location_stock | ||
2207 | 70 | product_id: stock_inventory_type.product_p2 | ||
2208 | 71 | product_qty: 50.0 | ||
2209 | 72 | product_uom: product.product_uom_unit | ||
2210 | 73 | type_id: stock_inventory_type.adjustment_type_expired | ||
2211 | 74 | comment: Expired product at 12/12/2012 | ||
2212 | 75 | - company_id: base.main_company | ||
2213 | 76 | location_id: stock.stock_location_stock | ||
2214 | 77 | product_id: stock_inventory_type.product_p3 | ||
2215 | 78 | product_qty: 10.0 | ||
2216 | 79 | product_uom: product.product_uom_unit | ||
2217 | 80 | type_id: stock_inventory_type.adjustment_type_scrap | ||
2218 | 81 | name: Test of UNI-SUP-1.15 | ||
2219 | 82 | state: draft | ||
2220 | 83 | - | ||
2221 | 84 | I confirm the Inventory | ||
2222 | 85 | - | ||
2223 | 86 | !python {model: stock.inventory}: | | ||
2224 | 87 | self.action_confirm(cr, uid, [ref('stock_inventory1')]) | ||
2225 | 88 | self.action_done(cr, uid, [ref('stock_inventory1')]) | ||
2226 | 89 | - | ||
2227 | 90 | I check the 'Loss' stock moves | ||
2228 | 91 | - | ||
2229 | 92 | !python {model: stock.move}: | | ||
2230 | 93 | move_ids = self.search(cr, uid, [('type_id', '=', ref('stock_inventory_type.adjustment_type_loss'))]) | ||
2231 | 94 | assert move_ids, "No lines with 'Loss' type" | ||
2232 | 95 | move = self.browse(cr, uid, move_ids[0]) | ||
2233 | 96 | assert move.product_id.id == ref('stock_inventory_type.product_p1'), "Move product (P1) is not correct" | ||
2234 | 97 | assert move.product_qty == 70.0, "Move quatity (70.0) is not correct" | ||
2235 | 98 | assert move.comment == 'Loss items', "Move comment (Loss items) is not correct" | ||
2236 | 99 | - | ||
2237 | 100 | I check the 'Expired' stock moves | ||
2238 | 101 | - | ||
2239 | 102 | !python {model: stock.move}: | | ||
2240 | 103 | move_ids = self.search(cr, uid, [('type_id', '=', ref('stock_inventory_type.adjustment_type_expired'))]) | ||
2241 | 104 | assert move_ids, "No lines with 'Expired' type" | ||
2242 | 105 | move = self.browse(cr, uid, move_ids[0]) | ||
2243 | 106 | assert move.product_id.id == ref('stock_inventory_type.product_p2'), "Move product (P2) is not correct" | ||
2244 | 107 | assert move.product_qty == 50.0, "Move quatity (50.0) is not correct" | ||
2245 | 108 | assert move.comment == 'Expired product at 12/12/2012', "Move comment (Expired product at 12/12/2012) is not correct" | ||
2246 | 109 | - | ||
2247 | 110 | I check the 'Scrapped' stock moves | ||
2248 | 111 | - | ||
2249 | 112 | !python {model: stock.move}: | | ||
2250 | 113 | move_ids = self.search(cr, uid, [('type_id', '=', ref('stock_inventory_type.adjustment_type_scrap'))]) | ||
2251 | 114 | assert move_ids, "No lines with 'Scrap' type" | ||
2252 | 115 | move = self.browse(cr, uid, move_ids[0]) | ||
2253 | 116 | assert move.product_id.id == ref('stock_inventory_type.product_p3'), "Move product (P3) is not correct" | ||
2254 | 117 | assert move.product_qty == 10.0, "Move quatity (10.0) is not correct" |
Please set supplier selection on procurement. list.line and move buttons "create_rfq", "create_po" from procurement. choose. supplier to procurement.list.