151 lines
5.1 KiB
Python
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()
|