mirror of
https://github.com/bringout/oca-ocb-l10n_europe.git
synced 2026-04-27 11:42:04 +02:00
19.0 vanilla
This commit is contained in:
parent
ff721d030e
commit
7721452493
1826 changed files with 124775 additions and 274114 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Argentinean eCommerce
|
||||
|
||||
Be able to see Identification Type and AFIP Responsibility in ecommerce checkout form.
|
||||
Bridge Website Sale for Argentina
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -10,36 +10,15 @@ pip install odoo-bringout-oca-ocb-l10n_ar_website_sale
|
|||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- website_sale
|
||||
- l10n_ar
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Argentinean eCommerce
|
||||
- **Version**: 1.0
|
||||
- **Category**: Accounting/Localizations/Website
|
||||
- **License**: LGPL-3
|
||||
- **Installable**: True
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `l10n_ar_website_sale`.
|
||||
- Repository: https://github.com/OCA/OCB
|
||||
- Branch: 19.0
|
||||
- Path: addons/l10n_ar_website_sale
|
||||
|
||||
## 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.
|
||||
|
|
|
|||
|
|
@ -1,4 +1 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import controllers
|
||||
from . import models
|
||||
from . import tests
|
||||
|
|
|
|||
|
|
@ -1,23 +1,26 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
'name': 'Argentinean eCommerce',
|
||||
'version': '1.0',
|
||||
'category': 'Accounting/Localizations/Website',
|
||||
'sequence': 14,
|
||||
'author': 'Odoo, ADHOC SA',
|
||||
'description': """Be able to see Identification Type and AFIP Responsibility in ecommerce checkout form.""",
|
||||
'countries': ['ar'],
|
||||
'icon': '/base/static/img/country_flags/ar.png',
|
||||
'description': """Bridge Website Sale for Argentina""",
|
||||
'depends': [
|
||||
'website_sale',
|
||||
'l10n_ar',
|
||||
],
|
||||
'data': [
|
||||
'data/ir_model_fields.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/templates.xml',
|
||||
],
|
||||
'demo': [
|
||||
'demo/website_demo.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_frontend': [
|
||||
'l10n_ar_website_sale/static/src/interactions/**/*',
|
||||
'l10n_ar_website_sale/static/src/scss/*.scss',
|
||||
]
|
||||
},
|
||||
'installable': True,
|
||||
'auto_install': True,
|
||||
'author': 'Odoo S.A.',
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import main
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import _
|
||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class L10nARWebsiteSale(WebsiteSale):
|
||||
|
||||
def _get_mandatory_fields_billing(self, country_id=False):
|
||||
"""Extend mandatory fields to add new identification and responsibility fields when company is argentina"""
|
||||
res = super()._get_mandatory_fields_billing(country_id)
|
||||
if request.website.sudo().company_id.country_id.code == "AR":
|
||||
res += ["l10n_latam_identification_type_id", "l10n_ar_afip_responsibility_type_id", "vat"]
|
||||
return res
|
||||
|
||||
def _get_country_related_render_values(self, kw, render_values):
|
||||
res = super()._get_country_related_render_values(kw, render_values)
|
||||
if request.website.sudo().company_id.country_id.code == "AR":
|
||||
res.update({'identification': kw.get('l10n_latam_identification_type_id'),
|
||||
'responsibility': kw.get('l10n_ar_afip_responsibility_type_id'),
|
||||
'responsibility_types': request.env['l10n_ar.afip.responsibility.type'].search([]),
|
||||
'identification_types': request.env['l10n_latam.identification.type'].search(
|
||||
['|', ('country_id', '=', False), ('country_id.code', '=', 'AR')])})
|
||||
return res
|
||||
|
||||
def _get_vat_validation_fields(self, data):
|
||||
res = super()._get_vat_validation_fields(data)
|
||||
if request.website.sudo().company_id.country_id.code == "AR":
|
||||
res.update({'l10n_latam_identification_type_id': int(data['l10n_latam_identification_type_id'])
|
||||
if data.get('l10n_latam_identification_type_id') else False})
|
||||
res.update({'name': data['name'] if data.get('name') else False})
|
||||
return res
|
||||
|
||||
def checkout_form_validate(self, mode, all_form_values, data):
|
||||
""" We extend the method to add a new validation. If AFIP Resposibility is:
|
||||
|
||||
* Final Consumer or Foreign Customer: then it can select any identification type.
|
||||
* Any other (Monotributista, RI, etc): should select always "CUIT" identification type"""
|
||||
error, error_message = super().checkout_form_validate(mode, all_form_values, data)
|
||||
|
||||
# Identification type and AFIP Responsibility Combination
|
||||
if request.website.sudo().company_id.country_id.code == "AR":
|
||||
if mode[1] == 'billing':
|
||||
if error and any(field in error for field in ['l10n_latam_identification_type_id', 'l10n_ar_afip_responsibility_type_id']):
|
||||
return error, error_message
|
||||
id_type_id = data.get("l10n_latam_identification_type_id")
|
||||
afip_resp_id = data.get("l10n_ar_afip_responsibility_type_id")
|
||||
|
||||
id_type = request.env['l10n_latam.identification.type'].browse(id_type_id) if id_type_id else False
|
||||
afip_resp = request.env['l10n_ar.afip.responsibility.type'].browse(afip_resp_id) if afip_resp_id else False
|
||||
cuit_id_type = request.env.ref('l10n_ar.it_cuit')
|
||||
|
||||
# Check if the AFIP responsibility is different from Final Consumer or Foreign Customer,
|
||||
# and if the identification type is different from CUIT
|
||||
if afip_resp.code not in ['5', '9'] and id_type != cuit_id_type:
|
||||
error["l10n_latam_identification_type_id"] = 'error'
|
||||
error_message.append(_('For the selected AFIP Responsibility you will need to set CUIT Identification Type'))
|
||||
|
||||
return error, error_message
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<function model="ir.model.fields" name="formbuilder_whitelist">
|
||||
<value>res.partner</value>
|
||||
<value eval="[
|
||||
'l10n_ar_afip_responsibility_type_id', 'l10n_latam_identification_type_id',
|
||||
]"/>
|
||||
</function>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="default_website_ri" model="website">
|
||||
<field name="name">(AR) Responsable Inscripto Website</field>
|
||||
<field name="company_id" ref="l10n_ar.company_ri"/>
|
||||
<field name="logo" type="base64" file="l10n_ar_website_sale/static/description/icon.png"/>
|
||||
<field name="domain" model="ir.config_parameter" eval="obj().env['ir.config_parameter'].sudo().get_param('web.base.url')"/>
|
||||
</record>
|
||||
<function model="payment.provider" name="copy">
|
||||
<value eval="[ref('payment.payment_provider_transfer')]"/>
|
||||
<value eval="{'company_id': ref('l10n_ar.company_ri'), 'state': 'enabled'}"/>
|
||||
</function>
|
||||
<function model="product.pricelist" name="write">
|
||||
<value model="product.pricelist" eval="obj().search([('currency_id', '=', ref('base.ARS')), ('company_id', '=', ref('l10n_ar.company_ri'))]).id"/>
|
||||
<value model="website" eval="{'sequence': 1, 'website_id': ref('l10n_ar_website_sale.default_website_ri')}"/>
|
||||
</function>
|
||||
<function model="product.product" name="write">
|
||||
<value model="product.product" eval="obj().search([('taxes_id', '=', False)]).ids"/>
|
||||
<value model="account.tax" eval="{'taxes_id': [(4, obj().search([('type_tax_use', '=', 'sale'), ('tax_group_id', '=', ref('l10n_ar.tax_group_iva_21')), ('company_id', '=', ref('l10n_ar.company_ri'))]).id)]}"/>
|
||||
</function>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_ar_website_sale
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-11-15 10:56+0000\n"
|
||||
"PO-Revision-Date: 2024-11-15 10:56+0000\n"
|
||||
"Last-Translator: María Fernanda Alvarez Ramírez <mfar@odoo.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:website,contact_us_button_url:l10n_ar_website_sale.default_website_ri
|
||||
msgid "/contactus"
|
||||
msgstr "/contacto"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "<option value=\"\">AFIP Responsibility...</option>"
|
||||
msgstr "<option value=\"\">Responsabilidad AFIP...</option>"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "<option value=\"\">Identification Type...</option>"
|
||||
msgstr "<option value=\"\">Tipo de identificación...</option>"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "AFIP Responsibility"
|
||||
msgstr "Responsabilidad AFIP"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid ""
|
||||
"Changing AFIP Responsibility type is not allowed once document(s) have been "
|
||||
"issued for your account. Please contact us directly for this operation."
|
||||
msgstr ""
|
||||
"No puede cambiar el tipo de responsabilidad AFIP después de que haya emitido "
|
||||
"documentos para su cuenta. Contáctenos para realizar esta operación."
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid ""
|
||||
"Changing Identification type is not allowed once document(s) have been "
|
||||
"issued for your account. Please contact us directly for this operation."
|
||||
msgstr ""
|
||||
"No puede cambiar el tipo de identificación después de que haya emitido "
|
||||
"documentos para su cuenta. Contáctenos para realizar esta operación."
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_ar_website_sale/controllers/main.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"For the selected AFIP Responsibility you will need to set CUIT "
|
||||
"Identification Type"
|
||||
msgstr ""
|
||||
"Para la responsabilidad AFIP seleccionada debe elegir el tipo de "
|
||||
"identificación CUIT"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "Identification Type"
|
||||
msgstr "Tipo de identificación"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:website,prevent_zero_price_sale_text:l10n_ar_website_sale.default_website_ri
|
||||
msgid "Not Available For Sale"
|
||||
msgstr "No está disponible para la venta"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.address
|
||||
msgid "Number"
|
||||
msgstr "Número"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_website
|
||||
msgid "Website"
|
||||
msgstr "Sitio web"
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_ar_website_sale
|
||||
#
|
||||
# "Fernanda Alvarez (mfar)" <mfar@odoo.com>, 2026.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 18.4a1+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-30 19:04+0000\n"
|
||||
"PO-Revision-Date: 2026-01-31 10:05+0000\n"
|
||||
"Last-Translator: \"Fernanda Alvarez (mfar)\" <mfar@odoo.com>\n"
|
||||
"Language-Team: Spanish (Latin America) <https://translate.odoo.com/projects/"
|
||||
"odoo-19-l10n/l10n_ar_website_sale/es_419/>\n"
|
||||
"Language: es_419\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.14.3\n"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr "Ajustes de configuración"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_product_template__display_name
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__display_name
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre Mostrado"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__l10n_ar_website_sale_show_both_prices
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__l10n_ar_website_sale_show_both_prices
|
||||
msgid "Display Price without National Taxes"
|
||||
msgstr "Mostrar Precio sin Impuestos Nacionales"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_product_template__id
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__id
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.l10n_ar_website_sale_products_item_inherit
|
||||
msgid "Precio s/Imp. Nac."
|
||||
msgstr "Precio s/Imp. Nac."
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.l10n_ar_website_sale_product_price_inherit
|
||||
msgid "Precio s/Imp. Nac.:"
|
||||
msgstr "Precio s/Imp. Nac.:"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_product_template
|
||||
msgid "Product"
|
||||
msgstr "Producto"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_website
|
||||
msgid "Website"
|
||||
msgstr "Website"
|
||||
|
|
@ -4,10 +4,10 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0+e\n"
|
||||
"Project-Id-Version: Odoo Server 19.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-11-15 10:56+0000\n"
|
||||
"PO-Revision-Date: 2024-11-15 10:56+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 19:04+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 19:04+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -16,61 +16,43 @@ msgstr ""
|
|||
"Plural-Forms: \n"
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:website,contact_us_button_url:l10n_ar_website_sale.default_website_ri
|
||||
msgid "/contactus"
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "<option value=\"\">AFIP Responsibility...</option>"
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_product_template__display_name
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__display_name
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "<option value=\"\">Identification Type...</option>"
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__l10n_ar_website_sale_show_both_prices
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__l10n_ar_website_sale_show_both_prices
|
||||
msgid "Display Price without National Taxes"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "AFIP Responsibility"
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_product_template__id
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_res_config_settings__id
|
||||
#: model:ir.model.fields,field_description:l10n_ar_website_sale.field_website__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid ""
|
||||
"Changing AFIP Responsibility type is not allowed once document(s) have been "
|
||||
"issued for your account. Please contact us directly for this operation."
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.l10n_ar_website_sale_products_item_inherit
|
||||
msgid "Precio s/Imp. Nac."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid ""
|
||||
"Changing Identification type is not allowed once document(s) have been "
|
||||
"issued for your account. Please contact us directly for this operation."
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.l10n_ar_website_sale_product_price_inherit
|
||||
msgid "Precio s/Imp. Nac.:"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_ar_website_sale/controllers/main.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"For the selected AFIP Responsibility you will need to set CUIT "
|
||||
"Identification Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.partner_info
|
||||
msgid "Identification Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model:website,prevent_zero_price_sale_text:l10n_ar_website_sale.default_website_ri
|
||||
msgid "Not Available For Sale"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_ar_website_sale.address
|
||||
msgid "Number"
|
||||
#: model:ir.model,name:l10n_ar_website_sale.model_product_template
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_ar_website_sale
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import product_template
|
||||
from . import res_config_settings
|
||||
from . import website
|
||||
from . import sale_order
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
def _get_sales_prices(self, website):
|
||||
'''
|
||||
Resolution 4/2025 requires us to display both prices on the e-commerce site:
|
||||
- Price including taxes
|
||||
- Price excluding taxes
|
||||
|
||||
If the website is configured to use tax-included pricing, we calculate the tax-excluded
|
||||
price separately. This tax-excluded price is displayed on the shop page (on both list and grid views).
|
||||
'''
|
||||
|
||||
res = super()._get_sales_prices(website)
|
||||
fiscal_position_id = request.fiscal_position
|
||||
pricelist_prices = request.pricelist._compute_price_rule(self, 1.0)
|
||||
|
||||
if (
|
||||
website
|
||||
and website.company_id.country_code == 'AR'
|
||||
and website.l10n_ar_website_sale_show_both_prices
|
||||
and website.show_line_subtotals_tax_selection == 'tax_included'
|
||||
):
|
||||
for template_id, template_val in res.items():
|
||||
# Get applicable taxes for the product and map them using the website's FPOS
|
||||
template = self.env['product.template'].browse(template_id)
|
||||
product_taxes = template.sudo().taxes_id._filter_taxes_by_company(self.env.company)
|
||||
mapped_taxes = fiscal_position_id.map_tax(product_taxes)
|
||||
|
||||
# Compute the tax-excluded value
|
||||
total_excluded_value = mapped_taxes.compute_all(
|
||||
price_unit=pricelist_prices[template.id][0],
|
||||
currency=website.currency_id,
|
||||
product=template,
|
||||
)['total_excluded']
|
||||
|
||||
# Store the tax-excluded price in the res for use in showing both prices
|
||||
res[template_id]['l10n_ar_price_tax_excluded'] = total_excluded_value
|
||||
|
||||
return res
|
||||
|
||||
def _get_additionnal_combination_info(self, product_or_template, quantity, uom, date, website):
|
||||
combination_info = super()._get_additionnal_combination_info(
|
||||
product_or_template, quantity, uom, date, website
|
||||
)
|
||||
if (
|
||||
website
|
||||
and website.company_id.country_code == 'AR'
|
||||
and website.l10n_ar_website_sale_show_both_prices
|
||||
and website.show_line_subtotals_tax_selection == 'tax_included'
|
||||
):
|
||||
# Get applicable taxes for the product and map them using the website's FPOS
|
||||
product_taxes = product_or_template.sudo().taxes_id._filter_taxes_by_company(self.env.company)
|
||||
mapped_taxes = request.fiscal_position.map_tax(product_taxes)
|
||||
|
||||
# Compute price per unit of product or template
|
||||
pricelist_prices = request.pricelist._compute_price_rule(product_or_template, quantity)
|
||||
unit_price = pricelist_prices[product_or_template.id][0]
|
||||
|
||||
# Compute the tax-excluded value
|
||||
total_excluded_value = mapped_taxes.compute_all(
|
||||
price_unit=unit_price,
|
||||
currency=website.currency_id,
|
||||
product=product_or_template,
|
||||
)['total_excluded']
|
||||
|
||||
# Check if a discount is applied and adjust the tax-excluded price accordingly
|
||||
if combination_info['has_discounted_price']:
|
||||
discount_percent = (combination_info['list_price'] - combination_info['price']) / combination_info['list_price']
|
||||
total_excluded_value = total_excluded_value * (1 - discount_percent)
|
||||
|
||||
# Store the tax-excluded price in the res for use in showing both prices
|
||||
combination_info['l10n_ar_price_tax_excluded'] = total_excluded_value
|
||||
|
||||
return combination_info
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
# Website Dependent Settings
|
||||
l10n_ar_website_sale_show_both_prices = fields.Boolean(
|
||||
related='website_id.l10n_ar_website_sale_show_both_prices',
|
||||
readonly=False,
|
||||
)
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import pytz
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
def _create_invoices(self, grouped=False, final=False, date=None):
|
||||
""" EXTENDS 'sale'
|
||||
Necessary because if someone creates an invoice after 9 pm Argentina time, if the invoice is created
|
||||
automatically, then it is created with the date of the next day (UTC date) instead of today.
|
||||
|
||||
This fix is necessary because it causes problems validating invoices in ARCA (ex AFIP), since when generating
|
||||
the invoice with the date of the next day, no more invoices could be generated with today's date.
|
||||
|
||||
We took the same approach that was used in the POS module to set the date, in this case always forcing the
|
||||
Argentina timezone """
|
||||
invoices = super()._create_invoices(grouped=grouped, final=final, date=date)
|
||||
for invoice in invoices:
|
||||
if invoice.country_code == 'AR':
|
||||
timezone = pytz.timezone('America/Buenos_Aires')
|
||||
context_today_ar = fields.Datetime.now().astimezone(timezone).date()
|
||||
invoice.invoice_date = context_today_ar
|
||||
return invoices
|
||||
|
|
@ -1,13 +1,27 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class Website(models.Model):
|
||||
_inherit = "website"
|
||||
_inherit = 'website'
|
||||
|
||||
def _display_partner_b2b_fields(self):
|
||||
""" Argentinean localization must always display b2b fields """
|
||||
self.ensure_one()
|
||||
return self.company_id.country_id.code == "AR" or super()._display_partner_b2b_fields()
|
||||
l10n_ar_website_sale_show_both_prices = fields.Boolean(
|
||||
string="Display Price without National Taxes",
|
||||
compute='_compute_l10n_ar_website_sale_show_both_prices',
|
||||
readonly=False,
|
||||
store=True,
|
||||
)
|
||||
|
||||
@api.depends('company_id')
|
||||
def _compute_l10n_ar_website_sale_show_both_prices(self):
|
||||
for website in self:
|
||||
website.l10n_ar_website_sale_show_both_prices = (
|
||||
website.company_id.account_fiscal_country_id.code == 'AR'
|
||||
)
|
||||
|
||||
@api.depends('company_id.account_fiscal_country_id')
|
||||
def _compute_show_line_subtotals_tax_selection(self):
|
||||
# EXTENDS 'website_sale'
|
||||
super()._compute_show_line_subtotals_tax_selection()
|
||||
for website in self:
|
||||
if website.company_id.account_fiscal_country_id.code == 'AR':
|
||||
website.show_line_subtotals_tax_selection = 'tax_included'
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,22 @@
|
|||
import { patch } from '@web/core/utils/patch';
|
||||
import { WebsiteSale } from '@website_sale/interactions/website_sale';
|
||||
|
||||
patch(WebsiteSale.prototype, {
|
||||
/**
|
||||
* @override
|
||||
* Updates the product's excluded price based on the selected variant.
|
||||
* Ensuring availability info stays accurate.
|
||||
*/
|
||||
_onChangeCombination(ev, parent, combination) {
|
||||
super._onChangeCombination(...arguments);
|
||||
const currencyValue = parent.querySelector(
|
||||
'.o_l10n_ar_price_tax_excluded .oe_currency_value'
|
||||
);
|
||||
if (currencyValue) {
|
||||
const { currency_precision, l10n_ar_price_tax_excluded } = combination;
|
||||
currencyValue.textContent = this._priceToStr(
|
||||
l10n_ar_price_tax_excluded, currency_precision,
|
||||
);
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.o_wsale_products_opt_layout_list{
|
||||
.o_wsale_product_sub{
|
||||
.o_wsale_product_btn:has(.btn) + .o_l10n_ar_product_price {
|
||||
text-align: end;
|
||||
}
|
||||
.o_wsale_product_btn:not(:has(.btn)) + .o_l10n_ar_product_price {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
from . import test_invoice
|
||||
from . import test_l10n_ar_website_sale
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo.addons.account_payment.tests.common import AccountPaymentCommon
|
||||
from odoo.addons.sale.tests.common import SaleCommon
|
||||
from odoo.addons.l10n_ar.tests.common import TestAr
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install', 'post_install_l10n')
|
||||
class TestWebsiteSaleInvoice(AccountPaymentCommon, SaleCommon, TestAr):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.website = cls.env['website'].create({'name': 'Test AR Website'})
|
||||
|
||||
def test_website_automatic_invoice_date(self):
|
||||
# Set automatic invoice
|
||||
self.env['ir.config_parameter'].sudo().set_param('sale.automatic_invoice', 'True')
|
||||
self.frozen_today = "2025-01-24T21:10:00"
|
||||
with freeze_time(self.frozen_today, tz_offset=3):
|
||||
|
||||
# Prepare values needed for AR invoice generation: Tax in all lines, and AFIP responsibility partner
|
||||
self.sale_order.order_line.write({'tax_id': self.company_data['default_tax_sale']})
|
||||
self.sale_order.partner_id = self.partner_cf
|
||||
self.sale_order.currency_id = self.env.ref('base.ARS')
|
||||
|
||||
# Create SO on Test Website
|
||||
self.sale_order.website_id = self.website.id
|
||||
|
||||
# Create the payment and invoices
|
||||
self.amount = self.sale_order.amount_total
|
||||
tx = self._create_transaction(flow='redirect', sale_order_ids=[self.sale_order.id], state='done')
|
||||
with mute_logger('odoo.addons.sale.models.payment_transaction'):
|
||||
tx.with_context(l10n_ar_invoice_skip_commit=True)._reconcile_after_done()
|
||||
|
||||
invoice = self.sale_order.invoice_ids
|
||||
self.assertTrue(invoice, "Do not create the invoice")
|
||||
self.assertEqual(invoice.state, "posted", "the invoice was not posted")
|
||||
self.assertEqual(fields.Datetime.now().date().strftime("%Y-%m-%d"), '2025-01-25', "UCT should be next day")
|
||||
self.assertEqual(invoice.invoice_date.strftime('%Y-%m-%d'), '2025-01-24', "Should be AR current date")
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
from datetime import datetime
|
||||
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import tagged
|
||||
|
||||
from odoo.addons.l10n_ar.tests.common import TestArCommon
|
||||
from odoo.addons.website_sale.tests.common import MockRequest
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestL10nArWebsiteSale(TestArCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
# Set up Argentina-specific test company and website
|
||||
cls.ar_company = cls.company_data['company']
|
||||
cls.ar_website = cls.env['website'].create({
|
||||
'name': 'AR Website',
|
||||
'company_id': cls.ar_company.id,
|
||||
})
|
||||
|
||||
# Create a base product template with default tax
|
||||
cls.product_1 = cls.env['product.template'].create({
|
||||
'name': 'Product 1',
|
||||
'is_published': True,
|
||||
'list_price': 1000,
|
||||
'taxes_id': cls.env['account.chart.template'].ref('ri_tax_vat_21_ventas'),
|
||||
})
|
||||
|
||||
# Create color attribute and values
|
||||
cls.color_attribute = cls.env['product.attribute'].create({
|
||||
'name': 'Color',
|
||||
'display_type': 'color',
|
||||
})
|
||||
cls.color_white = cls.env['product.attribute.value'].create({
|
||||
'name': 'White',
|
||||
'html_color': '#FFFFFF',
|
||||
'attribute_id': cls.color_attribute.id,
|
||||
})
|
||||
cls.color_black = cls.env['product.attribute.value'].create({
|
||||
'name': 'Black',
|
||||
'html_color': '#000000',
|
||||
'attribute_id': cls.color_attribute.id,
|
||||
})
|
||||
|
||||
def assertDictContains(self, actual_dict, expected_subset):
|
||||
"""Assert that actual_dict contains all key-value pairs from expected_subset."""
|
||||
for key, expected_value in expected_subset.items():
|
||||
self.assertEqual(actual_dict.get(key), expected_value)
|
||||
|
||||
def _get_combination_info(self, product_id=None, quantity=1):
|
||||
"""Helper method to retrieve combination info for a product."""
|
||||
with MockRequest(self.env, website=self.ar_website):
|
||||
return self.product_1._get_additionnal_combination_info(
|
||||
product_or_template=product_id or self.product_1,
|
||||
quantity=quantity,
|
||||
uom=self.uom_unit,
|
||||
date=datetime(2025, 5, 21),
|
||||
website=self.ar_website
|
||||
)
|
||||
|
||||
def test_default_website_sale_legal_values(self):
|
||||
"""Ensure legal default values are applied on AR website."""
|
||||
self.assertEqual(self.ar_website.l10n_ar_website_sale_show_both_prices, True)
|
||||
self.assertEqual(self.ar_website.show_line_subtotals_tax_selection, 'tax_included')
|
||||
|
||||
def test_price_calculation_with_tax_changes(self):
|
||||
"""Test list price and tax excluded price calculations for various tax setups."""
|
||||
with self.subTest(scenario="Single 21% VAT - tax excluded"):
|
||||
combo = self._get_combination_info()
|
||||
self.assertDictContains(combo, {
|
||||
'list_price': 1210.00, # 1000 + 21%
|
||||
'l10n_ar_price_tax_excluded': 1000.00,
|
||||
})
|
||||
|
||||
with self.subTest(scenario="Mixed taxes - 10.5% excluded + 27% included"):
|
||||
template = self.env['account.chart.template']
|
||||
tax_27_included = template.ref('ri_tax_vat_27_ventas')
|
||||
tax_10_5_excluded = template.ref('ri_tax_vat_10_ventas')
|
||||
|
||||
tax_27_included.price_include = True
|
||||
tax_10_5_excluded.price_include = False
|
||||
|
||||
self.product_1.taxes_id = (tax_27_included + tax_10_5_excluded).ids
|
||||
combo = self._get_combination_info()
|
||||
self.assertDictContains(combo, {
|
||||
'list_price': 1082.68, # Computed price including all taxes
|
||||
'l10n_ar_price_tax_excluded': 787.40, # Reverse calculated base price
|
||||
})
|
||||
|
||||
def test_price_calculation_with_pricelist_rules(self):
|
||||
"""Check that pricelist rules are taken into account."""
|
||||
self._enable_pricelists()
|
||||
self.pricelist.update({
|
||||
'website_id': self.ar_website.id,
|
||||
'item_ids': [
|
||||
Command.create({
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': 888.0,
|
||||
'min_quantity': 5.0,
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': self.product_1.id,
|
||||
}),
|
||||
Command.create({
|
||||
'compute_price': 'formula',
|
||||
'price_surcharge': 2.0,
|
||||
'applied_on': '3_global',
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
info_qty_3 = self._get_combination_info(quantity=3)
|
||||
self.assertEqual(info_qty_3['l10n_ar_price_tax_excluded'], 1002.0)
|
||||
|
||||
info_qty_5 = self._get_combination_info(quantity=5)
|
||||
self.assertEqual(info_qty_5['l10n_ar_price_tax_excluded'], 888.0)
|
||||
|
||||
def test_product_variant_prices_with_attributes(self):
|
||||
"""Test variant-specific price calculation with color attribute values."""
|
||||
self.product_1.taxes_id = self.env['account.chart.template'].ref('ri_tax_vat_21_ventas')
|
||||
|
||||
# Add attribute line and values to product template
|
||||
attribute_line = self.env['product.template.attribute.line'].create({
|
||||
'product_tmpl_id': self.product_1.id,
|
||||
'attribute_id': self.color_attribute.id,
|
||||
'value_ids': [(6, 0, [self.color_white.id, self.color_black.id])]
|
||||
})
|
||||
|
||||
# Set price extras for each variant
|
||||
attribute_line.product_template_value_ids[0].price_extra = 100 # White
|
||||
attribute_line.product_template_value_ids[1].price_extra = 200 # Black
|
||||
|
||||
white_variant = self.product_1.product_variant_ids[0]
|
||||
black_variant = self.product_1.product_variant_ids[1]
|
||||
|
||||
with self.subTest(scenario="White variant with 100 extra + 21% VAT"):
|
||||
combo = self._get_combination_info(product_id=white_variant)
|
||||
self.assertDictContains(combo, {
|
||||
'list_price': 1331.00, # (1000+100) + 21%
|
||||
'l10n_ar_price_tax_excluded': 1100.00,
|
||||
})
|
||||
|
||||
with self.subTest(scenario="Black variant with 200 extra + 21% VAT"):
|
||||
combo = self._get_combination_info(product_id=black_variant)
|
||||
self.assertDictContains(combo, {
|
||||
'list_price': 1452.00, # (1000+200) + 21%
|
||||
'l10n_ar_price_tax_excluded': 1200.00,
|
||||
})
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id='res_config_settings_view_form' model='ir.ui.view'>
|
||||
<field name='name'>res.config.settings.view.form.inherit.website.sale</field>
|
||||
<field name='model'>res.config.settings</field>
|
||||
<field name='inherit_id' ref='website_sale.res_config_settings_view_form'/>
|
||||
<field name='arch' type='xml'>
|
||||
<setting id='website_tax_inclusion_setting' position='inside'>
|
||||
<div invisible='country_code != "AR" or show_line_subtotals_tax_selection != "tax_included"'>
|
||||
<field name='l10n_ar_website_sale_show_both_prices'/>
|
||||
<label for='l10n_ar_website_sale_show_both_prices'/>
|
||||
</div>
|
||||
</setting>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,63 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="partner_info" name="Argentinean partner">
|
||||
|
||||
<!-- show afip responsibility -->
|
||||
<div t-attf-class="mb-3 #{error.get('l10n_ar_afip_responsibility_type_id') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="l10n_ar_afip_responsibility_type_id">AFIP Responsibility</label>
|
||||
<t t-if="partner.can_edit_vat()">
|
||||
<select name="l10n_ar_afip_responsibility_type_id" t-attf-class="form-select #{error.get('l10n_ar_afip_responsibility_type_id') and 'is-invalid' or ''}">
|
||||
<option value="">AFIP Responsibility...</option>
|
||||
<t t-foreach="responsibility_types or []" t-as="resp_type">
|
||||
<option t-att-value="resp_type.id" t-att-selected="resp_type.id == int(responsibility) if responsibility else resp_type.id == partner.l10n_ar_afip_responsibility_type_id.id">
|
||||
<t t-esc="resp_type.name"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p class="form-control" t-esc="partner.l10n_ar_afip_responsibility_type_id.name" readonly="1" title="Changing AFIP Responsibility type is not allowed once document(s) have been issued for your account. Please contact us directly for this operation."/>
|
||||
<input name="l10n_ar_afip_responsibility_type_id" class="form-control" t-att-value="partner.l10n_ar_afip_responsibility_type_id.id" type='hidden'/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- show identification type -->
|
||||
<div t-attf-class="mb-3 #{error.get('l10n_latam_identification_type_id') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="l10n_latam_identification_type_id">Identification Type</label>
|
||||
<t t-if="partner.can_edit_vat()">
|
||||
<select name="l10n_latam_identification_type_id" t-attf-class="form-select #{error.get('l10n_latam_identification_type_id') and 'is-invalid' or ''}">
|
||||
<option value="">Identification Type...</option>
|
||||
<t t-foreach="identification_types or []" t-as="id_type">
|
||||
<option t-att-value="id_type.id" t-att-selected="id_type.id == int(identification) if identification else id_type.id == partner.l10n_latam_identification_type_id.id">
|
||||
<t t-esc="id_type.name"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p class="form-control" t-esc="partner.l10n_latam_identification_type_id.name" readonly="1" title="Changing Identification type is not allowed once document(s) have been issued for your account. Please contact us directly for this operation."/>
|
||||
<input name="l10n_latam_identification_type_id" class="form-control" t-att-value="partner.l10n_latam_identification_type_id.id" type='hidden'/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<template id='l10n_ar_website_sale_product_price_inherit' inherit_id='website_sale.product_price'>
|
||||
<xpath expr='//div[1]'>
|
||||
<small t-if='combination_info.get("l10n_ar_price_tax_excluded")' class='h6 text-muted'>
|
||||
Precio s/Imp. Nac.:
|
||||
<span
|
||||
class='o_l10n_ar_price_tax_excluded'
|
||||
t-out='combination_info["l10n_ar_price_tax_excluded"]'
|
||||
t-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": website.currency_id,
|
||||
}'
|
||||
/>
|
||||
</small>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="address" inherit_id="website_sale.address">
|
||||
<xpath expr="//input[@name='vat']/.." position="before">
|
||||
<t t-if="mode[1] == 'billing'" positon="inside">
|
||||
<t t-if="res_company.country_id.code == 'AR'">
|
||||
<t t-set="partner" t-value="website_sale_order.partner_id"/>
|
||||
<t t-call="l10n_ar_website_sale.partner_info"/>
|
||||
</t>
|
||||
</t>
|
||||
<template id='l10n_ar_website_sale_products_item_inherit' inherit_id='website_sale.products_item'>
|
||||
<xpath expr='//div[hasclass("product_price")]' position='attributes'>
|
||||
<attribute name='t-attf-class' add='o_l10n_ar_product_price'/>
|
||||
</xpath>
|
||||
<xpath expr='//div[hasclass("product_price")]' position='inside'>
|
||||
<small t-if='template_price_vals.get("l10n_ar_price_tax_excluded")' class='d-block mt-1 text-muted'>
|
||||
Precio s/Imp. Nac.
|
||||
<span
|
||||
class='o_l10n_ar_price_tax_excluded'
|
||||
t-out='template_price_vals["l10n_ar_price_tax_excluded"]'
|
||||
t-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": website.currency_id,
|
||||
}'
|
||||
/>
|
||||
</small>
|
||||
</xpath>
|
||||
<label for="vat" position="attributes">
|
||||
<attribute name="t-if">res_company.country_id.code != 'AR'</attribute>
|
||||
</label>
|
||||
<label for="vat" position="after">
|
||||
<label t-if="res_company.country_id.code == 'AR'" class="col-form-label label-optional" for="vat">Number</label>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-ocb-l10n_ar_website_sale"
|
||||
version = "16.0.0"
|
||||
description = "Argentinean eCommerce - Odoo addon"
|
||||
description = "Argentinean eCommerce -
|
||||
Odoo addon
|
||||
"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-ocb-website_sale>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-l10n_ar>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_sale>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-l10n_ar>=19.0.0",
|
||||
"requests>=2.25.1"
|
||||
]
|
||||
readme = "README.md"
|
||||
|
|
@ -17,7 +19,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",
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue