199 lines
8.5 KiB
Python
Executable File
199 lines
8.5 KiB
Python
Executable File
# 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 operator
|
|
from decimal import Decimal
|
|
|
|
from trytond.i18n import gettext
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.transaction import Transaction
|
|
from trytond.exceptions import UserWarning, UserError
|
|
from .exceptions import COGSWarning
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class InvoiceLine(metaclass=PoolMeta):
|
|
__name__ = 'account.invoice.line'
|
|
|
|
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')
|
|
Currency = pool.get('currency.currency')
|
|
Date = Pool().get('ir.date')
|
|
AccountConfiguration = Pool().get('account.configuration')
|
|
account_configuration = AccountConfiguration(1)
|
|
|
|
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
|
|
|
|
move_line.lot = self.lot
|
|
amount_converted = amount
|
|
if self.invoice.currency != self.invoice.company.currency and type_ == 'in_supplier':
|
|
if account_configuration.stock_fx_forex == 'forex':
|
|
frate,amt = move_line.lot.get_forex_rate(amount)
|
|
logger.info("GET_PARTY_LINE:%s",frate)
|
|
if frate > 0:
|
|
amount = round(frate * amount,2)
|
|
logger.info("GET_PARTY_LINE2:%s",amount)
|
|
with Transaction().set_context(date=Date.today()):
|
|
amount += Currency.compute(self.invoice.currency,
|
|
amt, self.invoice.company.currency)
|
|
logger.info("GET_PARTY_LINE3:%s",amount)
|
|
amount_converted = round(amount,2)
|
|
else:
|
|
if self.invoice.rate:
|
|
amount_converted = round(amount / self.invoice.rate,2)
|
|
else:
|
|
with Transaction().set_context(date=self.invoice.currency_date):
|
|
amount_converted = Currency.compute(self.invoice.currency,
|
|
amount, self.invoice.company.currency)
|
|
else:
|
|
if self.invoice.rate:
|
|
amount_converted = round(amount / self.invoice.rate,2)
|
|
else:
|
|
with Transaction().set_context(date=self.invoice.currency_date):
|
|
amount_converted = Currency.compute(self.invoice.currency,
|
|
amount, self.invoice.company.currency)
|
|
move_line.second_currency = self.invoice.currency
|
|
|
|
if amount_converted < 0:
|
|
if type_.startswith('in_'):
|
|
move_line.debit = Decimal(0)
|
|
move_line.credit = -amount_converted
|
|
move_line.account = self.product.account_stock_in_used
|
|
if move_line.second_currency:
|
|
move_line.amount_second_currency = amount
|
|
else:
|
|
move_line.debit = -amount_converted
|
|
move_line.credit = Decimal(0)
|
|
move_line.account = self.product.account_stock_out_used
|
|
if move_line.second_currency:
|
|
move_line.amount_second_currency = amount
|
|
else:
|
|
if type_.startswith('in_'):
|
|
move_line.debit = amount_converted
|
|
move_line.credit = Decimal(0)
|
|
move_line.account = self.product.account_stock_in_used
|
|
if move_line.second_currency:
|
|
move_line.amount_second_currency = amount
|
|
else:
|
|
move_line.debit = Decimal(0)
|
|
move_line.credit = amount_converted
|
|
move_line.account = self.product.account_stock_out_used
|
|
if move_line.second_currency:
|
|
move_line.amount_second_currency = -amount
|
|
|
|
logger.info("_GET_ANGLO_MOVE_LINE_ACCOUNT1:%s",move_line.account)
|
|
result.append(move_line)
|
|
debit, credit = move_line.debit, move_line.credit
|
|
move_line = MoveLine()
|
|
move_line.lot = self.lot
|
|
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
|
|
logger.info("_GET_ANGLO_MOVE_LINE_ACCOUNT2:%s",move_line.account)
|
|
if move_line.account.party_required:
|
|
move_line.party = self.invoice.party
|
|
result.append(move_line)
|
|
return result
|
|
|
|
def get_move_lines(self):
|
|
pool = Pool()
|
|
Move = pool.get('stock.move')
|
|
Period = pool.get('account.period')
|
|
Warning = pool.get('res.user.warning')
|
|
|
|
logger.info("ENTERING_ANGLO_SAXON_GET_MOVE_LINES:%s",self)
|
|
|
|
result = super(InvoiceLine, self).get_move_lines()
|
|
|
|
if self.type != 'line':
|
|
return result
|
|
if not self.product:
|
|
return result
|
|
if self.product.type != 'goods' and not self.product.landed_cost:
|
|
return result
|
|
|
|
accounting_date = (self.invoice.accounting_date
|
|
or self.invoice.invoice_date)
|
|
period = Period.find(self.invoice.company, date=accounting_date)
|
|
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
|
|
if Warning.check(warning_name):
|
|
raise COGSWarning(warning_name,
|
|
gettext('account_stock_anglo_saxon'
|
|
'.msg_invoice_line_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.company.currency.round(cost)
|
|
if type_ == 'in_supplier':
|
|
cost = self.amount
|
|
else:
|
|
cost = self.lot.get_cog()
|
|
if not cost or cost == 0:
|
|
raise UserError('No COG for this invoice, please generate the reception of the goods')
|
|
if self.amount < 0 :
|
|
cost *= -1
|
|
logger.info("GETMOVELINES_COST:%s",cost)
|
|
anglo_saxon_move_lines_ = []
|
|
with Transaction().set_context(
|
|
company=self.invoice.company.id, date=accounting_date):
|
|
anglo_saxon_move_lines = self._get_anglo_saxon_move_lines(
|
|
cost, type_)
|
|
if type_ == 'in_supplier' and (self.lot.sale_invoice_line_prov or self.lot.sale_invoice_line) and not self.fee:
|
|
anglo_saxon_move_lines_ = self._get_anglo_saxon_move_lines(cost, 'out_customer')
|
|
result.extend(anglo_saxon_move_lines)
|
|
result.extend(anglo_saxon_move_lines_)
|
|
#Fee inventoried delivery management
|
|
if self.lot and type_ != 'in_supplier':
|
|
FeeLots = Pool().get('fee.lots')
|
|
fees = FeeLots.search(['lot','=',self.lot.id])
|
|
for fl in fees:
|
|
if fl.fee.type == 'ordered' and fl.fee.product.template.landed_cost:
|
|
AccountMove = Pool().get('account.move')
|
|
account_move = fl.fee._get_account_move_fee(fl.lot,'out')
|
|
AccountMove.save([account_move])
|
|
|
|
return result
|