[IMP] l10n_in*: multi GSTIN Using journal
=======
Purpose
=======
government rule that "GST registration should be obtained by a taxable person under GST in each of the State or Union Territory, from where the taxable supply of goods or services is made"
So we managed this using journal
User create journal and partner for other states
After user can select journal in Sale order, Purchase order and warehouse
========
Solution
========
-Add a field on the journal to define the GSTIN
-Add sale and purchase journal field in warehouse
-On the SO/PO, add the journal field and based on the warehouse journal it set automatically fill if warehouse journal is set.
task 1917619
This commit is contained in:
@@ -10,6 +10,22 @@ class AccountJournal(models.Model):
|
||||
|
||||
# Use for filter import and export type.
|
||||
l10n_in_import_export = fields.Boolean("Import/Export", help="Tick this if this journal is use for Import/Export Under Indian GST.")
|
||||
l10n_in_gstin_partner_id = fields.Many2one('res.partner', string="GSTIN", 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.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):
|
||||
|
||||
@@ -11,12 +11,14 @@ class AccountChartTemplate(models.Model):
|
||||
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
|
||||
if journal['code'] == 'INV':
|
||||
journal['name'] = _('Tax Invoices')
|
||||
|
||||
res += [
|
||||
{'type': 'sale', 'name': _('Retail Invoices'), 'code': 'RETINV', 'company_id': company.id, 'show_on_dashboard': True,},
|
||||
{'type': 'sale', 'name': _('Export Invoices'), 'code': 'EXPINV', 'company_id': company.id, 'show_on_dashboard': True, 'l10n_in_import_export': True}
|
||||
{'type': 'sale', 'name': _('Retail Invoices'), 'code': 'RETINV', 'company_id': company.id, 'show_on_dashboard': True, 'l10n_in_gstin_partner_id': company.partner_id.id},
|
||||
{'type': 'sale', 'name': _('Export Invoices'), 'code': 'EXPINV', 'company_id': company.id, 'show_on_dashboard': True, 'l10n_in_import_export': True, 'l10n_in_gstin_partner_id': company.partner_id.id}
|
||||
]
|
||||
return res
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
<xpath expr="//field[@name='loss_account_id']" position="after">
|
||||
<field name="l10n_in_import_export" attrs="{'invisible': [('type', 'not in', ['sale', 'purchase'])]}"/>
|
||||
</xpath>
|
||||
<field name="company_id" position="after">
|
||||
<field name="l10n_in_gstin_partner_id" context="{'show_vat':True}" options='{"no_create": True,"always_reload": True}'/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
],
|
||||
'data': [
|
||||
'views/report_purchase_order.xml',
|
||||
'views/purchase_order_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import purchase_order
|
||||
from . import account_move
|
||||
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
@api.onchange('purchase_vendor_bill_id', 'purchase_id')
|
||||
def _onchange_purchase_auto_complete(self):
|
||||
if self.purchase_vendor_bill_id.purchase_order_id or self.purchase_id:
|
||||
journal_id = self.purchase_vendor_bill_id.purchase_order_id.l10n_in_journal_id or self.purchase_id.l10n_in_journal_id
|
||||
if journal_id:
|
||||
self.journal_id = journal_id
|
||||
return super()._onchange_purchase_auto_complete()
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class PurchaseOrder(models.Model):
|
||||
_inherit = "purchase.order"
|
||||
|
||||
l10n_in_journal_id = fields.Many2one('account.journal', string="Journal", \
|
||||
states={'posted': [('readonly', True)]}, domain="[('type','=', 'purchase')]")
|
||||
|
||||
@api.onchange('company_id')
|
||||
def l10n_in_onchange_company_id(self):
|
||||
domain = [('company_id', '=', self.company_id.id), ('type', '=', 'purchase')]
|
||||
|
||||
journal = self.env['account.journal'].search(domain, limit=1)
|
||||
if journal:
|
||||
self.l10n_in_journal_id = journal.id
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_purchase_order_form_inherit_l10n_in_purchase" model="ir.ui.view">
|
||||
<field name="name">purchase.order.form.inherit.l10n.in.purchase</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='other_info']//field[@name='user_id']" position="after">
|
||||
<field name="l10n_in_journal_id" domain="[('company_id', '=', company_id), ('type','=','purchase')]" options="{'no_create': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': "India Purchase and Warehouse Management",
|
||||
|
||||
'summary': """
|
||||
Define default purchase journal on the warehouse""",
|
||||
|
||||
'description': """
|
||||
Define default purchase journal on the warehouse,
|
||||
help you to choose correct purchase journal on the purchase order when
|
||||
you change the picking operation.
|
||||
useful when you setup the multiple GSTIN units.
|
||||
""",
|
||||
|
||||
'author': "Odoo",
|
||||
'website': "https://www.odoo.com",
|
||||
'category': 'Accounting/Accounting',
|
||||
'version': '1.0',
|
||||
|
||||
'depends': ['l10n_in_purchase', 'l10n_in_stock'],
|
||||
|
||||
'data': [
|
||||
'views/stock_warehouse_views.xml',
|
||||
],
|
||||
'auto_install': True
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import purchase_order
|
||||
from . import stock_warehouse
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class PurchaseOrder(models.Model):
|
||||
_inherit = "purchase.order"
|
||||
|
||||
@api.onchange('company_id', 'picking_type_id')
|
||||
def l10n_in_onchange_company_id(self):
|
||||
if self.picking_type_id.warehouse_id and self.picking_type_id.warehouse_id.l10n_in_purchase_journal_id:
|
||||
self.l10n_in_journal_id = self.picking_type_id.warehouse_id.l10n_in_purchase_journal_id.id
|
||||
else:
|
||||
super().l10n_in_onchange_company_id()
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class Stock(models.Model):
|
||||
_inherit = 'stock.warehouse'
|
||||
|
||||
l10n_in_purchase_journal_id = fields.Many2one('account.journal', string="Purchase Journal")
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_stock_warehouse_inherit_l10n_in_stock" model="ir.ui.view">
|
||||
<field name="name">stock.warehouse.form.inherit.l10n.in.stock</field>
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="inherit_id" ref="stock.view_warehouse"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="l10n_in_purchase_journal_id" domain="[('company_id', '=', company_id), ('type','=','purchase')]" options="{'no_create': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -3,3 +3,4 @@
|
||||
|
||||
from . import models
|
||||
from . import report
|
||||
from . import wizard
|
||||
|
||||
@@ -9,8 +9,19 @@ class SaleOrder(models.Model):
|
||||
|
||||
l10n_in_reseller_partner_id = fields.Many2one('res.partner',
|
||||
string='Reseller', domain="[('vat', '!=', False), '|', ('company_id', '=', False), ('company_id', '=', company_id)]", states={'posted': [('readonly', True)]})
|
||||
l10n_in_journal_id = fields.Many2one('account.journal', string="Journal", states={'posted': [('readonly', True)]})
|
||||
|
||||
def _prepare_invoice(self):
|
||||
invoice_vals = super(SaleOrder, self)._prepare_invoice()
|
||||
invoice_vals['l10n_in_reseller_partner_id'] = self.l10n_in_reseller_partner_id.id
|
||||
if self.l10n_in_journal_id:
|
||||
invoice_vals['journal_id'] = self.l10n_in_journal_id.id
|
||||
return invoice_vals
|
||||
|
||||
@api.onchange('company_id')
|
||||
def l10n_in_onchange_company_id(self):
|
||||
domain = [('company_id', '=', self.company_id.id), ('type', '=', 'sale')]
|
||||
|
||||
journal = self.env['account.journal'].search(domain, limit=1)
|
||||
if journal:
|
||||
self.l10n_in_journal_id = journal.id
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="l10n_in_reseller_partner_id" groups="l10n_in.group_l10n_in_reseller"/>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='sale_info']//field[@name='invoice_status']" position="after">
|
||||
<field name="l10n_in_journal_id" domain="[('company_id', '=', company_id), ('type','=','sale')]" options="{'no_create': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import sale_make_invoice_advance
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class SaleAdvancePaymentInv(models.TransientModel):
|
||||
_inherit = "sale.advance.payment.inv"
|
||||
|
||||
def _create_invoice(self, order, so_line, amount):
|
||||
invoice = super()._create_invoice(order, so_line, amount)
|
||||
if order.l10n_in_journal_id:
|
||||
invoice.journal_id = order.l10n_in_journal_id
|
||||
return invoice
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': "India Sales and Warehouse Management",
|
||||
|
||||
'summary': """
|
||||
Define default sales journal on the warehouse""",
|
||||
|
||||
'description': """
|
||||
Define default sales journal on the warehouse,
|
||||
help you to choose correct sales journal on the sales order when
|
||||
you change the warehouse.
|
||||
useful when you setup the multiple GSTIN units.
|
||||
""",
|
||||
|
||||
'author': "Odoo",
|
||||
'website': "https://www.odoo.com",
|
||||
'category': 'Accounting/Accounting',
|
||||
'version': '0.1',
|
||||
|
||||
'depends': ['l10n_in_sale', 'l10n_in_stock'],
|
||||
|
||||
'data': [
|
||||
'views/stock_warehouse_views.xml',
|
||||
],
|
||||
'auto_install': True
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import sale_order
|
||||
from . import stock_warehouse
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
@api.onchange('company_id', 'warehouse_id')
|
||||
def l10n_in_onchange_company_id(self):
|
||||
if self.warehouse_id.l10n_in_sale_journal_id:
|
||||
self.l10n_in_journal_id = self.warehouse_id.l10n_in_sale_journal_id.id
|
||||
else:
|
||||
super().l10n_in_onchange_company_id()
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class Stock(models.Model):
|
||||
_inherit = 'stock.warehouse'
|
||||
|
||||
l10n_in_sale_journal_id = fields.Many2one('account.journal', string="Sale Journal")
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_stock_warehouse_inherit_l10n_in_stock" model="ir.ui.view">
|
||||
<field name="name">stock.warehouse.form.inherit.l10n.in.stock</field>
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="inherit_id" ref="stock.view_warehouse"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="l10n_in_sale_journal_id" domain="[('company_id', '=', company_id), ('type','=','sale')]" options="{'no_create': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user