Lot invoicing + Fee
This commit is contained in:
@@ -105,6 +105,39 @@ class InvoiceLineLotWeight(ModelSQL, ModelView):
|
|||||||
class Invoice(metaclass=PoolMeta):
|
class Invoice(metaclass=PoolMeta):
|
||||||
__name__ = 'account.invoice'
|
__name__ = 'account.invoice'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sale_padding_lots_to_clear_on_delete(cls, invoices):
|
||||||
|
lots = {}
|
||||||
|
for invoice in invoices:
|
||||||
|
if (getattr(invoice, 'type', None) != 'out'
|
||||||
|
or getattr(invoice, 'reference', None) != 'Provisional'
|
||||||
|
or getattr(invoice, 'number', None)):
|
||||||
|
continue
|
||||||
|
invoice_id = getattr(invoice, 'id', None)
|
||||||
|
for line in getattr(invoice, 'lines', None) or []:
|
||||||
|
if (getattr(line, 'type', None) != 'line'
|
||||||
|
or getattr(line, 'description', None) != 'Pro forma'):
|
||||||
|
continue
|
||||||
|
lot = getattr(line, 'lot', None)
|
||||||
|
if not lot:
|
||||||
|
continue
|
||||||
|
provisional_line = getattr(lot, 'sale_invoice_line_prov', None)
|
||||||
|
provisional_invoice = getattr(provisional_line, 'invoice', None)
|
||||||
|
if (invoice_id and provisional_invoice
|
||||||
|
and getattr(provisional_invoice, 'id', None) != invoice_id):
|
||||||
|
continue
|
||||||
|
if Decimal(str(getattr(lot, 'sale_invoice_padding', 0) or 0)):
|
||||||
|
lots[getattr(lot, 'id', id(lot))] = lot
|
||||||
|
return list(lots.values())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete(cls, invoices):
|
||||||
|
Lot = Pool().get('lot.lot')
|
||||||
|
padding_lots = cls._sale_padding_lots_to_clear_on_delete(invoices)
|
||||||
|
super().delete(invoices)
|
||||||
|
if padding_lots:
|
||||||
|
Lot.write(padding_lots, {'sale_invoice_padding': Decimal(0)})
|
||||||
|
|
||||||
def do_lot_invoicing(self):
|
def do_lot_invoicing(self):
|
||||||
super().do_lot_invoicing()
|
super().do_lot_invoicing()
|
||||||
self._create_lot_weight_snapshots()
|
self._create_lot_weight_snapshots()
|
||||||
|
|||||||
@@ -4869,7 +4869,7 @@ class LotInvoice(Wizard):
|
|||||||
break
|
break
|
||||||
if not invoice_line:
|
if not invoice_line:
|
||||||
raise UserError("No invoice line was generated from the selected lots.")
|
raise UserError("No invoice line was generated from the selected lots.")
|
||||||
self._invoice_selected_fees()
|
self._invoiced_fee_count = self._invoice_selected_fees()
|
||||||
self.message.invoice = invoice_line.invoice
|
self.message.invoice = invoice_line.invoice
|
||||||
|
|
||||||
return 'message'
|
return 'message'
|
||||||
@@ -4895,6 +4895,7 @@ class LotInvoice(Wizard):
|
|||||||
fees.append(fee)
|
fees.append(fee)
|
||||||
if fees:
|
if fees:
|
||||||
Fee.invoice(fees)
|
Fee.invoice(fees)
|
||||||
|
return len(fees)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _split_sale_padding(cls, padding, lots):
|
def _split_sale_padding(cls, padding, lots):
|
||||||
@@ -4913,10 +4914,16 @@ class LotInvoice(Wizard):
|
|||||||
lot.sale_invoice_padding = padding_by_lot.get(lot.id, Decimal(0))
|
lot.sale_invoice_padding = padding_by_lot.get(lot.id, Decimal(0))
|
||||||
Lot.save(lots)
|
Lot.save(lots)
|
||||||
|
|
||||||
def default_message(self, fields):
|
def default_message(self, fields):
|
||||||
return {
|
fee_count = getattr(self, '_invoiced_fee_count', 0)
|
||||||
'message': 'The invoice has been successfully created.',
|
message = 'The invoice has been successfully created.'
|
||||||
}
|
if fee_count:
|
||||||
|
message += (
|
||||||
|
' %s selected fee invoice(s) have also been processed.'
|
||||||
|
% fee_count)
|
||||||
|
return {
|
||||||
|
'message': message,
|
||||||
|
}
|
||||||
|
|
||||||
def do_see_invoice(self, action):
|
def do_see_invoice(self, action):
|
||||||
action['views'].reverse() # pour ouvrir en form directement
|
action['views'].reverse() # pour ouvrir en form directement
|
||||||
|
|||||||
@@ -7914,6 +7914,41 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
|||||||
self.assertEqual(invoice.report_commission_note_total_display, '24.60')
|
self.assertEqual(invoice.report_commission_note_total_display, '24.60')
|
||||||
fee.get_amount.assert_not_called()
|
fee.get_amount.assert_not_called()
|
||||||
|
|
||||||
|
def test_sale_provisional_invoice_delete_collects_padding_lots(self):
|
||||||
|
'deleting a draft sale provisional invoice clears its lot padding'
|
||||||
|
Invoice = Pool().get('account.invoice')
|
||||||
|
|
||||||
|
invoice = SimpleNamespace(
|
||||||
|
id=10,
|
||||||
|
type='out',
|
||||||
|
reference='Provisional',
|
||||||
|
number=None,
|
||||||
|
lines=[])
|
||||||
|
provisional_line = SimpleNamespace(invoice=invoice)
|
||||||
|
lot = SimpleNamespace(
|
||||||
|
id=20,
|
||||||
|
sale_invoice_padding=Decimal('2'),
|
||||||
|
sale_invoice_line_prov=provisional_line)
|
||||||
|
invoice.lines = [
|
||||||
|
SimpleNamespace(
|
||||||
|
type='line',
|
||||||
|
description='Pro forma',
|
||||||
|
lot=lot)]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
Invoice._sale_padding_lots_to_clear_on_delete([invoice]),
|
||||||
|
[lot])
|
||||||
|
|
||||||
|
def test_lot_invoice_message_mentions_processed_fees(self):
|
||||||
|
'lot invoice success message mentions selected fee invoicing'
|
||||||
|
wizard = lot_module.LotInvoice()
|
||||||
|
wizard._invoiced_fee_count = 2
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
wizard.default_message(None)['message'],
|
||||||
|
'The invoice has been successfully created. '
|
||||||
|
'2 selected fee invoice(s) have also been processed.')
|
||||||
|
|
||||||
def test_invoice_report_net_sums_signed_invoice_lines(self):
|
def test_invoice_report_net_sums_signed_invoice_lines(self):
|
||||||
'invoice report net uses the signed differential from invoice lines'
|
'invoice report net uses the signed differential from invoice lines'
|
||||||
Invoice = Pool().get('account.invoice')
|
Invoice = Pool().get('account.invoice')
|
||||||
|
|||||||
Reference in New Issue
Block a user