Updating cost price must update stock accounting

review244003
This commit is contained in:
Nicolas Évrard
2012-09-07 15:51:58 +02:00
parent 6f4a3b006b
commit 7b3caee98d
7 changed files with 278 additions and 3 deletions
+2
View File
@@ -1,3 +1,5 @@
* Updating cost price must update stock accounting
Version 2.4.0 - 2012-04-23
* Bug fixes (see mercurial logs for details)
* Create move also from supplier to customer
+5 -1
View File
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.model import Model, fields
from trytond.pyson import Eval, Bool
from trytond.pyson import Eval, Bool, Get
class Configuration(Model):
@@ -12,5 +12,9 @@ class Configuration(Model):
states={
'required': Bool(Eval('context', {}).get('company')),
}))
cost_price_counterpart_account = fields.Property(fields.Many2One(
'account.account', 'Cost Price Counterpart Account', domain=[
('company', 'in', [Get(Eval('context', {}), 'company'), None]),
]))
Configuration()
+2
View File
@@ -15,6 +15,8 @@ this repository contains the full copyright notices and license terms. -->
<newline/>
<label name="stock_journal"/>
<field name="stock_journal"/>
<label name="cost_price_counterpart_account"/>
<field name="cost_price_counterpart_account"/>
<newline/>
</xpath>
</data>
+15
View File
@@ -0,0 +1,15 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of this
# repository contains the full copyright notices and license terms.
from trytond.model import ModelSingleton, ModelView, fields
from trytond.pyson import Eval, Get
class Configuration(ModelSingleton, ModelView):
_name = 'stock.configuration'
cost_price_counterpart_account = fields.Property(fields.Many2One(
'account.account', 'Cost Price Counterpart Account', domain=[
('company', 'in', [Get(Eval('context', {}), 'company'), False]),
]))
Configuration()
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<tryton>
<data>
<record model="ir.ui.view" id="stock_configuration_form">
<field name="model">stock.configuration</field>
<field name="inherit" ref="stock.stock_configuration_view_form"/>
<field name="arch" type="xml">
<![CDATA[
<data>
<xpath expr="//field[@name='shipment_internal_sequence']"
position="after">
<label name="cost_price_counterpart_account"/>
<field name="cost_price_counterpart_account"/>
</xpath>
</data>
]]>
</field>
</record>
<record model="ir.action.act_window.view" id="stock.act_stock_configuration_view1">
<field name="view" ref="stock_configuration_form"/>
</record>
</data>
</tryton>
+182 -1
View File
@@ -1,7 +1,12 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import copy
from decimal import Decimal
from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Eval
from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.pyson import Eval, Get
from trytond.transaction import Transaction
from trytond.pool import Pool
class Category(ModelSQL, ModelView):
@@ -135,4 +140,180 @@ class Template(ModelSQL, ModelView):
account_stock_lost_found_used = fields.Function(fields.Many2One(
'account.account', 'Account Stock Lost and Found'), 'get_account')
def __init__(self):
super(Template, self).__init__()
self.cost_price = copy.copy(self.cost_price)
self.cost_price.states = copy.copy(self.cost_price.states)
self.cost_price.states['readonly'] = (
self.cost_price.states.get('readonly', False)
| ((Eval('type', 'goods') == 'goods') & (Eval('id', -1) >= 0)))
self.cost_price.depends = copy.copy(self.cost_price.depends)
if 'type' not in self.cost_price.depends:
self.cost_price.depends.append('type')
self._reset_columns()
Template()
class UpdateCostPriceAsk(ModelView):
'Update Cost Price Ask'
_name = 'product.update_cost_price.ask'
product = fields.Many2One('product.product', 'Product', readonly=True)
cost_price = fields.Numeric('Cost Price', required=True, digits=(16, 4))
UpdateCostPriceAsk()
class UpdateCostPriceShowMove(ModelView):
'Update Cost Price Show Move'
_name = 'product.update_cost_price.show_move'
price_difference = fields.Numeric('Price Difference', readonly=True,
digits=(16, 4))
amount = fields.Numeric('Amount', readonly=True,
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits'])
currency_digits = fields.Integer('Currency Digits', readonly=True)
journal = fields.Many2One('account.journal', 'Journal', required=True)
stock_account = fields.Many2One('account.account', 'Stock Account',
readonly=True)
counterpart = fields.Many2One('account.account', 'Counterpart',
domain=[
('company', 'in', [Get(Eval('context', {}), 'company'), False]),
('id', '!=', Eval('stock_account')),
],
depends=['company'], required=True)
description = fields.Char('Description', required=True)
UpdateCostPriceShowMove()
class UpdateCostPrice(Wizard):
'Update Cost Price'
_name = 'product.update_cost_price'
start_state = 'ask_price'
ask_price = StateView('product.update_cost_price.ask',
'account_stock_continental.update_cost_price_ask_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Ok', 'should_show_move', 'tryton-go-next', default=True),
])
should_show_move = StateTransition()
show_move = StateView('product.update_cost_price.show_move',
'account_stock_continental.update_cost_price_show_move_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Ok', 'create_move', 'tryton-ok', default=True),
])
create_move = StateTransition()
update_price = StateTransition()
def __init__(self):
super(UpdateCostPrice, self).__init__()
self._error_messages.update({
'same_account': 'The stock account and the counterpart can '
'not be the same account',
})
def default_ask_price(self, session, fields):
if 'product' in fields:
return {
'product': Transaction().context['active_id'],
}
def get_quantity(self):
pool = Pool()
date_obj = pool.get('ir.date')
product_obj = pool.get('product.product')
stock_obj = pool.get('stock.location')
locations = stock_obj.search([('type', '=', 'storage')])
stock_date_end = date_obj.today()
with Transaction().set_context(locations=locations,
stock_date_end=stock_date_end):
product = product_obj.browse(Transaction().context['active_id'])
if hasattr(product_obj, 'cost_price'):
return product.quantity
else:
return product.template.quantity
def transition_should_show_move(self, session):
if self.get_quantity() != 0:
return 'show_move'
return 'update_price'
def default_show_move(self, session, fields):
pool = Pool()
currency_obj = pool.get('currency.currency')
user_obj = pool.get('res.user')
accountconf_obj = pool.get('account.configuration')
product_obj = pool.get('product.product')
product = product_obj.browse(Transaction().context['active_id'])
price_diff = (session.ask_price.cost_price
- product.cost_price)
user = user_obj.browse(Transaction().user)
amount = currency_obj.round(user.company.currency,
Decimal(str(self.get_quantity())) * price_diff)
stock_account = product.account_stock_used.id
config = accountconf_obj.browse(1)
stock_journal = config.stock_journal.id
counterpart = (config.cost_price_counterpart_account.id if
config.cost_price_counterpart_account else None)
return {
'journal': stock_journal,
'amount': amount,
'price_difference': price_diff,
'stock_account': stock_account,
'counterpart': counterpart,
'currency_digits': user.company.currency.digits,
}
def get_move_lines(self, session):
amount = session.show_move.amount
return [{
'name': session.ask_price.product.name,
'debit': amount if amount > 0 else 0,
'credit': -amount if amount < 0 else 0,
'account': session.show_move.stock_account.id,
},
{
'name': session.ask_price.product.name,
'debit': -amount if amount < 0 else 0,
'credit': amount if amount > 0 else 0,
'account': session.show_move.counterpart.id,
},
]
def get_move(self, session):
pool = Pool()
date_obj = pool.get('ir.date')
period_obj = pool.get('account.period')
user_obj = pool.get('res.user')
user = user_obj.browse(Transaction().user)
period_id = period_obj.find(user.company.id)
return {
'name': session.show_move.description,
'period': period_id,
'journal': session.show_move.journal.id,
'date': date_obj.today(),
'lines': [('create', l)
for l in self.get_move_lines(session)],
}
def transition_create_move(self, session):
move_obj = Pool().get('account.move')
if session.show_move.counterpart == session.show_move.stock_account:
self.raise_user_error('same_account')
move_data = self.get_move(session)
with Transaction().set_user(0, set_context=True):
move_id = move_obj.create(move_data)
move_obj.post([move_id])
return 'update_price'
def transition_update_price(self, session):
product_obj = Pool().get('product.product')
product_obj.write(session.ask_price.product.id, {
'cost_price': session.ask_price.cost_price,
})
return 'end'
UpdateCostPrice()
+49 -1
View File
@@ -3,6 +3,55 @@
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="update_cost_price_ask_form">
<field name="model">product.update_cost_price.ask</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Update Cost Price" cursor="cost_price">
<label name="product"/>
<field name="product"/>
<label name="cost_price"/>
<field name="cost_price"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="update_cost_price_show_move_form">
<field name="model">product.update_cost_price.show_move</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Update Cost Price - Move">
<label name="journal"/>
<field name="journal"/>
<newline/>
<label name="amount"/>
<field name="amount"/>
<label name="price_difference"/>
<field name="price_difference"/>
<label name="stock_account"/>
<field name="stock_account"/>
<label name="counterpart"/>
<field name="counterpart"/>
</form>
]]>
</field>
</record>
<record model="ir.action.wizard" id="wizard_update_cost_price">
<field name="name">Update Cost Price</field>
<field name="wiz_name">product.update_cost_price</field>
</record>
<record model="ir.action.keyword" id="update_cost_price_keyword">
<field name="keyword">form_action</field>
<field name="model">product.product,-1</field>
<field name="action" ref="wizard_update_cost_price"/>
</record>
<record model="ir.action-res.group"
id="wizard_update_cost_price-group_account">
<field name="action" ref="wizard_update_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>
@@ -51,6 +100,5 @@ this repository contains the full copyright notices and license terms. -->
]]>
</field>
</record>
</data>
</tryton>