Updating cost price must update stock accounting
review244003
This commit is contained in:
@@ -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
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user