diff --git a/addons/l10n_pe_website_sale/__init__.py b/addons/l10n_pe_website_sale/__init__.py new file mode 100644 index 00000000000..4dcc9d3a4b7 --- /dev/null +++ b/addons/l10n_pe_website_sale/__init__.py @@ -0,0 +1,3 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import controllers +from . import models diff --git a/addons/l10n_pe_website_sale/__manifest__.py b/addons/l10n_pe_website_sale/__manifest__.py new file mode 100644 index 00000000000..8053279f8a3 --- /dev/null +++ b/addons/l10n_pe_website_sale/__manifest__.py @@ -0,0 +1,26 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +{ + "name": "Peruvian eCommerce", + "countries": ["pe"], + "version": "0.1", + "summary": "Be able to see Identification Type in ecommerce checkout form.", + "category": "Accounting/Localizations/Website", + "author": "Vauxoo, Odoo", + "license": "LGPL-3", + "depends": [ + "website_sale", + "l10n_pe", + ], + "data": [ + "security/ir.model.access.csv", + "data/ir_model_fields.xml", + "views/templates.xml", + ], + "assets": { + "web.assets_frontend": [ + "l10n_pe_website_sale/static/src/js/website_sale.js", + ], + }, + "installable": True, + "auto_install": True, +} diff --git a/addons/l10n_pe_website_sale/controllers/__init__.py b/addons/l10n_pe_website_sale/controllers/__init__.py new file mode 100644 index 00000000000..9a57ed53e47 --- /dev/null +++ b/addons/l10n_pe_website_sale/controllers/__init__.py @@ -0,0 +1,2 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import main diff --git a/addons/l10n_pe_website_sale/controllers/main.py b/addons/l10n_pe_website_sale/controllers/main.py new file mode 100644 index 00000000000..15440854ba2 --- /dev/null +++ b/addons/l10n_pe_website_sale/controllers/main.py @@ -0,0 +1,86 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import http +from odoo.http import request + +from odoo.addons.website_sale.controllers.main import WebsiteSale + + +class L10nPEWebsiteSale(WebsiteSale): + + def _get_mandatory_fields_billing(self, country_id=False): + """Extend mandatory fields to add new identification, responsibility + city_id and district fields when company is Peru""" + res = super()._get_mandatory_fields_billing(country_id) + if request.website.sudo().company_id.country_id.code != "PE": + return res + # For Peruvian company, the VAT is required for all the partners + res.append("vat") + if country_id == request.website.sudo().company_id.country_id.id: + res += ["city_id", "l10n_pe_district", "l10n_latam_identification_type_id"] + res.remove("city") + return res + + def _get_mandatory_fields_shipping(self, country_id=False): + """Extend mandatory fields to add city_id and district fields when the selected country is Peru""" + res = super()._get_mandatory_fields_shipping(country_id) + if request.website.sudo().company_id.country_id.code != "PE": + return res + if country_id == request.website.sudo().company_id.country_id.id: + res += ["city_id", "l10n_pe_district"] + res.remove("city") + 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 == "PE": + values = render_values["checkout"] + state = "state_id" in values \ + and values["state_id"] != "" \ + and request.env["res.country.state"].browse(int(values["state_id"])) + city = "city_id" in values \ + and values["city_id"] != "" \ + and request.env["res.city"].browse(int(values["city_id"])) + to_include = { + "identification": kw.get("l10n_latam_identification_type_id"), + "identification_types": request.env["l10n_latam.identification.type"].sudo().search( + ["|", ("country_id", "=", False), ("country_id.code", "=", "PE")] + ), + } + if state: + to_include["state"] = state + to_include["state_cities"] = request.env["res.city"].sudo().search([("state_id", "=", state.id)]) + if city: + to_include["city"] = city + to_include["city_districts"] = request.env["l10n_pe.res.city.district"].sudo().search([("city_id", "=", city.id)]) + res.update(to_include) + return res + + def _get_vat_validation_fields(self, data): + res = super()._get_vat_validation_fields(data) + if request.website.sudo().company_id.account_fiscal_country_id.code == "PE": + res.update({ + "l10n_latam_identification_type_id": + int(data["l10n_latam_identification_type_id"]) + if data.get("l10n_latam_identification_type_id") else False, + "name": data.get("name", False), + }) + return res + + @http.route( + ['/shop/state_infos/'], + type="json", + auth="public", + methods=["POST"], + website=True, + ) + def state_infos(self, state, **kw): + states = request.env["res.city"].sudo().search([("state_id", "=", state.id)]) + return {'cities': [(c.id, c.name, c.l10n_pe_code) for c in states]} + + @http.route( + ['/shop/city_infos/'], type="json", auth="public", methods=["POST"], website=True + ) + def city_infos(self, city, **kw): + districts = request.env["l10n_pe.res.city.district"].sudo().search([("city_id", "=", city.id)]) + return {'districts': [(d.id, d.name, d.code) for d in districts]} diff --git a/addons/l10n_pe_website_sale/data/ir_model_fields.xml b/addons/l10n_pe_website_sale/data/ir_model_fields.xml new file mode 100644 index 00000000000..88d25759c6d --- /dev/null +++ b/addons/l10n_pe_website_sale/data/ir_model_fields.xml @@ -0,0 +1,13 @@ + + + + + res.partner + + + + diff --git a/addons/l10n_pe_website_sale/i18n/es.po b/addons/l10n_pe_website_sale/i18n/es.po new file mode 100644 index 00000000000..43c515d2dbd --- /dev/null +++ b/addons/l10n_pe_website_sale/i18n/es.po @@ -0,0 +1,65 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_pe_website_sale +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-15 18:53+0000\n" +"PO-Revision-Date: 2023-11-15 18:53+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_pe_website_sale +#: model:website,contact_us_button_url:l10n_pe_website_sale.default_website_pe +msgid "/contactus" +msgstr "" + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_website_sale.partner_info +msgid "" +msgstr "" + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_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 se permite cambiar el tipo de identificación una vez que se hayan emitido los documentos " +"para su cuenta. Póngase en contacto con nosotros directamente para esta operación." + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_website_sale.partner_address_info +msgid "City" +msgstr "Ciudad" + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_website_sale.partner_address_info +msgid "District" +msgstr "Distrito" + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_website_sale.address +msgid "Identification Number" +msgstr "Número de identificación" + +#. module: l10n_pe_website_sale +#: model_terms:ir.ui.view,arch_db:l10n_pe_website_sale.partner_info +msgid "Identification Type" +msgstr "Tipo de Identificación" + +#. module: l10n_pe_website_sale +#: model:website,prevent_zero_price_sale_text:l10n_pe_website_sale.default_website_pe +msgid "Not Available For Sale" +msgstr "" + +#. module: l10n_pe_website_sale +#: model:ir.model,name:l10n_pe_website_sale.model_website +msgid "Website" +msgstr "Sitio web" diff --git a/addons/l10n_pe_website_sale/models/__init__.py b/addons/l10n_pe_website_sale/models/__init__.py new file mode 100644 index 00000000000..b8a42297a59 --- /dev/null +++ b/addons/l10n_pe_website_sale/models/__init__.py @@ -0,0 +1,3 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import website diff --git a/addons/l10n_pe_website_sale/models/website.py b/addons/l10n_pe_website_sale/models/website.py new file mode 100644 index 00000000000..1a28e3c8794 --- /dev/null +++ b/addons/l10n_pe_website_sale/models/website.py @@ -0,0 +1,12 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class Website(models.Model): + _inherit = "website" + + def _display_partner_b2b_fields(self): + """Peruvian localization must always display b2b fields""" + self.ensure_one() + return self.company_id.country_id.code == "PE" or super()._display_partner_b2b_fields() diff --git a/addons/l10n_pe_website_sale/security/ir.model.access.csv b/addons/l10n_pe_website_sale/security/ir.model.access.csv new file mode 100644 index 00000000000..1cd415c7836 --- /dev/null +++ b/addons/l10n_pe_website_sale/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_city_public,res_city_group_public,base_address_extended.model_res_city,base.group_public,1,0,0,0 +access_city_portal,res_city_group_portal,base_address_extended.model_res_city,base.group_portal,1,0,0,0 diff --git a/addons/l10n_pe_website_sale/static/src/js/website_sale.js b/addons/l10n_pe_website_sale/static/src/js/website_sale.js new file mode 100644 index 00000000000..7bc3f22f514 --- /dev/null +++ b/addons/l10n_pe_website_sale/static/src/js/website_sale.js @@ -0,0 +1,90 @@ +/** @odoo-module **/ +import {WebsiteSale} from "@website_sale/js/website_sale"; + +WebsiteSale.include({ + events: Object.assign({}, WebsiteSale.prototype.events, { + "change select[name='state_id']": "_onChangeState", + "change select[name='city_id']": "_onChangeCity", + }), + start: function () { + this.elementCities = document.querySelector("select[name='city_id']"); + this.elementDistricts = document.querySelector("select[name='l10n_pe_district']"); + this.cityBlock = document.querySelector(".div_city"); + this.autoFormat = document.querySelector(".checkout_autoformat"); + this.elementState = document.querySelector("select[name='state_id']"); + this.elemenCountry = document.querySelector("select[name='country_id']"); + this.isPeruvianCompany = this.elemenCountry?.dataset.company_country_code === 'PE'; + return this._super.apply(this, arguments); + }, + _changeOption: function (selectCheck, rpcRoute, place, selectElement) { + if (!selectCheck) { + return; + } + return this.rpc(rpcRoute, { + }).then((data) => { + if (this.isPeruvianCompany) { + if (data[place]?.length) { + selectElement.innerHTML = ""; + data[place].forEach((item) => { + let opt = document.createElement("option"); + opt.textContent = item[1]; + opt.value = item[0]; + opt.setAttribute("data-code", item[2]); + selectElement.appendChild(opt); + }); + selectElement.parentElement.style.display = "block"; + } else { + selectElement.value = ""; + selectElement.parentElement.style.display = "none"; + } + } + }); + }, + _onChangeState: function () { + if (this.isPeruvianCompany) { + if (this.elementState.value === "" && this.elemenCountry.value !== '') { + this.elementState.options[1].selected = true; + } + const state = this.elementState.value; + const rpcRoute = `/shop/state_infos/${state}`; + return this.autoFormat.length + ? this._changeOption(state, rpcRoute, "cities", this.elementCities).then(() => this._onChangeCity()) + : undefined; + } + }, + _onChangeCity: function () { + if (this.isPeruvianCompany) { + const city = this.elementCities.value; + const rpcRoute = `/shop/city_infos/${city}`; + return this.autoFormat.length + ? this._changeOption(city, rpcRoute, "districts", this.elementDistricts) + : undefined; + } + }, + _onChangeCountry: function (ev) { + return this._super.apply(this, arguments).then(() => { + if (this.isPeruvianCompany) { + let selectedCountry = ev.currentTarget.options[ev.currentTarget.selectedIndex].getAttribute("code"); + let cityInput = document.querySelector(".form-control[name='city']"); + if (selectedCountry == "PE") { + if (cityInput.value) { + cityInput.value = ""; + } + this.cityBlock.classList.add("d-none"); + return this._onChangeState().then(() => { + this._onChangeCity(); + }); + } else { + this.cityBlock.querySelectorAll("input").forEach((input) => { + input.value = ""; + }); + this.cityBlock.classList.remove("d-none"); + this.elementCities.value = ""; + this.elementCities.parentElement.style.display = "none"; + this.elementDistricts.value = ""; + this.elementDistricts.parentElement.style.display = "none"; + } + } + }); + }, +}); diff --git a/addons/l10n_pe_website_sale/views/templates.xml b/addons/l10n_pe_website_sale/views/templates.xml new file mode 100644 index 00000000000..27f4d3e59b5 --- /dev/null +++ b/addons/l10n_pe_website_sale/views/templates.xml @@ -0,0 +1,107 @@ + + + + + + + + + +