Template Melya
This commit is contained in:
1
modules/account_invoice/.~lock.invoice_melya.fodt#
Normal file
1
modules/account_invoice/.~lock.invoice_melya.fodt#
Normal file
@@ -0,0 +1 @@
|
||||
,PC_LO/baron,PC_LO,28.05.2026 13:23,file:///C:/Users/baron/AppData/Roaming/LibreOffice/4;
|
||||
@@ -1584,12 +1584,11 @@
|
||||
<text:p text:style-name="P8"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T6">Payment terms:</text:span></text:span></text:p>
|
||||
<text:p text:style-name="P8"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T9"><text:placeholder text:placeholder-type="text"><invoice.report_payment_description or ''></text:placeholder></text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T9"> </text:span></text:span></text:p>
|
||||
<text:p text:style-name="P4"/>
|
||||
<text:p text:style-name="P21">Bank: UBS SWITZERLAND AG</text:p>
|
||||
<text:p text:style-name="P8"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T9">Case Postale </text:span></text:span></text:p>
|
||||
<text:p text:style-name="P8"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T9">CH-1211 Genève 2</text:span></text:span></text:p>
|
||||
<text:p text:style-name="P21"><text:placeholder text:placeholder-type="text"><if test="invoice.report_melya_bank_name"></text:placeholder>Bank: <text:placeholder text:placeholder-type="text"><invoice.report_melya_bank_name></text:placeholder><text:placeholder text:placeholder-type="text"></if></text:placeholder></text:p>
|
||||
<text:p text:style-name="P8"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T9"><text:placeholder text:placeholder-type="text"><for each="line in invoice.report_melya_bank_address.splitlines()"></text:placeholder><text:placeholder text:placeholder-type="text"><line></text:placeholder><text:placeholder text:placeholder-type="text"></for></text:placeholder></text:span></text:span></text:p>
|
||||
<text:p text:style-name="P4"/>
|
||||
<text:p text:style-name="P22">IBAN : CH36 0021 5215 2487 7461 D</text:p>
|
||||
<text:p text:style-name="P22">SwifT Code: UBSWCHZH80A</text:p>
|
||||
<text:p text:style-name="P22"><text:placeholder text:placeholder-type="text"><if test="invoice.report_melya_bank_iban"></text:placeholder>IBAN : <text:placeholder text:placeholder-type="text"><invoice.report_melya_bank_iban></text:placeholder><text:placeholder text:placeholder-type="text"></if></text:placeholder></text:p>
|
||||
<text:p text:style-name="P22"><text:placeholder text:placeholder-type="text"><if test="invoice.report_melya_bank_swift"></text:placeholder>SwifT Code: <text:placeholder text:placeholder-type="text"><invoice.report_melya_bank_swift></text:placeholder><text:placeholder text:placeholder-type="text"></if></text:placeholder></text:p>
|
||||
<text:p text:style-name="P4"/>
|
||||
</table:table-cell>
|
||||
</table:table-row>
|
||||
|
||||
@@ -644,11 +644,74 @@ class Invoice(metaclass=PoolMeta):
|
||||
bank = getattr(account, 'bank', None) if account else None
|
||||
return getattr(bank, 'bic', None) or ''
|
||||
|
||||
@staticmethod
|
||||
def _get_report_bank_address(account):
|
||||
bank = getattr(account, 'bank', None) if account else None
|
||||
party = getattr(bank, 'party', None) if bank else None
|
||||
address_get = getattr(party, 'address_get', None) if party else None
|
||||
if callable(address_get):
|
||||
return address_get()
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _get_report_bank_party_name(account):
|
||||
bank = getattr(account, 'bank', None) if account else None
|
||||
party = getattr(bank, 'party', None) if bank else None
|
||||
address = Invoice._get_report_bank_address(account)
|
||||
return (
|
||||
getattr(address, 'party_full_name', None)
|
||||
or getattr(address, 'party_name', None)
|
||||
or getattr(party, 'rec_name', None)
|
||||
or getattr(bank, 'rec_name', None)
|
||||
or '')
|
||||
|
||||
@staticmethod
|
||||
def _get_report_bank_address_lines(account):
|
||||
address = Invoice._get_report_bank_address(account)
|
||||
full_address = getattr(address, 'full_address', None) if address else ''
|
||||
if not full_address and address:
|
||||
city_line = ' '.join(filter(None, [
|
||||
getattr(address, 'postal_code', None),
|
||||
getattr(address, 'city', None),
|
||||
]))
|
||||
full_address = '\n'.join(filter(None, [
|
||||
getattr(address, 'name', None),
|
||||
getattr(address, 'street', None),
|
||||
city_line,
|
||||
]))
|
||||
return '\n'.join(
|
||||
line for line in (full_address or '').splitlines()
|
||||
if line.strip())
|
||||
|
||||
@staticmethod
|
||||
def _format_report_payment_amount(value):
|
||||
amount = Decimal(str(value or 0)).quantize(Decimal('0.01'))
|
||||
return format(amount, 'f')
|
||||
|
||||
def _get_report_melya_bank_account(self):
|
||||
sale = self._get_report_deal_sale()
|
||||
return getattr(sale, 'our_bank_account', None) if sale else None
|
||||
|
||||
@property
|
||||
def report_melya_bank_name(self):
|
||||
return self._get_report_bank_party_name(
|
||||
self._get_report_melya_bank_account())
|
||||
|
||||
@property
|
||||
def report_melya_bank_address(self):
|
||||
return self._get_report_bank_address_lines(
|
||||
self._get_report_melya_bank_account())
|
||||
|
||||
@property
|
||||
def report_melya_bank_iban(self):
|
||||
return self._get_report_bank_account_number(
|
||||
self._get_report_melya_bank_account())
|
||||
|
||||
@property
|
||||
def report_melya_bank_swift(self):
|
||||
return self._get_report_bank_swift(
|
||||
self._get_report_melya_bank_account())
|
||||
|
||||
@property
|
||||
def _report_payment_order_company_account(self):
|
||||
return self._get_report_bank_account(getattr(self.company, 'party', None))
|
||||
|
||||
@@ -784,16 +784,51 @@ class Sale(metaclass=PoolMeta):
|
||||
|
||||
@property
|
||||
def report_deal(self):
|
||||
if self.lines and self.lines[0].lots and len(self.lines[0].lots) > 1:
|
||||
purchase = getattr(getattr(self.lines[0].lots[1], 'line', None),
|
||||
'purchase', None)
|
||||
purchase_number = getattr(purchase, 'number', None)
|
||||
purchase_number = self._format_report_deal_number(
|
||||
purchase_number, 'P')
|
||||
sale_number = self._format_report_deal_number(self.number, 'S')
|
||||
return ' '.join(
|
||||
number for number in [purchase_number, sale_number] if number)
|
||||
return ''
|
||||
purchase = self._get_report_deal_purchase()
|
||||
purchase_number = self._format_report_deal_number(
|
||||
getattr(purchase, 'number', None), 'P')
|
||||
sale_number = self._format_report_deal_number(
|
||||
getattr(self, 'number', None), 'S')
|
||||
return ' '.join(
|
||||
number for number in [purchase_number, sale_number] if number)
|
||||
|
||||
def _get_report_deal_purchase(self):
|
||||
lots = []
|
||||
for line in getattr(self, 'lines', []) or []:
|
||||
lots.extend(getattr(line, 'lots', []) or [])
|
||||
|
||||
for lot in lots:
|
||||
purchase = getattr(getattr(lot, 'line', None), 'purchase', None)
|
||||
if purchase:
|
||||
return purchase
|
||||
|
||||
if not lots:
|
||||
return None
|
||||
|
||||
LotQt = Pool().get('lot.qt')
|
||||
for lot in lots:
|
||||
lot_ids = []
|
||||
lot_id = getattr(lot, 'id', None)
|
||||
if lot_id:
|
||||
lot_ids.append(lot_id)
|
||||
get_vlot_s = getattr(lot, 'getVlot_s', None)
|
||||
if get_vlot_s:
|
||||
virtual_lot = get_vlot_s()
|
||||
virtual_lot_id = getattr(virtual_lot, 'id', None)
|
||||
if virtual_lot_id:
|
||||
lot_ids.append(virtual_lot_id)
|
||||
for lot_id in lot_ids:
|
||||
lot_qts = LotQt.search([
|
||||
('lot_s', '=', lot_id),
|
||||
('lot_p', '>', 0),
|
||||
], limit=1)
|
||||
for lot_qt in lot_qts:
|
||||
purchase = getattr(
|
||||
getattr(getattr(lot_qt, 'lot_p', None), 'line', None),
|
||||
'purchase', None)
|
||||
if purchase:
|
||||
return purchase
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _format_report_deal_number(number, prefix):
|
||||
|
||||
@@ -3259,6 +3259,75 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
|
||||
self.assertEqual(invoice.report_contract_number, 'P-12/S-34')
|
||||
|
||||
def test_invoice_melya_bank_uses_sale_our_bank_account(self):
|
||||
'invoice_melya bank block uses the sale company bank account'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
address = Mock(
|
||||
party_full_name='UBS SWITZERLAND AG',
|
||||
full_address='Case Postale\nCH-1211 Geneve 2',
|
||||
)
|
||||
party = Mock(rec_name='UBS')
|
||||
party.address_get.return_value = address
|
||||
bank = Mock(party=party, bic='UBSWCHZH80A')
|
||||
account = Mock(
|
||||
bank=bank,
|
||||
numbers=[Mock(type='iban', number='CH36 0021 5215 2487 7461 D')],
|
||||
)
|
||||
sale = Mock(our_bank_account=account)
|
||||
|
||||
invoice = Invoice()
|
||||
invoice._get_report_deal_sale = Mock(return_value=sale)
|
||||
|
||||
self.assertEqual(invoice.report_melya_bank_name, 'UBS SWITZERLAND AG')
|
||||
self.assertEqual(
|
||||
invoice.report_melya_bank_address,
|
||||
'Case Postale\nCH-1211 Geneve 2')
|
||||
self.assertEqual(
|
||||
invoice.report_melya_bank_iban,
|
||||
'CH36 0021 5215 2487 7461 D')
|
||||
self.assertEqual(invoice.report_melya_bank_swift, 'UBSWCHZH80A')
|
||||
|
||||
def test_sale_report_deal_uses_purchase_and_sale_numbers(self):
|
||||
'sale deal number includes the linked purchase number'
|
||||
Sale = Pool().get('sale.sale')
|
||||
|
||||
purchase = Mock(number='12')
|
||||
lot = Mock(line=Mock(purchase=purchase))
|
||||
sale = Sale()
|
||||
sale.number = '88'
|
||||
sale.lines = [Mock(lots=[lot])]
|
||||
|
||||
self.assertEqual(sale.report_deal, 'P-12 S-88')
|
||||
self.assertEqual(sale.report_melya_proforma_number, 'P-12 S-88')
|
||||
|
||||
def test_sale_report_deal_falls_back_to_lot_qt_matching(self):
|
||||
'sale deal number finds purchase through lot.qt matching'
|
||||
Sale = Pool().get('sale.sale')
|
||||
|
||||
class SaleLot:
|
||||
id = 99
|
||||
line = None
|
||||
|
||||
purchase = Mock(number='12')
|
||||
lot_qt_model = Mock()
|
||||
lot_qt_model.search.return_value = [
|
||||
Mock(lot_p=Mock(line=Mock(purchase=purchase)))]
|
||||
|
||||
sale = Sale()
|
||||
sale.number = '88'
|
||||
sale.lines = [Mock(lots=[SaleLot()])]
|
||||
|
||||
with patch('trytond.modules.purchase_trade.sale.Pool') as PoolMock:
|
||||
PoolMock.return_value.get.return_value = lot_qt_model
|
||||
|
||||
self.assertEqual(sale.report_deal, 'P-12 S-88')
|
||||
|
||||
lot_qt_model.search.assert_called_once_with([
|
||||
('lot_s', '=', 99),
|
||||
('lot_p', '>', 0),
|
||||
], limit=1)
|
||||
|
||||
def test_contract_factory_uses_one_line_per_selected_source(self):
|
||||
'matched multi-lot contract creation keeps one generated line per source lot'
|
||||
contract_detail = Mock(quantity=Decimal('2000'))
|
||||
|
||||
@@ -662,9 +662,11 @@
|
||||
</style:style>
|
||||
<style:style style:name="P63" style:family="paragraph" style:parent-style-name="Standard">
|
||||
<style:paragraph-properties fo:margin-left="10.76cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false" style:writing-mode="lr-tb"/>
|
||||
<style:text-properties style:font-name="Arial mt" fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
|
||||
</style:style>
|
||||
<style:style style:name="P64" style:family="paragraph" style:parent-style-name="P1">
|
||||
<style:paragraph-properties fo:margin-left="10.76cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false" style:writing-mode="lr-tb"/>
|
||||
<style:text-properties style:font-name="Arial1" fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
|
||||
</style:style>
|
||||
<style:style style:name="MelyaFooterVat" style:family="paragraph" style:parent-style-name="Standard">
|
||||
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:border-top="0.5pt solid #808080" fo:border-bottom="0.5pt solid #808080" fo:padding-top="0.12cm" fo:padding-bottom="0.12cm"/>
|
||||
|
||||
Reference in New Issue
Block a user