Files
tryton/invoice.py
T
Cédric Krier 09ed117eb0 Add warning about different product between invoice line and stock move
This allow to overcome the assert in update_anglo_saxon_quantity_product_cost.

issue6803
review38801002
2017-10-02 20:16:20 +02:00

121 lines
4.2 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
import operator
from trytond.pool import Pool, PoolMeta
__all__ = ['InvoiceLine']
class InvoiceLine:
__metaclass__ = PoolMeta
__name__ = 'account.invoice.line'
@classmethod
def __setup__(cls):
super(InvoiceLine, cls).__setup__()
cls._error_messages.update({
'stock_move_different_product': (
"The invoice line '%(line)s' is linked to stock moves "
"for other products than '%(product)s'.\n"
"This may compute a wrong COGS."),
})
def _get_anglo_saxon_move_lines(self, amount, type_):
'''
Return account move for anglo-saxon stock accounting
'''
pool = Pool()
MoveLine = pool.get('account.move.line')
assert type_.startswith('in_') or type_.startswith('out_'), \
'wrong type'
result = []
move_line = MoveLine()
move_line.description = self.description
move_line.amount_second_currency = None
move_line.second_currency = None
if type_.startswith('in_'):
move_line.debit = amount
move_line.credit = Decimal('0.0')
account_type = type_[3:]
else:
move_line.debit = Decimal('0.0')
move_line.credit = amount
account_type = type_[4:]
move_line.account = getattr(self.product,
'account_stock_%s_used' % account_type)
result.append(move_line)
debit, credit = move_line.debit, move_line.credit
move_line = MoveLine()
move_line.description = self.description
move_line.amount_second_currency = move_line.second_currency = None
move_line.debit, move_line.credit = credit, debit
if type_.endswith('supplier'):
move_line.account = self.account
else:
move_line.account = self.product.account_cogs_used
result.append(move_line)
return result
def get_move_lines(self):
pool = Pool()
Move = pool.get('stock.move')
Period = pool.get('account.period')
result = super(InvoiceLine, self).get_move_lines()
if self.type != 'line':
return result
if not self.product:
return result
if self.product.type != 'goods':
return result
accounting_date = (self.invoice.accounting_date
or self.invoice.invoice_date)
period_id = Period.find(self.invoice.company.id, date=accounting_date)
period = Period(period_id)
if period.fiscalyear.account_stock_method != 'anglo_saxon':
return result
# an empty list means we'll use the current cost price
moves = []
for move in self.stock_moves:
if move.state != 'done':
continue
# remove move for different product
if move.product != self.product:
warning_name = '%s.stock.different_product' % self
self.raise_user_warning(
warning_name, 'stock_move_different_product', {
'line': self.rec_name,
'product': self.product.rec_name,
})
else:
moves.append(move)
if self.invoice.type == 'in':
type_ = 'in_supplier'
elif self.invoice.type == 'out':
type_ = 'out_customer'
if self.quantity < 0:
direction, target = type_.split('_')
if direction == 'in':
direction = 'out'
else:
direction = 'in'
type_ = '%s_%s' % (direction, target)
moves.sort(key=operator.attrgetter('effective_date'))
cost = Move.update_anglo_saxon_quantity_product_cost(
self.product, moves, abs(self.quantity), self.unit, type_)
cost = self.invoice.currency.round(cost)
anglo_saxon_move_lines = self._get_anglo_saxon_move_lines(cost, type_)
result.extend(anglo_saxon_move_lines)
return result