changeset c828d3afdd9f in modules/account_stock_continental:default
details:
https://hg.tryton.org/modules/account_stock_continental?cmd=changeset;node=c828d3afdd9f
description:
Store product cost price revision
The "Modify Cost Price" wizard create a revision record for each
template or
product. The cost price re-computation methods apply those revisions at
the
beginning of their date.
The stock accounting move is created and posted when the cost price is
modified
by the re-computation.
issue8930
review260751002
diffstat:
__init__.py | 5 -
message.xml | 11 -
product.py | 184 +++++---------------------
product.xml | 25 ---
tests/scenario_account_stock_continental.rst | 6 +-
tryton.cfg | 1 -
view/modify_cost_price_ask_form.xml | 15 --
view/modify_cost_price_show_move_form.xml | 11 -
8 files changed, 42 insertions(+), 216 deletions(-)
diffs (346 lines):
diff -r 5edcf9732d0d -r c828d3afdd9f __init__.py
--- a/__init__.py Wed Jan 08 14:36:45 2020 +0100
+++ b/__init__.py Sun Jan 26 21:10:40 2020 +0100
@@ -18,9 +18,4 @@
account.ConfigurationStockJournal,
account.FiscalYear,
account.AccountMove,
- product.ModifyCostPriceAsk,
- product.ModifyCostPriceShowMove,
module='account_stock_continental', type_='model')
- Pool.register(
- product.ModifyCostPrice,
- module='account_stock_continental', type_='wizard')
diff -r 5edcf9732d0d -r c828d3afdd9f message.xml
--- a/message.xml Wed Jan 08 14:36:45 2020 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<tryton>
- <data grouped="1">
- <record model="ir.message" id="msg_product_change_cost_price">
- <field name="text">You cannot change the cost price of a product
which is associated to stock moves.
-You must use the "Modify Cost Price" wizard.</field>
- </record>
- </data>
-</tryton>
diff -r 5edcf9732d0d -r c828d3afdd9f product.py
--- a/product.py Wed Jan 08 14:36:45 2020 +0100
+++ b/product.py Sun Jan 26 21:10:40 2020 +0100
@@ -3,19 +3,14 @@
from decimal import Decimal
from trytond import backend
-from trytond.model import ModelView, fields
-from trytond.wizard import Wizard, StateView, StateTransition, Button
+from trytond.model import fields
from trytond.pyson import Eval
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.modules.account_product.product import (
account_used, template_property)
-from trytond.modules.product import price_digits
-__all__ = ['Category', 'CategoryAccount', 'Template',
- 'Product', 'ModifyCostPriceAsk',
- 'ModifyCostPriceShowMove', 'ModifyCostPrice']
account_names = [
'account_stock', 'account_stock_in', 'account_stock_out']
@@ -181,161 +176,62 @@
account_stock_in_used = template_property('account_stock_in_used')
account_stock_out_used = template_property('account_stock_out_used')
-
-class ModifyCostPriceAsk(ModelView):
- 'Modify Cost Price Ask'
- __name__ = 'product.modify_cost_price.ask'
- template = fields.Many2One('product.template', 'Product', readonly=True,
- states={
- 'invisible': ~Eval('template'),
- })
- product = fields.Many2One('product.product', 'Variant', readonly=True,
- states={
- 'invisible': ~Eval('product'),
- })
- cost_price = fields.Numeric('Cost Price', required=True,
- digits=price_digits)
-
-
-class ModifyCostPriceShowMove(ModelView):
- 'Modify Cost Price Show Move'
- __name__ = 'product.modify_cost_price.show_move'
- price_difference = fields.Numeric('Price Difference', readonly=True,
- digits=price_digits)
- amount = fields.Numeric('Amount', readonly=True,
- digits=(16, Eval('currency_digits', 2)), depends=['currency_digits'])
- currency_digits = fields.Integer('Currency Digits', readonly=True)
- description = fields.Char('Description')
-
-
-class ModifyCostPrice(Wizard):
- 'Modify Cost Price'
- __name__ = 'product.modify_cost_price'
- start_state = 'ask_price'
- ask_price = StateView('product.modify_cost_price.ask',
- 'account_stock_continental.modify_cost_price_ask_form', [
- Button('Cancel', 'end', 'tryton-cancel'),
- Button('OK', 'should_show_move', 'tryton-forward', default=True),
- ])
- should_show_move = StateTransition()
- show_move = StateView('product.modify_cost_price.show_move',
- 'account_stock_continental.modify_cost_price_show_move_form', [
- Button('Cancel', 'end', 'tryton-cancel'),
- Button('OK', 'create_move', 'tryton-ok', default=True),
- ])
- create_move = StateTransition()
- modify_price = StateTransition()
-
@classmethod
- def get_product(cls):
- 'Return the product instance'
- pool = Pool()
- Product = pool.get('product.product')
- context = Transaction().context
- return Product(context['active_id'])
-
- def default_ask_price(self, fields):
- default = {}
- product = self.get_product()
- default['product'] = product.id
- default['cost_price'] = getattr(
- product, 'recompute_cost_price_%s' % product.cost_price_method)()
- return default
-
- @classmethod
- def get_quantity(cls):
+ def update_cost_price(cls, costs):
pool = Pool()
Date = pool.get('ir.date')
Stock = pool.get('stock.location')
+ Company = pool.get('company.company')
+ Move = pool.get('account.move')
+ context = Transaction().context
locations = Stock.search([('type', '=', 'storage')])
stock_date_end = Date.today()
+ company = Company(context['company'])
+ moves = []
with Transaction().set_context(locations=[l.id for l in locations],
stock_date_end=stock_date_end):
- product = cls.get_product()
- return product.quantity
-
- @property
- def company(self):
- pool = Pool()
- User = pool.get('res.user')
- user = User(Transaction().user)
- return user.company
-
- @property
- def difference_price(self):
- product = self.get_product()
- return self.ask_price.cost_price - product.cost_price
-
- def get_amount(self):
- return self.company.currency.round(
- Decimal(str(self.get_quantity())) * self.difference_price)
-
- def transition_should_show_move(self):
- if self.get_quantity() != 0:
- return 'show_move'
- return 'modify_price'
+ for cost, products in costs.items():
+ products = cls.browse(products)
+ for product in products:
+ difference = cost - product.cost_price
+ quantity = product.quantity
+ amount = company.currency.round(
+ Decimal(str(quantity)) * difference)
+ if amount:
+ moves.append(product._update_cost_price_move(
+ amount, company))
+ Move.save(moves)
+ Move.post(moves)
+ super().update_cost_price(costs)
- def default_show_move(self, fields):
- return {
- 'amount': self.get_amount(),
- 'price_difference': self.difference_price,
- 'currency_digits': self.company.currency.digits,
- }
-
- def get_move_lines(self):
+ def _update_cost_price_move(self, amount, company):
pool = Pool()
- Line = pool.get('account.move.line')
- product = self.get_product()
- amount = self.get_amount()
- if amount > 0:
- account = product.account_stock_in_used
- else:
- account = product.account_stock_out_used
- return [Line(
- debit=amount if amount > 0 else 0,
- credit=-amount if amount < 0 else 0,
- account=product.account_stock_used,
- ),
- Line(
- debit=-amount if amount < 0 else 0,
- credit=amount if amount > 0 else 0,
- account=account,
- ),
- ]
-
- def get_move(self):
- pool = Pool()
+ AccountConfiguration = pool.get('account.configuration')
Date = pool.get('ir.date')
Period = pool.get('account.period')
- User = pool.get('res.user')
Move = pool.get('account.move')
- AccountConfiguration = pool.get('account.configuration')
+ Line = pool.get('account.move.line')
config = AccountConfiguration(1)
- user = User(Transaction().user)
- period_id = Period.find(user.company.id)
+ if amount > 0:
+ account = self.account_stock_in_used
+ else:
+ account = self.account_stock_out_used
return Move(
- description=self.show_move.description,
- period=period_id,
+ period=Period.find(company.id),
journal=config.stock_journal,
date=Date.today(),
- origin=self.get_product(),
- lines=self.get_move_lines(),
+ origin=self,
+ lines=[Line(
+ debit=amount if amount > 0 else 0,
+ credit=-amount if amount < 0 else 0,
+ account=self.account_stock_used,
+ ),
+ Line(
+ debit=-amount if amount < 0 else 0,
+ credit=amount if amount > 0 else 0,
+ account=account,
+ ),
+ ],
)
-
- def transition_create_move(self):
- Move = Pool().get('account.move')
- move = self.get_move()
- move.save()
- Move.post([move])
- return 'modify_price'
-
- def transition_modify_price(self):
- pool = Pool()
- Product = pool.get('product.product')
- with Transaction().set_context(_check_access=False):
- Product.write([self.get_product()], {
- 'cost_price': self.ask_price.cost_price,
- })
- return 'end'
diff -r 5edcf9732d0d -r c828d3afdd9f product.xml
--- a/product.xml Wed Jan 08 14:36:45 2020 +0100
+++ b/product.xml Sun Jan 26 21:10:40 2020 +0100
@@ -3,31 +3,6 @@
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
- <record model="ir.ui.view" id="modify_cost_price_ask_form">
- <field name="model">product.modify_cost_price.ask</field>
- <field name="type">form</field>
- <field name="name">modify_cost_price_ask_form</field>
- </record>
- <record model="ir.ui.view" id="modify_cost_price_show_move_form">
- <field name="model">product.modify_cost_price.show_move</field>
- <field name="type">form</field>
- <field name="name">modify_cost_price_show_move_form</field>
- </record>
- <record model="ir.action.wizard" id="wizard_modify_cost_price">
- <field name="name">Modify Cost Price</field>
- <field name="wiz_name">product.modify_cost_price</field>
- </record>
- <record model="ir.action.keyword"
id="modify_cost_price_product_keyword">
- <field name="keyword">form_action</field>
- <field name="model">product.product,-1</field>
- <field name="action" ref="wizard_modify_cost_price"/>
- </record>
- <record model="ir.action-res.group"
- id="wizard_modify_cost_price-group_account">
- <field name="action" ref="wizard_modify_cost_price"/>
- <field name="group" ref="account.group_account" />
- </record>
-
<record model="ir.ui.view" id="category_view_form">
<field name="model">product.category</field>
<field name="inherit" ref="product.category_view_form"/>
diff -r 5edcf9732d0d -r c828d3afdd9f
tests/scenario_account_stock_continental.rst
--- a/tests/scenario_account_stock_continental.rst Wed Jan 08 14:36:45
2020 +0100
+++ b/tests/scenario_account_stock_continental.rst Sun Jan 26 21:10:40
2020 +0100
@@ -376,10 +376,8 @@
>>> Account = Model.get('account.account')
>>> modify_price = Wizard('product.modify_cost_price', [product])
- >>> modify_price.form.cost_price = Decimal('3.00')
- >>> modify_price.execute('should_show_move')
- >>> modify_price.form.description = 'Change product cost price.'
- >>> modify_price.execute('create_move')
+ >>> modify_price.form.cost_price = '3.00'
+ >>> modify_price.execute('modify')
>>> product.cost_price
Decimal('3.00')
>>> stock_out.reload()
diff -r 5edcf9732d0d -r c828d3afdd9f tryton.cfg
--- a/tryton.cfg Wed Jan 08 14:36:45 2020 +0100
+++ b/tryton.cfg Sun Jan 26 21:10:40 2020 +0100
@@ -19,4 +19,3 @@
minimal_chart_pt.xml
minimal_chart_ru.xml
minimal_chart_sl.xml
- message.xml
diff -r 5edcf9732d0d -r c828d3afdd9f view/modify_cost_price_ask_form.xml
--- a/view/modify_cost_price_ask_form.xml Wed Jan 08 14:36:45 2020 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<form cursor="cost_price">
- <group id="label_product_template" col="1" xexpand="0">
- <label name="template"/>
- <label name="product"/>
- </group>
- <group id="product_template" col="1">
- <field name="template"/>
- <field name="product"/>
- </group>
- <label name="cost_price"/>
- <field name="cost_price"/>
-</form>
diff -r 5edcf9732d0d -r c828d3afdd9f view/modify_cost_price_show_move_form.xml
--- a/view/modify_cost_price_show_move_form.xml Wed Jan 08 14:36:45 2020 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<form>
- <label name="amount"/>
- <field name="amount"/>
- <label name="price_difference"/>
- <field name="price_difference"/>
- <label name="description"/>
- <field name="description" colspan="3"/>
-</form>