Initial commit: L10N_Asia Pacific packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:52 +02:00
commit 54c86b612c
828 changed files with 58224 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# G.C.C. - Arabic/English Invoice
Arabic/English for GCC
## Installation
```bash
pip install odoo-bringout-oca-ocb-l10n_gcc_invoice
```
## Dependencies
This addon depends on:
- account
## Manifest Information
- **Name**: G.C.C. - Arabic/English Invoice
- **Version**: 1.0.0
- **Category**: Accounting/Localizations
- **License**: LGPL-3
- **Installable**: False
## Source
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `l10n_gcc_invoice`.
## License
This package maintains the original LGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph L10n_gcc_invoice Module - l10n_gcc_invoice
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for l10n_gcc_invoice. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- [account](../../odoo-bringout-oca-ocb-account)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon l10n_gcc_invoice or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-ocb-l10n_gcc_invoice"
# or
uv pip install odoo-bringout-oca-ocb-l10n_gcc_invoice"
```

View file

@ -0,0 +1,13 @@
# Models
Detected core models and extensions in l10n_gcc_invoice.
```mermaid
classDiagram
class account_move
class account_move_line
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: l10n_gcc_invoice. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon l10n_gcc_invoice
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon l10n_gcc_invoice
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import tests

View file

@ -0,0 +1,16 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'G.C.C. - Arabic/English Invoice',
'version': '1.0.0',
'author': 'Odoo',
'category': 'Accounting/Localizations',
'description': """
Arabic/English for GCC
""",
'license': 'LGPL-3',
'depends': ['account'],
'data': [
'views/report_invoice.xml',
],
}

View file

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account_move

View file

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api
class AccountMove(models.Model):
_inherit = 'account.move'
narration = fields.Html(translate=True)
def _get_name_invoice_report(self):
self.ensure_one()
if self.company_id.country_id in self.env.ref('base.gulf_cooperation_council').country_ids:
return 'l10n_gcc_invoice.arabic_english_invoice'
return super()._get_name_invoice_report()
def _load_narration_translation(self):
# Workaround to have the english/arabic version of the payment terms
# in the report
if not self:
return
gcc_countries = self.env.ref('base.gulf_cooperation_council').country_ids
moves_to_fix = self.env['account.move']
for move in self.filtered(lambda m: m.company_id.country_id in gcc_countries and m.is_sale_document(include_receipts=True) and m.narration):
lang = move.partner_id.lang or self.env.user.lang
if move.company_id.terms_type == 'html' or move.narration != move.company_id.with_context(lang=lang).invoice_terms:
continue
moves_to_fix |= move
if not moves_to_fix:
return
self.env['res.company'].flush_model(['invoice_terms'])
self.env.cr.execute('SELECT "id","invoice_terms" FROM "res_company" WHERE id = any(%s)', [moves_to_fix.company_id.ids])
translation_by_company_id = {company_id: narration for company_id, narration in self.env.cr.fetchall()}
self.env.cache.update_raw(moves_to_fix, self._fields['narration'], [
translation_by_company_id[move.company_id.id]
for move in moves_to_fix
], dirty=True)
moves_to_fix.modified(['narration'])
@api.model_create_multi
def create(self, vals_list):
moves = super().create(vals_list)
moves._load_narration_translation()
return moves
def _compute_narration(self):
super()._compute_narration()
# Only update translations of real records
self.filtered('id')._load_narration_translation()
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
l10n_gcc_invoice_tax_amount = fields.Float(string='Tax Amount', compute='_compute_tax_amount', digits='Product Price')
@api.depends('price_subtotal', 'price_total')
def _compute_tax_amount(self):
for record in self:
record.l10n_gcc_invoice_tax_amount = record.price_total - record.price_subtotal

View file

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import test_gcc_invoice

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from markupsafe import Markup
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestGccInvoice(AccountTestInvoicingCommon):
def test_invoice_narration_translation(self):
''' The narration field should be copied translations included'''
# Activate second lang and parameter needed to display invoice terms
self.env['res.lang']._activate_lang('ar_001')
self.env['ir.config_parameter'].sudo().set_param('account.use_invoice_terms', True)
gcc_countries = self.env.ref('base.gulf_cooperation_council').country_ids
self.env.company.write({
'country_id': gcc_countries[0].id,
'invoice_terms': 'English Terms',
'terms_type': 'plain',
})
# Add translation to invoice terms
self.env.company.update_field_translations('invoice_terms', {'en_US': {'English Terms': 'English Terms'}, 'ar_001': {'English Terms': 'Arabic Terms'}})
invoice = self.init_invoice('out_invoice', products=self.product_a)
self.assertEqual(invoice.narration, Markup('<p>English Terms</p>'), 'Original narration not correct')
self.assertEqual(invoice.with_context(lang='ar_001').narration, Markup('<p>Arabic Terms</p>'), 'Translation not loaded succesfully')

View file

@ -0,0 +1,556 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_gcc_invoice.arabic_english_invoice'"
t-call="l10n_gcc_invoice.arabic_english_invoice" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_gcc_invoice.arabic_english_invoice'"
t-call="l10n_gcc_invoice.arabic_english_invoice" t-lang="lang"/>
</xpath>
</template>
<template id="arabic_english_invoice">
<t t-call="web.external_layout">
<t t-set="o" t-value="o.with_context(lang=lang)" />
<t t-set="forced_vat" t-value="o.fiscal_position_id.foreign_vat"/> <!-- So that it appears in the footer of the report instead of the company VAT if it's set -->
<t t-set="address">
<address t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' style="text-align: right"/>
<div t-if="o.partner_id.vat" class="mt16" style="text-align: right">
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/></div>
</t>
<t t-set="o_sec" t-value="o.with_context(lang='ar_001')"/>
<t t-set="o" t-value="o.with_context(lang='en_US')"/>
<div class="page">
<h3>
<div class="row">
<div class="col-4" style="text-align:left">
<span t-if="o.move_type == 'out_invoice' and o.state == 'posted'">
Tax Invoice
</span>
<span t-if="o.move_type == 'out_invoice' and o.state == 'draft'">
Draft Invoice
</span>
<span t-if="o.move_type == 'out_invoice' and o.state == 'cancel'">
Cancelled Invoice
</span>
<span t-if="o.move_type == 'out_refund'">
Credit Note
</span>
<span t-if="o.move_type == 'in_refund'">
Vendor Credit Note
</span>
<span t-if="o.move_type == 'in_invoice'">
Vendor Bill
</span>
</div>
<div class="col-4 text-center">
<span t-if="o.name != '/'" t-field="o.name"/>
</div>
<div class="col-4" style="text-align:right">
<span t-if="o.move_type == 'out_invoice' and o.state == 'posted'">
فاتورة ضريبية
</span>
<span t-if="o.move_type == 'out_invoice' and o.state == 'draft'">
مسودة فاتورة
</span>
<span t-if="o.move_type == 'out_invoice' and o.state == 'cancel'">
فاتورة ملغاة
</span>
<span t-if="o.move_type == 'out_refund'">
إشعار دائن
</span>
<span t-if="o.move_type == 'in_refund'">
إشعار مدين
</span>
<span t-if="o.move_type == 'in_invoice'">
فاتورة المورد
</span>
</div>
</div>
</h3>
<div id="informations" class="pb-3">
<div class="row" t-if="o.invoice_date" name="invoice_date">
<div class="col-2 offset-6">
<strong style="white-space:nowrap">Invoice Date:
</strong>
</div>
<div class="col-2">
<span t-field="o.invoice_date"/>
</div>
<div class="col-2 text-end">
<strong style="white-space:nowrap">:
تاريخ الفاتورة
</strong>
</div>
</div>
<div class="row"
t-if="o.invoice_date_due and o.move_type == 'out_invoice' and o.state == 'posted'"
name="due_date">
<div class="col-2 offset-6">
<strong style="white-space:nowrap">Due Date:
</strong>
</div>
<div class="col-2">
<span t-field="o.invoice_date_due"/>
</div>
<div class="col-2 text-end">
<strong style="white-space:nowrap">:
تاريخ الاستحقاق
</strong>
</div>
</div>
<div class="row" t-if="o.invoice_origin" name="origin">
<div class="col-2 offset-6">
<strong style="white-space:nowrap">Source:
</strong>
</div>
<div class="col-2">
<span t-field="o.invoice_origin"/>
</div>
<div class="col-2 text-end">
<strong style="white-space:nowrap">:
المصدر
</strong>
</div>
</div>
<div class="row" t-if="o.partner_id.ref" name="customer_code">
<div class="col-2 offset-6">
<strong style="white-space:nowrap">:
Customer Code
</strong>
</div>
<div class="col-2">
<span t-field="o.partner_id.ref"/>
</div>
<div class="col-2 text-end">
<strong style="white-space:nowrap">:
كود العميل
</strong>
</div>
</div>
<div class="row" t-if="o.ref" name="reference">
<div class="col-2">
<strong style="white-space:nowrap">Reference:
</strong>
</div>
<div class="col-8">
<span t-field="o.ref"/>
</div>
<div class="col-2 text-end">
<strong style="white-space:nowrap">:
رقم الإشارة
</strong>
</div>
</div>
</div>
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
<table class="table table-sm o_main_table" name="invoice_line_table">
<thead>
<tr>
<t t-set="colspan" t-value="6"/>
<th name="th_total" class="text-end">
<span>
السعر الاجمالي
</span>
<br/>
<span>
Total Price
</span>
</th>
<th name="th_tax_amount"
class="text-end">
<span>
قيمة الضريبة
</span>
<br/>
<span>
VAT Amount
</span>
</th>
<th name="th_subtotal" class="text-end">
<span>
مبلغ
</span>
<br/>
<span>
Amount
</span>
</th>
<th name="th_taxes"
class="text-end">
<span>
الضرائب
</span>
<br/>
<span>
Taxes
</span>
</th>
<th name="th_price_unit" t-if="display_discount"
class="text-end">
<span>
خصم %
</span>
<br/>
<span>
Disc.%
</span>
<t t-set="colspan" t-value="colspan+1"/>
</th>
<th name="th_priceunit"
class="text-end">
<span>
سعر الوحدة
</span>
<br/>
<span>
Unit price
</span>
</th>
<th name="th_quantity" class="text-end">
<span>
الكمية
</span>
<br/>
<span>
Quantity
</span>
</th>
<th name="th_source" class="d-none text-start" t-if="0">
<span>
المستند المصدر
</span>
<br/>
<span>
Source Document
</span>
</th>
<th name="th_description" class="text-end">
<span>
الوصف
</span>
<br/>
<span>
Description
</span>
</th>
</tr>
</thead>
<tbody class="invoice_tbody">
<t t-set="current_subtotal" t-value="0"/>
<t t-set="lines"
t-value="o.invoice_line_ids.sorted(key=lambda l: (-l.sequence, l.date, l.move_name, -l.id), reverse=True)"/>
<t t-foreach="lines" t-as="line">
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal"
groups="account.group_show_line_subtotals_tax_excluded"/>
<t t-set="current_subtotal" t-value="current_subtotal + line.price_total"
groups="account.group_show_line_subtotals_tax_included"/>
<tr t-att-class="'bg-200 fw-bold o_line_section' if line.display_type == 'line_section' else 'fst-italic o_line_note' if line.display_type == 'line_note' else ''">
<t t-if="line.display_type not in ('line_note', 'line_section')" name="account_invoice_line_accountable">
<td class="text-end o_price_total">
<span class="text-nowrap" t-field="line.price_total"/>
</td>
<td class="text-end">
<span class="text-nowrap" t-field="line.l10n_gcc_invoice_tax_amount"/>
</td>
<td class="text-end o_price_total">
<span class="text-nowrap" t-field="line.price_subtotal"/>
</td>
<td class="text-end">
<span t-out="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))"
id="line_tax_ids"/>
</td>
<td t-if="display_discount"
class="text-end">
<span class="text-nowrap" t-field="line.discount"/>
</td>
<td class="text-end">
<span class="text-nowrap" t-field="line.price_unit"/>
</td>
<td class="text-end">
<span t-field="line.quantity"/>
<span t-field="line.product_uom_id" groups="uom.group_uom"/>
</td>
<td name="account_invoice_line_name" class="text-end">
<t t-if="line.product_id">
<t t-set="english_name" t-value="line.with_context(lang='en_US').product_id.display_name"/>
<t t-set="arabic_name" t-value="line.with_context(lang='ar_001').product_id.display_name"/>
<span t-out="arabic_name + '\n'" t-if="arabic_name not in line.name" t-options="{'widget': 'text'}"/>
<span t-out="english_name + '\n'" t-if="(english_name != arabic_name) and (english_name not in line.name)" t-options="{'widget': 'text'}"/>
</t>
<span t-out="line.name" t-options="{'widget': 'text'}"/>
</td>
</t>
<t t-if="line.display_type == 'line_section'">
<td colspan="99">
<span t-field="line.name" t-options="{'widget': 'text'}"/>
</td>
<t t-set="current_section" t-value="line"/>
<t t-set="current_subtotal" t-value="0"/>
</t>
<t t-if="line.display_type == 'line_note'">
<td colspan="99">
<span t-field="line.name" t-options="{'widget': 'text'}"/>
</td>
</t>
</tr>
<t t-if="current_section and (line_last or lines[line_index+1].display_type == 'line_section')">
<tr class="is-subtotal text-end">
<td colspan="99">
<strong class="mr16" style="display: inline-block">Subtotal/الإجمالي الفرعي</strong>
<span
t-out="current_subtotal"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
/>
</td>
</tr>
</t>
</t>
</tbody>
</table>
<div class="clearfix pt-4 pb-3">
<div id="total" class="row">
<div class="col-6">
<table class="table table-sm" style="page-break-inside: avoid;">
<tr class="border-black o_subtotal">
<td class="text-end">
<span t-field="o.amount_untaxed"/>
</td>
<td class="text-end">
<strong>
Subtotal
/
الإجمالي الفرعي
</strong>
</td>
</tr>
<t t-set="tax_totals" t-value="o.tax_totals"/>
<t t-foreach="tax_totals['subtotals']" t-as="subtotal">
<t t-set="subtotal_to_show" t-value="subtotal['name']"/>
<!-- copy-pasted template "account.tax_groups_totals" with reversed columns order -->
<t t-foreach="tax_totals['groups_by_subtotal'][subtotal_to_show]" t-as="amount_by_group">
<tr>
<td class="text-end o_price_total">
<span class="text-nowrap" t-esc="amount_by_group['formatted_tax_group_amount']"/>
</td>
<td class="text-end">
<strong>
<span t-esc="amount_by_group['tax_group_name']"/>
<t t-if="tax_totals['display_tax_base']">
<span class="text-nowrap"> on
<t t-esc="amount_by_group['formatted_tax_group_base_amount']"/>
</span>
</t>
<!-- Arabic translation of tax group -->
<t t-set="arabic_tax_group_name" t-value="o_sec.tax_totals['groups_by_subtotal'][o_sec.tax_totals['subtotals'][subtotal_index]['name']][amount_by_group_index]['tax_group_name']"/>
<span t-if="arabic_tax_group_name != amount_by_group['tax_group_name']" class="text-nowrap">/
<t t-esc="arabic_tax_group_name"/>
</span>
</strong>
</td>
</tr>
</t>
</t>
<tr class="border-black o_total">
<td class="text-end">
<span class="text-nowrap" t-field="o.amount_total"/>
</td>
<td class="text-end">
<strong>
Total
/
المجموع
</strong>
</td>
</tr>
<t t-if="print_with_payments">
<t t-if="o.payment_state != 'invoicing_legacy'">
<t t-set="payments_vals" t-value="o.sudo().invoice_payments_widget and o.sudo().invoice_payments_widget['content'] or []"/>
<t t-foreach="payments_vals" t-as="payment_vals">
<tr class="border-black o_total">
<td>
<i class="row">
<div class="col-7 oe_form_field oe_payment_label">
Paid on/دفعت في:
</div>
<div class="col-5 ps-0 oe_form_field oe_payment_label">
<t t-out="payment_vals['date']"/>
</div>
</i>
</td>
<td class="text-end">
<span t-out="payment_vals['amount']"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td>
</tr>
</t>
<t t-if="len(payments_vals) > 0">
<tr class="border-black">
<td>
<strong>
Amount Due
/
المبلغ المستحق
</strong>
</td>
<td class="text-end">
<span t-field="o.amount_residual"/>
</td>
</tr>
</t>
</t>
</t>
</table>
</div>
</div>
</div>
<p t-if="o.move_type in ('out_invoice', 'in_refund') and o.payment_reference" name="payment_communication" class="pt-1">
<div class="row">
<div class="col-2 text-nowrap">
Payment Reference:
</div>
<div class="col-2 text-center">
<b>
<span t-field="o.payment_reference"/>
</b>
</div>
<div class="col-2 text-end">
:رقم إشارة الدفعة
</div>
</div>
</p>
<p t-if="o.invoice_payment_term_id" name="payment_term">
<div class="row">
<div class="col-3 text-start">
<span t-out="o.invoice_payment_term_id.note"/>
</div>
<div class="col-3 text-end">
<span t-if="o.invoice_payment_term_id.note != o_sec.invoice_payment_term_id.note" dir="rtl" t-out="o_sec.invoice_payment_term_id.note"/>
</div>
</div>
<t t-if="o.invoice_payment_term_id.display_on_invoice and o.payment_term_details">
<div t-if="o.show_payment_term_details" id="total_payment_term_details_table" class="row">
<t t-set="pt_size" t-value="'col-9 offset-3' if o.show_discount_details else 'col-6 offset-6'"/>
<t t-set="pt_size_html" t-value="'col-sm-9 col-md-8 offset-sm-3 offset-md-4' if o.show_discount_details else 'col-sm-6 col-md-6 offset-sm-6 offset-md-6'"/>
<div t-attf-class="#{pt_size if report_type != 'html' else pt_size_html} mt-2 mb-2">
<table class="table table-sm" style="page-break-inside: avoid;">
<th class="border-black text-start">
<span>
تاريخ الاستحقاق
</span>
<br/>
<span>
Due Date
</span>
</th>
<th class="border-black text-end">
<span>
المبلغ المستحق
</span>
<br/>
<span>
Amount Due
</span>
</th>
<th t-if="o.show_discount_details" class="border-black text-end">
<span>
الخصم
</span>
<br/>
<span>
Discount
</span>
</th>
<t t-foreach="o.payment_term_details" t-as="term">
<tr>
<td t-esc="term.get('date')" class="text-start"/>
<td t-options="{'widget': 'monetary', 'display_currency': o.currency_id}" t-esc="term.get('amount')" class="text-end"/>
<td t-if="term.get('discount_date')" class="text-end">
<span dir="rtl" style="white-space: normal;">
<span t-options="{'widget': 'monetary', 'display_currency': o.currency_id}"
t-esc="term.get('discount_amount_currency')"/> إذا تم الدفع قبل
<span t-esc="term.get('discount_date')"/>
</span>
<br/>
<span t-options="{'widget': 'monetary', 'display_currency': o.currency_id}"
t-esc="term.get('discount_amount_currency')"/> if paid before
<span t-esc="term.get('discount_date')"/>
</td>
</tr>
</t>
</table>
</div>
</div>
</t>
</p>
<p t-if="o.narration" name="comment">
<div class="row">
<div class="col-6 text-start">
<span t-out="o.narration"/>
</div>
<div class="col-6 text-end">
<span t-if="o.narration != o_sec.narration" dir="rtl" t-out="o_sec.narration"/>
</div>
</div>
</p>
<p t-if="o.fiscal_position_id.note" name="note">
<div class="row">
<div class="col-6 text-start">
<span t-out="o.fiscal_position_id.note"/>
</div>
<div class="col-6 text-end">
<span t-if="o.fiscal_position_id.note != o_sec.fiscal_position_id.note" dir="rtl" t-out="o_sec.fiscal_position_id.note"/>
</div>
</div>
</p>
<p t-if="o.invoice_incoterm_id" name="incoterm">
<div class="row">
<div class="col-6 text-start">
<strong>Incoterm:
</strong>
<span
t-out="o.invoice_incoterm_id.code"/>
-
<span
t-out="o.invoice_incoterm_id.name"/>
</div>
<div class="col-6 text-end">
<strong>شرط تجاري:
</strong>
<span
t-out="o_sec.invoice_incoterm_id.code"/>
-
<span
t-out="o_sec.invoice_incoterm_id.name"/>
</div>
</div>
</p>
</div>
</t>
</template>
</odoo>

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-ocb-l10n_gcc_invoice"
version = "16.0.0"
description = "G.C.C. - Arabic/English Invoice - Odoo addon"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-account>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["l10n_gcc_invoice"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]