[ADD] l10n_in_edi_ewaybill: Create Indian E-waybill from invoice/bill
This module creates E-waybill in two types
1) Based on E-invoice API:
Generates the E-waybill using the Invoice Registration Number (IRN) that create by the E-invoice service
2) Direct using E-waybill API:
Generates the E-waybill using E-waybill API
X-original-commit: 2374d127792b3412e0ffe62515499d5b8f8ba434
Part-of: odoo/odoo#109390
This commit is contained in:
committed by
Josse Colpaert
parent
2c65d25e95
commit
be311c72fc
@@ -18,7 +18,7 @@ We use "Tera Software Limited" as GSP
|
||||
|
||||
Step 1: First you need to create an API username and password in the E-invoice portal.
|
||||
Step 2: Switch to company related to that GST number
|
||||
Step 3: Set that username and password in Odoo (Goto: Invoicing/Accounting -> Configration -> Settings -> Customer Invoices or find "E-invoice" in search bar)
|
||||
Step 3: Set that username and password in Odoo (Goto: Invoicing/Accounting -> Configuration -> Settings -> Customer Invoices or find "E-invoice" in search bar)
|
||||
Step 4: Repeat steps 1,2,3 for all GSTIN you have in odoo. If you have a multi-company with the same GST number then perform step 1 for the first company only.
|
||||
|
||||
For the creation of API username and password please ref this document: <https://service.odoo.co.in/einvoice_create_api_user>
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
"name": """Indian - E-waybill""",
|
||||
"version": "1.03.00",
|
||||
"icon": "/l10n_in/static/description/icon.png",
|
||||
"category": "Accounting/Localizations/EDI",
|
||||
"depends": [
|
||||
"l10n_in_edi",
|
||||
],
|
||||
"description": """
|
||||
Indian - E-waybill
|
||||
====================================
|
||||
To submit E-waybill through API to the government.
|
||||
We use "Tera Software Limited" as GSP
|
||||
|
||||
Step 1: First you need to create an API username and password in the E-waybill portal.
|
||||
Step 2: Switch to company related to that GST number
|
||||
Step 3: Set that username and password in Odoo (Goto: Invoicing/Accounting -> Configration -> Settings -> Indian Electronic WayBill or find "E-waybill" in search bar)
|
||||
Step 4: Repeat steps 1,2,3 for all GSTIN you have in odoo. If you have a multi-company with the same GST number then perform step 1 for the first company only.
|
||||
""",
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"data/account_edi_data.xml",
|
||||
"data/ewaybill_type_data.xml",
|
||||
"views/account_move_views.xml",
|
||||
"views/edi_pdf_report.xml",
|
||||
"views/res_config_settings_views.xml",
|
||||
],
|
||||
"demo": [
|
||||
"demo/demo_company.xml",
|
||||
"demo/res_partner_demo.xml",
|
||||
"demo/account_invoice_demo.xml",
|
||||
],
|
||||
"installable": True,
|
||||
# not applicable when company is related to service industry so auto install is False
|
||||
"auto_install": False,
|
||||
"license": "LGPL-3",
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="edi_in_ewaybill_json_1_03" model="account.edi.format">
|
||||
<field name="name">E-waybill (IN)</field>
|
||||
<field name="code">in_ewaybill_1_03</field>
|
||||
</record>
|
||||
</odoo>
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Document Type -->
|
||||
<record id="type_tax_invoice_sub_type_supply" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Tax Invoice</field>
|
||||
<field name="code">INV</field>
|
||||
<field name="sub_type">Supply</field>
|
||||
<field name="sub_type_code">1</field>
|
||||
<field name="allowed_supply_type">both</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_tax_invoice_sub_type_export" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Tax Invoice</field>
|
||||
<field name="code">INV</field>
|
||||
<field name="sub_type">Export</field>
|
||||
<field name="sub_type_code">3</field>
|
||||
<field name="allowed_supply_type">out</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_tax_invoice_sub_type_skd_ckd_lots" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Tax Invoice</field>
|
||||
<field name="code">INV</field>
|
||||
<field name="sub_type">SKD/CKD/Lots</field>
|
||||
<field name="sub_type_code">9</field>
|
||||
<field name="allowed_supply_type">both</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_bill_of_supply_sub_type_supply" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Bill of Supply</field>
|
||||
<field name="code">BIL</field>
|
||||
<field name="sub_type">Supply</field>
|
||||
<field name="sub_type_code">1</field>
|
||||
<field name="allowed_supply_type">both</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_bill_of_supply_sub_type_export" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Bill of Supply</field>
|
||||
<field name="code">BIL</field>
|
||||
<field name="sub_type">Export</field>
|
||||
<field name="sub_type_code">3</field>
|
||||
<field name="allowed_supply_type">out</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_bill_of_supply_sub_type_skd_ckd_lots" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Bill of Supply</field>
|
||||
<field name="code">BIL</field>
|
||||
<field name="sub_type">SKD/CKD/Lots</field>
|
||||
<field name="sub_type_code">9</field>
|
||||
<field name="allowed_supply_type">both</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="type_bill_of_entry_sub_type_import" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Bill of Entry</field>
|
||||
<field name="code">BOE</field>
|
||||
<field name="sub_type">Import</field>
|
||||
<field name="sub_type_code">2</field>
|
||||
<field name="allowed_supply_type">in</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
<record id="type_bill_of_entry_sub_skd_ckd_lots" model="l10n.in.ewaybill.type">
|
||||
<field name="name">Bill of Entry</field>
|
||||
<field name="code">BOE</field>
|
||||
<field name="sub_type">SKD/CKD/Lots</field>
|
||||
<field name="sub_type_code">9</field>
|
||||
<field name="allowed_supply_type">in</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<function model="account.journal" name="write">
|
||||
<value model="account.journal"
|
||||
eval="obj().search([
|
||||
('type', '=', 'sale'),
|
||||
('company_id', '=', ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill'))], limit=1).ids"/>
|
||||
<value eval="{'edi_format_ids': [(6,0,[ref('edi_in_ewaybill_json_1_03')])]}"/>
|
||||
</function>
|
||||
<!-- Demo of B2B (business-to-business) Taxable supplies made to other registered person.-->
|
||||
<record id="demo_invoice_b2b_ewaybill" model="account.move">
|
||||
<field name="move_type">out_invoice</field>
|
||||
<field name="partner_id" ref="res_partner_registered_customer_ewaybill"/>
|
||||
<field name="invoice_user_id" ref="base.user_demo"/>
|
||||
<field name="invoice_payment_term_id" ref="account.account_payment_term_end_following_month"/>
|
||||
<field name="invoice_date" eval="time.strftime('%Y-%m')+'-01'"/>
|
||||
<field name="l10n_in_gst_treatment">regular</field>
|
||||
<field name="l10n_in_type_id" ref="type_tax_invoice_sub_type_supply"/>
|
||||
<field name="l10n_in_distance">20</field>
|
||||
<field name="l10n_in_mode">1</field>
|
||||
<field name="l10n_in_vehicle_no">GJ11OD1234</field>
|
||||
<field name="l10n_in_vehicle_type">R</field>
|
||||
<field name="journal_id" model="account.journal"
|
||||
eval="obj().search([
|
||||
('type', '=', 'sale'),
|
||||
('company_id', '=', ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill'))], limit=1).id"/>
|
||||
<field name="invoice_line_ids" model="account.move.line" eval="[
|
||||
(0, 0, {
|
||||
'product_id': ref('product.product_product_8'),
|
||||
'quantity': 2,
|
||||
'price_unit': 40000.0,
|
||||
'tax_ids': [(6, 0, obj().tax_ids.search([
|
||||
('company_id', '=', ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill')),
|
||||
('type_tax_use', '=', 'sale'),
|
||||
('amount','=', 28),
|
||||
('tax_group_id', '=', ref('l10n_in.igst_group'))], limit=1).ids)]
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': ref('product.product_product_9'),
|
||||
'quantity': 3,
|
||||
'price_unit': 400.0,
|
||||
'tax_ids': [(6, 0, obj().tax_ids.search([
|
||||
('company_id', '=', ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill')),
|
||||
('type_tax_use', '=', 'sale'),
|
||||
('amount','=', 18),
|
||||
('tax_group_id', '=', ref('l10n_in.igst_group'))], limit=1).ids)]
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': ref('product.product_product_10'),
|
||||
'quantity': 4,
|
||||
'price_unit': 300.0,
|
||||
'tax_ids': [(6, 0, obj().tax_ids.search([
|
||||
('company_id', '=', ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill')),
|
||||
('type_tax_use', '=', 'sale'),
|
||||
'|',
|
||||
'&',
|
||||
('amount', '=', 18),
|
||||
('tax_group_id', '=', ref('l10n_in.igst_group')),
|
||||
'&',
|
||||
('tax_group_id', '=', ref('l10n_in.cess_group')),
|
||||
('children_tax_ids.amount','=', 5)
|
||||
], limit=2).ids)]
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
</odoo>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="partner_demo_company_in_ewaybill" model="res.partner">
|
||||
<field name="name">E-Waybill Company</field>
|
||||
<field name="vat">05AAACH6188F1ZM</field>
|
||||
<field name="street">46B 49B, RAIPUR</field>
|
||||
<field name="street2">BHAGWANPUR, ROORKEE</field>
|
||||
<field name="city">Haridwar</field>
|
||||
<field name="country_id" ref="base.in"/>
|
||||
<field name="state_id" ref="base.state_in_uk"/>
|
||||
<field name="zip">247667</field>
|
||||
</record>
|
||||
|
||||
<record id="demo_company_in_ewaybill" model="res.company">
|
||||
<field name="name">E-Waybill Company</field>
|
||||
<field name="partner_id" ref="partner_demo_company_in_ewaybill"/>
|
||||
<field name="l10n_in_edi_ewaybill_username">05AAACH6188F1ZM</field>
|
||||
<field name="l10n_in_edi_ewaybill_password">abc123@@</field>
|
||||
</record>
|
||||
|
||||
<function model="res.company" name="_onchange_country_id">
|
||||
<value eval="[ref('demo_company_in_ewaybill')]"/>
|
||||
</function>
|
||||
|
||||
<function model="res.users" name="write">
|
||||
<value eval="[ref('base.user_root'), ref('base.user_admin'), ref('base.user_demo')]"/>
|
||||
<value eval="{'company_ids': [(4, ref('demo_company_in_ewaybill'))]}"/>
|
||||
</function>
|
||||
|
||||
<function model="account.chart.template" name="try_loading">
|
||||
<value eval="[ref('l10n_in.indian_chart_template_standard')]"/>
|
||||
<value model="res.company" eval="obj().env.ref('l10n_in_edi_ewaybill.demo_company_in_ewaybill')"/>
|
||||
</function>
|
||||
</odoo>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_partner_registered_customer_ewaybill" model="res.partner">
|
||||
<field name="name">Registered Customer (E-Waybill)</field>
|
||||
<field eval="[(6, 0, [ref('l10n_in.res_partner_category_registered')])]" name="category_id"/>
|
||||
<field name="is_company">1</field>
|
||||
<field name="l10n_in_gst_treatment">regular</field>
|
||||
<field name="street">19, Ground Floor</field>
|
||||
<field name="street2">Survey Road</field>
|
||||
<field name="city">Dehradun</field>
|
||||
<field name="zip">248001</field>
|
||||
<field name="state_id" ref="base.state_in_uk"/>
|
||||
<field name="country_id" ref="base.in"/>
|
||||
<field name="vat">05AAACH6605F1Z0</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,522 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_in_edi_ewaybill
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 15.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-01-06 21:57+0000\n"
|
||||
"PO-Revision-Date: 2023-01-06 21:57+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_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/ewaybill_type.py:0
|
||||
#, python-format
|
||||
msgid " (Sub-Type: %s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "%s number should be set and not more than 16 characters"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "- Document Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"- Transport document number and date is required when Transportation Mode is"
|
||||
" Rail,Air or Ship"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "- Transportation Mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "- Transporter is required when E-waybill is managed by transporter"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"- Vehicle Number and Type is required when Transportation Mode is By Road"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid ""
|
||||
"<span class=\"fa fa-lg fa-building-o\" title=\"Values set here are company-"
|
||||
"specific.\" aria-label=\"Values set here are company-specific.\" "
|
||||
"groups=\"base.group_multi_company\" role=\"img\"/>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "<span>km</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.l10n_in_einvoice_report_invoice_document_inherit
|
||||
msgid "<strong>E-waybill Number:</strong>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.l10n_in_einvoice_report_invoice_document_inherit
|
||||
msgid "<strong>E-waybill Valid Till:</strong>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A username and password still needs to be set or it's wrong for the "
|
||||
"E-waybill(IN). It needs to be added and verify in the Settings."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__active
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_mode__3
|
||||
msgid "Air"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__allowed_supply_type
|
||||
msgid "Allowed for supply type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_mode__1
|
||||
msgid "By Road"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Cancel Reason"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model,name:l10n_in_edi_ewaybill.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model,name:l10n_in_edi_ewaybill.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_transportation_doc_date
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_move__l10n_in_transportation_doc_date
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_payment__l10n_in_transportation_doc_date
|
||||
msgid "Date on the transporter document"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_distance
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_distance
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_distance
|
||||
msgid "Distance"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_transportation_doc_date
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_transportation_doc_date
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_transportation_doc_date
|
||||
msgid "Document Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_transportation_doc_no
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_transportation_doc_no
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_transportation_doc_no
|
||||
msgid "Document Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_type_id
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_type_id
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_type_id
|
||||
msgid "Document Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_res_company__l10n_in_edi_ewaybill_password
|
||||
msgid "E-Waybill (IN) Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_res_company__l10n_in_edi_ewaybill_username
|
||||
msgid "E-Waybill (IN) Username"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_res_company__l10n_in_edi_ewaybill_auth_validity
|
||||
msgid "E-Waybill (IN) Valid Until"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model,name:l10n_in_edi_ewaybill.model_l10n_in_ewaybill_type
|
||||
msgid "E-Waybill Document Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_move.py:0
|
||||
#, python-format
|
||||
msgid "E-waybill is already created"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_edi_ewaybill_direct_api
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_edi_ewaybill_direct_api
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_edi_ewaybill_direct_api
|
||||
msgid "E-waybill(IN) direct API"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model,name:l10n_in_edi_ewaybill.model_account_edi_format
|
||||
msgid "EDI format"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "HSN code is not set in product %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Impossible to send the Ewaybill."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__l10n_in_ewaybill_type__allowed_supply_type__in
|
||||
msgid "Incoming"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__l10n_in_ewaybill_type__allowed_supply_type__both
|
||||
msgid "Incoming and Outgoing"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/res_config_settings.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Incorrect username or password, or the GST number on company does not match."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_res_config_settings__l10n_in_edi_ewaybill_password
|
||||
msgid "Indian EDI Stock password"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_res_config_settings__l10n_in_edi_ewaybill_username
|
||||
msgid "Indian EDI Stock username"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Indian Electronic WayBill"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Invalid HSN Code (%s) in product %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_move.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Invalid invoice configuration:\n"
|
||||
"\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model,name:l10n_in_edi_ewaybill.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_mode__0
|
||||
msgid "Managed by Transporter"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_vehicle_type__o
|
||||
msgid "ODC"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Only check if you are in production."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__l10n_in_ewaybill_type__allowed_supply_type__out
|
||||
msgid "Outgoing"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Production Environment"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_mode__2
|
||||
msgid "Rail"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_vehicle_type__r
|
||||
msgid "Regular"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Send E-waybill"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Setup E-Waybill"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Setup E-Waybill Service for this company"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields.selection,name:l10n_in_edi_ewaybill.selection__account_move__l10n_in_mode__4
|
||||
msgid "Ship"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_edi_ewaybill_show_send_button
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_edi_ewaybill_show_send_button
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_edi_ewaybill_show_send_button
|
||||
msgid "Show Send E-waybill Button"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Somehow this E-waybill has been canceled in the government portal before. "
|
||||
"You can verify by checking the details into the government "
|
||||
"(https://ewaybillgst.gov.in/Others/EBPrintnew.asp)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Somehow this E-waybill has been generated in the government portal before. "
|
||||
"You can verify by checking the invoice details into the government "
|
||||
"(https://ewaybillgst.gov.in/Others/EBPrintnew.asp)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__sub_type
|
||||
msgid "Sub-type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__sub_type_code
|
||||
msgid "Sub-type Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The following information are missing on the invoice (see eWayBill tab):"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_move.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"To cancel E-waybill set cancel reason and remarks at E-waybill tab in: \n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Transaction Details"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_transportation_doc_no
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_move__l10n_in_transportation_doc_no
|
||||
#: model:ir.model.fields,help:l10n_in_edi_ewaybill.field_account_payment__l10n_in_transportation_doc_no
|
||||
msgid ""
|
||||
"Transport document number. If it is more than 15 chars, last 15 chars may be"
|
||||
" entered"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Transportation Details"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_mode
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_mode
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_mode
|
||||
msgid "Transportation Mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_transporter_id
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_transporter_id
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_transporter_id
|
||||
msgid "Transporter"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__name
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_l10n_in_ewaybill_type__code
|
||||
msgid "Type Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Unable to connect to the E-WayBill service.The web service may be temporary "
|
||||
"down. Please try again in a moment."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_vehicle_no
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_vehicle_no
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_vehicle_no
|
||||
msgid "Vehicle Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_bank_statement_line__l10n_in_vehicle_type
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_move__l10n_in_vehicle_type
|
||||
#: model:ir.model.fields,field_description:l10n_in_edi_ewaybill.field_account_payment__l10n_in_vehicle_type
|
||||
msgid "Vehicle Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.res_config_settings_view_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "Verify Username and Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_move.py:0
|
||||
#, python-format
|
||||
msgid "You can only create E-waybill from posted invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You need at least one product having \"Product Type\" as stockable or "
|
||||
"consumable."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_in_edi_ewaybill.invoice_form_inherit_l10n_in_edi_ewaybill
|
||||
msgid "eWayBill"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "product is required to get HSN code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_in_edi_ewaybill
|
||||
#: code:addons/l10n_in_edi_ewaybill/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "waiting For IRN generation To create E-waybill"
|
||||
msgstr ""
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import ewaybill_type
|
||||
from . import res_company
|
||||
from . import res_config_settings
|
||||
from . import account_move
|
||||
from . import account_edi_format
|
||||
+607
@@ -0,0 +1,607 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import re
|
||||
import json
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools import html_escape
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.addons.iap import jsonrpc
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_IAP_ENDPOINT = "https://l10n-in-edi.api.odoo.com"
|
||||
DEFAULT_IAP_TEST_ENDPOINT = "https://l10n-in-edi-demo.api.odoo.com"
|
||||
|
||||
|
||||
class AccountEdiFormat(models.Model):
|
||||
_inherit = "account.edi.format"
|
||||
|
||||
def _l10n_in_edi_ewaybill_base_irn_or_direct(self, move):
|
||||
"""
|
||||
There is two type of api call to create E-waybill
|
||||
1. base on IRN, IRN is number created when we do E-invoice
|
||||
2. direct call, when E-invoice not aplicable or it"s credit not
|
||||
"""
|
||||
if move.move_type == "out_refund":
|
||||
return "direct"
|
||||
einvoice_in_edi_format = move.journal_id.edi_format_ids.filtered(lambda f: f.code == "in_einvoice_1_03")
|
||||
return einvoice_in_edi_format and einvoice_in_edi_format._is_required_for_invoice(move) and "irn" or "direct"
|
||||
|
||||
def _is_compatible_with_journal(self, journal):
|
||||
if self.code == "in_ewaybill_1_03":
|
||||
return journal.type in ("sale", "purchase")
|
||||
return super()._is_compatible_with_journal(journal)
|
||||
|
||||
def _is_enabled_by_default_on_journal(self, journal):
|
||||
"""
|
||||
It's sent with a button action on the invoice so it's disabled by default
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.code == "in_ewaybill_1_03":
|
||||
return False
|
||||
return super()._is_enabled_by_default_on_journal(journal)
|
||||
|
||||
def _is_required_for_invoice(self, invoice):
|
||||
self.ensure_one()
|
||||
if self.code == "in_ewaybill_1_03":
|
||||
return invoice.l10n_in_mode and invoice.is_invoice(include_receipts=True)
|
||||
return super()._is_required_for_invoice(invoice)
|
||||
|
||||
def _needs_web_services(self):
|
||||
self.ensure_one()
|
||||
return self.code == "in_ewaybill_1_03" or super()._needs_web_services()
|
||||
|
||||
def _get_invoice_edi_content(self, move):
|
||||
if self.code != "in_ewaybill_1_03":
|
||||
return super()._get_invoice_edi_content(move)
|
||||
base = self._l10n_in_edi_ewaybill_base_irn_or_direct(move)
|
||||
if base == "irn":
|
||||
json_dump = json.dumps(self._l10n_in_edi_irn_ewaybill_generate_json(move))
|
||||
else:
|
||||
json_dump = json.dumps(self._l10n_in_edi_ewaybill_generate_json(move))
|
||||
return json_dump.encode()
|
||||
|
||||
def _check_move_configuration(self, move):
|
||||
if self.code != "in_ewaybill_1_03":
|
||||
return super()._check_move_configuration(move)
|
||||
error_message = []
|
||||
if not move.l10n_in_type_id:
|
||||
error_message.append(_("- Document Type"))
|
||||
if not move.l10n_in_mode:
|
||||
error_message.append(_("- Transportation Mode"))
|
||||
elif move.l10n_in_mode == "0" and not move.l10n_in_transporter_id:
|
||||
error_message.append(_("- Transporter is required when E-waybill is managed by transporter"))
|
||||
elif move.l10n_in_mode == "1":
|
||||
if not move.l10n_in_vehicle_no and move.l10n_in_vehicle_type:
|
||||
error_message.append(_("- Vehicle Number and Type is required when Transportation Mode is By Road"))
|
||||
elif move.l10n_in_mode in ("2", "3", "4"):
|
||||
if not move.l10n_in_transportation_doc_no and move.l10n_in_transportation_doc_date:
|
||||
error_message.append(_("- Transport document number and date is required when Transportation Mode is Rail,Air or Ship"))
|
||||
if error_message:
|
||||
error_message.insert(0, _("The following information are missing on the invoice (see eWayBill tab):"))
|
||||
base = self._l10n_in_edi_ewaybill_base_irn_or_direct(move)
|
||||
if base == "irn":
|
||||
# already checked by E-invoice (l10n_in_edi) so no need to check
|
||||
return error_message
|
||||
is_purchase = move.is_purchase_document(include_receipts=True)
|
||||
error_message += self._l10n_in_validate_partner(move.partner_id)
|
||||
error_message += self._l10n_in_validate_partner(move.company_id.partner_id, is_company=True)
|
||||
if not re.match("^.{1,16}$", is_purchase and move.ref or move.name):
|
||||
error_message.append(_("%s number should be set and not more than 16 characters",
|
||||
(is_purchase and "Bill Reference" or "Invoice")))
|
||||
goods_line_is_available = False
|
||||
for line in move.invoice_line_ids.filtered(lambda line: not (line.display_type or line.is_rounding_line or line.product_id.type == "service")):
|
||||
goods_line_is_available = True
|
||||
if line.product_id:
|
||||
hsn_code = self._l10n_in_edi_extract_digits(line.product_id.l10n_in_hsn_code)
|
||||
if not hsn_code:
|
||||
error_message.append(_("HSN code is not set in product %s", line.product_id.name))
|
||||
elif not re.match("^[0-9]+$", hsn_code):
|
||||
error_message.append(_(
|
||||
"Invalid HSN Code (%s) in product %s", hsn_code, line.product_id.name
|
||||
))
|
||||
else:
|
||||
error_message.append(_("product is required to get HSN code"))
|
||||
if not goods_line_is_available:
|
||||
error_message.append(_('You need at least one product having "Product Type" as stockable or consumable.'))
|
||||
if error_message:
|
||||
error_message.insert(0, _("Impossible to send the Ewaybill."))
|
||||
return error_message
|
||||
|
||||
def _post_invoice_edi(self, invoices):
|
||||
if self.code != "in_ewaybill_1_03":
|
||||
return super()._post_invoice_edi(invoices)
|
||||
base = self._l10n_in_edi_ewaybill_base_irn_or_direct(invoices)
|
||||
if base == "irn":
|
||||
return self._l10n_in_edi_ewaybill_irn_post_invoice_edi(invoices)
|
||||
else:
|
||||
return self._l10n_in_edi_ewaybill_post_invoice_edi(invoices)
|
||||
|
||||
def _cancel_invoice_edi(self, invoices):
|
||||
if self.code != "in_ewaybill_1_03":
|
||||
return super()._cancel_invoice_edi(invoices)
|
||||
response = {}
|
||||
res = {}
|
||||
ewaybill_response_json = invoices._get_l10n_in_edi_ewaybill_response_json()
|
||||
cancel_json = {
|
||||
"ewbNo": ewaybill_response_json.get("ewayBillNo") or ewaybill_response_json.get("EwbNo"),
|
||||
"cancelRsnCode": int(invoices.l10n_in_edi_cancel_reason),
|
||||
"CnlRem": invoices.l10n_in_edi_cancel_remarks,
|
||||
}
|
||||
response = self._l10n_in_edi_ewaybill_cancel(invoices.company_id, cancel_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "238" in error_codes:
|
||||
# Invalid token eror then create new token and send generate request again.
|
||||
# This happen when authenticate called from another odoo instance with same credentials (like. Demo/Test)
|
||||
authenticate_response = self._l10n_in_edi_ewaybill_authenticate(invoices.company_id)
|
||||
if not authenticate_response.get("error"):
|
||||
error = []
|
||||
response = self._l10n_in_edi_ewaybill_cancel(invoices.company_id, cancel_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "312" in error_codes:
|
||||
# E-waybill is already canceled
|
||||
# this happens when timeout from the Government portal but IRN is generated
|
||||
error_message = "<br/>".join(["[%s] %s" % (e.get("code"), html_escape(e.get("message"))) for e in error])
|
||||
error = []
|
||||
response = {"data": ""}
|
||||
odoobot = self.env.ref("base.partner_root")
|
||||
invoices.message_post(author_id=odoobot.id, body=
|
||||
"%s<br/>%s:<br/>%s" %(
|
||||
_("Somehow this E-waybill has been canceled in the government portal before. You can verify by checking the details into the government (https://ewaybillgst.gov.in/Others/EBPrintnew.asp)"),
|
||||
_("Error"),
|
||||
error_message
|
||||
)
|
||||
)
|
||||
if "no-credit" in error_codes:
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": self._l10n_in_edi_get_iap_buy_credits_message(invoices.company_id),
|
||||
"blocking_level": "error",
|
||||
}
|
||||
elif error:
|
||||
error_message = "<br/>".join(["[%s] %s" % (e.get("code"), html_escape(e.get("message"))) for e in error])
|
||||
blocking_level = "error"
|
||||
if "404" in error_codes:
|
||||
blocking_level = "warning"
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": error_message,
|
||||
"blocking_level": blocking_level,
|
||||
}
|
||||
if not response.get("error"):
|
||||
json_dump = json.dumps(response.get("data"))
|
||||
json_name = "%s_ewaybill_cancel.json" % (invoices.name.replace("/", "_"))
|
||||
attachment = self.env["ir.attachment"].create({
|
||||
"name": json_name,
|
||||
"raw": json_dump.encode(),
|
||||
"res_model": "account.move",
|
||||
"res_id": invoices.id,
|
||||
"mimetype": "application/json",
|
||||
})
|
||||
inv_res = {"success": True, "attachment": attachment}
|
||||
res[invoices] = inv_res
|
||||
return res
|
||||
|
||||
def _l10n_in_edi_ewaybill_irn_post_invoice_edi(self, invoices):
|
||||
response = {}
|
||||
res = {}
|
||||
generate_json = self._l10n_in_edi_irn_ewaybill_generate_json(invoices)
|
||||
response = self._l10n_in_edi_irn_ewaybill_generate(invoices.company_id, generate_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "1005" in error_codes:
|
||||
# Invalid token eror then create new token and send generate request again.
|
||||
# This happen when authenticate called from another odoo instance with same credentials (like. Demo/Test)
|
||||
authenticate_response = self._l10n_in_edi_authenticate(invoices.company_id)
|
||||
if not authenticate_response.get("error"):
|
||||
error = []
|
||||
response = self._l10n_in_edi_irn_ewaybill_generate(invoices.company_id, generate_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "4002" in error_codes:
|
||||
# Get E-waybill by details in case of IRN is already generated
|
||||
# this happens when timeout from the Government portal but E-waybill is generated
|
||||
response = self._l10n_in_edi_irn_ewaybill_get(invoices.company_id, generate_json.get("Irn"))
|
||||
if not response.get("error"):
|
||||
error = []
|
||||
odoobot = self.env.ref("base.partner_root")
|
||||
invoices.message_post(author_id=odoobot.id, body=
|
||||
_("Somehow this E-waybill has been generated in the government portal before. You can verify by checking the invoice details into the government (https://ewaybillgst.gov.in/Others/EBPrintnew.asp)")
|
||||
)
|
||||
|
||||
if "no-credit" in error_codes:
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": self._l10n_in_edi_get_iap_buy_credits_message(invoices.company_id),
|
||||
"blocking_level": "error",
|
||||
}
|
||||
elif error:
|
||||
error_message = "<br/>".join(["[%s] %s" % (e.get("code"), html_escape(e.get("message"))) for e in error])
|
||||
blocking_level = "error"
|
||||
if "404" in error_codes or "waiting" in error_codes:
|
||||
blocking_level = "warning"
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": error_message,
|
||||
"blocking_level": blocking_level,
|
||||
}
|
||||
if not response.get("error"):
|
||||
json_dump = json.dumps(response.get("data"))
|
||||
json_name = "%s_irn_ewaybill.json" % (invoices.name.replace("/", "_"))
|
||||
attachment = self.env["ir.attachment"].create({
|
||||
"name": json_name,
|
||||
"raw": json_dump.encode(),
|
||||
"res_model": "account.move",
|
||||
"res_id": invoices.id,
|
||||
"mimetype": "application/json",
|
||||
})
|
||||
inv_res = {"success": True, "attachment": attachment}
|
||||
res[invoices] = inv_res
|
||||
return res
|
||||
|
||||
def _l10n_in_edi_irn_ewaybill_generate_json(self, invoice):
|
||||
json_payload = {
|
||||
"Irn": invoice._get_l10n_in_edi_response_json().get("Irn"),
|
||||
"Distance": invoice.l10n_in_distance,
|
||||
}
|
||||
if invoice.l10n_in_mode == "0":
|
||||
json_payload.update({
|
||||
"TransId": invoice.l10n_in_transporter_id.vat,
|
||||
"TransName": invoice.l10n_in_transporter_id.name,
|
||||
})
|
||||
elif invoice.l10n_in_mode == "1":
|
||||
json_payload.update({
|
||||
"TransMode": invoice.l10n_in_mode,
|
||||
"VehNo": invoice.l10n_in_vehicle_no,
|
||||
"VehType": invoice.l10n_in_vehicle_type,
|
||||
})
|
||||
elif invoice.l10n_in_mode in ("2", "3", "4"):
|
||||
doc_date = invoice.l10n_in_transportation_doc_date
|
||||
json_payload.update({
|
||||
"TransMode": invoice.l10n_in_mode,
|
||||
"TransDocDt": doc_date and doc_date.strftime("%d/%m/%Y") or False,
|
||||
"TransDocNo": invoice.l10n_in_transportation_doc_no,
|
||||
})
|
||||
return json_payload
|
||||
|
||||
def _l10n_in_edi_ewaybill_post_invoice_edi(self, invoices):
|
||||
response = {}
|
||||
res = {}
|
||||
generate_json = self._l10n_in_edi_ewaybill_generate_json(invoices)
|
||||
response = self._l10n_in_edi_ewaybill_generate(invoices.company_id, generate_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "238" in error_codes:
|
||||
# Invalid token eror then create new token and send generate request again.
|
||||
# This happen when authenticate called from another odoo instance with same credentials (like. Demo/Test)
|
||||
authenticate_response = self._l10n_in_edi_ewaybill_authenticate(invoices.company_id)
|
||||
if not authenticate_response.get("error"):
|
||||
error = []
|
||||
response = self._l10n_in_edi_ewaybill_generate(invoices.company_id, generate_json)
|
||||
if response.get("error"):
|
||||
error = response["error"]
|
||||
error_codes = [e.get("code") for e in error]
|
||||
if "604" in error_codes:
|
||||
# Get E-waybill by details in case of E-waybill is already generated
|
||||
# this happens when timeout from the Government portal but E-waybill is generated
|
||||
response = self._l10n_in_edi_ewaybill_get_by_consigner(
|
||||
invoices.company_id, generate_json.get("docType"), generate_json.get("docNo"))
|
||||
if not response.get("error"):
|
||||
error = []
|
||||
odoobot = self.env.ref("base.partner_root")
|
||||
invoices.message_post(author_id=odoobot.id, body=
|
||||
_("Somehow this E-waybill has been generated in the government portal before. You can verify by checking the invoice details into the government (https://ewaybillgst.gov.in/Others/EBPrintnew.asp)")
|
||||
)
|
||||
if "no-credit" in error_codes:
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": self._l10n_in_edi_get_iap_buy_credits_message(invoices.company_id),
|
||||
"blocking_level": "error",
|
||||
}
|
||||
elif error:
|
||||
error_message = "<br/>".join(["[%s] %s" % (e.get("code"), html_escape(e.get("message"))) for e in error])
|
||||
blocking_level = "error"
|
||||
if "404" in error_codes:
|
||||
blocking_level = "warning"
|
||||
res[invoices] = {
|
||||
"success": False,
|
||||
"error": error_message,
|
||||
"blocking_level": blocking_level,
|
||||
}
|
||||
if not response.get("error"):
|
||||
json_dump = json.dumps(response.get("data"))
|
||||
json_name = "%s_ewaybill.json" % (invoices.name.replace("/", "_"))
|
||||
attachment = self.env["ir.attachment"].create({
|
||||
"name": json_name,
|
||||
"raw": json_dump.encode(),
|
||||
"res_model": "account.move",
|
||||
"res_id": invoices.id,
|
||||
"mimetype": "application/json",
|
||||
})
|
||||
inv_res = {"success": True, "attachment": attachment}
|
||||
res[invoices] = inv_res
|
||||
return res
|
||||
|
||||
def _get_l10n_in_edi_saler_buyer_party(self, move):
|
||||
res = super()._get_l10n_in_edi_saler_buyer_party(move)
|
||||
if move.is_purchase_document(include_receipts=True):
|
||||
res = {
|
||||
"seller_details": move.partner_id,
|
||||
"dispatch_details": move._l10n_in_get_shipping_partner(),
|
||||
"buyer_details": move.company_id.partner_id,
|
||||
"ship_to_details": move._l10n_in_get_warehouse_address() or move.company_id.partner_id,
|
||||
}
|
||||
return res
|
||||
|
||||
def _l10n_in_edi_ewaybill_generate_json(self, invoices):
|
||||
def get_transaction_type(seller_details, dispatch_details, buyer_details, ship_to_details):
|
||||
"""
|
||||
1 - Regular
|
||||
2 - Bill To - Ship To
|
||||
3 - Bill From - Dispatch From
|
||||
4 - Combination of 2 and 3
|
||||
"""
|
||||
if seller_details != dispatch_details and buyer_details != ship_to_details:
|
||||
return 4
|
||||
elif seller_details != dispatch_details:
|
||||
return 3
|
||||
elif buyer_details != ship_to_details:
|
||||
return 2
|
||||
else:
|
||||
return 1
|
||||
|
||||
def filter_invl_to_apply(invoice_line):
|
||||
if invoice_line.product_id.type == "service":
|
||||
return False
|
||||
return True
|
||||
|
||||
saler_buyer = self._get_l10n_in_edi_saler_buyer_party(invoices)
|
||||
seller_details = saler_buyer.get("seller_details")
|
||||
dispatch_details = saler_buyer.get("dispatch_details")
|
||||
buyer_details = saler_buyer.get("buyer_details")
|
||||
ship_to_details = saler_buyer.get("ship_to_details")
|
||||
sign = invoices.is_inbound() and -1 or 1
|
||||
extract_digits = self._l10n_in_edi_extract_digits
|
||||
tax_details = self._l10n_in_prepare_edi_tax_details(invoices, filter_invl_to_apply=filter_invl_to_apply)
|
||||
tax_details_by_code = self._get_l10n_in_tax_details_by_line_code(tax_details.get("tax_details", {}))
|
||||
invoice_line_tax_details = tax_details.get("invoice_line_tax_details")
|
||||
json_payload = {
|
||||
"supplyType": invoices.is_purchase_document(include_receipts=True) and "I" or "O",
|
||||
"subSupplyType": invoices.l10n_in_type_id.sub_type_code,
|
||||
"docType": invoices.l10n_in_type_id.code,
|
||||
"transactionType": get_transaction_type(seller_details, dispatch_details, buyer_details, ship_to_details),
|
||||
"transDistance": str(invoices.l10n_in_distance),
|
||||
"docNo": invoices.is_purchase_document(include_receipts=True) and invoices.ref or invoices.name,
|
||||
"docDate": invoices.date.strftime("%d/%m/%Y"),
|
||||
"fromGstin": seller_details.commercial_partner_id.vat or "URP",
|
||||
"fromTrdName": seller_details.commercial_partner_id.name,
|
||||
"fromAddr1": dispatch_details.street or "",
|
||||
"fromAddr2": dispatch_details.street2 or "",
|
||||
"fromPlace": dispatch_details.city or "",
|
||||
"fromPincode": dispatch_details.country_id.code == "IN" and int(extract_digits(dispatch_details.zip)) or "",
|
||||
"fromStateCode": int(seller_details.state_id.l10n_in_tin) or "",
|
||||
"actFromStateCode": dispatch_details.state_id.l10n_in_tin and int(dispatch_details.state_id.l10n_in_tin) or "",
|
||||
"toGstin": buyer_details.commercial_partner_id.vat or "URP",
|
||||
"toTrdName": buyer_details.commercial_partner_id.name,
|
||||
"toAddr1": ship_to_details.street or "",
|
||||
"toAddr2": ship_to_details.street2 or "",
|
||||
"toPlace": ship_to_details.city or "",
|
||||
"toPincode": int(extract_digits(ship_to_details.zip)),
|
||||
"actToStateCode": int(ship_to_details.state_id.l10n_in_tin),
|
||||
"toStateCode": invoices.l10n_in_state_id.l10n_in_tin and int(invoices.l10n_in_state_id.l10n_in_tin) or (
|
||||
buyer_details.state_id.l10n_in_tin or int(buyer_details.state_id.l10n_in_tin) or ""
|
||||
),
|
||||
"itemList": [
|
||||
self._get_l10n_in_edi_ewaybill_line_details(line, line_tax_details, sign)
|
||||
for line, line_tax_details in invoice_line_tax_details.items()
|
||||
],
|
||||
"totalValue": self._l10n_in_round_value(tax_details.get("base_amount") * sign),
|
||||
"cgstValue": self._l10n_in_round_value(tax_details_by_code.get("cgst_amount", 0.00) * sign),
|
||||
"sgstValue": self._l10n_in_round_value(tax_details_by_code.get("sgst_amount", 0.00) * sign),
|
||||
"igstValue": self._l10n_in_round_value(tax_details_by_code.get("igst_amount", 0.00) * sign),
|
||||
"cessValue": self._l10n_in_round_value(tax_details_by_code.get("cess_amount", 0.00) * sign),
|
||||
"cessNonAdvolValue": self._l10n_in_round_value(tax_details_by_code.get("cess_non_advol_amount", 0.00) * sign),
|
||||
"otherValue": self._l10n_in_round_value(tax_details_by_code.get("other_amount", 0.00) * sign),
|
||||
"totInvValue": self._l10n_in_round_value((tax_details.get("base_amount") + tax_details.get("tax_amount")) * sign),
|
||||
}
|
||||
is_overseas = invoices.l10n_in_gst_treatment in ("overseas", "special_economic_zone")
|
||||
if invoices.is_purchase_document(include_receipts=True):
|
||||
if is_overseas:
|
||||
json_payload.update({"fromStateCode": 99})
|
||||
if is_overseas and dispatch_details.state_id.country_id.code != "IN":
|
||||
json_payload.update({
|
||||
"actFromStateCode": 99,
|
||||
"fromPincode": 999999,
|
||||
})
|
||||
else:
|
||||
json_payload.update({
|
||||
"actFromStateCode": dispatch_details.state_id.l10n_in_tin and int(dispatch_details.state_id.l10n_in_tin) or "",
|
||||
"fromPincode": int(extract_digits(dispatch_details.zip)),
|
||||
})
|
||||
else:
|
||||
if is_overseas:
|
||||
json_payload.update({"toStateCode": 99})
|
||||
if is_overseas and ship_to_details.state_id.country_id.code != "IN":
|
||||
json_payload.update({
|
||||
"actToStateCode": 99,
|
||||
"toPincode": 999999,
|
||||
})
|
||||
else:
|
||||
json_payload.update({
|
||||
"actToStateCode": int(ship_to_details.state_id.l10n_in_tin),
|
||||
"toPincode": int(extract_digits(ship_to_details.zip)),
|
||||
})
|
||||
|
||||
if invoices.l10n_in_mode == "0":
|
||||
json_payload.update({
|
||||
"transporterId": invoices.l10n_in_transporter_id.vat or "",
|
||||
"transporterName": invoices.l10n_in_transporter_id.name or "",
|
||||
})
|
||||
if invoices.l10n_in_mode in ("2", "3", "4"):
|
||||
json_payload.update({
|
||||
"transMode": invoices.l10n_in_mode,
|
||||
"transDocNo": invoices.l10n_in_transporter_doc_no or "",
|
||||
"transDocDate": invoices.l10n_in_transporter_doc_date and
|
||||
invoices.l10n_in_transporter_doc_date.strftime("%d/%m/%Y") or "",
|
||||
})
|
||||
if invoices.l10n_in_mode == "1":
|
||||
json_payload.update({
|
||||
"transMode": invoices.l10n_in_mode,
|
||||
"vehicleNo": invoices.l10n_in_vehicle_no or "",
|
||||
"vehicleType": invoices.l10n_in_vehicle_type or "",
|
||||
})
|
||||
return json_payload
|
||||
|
||||
def _get_l10n_in_edi_ewaybill_line_details(self, line, line_tax_details, sign):
|
||||
extract_digits = self._l10n_in_edi_extract_digits
|
||||
tax_details_by_code = self._get_l10n_in_tax_details_by_line_code(line_tax_details.get("tax_details", {}))
|
||||
line_details = {
|
||||
"productName": line.product_id.name,
|
||||
"hsnCode": extract_digits(line.product_id.l10n_in_hsn_code),
|
||||
"productDesc": line.name,
|
||||
"quantity": line.quantity,
|
||||
"qtyUnit": line.product_id.uom_id.l10n_in_code and line.product_id.uom_id.l10n_in_code.split("-")[0] or "OTH",
|
||||
"taxableAmount": self._l10n_in_round_value(line.balance * sign),
|
||||
}
|
||||
if tax_details_by_code.get("igst_rate"):
|
||||
line_details.update({"igstRate": self._l10n_in_round_value(tax_details_by_code["igst_rate"])})
|
||||
else:
|
||||
line_details.update({
|
||||
"cgstRate": self._l10n_in_round_value(tax_details_by_code.get("cgst_rate", 0.00)),
|
||||
"sgstRate": self._l10n_in_round_value(tax_details_by_code.get("sgst_rate", 0.00)),
|
||||
})
|
||||
if tax_details_by_code.get("cess_rate"):
|
||||
line_details.update({"cessRate": self._l10n_in_round_value(tax_details_by_code.get("cess_rate"))})
|
||||
return line_details
|
||||
|
||||
#================================ E-invoice API methods ===========================
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_irn_ewaybill_generate(self, company, json_payload):
|
||||
# IRN is created by E-invoice API call so waiting for it.
|
||||
if not json_payload.get("Irn"):
|
||||
return {"error": [{
|
||||
"code": "waiting",
|
||||
"message": _("waiting For IRN generation To create E-waybill")}
|
||||
]}
|
||||
token = self._l10n_in_edi_get_token(company)
|
||||
if not token:
|
||||
return self._l10n_in_edi_no_config_response()
|
||||
params = {
|
||||
"auth_token": token,
|
||||
"json_payload": json_payload,
|
||||
}
|
||||
return self._l10n_in_edi_connect_to_server(company, url_path="/iap/l10n_in_edi/1/generate_ewaybill_by_irn", params=params)
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_irn_ewaybill_get(self, company, irn):
|
||||
token = self._l10n_in_edi_get_token(company)
|
||||
if not token:
|
||||
return self._l10n_in_edi_no_config_response()
|
||||
params = {
|
||||
"auth_token": token,
|
||||
"irn": irn,
|
||||
}
|
||||
return self._l10n_in_edi_connect_to_server(company, url_path="/iap/l10n_in_edi/1/get_ewaybill_by_irn", params=params)
|
||||
|
||||
#=============================== E-waybill API methods ===================================
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_no_config_response(self):
|
||||
return {"error": [{
|
||||
"code": "000",
|
||||
"message": _(
|
||||
"A username and password still needs to be set or it's wrong for the E-waybill(IN). "
|
||||
"It needs to be added and verify in the Settings."
|
||||
)}
|
||||
]}
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_check_authentication(self, company):
|
||||
sudo_company = company.sudo()
|
||||
if sudo_company.l10n_in_edi_ewaybill_username and sudo_company._l10n_in_edi_ewaybill_token_is_valid():
|
||||
return True
|
||||
elif sudo_company.l10n_in_edi_ewaybill_username and sudo_company.l10n_in_edi_ewaybill_password:
|
||||
authenticate_response = self._l10n_in_edi_ewaybill_authenticate(company)
|
||||
if not authenticate_response.get("error"):
|
||||
return True
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_connect_to_server(self, company, url_path, params):
|
||||
user_token = self.env["iap.account"].get("l10n_in_edi")
|
||||
params.update({
|
||||
"account_token": user_token.account_token,
|
||||
"dbuuid": self.env["ir.config_parameter"].sudo().get_param("database.uuid"),
|
||||
"username": company.sudo().l10n_in_edi_ewaybill_username,
|
||||
"gstin": company.vat,
|
||||
})
|
||||
if company.sudo().l10n_in_edi_production_env:
|
||||
default_endpoint = DEFAULT_IAP_ENDPOINT
|
||||
else:
|
||||
default_endpoint = DEFAULT_IAP_TEST_ENDPOINT
|
||||
endpoint = self.env["ir.config_parameter"].sudo().get_param("l10n_in_edi_ewaybill.endpoint", default_endpoint)
|
||||
url = "%s%s" % (endpoint, url_path)
|
||||
try:
|
||||
return jsonrpc(url, params=params, timeout=25)
|
||||
except AccessError as e:
|
||||
_logger.warning("Connection error: %s", e.args[0])
|
||||
return {
|
||||
"error": [{
|
||||
"code": "access_error",
|
||||
"message": _("Unable to connect to the E-WayBill service."
|
||||
"The web service may be temporary down. Please try again in a moment.")
|
||||
}]
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_authenticate(self, company):
|
||||
params = {"password": company.sudo().l10n_in_edi_ewaybill_password}
|
||||
response = self._l10n_in_edi_ewaybill_connect_to_server(
|
||||
company, url_path="/iap/l10n_in_edi_ewaybill/1/authenticate", params=params
|
||||
)
|
||||
if response and response.get("status_cd") == "1":
|
||||
company.sudo().l10n_in_edi_ewaybill_auth_validity = fields.Datetime.now() + timedelta(
|
||||
hours=6, minutes=00, seconds=00)
|
||||
return response
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_generate(self, company, json_payload):
|
||||
is_authenticated = self._l10n_in_edi_ewaybill_check_authentication(company)
|
||||
if not is_authenticated:
|
||||
return self._l10n_in_edi_ewaybill_no_config_response()
|
||||
params = {"json_payload": json_payload}
|
||||
return self._l10n_in_edi_ewaybill_connect_to_server(
|
||||
company, url_path="/iap/l10n_in_edi_ewaybill/1/generate", params=params
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_cancel(self, company, json_payload):
|
||||
is_authenticated = self._l10n_in_edi_ewaybill_check_authentication(company)
|
||||
if not is_authenticated:
|
||||
return self._l10n_in_edi_ewaybill_no_config_response()
|
||||
params = {"json_payload": json_payload}
|
||||
return self._l10n_in_edi_ewaybill_connect_to_server(
|
||||
company, url_path="/iap/l10n_in_edi_ewaybill/1/cancel", params=params
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _l10n_in_edi_ewaybill_get_by_consigner(self, company, document_type, document_number):
|
||||
is_authenticated = self._l10n_in_edi_ewaybill_check_authentication(company)
|
||||
if not is_authenticated:
|
||||
return self._l10n_in_edi_ewaybill_no_config_response()
|
||||
params = {"document_type": document_type, "document_number": document_number}
|
||||
return self._l10n_in_edi_ewaybill_connect_to_server(
|
||||
company, url_path="/iap/l10n_in_edi_ewaybill/1/getewaybillgeneratedbyconsigner", params=params
|
||||
)
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import json
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = "account.move"
|
||||
|
||||
# Transaction Details
|
||||
l10n_in_type_id = fields.Many2one("l10n.in.ewaybill.type", "E-waybill Document Type", tracking=True)
|
||||
|
||||
# transportation details
|
||||
l10n_in_distance = fields.Integer("Distance", tracking=True)
|
||||
l10n_in_mode = fields.Selection([
|
||||
("0", "Managed by Transporter"),
|
||||
("1", "By Road"),
|
||||
("2", "Rail"),
|
||||
("3", "Air"),
|
||||
("4", "Ship")],
|
||||
string="Transportation Mode", copy=False, tracking=True)
|
||||
|
||||
# Vehicle Number and Type required when transportation mode is By Road.
|
||||
l10n_in_vehicle_no = fields.Char("Vehicle Number", copy=False, tracking=True)
|
||||
l10n_in_vehicle_type = fields.Selection([
|
||||
("R", "Regular"),
|
||||
("O", "ODC")],
|
||||
string="Vehicle Type", copy=False, tracking=True)
|
||||
|
||||
# Document number and date required in case of transportation mode is Rail, Air or Ship.
|
||||
l10n_in_transportation_doc_no = fields.Char(
|
||||
string="E-waybill Document Number",
|
||||
help="""Transport document number. If it is more than 15 chars, last 15 chars may be entered""",
|
||||
copy=False, tracking=True)
|
||||
l10n_in_transportation_doc_date = fields.Date(
|
||||
string="Document Date",
|
||||
help="Date on the transporter document",
|
||||
copy=False,
|
||||
tracking=True)
|
||||
|
||||
# transporter id required when transportation done by other party.
|
||||
l10n_in_transporter_id = fields.Many2one("res.partner", "Transporter", copy=False, tracking=True)
|
||||
# show and hide fields base on this
|
||||
l10n_in_edi_ewaybill_direct_api = fields.Boolean(string="E-waybill(IN) direct API", compute="_compute_l10n_in_edi_ewaybill_direct")
|
||||
l10n_in_edi_ewaybill_show_send_button = fields.Boolean(string="Show Send E-waybill Button", compute="_compute_l10n_in_edi_ewaybill_show_send_button")
|
||||
|
||||
@api.depends('state', 'edi_document_ids', 'edi_document_ids.state')
|
||||
def _compute_l10n_in_edi_ewaybill_show_send_button(self):
|
||||
edi_format = self.env.ref('l10n_in_edi_ewaybill.edi_in_ewaybill_json_1_03')
|
||||
posted_moves = self.filtered(lambda x: x.is_invoice() and x.state == 'posted')
|
||||
for move in posted_moves:
|
||||
already_sent = move.edi_document_ids.filtered(lambda x: x.edi_format_id == edi_format and x.state in ('sent', 'to_cancel', 'to_send'))
|
||||
if already_sent:
|
||||
move.l10n_in_edi_ewaybill_show_send_button = False
|
||||
else:
|
||||
move.l10n_in_edi_ewaybill_show_send_button = True
|
||||
(self - posted_moves).l10n_in_edi_ewaybill_show_send_button = False
|
||||
|
||||
@api.depends("l10n_in_gst_treatment")
|
||||
def _compute_l10n_in_edi_ewaybill_direct(self):
|
||||
for move in self:
|
||||
base = self.env["account.edi.format"]._l10n_in_edi_ewaybill_base_irn_or_direct(move)
|
||||
move.l10n_in_edi_ewaybill_direct_api = base == "direct"
|
||||
|
||||
@api.depends("edi_document_ids")
|
||||
def _compute_l10n_in_edi_show_cancel(self):
|
||||
super()._compute_l10n_in_edi_show_cancel()
|
||||
for invoice in self:
|
||||
if invoice.edi_document_ids.filtered(lambda i: i.edi_format_id.code == "in_ewaybill_1_03" and i.state in ("sent", "to_cancel", "cancelled")):
|
||||
invoice.l10n_in_edi_show_cancel = True
|
||||
|
||||
def _get_l10n_in_edi_ewaybill_response_json(self):
|
||||
self.ensure_one()
|
||||
l10n_in_edi = self.edi_document_ids.filtered(lambda i: i.edi_format_id.code == "in_ewaybill_1_03"
|
||||
and i.state in ("sent", "to_cancel"))
|
||||
if l10n_in_edi and l10n_in_edi.attachment_id:
|
||||
return json.loads(l10n_in_edi.attachment_id.raw.decode("utf-8"))
|
||||
else:
|
||||
return {}
|
||||
|
||||
def button_cancel_posted_moves(self):
|
||||
"""Mark the edi.document related to this move to be canceled."""
|
||||
reason_and_remarks_not_set = self.env["account.move"]
|
||||
for move in self:
|
||||
send_l10n_in_edi_ewaybill = move.edi_document_ids.filtered(lambda doc: doc.edi_format_id.code == "in_ewaybill_1_03")
|
||||
# check submitted E-waybill does not have reason and remarks
|
||||
# because it's needed to cancel E-waybill
|
||||
if send_l10n_in_edi_ewaybill and (not move.l10n_in_edi_cancel_reason or not move.l10n_in_edi_cancel_remarks):
|
||||
reason_and_remarks_not_set += move
|
||||
if reason_and_remarks_not_set:
|
||||
raise UserError(_(
|
||||
"To cancel E-waybill set cancel reason and remarks at E-waybill tab in: \n%s",
|
||||
("\n".join(reason_and_remarks_not_set.mapped("name"))),
|
||||
))
|
||||
return super().button_cancel_posted_moves()
|
||||
|
||||
def l10n_in_edi_ewaybill_send(self):
|
||||
edi_format = self.env.ref('l10n_in_edi_ewaybill.edi_in_ewaybill_json_1_03')
|
||||
edi_document_vals_list = []
|
||||
for move in self:
|
||||
if move.state != 'posted':
|
||||
raise UserError(_("You can only create E-waybill from posted invoice"))
|
||||
errors = edi_format._check_move_configuration(move)
|
||||
if errors:
|
||||
raise UserError(_("Invalid invoice configuration:\n\n%s") % '\n'.join(errors))
|
||||
existing_edi_document = move.edi_document_ids.filtered(lambda x: x.edi_format_id == edi_format)
|
||||
if existing_edi_document:
|
||||
if existing_edi_document.state in ('sent', 'to_cancel'):
|
||||
raise UserError(_("E-waybill is already created") % '\n'.join(errors))
|
||||
existing_edi_document.write({
|
||||
'state': 'to_send',
|
||||
'attachment_id': False,
|
||||
})
|
||||
else:
|
||||
edi_document_vals_list.append({
|
||||
'edi_format_id': edi_format.id,
|
||||
'move_id': move.id,
|
||||
'state': 'to_send',
|
||||
})
|
||||
self.env['account.edi.document'].create(edi_document_vals_list)
|
||||
self.env.ref('account_edi.ir_cron_edi_network')._trigger()
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, _
|
||||
|
||||
|
||||
class EWayBillType(models.Model):
|
||||
_name = "l10n.in.ewaybill.type"
|
||||
_description = "E-Waybill Document Type"
|
||||
|
||||
name = fields.Char("Type")
|
||||
code = fields.Char("Type Code")
|
||||
sub_type = fields.Char("Sub-type")
|
||||
sub_type_code = fields.Char("Sub-type Code")
|
||||
allowed_supply_type = fields.Selection(
|
||||
[
|
||||
("both", "Incoming and Outgoing"),
|
||||
("out", "Outgoing"),
|
||||
("in", "Incoming"),
|
||||
],
|
||||
string="Allowed for supply type",
|
||||
)
|
||||
active = fields.Boolean("Active", default=True)
|
||||
|
||||
def name_get(self):
|
||||
"""Show name and sub_type in name"""
|
||||
result_dict = dict()
|
||||
for ewaybill_type in self:
|
||||
name = ewaybill_type.name
|
||||
name += _(" (Sub-Type: %s)", ewaybill_type.sub_type)
|
||||
result_dict[ewaybill_type.id] = name
|
||||
return list(result_dict.items())
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = "res.company"
|
||||
|
||||
l10n_in_edi_ewaybill_username = fields.Char("E-Waybill (IN) Username", groups="base.group_system")
|
||||
l10n_in_edi_ewaybill_password = fields.Char("E-Waybill (IN) Password", groups="base.group_system")
|
||||
l10n_in_edi_ewaybill_auth_validity = fields.Datetime("E-Waybill (IN) Valid Until", groups="base.group_system")
|
||||
|
||||
def _l10n_in_edi_ewaybill_token_is_valid(self):
|
||||
self.ensure_one()
|
||||
if self.l10n_in_edi_ewaybill_auth_validity and self.l10n_in_edi_ewaybill_auth_validity > fields.Datetime.now():
|
||||
return True
|
||||
return False
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import html_escape
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
l10n_in_edi_ewaybill_username = fields.Char("Indian EDI Stock username",
|
||||
related="company_id.l10n_in_edi_ewaybill_username", readonly=False)
|
||||
l10n_in_edi_ewaybill_password = fields.Char("Indian EDI Stock password",
|
||||
related="company_id.l10n_in_edi_ewaybill_password", readonly=False)
|
||||
|
||||
def l10n_in_edi_ewaybill_test(self):
|
||||
response = self.env["account.edi.format"]._l10n_in_edi_ewaybill_authenticate(self.company_id)
|
||||
if response.get("error") or not self.company_id.sudo()._l10n_in_edi_ewaybill_token_is_valid():
|
||||
error_message = _("Incorrect username or password, or the GST number on company does not match.")
|
||||
if response.get("error"):
|
||||
error_message = "\n".join(["[%s] %s" % (e.get("code"), html_escape(e.get("message"))) for e in response["error"]])
|
||||
raise UserError(error_message)
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
l10n_in_edi_ewaybill.access_l10n_in_ewaybill_type,access_l10n_in_ewaybill_type,l10n_in_edi_ewaybill.model_l10n_in_ewaybill_type,base.group_user,1,0,0,0
|
||||
|
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_edi_ewaybill_json
|
||||
@@ -0,0 +1,115 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.addons.l10n_in_edi.tests.test_edi_json import TestEdiJson
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged("post_install_l10n", "post_install", "-at_install")
|
||||
class TestEdiEwaybillJson(TestEdiJson):
|
||||
|
||||
def test_edi_json(self):
|
||||
(self.invoice + self.invoice_full_discount + self.invoice_zero_qty).write({
|
||||
"l10n_in_type_id": self.env.ref("l10n_in_edi_ewaybill.type_tax_invoice_sub_type_supply"),
|
||||
"l10n_in_distance": 20,
|
||||
"l10n_in_mode": "1",
|
||||
"l10n_in_vehicle_no": "GJ11AA1234",
|
||||
"l10n_in_vehicle_type": "R",
|
||||
})
|
||||
json_value = self.env["account.edi.format"]._l10n_in_edi_ewaybill_generate_json(self.invoice)
|
||||
expected = {
|
||||
"supplyType": "O",
|
||||
"docType": "INV",
|
||||
"subSupplyType": "1",
|
||||
"transactionType": 1,
|
||||
"transDistance": "20",
|
||||
"transMode": "1",
|
||||
"vehicleNo": "GJ11AA1234",
|
||||
"vehicleType": "R",
|
||||
"docNo": "INV/2019/00001",
|
||||
"docDate": "01/01/2019",
|
||||
"fromGstin": "36AABCT1332L011",
|
||||
"fromTrdName": "company_1_data",
|
||||
"fromAddr1": "Block no. 401",
|
||||
"fromAddr2": "Street 2",
|
||||
"fromPlace": "City 1",
|
||||
"fromPincode": 500001,
|
||||
"fromStateCode": 36,
|
||||
"actFromStateCode": 36,
|
||||
"toGstin": "36BBBFF5679L8ZR",
|
||||
"toTrdName": "partner_a",
|
||||
"toAddr1": "Block no. 401",
|
||||
"toAddr2": "Street 2",
|
||||
"toPlace": "City 2",
|
||||
"toPincode": 500001,
|
||||
"actToStateCode": 36,
|
||||
"toStateCode": 36,
|
||||
"itemList": [
|
||||
{
|
||||
"productName": "product_a",
|
||||
"hsnCode": "01111",
|
||||
"productDesc": "product_a",
|
||||
"quantity": 1.0,
|
||||
"qtyUnit": "UNT",
|
||||
"taxableAmount": 900.0,
|
||||
"cgstRate": 2.5,
|
||||
"sgstRate": 2.5
|
||||
},
|
||||
{
|
||||
"productName": "product_with_cess",
|
||||
"hsnCode": "02222",
|
||||
"productDesc": "product_with_cess",
|
||||
"quantity": 1.0,
|
||||
"qtyUnit": "UNT",
|
||||
"taxableAmount": 900.0,
|
||||
"cgstRate": 6.0,
|
||||
"sgstRate": 6.0,
|
||||
"cessRate": 5.0
|
||||
}
|
||||
],
|
||||
"totalValue": 1800.0,
|
||||
"cgstValue": 76.5,
|
||||
"sgstValue": 76.5,
|
||||
"igstValue": 0.0,
|
||||
"cessValue": 45.0,
|
||||
"cessNonAdvolValue": 1.59,
|
||||
"otherValue": 0.0,
|
||||
"totInvValue": 1999.59
|
||||
}
|
||||
self.assertDictEqual(json_value, expected, "Indian EDI send json value is not matched")
|
||||
|
||||
#=================================== Full discount test =====================================
|
||||
json_value = self.env["account.edi.format"]._l10n_in_edi_ewaybill_generate_json(self.invoice_full_discount)
|
||||
expected.update({
|
||||
"docNo": "INV/2019/00002",
|
||||
"itemList": [{
|
||||
"productName": "product_a", "hsnCode": "01111", "productDesc": "product_a", "quantity": 1.0,
|
||||
"qtyUnit": "UNT", "taxableAmount": 0.0, "cgstRate": 0.0, "sgstRate": 0.0
|
||||
}],
|
||||
"totalValue": 0.0,
|
||||
"cgstValue": 0.0,
|
||||
"sgstValue": 0.0,
|
||||
"igstValue": 0.0,
|
||||
"cessValue": 0.0,
|
||||
"cessNonAdvolValue": 0.00,
|
||||
"otherValue": 0.0,
|
||||
"totInvValue": 0.0
|
||||
})
|
||||
self.assertDictEqual(json_value, expected, "Indian EDI with 100% discount sent json value is not matched")
|
||||
|
||||
#=================================== Zero quantity test =============================================
|
||||
json_value = self.env["account.edi.format"]._l10n_in_edi_ewaybill_generate_json(self.invoice_zero_qty)
|
||||
expected.update({
|
||||
"docNo": "INV/2019/00003",
|
||||
"itemList": [{
|
||||
"productName": "product_a", "hsnCode": "01111", "productDesc": "product_a", "quantity": 0.0,
|
||||
"qtyUnit": "UNT", "taxableAmount": 0.0, "cgstRate": 0.0, "sgstRate": 0.0
|
||||
}],
|
||||
"totalValue": 0.0,
|
||||
"cgstValue": 0.0,
|
||||
"sgstValue": 0.0,
|
||||
"igstValue": 0.0,
|
||||
"cessValue": 0.0,
|
||||
"cessNonAdvolValue": 0.00,
|
||||
"otherValue": 0.0,
|
||||
"totInvValue": 0.0
|
||||
})
|
||||
self.assertDictEqual(json_value, expected, "Indian EDI with 0(zero) quantity sent json value is not matched")
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="invoice_form_inherit_l10n_in_edi_ewaybill" model="ir.ui.view">
|
||||
<field name="name">account.move.form.inherit.l10n.in.ewaybill</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='button_set_checked']" position="after">
|
||||
<field name="l10n_in_edi_ewaybill_show_send_button" invisible="1"/>
|
||||
<button name="l10n_in_edi_ewaybill_send" string="Send E-waybill" class="oe_highlight" type="object" groups="account.group_account_invoice" attrs="{'invisible' : [('l10n_in_edi_ewaybill_show_send_button','!=',True)]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//notebook/page[@name='other_info']" position="before">
|
||||
<page string="eWayBill" name="l10n_in_edi_ewaybill_page"
|
||||
attrs="{'invisible':[('move_type', '=', 'entry'), ('country_code', '!=', 'IN')]}">
|
||||
<field name="l10n_in_edi_ewaybill_direct_api" invisible="1"/>
|
||||
<group name="ewaybill_group">
|
||||
<group string="Transaction Details" name="Transaction_group"
|
||||
attrs="{'invisible': [('l10n_in_edi_ewaybill_direct_api', '!=', True)]}">
|
||||
<field name="l10n_in_type_id"
|
||||
attrs="{'invisible': [
|
||||
('move_type','in',('in_invoice','in_refund','in_receipt'))]}"
|
||||
domain="[('allowed_supply_type','in',('in','both'))]"/>
|
||||
<field name="l10n_in_type_id"
|
||||
attrs="{'invisible': [
|
||||
('move_type','in',('out_invoice','out_refund','out_receipt'))]}"
|
||||
domain="[('allowed_supply_type','in',('out','both'))]"/>
|
||||
</group>
|
||||
<group string="Transportation Details" name="transportation_group">
|
||||
<field name="l10n_in_mode"/>
|
||||
<label for="l10n_in_distance"/>
|
||||
<div class="o_row" name="l10n_in_distance">
|
||||
<field name="l10n_in_distance"/>
|
||||
<span>km</span>
|
||||
</div>
|
||||
<field name="l10n_in_vehicle_type"
|
||||
attrs="{'invisible': [('l10n_in_mode','!=','1')], 'required': [('l10n_in_mode','=','1')]}"/>
|
||||
<field name="l10n_in_vehicle_no"
|
||||
attrs="{'invisible': [('l10n_in_mode','!=','1')], 'required': [('l10n_in_mode','=','1')]}"/>
|
||||
<field name="l10n_in_transporter_id"
|
||||
domain="[('vat','not in', ['', False]), ('country_id.code','=','IN')]"
|
||||
attrs="{'invisible': [('l10n_in_mode','!=','0')], 'required': [('l10n_in_mode','=','0')]}"/>
|
||||
<field name="l10n_in_transportation_doc_no"
|
||||
attrs="{'invisible': [('l10n_in_mode','not in',('2','3','4'))], 'required': [('l10n_in_mode','in',('2','3','4'))]}"/>
|
||||
<field name="l10n_in_transportation_doc_date"
|
||||
attrs="{'invisible': [('l10n_in_mode','not in',('2','3','4'))], 'required': [('l10n_in_mode','in',('2','3','4'))]}"/>
|
||||
</group>
|
||||
<group string="Cancel Reason" attrs="{'invisible': ['|', '|',
|
||||
('country_code', '!=', 'IN'),
|
||||
('state', '!=', 'posted'),
|
||||
('l10n_in_edi_show_cancel', '!=', True)]}">
|
||||
<field name="l10n_in_edi_cancel_reason"/>
|
||||
<field name="l10n_in_edi_cancel_remarks"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="l10n_in_einvoice_report_invoice_document_inherit" inherit_id="account.report_invoice_document">
|
||||
<xpath expr="//div[@id='informations']" position="before">
|
||||
<t t-set="l10n_in_ewaybill_json" t-value="o._get_l10n_in_edi_ewaybill_response_json()"/>
|
||||
<div id="l10n_in_ewaybill_informations" class="row mt-4 mb-4">
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="l10n_in_ewaybill_json" name="ewaybill_number">
|
||||
<strong>E-waybill Number:</strong>
|
||||
<p t-if="'EwbNo' in l10n_in_ewaybill_json" class="m-0" t-esc="l10n_in_ewaybill_json['EwbNo']"/>
|
||||
<p t-if="'ewayBillNo' in l10n_in_ewaybill_json" class="m-0" t-esc="l10n_in_ewaybill_json['ewayBillNo']"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="l10n_in_ewaybill_json" name="ewaybill_validity">
|
||||
<strong>E-waybill Valid Till:</strong>
|
||||
<p t-if="'EwbValidTill' in l10n_in_ewaybill_json" class="m-0" t-esc="l10n_in_ewaybill_json['EwbValidTill']"/>
|
||||
<p t-if="'validUpto' in l10n_in_ewaybill_json" class="m-0" t-esc="l10n_in_ewaybill_json['validUpto']"/>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form_inherit_l10n_in_edi_ewaybill" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.form.inherit.l10n_in_edi_ewaybill</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<app name="account" position="inside">
|
||||
<block title="Indian Electronic Waybill" attrs="{'invisible': [('country_code', '!=', 'IN')]}">
|
||||
<setting id="l10n_in_eway_iap" string="Setup Electronic Waybill" help="Check the documentation to get credentials." company_dependent="1">
|
||||
<div class="content-group mt16">
|
||||
<label for="l10n_in_edi_ewaybill_username" string="Username" class="col-3 col-lg-3 o_light_label"/>
|
||||
<field name="l10n_in_edi_ewaybill_username" nolabel="1"/>
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<label for="l10n_in_edi_ewaybill_password" string="Password" class="col-3 col-lg-3 o_light_label" />
|
||||
<field name="l10n_in_edi_ewaybill_password" password="True" nolabel="1"/>
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<label for="l10n_in_edi_production_env" string="Production Environment" class="col-3 col-lg-3 o_light_label"/>
|
||||
<field name="l10n_in_edi_production_env" nolabel="1"/>
|
||||
</div>
|
||||
<div class='mt8'>
|
||||
<button name="l10n_in_edi_ewaybill_test" icon="fa-arrow-right" type="object" string="Verify Username and Password" class="btn-link"/>
|
||||
</div>
|
||||
</setting>
|
||||
</block>
|
||||
</app>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user