Merge lp:~unifield-team/unifield-wm/us-802 into lp:unifield-wm

Proposed by jftempo
Status: Merged
Merged at revision: 2716
Proposed branch: lp:~unifield-team/unifield-wm/us-802
Merge into: lp:unifield-wm
Diff against target: 676 lines (+513/-4)
11 files modified
delivery_mechanism/delivery_mechanism.py (+28/-4)
product_attributes/__init__.py (+2/-0)
product_attributes/__openerp__.py (+1/-0)
product_attributes/product_attributes.py (+20/-0)
product_attributes/report/__init__.py (+24/-0)
product_attributes/report/standard_price_track_changes.mako (+134/-0)
product_attributes/report/standard_price_track_changes_report.py (+84/-0)
product_attributes/report/standard_price_track_changes_report.xml (+19/-0)
product_attributes/security/ir.model.access.csv (+1/-0)
product_attributes/standard_price_track_changes.py (+180/-0)
specific_rules/stock.py (+20/-0)
To merge this branch: bzr merge lp:~unifield-team/unifield-wm/us-802
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+283080@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'delivery_mechanism/delivery_mechanism.py'
2--- delivery_mechanism/delivery_mechanism.py 2015-11-23 16:52:52 +0000
3+++ delivery_mechanism/delivery_mechanism.py 2016-01-19 10:41:08 +0000
4@@ -733,6 +733,16 @@
5
6 # Write the field according to price type field
7 product_obj.write(cr, uid, [line.product_id.id], {'standard_price': new_std_price})
8+ pchanged = False
9+ # Is price changed ?
10+ if line.cost and move.purchase_line_id:
11+ p_price = move.purchase_line_id.price_unit
12+ pchanged = abs(p_price - line.cost) > 10**-3
13+ sptc_values = {
14+ 'standard_price': new_std_price,
15+ 'old_price': line.product_id.standard_price,
16+ 'manually_changed': pchanged,
17+ }
18
19 # Record the values that were chosen in the wizard, so they can be
20 # used for inventory valuation of real-time valuation is enabled.
21@@ -741,7 +751,7 @@
22 'price_currency_id': line.currency.id,
23 }
24
25- return average_values
26+ return average_values, sptc_values
27
28 def _get_values_from_line(self, cr, uid, move, line, db_data, context=None):
29 """
30@@ -925,6 +935,7 @@
31 move_obj = self.pool.get('stock.move')
32 sequence_obj = self.pool.get('ir.sequence')
33 cur_obj = self.pool.get('res.currency')
34+ sptc_obj = self.pool.get('standard.price.track.changes')
35 wf_service = netsvc.LocalService("workflow")
36 usb_entity = self._get_usb_entity_type(cr, uid)
37
38@@ -983,6 +994,7 @@
39 mirror_data = move_obj.get_mirror_move(cr, uid, [move.id], data_back, context=context)[move.id]
40 out_moves = mirror_data['moves']
41 average_values = {}
42+ move_sptc_values = []
43
44 for line in move_proc_obj.browse(cr, uid, proc_ids, context=context):
45 values = self._get_values_from_line(cr, uid, move, line, db_data_dict, context=context)
46@@ -996,8 +1008,9 @@
47 compute_average = picking.type == 'in' and line.product_id.cost_method == 'average'
48
49 if compute_average:
50- average_values = self._compute_average_values(cr, uid, move, line, product_availability, context=context)
51+ average_values, sptc_values = self._compute_average_values(cr, uid, move, line, product_availability, context=context)
52 values.update(average_values)
53+ move_sptc_values.append(sptc_values)
54
55 # The quantity
56 if line.uom_id.id != move.product_uom.id:
57@@ -1155,7 +1168,12 @@
58 # If there is remaining quantity for the move, put the ID of the move
59 # and the remaining quantity to list of moves to put in backorder
60 if diff_qty > 0.00 and move.state != 'cancel':
61- backordered_moves.append((move, diff_qty, average_values, data_back))
62+ backordered_moves.append((move, diff_qty, average_values, data_back, move_sptc_values))
63+ else:
64+ for sptc_values in move_sptc_values:
65+ sptc_obj.track_change(cr, uid, move.product_id.id,
66+ _('Reception %s') % move.picking_id.name,
67+ sptc_values, context=context)
68
69 # UTP-967
70 if move.state != 'cancel' and move.purchase_line_id and move.purchase_line_id.procurement_id:
71@@ -1202,8 +1220,10 @@
72 if backorder_ids:
73 backorder_id = backorder_ids[0]
74
75+ backorder_name = picking.name
76 if not backorder_id:
77 backorder_id = self.copy(cr, uid, picking.id, initial_vals_copy, context=context)
78+ backorder_name = self.read(cr, uid, backorder_id, ['name'], context=context)['name']
79
80 back_order_post_copy_vals = {}
81 if usb_entity == self.CENTRAL_PLATFORM and context.get('rw_backorder_name', False):
82@@ -1220,7 +1240,11 @@
83 if back_order_post_copy_vals:
84 self.write(cr, uid, backorder_id, back_order_post_copy_vals, context=context)
85
86- for bo_move, bo_qty, av_values, data_back in backordered_moves:
87+ for bo_move, bo_qty, av_values, data_back, move_sptc_values in backordered_moves:
88+ for sptc_values in move_sptc_values:
89+ sptc_obj.track_change(cr, uid, move.product_id.id,
90+ _('Reception %s') % backorder_name,
91+ sptc_values, context=context)
92 if bo_move.product_qty != bo_qty:
93 # Create the corresponding move in the backorder - reset batch - reset asset_id
94 bo_values = {
95
96=== modified file 'product_attributes/__init__.py'
97--- product_attributes/__init__.py 2013-08-08 14:14:44 +0000
98+++ product_attributes/__init__.py 2016-01-19 10:41:08 +0000
99@@ -20,6 +20,8 @@
100 ##############################################################################
101
102 import product_attributes
103+import standard_price_track_changes
104 import wizard
105+import report
106
107 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
108
109=== modified file 'product_attributes/__openerp__.py'
110--- product_attributes/__openerp__.py 2014-12-01 13:28:42 +0000
111+++ product_attributes/__openerp__.py 2016-01-19 10:41:08 +0000
112@@ -31,6 +31,7 @@
113 'init_xml': [
114 'security/ir.model.access.csv',
115 'wizard/product_where_used_view.xml',
116+ 'report/standard_price_track_changes_report.xml',
117 'data/product_section_code.xml',
118 'data/product_supply_source.xml',
119 'data/product_justification_code.xml',
120
121=== modified file 'product_attributes/product_attributes.py'
122--- product_attributes/product_attributes.py 2015-11-25 13:05:56 +0000
123+++ product_attributes/product_attributes.py 2016-01-19 10:41:08 +0000
124@@ -1055,6 +1055,26 @@
125 (_check_gmdn_code, 'Warning! GMDN code must be digits!', ['gmdn_code'])
126 ]
127
128+ def create(self, cr, user, vals, context=None):
129+ """
130+ At product.product creation, create a standard.price.track.changes
131+ record with the standard price as new value and None as old value.
132+ :param cr: Cursor to the database
133+ :param user: ID of the user that creates the record
134+ :param vals: Values of the new product.product to create
135+ :param context: Context of the call
136+ :return: The ID of the new product.template record
137+ """
138+ sptc_obj = self.pool.get('standard.price.track.changes')
139+
140+ res = super(product_attributes, self).create(cr, user, vals,
141+ context=context)
142+
143+ sptc_obj.track_change(cr, user, res, _('Product creation'), vals,
144+ context=context)
145+
146+ return res
147+
148 product_attributes()
149
150
151
152=== added directory 'product_attributes/report'
153=== added file 'product_attributes/report/__init__.py'
154--- product_attributes/report/__init__.py 1970-01-01 00:00:00 +0000
155+++ product_attributes/report/__init__.py 2016-01-19 10:41:08 +0000
156@@ -0,0 +1,24 @@
157+# -*- coding: utf-8 -*-
158+##############################################################################
159+#
160+# OpenERP, Open Source Management Solution
161+# Copyright (C) 2015 TeMPO consulting, MSF
162+#
163+# This program is free software: you can redistribute it and/or modify
164+# it under the terms of the GNU Affero General Public License as
165+# published by the Free Software Foundation, either version 3 of the
166+# License, or (at your option) any later version.
167+#
168+# This program is distributed in the hope that it will be useful,
169+# but WITHOUT ANY WARRANTY; without even the implied warranty of
170+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
171+# GNU Affero General Public License for more details.
172+#
173+# You should have received a copy of the GNU Affero General Public License
174+# along with this program. If not, see <http://www.gnu.org/licenses/>.
175+#
176+##############################################################################
177+
178+import standard_price_track_changes_report
179+
180+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
181
182=== added file 'product_attributes/report/standard_price_track_changes.mako'
183--- product_attributes/report/standard_price_track_changes.mako 1970-01-01 00:00:00 +0000
184+++ product_attributes/report/standard_price_track_changes.mako 2016-01-19 10:41:08 +0000
185@@ -0,0 +1,134 @@
186+<?xml version="1.0"?>
187+<?mso-application progid="Excel.Sheet"?>
188+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
189+ xmlns:o="urn:schemas-microsoft-com:office:office"
190+ xmlns:x="urn:schemas-microsoft-com:office:excel"
191+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
192+ xmlns:html="http://www.w3.org/TR/REC-html40">
193+ <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
194+ <Author>MSF</Author>
195+ <LastAuthor>MSF</LastAuthor>
196+ <Created>${time.strftime('%Y-%m-%dT%H:%M:%SZ')|x}</Created>
197+ <Company>Medecins Sans Frontieres</Company>
198+ <Version>11.9999</Version>
199+ </DocumentProperties>
200+ <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
201+ <WindowHeight>13170</WindowHeight>
202+ <WindowWidth>19020</WindowWidth>
203+ <WindowTopX>120</WindowTopX>
204+ <WindowTopY>60</WindowTopY>
205+ <ProtectStructure>False</ProtectStructure>
206+ <ProtectWindows>False</ProtectWindows>
207+ </ExcelWorkbook>
208+ <Styles>
209+ <Style ss:ID="line_header">
210+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="0"/>
211+ <Font ss:FontName="Calibri" x:Family="Swiss" ss:Color="#000000" ss:Bold="1" />
212+ <Interior ss:Color="#E6E6E6" ss:Pattern="Solid"/>
213+ <Borders>
214+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
215+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
216+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
217+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
218+ </Borders>
219+ </Style>
220+ <Style ss:ID="line">
221+ <Alignment ss:Horizontal="Left" ss:Vertical="Center" ss:WrapText="1"/>
222+ <Font ss:FontName="Calibri" x:Family="Swiss" ss:Color="#000000" ss:Bold="0" />
223+ <Borders>
224+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
225+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
226+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
227+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
228+ </Borders>
229+ </Style>
230+ <Style ss:ID="line_short_date">
231+ <Alignment ss:Horizontal="Left" ss:Vertical="Center" ss:WrapText="1"/>
232+ <Font ss:FontName="Calibri" x:Family="Swiss" ss:Color="#000000" ss:Bold="0" />
233+ <Borders>
234+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
235+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
236+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
237+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
238+ </Borders>
239+ <NumberFormat ss:Format="General Date"/>
240+ </Style>
241+ </Styles>
242+ % for o in objects:
243+ <ss:Worksheet ss:Name="${o.default_code|x}">
244+ <Table>
245+ <Column ss:AutoFitWidth="1" ss:Width="120" />
246+ <Column ss:AutoFitWidth="1" ss:Width="120" />
247+ <Column ss:AutoFitWidth="1" ss:Width="120" />
248+ <Column ss:AutoFitWidth="1" ss:Width="120" />
249+ <Column ss:AutoFitWidth="1" ss:Width="120" />
250+ <Column ss:AutoFitWidth="1" ss:Width="120" />
251+
252+ <Row>
253+ <Cell ss:StyleID="line_header" ss:MergeAcross="1">
254+ <Data ss:Type="String">Product code</Data>
255+ </Cell>
256+ <Cell ss:StyleID="line" ss:MergeAcross="3">
257+ <Data ss:Type="String">${o.default_code|x}</Data>
258+ </Cell>
259+ </Row>
260+ <Row>
261+ <Cell ss:StyleID="line_header" ss:MergeAcross="1">
262+ <Data ss:Type="String">Product description</Data>
263+ </Cell>
264+ <Cell ss:StyleID="line" ss:MergeAcross="3">
265+ <Data ss:Type="String">${o.name|x}</Data>
266+ </Cell>
267+ </Row>
268+
269+ <!-- Empty row -->
270+ <Row></Row>
271+
272+ <Row>
273+ <Cell ss:StyleID="line_header">
274+ <Data ss:Type="String">Date</Data>
275+ </Cell>
276+ <Cell ss:StyleID="line_header">
277+ <Data ss:Type="String">User</Data>
278+ </Cell>
279+ <Cell ss:StyleID="line_header">
280+ <Data ss:Type="String">Old Cost Price</Data>
281+ </Cell>
282+ <Cell ss:StyleID="line_header">
283+ <Data ss:Type="String">New Cost Price</Data>
284+ </Cell>
285+ <Cell ss:StyleID="line_header">
286+ <Data ss:Type="String">Transaction</Data>
287+ </Cell>
288+ <Cell ss:StyleID="line_header">
289+ <Data ss:Type="String">Manually changed (at reception)</Data>
290+ </Cell>
291+ </Row>
292+ % for sptc in getSPTC(o.id):
293+ <Row>
294+ <Cell ss:StyleID="line_short_date">
295+ <Data ss:Type="DateTime">${sptc.change_date.replace(' ', 'T')|n}.000</Data>
296+ </Cell>
297+ <Cell ss:StyleID="line">
298+ <Data ss:Type="String">${sptc.user_id.name|x}</Data>
299+ </Cell>
300+ <Cell ss:StyleID="line">
301+ <Data ss:Type="Number">${sptc.old_standard_price|x}</Data>
302+ </Cell>
303+ <Cell ss:StyleID="line">
304+ <Data ss:Type="Number">${sptc.new_standard_price|x}</Data>
305+ </Cell>
306+ <Cell ss:StyleID="line">
307+ <Data ss:Type="String">${sptc.transaction_name or ''|x}</Data>
308+ </Cell>
309+ <Cell ss:StyleID="line">
310+ <Data ss:Type="String">${sptc.in_price_changed and 'X' or ''|x}</Data>
311+ </Cell>
312+ </Row>
313+ % endfor-->
314+ </Table>
315+ <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
316+ </WorksheetOptions>
317+ </ss:Worksheet>
318+ % endfor
319+</Workbook>
320\ No newline at end of file
321
322=== added file 'product_attributes/report/standard_price_track_changes_report.py'
323--- product_attributes/report/standard_price_track_changes_report.py 1970-01-01 00:00:00 +0000
324+++ product_attributes/report/standard_price_track_changes_report.py 2016-01-19 10:41:08 +0000
325@@ -0,0 +1,84 @@
326+# -*- coding: utf-8 -*-
327+##############################################################################
328+#
329+# OpenERP, Open Source Management Solution
330+# Copyright (C) 2015 TeMPO Consulting, MSF. All Rights Reserved
331+#
332+# This program is free software: you can redistribute it and/or modify
333+# it under the terms of the GNU Affero General Public License as
334+# published by the Free Software Foundation, either version 3 of the
335+# License, or (at your option) any later version.
336+#
337+# This program is distributed in the hope that it will be useful,
338+# but WITHOUT ANY WARRANTY; without even the implied warranty of
339+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
340+# GNU Affero General Public License for more details.
341+#
342+# You should have received a copy of the GNU Affero General Public License
343+# along with this program. If not, see <http://www.gnu.org/licenses/>.
344+#
345+##############################################################################
346+import time
347+
348+import pooler
349+
350+from report import report_sxw
351+from msf_supply_doc_export.msf_supply_doc_export import WebKitParser
352+from msf_supply_doc_export.msf_supply_doc_export import getIds
353+
354+
355+class parser_standard_price_track_changes_report_xls(report_sxw.rml_parse):
356+ def __init__(self, cr, uid, name, context):
357+ super(parser_standard_price_track_changes_report_xls, self).__init__(
358+ cr, uid, name, context=context)
359+ self.localcontext.update({
360+ 'time': time,
361+ 'getSPTC': self._get_sptc,
362+ })
363+
364+ def _get_sptc(self, product_id):
365+ """
366+ Return the standard.price.track.changes related to the product_id
367+ :param product_id:
368+ :return: List of browse_record of standard.price.track.changes
369+ """
370+ sptc_obj = self.pool.get('standard.price.track.changes')
371+ sptc_ids = sptc_obj.search(self.cr, self.uid, [
372+ ('product_id', '=', product_id),
373+ ])
374+ return sptc_obj.browse(self.cr, self.uid, sptc_ids)
375+
376+
377+class standard_price_track_changes_report_xls(WebKitParser):
378+ """
379+ Parser to generate the Cost Price Track Changes Excel report for a
380+ specific product.
381+ """
382+
383+ def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse,
384+ header='external', store=False):
385+ WebKitParser.__init__(self, name, table, rml=rml, parser=parser,
386+ header=header, store=store)
387+
388+ def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
389+ report_xml.webkit_debug = 1
390+ report_xml.header= " "
391+ report_xml.webkit_header.html = "${_debug or ''|n}"
392+ return super(standard_price_track_changes_report_xls,
393+ self).create_single_pdf(cr, uid, ids, data, report_xml,
394+ context=context)
395+
396+ def create(self, cr, uid, ids, data, context=None):
397+ ids = getIds(self, cr, uid, ids, context)
398+ a = super(standard_price_track_changes_report_xls, self).create(cr,
399+ uid,
400+ ids,
401+ data,
402+ context)
403+ return a[0], 'xls'
404+
405+standard_price_track_changes_report_xls(
406+ 'report.product.cost.track.changes.xls',
407+ 'product.product',
408+ 'addons/product_attributes/report/standard_price_track_changes.mako',
409+ parser=parser_standard_price_track_changes_report_xls)
410\ No newline at end of file
411
412=== added file 'product_attributes/report/standard_price_track_changes_report.xml'
413--- product_attributes/report/standard_price_track_changes_report.xml 1970-01-01 00:00:00 +0000
414+++ product_attributes/report/standard_price_track_changes_report.xml 2016-01-19 10:41:08 +0000
415@@ -0,0 +1,19 @@
416+<?xml version="1.0" encoding="utf-8" ?>
417+<openerp>
418+ <data>
419+
420+ <!-- Product Cost Price Track Changes -->
421+ <report
422+ id="report_product_cost_track_changes_xls"
423+ string="Track changes - Product prices"
424+ model="product.product"
425+ name="product.cost.track.changes.xls"
426+ file="product_attributes/report/standard_price_track_changes.mako"
427+ report_type="webkit"
428+ header="False"
429+ auto="False"
430+ menu="True"
431+ />
432+
433+ </data>
434+</openerp>
435\ No newline at end of file
436
437=== modified file 'product_attributes/security/ir.model.access.csv'
438--- product_attributes/security/ir.model.access.csv 2012-08-02 16:08:42 +0000
439+++ product_attributes/security/ir.model.access.csv 2016-01-19 10:41:08 +0000
440@@ -3,3 +3,4 @@
441 "access_product_justification_code_all","product.justification.code.all","model_product_justification_code",,1,1,1,1
442 "access_product_supply_source_all","product.supply.source.all","model_product_supply_source",,1,1,1,1
443 "access_res_country_restriction_all","res.country.restriction.all","model_res_country_restriction",,1,1,1,1
444+"access_standrad_price_track_changes_all","standard.price.track.changes.all","model_standard_price_track_changes",,1,1,1,1
445
446=== added file 'product_attributes/standard_price_track_changes.py'
447--- product_attributes/standard_price_track_changes.py 1970-01-01 00:00:00 +0000
448+++ product_attributes/standard_price_track_changes.py 2016-01-19 10:41:08 +0000
449@@ -0,0 +1,180 @@
450+# encoding: utf-8
451+##############################################################################
452+#
453+# OpenERP, Open Source Management Solution
454+# Copyright (C) 2015 TeMPO consulting, MSF
455+#
456+# This program is free software: you can redistribute it and/or modify
457+# it under the terms of the GNU General Public License as published by
458+# the Free Software Foundation, either version 3 of the License, or
459+# (at your option) any later version.
460+#
461+# This program is distributed in the hope that it will be useful,
462+# but WITHOUT ANY WARRANTY; without even the implied warranty of
463+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
464+# GNU General Public License for more details.
465+#
466+# You should have received a copy of the GNU General Public License
467+# along with this program. If not, see <http://www.gnu.org/licenses/>.
468+#
469+##############################################################################
470+import time
471+
472+import decimal_precision as dp
473+
474+from tools.translate import _
475+from osv import fields
476+from osv import osv
477+
478+
479+class standard_price_track_changes(osv.osv):
480+ """
481+ Records the modification of the cost price (standard_price) of a product.
482+ It is complementary (but independent) to the Track Changes feature.
483+
484+ To record the modification of the cost price, the product Costing Method
485+ should always be average price. The recorded prices are always in
486+ functional currency.
487+
488+ Here is the list of transactions where a modification of the cost price
489+ is recorded:
490+ * at original import/creation of Product,
491+ * at Initial stock inventory,
492+ * Each time product is received via IN, cost is re-calculated based on
493+ Moving Average Cost calculation,
494+ * When Product Cost re-valuation is done.
495+
496+ These records are only available with an Excel report on the product form.
497+ """
498+ _name = 'standard.price.track.changes'
499+ _description = 'Product Cost Price Track Changes'
500+ _rec_name = 'change_date'
501+ _order = 'change_date, id'
502+
503+ _columns = {
504+ 'change_date': fields.datetime(
505+ string='Date',
506+ required=True,
507+ readonly=True,
508+ ),
509+ 'product_id': fields.many2one(
510+ 'product.product',
511+ string='Product',
512+ required=True,
513+ readonly=True,
514+ ondelete='cascade',
515+ ),
516+ 'old_standard_price': fields.float(
517+ string='Old Cost Price',
518+ digits_compute=dp.get_precision('Account'),
519+ required=False,
520+ readonly=True,
521+ ),
522+ 'new_standard_price': fields.float(
523+ string='New Cost Price',
524+ digits_compute=dp.get_precision('Account'),
525+ required=True,
526+ readonly=True,
527+ ),
528+ 'user_id': fields.many2one(
529+ 'res.users',
530+ string='User',
531+ required=True,
532+ readonly=True,
533+ ondelete='set null',
534+ ),
535+ 'transaction_name': fields.char(
536+ string='Transaction name',
537+ size=256,
538+ required=False,
539+ readonly=True,
540+ translate=True,
541+ help="Name of the transaction which changed the product cost price",
542+ ),
543+ 'in_price_changed': fields.boolean(
544+ string='IN price changed',
545+ help="True if the price has been manually changed during reception",
546+ ),
547+ }
548+
549+ _defaults = {
550+ 'change_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
551+ 'user_id': lambda obj, cr, uid, c={}: hasattr(uid, 'realUid') and uid.realUid or uid,
552+ 'in_price_changed': False,
553+ }
554+
555+ def copy(self, cr, uid, obj_id, default=None, context=None):
556+ """
557+ Disallow the possibility to copy standard.price.track.changes object
558+ :param cr: Cursor to the database
559+ :param uid: ID of the user that copy the record
560+ :param obj_id: ID of the standard.price.track.changes to copy
561+ :param default: Default values for the new record
562+ :param context: Context of the call
563+ :return: The ID of the new standard.price.track.changes record
564+ """
565+ raise osv.except_osv(
566+ _('Operation not allowed'),
567+ _('Copy of standard.price.track.changes is not allowed'),
568+ )
569+
570+ def track_change(self, cr, uid, product_id, transaction_name, vals=None,
571+ context=None):
572+ """
573+ Create a new standard.price.track.changes record linked to the given
574+ `product_id`. Values are taken from `vals` or from the product
575+ information if the value is not in `vals`.
576+ :param cr: Cursor to the database
577+ :param uid: ID of the user that creates the record
578+ :param product_id: ID of the product.product which the cost price was
579+ changed
580+ :param transaction_name: Label of the transaction that made the price
581+ change
582+ :param vals: Values of the transaction
583+ :param context: Context of the call
584+ :return: The ID of new standard.price.track.changes record
585+ """
586+ prod_obj = self.pool.get('product.product')
587+
588+ if vals is None:
589+ vals = {}
590+
591+ prod_info = prod_obj.read(cr, uid, product_id, [
592+ 'cost_method',
593+ 'standard_price',
594+ ], context=context)
595+
596+ # If the product costing method is not 'Average Price', don't track
597+ # price changes.
598+ if vals.get('cost_method', prod_info['cost_method']) != 'average':
599+ return None
600+
601+ new_price = vals.get('standard_price', False)
602+ old_price = vals.get('old_price', False)
603+
604+ if new_price and old_price and abs(new_price - old_price) <= 10**-3:
605+ return None
606+
607+ # If it is the first standard.price.track.changes for this product
608+ # the old price must be False and the new price is the current
609+ # standard price of the product.
610+ if not old_price:
611+ new_sptc = self.search(cr, uid, [
612+ ('product_id', '=', product_id),
613+ ], limit=1, context=context)
614+ if new_sptc:
615+ old_price = prod_info['standard_price']
616+ elif not new_price:
617+ new_price = prod_info['standard_price']
618+
619+ return self.create(cr, uid, {
620+ 'product_id': product_id,
621+ 'old_standard_price': old_price,
622+ 'new_standard_price': new_price,
623+ 'transaction_name': transaction_name,
624+ 'in_price_changed': vals.get('manually_changed', False),
625+ }, context=context)
626+
627+standard_price_track_changes()
628+
629+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
630
631=== modified file 'specific_rules/stock.py'
632--- specific_rules/stock.py 2015-11-09 09:46:22 +0000
633+++ specific_rules/stock.py 2016-01-19 10:41:08 +0000
634@@ -136,10 +136,20 @@
635
636 move_obj = self.pool.get('stock.move')
637 prod_obj = self.pool.get('product.product')
638+ sptc_obj = self.pool.get('standard.price.track.changes')
639 for inv in self.browse(cr, uid, ids, context=context):
640 # Set the cost price on product form with the new value, and process the stock move
641 for move in inv.move_ids:
642 new_std_price = move.price_unit
643+ sptc_obj.track_change(cr,
644+ uid,
645+ move.product_id.id,
646+ _('Initial stock inventory %s') % inv.name,
647+ vals={
648+ 'standard_price': new_std_price,
649+ 'old_price': move.product_id.standard_price,
650+ },
651+ context=context)
652 prod_obj.write(cr, uid, move.product_id.id, {'standard_price': new_std_price}, context=context)
653 move_obj.action_done(cr, uid, move.id, context=context)
654
655@@ -477,11 +487,21 @@
656 '''
657 Change the price of the products in the lines
658 '''
659+ sptc_obj = self.pool.get('standard.price.track.changes')
660+
661 if isinstance(ids, (int, long)):
662 ids = [ids]
663
664 for obj in self.browse(cr, uid, ids, context=context):
665 for line in obj.reevaluation_line_ids:
666+ sptc_obj.track_change(cr,
667+ uid,
668+ line.product_id.id,
669+ _('Product cost reevaluation %s') % obj.name,
670+ vals={
671+ 'standard_price': line.average_cost,
672+ 'old_price': line.product_id.standard_price,
673+ }, context=context)
674 self.pool.get('product.product').write(cr, uid, line.product_id.id, {'standard_price': line.average_cost})
675
676 return self.write(cr, uid, ids, {'state': 'done'}, context=context)

Subscribers

People subscribed via source and target branches