Active Record

This commit is contained in:
Cédric Krier committed 2012-09-24 22:17:38 +02:00
1 parent d17de3a45b
commit 0e3f5ffd20
5 files changed
+206 -197

No files matched your search

+15
View File
@@ -1,6 +1,21 @@
#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.pool import Pool
from .stock import *
from .product import *
from .account import *
def register():
Pool.register(
Move,
Category,
Template,
Configuration,
UpdateCostPriceAsk,
UpdateCostPriceShowMove,
module='account_stock_continental', type_='model')
Pool.register(
UpdateCostPrice,
module='account_stock_continental', type_='wizard')
+7 -6
View File
@@ -1,12 +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 Model, fields
from trytond.model import fields
from trytond.pyson import Eval, Bool, Get
from trytond.pool import PoolMeta
__all__ = ['Configuration']
__metaclass__ = PoolMeta
class Configuration(Model):
_name = 'account.configuration'
class Configuration:
__name__ = 'account.configuration'
stock_journal = fields.Property(fields.Many2One(
'account.journal', 'Stock Journal',
states={
@@ -16,5 +19,3 @@ class Configuration(Model):
'account.account', 'Cost Price Counterpart Account', domain=[
('company', 'in', [Get(Eval('context', {}), 'company'), None]),
]))
Configuration()
+94 -103
View File
@@ -1,17 +1,19 @@
#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.model import ModelView, fields
from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.pyson import Eval, Get
from trytond.transaction import Transaction
from trytond.pool import Pool
from trytond.pool import Pool, PoolMeta
__all__ = ['Category', 'Template', 'UpdateCostPriceAsk',
'UpdateCostPriceShowMove', 'UpdateCostPrice']
__metaclass__ = PoolMeta
class Category(ModelSQL, ModelView):
_name = 'product.category'
class Category:
__name__ = 'product.category'
account_stock = fields.Property(fields.Many2One('account.account',
'Account Stock', domain=[
('kind', '=', 'stock'),
@@ -61,12 +63,9 @@ class Category(ModelSQL, ModelView):
account_stock_lost_found_used = fields.Function(fields.Many2One(
'account.account', 'Account Stock Lost and Found'), 'get_account')
Category()
class Template(ModelSQL, ModelView):
_name = 'product.template'
class Template:
__name__ = 'product.template'
account_stock = fields.Property(fields.Many2One('account.account',
'Account Stock',
domain=[
@@ -140,33 +139,26 @@ 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)
@classmethod
def __setup__(cls):
super(Template, cls).__setup__()
cls.cost_price.states['readonly'] = (
cls.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()
if 'type' not in cls.cost_price.depends:
cls.cost_price.depends.append('type')
class UpdateCostPriceAsk(ModelView):
'Update Cost Price Ask'
_name = 'product.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'
__name__ = 'product.update_cost_price.show_move'
price_difference = fields.Numeric('Price Difference', readonly=True,
digits=(16, 4))
amount = fields.Numeric('Amount', readonly=True,
@@ -183,12 +175,10 @@ class UpdateCostPriceShowMove(ModelView):
depends=['company', 'stock_account'], required=True)
description = fields.Char('Description', required=True)
UpdateCostPriceShowMove()
class UpdateCostPrice(Wizard):
'Update Cost Price'
_name = 'product.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', [
@@ -204,116 +194,117 @@ class UpdateCostPrice(Wizard):
create_move = StateTransition()
update_price = StateTransition()
def __init__(self):
super(UpdateCostPrice, self).__init__()
self._error_messages.update({
@classmethod
def __setup__(cls):
super(UpdateCostPrice, cls).__setup__()
cls._error_messages.update({
'same_account': 'The stock account and the counterpart can '
'not be the same account',
})
def default_ask_price(self, session, fields):
def default_ask_price(self, fields):
if 'product' in fields:
return {
'product': Transaction().context['active_id'],
}
def get_quantity(self):
@staticmethod
def get_quantity():
pool = Pool()
date_obj = pool.get('ir.date')
product_obj = pool.get('product.product')
stock_obj = pool.get('stock.location')
Date = pool.get('ir.date')
Product = pool.get('product.product')
Stock = pool.get('stock.location')
locations = stock_obj.search([('type', '=', 'storage')])
stock_date_end = date_obj.today()
with Transaction().set_context(locations=locations,
locations = Stock.search([('type', '=', 'storage')])
stock_date_end = Date.today()
with Transaction().set_context(locations=[l.id for l in locations],
stock_date_end=stock_date_end):
product = product_obj.browse(Transaction().context['active_id'])
if hasattr(product_obj, 'cost_price'):
product = Product(Transaction().context['active_id'])
if hasattr(Product, 'cost_price'):
return product.quantity
else:
return product.template.quantity
def transition_should_show_move(self, session):
def transition_should_show_move(self):
if self.get_quantity() != 0:
return 'show_move'
return 'update_price'
def default_show_move(self, session, fields):
def default_show_move(self, 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')
User = pool.get('res.user')
AccountConfiguration = pool.get('account.configuration')
Product = pool.get('product.product')
product = product_obj.browse(Transaction().context['active_id'])
price_diff = (session.ask_price.cost_price
product = Product(Transaction().context['active_id'])
price_diff = (self.ask_price.cost_price
- product.cost_price)
user = user_obj.browse(Transaction().user)
amount = currency_obj.round(user.company.currency,
user = User(Transaction().user)
amount = user.company.currency.round(
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
stock_account_id = product.account_stock_used.id
config = AccountConfiguration(1)
stock_journal_id = config.stock_journal.id
counterpart_id = (config.cost_price_counterpart_account.id if
config.cost_price_counterpart_account else None)
return {
'journal': stock_journal,
'journal': stock_journal_id,
'amount': amount,
'price_difference': price_diff,
'stock_account': stock_account,
'counterpart': counterpart,
'stock_account': stock_account_id,
'counterpart': counterpart_id,
'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_lines(self):
Line = Pool.get('account.move.line')
amount = self.show_move.amount
return [Line(
name=self.ask_price.product.name,
debit=amount if amount > 0 else 0,
credit=-amount if amount < 0 else 0,
account=self.show_move.stock_account,
),
Line(
name=self.ask_price.product.name,
debit=-amount if amount < 0 else 0,
credit=amount if amount > 0 else 0,
account=self.show_move.counterpart,
),
]
def get_move(self, session):
def get_move(self):
pool = Pool()
date_obj = pool.get('ir.date')
period_obj = pool.get('account.period')
user_obj = pool.get('res.user')
Date = pool.get('ir.date')
Period = pool.get('account.period')
User = pool.get('res.user')
Move = pool.get('account.move')
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)
user = User(Transaction().user)
period_id = Period.find(user.company.id)
with Transaction().set_user(0, set_context=True):
move_id = move_obj.create(move_data)
move_obj.post([move_id])
return Move(
name=self.show_move.description,
period=period_id,
journal=self.show_move.journal,
date=Date.today(),
lines=self.get_move_lines(),
)
def transition_create_move(self):
Move = Pool().get('account.move')
if self.show_move.counterpart == self.show_move.stock_account:
self.raise_user_error('same_account')
move = self.get_move()
move.save()
with Transaction().set_user(0, set_context=True):
Move.post([move])
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,
def transition_update_price(self):
Product = Pool().get('product.product')
Product.write([self.ask_price.product], {
'cost_price': self.ask_price.cost_price,
})
return 'end'
UpdateCostPrice()
+88 -86
View File
@@ -1,94 +1,102 @@
#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 decimal import Decimal
from trytond.model import Model, fields
from trytond.pool import Pool
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
__all__ = ['Move']
__metaclass__ = PoolMeta
class Move(Model):
_name = 'stock.move'
class Move:
__name__ = 'stock.move'
account_move = fields.Many2One('account.move', 'Account Move',
readonly=True)
def _get_account_stock_move_lines(self, move, type_):
def _get_account_stock_move_lines(self, type_):
'''
Return move line values for stock move
Return move lines for stock move
'''
uom_obj = Pool().get('product.uom')
currency_obj = Pool().get('currency.currency')
pool = Pool()
Uom = pool.get('product.uom')
AccountMoveLine = pool.get('account.move.line')
assert type_.startswith('in_') or type_.startswith('out_'), \
'wrong type'
move_line = {
'name': move.rec_name,
}
with Transaction().set_user(0, set_context=True):
move_line = AccountMoveLine(name=self.rec_name)
if (type_.endswith('supplier')
and move.product.cost_price_method != 'fixed'):
unit_price = move.unit_price
and self.product.cost_price_method != 'fixed'):
unit_price = self.unit_price
else:
unit_price = uom_obj.compute_price(move.product.default_uom,
move.cost_price, move.uom)
amount = currency_obj.round(move.company.currency,
Decimal(str(move.quantity)) * unit_price)
unit_price = Uom.compute_price(self.product.default_uom,
self.cost_price, self.uom)
amount = self.company.currency.round(
Decimal(str(self.quantity)) * unit_price)
if type_.startswith('in_'):
move_line['debit'] = Decimal('0.0')
move_line['credit'] = amount
move_line.debit = Decimal('0.0')
move_line.credit = amount
account_type = type_[3:]
else:
move_line['debit'] = amount
move_line['credit'] = Decimal('0.0')
move_line.debit = amount
move_line.credit = Decimal('0.0')
account_type = type_[4:]
move_line['account'] = getattr(move.product,
'account_stock_%s_used' % account_type).id
move_line.account = getattr(self.product,
'account_stock_%s_used' % account_type)
return [move_line]
def _get_account_stock_move_line(self, move, amount):
def _get_account_stock_move_line(self, amount):
'''
Return counterpart move line value for stock move
'''
move_line = {
'name': move.rec_name,
'account': move.product.account_stock_used.id,
}
pool = Pool()
AccountMoveLine = pool.get('account.move.line')
with Transaction().set_user(0, set_context=True):
move_line = AccountMoveLine(
name=self.rec_name,
account=self.product.account_stock_used,
)
if not amount:
return
if amount >= Decimal('0.0'):
move_line['debit'] = Decimal('0.0')
move_line['credit'] = amount
move_line.debit = Decimal('0.0')
move_line.credit = amount
else:
move_line['debit'] = - amount
move_line['credit'] = Decimal('0.0')
move_line.debit = - amount
move_line.credit = Decimal('0.0')
return move_line
def _get_account_stock_move(self, move, move_lines):
def _get_account_stock_move(self, move_lines):
'''
Return account move value for stock move
'''
date_obj = Pool().get('ir.date')
period_obj = Pool().get('account.period')
account_configuration_obj = Pool().get('account.configuration')
pool = Pool()
Date = pool.get('ir.date')
Period = pool.get('account.period')
AccountConfiguration = pool.get('account.configuration')
AccountMove = pool.get('account.move')
date = move.effective_date or date_obj.today()
period_id = period_obj.find(move.company.id, date=date)
account_configuration = account_configuration_obj.browse(1)
journal_id = account_configuration.stock_journal.id
return {
'journal': journal_id,
'period': period_id,
'date': date,
'lines': [('create', line) for line in move_lines],
}
date = self.effective_date or Date.today()
period_id = Period.find(self.company.id, date=date)
account_configuration = AccountConfiguration(1)
with Transaction().set_user(0, set_context=True):
return AccountMove(
journal=account_configuration.stock_journal,
period=period_id,
date=date,
lines=move_lines,
)
def _get_account_stock_move_type(self, move):
def _get_account_stock_move_type(self):
'''
Get account move type
'''
type_ = (move.from_location.type, move.to_location.type)
type_ = (self.from_location.type, self.to_location.type)
if type_ == ('supplier', 'storage'):
return 'in_supplier'
elif type_ == ('storage', 'supplier'):
@@ -106,70 +114,64 @@ class Move(Model):
elif type_ == ('customer', 'supplier'):
return 'customer_supplier'
def _create_account_stock_move(self, move):
def _create_account_stock_move(self):
'''
Create account move for stock move
'''
account_move_obj = Pool().get('account.move')
if move.product.type != 'goods':
AccountMove = Pool().get('account.move')
if self.product.type != 'goods':
return
type_ = self._get_account_stock_move_type(move)
type_ = self._get_account_stock_move_type()
if not type_:
return
assert not move.account_move, 'account move field not empty'
assert not self.account_move, 'account move field not empty'
if type_ == 'supplier_customer':
account_move_lines = self._get_account_stock_move_lines(move,
account_move_lines = self._get_account_stock_move_lines(
'in_supplier')
account_move_lines.extend(self._get_account_stock_move_lines(move,
account_move_lines.extend(self._get_account_stock_move_lines(
'out_customer'))
elif type_ == 'customer_supplier':
account_move_lines = self._get_account_stock_move_lines(move,
account_move_lines = self._get_account_stock_move_lines(
'in_customer')
account_move_lines.extend(self._get_account_stock_move_lines(move,
account_move_lines.extend(self._get_account_stock_move_lines(
'out_supplier'))
else:
account_move_lines = self._get_account_stock_move_lines(move,
type_)
account_move_lines = self._get_account_stock_move_lines(type_)
amount = Decimal('0.0')
for line in account_move_lines:
amount += line['debit'] - line['credit']
move_line = self._get_account_stock_move_line(move, amount)
amount += line.debit - line.credit
move_line = self._get_account_stock_move_line(amount)
if move_line:
account_move_lines.append(move_line)
account_move = self._get_account_stock_move(account_move_lines)
account_move.save()
with Transaction().set_user(0, set_context=True):
account_move_id = account_move_obj.create(
self._get_account_stock_move(move, account_move_lines))
account_move_obj.post(account_move_id)
self.write(move.id, {
'account_move': account_move_id,
})
return account_move_id
AccountMove.post([account_move])
self.write([self], {
'account_move': account_move.id,
})
return account_move
def copy(self, ids, default=None):
@classmethod
def copy(cls, moves, default=None):
if default is None:
default = {}
default = default.copy()
default.setdefault('account_move', None)
return super(Move, self).copy(ids, default=default)
return super(Move, cls).copy(moves, default=default)
def create(self, vals):
new_id = super(Move, self).create(vals)
@classmethod
def create(cls, vals):
move = super(Move, cls).create(vals)
if vals.get('state') == 'done':
move = self.browse(new_id)
self._create_account_stock_move(move)
return new_id
move._create_account_stock_move()
return move
def write(self, ids, vals):
res = super(Move, self).write(ids, vals)
@classmethod
def write(cls, moves, vals):
super(Move, cls).write(moves, vals)
if vals.get('state') == 'done':
if isinstance(ids, (int, long)):
move = self.browse(ids)
self._create_account_stock_move(move)
else:
for move in self.browse(ids):
self._create_account_stock_move(move)
return res
Move()
for move in moves:
move._create_account_stock_move()
+2 -2
View File
@@ -154,7 +154,7 @@ Create product::
>>> product.account_stock_customer = stock_customer
>>> product.account_stock_lost_found = stock_lost_found
>>> product.save()
>>> product_average = Product(Product.copy(product.id, config.context))
>>> product_average = Product(Product.copy([product.id], config.context)[0])
>>> product_average.cost_price_method = 'average'
>>> product_average.save()
@@ -312,7 +312,7 @@ Create an Inventory::
>>> inventory = Inventory()
>>> inventory.location = storage
>>> inventory.save()
>>> Inventory.complete_lines(inventory.id, config.context)
>>> Inventory.complete_lines([inventory.id], config.context)
>>> inventory_line = inventory.lines[0]
>>> inventory_line.quantity = 1.0
>>> inventory_line = inventory.lines[1]