Add Purchase order template

This commit is contained in:
2026-04-07 11:42:09 +02:00
parent 3480eb8a7a
commit 00330008d1
6 changed files with 2040 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,7 @@ class Configuration(ModelSingleton, ModelSQL, ModelView):
invoice_report_template = fields.Char("Invoice Template")
invoice_cndn_report_template = fields.Char("CN/DN Template")
invoice_prepayment_report_template = fields.Char("Prepayment Template")
invoice_payment_order_report_template = fields.Char("Payment Order Template")
purchase_report_template = fields.Char("Purchase Template")
shipment_shipping_report_template = fields.Char("Shipping Template")
shipment_insurance_report_template = fields.Char("Insurance Template")

View File

@@ -111,6 +111,7 @@ Derniere mise a jour: `2026-04-02`
- Sections actuellement attendues:
- `Sale`
- `Invoice`
- `Payment`
- `Purchase`
- `Shipment`
- Regle:

View File

@@ -1,8 +1,10 @@
from decimal import Decimal, ROUND_HALF_UP
from datetime import date as dt_date
from trytond.pool import Pool, PoolMeta
from trytond.modules.purchase_trade.numbers_to_words import amount_to_currency_words
from trytond.exceptions import UserError
from trytond.transaction import Transaction
from trytond.modules.account_invoice.invoice import (
InvoiceReport as BaseInvoiceReport)
from trytond.modules.sale.sale import SaleReport as BaseSaleReport
@@ -147,6 +149,153 @@ class Invoice(metaclass=PoolMeta):
or getattr(lot, 'lot_shipment_internal', None)
)
@staticmethod
def _get_report_bank_account(party):
accounts = list(getattr(party, 'bank_accounts', []) or [])
return accounts[0] if accounts else None
@staticmethod
def _get_report_bank_account_number(account):
if not account:
return ''
numbers = list(getattr(account, 'numbers', []) or [])
for number in numbers:
if getattr(number, 'type', None) == 'iban' and getattr(number, 'number', None):
return number.number or ''
for number in numbers:
if getattr(number, 'number', None):
return number.number or ''
return ''
@staticmethod
def _get_report_bank_name(account):
bank = getattr(account, 'bank', None) if account else None
party = getattr(bank, 'party', None) if bank else None
return getattr(party, 'rec_name', None) or getattr(bank, 'rec_name', None) or ''
@staticmethod
def _get_report_bank_city(account):
bank = getattr(account, 'bank', None) if account else None
party = getattr(bank, 'party', None) if bank else None
address = party.address_get() if party and hasattr(party, 'address_get') else None
return getattr(address, 'city', None) or ''
@staticmethod
def _get_report_bank_swift(account):
bank = getattr(account, 'bank', None) if account else None
return getattr(bank, 'bic', None) or ''
@staticmethod
def _format_report_payment_amount(value):
amount = Decimal(str(value or 0)).quantize(Decimal('0.01'))
return format(amount, 'f')
@property
def _report_payment_order_company_account(self):
return self._get_report_bank_account(getattr(self.company, 'party', None))
@property
def _report_payment_order_beneficiary_account(self):
return self._get_report_bank_account(self.party)
@property
def report_payment_order_short_name(self):
company_party = getattr(self.company, 'party', None)
return getattr(company_party, 'rec_name', '') or ''
@property
def report_payment_order_document_reference(self):
return self.number or self.reference or ''
@property
def report_payment_order_from_account_nb(self):
return self._get_report_bank_account_number(
self._report_payment_order_company_account)
@property
def report_payment_order_to_bank_name(self):
return self._get_report_bank_name(self._report_payment_order_beneficiary_account)
@property
def report_payment_order_to_bank_city(self):
return self._get_report_bank_city(self._report_payment_order_beneficiary_account)
@property
def report_payment_order_amount(self):
return self._format_report_payment_amount(self.total_amount)
@property
def report_payment_order_currency_code(self):
currency = self.currency
return (
getattr(currency, 'code', None)
or getattr(currency, 'rec_name', None)
or getattr(currency, 'symbol', None)
or '')
@property
def report_payment_order_amount_text(self):
return amount_to_currency_words(self.total_amount)
@property
def report_payment_order_value_date(self):
value_date = self.payment_term_date or self.invoice_date
if isinstance(value_date, dt_date):
return value_date.strftime('%d-%m-%Y')
return ''
@property
def report_payment_order_company_address(self):
if self.invoice_address and getattr(self.invoice_address, 'full_address', None):
return self.invoice_address.full_address
return self.report_address
@property
def report_payment_order_beneficiary_account_nb(self):
return self._get_report_bank_account_number(
self._report_payment_order_beneficiary_account)
@property
def report_payment_order_beneficiary_bank_name(self):
return self._get_report_bank_name(self._report_payment_order_beneficiary_account)
@property
def report_payment_order_beneficiary_bank_city(self):
return self._get_report_bank_city(self._report_payment_order_beneficiary_account)
@property
def report_payment_order_swift_code(self):
return self._get_report_bank_swift(self._report_payment_order_beneficiary_account)
@property
def report_payment_order_other_instructions(self):
return self.description or ''
@property
def report_payment_order_reference(self):
return self.reference or self.number or ''
@staticmethod
def _get_report_current_user():
user_id = Transaction().user
if not user_id:
return None
User = Pool().get('res.user')
return User(user_id)
@property
def report_payment_order_current_user(self):
user = self._get_report_current_user()
return getattr(user, 'rec_name', None) or ''
@property
def report_payment_order_current_user_email(self):
user = self._get_report_current_user()
party = getattr(user, 'party', None) if user else None
if party and hasattr(party, 'contact_mechanism_get'):
return party.contact_mechanism_get('email') or ''
return getattr(user, 'email', None) or ''
@property
def report_address(self):
trade = self._get_report_trade()
@@ -746,6 +895,9 @@ class InvoiceReport(ReportTemplateMixin, BaseInvoiceReport):
if (report_path.endswith('/prepayment.fodt')
or action_name == 'Prepayment'):
field_name = 'invoice_prepayment_report_template'
elif (report_path.endswith('/payment_order.fodt')
or action_name == 'Payment Order'):
field_name = 'invoice_payment_order_report_template'
elif (report_path.endswith('/invoice_ict_final.fodt')
or action_name == 'CN/DN'):
field_name = 'invoice_cndn_report_template'

View File

@@ -313,6 +313,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
invoice_report_template='invoice_melya.fodt',
invoice_cndn_report_template='invoice_ict_final.fodt',
invoice_prepayment_report_template='prepayment.fodt',
invoice_payment_order_report_template='payment_order.fodt',
purchase_report_template='purchase_melya.fodt',
)
]
@@ -340,6 +341,12 @@ class PurchaseTradeTestCase(ModuleTestCase):
'report': 'account_invoice/invoice_ict_final.fodt',
}),
'account_invoice/invoice_ict_final.fodt')
self.assertEqual(
report_class._resolve_configured_report_path({
'name': 'Payment Order',
'report': 'account_invoice/payment_order.fodt',
}),
'account_invoice/payment_order.fodt')
def test_invoice_report_raises_when_template_is_missing(self):
'invoice report must fail clearly when no template is configured'
@@ -350,6 +357,7 @@ class PurchaseTradeTestCase(ModuleTestCase):
invoice_report_template='',
invoice_cndn_report_template='',
invoice_prepayment_report_template='',
invoice_payment_order_report_template='',
)
]
@@ -362,6 +370,11 @@ class PurchaseTradeTestCase(ModuleTestCase):
'name': 'Invoice',
'report': 'account_invoice/invoice.fodt',
})
with self.assertRaises(UserError):
report_class._resolve_configured_report_path({
'name': 'Payment Order',
'report': 'account_invoice/payment_order.fodt',
})
def test_sale_report_uses_templates_from_configuration(self):
'sale report paths are resolved from purchase_trade configuration'

View File

@@ -16,6 +16,10 @@
<label name="invoice_prepayment_report_template"/>
<field name="invoice_prepayment_report_template" colspan="3"/>
<separator id="payment_templates" string="Payment" colspan="4"/>
<label name="invoice_payment_order_report_template"/>
<field name="invoice_payment_order_report_template" colspan="3"/>
<separator id="purchase_templates" string="Purchase" colspan="4"/>
<label name="purchase_report_template"/>
<field name="purchase_report_template" colspan="3"/>