19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:31:34 +01:00
parent c5006a6999
commit 80293571e7
420 changed files with 21812 additions and 44297 deletions

View file

@ -14,36 +14,15 @@ pip install odoo-bringout-oca-ocb-l10n_eg_edi_eta
## Dependencies
This addon depends on:
- account_edi
- l10n_eg
## Manifest Information
- **Name**: Egypt E-Invoicing
- **Version**: 0.2
- **Category**: account
- **License**: LGPL-3
- **Installable**: False
## Source
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `l10n_eg_edi_eta`.
- Repository: https://github.com/OCA/OCB
- Branch: 19.0
- Path: addons/l10n_eg_edi_eta
## 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
This package preserves the original LGPL-3 license.

View file

@ -2,7 +2,7 @@
{
'name': "Egypt E-Invoicing",
'summary': """
Egyptian Tax Authority Invoice Integration
Egypt Tax Authority Invoice Integration
""",
'description': """
Egypt Tax Authority Invoice Integration
@ -14,6 +14,8 @@ Integrates with the ETA portal to automatically send and sign the Invoices to th
'version': '0.2',
'license': 'LGPL-3',
'depends': ['account_edi', 'l10n_eg'],
'icon': '/account/static/description/l10n.png',
'countries': ['eg'],
'data': [
'data/account_edi_data.xml',
'data/l10n_eg_edi.activity.type.csv',
@ -32,10 +34,13 @@ Integrates with the ETA portal to automatically send and sign the Invoices to th
],
'assets': {
'web.assets_backend': [
'l10n_eg_edi_eta/static/src/js/sign_invoice.js',
'l10n_eg_edi_eta/static/src/**/*.js',
],
},
'external_dependencies': {
'python': ['asn1crypto'],
'apt': {
'asn1crypto': 'python3-asn1crypto',
},
},
}

View file

@ -11,15 +11,15 @@
<field name="type" invisible="1"/>
<field name="l10n_eg_building_no" placeholder="Building Number..." class="o_address_street"/>
<field name="street" placeholder="Street" class="o_address_street"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
readonly="type == 'contact' and parent_id"/>
<field name="street2" invisible="1"/>
<field name="city"/>
<field name="state_id" class="o_address_state" placeholder="State..." options='{"no_open": True}'
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
readonly="type == 'contact' and parent_id"/>
<field name="zip" placeholder="ZIP" class="o_address_zip"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
readonly="type == 'contact' and parent_id"/>
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
readonly="type == 'contact' and parent_id"/>
</div>
</form>
</field>

View file

@ -16,4 +16,5 @@ uom.product_uom_lb,l10n_eg_edi_uom_code_LB
uom.product_uom_meter,l10n_eg_edi_uom_code_M
uom.product_uom_mile,l10n_eg_edi_uom_code_SMI
uom.product_uom_cubic_meter,l10n_eg_edi_uom_code_MTQ
uom.product_uom_oz,l10n_eg_edi_uom_code_ONZ
uom.product_uom_oz,l10n_eg_edi_uom_code_ONZ
uom.product_uom_millimeter,l10n_eg_edi_uom_code_MMT

1 id l10n_eg_unit_code_id/id
16 uom.product_uom_meter l10n_eg_edi_uom_code_M
17 uom.product_uom_mile l10n_eg_edi_uom_code_SMI
18 uom.product_uom_cubic_meter l10n_eg_edi_uom_code_MTQ
19 uom.product_uom_oz l10n_eg_edi_uom_code_ONZ
20 uom.product_uom_millimeter l10n_eg_edi_uom_code_MMT

View file

@ -1,30 +1,31 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * l10n_eg_edi_eta
# * l10n_eg_edi_eta
#
# Translators:
# Malaz Abuidris <msea@odoo.com>, 2022
# Martin Trigaux, 2022
#
# Weblate <noreply-mt-weblate@weblate.org>, 2025.
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-17 10:23+0000\n"
"PO-Revision-Date: 2022-05-17 12:39+0000\n"
"Last-Translator: Martin Trigaux, 2022\n"
"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n"
"POT-Creation-Date: 2025-12-30 19:06+0000\n"
"PO-Revision-Date: 2025-11-17 03:10+0000\n"
"Last-Translator: Weblate <noreply-mt-weblate@weblate.org>\n"
"Language-Team: Arabic <https://translate.odoo.com/projects/odoo-19-l10n/"
"l10n_eg_edi_eta/ar/>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 5.12.2\n"
#. module: l10n_eg_edi_eta
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.res_config_settings_view_form
msgid ""
"<span class=\"o_form_label\">ETA API Integration</span>\n"
" <span class=\"fa fa-lg fa-building-o\" title=\"Values set here are company-specific.\" aria-label=\"Values set here are company-specific.\" groups=\"base.group_multi_company\" role=\"img\"/>"
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.egyptian_invoice
msgid "<strong class=\"text-center\">ETA QR Code</strong>"
msgstr ""
#. module: l10n_eg_edi_eta
@ -158,16 +159,14 @@ msgid "Air transport of passengers"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "An error occured in created the ETA invoice, please retry signing"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "An unexpected error has occurred"
msgstr ""
@ -225,7 +224,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.uom.code,name:l10n_eg_edi_eta.l10n_eg_edi_uom_code_BOX
msgid "Box"
msgstr "صندوق "
msgstr "صندوق"
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__l10n_eg_branch_id
@ -418,8 +417,8 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_6202
msgid ""
"Computer consultancy experience and facilities management activities related"
" to computer fields"
"Computer consultancy experience and facilities management activities related "
"to computer fields"
msgstr ""
#. module: l10n_eg_edi_eta
@ -457,6 +456,11 @@ msgstr "جهة اتصال "
msgid "Country"
msgstr "الدولة"
#. module: l10n_eg_edi_eta
#: model:ir.model,website_form_label:l10n_eg_edi_eta.model_res_partner
msgid "Create a Customer"
msgstr "Create a Customer"
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__create_uid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__create_uid
@ -478,8 +482,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_6430
msgid ""
"Credit activities, provision of credits, and similar financial entities"
msgid "Credit activities, provision of credits, and similar financial entities"
msgstr ""
#. module: l10n_eg_edi_eta
@ -524,8 +527,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_0111
msgid ""
"Cultivation of grains and crops (except for rice), legumes and oilseeds"
msgid "Cultivation of grains and crops (except for rice), legumes and oilseeds"
msgstr ""
#. module: l10n_eg_edi_eta
@ -600,22 +602,31 @@ msgid "Defense activities"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_edi_format__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_product__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_template__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_currency_rate__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_partner__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_uom_uom__display_name
msgid "Display Name"
msgstr "اسم العرض "
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Document Canceled"
msgid "Document Cancelled"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_uuid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_uuid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_uuid
msgid "Document UUID"
msgstr ""
@ -629,6 +640,11 @@ msgstr "صيغة EDI "
msgid "ETA"
msgstr ""
#. module: l10n_eg_edi_eta
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.res_config_settings_view_form
msgid "ETA API Integration"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__l10n_eg_activity_type_id
msgid "ETA Activity Code"
@ -678,6 +694,24 @@ msgstr ""
msgid "ETA Item code"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_eta_json_doc_file
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_eta_json_doc_file
msgid "ETA JSON Document"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_long_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_long_id
msgid "ETA Long ID"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_qr_code
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_qr_code
msgid "ETA QR Code"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__l10n_eg_client_secret
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__l10n_eg_client_secret
@ -705,14 +739,14 @@ msgid "ETA code for the unit of measures"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "ETA invoice has been received"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "ETA_INVOICE_DOC_%s"
msgstr ""
@ -733,8 +767,8 @@ msgid "Egyptian Electronic Invoicing"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Egyptian Tax authority JSON invoice generated for %s."
msgstr ""
@ -795,18 +829,14 @@ msgid "Errand stamp"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Error trying to connect to Odoo. Check your internet connection"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Error trying to connect to the middleware. Is the middleware running?"
msgstr ""
@ -1055,9 +1085,19 @@ msgid "Hydraulic Horse Power"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_edi_format__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_product__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_template__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_currency_rate__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_partner__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_uom_uom__id
msgid "ID"
msgstr "المُعرف"
@ -1248,17 +1288,9 @@ msgstr ""
msgid "Kilowatt ( KW )"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_eta_json_doc_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_eta_json_doc_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_eta_json_doc_id
msgid "L10N Eg Eta Json Doc"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_is_signed
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_is_signed
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_is_signed
msgid "L10N Eg Is Signed"
msgstr ""
@ -1267,13 +1299,6 @@ msgstr ""
msgid "Land transportation of goods by bus"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type____last_update
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive____last_update
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code____last_update
msgid "Last Modified on"
msgstr "آخر تعديل في"
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__write_uid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__write_uid
@ -1296,7 +1321,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.uom.code,name:l10n_eg_edi_eta.l10n_eg_edi_uom_code_LVL
msgid "Level"
msgstr "المستوى "
msgstr "المستوى"
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_9101
@ -1377,8 +1402,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_1622
msgid ""
"Manufacture of carpentry accessories intended for buildings and "
"installations"
"Manufacture of carpentry accessories intended for buildings and installations"
msgstr ""
#. module: l10n_eg_edi_eta
@ -1478,8 +1502,8 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_2920
msgid ""
"Manufacture of motor vehicle bodies and the manufacture of trailers and "
"semi-trailers"
"Manufacture of motor vehicle bodies and the manufacture of trailers and semi-"
"trailers"
msgstr ""
#. module: l10n_eg_edi_eta
@ -1528,8 +1552,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_2599
msgid ""
"Manufacture of other fabricated metal products not classified elsewhere"
msgid "Manufacture of other fabricated metal products not classified elsewhere"
msgstr ""
#. module: l10n_eg_edi_eta
@ -1611,8 +1634,8 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_3520
msgid ""
"Manufacture of sulfur gas and distribution of gaseous fuels by means of main"
" pipes"
"Manufacture of sulfur gas and distribution of gaseous fuels by means of main "
"pipes"
msgstr ""
#. module: l10n_eg_edi_eta
@ -1753,20 +1776,18 @@ msgid "Minute ( min )"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Missing Dependency - If you are using Windows, make sure eps2003csp11.dll is"
" correctly installed. You can download it here: "
"https://www.egypttrust.com/en/downloads/other-drivers. If you are using "
"Linux or macOS, please install OpenSC"
"Missing Dependency - If you are using Windows, make sure eps2003csp11.dll is "
"correctly installed. You can download it here: https://www.egypttrust.com/en/"
"downloads/other-drivers. If you are using Linux or macOS, please install "
"OpenSC"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Missing library - Please make sure that PyKCS11 is correctly installed on "
"the local proxy server"
@ -1788,12 +1809,11 @@ msgid "Motion picture, video and television program distribution activities"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Multiple drive detected - Only one secure thumb drive can be inserted at the"
" same time"
"Multiple drive detected - Only one secure thumb drive can be inserted at the "
"same time"
msgstr ""
#. module: l10n_eg_edi_eta
@ -1818,9 +1838,8 @@ msgid "Nanometer ( nm )"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "No drive found - Make sure the thumb drive is correctly inserted"
msgstr ""
@ -2069,8 +2088,8 @@ msgid "Ounce ( oz )"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "PDF Document is not available"
msgstr ""
@ -2147,89 +2166,90 @@ msgid "Plastics industry in its primary forms and synthetic rubber"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please add all the required fields in the branch details"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please add all the required fields in the customer details"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please configure the API domain from the system parameters"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please configure the token domain from the system parameters"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/eta_thumb_drive.py:0
#, python-format
msgid "Please define the host of sign tool."
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/res_currency_rate.py:0
#, python-format
msgid ""
"Please make sure that the EGP per unit is within 5 decimal accuracy.\n"
"Higher decimal accuracy might lead to inconsistency with the ETA invoicing portal!"
"Higher decimal accuracy might lead to inconsistency with the ETA invoicing "
"portal!"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the EGS/GS1 Barcode is set correctly on all products"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the invoice is signed"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the invoice lines UoM codes are all set up correctly"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"Please make sure the invoice lines taxes all have the correct ETA tax code"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please only sign invoices from one company at a time"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please set the all the ETA information on the invoice's journal"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please setup a personal drive for company %s"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please setup the certificate on the thumb drive menu"
msgstr ""
@ -2284,20 +2304,20 @@ msgid "Processing and spinning of textile fibers"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_product
#: model:ir.model,name:l10n_eg_edi_eta.model_product_template
msgid "Product"
msgstr "المنتج"
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_template
msgid "Product Template"
msgstr "قالب المنتج"
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_uom_uom
msgid "Product Unit of Measure"
msgstr "وحدة قياس المنتج"
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_product
msgid "Product Variant"
msgstr "متغير المنتج"
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_5920
msgid "Production and publishing of sound and music recordings"
@ -2749,7 +2769,6 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_signing_time
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_signing_time
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_signing_time
msgid "Signing Time"
msgstr ""
@ -2823,7 +2842,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.eg_partner_address_form
msgid "State..."
msgstr ""
msgstr "المحافظة..."
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_3530
@ -2843,7 +2862,6 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_submission_number
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_submission_number
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_submission_number
msgid "Submission ID"
msgstr ""
@ -2870,9 +2888,8 @@ msgid "Support activities for joint facilities"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "System not supported"
msgstr ""
@ -2974,16 +2991,16 @@ msgid ""
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"This invoice has been marked as invalid by the ETA. Please check the ETA "
"website for more information"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"This invoice has been sent to the ETA, but we are still awaiting validation"
msgstr ""
@ -3079,25 +3096,17 @@ msgid "Treatment and disposal of non-hazardous waste"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Unauthorized"
msgstr ""
msgstr "غير مصرح به"
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
msgid "Unexpected error:"
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Unexpected error: “%s”"
msgstr ""
#. module: l10n_eg_edi_eta
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Unknown error"
msgstr "خطأ غير معروف"
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_0721
msgid "Uranium and raw thorium mining"
@ -3119,8 +3128,8 @@ msgid "Volt ( V )"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/res_currency_rate.py:0
#, python-format
msgid "Warning for %s"
msgstr "تحذير لـ %s"
@ -3187,8 +3196,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_4651
msgid ""
"Wholesale trade of computer hardware, accessories and computer software"
msgid "Wholesale trade of computer hardware, accessories and computer software"
msgstr ""
#. module: l10n_eg_edi_eta
@ -3199,8 +3207,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_4652
msgid ""
"Wholesale trade of electronic devices, communications devices and "
"accessories"
"Wholesale trade of electronic devices, communications devices and accessories"
msgstr ""
#. module: l10n_eg_edi_eta
@ -3271,8 +3278,8 @@ msgid "You can only have one thumb drive per user per company!"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"You cannot issue an invoice to a partner with the same VAT number as the "
"branch."
@ -3284,15 +3291,14 @@ msgid "ZIP"
msgstr "رمز ZIP "
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "an Unknown error has occured"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "an Unknown error has occurred"
msgstr ""
@ -3329,7 +3335,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.uom.code,name:l10n_eg_edi_eta.l10n_eg_edi_uom_code_PMP
msgid "pump"
msgstr ""
msgstr "مضخة"
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_6520
@ -3339,7 +3345,7 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.uom.code,name:l10n_eg_edi_eta.l10n_eg_edi_uom_code_RUN
msgid "run"
msgstr ""
msgstr "تشغيل"
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_0121

View file

@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0+e\n"
"Project-Id-Version: Odoo Server 19.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-17 10:23+0000\n"
"PO-Revision-Date: 2022-05-17 10:23+0000\n"
"POT-Creation-Date: 2025-12-30 19:06+0000\n"
"PO-Revision-Date: 2025-12-30 19:06+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -16,10 +16,8 @@ msgstr ""
"Plural-Forms: \n"
#. module: l10n_eg_edi_eta
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.res_config_settings_view_form
msgid ""
"<span class=\"o_form_label\">ETA API Integration</span>\n"
" <span class=\"fa fa-lg fa-building-o\" title=\"Values set here are company-specific.\" aria-label=\"Values set here are company-specific.\" groups=\"base.group_multi_company\" role=\"img\"/>"
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.egyptian_invoice
msgid "<strong class=\"text-center\">ETA QR Code</strong>"
msgstr ""
#. module: l10n_eg_edi_eta
@ -153,16 +151,14 @@ msgid "Air transport of passengers"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "An error occured in created the ETA invoice, please retry signing"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "An unexpected error has occurred"
msgstr ""
@ -452,6 +448,11 @@ msgstr ""
msgid "Country"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model,website_form_label:l10n_eg_edi_eta.model_res_partner
msgid "Create a Customer"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__create_uid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__create_uid
@ -595,22 +596,31 @@ msgid "Defense activities"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_edi_format__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_product__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_template__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_currency_rate__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_partner__display_name
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_uom_uom__display_name
msgid "Display Name"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Document Canceled"
msgid "Document Cancelled"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_uuid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_uuid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_uuid
msgid "Document UUID"
msgstr ""
@ -624,6 +634,11 @@ msgstr ""
msgid "ETA"
msgstr ""
#. module: l10n_eg_edi_eta
#: model_terms:ir.ui.view,arch_db:l10n_eg_edi_eta.res_config_settings_view_form
msgid "ETA API Integration"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__l10n_eg_activity_type_id
msgid "ETA Activity Code"
@ -673,6 +688,24 @@ msgstr ""
msgid "ETA Item code"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_eta_json_doc_file
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_eta_json_doc_file
msgid "ETA JSON Document"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_long_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_long_id
msgid "ETA Long ID"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_qr_code
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_qr_code
msgid "ETA QR Code"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__l10n_eg_client_secret
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__l10n_eg_client_secret
@ -700,14 +733,14 @@ msgid "ETA code for the unit of measures"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "ETA invoice has been received"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "ETA_INVOICE_DOC_%s"
msgstr ""
@ -728,8 +761,8 @@ msgid "Egyptian Electronic Invoicing"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Egyptian Tax authority JSON invoice generated for %s."
msgstr ""
@ -790,18 +823,14 @@ msgid "Errand stamp"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Error trying to connect to Odoo. Check your internet connection"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Error trying to connect to the middleware. Is the middleware running?"
msgstr ""
@ -1050,9 +1079,19 @@ msgid "Hydraulic Horse Power"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_edi_format__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_journal__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_product__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_product_template__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_company__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_config_settings__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_currency_rate__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_res_partner__id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_uom_uom__id
msgid "ID"
msgstr ""
@ -1243,17 +1282,9 @@ msgstr ""
msgid "Kilowatt ( KW )"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_eta_json_doc_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_eta_json_doc_id
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_eta_json_doc_id
msgid "L10N Eg Eta Json Doc"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_is_signed
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_is_signed
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_is_signed
msgid "L10N Eg Is Signed"
msgstr ""
@ -1262,13 +1293,6 @@ msgstr ""
msgid "Land transportation of goods by bus"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type____last_update
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive____last_update
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_uom_code____last_update
msgid "Last Modified on"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_activity_type__write_uid
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_l10n_eg_edi_thumb_drive__write_uid
@ -1748,9 +1772,8 @@ msgid "Minute ( min )"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Missing Dependency - If you are using Windows, make sure eps2003csp11.dll is"
" correctly installed. You can download it here: "
@ -1759,9 +1782,8 @@ msgid ""
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Missing library - Please make sure that PyKCS11 is correctly installed on "
"the local proxy server"
@ -1783,9 +1805,8 @@ msgid "Motion picture, video and television program distribution activities"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid ""
"Multiple drive detected - Only one secure thumb drive can be inserted at the"
" same time"
@ -1813,9 +1834,8 @@ msgid "Nanometer ( nm )"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "No drive found - Make sure the thumb drive is correctly inserted"
msgstr ""
@ -2064,8 +2084,8 @@ msgid "Ounce ( oz )"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "PDF Document is not available"
msgstr ""
@ -2142,89 +2162,89 @@ msgid "Plastics industry in its primary forms and synthetic rubber"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please add all the required fields in the branch details"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please add all the required fields in the customer details"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please configure the API domain from the system parameters"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please configure the token domain from the system parameters"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/eta_thumb_drive.py:0
#, python-format
msgid "Please define the host of sign tool."
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/res_currency_rate.py:0
#, python-format
msgid ""
"Please make sure that the EGP per unit is within 5 decimal accuracy.\n"
"Higher decimal accuracy might lead to inconsistency with the ETA invoicing portal!"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the EGS/GS1 Barcode is set correctly on all products"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the invoice is signed"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please make sure the invoice lines UoM codes are all set up correctly"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"Please make sure the invoice lines taxes all have the correct ETA tax code"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please only sign invoices from one company at a time"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Please set the all the ETA information on the invoice's journal"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please setup a personal drive for company %s"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_move.py:0
#, python-format
msgid "Please setup the certificate on the thumb drive menu"
msgstr ""
@ -2278,14 +2298,9 @@ msgstr ""
msgid "Processing and spinning of textile fibers"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_product
msgid "Product"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_template
msgid "Product Template"
msgid "Product"
msgstr ""
#. module: l10n_eg_edi_eta
@ -2293,6 +2308,11 @@ msgstr ""
msgid "Product Unit of Measure"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model,name:l10n_eg_edi_eta.model_product_product
msgid "Product Variant"
msgstr ""
#. module: l10n_eg_edi_eta
#: model:l10n_eg_edi.activity.type,name:l10n_eg_edi_eta.l10n_eg_activity_type_5920
msgid "Production and publishing of sound and music recordings"
@ -2744,7 +2764,6 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_signing_time
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_signing_time
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_signing_time
msgid "Signing Time"
msgstr ""
@ -2838,7 +2857,6 @@ msgstr ""
#. module: l10n_eg_edi_eta
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_bank_statement_line__l10n_eg_submission_number
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_move__l10n_eg_submission_number
#: model:ir.model.fields,field_description:l10n_eg_edi_eta.field_account_payment__l10n_eg_submission_number
msgid "Submission ID"
msgstr ""
@ -2865,9 +2883,8 @@ msgid "Support activities for joint facilities"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "System not supported"
msgstr ""
@ -2969,16 +2986,16 @@ msgid ""
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"This invoice has been marked as invalid by the ETA. Please check the ETA "
"website for more information"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"This invoice has been sent to the ETA, but we are still awaiting validation"
msgstr ""
@ -3074,23 +3091,15 @@ msgid "Treatment and disposal of non-hazardous waste"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Unauthorized"
msgstr ""
#. module: l10n_eg_edi_eta
#. openerp-web
#: code:addons/l10n_eg_edi_eta/static/src/js/sign_invoice.js:0
#, python-format
msgid "Unexpected error:"
msgstr ""
#. module: l10n_eg_edi_eta
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "Unknown error"
#. odoo-javascript
#: code:addons/l10n_eg_edi_eta/static/src/client_action/sign_invoice.js:0
msgid "Unexpected error: “%s”"
msgstr ""
#. module: l10n_eg_edi_eta
@ -3114,8 +3123,8 @@ msgid "Volt ( V )"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/res_currency_rate.py:0
#, python-format
msgid "Warning for %s"
msgstr ""
@ -3266,8 +3275,8 @@ msgid "You can only have one thumb drive per user per company!"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid ""
"You cannot issue an invoice to a partner with the same VAT number as the "
"branch."
@ -3279,15 +3288,14 @@ msgid "ZIP"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "an Unknown error has occured"
msgstr ""
#. module: l10n_eg_edi_eta
#. odoo-python
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#: code:addons/l10n_eg_edi_eta/models/account_edi_format.py:0
#, python-format
msgid "an Unknown error has occurred"
msgstr ""

View file

@ -2,13 +2,14 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import json
import logging
import requests
from werkzeug.urls import url_quote
from base64 import b64encode
from json import JSONDecodeError
from odoo.addons.account.tools import LegacyHTTPAdapter
from json.decoder import JSONDecodeError
from odoo import api, models, _
from odoo.tools.float_utils import json_float_round
@ -67,7 +68,18 @@ class AccountEdiFormat(models.Model):
'error': response_data.get('error'),
'blocking_level': 'error'
}
return {'response': request_response}
try:
response_data = request_response.json()
except requests.exceptions.JSONDecodeError:
response_data = {}
return {
'response': str(request_response),
'ok': request_response.ok,
'content': request_response.content,
'data': response_data,
}
@api.model
def _l10n_eg_edi_round(self, amount, precision_digits=5):
@ -82,7 +94,7 @@ class AccountEdiFormat(models.Model):
access_data = self._l10n_eg_eta_get_access_token(invoice)
if access_data.get('error'):
return access_data
invoice_json = json.loads(invoice.l10n_eg_eta_json_doc_id.raw)
invoice_json = json.loads(base64.b64decode(invoice.l10n_eg_eta_json_doc_file))
request_url = '/api/v1.0/documentsubmissions'
request_data = {
'body': json.dumps({'documents': [invoice_json['request']]}, ensure_ascii=False, indent=4).encode('utf-8'),
@ -91,7 +103,7 @@ class AccountEdiFormat(models.Model):
response_data = self._l10n_eg_eta_connect_to_server(request_data, request_url, 'POST', production_enviroment=invoice.company_id.l10n_eg_production_env)
if response_data.get('error'):
return response_data
response_data = response_data.get('response').json()
response_data = response_data.get('data')
if response_data.get('rejectedDocuments', False) and isinstance(response_data.get('rejectedDocuments'), list):
return {
'error': str(response_data.get('rejectedDocuments')[0].get('error')),
@ -105,8 +117,14 @@ class AccountEdiFormat(models.Model):
'l10n_eg_hash_key': response_data['acceptedDocuments'][0].get('hashKey'),
'l10n_eg_submission_number': response_data['submissionId'],
}
invoice.l10n_eg_eta_json_doc_id.raw = json.dumps(invoice_json)
return {'attachment': invoice.l10n_eg_eta_json_doc_id}
invoice.l10n_eg_eta_json_doc_file = base64.b64encode(json.dumps(invoice_json).encode())
invoice.invalidate_recordset(fnames=['l10n_eg_eta_json_doc_file'])
json_doc_attachment_id = self.env['ir.attachment'].search([
('res_model', '=', invoice._name),
('res_id', '=', invoice.id),
('res_field', '=', 'l10n_eg_eta_json_doc_file'),
])
return {'attachment': json_doc_attachment_id}
return {
'error': _('an Unknown error has occurred'),
'blocking_level': 'warning'
@ -130,7 +148,7 @@ class AccountEdiFormat(models.Model):
response_data = self._l10n_eg_eta_connect_to_server(request_data, request_url, 'PUT', production_enviroment=invoice.company_id.l10n_eg_production_env)
if response_data.get('error'):
return response_data
if response_data.get('response').ok:
if response_data.get('ok'):
return {'success': True}
return {
'error': _('an Unknown error has occurred'),
@ -150,7 +168,7 @@ class AccountEdiFormat(models.Model):
response_data = self._l10n_eg_eta_connect_to_server(request_data, request_url, 'GET', production_enviroment=invoice.company_id.l10n_eg_production_env)
if response_data.get('error'):
return response_data
response_data = response_data.get('response').json()
response_data = response_data.get('data')
document_summary = [doc for doc in response_data.get('documentSummary', []) if doc.get('uuid') == invoice.l10n_eg_uuid]
return {'doc_data': document_summary}
@ -167,7 +185,7 @@ class AccountEdiFormat(models.Model):
'blocking_level': 'info'
},
'Valid': {'success': True},
'Cancelled': {'error': _('Document Canceled'), 'blocking_level': 'error'},
'Cancelled': {'error': _('Document Cancelled'), 'blocking_level': 'error'},
}
if document_summary.get('doc_data') and return_dict.get(document_summary['doc_data'][0].get('status')):
return return_dict.get(document_summary['doc_data'][0]['status'])
@ -183,7 +201,7 @@ class AccountEdiFormat(models.Model):
response_data = self._l10n_eg_eta_connect_to_server(request_data, request_url, 'POST', is_access_token_req=True, production_enviroment=invoice.company_id.l10n_eg_production_env)
if response_data.get('error'):
return response_data
return {'access_token' : response_data.get('response').json().get('access_token')}
return {'access_token': response_data.get('data').get('access_token')}
@api.model
def _l10n_eg_get_eta_invoice_pdf(self, invoice):
@ -195,12 +213,10 @@ class AccountEdiFormat(models.Model):
response_data = self._l10n_eg_eta_connect_to_server(request_data, request_url, 'GET', production_enviroment=invoice.company_id.l10n_eg_production_env)
if response_data.get('error'):
return response_data
response_data = response_data.get('response')
_logger.warning('PDF Function Response %s.', response_data)
if response_data.ok:
return {'data': response_data.content}
else:
return {'error': _('PDF Document is not available')}
_logger.warning('PDF Function Response %s.', response_data.get('response'))
if response_data.get('ok'):
return {'data': response_data.get('content')}
return {'error': _('PDF Document is not available')}
@api.model
def _l10n_eg_validate_info_address(self, partner_id, issuer=False, invoice=False):
@ -213,14 +229,51 @@ class AccountEdiFormat(models.Model):
@api.model
def _l10n_eg_eta_prepare_eta_invoice(self, invoice):
AccountTax = self.env['account.tax']
base_amls = invoice.line_ids.filtered(lambda x: x.display_type == 'product')
base_lines = [invoice._prepare_product_base_line_for_taxes_computation(x) for x in base_amls]
tax_amls = invoice.line_ids.filtered('tax_repartition_line_id')
tax_lines = [invoice._prepare_tax_line_for_taxes_computation(x) for x in tax_amls]
AccountTax._add_tax_details_in_base_lines(base_lines, invoice.company_id)
AccountTax._round_base_lines_tax_details(base_lines, invoice.company_id, tax_lines=tax_lines)
def group_tax_retention(base_line, tax_values):
tax = tax_values['tax_repartition_line'].tax_id
return {'l10n_eg_eta_code': tax.l10n_eg_eta_code.split('_')[0]}
# Tax amounts per line.
def grouping_function_base_line(base_line, tax_data):
if not tax_data:
return None
tax = tax_data['tax']
code_split = tax.l10n_eg_eta_code.split('_')
return {
'rate': abs(tax.amount) if tax.amount_type != 'fixed' else 0,
'tax_type': code_split[0].upper(),
'sub_type': code_split[1].upper(),
}
base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, grouping_function_base_line)
invoice_line_data, totals = self._l10n_eg_eta_prepare_invoice_lines_data(invoice, base_lines_aggregated_values)
# Tax amounts for the whole document.
def grouping_function_global(base_line, tax_data):
if not tax_data:
return None
tax = tax_data['tax']
code_split = tax.l10n_eg_eta_code.split('_')
return {
'tax_type': code_split[0].upper(),
}
def grouping_function_total_amount(base_line, tax_data):
return True if tax_data else None
base_lines_aggregated_values_total_amount = AccountTax._aggregate_base_lines_tax_details(base_lines, grouping_function_total_amount)
values_per_grouping_key_total_amount = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values_total_amount)
base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, grouping_function_global)
values_per_grouping_key = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values)
date_string = invoice.invoice_date.strftime('%Y-%m-%dT%H:%M:%SZ')
grouped_taxes = invoice._prepare_edi_tax_details(grouping_key_generator=group_tax_retention)
invoice_line_data, totals = self._l10n_eg_eta_prepare_invoice_lines_data(invoice, grouped_taxes['tax_details_per_record'])
eta_invoice = {
'issuer': self._l10n_eg_eta_prepare_address_data(invoice.journal_id.l10n_eg_branch_id, invoice, issuer=True,),
'receiver': self._l10n_eg_eta_prepare_address_data(invoice.partner_id, invoice),
@ -232,14 +285,18 @@ class AccountEdiFormat(models.Model):
}
eta_invoice.update({
'invoiceLines': invoice_line_data,
'taxTotals': [{
'taxType': tax['l10n_eg_eta_code'].split('_')[0].upper(),
'amount': self._l10n_eg_edi_round(abs(tax['tax_amount'])),
} for tax in grouped_taxes['tax_details'].values()],
'taxTotals': [
{
'taxType': grouping_key['tax_type'],
'amount': self._l10n_eg_edi_round(abs(tax_values['tax_amount'])),
}
for grouping_key, tax_values in values_per_grouping_key.items()
if grouping_key
],
'totalDiscountAmount': self._l10n_eg_edi_round(totals['discount_total']),
'totalSalesAmount': self._l10n_eg_edi_round(totals['total_price_subtotal_before_discount']),
'netAmount': self._l10n_eg_edi_round(abs(invoice.amount_untaxed_signed)),
'totalAmount': self._l10n_eg_edi_round(abs(invoice.amount_total_signed)),
'netAmount': self._l10n_eg_edi_round(sum(x['base_amount'] for x in values_per_grouping_key_total_amount.values())),
'totalAmount': self._l10n_eg_edi_round(sum(x['base_amount'] + x['tax_amount'] for x in values_per_grouping_key_total_amount.values())),
'extraDiscountAmount': 0.0,
'totalItemsDiscountAmount': 0.0,
})
@ -250,14 +307,15 @@ class AccountEdiFormat(models.Model):
return eta_invoice
@api.model
def _l10n_eg_eta_prepare_invoice_lines_data(self, invoice, tax_data):
def _l10n_eg_eta_prepare_invoice_lines_data(self, invoice, base_lines_aggregated_values):
lines = []
totals = {
'discount_total': 0.0,
'total_price_subtotal_before_discount' : 0.0,
}
for line in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_note', 'line_section')):
line_tax_details = tax_data.get(line, {})
for base_line, aggregated_values in base_lines_aggregated_values:
line = base_line['record']
tax_details = base_line['tax_details']
price_unit = self._l10n_eg_edi_round(abs((line.balance / line.quantity) / (1 - (line.discount / 100.0)))) if line.quantity and line.discount != 100.0 else line.price_unit
price_subtotal_before_discount = self._l10n_eg_edi_round(abs(line.balance / (1 - (line.discount / 100)))) if line.discount != 100.0 else self._l10n_eg_edi_round(price_unit * line.quantity)
discount_amount = self._l10n_eg_edi_round(price_subtotal_before_discount - abs(line.balance))
@ -282,16 +340,17 @@ class AccountEdiFormat(models.Model):
},
'taxableItems': [
{
'taxType': tax['tax_repartition_line'].tax_id.l10n_eg_eta_code.split('_')[0].upper().upper(),
'amount': self._l10n_eg_edi_round(abs(tax['tax_amount'])),
'subType': tax['tax_repartition_line'].tax_id.l10n_eg_eta_code.split('_')[1].upper(),
**({'rate': abs(tax['tax_repartition_line'].tax_id.amount)} if tax['tax_repartition_line'].tax_id.amount_type != 'fixed' else {}),
'taxType': grouping_key['tax_type'],
'amount': self._l10n_eg_edi_round(abs(tax_values['tax_amount'])),
'subType': grouping_key['sub_type'],
'rate': grouping_key['rate'],
}
for tax_details in line_tax_details.get('tax_details', {}).values() for tax in tax_details.get('group_tax_details')
for grouping_key, tax_values in aggregated_values.items()
if grouping_key
],
'salesTotal': price_subtotal_before_discount,
'netTotal': self._l10n_eg_edi_round(abs(line.balance)),
'total': self._l10n_eg_edi_round(abs(line.balance) + line_tax_details.get('tax_amount', 0.0)),
'netTotal': self._l10n_eg_edi_round(tax_details['total_excluded'] + tax_details['delta_total_excluded']),
'total': self._l10n_eg_edi_round(tax_details['total_included']),
})
totals['discount_total'] += discount_amount
totals['total_price_subtotal_before_discount'] += price_subtotal_before_discount
@ -367,11 +426,11 @@ class AccountEdiFormat(models.Model):
errors.append(_("Please add all the required fields in the branch details"))
if not self._l10n_eg_validate_info_address(invoice.partner_id, invoice=invoice):
errors.append(_("Please add all the required fields in the customer details"))
if not all(aml.product_uom_id.l10n_eg_unit_code_id.code for aml in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_note', 'line_section'))):
if not all(aml.product_uom_id.l10n_eg_unit_code_id.code for aml in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_section', 'line_subsection', 'line_note'))):
errors.append(_("Please make sure the invoice lines UoM codes are all set up correctly"))
if not all(tax.l10n_eg_eta_code for tax in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_note', 'line_section')).tax_ids):
if not all(tax.l10n_eg_eta_code for tax in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_section', 'line_subsection', 'line_note')).tax_ids):
errors.append(_("Please make sure the invoice lines taxes all have the correct ETA tax code"))
if not all(aml.product_id.l10n_eg_eta_code or aml.product_id.barcode for aml in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_note', 'line_section'))):
if not all(aml.product_id.l10n_eg_eta_code or aml.product_id.barcode for aml in invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_section', 'line_subsection', 'line_note'))):
errors.append(_("Please make sure the EGS/GS1 Barcode is set correctly on all products"))
return errors
@ -380,14 +439,14 @@ class AccountEdiFormat(models.Model):
if invoice.l10n_eg_submission_number:
return {invoice: self._l10n_eg_get_einvoice_status(invoice)}
if not invoice.l10n_eg_eta_json_doc_id:
if not invoice.l10n_eg_eta_json_doc_file:
return {
invoice: {
'error': _("An error occured in created the ETA invoice, please retry signing"),
'blocking_level': 'error'
}
}
invoice_json = json.loads(invoice.l10n_eg_eta_json_doc_id.raw)['request']
invoice_json = json.loads(base64.b64decode(invoice.l10n_eg_eta_json_doc_file))['request']
if not invoice_json.get('signatures'):
return {
invoice: {

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import logging
import json
@ -19,7 +20,11 @@ class AccountMove(models.Model):
l10n_eg_qr_code = fields.Char(string='ETA QR Code', compute='_compute_eta_qr_code_str')
l10n_eg_submission_number = fields.Char(string='Submission ID', compute='_compute_eta_response_data', store=True, copy=False)
l10n_eg_uuid = fields.Char(string='Document UUID', compute='_compute_eta_response_data', store=True, copy=False)
l10n_eg_eta_json_doc_id = fields.Many2one('ir.attachment', copy=False)
l10n_eg_eta_json_doc_file = fields.Binary(
string='ETA JSON Document',
attachment=True,
copy=False,
)
l10n_eg_signing_time = fields.Datetime('Signing Time', copy=False)
l10n_eg_is_signed = fields.Boolean(copy=False)
@ -30,10 +35,10 @@ class AccountMove(models.Model):
create_column(self.env.cr, "account_move", "l10n_eg_submission_number", "VARCHAR")
return super()._auto_init()
@api.depends('l10n_eg_eta_json_doc_id.raw')
@api.depends('l10n_eg_eta_json_doc_file')
def _compute_eta_long_id(self):
for rec in self:
response_data = rec.l10n_eg_eta_json_doc_id and json.loads(rec.l10n_eg_eta_json_doc_id.raw).get('response')
response_data = rec.l10n_eg_eta_json_doc_file and json.loads(base64.b64decode(rec.l10n_eg_eta_json_doc_file)).get('response')
if response_data:
rec.l10n_eg_long_id = response_data.get('l10n_eg_long_id')
else:
@ -50,10 +55,10 @@ class AccountMove(models.Model):
else:
move.l10n_eg_qr_code = ''
@api.depends('l10n_eg_eta_json_doc_id.raw')
@api.depends('l10n_eg_eta_json_doc_file')
def _compute_eta_response_data(self):
for rec in self:
response_data = rec.l10n_eg_eta_json_doc_id and json.loads(rec.l10n_eg_eta_json_doc_id.raw).get('response')
response_data = rec.l10n_eg_eta_json_doc_file and json.loads(base64.b64decode(rec.l10n_eg_eta_json_doc_file)).get('response')
if response_data:
rec.l10n_eg_uuid = response_data.get('l10n_eg_uuid')
rec.l10n_eg_submission_number = response_data.get('l10n_eg_submission_number')
@ -61,8 +66,12 @@ class AccountMove(models.Model):
rec.l10n_eg_uuid = False
rec.l10n_eg_submission_number = False
def _get_fields_to_detach(self):
fields_list = super()._get_fields_to_detach()
fields_list.append('l10n_eg_eta_json_doc_file')
return fields_list
def button_draft(self):
self.l10n_eg_eta_json_doc_id = False
self.l10n_eg_is_signed = False
return super().button_draft()
@ -91,16 +100,17 @@ class AccountMove(models.Model):
for invoice in invoices:
eta_invoice = self.env['account.edi.format']._l10n_eg_eta_prepare_eta_invoice(invoice)
attachment = self.env['ir.attachment'].create({
self.env['ir.attachment'].create({
'name': _('ETA_INVOICE_DOC_%s', invoice.name),
'res_id': invoice.id,
'res_model': invoice._name,
'res_field': 'l10n_eg_eta_json_doc_file',
'type': 'binary',
'raw': json.dumps(dict(request=eta_invoice)),
'mimetype': 'application/json',
'description': _('Egyptian Tax authority JSON invoice generated for %s.', invoice.name),
})
invoice.l10n_eg_eta_json_doc_id = attachment.id
invoice.invalidate_recordset(fnames=['l10n_eg_eta_json_doc_file'])
return drive_id.action_sign_invoices(invoices)
def action_get_eta_invoice_pdf(self):
@ -111,9 +121,10 @@ class AccountMove(models.Model):
if eta_invoice_pdf.get('error', False):
_logger.warning('PDF Content Error: %s.', eta_invoice_pdf.get('error'))
return
self.with_context(no_new_invoice=True).message_post(body=_('ETA invoice has been received'),
attachments=[('ETA invoice of %s.pdf' % self.name,
eta_invoice_pdf.get('data'))])
self.message_post(
body=_('ETA invoice has been received'),
attachments=[('ETA invoice of %s.pdf' % self.name, eta_invoice_pdf.get('data'))]
)
def _l10n_eg_edi_exchange_currency_rate(self):
""" Calculate the rate based on the balance and amount_currency, so we recuperate the one used at the time"""

View file

@ -2,22 +2,14 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api
from odoo.osv import expression
from odoo import fields, models
class EtaActivityType(models.Model):
class L10n_Eg_EdiActivityType(models.Model):
_name = 'l10n_eg_edi.activity.type'
_description = 'ETA code for activity type'
_rec_name = 'name'
_rec_names_search = ['name', 'code']
name = fields.Char(required=True, translate=True)
code = fields.Char(required=True)
@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if operator == 'ilike' and not(name or '').strip():
domain = []
else:
domain = ['|', ('name', operator, name), ('code', operator, name)]
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)

View file

@ -12,7 +12,7 @@ from odoo import models, fields, _
from odoo.exceptions import ValidationError
class EtaThumbDrive(models.Model):
class L10n_Eg_EdiThumbDrive(models.Model):
_name = 'l10n_eg_edi.thumb.drive'
_description = 'Thumb drive used to sign invoices in Egypt'
@ -22,9 +22,10 @@ class EtaThumbDrive(models.Model):
pin = fields.Char('ETA USB Pin', required=True)
access_token = fields.Char(required=True)
_sql_constraints = [
('user_drive_uniq', 'unique (user_id, company_id)', 'You can only have one thumb drive per user per company!'),
]
_user_drive_uniq = models.Constraint(
'unique (user_id, company_id)',
'You can only have one thumb drive per user per company!',
)
def action_sign_invoices(self, invoice_ids):
self.ensure_one()
@ -32,7 +33,7 @@ class EtaThumbDrive(models.Model):
to_sign_dict = dict()
for invoice_id in invoice_ids:
eta_invoice = json.loads(invoice_id.l10n_eg_eta_json_doc_id.raw)['request']
eta_invoice = json.loads(base64.b64decode(invoice_id.l10n_eg_eta_json_doc_file))['request']
signed_attrs = self._generate_signed_attrs__(eta_invoice, invoice_id.l10n_eg_signing_time)
to_sign_dict[invoice_id.id] = base64.b64encode(signed_attrs.dump()).decode()
@ -74,13 +75,13 @@ class EtaThumbDrive(models.Model):
invoices = json.loads(invoices)
for key, value in invoices.items():
invoice_id = self.env['account.move'].browse(int(key))
eta_invoice_json = json.loads(invoice_id.l10n_eg_eta_json_doc_id.raw)
eta_invoice_json = json.loads(base64.b64decode(invoice_id.l10n_eg_eta_json_doc_file))
signature = self._generate_cades_bes_signature(eta_invoice_json['request'], invoice_id.l10n_eg_signing_time,
base64.b64decode(value))
eta_invoice_json['request']['signatures'] = [{'signatureType': 'I', 'value': signature}]
invoice_id.l10n_eg_eta_json_doc_id.raw = json.dumps(eta_invoice_json)
invoice_id.l10n_eg_eta_json_doc_file = base64.b64encode(json.dumps(eta_invoice_json).encode())
invoice_id.l10n_eg_is_signed = True
return True

View file

@ -1,5 +1,6 @@
from odoo import models, fields
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'

View file

@ -4,7 +4,7 @@
from odoo import models, fields
class UomCode(models.Model):
class L10n_Eg_EdiUomCode(models.Model):
_name = 'l10n_eg_edi.uom.code'
_description = 'ETA code for the unit of measures'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -0,0 +1,73 @@
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
async function actionGetDrive(env, action, type) {
const { drive_id, sign_host: host } = action.params;
const { orm, http, dialog, action: actionService } = env.services;
let route = host;
let key, method;
if (type === "certificate") {
route += "/hw_l10n_eg_eta/certificate";
method = "set_certificate";
key = "certificate";
} else if (type === "sign") {
route += "/hw_l10n_eg_eta/sign";
method = "set_signature_data";
key = "invoices";
}
let result;
try {
result = await http.post(route, action.params);
} catch {
dialog.add(AlertDialog, {
body: _t("Error trying to connect to the middleware. Is the middleware running?"),
});
return;
}
if (result.error) {
const typeToErrorMessage = {
no_pykcs11: _t(
"Missing library - Please make sure that PyKCS11 is correctly installed on the local proxy server"
),
missing_dll: _t(
"Missing Dependency - If you are using Windows, make sure eps2003csp11.dll is correctly installed. You can download it here: https://www.egypttrust.com/en/downloads/other-drivers. If you are using Linux or macOS, please install OpenSC"
),
no_drive: _t("No drive found - Make sure the thumb drive is correctly inserted"),
multiple_drive: _t(
"Multiple drive detected - Only one secure thumb drive can be inserted at the same time"
),
system_unsupported: _t("System not supported"),
unauthorized: _t("Unauthorized"),
};
dialog.add(AlertDialog, {
body: typeToErrorMessage[result.error] || _t("Unexpected error: “%s”", result.error),
});
} else if (result[key]) {
await orm.call("l10n_eg_edi.thumb.drive", method, [[drive_id], result[key]]).catch(() => {
dialog.add(AlertDialog, {
body: _t("Error trying to connect to Odoo. Check your internet connection"),
});
});
actionService.doAction({
type: "ir.actions.client",
tag: "reload",
});
} else {
dialog.add(AlertDialog, {
body: _t("An unexpected error has occurred"),
});
}
}
registry
.category("actions")
.add("action_get_drive_certificate", (env, action) =>
actionGetDrive(env, action, "certificate")
);
registry
.category("actions")
.add("action_post_sign_invoice", (env, action) => actionGetDrive(env, action, "sign"));

View file

@ -1,87 +0,0 @@
odoo.define('l10n_eg_edi_eta.action_post_sign_invoice', function (require) {
const core = require('web.core');
const ajax = require('web.ajax');
const Dialog = require('web.Dialog');
var rpc = require('web.rpc');
var _t = core._t;
function get_drive_error(value) {
switch(value) {
case 'no_pykcs11': return _t("Missing library - Please make sure that PyKCS11 is correctly installed on the local proxy server");
case 'missing_dll': return _t("Missing Dependency - If you are using Windows, make sure eps2003csp11.dll is correctly installed. You can download it here: https://www.egypttrust.com/en/downloads/other-drivers. If you are using Linux or macOS, please install OpenSC");
case 'no_drive': return _t("No drive found - Make sure the thumb drive is correctly inserted");
case 'multiple_drive': return _t("Multiple drive detected - Only one secure thumb drive can be inserted at the same time");
case 'system_unsupported': return _t("System not supported");
case 'unauthorized': return _t("Unauthorized");
}
return _t("Unexpected error:") + value;
}
async function action_get_drive_certificate(parent, {params}) {
const host = params.sign_host;
const drive_id = params.drive_id;
delete params.sign_host;
delete params.drive_id;
await ajax.post(host + '/hw_l10n_eg_eta/certificate', params).then(function (res) {
const res_obj = JSON.parse(res);
if (res_obj.error) {
Dialog.alert(this, get_drive_error(res_obj.error));
} else if (res_obj.certificate) {
rpc.query({
model: 'l10n_eg_edi.thumb.drive',
method: 'set_certificate',
args: [[drive_id], res_obj.certificate],
}).then(function () {
parent.services.action.doAction({
'type': 'ir.actions.client',
'tag': 'reload',
});
}, function () {
Dialog.alert(this, _t("Error trying to connect to Odoo. Check your internet connection"));
})
} else {
Dialog.alert(this, _t('An unexpected error has occurred'));
}
}, function () {
Dialog.alert(this, _t("Error trying to connect to the middleware. Is the middleware running?"));
})
}
async function action_post_sign_invoice(parent, {params}) {
const host = params.sign_host;
const drive_id = params.drive_id;
delete params.sign_host;
delete params.drive_id;
await ajax.post(host + '/hw_l10n_eg_eta/sign', params).then(function (res) {
const res_obj = JSON.parse(res);
if (res_obj.error) {
Dialog.alert(this, get_drive_error(res_obj.error));
} else if (res_obj.invoices) {
rpc.query({
model: 'l10n_eg_edi.thumb.drive',
method: 'set_signature_data',
args: [[drive_id], res_obj.invoices],
}).then(function () {
parent.services.action.doAction({
'type': 'ir.actions.client',
'tag': 'reload',
});
}, function () {
Dialog.alert(this, _t("Error trying to connect to Odoo. Check your internet connection"));
})
} else {
Dialog.alert(this, _t('An unexpected error has occurred'));
}
}, function () {
Dialog.alert(this, _t("Error trying to connect to the middleware. Is the middleware running?"));
})
}
core.action_registry.add('action_get_drive_certificate', action_get_drive_certificate);
core.action_registry.add('action_post_sign_invoice', action_post_sign_invoice);
return action_post_sign_invoice;
});

View file

@ -9,31 +9,28 @@ from odoo.addons.account_edi.tests.common import AccountEdiTestCommon
class TestEGEdiCommon(AccountEdiTestCommon):
@classmethod
def setUpClass(cls, chart_template_ref='l10n_eg.egypt_chart_template_standard', edi_format_ref='l10n_eg_edi_eta.edi_eg_eta'):
super().setUpClass(chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref)
@AccountEdiTestCommon.setup_edi_format('l10n_eg_edi_eta.edi_eg_eta')
@AccountEdiTestCommon.setup_country('eg')
def setUpClass(cls):
super().setUpClass()
cls.frozen_today = datetime(year=2022, month=3, day=15, hour=0, minute=0, second=0, tzinfo=timezone('utc'))
cls.currency_aed_id = cls.env.ref('base.AED')
cls.currency_aed_id.write({'active': True})
cls.env['res.currency.rate'].search([]).unlink()
cls.env['res.currency.rate'].create({'currency_id': cls.currency_aed_id.id,
'rate': 0.198117095128, 'name': '2022-03-15'})
cls.currency_aed_id = cls.setup_other_currency('AED', rates=[('2022-03-15', 0.198117095128)])
# Allow to see the full result of AssertionError.
cls.maxDiff = None
cls.company_data['company'].write({
'country_id': cls.env.ref('base.eg').id,
'l10n_eg_client_identifier': 'ahuh1pojnbakKK',
'l10n_eg_client_secret': '1ashiqwhejmasn197',
'vat': 'EG1103143170L',
'vat': '123-456-789',
})
# ==== Business ====
cls.partner_a.write({
'vat': 'BE0477472701',
'vat': '123456789',
'country_id': cls.env.ref('base.eg').id,
'city': 'Iswan',
'state_id': cls.env.ref('base.state_eg_c').id,
@ -52,7 +49,7 @@ class TestEGEdiCommon(AccountEdiTestCommon):
})
cls.partner_c = cls.env['res.partner'].create({
'name': 'عميل 1',
'vat': 'EG11231212',
'vat': '123456789',
'country_id': cls.env.ref('base.eg').id,
'city': 'Iswan',
'state_id': cls.env.ref('base.state_eg_c').id,
@ -68,7 +65,7 @@ class TestEGEdiCommon(AccountEdiTestCommon):
})
cls.company_branch = cls.env['res.partner'].create({
'name': 'branch partner',
'vat': '918KKL1',
'vat': '456789123',
'country_id': cls.env.ref('base.eg').id,
'city': 'Iswan',
'state_id': cls.env.ref('base.state_eg_c').id,
@ -84,7 +81,7 @@ class TestEGEdiCommon(AccountEdiTestCommon):
@classmethod
def _get_tax_by_xml_id(cls, trailing_xml_id):
return cls.env.ref(f'l10n_es.{cls.env.company.id}_account_tax_template_{trailing_xml_id}')
return cls.env.ref(f'account.{cls.env.company.id}_account_tax_template_{trailing_xml_id}')
@classmethod
def create_invoice(cls, **kwargs):

View file

@ -1,9 +1,12 @@
import base64
import json
from unittest.mock import patch
from freezegun import freeze_time
from odoo import Command
from odoo.tests import tagged
from odoo import Command
from .common import TestEGEdiCommon
@ -28,7 +31,7 @@ COMMON_REQUEST_DICT = {
},
'name': 'branch partner',
'type': 'B',
'id': '918KKL1',
'id': '456789123',
},
'documentType': 'i',
'documentTypeVersion': '1.0',
@ -45,26 +48,33 @@ def mocked_action_post_sign_invoices(self):
for invoice in self:
eta_invoice = self.env['account.edi.format']._l10n_eg_eta_prepare_eta_invoice(self)
eta_invoice['signatures'] = ETA_TEST_SIGNATURES
attachment = self.env['ir.attachment'].create(
self.env['ir.attachment'].create(
{
'name': ('ETA_INVOICE_DOC_%s', invoice.name),
'res_id': invoice.id,
'res_model': invoice._name,
'res_field': 'l10n_eg_eta_json_doc_file',
'type': 'binary',
'raw': json.dumps(dict(request=eta_invoice)),
'mimetype': 'application/json',
'description': ('Egyptian Tax authority JSON invoice generated for %s.', invoice.name),
}
},
)
invoice.l10n_eg_eta_json_doc_id = attachment.id
invoice.invalidate_recordset(fnames=['l10n_eg_eta_json_doc_file'])
return True
def mocked_l10n_eg_edi_post_invoice_web_service(self, invoice):
eta_invoice_json = json.loads(invoice.l10n_eg_eta_json_doc_id.raw)
eta_invoice_json = json.loads(base64.b64decode(invoice.l10n_eg_eta_json_doc_file))
eta_invoice_json['response'] = ETA_TEST_RESPONSE
invoice.l10n_eg_eta_json_doc_id.raw = json.dumps(eta_invoice_json)
return {'success': True, 'attachment': invoice.l10n_eg_eta_json_doc_id}
invoice.l10n_eg_eta_json_doc_file = base64.b64encode(json.dumps(eta_invoice_json).encode())
invoice.invalidate_recordset(fnames=['l10n_eg_eta_json_doc_file'])
json_doc_attachment_id = self.env['ir.attachment'].search([
('res_model', '=', invoice._name),
('res_id', '=', invoice.id),
('res_field', '=', 'l10n_eg_eta_json_doc_file'),
])
return {'success': True, 'attachment': json_doc_attachment_id}
@tagged('post_install_l10n', 'post_install', '-at_install')
@ -116,7 +126,7 @@ class TestEdiJson(TestEGEdiCommon):
},
'name': 'partner_a',
'type': 'B',
'id': 'BE0477472701',
'id': '123456789',
},
'invoiceLines': [
{
@ -179,14 +189,14 @@ class TestEdiJson(TestEGEdiCommon):
'price_unit': 120.99,
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids)],
},
{
'product_id': self.product_a.id,
'price_unit': 999.99,
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids)],
},
],
)
@ -211,7 +221,7 @@ class TestEdiJson(TestEGEdiCommon):
},
'name': 'partner_a',
'type': 'B',
'id': 'BE0477472701',
'id': '123456789',
},
'invoiceLines': [
{
@ -276,7 +286,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids)],
},
{
'product_id': self.product_a.id,
@ -284,7 +294,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'discount': 10.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids)],
},
],
)
@ -309,7 +319,7 @@ class TestEdiJson(TestEGEdiCommon):
},
'name': 'partner_a',
'type': 'B',
'id': 'BE0477472701',
'id': '123456789',
},
'internalID': 'RINV/2022/00001',
'documentType': 'c',
@ -359,7 +369,7 @@ class TestEdiJson(TestEGEdiCommon):
},
)
def test_4_simple_test_local_parter_vat_14_discount(self):
def test_4_simple_test_local_parter_vat_14_discount_multiple_tax(self):
with freeze_time(self.frozen_today), patch(
'odoo.addons.l10n_eg_edi_eta.models.account_move.AccountMove.action_post_sign_invoices',
new=mocked_action_post_sign_invoices,
@ -367,6 +377,7 @@ class TestEdiJson(TestEGEdiCommon):
'odoo.addons.l10n_eg_edi_eta.models.account_edi_format.AccountEdiFormat._l10n_eg_edi_post_invoice_web_service',
new=mocked_l10n_eg_edi_post_invoice_web_service,
):
ref_eg_standard_sale_14 = self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids
invoice = self.create_invoice(
partner_id=self.partner_a.id,
invoice_line_ids=[
@ -376,7 +387,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [Command.set(ref_eg_standard_sale_14)],
},
{
'product_id': self.product_a.id,
@ -384,7 +395,23 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'discount': 10.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_standard_sale_14').ids)],
'tax_ids': [Command.set(ref_eg_standard_sale_14)],
},
{
'product_id': self.product_a.id,
'price_unit': 100,
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [
Command.set(ref_eg_standard_sale_14),
Command.create({
"amount_type": "fixed",
"amount": 10.0,
"name": "Fixed Tax",
"l10n_eg_eta_code": "t3_tbl02",
}),
],
},
],
)
@ -409,7 +436,7 @@ class TestEdiJson(TestEGEdiCommon):
},
'name': 'partner_a',
'type': 'B',
'id': 'BE0477472701',
'id': '123456789',
},
'documentType': 'i',
'invoiceLines': [
@ -447,12 +474,29 @@ class TestEdiJson(TestEGEdiCommon):
'netTotal': 899.6,
'total': 1025.54,
},
{
'description': 'product_a',
'itemType': 'GS1',
'itemCode': '1KGS1TEST',
'unitType': 'C62',
'quantity': 1.0,
'internalCode': '',
'valueDifference': 0.0,
'totalTaxableFees': 0.0,
'itemsDiscount': 0.0,
'unitValue': {'currencySold': 'EGP', 'amountEGP': 100.0},
'discount': {'rate': 10.0, 'amount': 10.0},
'taxableItems': [{'taxType': 'T1', 'amount': 12.6, 'subType': 'V009', 'rate': 14.0}, {'taxType': 'T3', 'amount': 10.0, 'subType': 'TBL02', 'rate': 0}],
'salesTotal': 100.0,
'netTotal': 90.0,
'total': 112.6,
},
],
'taxTotals': [{'taxType': 'T1', 'amount': 141.18}],
'totalDiscountAmount': 112.05445,
'totalSalesAmount': 1120.54445,
'netAmount': 1008.49,
'totalAmount': 1149.67,
'taxTotals': [{'taxType': 'T1', 'amount': 153.78}, {'taxType': 'T3', 'amount': 10.0}],
'totalDiscountAmount': 122.05445,
'totalSalesAmount': 1220.54445,
'netAmount': 1098.49,
'totalAmount': 1262.27
},
'response': ETA_TEST_RESPONSE,
},
@ -475,7 +519,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
{
'product_id': self.product_b.id,
@ -483,7 +527,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 5.0,
'discount': 13.0,
'product_uom_id': self.env.ref('uom.product_uom_cm').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
],
)
@ -575,7 +619,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
{
'product_id': self.product_b.id,
@ -583,7 +627,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 5.0,
'discount': 13.0,
'product_uom_id': self.env.ref('uom.product_uom_cm').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
],
)
@ -685,7 +729,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
{
'product_id': self.product_b.id,
@ -693,7 +737,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 5.0,
'discount': 13.0,
'product_uom_id': self.env.ref('uom.product_uom_cm').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
],
)
@ -795,7 +839,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'discount': 10.0,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
{
'product_id': self.product_b.id,
@ -803,7 +847,7 @@ class TestEdiJson(TestEGEdiCommon):
'quantity': 5.0,
'discount': 13.0,
'product_uom_id': self.env.ref('uom.product_uom_cm').id,
'tax_ids': [(6, 0, self.env.ref(f'l10n_eg.{self.env.company.id}_eg_exempt_sale').ids)],
'tax_ids': [(6, 0, self.env.ref(f'account.{self.env.company.id}_eg_exempt_sale').ids)],
},
],
)
@ -814,4 +858,78 @@ class TestEdiJson(TestEGEdiCommon):
self.assertTrue(generated_files)
json_file = json.loads(generated_files[0])
serialized_string = self.env['l10n_eg_edi.thumb.drive']._serialize_for_signing(json_file['request'])
self.assertEqual(serialized_string, '"ISSUER""ADDRESS""COUNTRY""EG""GOVERNATE""Cairo""REGIONCITY""Iswan""STREET""12th dec. street""BUILDINGNUMBER""10""POSTALCODE""""BRANCHID""0""NAME""branch partner""TYPE""B""ID""918KKL1""RECEIVER""ADDRESS""COUNTRY""EG""GOVERNATE""Cairo""REGIONCITY""Iswan""STREET""12th dec. street""BUILDINGNUMBER""12""POSTALCODE""""NAME""عميل 1""TYPE""B""ID""EG11231212""DOCUMENTTYPE""i""DOCUMENTTYPEVERSION""1.0""DATETIMEISSUED""2022-03-15T00:00:00Z""TAXPAYERACTIVITYCODE""8121""INTERNALID""INV/2022/00001""INVOICELINES""INVOICELINES""DESCRIPTION""product_a""ITEMTYPE""GS1""ITEMCODE""1KGS1TEST""UNITTYPE""C62""QUANTITY""1.0""INTERNALCODE""""VALUEDIFFERENCE""0.0""TOTALTAXABLEFEES""0.0""ITEMSDISCOUNT""0.0""UNITVALUE""CURRENCYSOLD""AED""AMOUNTEGP""504.75556""CURRENCYEXCHANGERATE""5.04756""AMOUNTSOLD""100.0""DISCOUNT""RATE""10.0""AMOUNT""50.47556""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""0.0""SUBTYPE""V003""RATE""0.0""SALESTOTAL""504.75556""NETTOTAL""454.28""TOTAL""454.28""INVOICELINES""DESCRIPTION""product_b""ITEMTYPE""EGS""ITEMCODE""EG-EGS-TEST""UNITTYPE""CMT""QUANTITY""5.0""INTERNALCODE""""VALUEDIFFERENCE""0.0""TOTALTAXABLEFEES""0.0""ITEMSDISCOUNT""0.0""UNITVALUE""CURRENCYSOLD""AED""AMOUNTEGP""506.51494""CURRENCYEXCHANGERATE""5.04756""AMOUNTSOLD""100.35""DISCOUNT""RATE""13.0""AMOUNT""329.23471""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""0.0""SUBTYPE""V003""RATE""0.0""SALESTOTAL""2532.57471""NETTOTAL""2203.34""TOTAL""2203.34""TAXTOTALS""TAXTOTALS""TAXTYPE""T1""AMOUNT""0.0""TOTALDISCOUNTAMOUNT""379.71027""TOTALSALESAMOUNT""3037.33027""NETAMOUNT""2657.62""TOTALAMOUNT""2657.62""EXTRADISCOUNTAMOUNT""0.0""TOTALITEMSDISCOUNTAMOUNT""0.0""SIGNATURES""SIGNATURES""1""1"')
self.assertEqual(serialized_string, '"ISSUER""ADDRESS""COUNTRY""EG""GOVERNATE""Cairo""REGIONCITY""Iswan""STREET""12th dec. street""BUILDINGNUMBER""10""POSTALCODE""""BRANCHID""0""NAME""branch partner""TYPE""B""ID""456789123""RECEIVER""ADDRESS""COUNTRY""EG""GOVERNATE""Cairo""REGIONCITY""Iswan""STREET""12th dec. street""BUILDINGNUMBER""12""POSTALCODE""""NAME""عميل 1""TYPE""B""ID""123456789""DOCUMENTTYPE""i""DOCUMENTTYPEVERSION""1.0""DATETIMEISSUED""2022-03-15T00:00:00Z""TAXPAYERACTIVITYCODE""8121""INTERNALID""INV/2022/00001""INVOICELINES""INVOICELINES""DESCRIPTION""product_a""ITEMTYPE""GS1""ITEMCODE""1KGS1TEST""UNITTYPE""C62""QUANTITY""1.0""INTERNALCODE""""VALUEDIFFERENCE""0.0""TOTALTAXABLEFEES""0.0""ITEMSDISCOUNT""0.0""UNITVALUE""CURRENCYSOLD""AED""AMOUNTEGP""504.75556""CURRENCYEXCHANGERATE""5.04756""AMOUNTSOLD""100.0""DISCOUNT""RATE""10.0""AMOUNT""50.47556""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""0.0""SUBTYPE""V003""RATE""0.0""SALESTOTAL""504.75556""NETTOTAL""454.28""TOTAL""454.28""INVOICELINES""DESCRIPTION""product_b""ITEMTYPE""EGS""ITEMCODE""EG-EGS-TEST""UNITTYPE""CMT""QUANTITY""5.0""INTERNALCODE""""VALUEDIFFERENCE""0.0""TOTALTAXABLEFEES""0.0""ITEMSDISCOUNT""0.0""UNITVALUE""CURRENCYSOLD""AED""AMOUNTEGP""506.51494""CURRENCYEXCHANGERATE""5.04756""AMOUNTSOLD""100.35""DISCOUNT""RATE""13.0""AMOUNT""329.23471""TAXABLEITEMS""TAXABLEITEMS""TAXTYPE""T1""AMOUNT""0.0""SUBTYPE""V003""RATE""0.0""SALESTOTAL""2532.57471""NETTOTAL""2203.34""TOTAL""2203.34""TAXTOTALS""TAXTOTALS""TAXTYPE""T1""AMOUNT""0.0""TOTALDISCOUNTAMOUNT""379.71027""TOTALSALESAMOUNT""3037.33027""NETAMOUNT""2657.62""TOTALAMOUNT""2657.62""EXTRADISCOUNTAMOUNT""0.0""TOTALITEMSDISCOUNTAMOUNT""0.0""SIGNATURES""SIGNATURES""1""1"')
def test_9_test_withholding_tax(self):
with freeze_time(self.frozen_today), patch(
'odoo.addons.l10n_eg_edi_eta.models.account_move.AccountMove.action_post_sign_invoices',
new=mocked_action_post_sign_invoices,
), patch(
'odoo.addons.l10n_eg_edi_eta.models.account_edi_format.AccountEdiFormat._l10n_eg_edi_post_invoice_web_service',
new=mocked_l10n_eg_edi_post_invoice_web_service,
):
taxes = self.env.ref(f'account.{self.env.company.id}_eg_standard_sale_14').ids + self.env.ref(f'account.{self.env.company.id}_eg_withholding_3_sale').ids
invoice = self.create_invoice(
move_type='out_invoice',
partner_id=self.partner_a.id,
invoice_line_ids=[
{
'product_id': self.product_a.id,
'price_unit': 100.0,
'quantity': 1.0,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'tax_ids': [Command.set(taxes)],
},
],
)
invoice.action_post()
invoice.action_post_sign_invoices()
generated_files = self._process_documents_web_services(invoice, {'eg_eta'})
self.assertTrue(generated_files)
json_file = json.loads(generated_files[0])
self.assertEqual(
json_file,
{
'request': {**COMMON_REQUEST_DICT,
'receiver': {
'address': {
'country': 'EG',
'governate': 'Cairo',
'regionCity': 'Iswan',
'street': '12th dec. street',
'buildingNumber': '12',
'postalCode': '',
},
'name': 'partner_a',
'type': 'B',
'id': '123456789',
},
'invoiceLines': [
{
'description': 'product_a',
'itemType': 'GS1',
'itemCode': '1KGS1TEST',
'unitType': 'C62',
'quantity': 1.0,
'internalCode': '',
'valueDifference': 0.0,
'totalTaxableFees': 0.0,
'itemsDiscount': 0.0,
'unitValue': {'currencySold': 'EGP', 'amountEGP': 100.0},
'discount': {'rate': 0.0, 'amount': 0.0},
'taxableItems': [{'taxType': 'T1', 'amount': 14.0, 'subType': 'V009', 'rate': 14.0}, {'taxType': 'T4', 'amount': 3.0, 'subType': 'W004', 'rate': 3.0}],
'salesTotal': 100.0,
'netTotal': 100.0,
'total': 111.00,
},
],
'taxTotals': [{'taxType': 'T1', 'amount': 14.0}, {'amount': 3.0, 'taxType': 'T4'}],
'totalSalesAmount': 100.0,
'netAmount': 100.0,
'totalAmount': 111.0,
},
'response': ETA_TEST_RESPONSE,
},
)

View file

@ -8,7 +8,7 @@
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
<group string="Egyptian ETA settings" attrs="{'invisible': ['|', ('type', '!=', 'sale'), ('country_code', '!=', 'EG')]}">
<group string="Egyptian ETA settings" invisible="type != 'sale' or country_code != 'EG'">
<field name="l10n_eg_branch_id"/>
<field name="l10n_eg_activity_type_id"/>
<field name="l10n_eg_branch_identifier"/>

View file

@ -2,7 +2,6 @@
<data>
<record id="action_sign_invoices" model="ir.actions.server">
<field name="name">Sign invoices</field>
<field name="type">ir.actions.server</field>
<field name="state">code</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="binding_model_id" ref="account.model_account_move"/>
@ -23,17 +22,17 @@
class="oe_highlight"
groups="account.group_account_manager"
string="Sign Invoice"
attrs="{'invisible': ['|', '|', ('country_code', '!=', 'EG'), ('l10n_eg_is_signed', '=', True), ('state', '!=', 'posted')]}"/>
invisible="country_code != 'EG' or l10n_eg_is_signed or state != 'posted'"/>
</xpath>
<notebook position="inside">
<page string="ETA E-Invoice" attrs="{'invisible': [('country_code', '!=', 'EG')]}">
<page string="ETA E-Invoice" name="page_eta_e_invoice" invisible="country_code != 'EG'">
<group>
<group>
<field name="l10n_eg_uuid" readonly="1"/>
<field name="l10n_eg_submission_number" readonly="1"/>
</group>
<group>
<field name="l10n_eg_eta_json_doc_id" readonly="1" invisible="1"/>
<field name="l10n_eg_eta_json_doc_file" widget="binary" readonly="1" invisible="1"/>
<field name="l10n_eg_is_signed" invisible="1"/>
</group>
<group>
@ -42,7 +41,7 @@
class="oe_link"
icon="fa-clone"
string="Get ETA Invoice PDF"
attrs="{'invisible': [('edi_state', '!=', 'sent')]}"/>
invisible="edi_state != 'sent'"/>
</group>
</group>
</page>

View file

@ -4,21 +4,21 @@
<field name="name">view_l10n_eg_edi_thumb_drive_tree</field>
<field name="model">l10n_eg_edi.thumb.drive</field>
<field name="arch" type="xml">
<tree editable="top">
<field name="user_id" invisible="1"/>
<field name="certificate" invisible="1"/>
<list editable="top">
<field name="user_id" column_invisible="True"/>
<field name="certificate" column_invisible="True"/>
<field name="company_id"/>
<field name="pin" password="True"/>
<field name="access_token" password="True"/>
<button name="action_set_certificate_from_usb" type="object" string="Get certificate" attrs="{'invisible': [('certificate', '!=', False)]}"/>
</tree>
<button name="action_set_certificate_from_usb" type="object" string="Get certificate" invisible="certificate"/>
</list>
</field>
</record>
<record id="action_eta_thumb_drive_tree" model="ir.actions.act_window">
<field name="name">Thumb Drive</field>
<field name="res_model">l10n_eg_edi.thumb.drive</field>
<field name="view_mode">tree</field>
<field name="view_mode">list</field>
</record>
<menuitem id="account_eta_menu" name="ETA" groups="account.group_account_manager" parent="account.menu_finance_configuration" sequence="99">

View file

@ -8,10 +8,13 @@
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<page name="invoicing" position="inside">
<group name="l10n_eg_eta_edi" string="Egyptian Electronic Invoicing" attrs="{'invisible': [('product_variant_count', '>', 1)]}">
<group name="l10n_eg_eta_edi" string="Egyptian Electronic Invoicing" invisible="'EG' not in fiscal_country_codes or product_variant_count &gt; 1">
<field name="l10n_eg_eta_code" help="ETA Field for GS1/EGS product codes. Please use the barcode field to store GS1/EGS ETA code if possible"/>
</group>
</page>
<page name="invoicing" position="attributes">
<attribute name="groups">account.group_account_invoice,account.group_account_readonly</attribute>
</page>
</field>
</record>

View file

@ -6,7 +6,7 @@
<p>
<strong class="text-center">ETA QR Code</strong>
<img style="display:block;"
t-att-src="'/report/barcode/?barcode_type=%s&amp;value=%s&amp;width=%s&amp;height=%s'%('QR', o.l10n_eg_qr_code, 130, 130)"/>
t-att-src="'/report/barcode/?barcode_type=%s&amp;value=%s&amp;width=%s&amp;height=%s&amp;quiet=%s'%('QR', o.l10n_eg_qr_code, 130, 130, 0)"/>
</p>
</div>
</xpath>

View file

@ -6,39 +6,30 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@data-key='account']/div" position="after">
<h2 attrs="{'invisible':[('country_code', '!=', 'EG')]}">ETA E-Invoicing Settings</h2>
<div class="row mt16 o_settings_container" name="egyption_eta_edi" attrs="{'invisible':[('country_code', '!=', 'EG')]}">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">ETA API Integration</span>
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." aria-label="Values set here are company-specific." groups="base.group_multi_company" role="img"/>
<div class="text-muted">
Enter your API credentials to enable ETA E-Invoicing.
<field name="country_code" invisible="1"/>
<xpath expr="//app[@name='account']/block" position="after">
<block title="ETA E-Invoicing Settings" name="egyption_eta_edi" invisible="country_code != 'EG'">
<field name="country_code" invisible="1"/>
<setting string="ETA API Integration" help="Enter your API credentials to enable ETA E-Invoicing." company_dependent="1">
<div class="content-group">
<div class="row mt16">
<label for="l10n_eg_production_env" class="col-lg-6 o_light_label"/>
<field name="l10n_eg_production_env" help="Check to start sending invoices to your e-invoicing production environment"/>
</div>
<div class="content-group">
<div class="row mt16">
<label for="l10n_eg_production_env" class="col-lg-6 o_light_label"/>
<field name="l10n_eg_production_env" help="Check to start sending invoices to your e-invoicing production environment"/>
</div>
<div class="row">
<label for="l10n_eg_client_identifier" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_client_identifier" help="The client ID retrieved from the ETA e-invoicing portal"/>
</div>
<div class="row">
<label for="l10n_eg_client_secret" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_client_secret" password="True" help="The secret key provided by the ETA. You can input client secret 1 or 2"/>
</div>
<div class="row">
<label for="l10n_eg_invoicing_threshold" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_invoicing_threshold" help="Set the threshold amount for invoices that won't require the VAT ID of individuals when invoicing"/>
</div>
<div class="row">
<label for="l10n_eg_client_identifier" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_client_identifier" help="The client ID retrieved from the ETA e-invoicing portal"/>
</div>
<div class="row">
<label for="l10n_eg_client_secret" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_client_secret" password="True" help="The secret key provided by the ETA. You can input client secret 1 or 2"/>
</div>
<div class="row">
<label for="l10n_eg_invoicing_threshold" class="col-lg-4 o_light_label"/>
<field name="l10n_eg_invoicing_threshold" help="Set the threshold amount for invoices that won't require the VAT ID of individuals when invoicing"/>
</div>
</div>
</div>
</div>
</setting>
</block>
</xpath>
</field>
</record>

View file

@ -5,8 +5,8 @@
<field name="model">uom.uom</field>
<field name="inherit_id" ref="uom.product_uom_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='uom_type']" position="after">
<field name="l10n_eg_unit_code_id"/>
<xpath expr="//field[@name='name']" position="after">
<field name="l10n_eg_unit_code_id" invisible="'EG' not in fiscal_country_codes"/>
</xpath>
</field>
</record>

View file

@ -2,14 +2,17 @@
name = "odoo-bringout-oca-ocb-l10n_eg_edi_eta"
version = "16.0.0"
description = "Egypt E-Invoicing -
Egyptian Tax Authority Invoice Integration
Egypt Tax Authority Invoice Integration
"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-account_edi>=16.0.0",
"odoo-bringout-oca-ocb-l10n_eg>=16.0.0",
"odoo-bringout-oca-ocb-account_edi>=19.0.0",
"odoo-bringout-oca-ocb-l10n_eg>=19.0.0",
"asn1crypto",
"requests>=2.25.1"
]
readme = "README.md"
@ -19,7 +22,7 @@ classifiers = [
"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.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]