Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] website_autocomplete_gst : Get Auto-completed Company address based on VAT #625

Draft
wants to merge 12 commits into
base: 18.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions website_autocomplete_gst/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
22 changes: 22 additions & 0 deletions website_autocomplete_gst/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
'name': "Website Autocomplete GST",
'version': "1.0",
'category': "Website/Website",
'summary': "Get Auto-completed Company address based on VAT",
'depends': [
'base', 'website_sale'
],
'description': """
This module adds an option of "do you want tax credit" during checkout proccess in website and upon entering valid VAT number auto-completes company address details
""",
'data' : [
'views/templates.xml'
],
'assets': {
'web.assets_frontend': [
'website_autocomplete_gst/static/src/js/**/*'
],
},
'installable' : True,
'license': "AGPL-3"
}
1 change: 1 addition & 0 deletions website_autocomplete_gst/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
56 changes: 56 additions & 0 deletions website_autocomplete_gst/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from odoo.http import request, route

from odoo.addons.website_sale.controllers import main


class WebsiteSale(main.WebsiteSale):
@route('/shop/checkout', type='http', methods=['GET'], auth='public', website=True, sitemap=False)
def shop_checkout(self, **kwargs):
vat_label = request.env._('VAT')
return super().shop_checkout(**kwargs)

@route('/shop/get_data', type='json', auth='public', website=True, sitemap=False)
def get_company_details(self):
vat = request.params.get('vat')
partner = request.env['res.partner']._get_company_details_from_vat(vat)
return partner if partner else {}

def _get_checkout_page_values(self, **kwargs):
qcontext = super()._get_checkout_page_values(**kwargs)
qcontext.pop('use_delivery_as_billing', None)
return qcontext

@route('/shop/update_invoice_address', type='json', auth='public', website=True)
def shop_update_invoice_address(self, address_type='billing', **kw):
company_data = self.get_company_details()
if company_data:
order_sudo = request.website.sale_get_order()
if order_sudo:
#Update the invoice address based on vat
ResPartner = request.env['res.partner']
exist_partner = ResPartner.search([
('vat', '=', company_data.get('vat'))
], limit=1)
if exist_partner:
order_sudo.partner_invoice_id = exist_partner
else:
order_sudo.partner_invoice_id = ResPartner.sudo().create({
'name': company_data.get('name'),
'company_type': 'company',
'parent_id': False,
'street': company_data.get('street'),
'street2': company_data.get('street2'),
'city': company_data.get('city'),
'state_id': company_data.get('state_id'),
'country_id': company_data.get('country_id'),
'zip': company_data.get('zip'),
'vat': company_data.get('vat'),
})
partner_fnames = set()
partner_sudo = ResPartner.browse(order_sudo.partner_invoice_id.id).exists()
if (address_type == 'billing' and partner_sudo != order_sudo.partner_invoice_id):
partner_fnames.add('partner_invoice_id')
order_sudo.sudo()._update_address(order_sudo.partner_invoice_id.id, partner_fnames)
order_sudo.partner_shipping_id.write({
'parent_id': order_sudo.partner_invoice_id.id,
})
1 change: 1 addition & 0 deletions website_autocomplete_gst/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_partner
29 changes: 29 additions & 0 deletions website_autocomplete_gst/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from odoo import models


class ResPartner(models.Model):
_inherit = 'res.partner'

def _can_be_edited_by_current_customer(self, sale_order, address_type):
return sale_order, address_type

def _get_company_details_from_vat(self, vat):
company_details = self.read_by_vat(vat)
company_data = company_details[0] if company_details else {}
if company_data:
partner_gid = company_data.get('partner_gid')
if partner_gid:
company_data = self.enrich_company(company_domain=None, partner_gid=partner_gid, vat=company_data.get('vat'))
return {
'name': company_data.get('name'),
'company_type': 'company',
'partner_id': partner_gid,
'street': company_data.get('street'),
'street2': company_data.get('street2'),
'city': company_data.get('city'),
'state_id': company_data.get('state_id', {}).get('id', False),
'country_id': company_data.get('country_id', {}).get('id', False),
'zip': company_data.get('zip'),
'vat': company_data.get('vat'),
}
return {}
95 changes: 95 additions & 0 deletions website_autocomplete_gst/static/src/js/checkout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { rpc } from "@web/core/network/rpc";
import publicWidget from '@web/legacy/js/public/public_widget';

publicWidget.registry.WebsiteSaleCheckout.include({
/**
* @override
*/
events: Object.assign({}, publicWidget.registry.WebsiteSaleCheckout.prototype.events, {
'change #want_tax_credit': '_toggleTaxCreditRow',
}),

async start() {
await this._super.apply(this, arguments);
this.want_tax_credit_toggle = document.querySelector('#want_tax_credit');
this.taxCreditContainer = this.el.querySelector('#tax_credit_container');
this.$vatInput = this.$("#o_vat");
this.$companyNameInput = this.$("#o_company_name");
if (this.$vatInput.length) {
this.$vatInput.on("change", this._fetchCompanyDetails.bind(this));
}
},

async _fetchCompanyDetails() {
const vat = this.$vatInput.val().trim();
if (!vat) {
return;
}
try {
const result = await rpc("/shop/get_data", { vat: vat });
if (result && result.name) {
console.log(result)
this.$companyNameInput.val(result.name);
await this.updateInvoiceAddress('billing', vat);
} else {
console.warn("Could not find any company registered to this VAT : ", vat);
}
} catch (error) {
console.error("Failed to fetch company details:", error);
}
},

async _changeAddress(ev) {
const newAddress = ev.currentTarget;
if (newAddress.classList.contains('bg-primary')) {
return;
}
const addressType = newAddress.dataset.addressType;
// Remove the highlighting from the previously selected address card.
const previousAddress = this._getSelectedAddress(addressType);
this._tuneDownAddressCard(previousAddress);
// Highlight the newly selected address card.
this._highlightAddressCard(newAddress);
const selectedPartnerId = newAddress.dataset.partnerId;
await this.updateAddress(addressType, selectedPartnerId);
// A delivery address is changed.
if (addressType === 'delivery' || this.taxCreditContainer.dataset.deliveryAddressDisabled) {
if (this.taxCreditContainer.dataset.deliveryAddressDisabled) {
// If a delivery address is disabled in the settings, use a billing address as
// a delivery one.
await this.updateAddress('delivery', selectedPartnerId);
}
if (!this.want_tax_credit_toggle?.checked) {
await this._selectMatchingBillingAddress(selectedPartnerId);
}
// Update the available delivery methods.
document.getElementById('o_delivery_form').innerHTML = await rpc(
'/shop/delivery_methods'
);
await this._prepareDeliveryMethods();
}
this._enableMainButton(); // Try to enable the main button.
},

async _toggleTaxCreditRow(ev) {
const useTaxCredit = ev.target.checked;
if (!useTaxCredit) {
this.taxCreditContainer.classList.add('d-none'); // Hide the Tax Credit row.
const selectedDeliveryAddress = this._getSelectedAddress('delivery');
await this._selectMatchingBillingAddress(selectedDeliveryAddress.dataset.partnerId);
} else {
this._disableMainButton();
this.taxCreditContainer.classList.remove('d-none'); // Show the Tax Credit row.
}

this._enableMainButton(); // Try to enable the main button.
},

async updateInvoiceAddress(addressType, vat) {
await rpc('/shop/update_invoice_address', { address_type: addressType, vat: vat });
},

_isBillingAddressSelected() {
return this.want_tax_credit_toggle?.checked;
},
});
53 changes: 53 additions & 0 deletions website_autocomplete_gst/views/templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0"?>
<odoo>
<template id="website_sale_address_inherit" inherit_id="website_sale.address" name="Address Management">
<xpath expr='//t[@t-if="website._display_partner_b2b_fields()"]' position="replace">
</xpath>
</template>
<template id="website_sale_billing_address_row_inherit" inherit_id="website_sale.billing_address_row">
<xpath expr="//div[@id='billing_address_row']" position="replace">
<div id="billing_address_row" class="mb-3">
<h4 class="text-uppercase small fs-6 fw-bold mt-3">
<t groups="!account.group_delivery_invoice_address">Your address</t>
</h4>
<t groups="account.group_delivery_invoice_address">
<t t-set="has_delivery" t-value="order._has_deliverable_products()"/>
<div t-if="has_delivery" class="form-check form-switch mt-2 mb-3">
<label id="want_tax_credit_label">
<input type="checkbox" id="want_tax_credit" class="form-check-input" t-att-checked="want_tax_credit"/>
want tax-credit
</label>
</div>
</t>
<t t-set="tax_credit_enable" groups="!account.group_delivery_invoice_address" t-value="True"/>
<t t-set="tax_credit_enable" groups="account.group_delivery_invoice_address" t-value="False"/>
<div id="tax_credit_container" t-attf-class="{{'d-none' if not want_tax_credit and has_delivery else ''}}" t-att-data-tax-credit-enable="tax_credit_enable">
<label for="o_vat">
<t t-out="vat_label or 'VAT'"/>
<input type="text" id="o_vat" name="vat" t-att-value="vat" class="form-control"/>
</label>
<label>
Company Name
<input type="text" id="o_company_name" name="name" autocomplete="organization" class="form-control"/>
</label>
</div>
</div>
</xpath>
</template>
<template id="address_on_payment_inherit" inherit_id="website_sale.address_on_payment" name="Address on payment">
<xpath expr="//div[hasclass('card')]" position="replace">
<div class="card">
<div class="card-body" id="delivery_and_billing">
<a class="float-end no-decoration" href="/shop/checkout">
<i class="fa fa-pencil me-1"/>
Edit
</a>
<t>
<b>Delivery: </b>
<span t-out="order.partner_shipping_id" t-options="dict(widget='contact', fields=['address'], no_marker=True, separator=', ')" class="address-inline"/>
</t>
</div>
</div>
</xpath>
</template>
</odoo>