mirror of
https://github.com/bringout/oca-ocb-l10n_asia-pacific.git
synced 2026-04-27 05:02:04 +02:00
Initial commit: L10N_Asia Pacific packages
This commit is contained in:
commit
54c86b612c
828 changed files with 58224 additions and 0 deletions
13
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/__init__.py
Normal file
13
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/__init__.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import account
|
||||
from . import account_invoice
|
||||
from . import chart_template
|
||||
from . import product_template
|
||||
from . import port_code
|
||||
from . import res_config_settings
|
||||
from . import res_country_state
|
||||
from . import res_partner
|
||||
from . import uom_uom
|
||||
from . import mail_message
|
||||
77
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/account.py
Normal file
77
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/account.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo import tools
|
||||
|
||||
|
||||
class AccountJournal(models.Model):
|
||||
_inherit = "account.journal"
|
||||
|
||||
# Use for filter import and export type.
|
||||
l10n_in_gstin_partner_id = fields.Many2one('res.partner', string="GSTIN Unit", ondelete="restrict", help="GSTIN related to this journal. If empty then consider as company GSTIN.")
|
||||
|
||||
def name_get(self):
|
||||
"""
|
||||
Add GSTIN number in name as suffix so user can easily find the right journal.
|
||||
Used super to ensure nothing is missed.
|
||||
"""
|
||||
result = super().name_get()
|
||||
result_dict = dict(result)
|
||||
indian_journals = self.filtered(lambda j: j.company_id.account_fiscal_country_id.code == 'IN' and
|
||||
j.l10n_in_gstin_partner_id and j.l10n_in_gstin_partner_id.vat)
|
||||
for journal in indian_journals:
|
||||
name = result_dict[journal.id]
|
||||
name += "- %s" % (journal.l10n_in_gstin_partner_id.vat)
|
||||
result_dict[journal.id] = name
|
||||
return list(result_dict.items())
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = "account.move.line"
|
||||
|
||||
def init(self):
|
||||
tools.create_index(self._cr, 'account_move_line_move_product_index', self._table, ['move_id', 'product_id'])
|
||||
|
||||
@api.depends('move_id.line_ids', 'move_id.line_ids.tax_line_id', 'move_id.line_ids.debit', 'move_id.line_ids.credit')
|
||||
def _compute_tax_base_amount(self):
|
||||
aml = self.filtered(lambda l: l.company_id.account_fiscal_country_id.code == 'IN' and l.tax_line_id and l.product_id)
|
||||
for move_line in aml:
|
||||
base_lines = move_line.move_id.line_ids.filtered(lambda line: move_line.tax_line_id in line.tax_ids and move_line.product_id == line.product_id)
|
||||
move_line.tax_base_amount = abs(sum(base_lines.mapped('balance')))
|
||||
remaining_aml = self - aml
|
||||
if remaining_aml:
|
||||
return super(AccountMoveLine, remaining_aml)._compute_tax_base_amount()
|
||||
|
||||
|
||||
class AccountTax(models.Model):
|
||||
_inherit = 'account.tax'
|
||||
|
||||
l10n_in_reverse_charge = fields.Boolean("Reverse charge", help="Tick this if this tax is reverse charge. Only for Indian accounting")
|
||||
|
||||
@api.model
|
||||
def _get_generation_dict_from_base_line(self, line_vals, tax_vals, force_caba_exigibility=False):
|
||||
# EXTENDS account
|
||||
# Group taxes also by product.
|
||||
res = super()._get_generation_dict_from_base_line(line_vals, tax_vals, force_caba_exigibility=force_caba_exigibility)
|
||||
record = line_vals['record']
|
||||
if isinstance(record, models.Model)\
|
||||
and record._name == 'account.move.line'\
|
||||
and record.company_id.account_fiscal_country_id.code == 'IN':
|
||||
res['product_id'] = record.product_id.id
|
||||
res['product_uom_id'] = record.product_uom_id.id
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_generation_dict_from_tax_line(self, line_vals):
|
||||
# EXTENDS account
|
||||
# Group taxes also by product.
|
||||
res = super()._get_generation_dict_from_tax_line(line_vals)
|
||||
record = line_vals['record']
|
||||
if isinstance(record, models.Model)\
|
||||
and record._name == 'account.move.line'\
|
||||
and record.company_id.account_fiscal_country_id.code == 'IN':
|
||||
res['product_id'] = record.product_id.id
|
||||
res['product_uom_id'] = record.product_uom_id.id
|
||||
return res
|
||||
142
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/account_invoice.py
Normal file
142
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/account_invoice.py
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError, RedirectWarning, UserError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = "account.move"
|
||||
|
||||
amount_total_words = fields.Char("Total (In Words)", compute="_compute_amount_total_words")
|
||||
l10n_in_gst_treatment = fields.Selection([
|
||||
('regular', 'Registered Business - Regular'),
|
||||
('composition', 'Registered Business - Composition'),
|
||||
('unregistered', 'Unregistered Business'),
|
||||
('consumer', 'Consumer'),
|
||||
('overseas', 'Overseas'),
|
||||
('special_economic_zone', 'Special Economic Zone'),
|
||||
('deemed_export', 'Deemed Export'),
|
||||
('uin_holders', 'UIN Holders'),
|
||||
], string="GST Treatment", compute="_compute_l10n_in_gst_treatment", store=True, readonly=False, copy=True)
|
||||
l10n_in_state_id = fields.Many2one('res.country.state', string="Place of supply", compute="_compute_l10n_in_state_id", store=True, readonly=False)
|
||||
l10n_in_gstin = fields.Char(string="GSTIN")
|
||||
# For Export invoice this data is need in GSTR report
|
||||
l10n_in_shipping_bill_number = fields.Char('Shipping bill number', readonly=True, states={'draft': [('readonly', False)]})
|
||||
l10n_in_shipping_bill_date = fields.Date('Shipping bill date', readonly=True, states={'draft': [('readonly', False)]})
|
||||
l10n_in_shipping_port_code_id = fields.Many2one('l10n_in.port.code', 'Port code', readonly=True, states={'draft': [('readonly', False)]})
|
||||
l10n_in_reseller_partner_id = fields.Many2one('res.partner', 'Reseller', domain=[('vat', '!=', False)], help="Only Registered Reseller", readonly=True, states={'draft': [('readonly', False)]})
|
||||
l10n_in_journal_type = fields.Selection(string="Journal Type", related='journal_id.type')
|
||||
|
||||
@api.depends('amount_total')
|
||||
def _compute_amount_total_words(self):
|
||||
for invoice in self:
|
||||
invoice.amount_total_words = invoice.currency_id.amount_to_text(invoice.amount_total)
|
||||
|
||||
@api.depends('partner_id')
|
||||
def _compute_l10n_in_gst_treatment(self):
|
||||
indian_invoice = self.filtered(lambda m: m.country_code == 'IN')
|
||||
for record in indian_invoice:
|
||||
gst_treatment = record.partner_id.l10n_in_gst_treatment
|
||||
if not gst_treatment:
|
||||
gst_treatment = 'unregistered'
|
||||
if record.partner_id.country_id.code == 'IN' and record.partner_id.vat:
|
||||
gst_treatment = 'regular'
|
||||
elif record.partner_id.country_id and record.partner_id.country_id.code != 'IN':
|
||||
gst_treatment = 'overseas'
|
||||
record.l10n_in_gst_treatment = gst_treatment
|
||||
(self - indian_invoice).l10n_in_gst_treatment = False
|
||||
|
||||
@api.depends('partner_id', 'company_id')
|
||||
def _compute_l10n_in_state_id(self):
|
||||
for move in self:
|
||||
if move.country_code == 'IN' and move.journal_id.type == 'sale':
|
||||
country_code = move.partner_id.country_id.code
|
||||
if country_code == 'IN':
|
||||
move.l10n_in_state_id = move.partner_id.state_id
|
||||
elif country_code:
|
||||
move.l10n_in_state_id = self.env.ref('l10n_in.state_in_oc', raise_if_not_found=False)
|
||||
else:
|
||||
move.l10n_in_state_id = move.company_id.state_id
|
||||
elif move.country_code == 'IN' and move.journal_id.type == 'purchase':
|
||||
move.l10n_in_state_id = move.company_id.state_id
|
||||
else:
|
||||
move.l10n_in_state_id = False
|
||||
|
||||
def _get_name_invoice_report(self):
|
||||
if self.country_code == 'IN':
|
||||
# TODO: remove the view mode check in master, only for stable releases
|
||||
in_invoice_view = self.env.ref('l10n_in.l10n_in_report_invoice_document_inherit', raise_if_not_found=False)
|
||||
if (in_invoice_view and in_invoice_view.sudo().mode == "primary"):
|
||||
return 'l10n_in.l10n_in_report_invoice_document_inherit'
|
||||
return super()._get_name_invoice_report()
|
||||
|
||||
def _post(self, soft=True):
|
||||
"""Use journal type to define document type because not miss state in any entry including POS entry"""
|
||||
posted = super()._post(soft)
|
||||
gst_treatment_name_mapping = {k: v for k, v in
|
||||
self._fields['l10n_in_gst_treatment']._description_selection(self.env)}
|
||||
for move in posted.filtered(lambda m: m.country_code == 'IN' and m.is_sale_document()):
|
||||
"""Check state is set in company/sub-unit"""
|
||||
company_unit_partner = move.journal_id.l10n_in_gstin_partner_id or move.journal_id.company_id
|
||||
if move.l10n_in_state_id and not move.l10n_in_state_id.l10n_in_tin:
|
||||
raise UserError(_("Please set a valid TIN Number on the Place of Supply %s", move.l10n_in_state_id.name))
|
||||
if not company_unit_partner.state_id:
|
||||
msg = _("Your company %s needs to have a correct address in order to validate this invoice.\n"
|
||||
"Set the address of your company (Don't forget the State field)") % (company_unit_partner.name)
|
||||
action = {
|
||||
"view_mode": "form",
|
||||
"res_model": "res.company",
|
||||
"type": "ir.actions.act_window",
|
||||
"res_id" : move.company_id.id,
|
||||
"views": [[self.env.ref("base.view_company_form").id, "form"]],
|
||||
}
|
||||
raise RedirectWarning(msg, action, _('Go to Company configuration'))
|
||||
|
||||
move.l10n_in_gstin = move.partner_id.vat
|
||||
if not move.l10n_in_gstin and move.l10n_in_gst_treatment in ['regular', 'composition', 'special_economic_zone', 'deemed_export']:
|
||||
raise ValidationError(_(
|
||||
"Partner %(partner_name)s (%(partner_id)s) GSTIN is required under GST Treatment %(name)s",
|
||||
partner_name=move.partner_id.name,
|
||||
partner_id=move.partner_id.id,
|
||||
name=gst_treatment_name_mapping.get(move.l10n_in_gst_treatment)
|
||||
))
|
||||
return posted
|
||||
|
||||
def _l10n_in_get_warehouse_address(self):
|
||||
"""Return address where goods are delivered/received for Invoice/Bill"""
|
||||
# TO OVERRIDE
|
||||
self.ensure_one()
|
||||
return False
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _unlink_l10n_in_except_once_post(self):
|
||||
# Prevent deleting entries once it's posted for Indian Company only
|
||||
if any(m.country_code == 'IN' and m.posted_before for m in self) and not self._context.get('force_delete'):
|
||||
raise UserError(_("To keep the audit trail, you can not delete journal entries once they have been posted.\nInstead, you can cancel the journal entry."))
|
||||
|
||||
def _can_be_unlinked(self):
|
||||
self.ensure_one()
|
||||
return (self.country_code != 'IN' or not self.posted_before) and super()._can_be_unlinked()
|
||||
|
||||
def unlink(self):
|
||||
# Add logger here becouse in api ondelete account.move.line is deleted and we can't get total amount
|
||||
logger_msg = False
|
||||
if any(m.country_code == 'IN' and m.posted_before for m in self):
|
||||
if self._context.get('force_delete'):
|
||||
moves_details = ", ".join("{entry_number} ({move_id}) amount {amount_total} {currency} and partner {partner_name}".format(
|
||||
entry_number=m.name,
|
||||
move_id=m.id,
|
||||
amount_total=m.amount_total,
|
||||
currency=m.currency_id.name,
|
||||
partner_name=m.partner_id.display_name)
|
||||
for m in self)
|
||||
logger_msg = 'Force deleted Journal Entries %s by %s (%s)' % (moves_details, self.env.user.name, self.env.user.id)
|
||||
res = super().unlink()
|
||||
if logger_msg:
|
||||
_logger.info(logger_msg)
|
||||
return res
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class AccountChartTemplate(models.Model):
|
||||
_inherit = 'account.chart.template'
|
||||
|
||||
def _prepare_all_journals(self, acc_template_ref, company, journals_dict=None):
|
||||
res = super(AccountChartTemplate, self)._prepare_all_journals(acc_template_ref, company, journals_dict=journals_dict)
|
||||
if self == self.env.ref('l10n_in.indian_chart_template_standard'):
|
||||
for journal in res:
|
||||
if journal.get('type') in ('sale','purchase'):
|
||||
journal['l10n_in_gstin_partner_id'] = company.partner_id.id
|
||||
return res
|
||||
|
||||
def _load(self, company):
|
||||
res = super(AccountChartTemplate, self)._load(company)
|
||||
if self == self.env.ref("l10n_in.indian_chart_template_standard"):
|
||||
company.write({
|
||||
'account_opening_date': fields.Date.context_today(self).replace(month=4, day=1),
|
||||
'fiscalyear_last_month': '3',
|
||||
})
|
||||
return res
|
||||
|
||||
|
||||
class AccountTaxTemplate(models.Model):
|
||||
_inherit = 'account.tax.template'
|
||||
|
||||
l10n_in_reverse_charge = fields.Boolean("Reverse charge", help="Tick this if this tax is reverse charge. Only for Indian accounting")
|
||||
|
||||
def _get_tax_vals(self, company, tax_template_to_tax):
|
||||
val = super(AccountTaxTemplate, self)._get_tax_vals(company, tax_template_to_tax)
|
||||
if self.tax_group_id:
|
||||
val['l10n_in_reverse_charge'] = self.l10n_in_reverse_charge
|
||||
return val
|
||||
56
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/mail_message.py
Normal file
56
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/mail_message.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from markupsafe import Markup
|
||||
|
||||
from odoo import fields, api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class Message(models.Model):
|
||||
_inherit = 'mail.message'
|
||||
|
||||
l10n_in_audit_log_preview = fields.Html(string="Description", compute="_compute_l10n_in_audit_log_preview")
|
||||
l10n_in_audit_log_account_move_id = fields.Many2one('account.move', string="Journal Entry", compute="_compute_l10n_in_audit_log_document_name", search="_search_l10n_in_audit_log_document_name")
|
||||
|
||||
@api.depends('body', 'subject', 'tracking_value_ids', 'subtype_id')
|
||||
def _compute_l10n_in_audit_log_preview(self):
|
||||
for message in self:
|
||||
title = message.subject or message.preview
|
||||
tracking_value_ids = message.sudo().tracking_value_ids
|
||||
if not title and tracking_value_ids:
|
||||
title = _("Updated")
|
||||
elif not title and message.subtype_id and not message.subtype_id.internal:
|
||||
title = message.subtype_id.display_name
|
||||
audit_log_preview = Markup("<div>%s</div>") % (title)
|
||||
for value in tracking_value_ids:
|
||||
audit_log_preview += Markup(
|
||||
"<li>%(old_value)s <i class='o_TrackingValue_separator fa fa-long-arrow-right mx-1 text-600' title='%(title)s' role='img' aria-label='%(title)s'></i>%(new_value)s (%(field)s)</li>"
|
||||
) % {
|
||||
'old_value': value._get_old_display_value()[0] or _("None"),
|
||||
'new_value': value._get_new_display_value()[0] or _("None"),
|
||||
'title': _("Changed"),
|
||||
'field': value.field.field_description,
|
||||
}
|
||||
message.l10n_in_audit_log_preview = audit_log_preview
|
||||
|
||||
@api.depends('model', 'res_id')
|
||||
def _compute_l10n_in_audit_log_document_name(self):
|
||||
messages_of_account_move = self.filtered(lambda m: m.model == 'account.move' and m.res_id)
|
||||
(self - messages_of_account_move).l10n_in_audit_log_account_move_id = False
|
||||
moves = self.env['account.move'].search([('id', 'in', messages_of_account_move.mapped('res_id'))])
|
||||
moves_by_id = {m.id: m for m in moves}
|
||||
for message in messages_of_account_move:
|
||||
message.l10n_in_audit_log_account_move_id = moves_by_id.get(message.res_id, False)
|
||||
|
||||
def _search_l10n_in_audit_log_document_name(self, operator, value):
|
||||
is_set = False
|
||||
if operator == '!=' and isinstance(value, bool):
|
||||
is_set = True
|
||||
elif operator not in ['=', 'ilike'] or not isinstance(value, str):
|
||||
raise UserError(_('Operation not supported'))
|
||||
move_domain = [('company_id.account_fiscal_country_id.code', '=', 'IN')]
|
||||
if not is_set:
|
||||
move_domain += [('name', operator, value)]
|
||||
move_query = self.env['account.move']._search(move_domain)
|
||||
return [('model', '=', 'account.move'), ('res_id', 'in', move_query)]
|
||||
19
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/port_code.py
Normal file
19
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/port_code.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class L10nInPortCode(models.Model):
|
||||
"""Port code must be mentioned in export and import of goods under GST."""
|
||||
_name = 'l10n_in.port.code'
|
||||
_description = "Indian port code"
|
||||
_rec_name = 'code'
|
||||
|
||||
code = fields.Char(string="Port Code", required=True)
|
||||
name = fields.Char(string="Port", required=True)
|
||||
state_id = fields.Many2one('res.country.state', string="State")
|
||||
|
||||
_sql_constraints = [
|
||||
('code_uniq', 'unique (code)', 'The Port Code must be unique!')
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
l10n_in_hsn_code = fields.Char(string="HSN/SAC Code", help="Harmonized System Nomenclature/Services Accounting Code")
|
||||
l10n_in_hsn_description = fields.Char(string="HSN/SAC Description", help="HSN/SAC description is required if HSN/SAC code is not provided.")
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
group_l10n_in_reseller = fields.Boolean(implied_group='l10n_in.group_l10n_in_reseller', string="Manage Reseller(E-Commerce)")
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class CountryState(models.Model):
|
||||
_inherit = 'res.country.state'
|
||||
|
||||
l10n_in_tin = fields.Char('TIN Number', size=2, help="TIN number-first two digits")
|
||||
58
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/res_partner.py
Normal file
58
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/res_partner.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
TEST_GST_NUMBER = "36AABCT1332L011"
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
l10n_in_gst_treatment = fields.Selection([
|
||||
('regular', 'Registered Business - Regular'),
|
||||
('composition', 'Registered Business - Composition'),
|
||||
('unregistered', 'Unregistered Business'),
|
||||
('consumer', 'Consumer'),
|
||||
('overseas', 'Overseas'),
|
||||
('special_economic_zone', 'Special Economic Zone'),
|
||||
('deemed_export', 'Deemed Export'),
|
||||
('uin_holders', 'UIN Holders'),
|
||||
], string="GST Treatment")
|
||||
|
||||
@api.onchange('company_type')
|
||||
def onchange_company_type(self):
|
||||
res = super().onchange_company_type()
|
||||
if self.country_id and self.country_id.code == 'IN':
|
||||
self.l10n_in_gst_treatment = (self.company_type == 'company') and 'regular' or 'consumer'
|
||||
return res
|
||||
|
||||
@api.onchange('country_id')
|
||||
def _onchange_country_id(self):
|
||||
res = super()._onchange_country_id()
|
||||
if self.country_id and self.country_id.code != 'IN':
|
||||
self.l10n_in_gst_treatment = 'overseas'
|
||||
elif self.country_id and self.country_id.code == 'IN':
|
||||
self.l10n_in_gst_treatment = (self.company_type == 'company') and 'regular' or 'consumer'
|
||||
return res
|
||||
|
||||
@api.onchange('vat')
|
||||
def onchange_vat(self):
|
||||
if self.vat and self.check_vat_in(self.vat):
|
||||
state_id = self.env['res.country.state'].search([('l10n_in_tin', '=', self.vat[:2])], limit=1)
|
||||
if state_id:
|
||||
self.state_id = state_id
|
||||
|
||||
@api.model
|
||||
def _commercial_fields(self):
|
||||
res = super()._commercial_fields()
|
||||
return res + ['l10n_in_gst_treatment']
|
||||
|
||||
def check_vat_in(self, vat):
|
||||
"""
|
||||
This TEST_GST_NUMBER is used as test credentials for EDI
|
||||
but this is not a valid number as per the regular expression
|
||||
so TEST_GST_NUMBER is considered always valid
|
||||
"""
|
||||
if vat == TEST_GST_NUMBER:
|
||||
return True
|
||||
return super().check_vat_in(vat)
|
||||
11
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/uom_uom.py
Normal file
11
odoo-bringout-oca-ocb-l10n_in/l10n_in/models/uom_uom.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class UoM(models.Model):
|
||||
_inherit = "uom.uom"
|
||||
|
||||
# As per GST Rules you need to Specify UQC given by GST.
|
||||
l10n_in_code = fields.Char("Indian GST UQC", help="Unique Quantity Code (UQC) under GST")
|
||||
Loading…
Add table
Add a link
Reference in a new issue