first commit
This commit is contained in:
127
modules/account_invoice_stock/stock.py
Normal file
127
modules/account_invoice_stock/stock.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# 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, Workflow, fields
|
||||
from trytond.modules.product import round_price
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Move(metaclass=PoolMeta):
|
||||
__name__ = 'stock.move'
|
||||
invoice_lines = fields.Many2Many(
|
||||
'account.invoice.line-stock.move', 'stock_move', 'invoice_line',
|
||||
"Invoice Lines",
|
||||
domain=[
|
||||
('product.default_uom_category',
|
||||
'=', Eval('product_uom_category', -1)),
|
||||
('type', '=', 'line'),
|
||||
['OR',
|
||||
('invoice.type', 'in', Eval('invoice_types', [])),
|
||||
('invoice_type', 'in', Eval('invoice_types', [])),
|
||||
],
|
||||
],
|
||||
states={
|
||||
'invisible': ~Eval('invoice_types', []),
|
||||
})
|
||||
invoice_types = fields.Function(
|
||||
fields.MultiSelection('get_invoice_types', "Invoice Types"),
|
||||
'on_change_with_invoice_types')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls._allow_modify_closed_period.add('invoice_lines')
|
||||
|
||||
@classmethod
|
||||
def get_invoice_types(cls):
|
||||
pool = Pool()
|
||||
Invoice = pool.get('account.invoice')
|
||||
return Invoice.fields_get(['type'])['type']['selection']
|
||||
|
||||
@fields.depends('from_location', 'to_location')
|
||||
def on_change_with_invoice_types(self, name=None):
|
||||
types = set()
|
||||
for location in [self.from_location, self.to_location]:
|
||||
if location:
|
||||
if location.type == 'customer':
|
||||
types.add('out')
|
||||
elif location.type == 'supplier':
|
||||
types.add('in')
|
||||
return list(types)
|
||||
|
||||
@property
|
||||
def invoiced_quantity(self):
|
||||
'The quantity from linked invoice lines in move unit'
|
||||
pool = Pool()
|
||||
Uom = pool.get('product.uom')
|
||||
quantity = 0
|
||||
for invoice_line in self.invoice_lines:
|
||||
if invoice_line.invoice_state != 'cancelled':
|
||||
quantity += Uom.compute_qty(
|
||||
invoice_line.unit, invoice_line.quantity, self.unit)
|
||||
return quantity
|
||||
|
||||
@classmethod
|
||||
def copy(cls, moves, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
if not Transaction().context.get('_stock_move_split'):
|
||||
default.setdefault('invoice_lines', None)
|
||||
return super().copy(moves, default=default)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
def do(cls, moves):
|
||||
super().do(moves)
|
||||
cls.update_unit_price(moves)
|
||||
|
||||
@classmethod
|
||||
def write(cls, *args):
|
||||
super().write(*args)
|
||||
moves = sum(args[0:None:2], [])
|
||||
cls.update_unit_price(moves)
|
||||
|
||||
@classmethod
|
||||
def update_unit_price(cls, moves):
|
||||
for move in moves:
|
||||
if move.state == 'done' and move.unit_price_required:
|
||||
unit_price = move._compute_unit_price(
|
||||
unit_price=move.unit_price)
|
||||
if unit_price != move.unit_price:
|
||||
move.unit_price = unit_price
|
||||
cls.save(moves)
|
||||
|
||||
def _compute_unit_price(self, unit_price):
|
||||
pool = Pool()
|
||||
UoM = pool.get('product.uom')
|
||||
Currency = pool.get('currency.currency')
|
||||
amount, quantity = 0, 0
|
||||
for line in self.invoice_lines:
|
||||
if line.invoice and line.invoice.state in {'posted', 'paid'}:
|
||||
with Transaction().set_context(date=self.effective_date):
|
||||
amount += Currency.compute(
|
||||
line.invoice.currency, line.amount, self.currency)
|
||||
if line.invoice.type == 'out' or not line.correction:
|
||||
quantity += UoM.compute_qty(
|
||||
line.unit, line.quantity, self.unit)
|
||||
if quantity:
|
||||
unit_price = amount / Decimal(str(quantity))
|
||||
if unit_price is not None:
|
||||
unit_price = round_price(unit_price)
|
||||
return unit_price
|
||||
|
||||
|
||||
class ShipmentOut(metaclass=PoolMeta):
|
||||
__name__ = 'stock.shipment.out'
|
||||
|
||||
def _sync_outgoing_move(self, template=None):
|
||||
move = super()._sync_outgoing_move(template=template)
|
||||
if template and template.invoice_lines:
|
||||
move.invoice_lines = list(template.invoice_lines)
|
||||
return move
|
||||
Reference in New Issue
Block a user