Files
tryton/stock.py
T

151 lines
5.1 KiB
Python

#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 ModelView, ModelSQL, fields
from trytond.pool import Pool
class Move(ModelSQL, ModelView):
_name = 'stock.move'
account_move = fields.Many2One('account.move', 'Account Move',
readonly=True)
def _get_account_stock_move_lines(self, move, type_):
'''
Return move line values for stock move
'''
uom_obj = Pool().get('product.uom')
currency_obj = Pool().get('currency.currency')
assert type_.startswith('in_') or type_.startswith('out_'), 'wrong type'
move_line = {
'name': move.rec_name,
}
if type_.endswith('supplier'):
unit_price = move.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)
if type_.startswith('in_'):
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')
account_type = type_[4:]
move_line['account'] = getattr(move.product,
'account_stock_%s_used' % account_type).id
return [move_line]
def _get_account_stock_move_line(self, move, amount):
'''
Return counterpart move line value for stock move
'''
move_line = {
'name': move.rec_name,
'account': move.product.account_stock_used.id,
}
if amount >= Decimal('0.0'):
move_line['debit'] = Decimal('0.0')
move_line['credit'] = amount
else:
move_line['debit'] = - amount
move_line['credit'] = Decimal('0.0')
return move_line
def _get_account_stock_move(self, move, move_lines, type_):
'''
Return account move value for stock move
'''
date_obj = Pool().get('ir.date')
period_obj = Pool().get('account.period')
assert type_.startswith('in_') or type_.startswith('out_'), 'wrong type'
date = move.effective_date or date_obj.today()
period_id = period_obj.find(move.company.id, date=date)
if type_.startswith('in_'):
journal_type = type_[3:]
else:
journal_type = type_[4:]
journal_id = getattr(move.product,
'account_journal_stock_%s_used' % journal_type).id
return {
'journal': journal_id,
'period': period_id,
'date': date,
'lines': [('create', line) for line in move_lines],
}
def _get_account_stock_move_type(self, move):
'''
Get account move type
'''
type_ = (move.from_location.type, move.to_location.type)
if type_ == ('supplier', 'storage'):
return 'in_supplier'
elif type_ == ('storage', 'supplier'):
return 'out_supplier'
elif type_ == ('storage', 'customer'):
return 'out_customer'
elif type_ == ('customer', 'storage'):
return 'in_customer'
elif type_ == ('storage', 'lost_found'):
return 'out_lost_found'
elif type_ == ('lost_found', 'storage'):
return 'in_lost_found'
def _create_account_stock_move(self, move):
'''
Create account move for stock move
'''
account_move_obj = Pool().get('account.move')
type_ = self._get_account_stock_move_type(move)
if not type_:
return
assert not move.account_move, 'account move field not empty'
account_move_lines = self._get_account_stock_move_lines(move, type_)
amount = Decimal('0.0')
for line in account_move_lines:
amount += line['debit'] - line['credit']
account_move_lines.append(
self._get_account_stock_move_line(move, amount))
account_move_id = account_move_obj.create(
self._get_account_stock_move(move, account_move_lines, type_))
self.write(move.id, {
'account_move': account_move_id,
})
account_move_obj.post(account_move_id)
return account_move_id
def create(self, vals):
new_id = super(Move, self).create(vals)
if vals.get('state') == 'done':
move = self.browse(new_id)
self._create_account_stock_move(move)
return new_id
def write(self, ids, vals):
res = super(Move, self).write(ids, 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()