Lot invoicing + Fee invoicing
This commit is contained in:
@@ -25,7 +25,16 @@ from trytond.modules.purchase_trade.service import ContractFactory
|
||||
from trytond.modules.purchase_trade.company_defaults import (
|
||||
default_itsa_unit, is_itsa_company)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _fee_invoice_action(fee, invoice_action):
|
||||
invoice = fee.get_invoice('inv') if fee else None
|
||||
if invoice_action == 'final' and invoice:
|
||||
return 'dn_cn'
|
||||
if invoice:
|
||||
return 'already_invoiced'
|
||||
return 'standard'
|
||||
|
||||
class LotAccountingGraph(ModelSQL,ModelView):
|
||||
"Lot accounting graph"
|
||||
@@ -4667,7 +4676,7 @@ class LotInvoice(Wizard):
|
||||
def transition_start(self):
|
||||
return 'inv'
|
||||
|
||||
def default_inv(self, fields):
|
||||
def default_inv(self, fields):
|
||||
lot_p = []
|
||||
lot_s = []
|
||||
fee_pur = []
|
||||
@@ -4675,8 +4684,10 @@ class LotInvoice(Wizard):
|
||||
fee_sale = []
|
||||
pp_sale = []
|
||||
act = 'prov'
|
||||
line = None
|
||||
sale_line = None
|
||||
line = None
|
||||
sale_line = None
|
||||
purchase_lines = []
|
||||
sale_lines = []
|
||||
val = {}
|
||||
Lot = Pool().get('lot.lot')
|
||||
LotQt = Pool().get('lot.qt')
|
||||
@@ -4690,7 +4701,9 @@ class LotInvoice(Wizard):
|
||||
lot = lqts[0].lot_p
|
||||
else:
|
||||
lot = Lot(i)
|
||||
line = lot.line
|
||||
line = lot.line
|
||||
if line and line not in purchase_lines:
|
||||
purchase_lines.append(line)
|
||||
if lot.line.purchase:
|
||||
if lot.line.purchase.wb:
|
||||
if lot.line.purchase.wb.qt_type in [e.quantity_type for e in lot.lot_hist]:
|
||||
@@ -4715,7 +4728,9 @@ class LotInvoice(Wizard):
|
||||
unit = val['lot_unit']
|
||||
val['lot_currency'] = lot.lot_price_ct_symbol
|
||||
lot_p.append(val)
|
||||
sale_line = lot.sale_line
|
||||
sale_line = lot.sale_line
|
||||
if sale_line and sale_line not in sale_lines:
|
||||
sale_lines.append(sale_line)
|
||||
val_s = val.copy() # ou utiliser deepcopy si certains champs sont des objets imbriqués
|
||||
val_s['lot_price'] = lot.lot_price_sale
|
||||
val_s['lot_amount'] = lot.get_current_quantity_converted() * lot.lot_price_sale if lot.lot_price_sale else Decimal(0)
|
||||
@@ -4737,22 +4752,28 @@ class LotInvoice(Wizard):
|
||||
val_s['lot_currency'] = lot.lot_price_ct_symbol_sale
|
||||
val_s['lot_unit'] = sale_line.unit.id if sale_line else None
|
||||
lot_s.append(val_s)
|
||||
if line:
|
||||
if line.fees:
|
||||
for f in line.fees:
|
||||
if f.type == 'ordered':
|
||||
val = {}
|
||||
val['fee'] = f.id
|
||||
val['fee_type'] = f.product.id
|
||||
val['fee_quantity'] = f.quantity
|
||||
val['fee_price'] = f.price
|
||||
val['fee_unit'] = line.unit.id
|
||||
val['fee_amount'] = f.amount
|
||||
val['fee_landed_cost'] = f.fee_landed_cost
|
||||
fee_pur.append(val)
|
||||
if line.purchase:
|
||||
Prep = Pool().get('account.invoice')
|
||||
prep = Prep.search([('description','=','Prepayment'),('party','=',line.purchase.party.id),('state','!=','draft')])
|
||||
seen_fees = set()
|
||||
for purchase_line in purchase_lines:
|
||||
if purchase_line.fees:
|
||||
for f in purchase_line.fees:
|
||||
if f.type == 'ordered':
|
||||
fee_key = getattr(f, 'id', None) or id(f)
|
||||
if fee_key in seen_fees:
|
||||
continue
|
||||
seen_fees.add(fee_key)
|
||||
val = {}
|
||||
val['fee'] = f.id
|
||||
val['fee_type'] = f.product.id
|
||||
val['fee_quantity'] = f.quantity
|
||||
val['fee_price'] = f.price
|
||||
val['fee_unit'] = purchase_line.unit.id
|
||||
val['fee_amount'] = f.amount
|
||||
val['fee_landed_cost'] = f.fee_landed_cost
|
||||
fee_pur.append(val)
|
||||
if line:
|
||||
if line.purchase:
|
||||
Prep = Pool().get('account.invoice')
|
||||
prep = Prep.search([('description','=','Prepayment'),('party','=',line.purchase.party.id),('state','!=','draft')])
|
||||
if prep:
|
||||
for p in prep:
|
||||
for li in p.lines:
|
||||
@@ -4760,21 +4781,27 @@ class LotInvoice(Wizard):
|
||||
val['inv'] = li.id
|
||||
val['inv_amount'] = li.amount
|
||||
pp_pur.append(val)
|
||||
if sale_line:
|
||||
if sale_line.fees:
|
||||
for f in sale_line.fees:
|
||||
if f.type == 'ordered':
|
||||
val = {}
|
||||
val['fee'] = f.id
|
||||
val['fee_type'] = f.product.id
|
||||
val['fee_quantity'] = f.quantity
|
||||
val['fee_price'] = f.price
|
||||
val['fee_unit'] = sale_line.unit.id
|
||||
val['fee_amount'] = f.amount
|
||||
val['fee_landed_cost'] = f.fee_landed_cost
|
||||
fee_sale.append(val)
|
||||
if sale_line.sale:
|
||||
Prep = Pool().get('account.invoice')
|
||||
seen_fees = set()
|
||||
for current_sale_line in sale_lines:
|
||||
if current_sale_line.fees:
|
||||
for f in current_sale_line.fees:
|
||||
if f.type == 'ordered':
|
||||
fee_key = getattr(f, 'id', None) or id(f)
|
||||
if fee_key in seen_fees:
|
||||
continue
|
||||
seen_fees.add(fee_key)
|
||||
val = {}
|
||||
val['fee'] = f.id
|
||||
val['fee_type'] = f.product.id
|
||||
val['fee_quantity'] = f.quantity
|
||||
val['fee_price'] = f.price
|
||||
val['fee_unit'] = current_sale_line.unit.id
|
||||
val['fee_amount'] = f.amount
|
||||
val['fee_landed_cost'] = f.fee_landed_cost
|
||||
fee_sale.append(val)
|
||||
if sale_line:
|
||||
if sale_line.sale:
|
||||
Prep = Pool().get('account.invoice')
|
||||
prep = Prep.search([('description','=','Prepayment'),('party','=',sale_line.sale.party.id),('state','!=','draft')])
|
||||
if prep:
|
||||
for p in prep:
|
||||
@@ -4842,10 +4869,33 @@ class LotInvoice(Wizard):
|
||||
break
|
||||
if not invoice_line:
|
||||
raise UserError("No invoice line was generated from the selected lots.")
|
||||
self._invoice_selected_fees()
|
||||
self.message.invoice = invoice_line.invoice
|
||||
|
||||
return 'message'
|
||||
|
||||
def _invoice_selected_fees(self):
|
||||
Fee = Pool().get('fee.fee')
|
||||
fee_lines = (
|
||||
self.inv.fee_pur
|
||||
if self.inv.type == 'purchase' else self.inv.fee_sale)
|
||||
fees = []
|
||||
seen = set()
|
||||
for line in fee_lines or []:
|
||||
fee = getattr(line, 'fee', None)
|
||||
if not getattr(line, 'to_invoice', False) or not fee:
|
||||
continue
|
||||
fee_key = getattr(fee, 'id', None) or id(fee)
|
||||
if fee_key in seen:
|
||||
continue
|
||||
seen.add(fee_key)
|
||||
action = _fee_invoice_action(fee, self.inv.action)
|
||||
if action == 'already_invoiced':
|
||||
continue
|
||||
fees.append(fee)
|
||||
if fees:
|
||||
Fee.invoice(fees)
|
||||
|
||||
@classmethod
|
||||
def _split_sale_padding(cls, padding, lots):
|
||||
padding = Decimal(str(padding or 0))
|
||||
@@ -4983,19 +5033,31 @@ class LotInvoiceStart(ModelView):
|
||||
def default_type(cls):
|
||||
return 'purchase'
|
||||
|
||||
class LotInvoicingFee(ModelView):
|
||||
class LotInvoicingFee(ModelView):
|
||||
"Fees"
|
||||
__name__ = "lot.invoicing.fee"
|
||||
|
||||
lfs = fields.Many2One('lot.invoice.start',"Invoicing")
|
||||
fee = fields.Many2One('fee.fee',"Fee")
|
||||
fee_type = fields.Many2One('product.product',"Fee type")
|
||||
to_invoice = fields.Boolean("To invoice")
|
||||
fee_type = fields.Many2One('product.product',"Fee type")
|
||||
invoice_action = fields.Function(fields.Selection([
|
||||
('standard', 'Standard invoice'),
|
||||
('dn_cn', 'DN/CN'),
|
||||
('already_invoiced', 'Already invoiced'),
|
||||
], "Invoice action"), 'on_change_with_invoice_action')
|
||||
to_invoice = fields.Boolean("To invoice", states={
|
||||
'readonly': Eval('invoice_action') == 'already_invoiced',
|
||||
}, depends=['invoice_action'])
|
||||
fee_unit = fields.Many2One('product.uom',"Unit",readonly=True)
|
||||
fee_quantity = fields.Numeric("Qt",digits=(1,5),readonly=True)
|
||||
fee_price = fields.Numeric("Price",digits=(1,4),readonly=True)
|
||||
fee_amount = fields.Numeric("Amount",digits=(1,2),readonly=True)
|
||||
fee_landed_cost = fields.Boolean("To inventory",readonly=True)
|
||||
fee_landed_cost = fields.Boolean("To inventory",readonly=True)
|
||||
|
||||
@fields.depends('fee', '_parent_lfs.action')
|
||||
def on_change_with_invoice_action(self, name=None):
|
||||
action = self.lfs.action if self.lfs else None
|
||||
return _fee_invoice_action(self.fee, action)
|
||||
|
||||
class LotInvoicingInv(ModelView):
|
||||
"Fees"
|
||||
|
||||
Reference in New Issue
Block a user