diff --git a/addons/l10n_in/data/account_tax_template_data.xml b/addons/l10n_in/data/account_tax_template_data.xml index 5b6a59ee..493850d7 100644 --- a/addons/l10n_in/data/account_tax_template_data.xml +++ b/addons/l10n_in/data/account_tax_template_data.xml @@ -45,7 +45,7 @@ - CESS 5% + RS.1591/THOUSAND + CESS 5% + RS.1591/THOUSAND CESS 5% + RS.1591/THOUSAND sale group @@ -56,14 +56,15 @@ - CESS 21% or RS.4170/THOUSAND + CESS 21% or RS.4170/THOUSAND CESS 21% or RS.4170/THOUSAND sale code 0 result=base_amount * 0.21 -tax=quantity * 4.17 -if tax > result:result=tax + tax=quantity * 4.17 + if tax > result:result=tax + @@ -72,7 +73,7 @@ if tax > result:result=tax - IGST 1% + IGST Sale 1% IGST 1% sale percent @@ -85,7 +86,7 @@ if tax > result:result=tax - IGST 2% + IGST Sale 2% IGST 2% sale percent @@ -98,7 +99,7 @@ if tax > result:result=tax - IGST 28% + IGST Sale 28% IGST 28% sale percent @@ -111,7 +112,7 @@ if tax > result:result=tax - IGST 18% + IGST Sale 18% IGST 18% sale percent @@ -124,7 +125,7 @@ if tax > result:result=tax - IGST 12% + IGST Sale 12% IGST 12% sale percent @@ -137,7 +138,7 @@ if tax > result:result=tax - IGST 5% + IGST Sale 5% IGST 5% sale percent @@ -178,7 +179,7 @@ if tax > result:result=tax - GST 1% + GST Sale 1% GST 1% sale group @@ -214,7 +215,7 @@ if tax > result:result=tax - GST 2% + GST Sale 2% GST 2% sale group @@ -250,7 +251,7 @@ if tax > result:result=tax - GST 28% + GST Sale 28% GST 28% sale group @@ -259,7 +260,7 @@ if tax > result:result=tax - + SGST Sale 9% SGST 9% none @@ -286,7 +287,7 @@ if tax > result:result=tax - GST 18% + GST Sale 18% GST 18% sale group @@ -322,7 +323,7 @@ if tax > result:result=tax - GST 12% + GST Sale 12% GST 12% sale group @@ -331,7 +332,7 @@ if tax > result:result=tax - + SGST Sale 2.5% SGST 2.5% none @@ -358,7 +359,7 @@ if tax > result:result=tax - GST 5% + GST Sale 5% GST 5% sale group @@ -394,7 +395,7 @@ if tax > result:result=tax - CESS 5% + RS.1591/THOUSAND + CESS 5% + RS.1591/THOUSAND CESS 5% + RS.1591/THOUSAND purchase group @@ -404,14 +405,15 @@ if tax > result:result=tax - CESS 21% or RS.4170/THOUSAND + CESS 21% or RS.4170/THOUSAND CESS 21% or RS.4170/THOUSAND purchase code 0 result=base_amount * 0.21 -tax=quantity * 4.17 -if tax > result:result=tax + tax=quantity * 4.17 + if tax > result:result=tax + @@ -420,7 +422,7 @@ if tax > result:result=tax - IGST 1% + IGST Purchase 1% IGST 1% purchase percent @@ -433,7 +435,7 @@ if tax > result:result=tax - IGST 2% + IGST Purchase 2% IGST 2% purchase percent @@ -446,7 +448,7 @@ if tax > result:result=tax - IGST 28% + IGST Purchase 28% IGST 28% purchase percent @@ -459,7 +461,7 @@ if tax > result:result=tax - IGST 18% + IGST Purchase 18% IGST 18% purchase percent @@ -472,7 +474,7 @@ if tax > result:result=tax - IGST 12% + IGST Purchase 12% IGST 12% purchase percent @@ -485,7 +487,7 @@ if tax > result:result=tax - IGST 5% + IGST Purchase 5% IGST 5% purchase percent @@ -526,7 +528,7 @@ if tax > result:result=tax - GST 1% + GST Purchase 1% GST 1% purchase group @@ -562,7 +564,7 @@ if tax > result:result=tax - GST 2% + GST Purchase 2% GST 2% purchase group @@ -598,7 +600,7 @@ if tax > result:result=tax - GST 28% + GST Purchase 28% GST 28% purchase group @@ -607,7 +609,7 @@ if tax > result:result=tax - + SGST Purchase 9% SGST 9% none @@ -634,7 +636,7 @@ if tax > result:result=tax - GST 18% + GST Purchase 18% GST 18% purchase group @@ -670,7 +672,7 @@ if tax > result:result=tax - GST 12% + GST Purchase 12% GST 12% purchase group @@ -706,7 +708,7 @@ if tax > result:result=tax - GST 5% + GST Purchase 5% GST 5% purchase group @@ -715,4 +717,33 @@ if tax > result:result=tax + + + Exempt 0% + Exempt 0% + sale + percent + 0 + 19 + + + + + + + + Exempt 0% + Exempt 0% + purchase + percent + 0 + 60 + + + + + + diff --git a/addons/l10n_in/data/l10n_in_chart_data.xml b/addons/l10n_in/data/l10n_in_chart_data.xml index ac4e14e1..03dce09b 100644 --- a/addons/l10n_in/data/l10n_in_chart_data.xml +++ b/addons/l10n_in/data/l10n_in_chart_data.xml @@ -33,21 +33,21 @@ accounts - + Inventories 10031 - + Debtors 10040 - + SGST Receivable 10051 @@ -56,7 +56,7 @@ - + CGST Receivable 10052 @@ -65,7 +65,7 @@ - + IGST Receivable 10053 @@ -73,21 +73,21 @@ - + TDS Receivable 10058 - + Deposit Account 10061 - + Prepaid Insurance 10071 @@ -95,56 +95,56 @@ - + Buildings 1011 - + Land 1012 - + Equipments 1013 - + Vehicle 1014 - + Computer/Laptops (Assets) 1015 - + Furniture 1016 - + Air Conditionar 1017 - + Misc Assets 1018 @@ -154,56 +154,56 @@ - + Capital Account 1111 - + Reserve And Surplus Account 1112 - + Creditors 11211 - + Bank OD Account 11221 - + Secured Loan Account 11222 - + Unsecured Loan Account 11223 - + TDS Payable 11231 - + SGST Payable 11232 @@ -212,7 +212,7 @@ - + CGST Payable 11233 @@ -221,7 +221,7 @@ - + IGST Payable 11234 @@ -229,21 +229,21 @@ - + Wages Payable 11241 - + Interest Payable 11242 - + Notes Payable 11243 @@ -252,63 +252,63 @@ - + Local Sales 20011 - + Retail Sales 20012 - + Export Sales 20013 - + Local Services 20021 - + Export Services 20022 - + Interest Revenues 2010 - + Gain on Sale of Assets 2011 - + Write off Income 2012 - + Foreign Exchange Profit 2013 @@ -317,182 +317,182 @@ - + Electricity Expense 2100 - + Salary Expense 2101 - + Office Rent 2102 - + House Keeping Expense 2103 - + Postage And Courier Expense 2104 - + Internet Expense 2105 - + Telephone Expense 2106 - + Purchase Expense 2107 - + Computer/Laptop Accessories 2108 - + News Paper And Magazine 2109 - + Business Promotion 2110 - + Entertainment Expense 2111 - + Professional Services 2112 - + Bank Charges 2113 - + Diwali Bonus/Gift 2114 - + Parts Purchase 2115 - + Repairing Expense 2116 - + Foreign Exchange Loss 2117 - + Sales Commission Expense 21181 - + Stationary Expense 21182 - + Travelling Expense 21183 - + Opening Stock 2121 - + Purchase Stock 2122 - + Closing Stock 2123 - + Loss on Sale of Assets 2131 - + Write Off Expense 2132 @@ -500,14 +500,258 @@ - - - - - - - - - + + Sales Tax Receivable + 10050 + + + + + + VAT Receivable + 10054 + + + + + + Excise Duty Receivable + 100521 + + + + + + Education Cess Receivable On Excise Duty + 100522 + + + + + + Higher Education Cess Receivable On Excise + Duty + + 100523 + + + + + + Service Tax Receivable + 100531 + + + + + + Education Cess Receivable On Service Tax + 100532 + + + + + + Higher Education Cess Receivable On Service + Tax + + 100533 + + + + + + + + Capital Account + 1111 + + + + + + Reserve And Surplus Account + 1112 + + + + + + Creditors + 11211 + + + + + + Bank OD Account + 11221 + + + + + + Secured Loan Account + 11222 + + + + + + Unsecured Loan Account + 11223 + + + + + + TDS Payable + 11231 + + + + + + VAT Payable + 11232 + + + + + + Excise Duty Payable + 112331 + + + + + + Education Cess Payable On Excise Duty + 112332 + + + + + + Higher Education Cess Payable On Excise Duty + + 112333 + + + + + + Service Tax Payable + 112341 + + + + + + Education Cess Payable On Service Tax + 112342 + + + + + + Higher Education Cess Payable On Service Tax + + 112343 + + + + + + Sales Tax Payable + 11235 + + + + + + Wages Payable + 11241 + + + + + + Interest Payable + 11242 + + + + + + Notes Payable + 11243 + + + + + + + Exempt + accounts + + + + Exempt-Sales Account + 112540 + + + + + + + + Exempt-Purchase Account + 100840 + + + + + + + + + + + + + + + diff --git a/addons/l10n_in_gst/__init__.py b/addons/l10n_in_gst/__init__.py new file mode 100644 index 00000000..47f89334 --- /dev/null +++ b/addons/l10n_in_gst/__init__.py @@ -0,0 +1,6 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import models +from . import wizard +from . import report +from . import controllers diff --git a/addons/l10n_in_gst/__manifest__.py b/addons/l10n_in_gst/__manifest__.py new file mode 100644 index 00000000..df4533db --- /dev/null +++ b/addons/l10n_in_gst/__manifest__.py @@ -0,0 +1,44 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +{ + 'name': 'GST Reporting For Indian Localization', + 'version': '1.0', + 'author': 'FlectraHQ', + 'website': 'https://flectrahq.com', + 'category': 'Accounting', + 'summary': 'Goods and Services Tax (India)', + 'description': ''' + GST module for Flectra enables Indian Organization to use Flectra + Accounting in accordance to GST taxation structure. Providing + necessary reporting data for GSTR-1 & GSTR-2 filling, Tax Credit etc. + ''', + 'depends': ['account_invoicing', 'l10n_in'], + 'data': [ + 'security/ir.model.access.csv', + 'data/product_uom_data.xml', + 'data/note_issue_reason_data.xml', + 'wizard/account_invoice_refund_view.xml', + 'views/product_uom_view.xml', + 'views/res_partner_view.xml', + 'views/res_company_view.xml', + 'views/account_invoice_view.xml', + 'views/res_config_settings_views.xml', + 'views/gst_report_view.xml', + 'views/assets.xml', + 'views/note_issue_reason_view.xml', + 'views/menuitems_view.xml', + ], + 'qweb': [ + 'static/src/xml/*.xml' + ], + 'demo': [ + 'demo/res_company_demo.xml', + 'demo/res_partner_demo.xml', + 'demo/product_demo.xml', + 'demo/account_account_demo.xml', + 'demo/account_invoice_demo.xml', + ], + 'installable': True, + 'auto_install': False, + 'application': True, +} diff --git a/addons/l10n_in_gst/controllers/__init__.py b/addons/l10n_in_gst/controllers/__init__.py new file mode 100644 index 00000000..52c05d92 --- /dev/null +++ b/addons/l10n_in_gst/controllers/__init__.py @@ -0,0 +1,3 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import main diff --git a/addons/l10n_in_gst/controllers/main.py b/addons/l10n_in_gst/controllers/main.py new file mode 100644 index 00000000..a092d1d9 --- /dev/null +++ b/addons/l10n_in_gst/controllers/main.py @@ -0,0 +1,58 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from datetime import datetime + +import pytz +from flectra import http, _ +from flectra.http import request +from flectra.tools import DEFAULT_SERVER_DATETIME_FORMAT + + +class ExportExcel(http.Controller): + @http.route('/l10n_in_gst/export_excel', type='http', auth='user') + def get_report(self, **kwargs): + uid = request.session.uid + gst_report_obj = request.env['gst.report'].sudo(uid) + data = { + 'from_date': kwargs['from_date'], + 'to_date': kwargs['to_date'], + 'company_id': int(kwargs['company_id']), + 'year': kwargs['year'], + 'month': kwargs['month'], + 'summary_type': kwargs['summary_type'], + } + + utc_tz = pytz.timezone('UTC') + tz = pytz.timezone( + request.env.user.tz) if request.env.user.tz else pytz.utc + + def utc_to_local_zone(naive_datetime): + utc_dt = utc_tz.localize(naive_datetime, + is_dst=False) + return utc_dt.astimezone(tz) + + create_date = datetime.strptime( + datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT), + DEFAULT_SERVER_DATETIME_FORMAT) + company_id = request.env['res.company'].browse(int(data['company_id'])) + gst_file_name = '' + if data['summary_type'] == 'gstr1': + gst_file_name = _('GSTR-1') + elif data['summary_type'] == 'gstr2': + gst_file_name = _('GSTR-2') + filename = gst_file_name + _('_%s_%s-%s_%s.xlsx') % ( + company_id.vat, datetime.today().strftime("%B"), + data['year'], + utc_to_local_zone(create_date).strftime( + "%d/%m/%Y %H:%M:%S")) + + response = request.make_response( + None, + headers=[ + ('Content-Type', 'application/vnd.ms-excel'), + ('Content-Disposition', + 'attachment; filename=' + filename + ';') + ] + ) + gst_report_obj.print_report(data, 1, response) + return response diff --git a/addons/l10n_in_gst/data/note_issue_reason_data.xml b/addons/l10n_in_gst/data/note_issue_reason_data.xml new file mode 100644 index 00000000..dff2a36b --- /dev/null +++ b/addons/l10n_in_gst/data/note_issue_reason_data.xml @@ -0,0 +1,44 @@ + + + + + + + + + 01 + Sales Return + + + + 02 + Post Sale Discount + + + + 03 + Deficiency in services + + + + 04 + Correction in Invoice + + + + 05 + Change in POS + + + + 06 + Finalization of Provisional assessment + + + + 07 + Others + + + + diff --git a/addons/l10n_in_gst/data/product_uom_data.xml b/addons/l10n_in_gst/data/product_uom_data.xml new file mode 100644 index 00000000..f25337bb --- /dev/null +++ b/addons/l10n_in_gst/data/product_uom_data.xml @@ -0,0 +1,425 @@ + + + + + + + + CENTIMETER + CMS + + + + DOZEN + DOZ + + + + FTS + FEET + + + + GMS + GRAMS + + + + INC + INCHES + + + + KGS + Kilograms + + + + + KILOLITER + + + KLR + + + + KME + KILOMETERS + + + + LTR + LITERS + + + + MTR + METER + + + + QTL + QUINTAL + + + + UGS + US GALLONS + + + + UNT + UNITS + + + + LBS + POUNDS + + + + + BAG + + + BAG + + + + + BAGS + + + BGS + + + + + BUCKLES + + + BKL + + + + + BOU + + + BOU + + + + + BOX + + + BOX + + + + + BUNCHES + + + BUN + + + + + BOTTLES + + + BTL + + + + + CUBIC METER + + + CBM + + + + + CUBIC METERS + + + CQM + + + + + CUBIC CENTIMETER + + + CCM + + + + + CUBIC INCHES + + + CIN + + + + + CARTON + + + CTN + + + + + DRUM + + + DRM + + + + + GREAT GROSS + + + GGR + + + + + GROSS + + + GRS + + + + + GROSS YARDS + + + GYD + + + + + HANKS + + + HKS + + + + + LOTS + + + LOT + + + + + MILLI GRAMS + + + MGS + + + + + METRIC TON + + + MTS + + + + + Numbers + + + NOS + + + + + ODDS + + + ODD + + + + + PACKS + + + PAC + + + + + Pieces + + + PCS + + + + + PAIRS + + + PRS + + + + + ROLLS + + + ROL + + + + + DECAMETER SQUARE + + + SDM + + + + + SETS + + + SET + + + + + SHEETS + + + SHT + + + + + SQUARE INCHES + + + SQI + + + + + SQUARE FEET + + + SQF + + + + + SQUARE METER + + + SQM + + + + + SQUARE YARDS + + + SQY + + + + + TABLETS + + + TBS + + + + + THOUSANDS + + + THD + + + + + TOLA + + + TOL + + + + + GREAT BRITAIN TON + + + TON + + + + + TUBES + + + TUB + + + + + Vials + + + VLS + + + + + YARDS + + + YDS + + + + DAY + + + + FLOZ + + + + HOUR + + + + MILE + + + + OZ + + + + TON + + + + diff --git a/addons/l10n_in_gst/demo/account_account_demo.xml b/addons/l10n_in_gst/demo/account_account_demo.xml new file mode 100644 index 00000000..5fa0b700 --- /dev/null +++ b/addons/l10n_in_gst/demo/account_account_demo.xml @@ -0,0 +1,19 @@ + + + + + + + + 200111 + Demo Local Sales + + + + + Purchase Expense + 21071 + + + + diff --git a/addons/l10n_in_gst/demo/account_invoice_demo.xml b/addons/l10n_in_gst/demo/account_invoice_demo.xml new file mode 100644 index 00000000..1e1d023b --- /dev/null +++ b/addons/l10n_in_gst/demo/account_invoice_demo.xml @@ -0,0 +1,677 @@ + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Little server + + + 40000.0 + 2.0 + + + + + + + Basic Computer + + + 23500.0 + 3.0 + + + + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Server + + + 65000.0 + 4.0 + + + + + + + Basic Computer + + + 23500.0 + 1.0 + + + + + + + Laptop E5023 + + + 2870.0 + 3.0 + + + + + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Little server + + + 40000.0 + 1.0 + + + + + + + Basic Computer + + + 23500.0 + 4.0 + + + + + + + Server + + + 65000.0 + 2.0 + + + + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Little server + + + 40000.0 + 2.0 + + + + + + + Server + + + 65000.0 + 5.0 + + + + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Laptop E5023 + + + 2870.0 + 8.0 + + + + + + + Server + + + 65000.0 + 4.0 + + + + + + + + + + + 04-Correction in Invoice + refund + + + + + + + + + + + + 03-Deficiency in services + refund + + + + + + + + + + + + + + + none + + draft + out_invoice + + + + + + + Laptop E5023 + + + 2870.0 + 8.0 + + + + + Server + + + 65000.0 + 6.0 + + + + + + + + none + + draft + out_invoice + + + + + + + Server + + + 65000.0 + 1.0 + + + + + Basic Computer + + + 23500.0 + 2.0 + + + + + Laptop E5023 + + + 2870.0 + 5.0 + + + + + + + + none + + draft + out_invoice + + + + + + + Little server + + + 40000.0 + 2.0 + + + + + Basic Computer + + + 23500.0 + 3.0 + + + + + Server + + + 65000.0 + 2.0 + + + + + + + + none + + draft + out_invoice + + + + + + + Laptop E5023 + + + 2870.0 + 2.0 + + + + + Server + + + 65000.0 + 3.0 + + + + + + + + none + + draft + out_invoice + + + + + + + Laptop E5023 + + + 2870.0 + 8.0 + + + + + + + Server + + + 65000.0 + 4.0 + + + + + + + + + + + 04-Correction in Invoice + refund + + + + + + + + + + + + 03-Deficiency in services + refund + + + + + + + + + + + + + + + + none + + draft + in_invoice + + + + + + + Little server + + + 40000.0 + 2.0 + + + + + + + Basic Computer + + + 23500.0 + 3.0 + + + + + + + + + + + + + + + none + + draft + in_invoice + + + + + + + Little server + + + 40000.0 + 1.0 + + + + + + + Basic Computer + + + 23500.0 + 4.0 + + + + + + + Server + + + 65000.0 + 2.0 + + + + + + + + + + + 04-Correction in Invoice + refund + + + + + + + + + + + + 03-Deficiency in services + refund + + + + + + + + + + + diff --git a/addons/l10n_in_gst/demo/product_demo.xml b/addons/l10n_in_gst/demo/product_demo.xml new file mode 100644 index 00000000..7f49d6bd --- /dev/null +++ b/addons/l10n_in_gst/demo/product_demo.xml @@ -0,0 +1,33 @@ + + + + + + + + + 8492 + + + + + + 84713011 + + + + + + 847132 + + + + + + 84713011 + + + + + + diff --git a/addons/l10n_in_gst/demo/res_company_demo.xml b/addons/l10n_in_gst/demo/res_company_demo.xml new file mode 100644 index 00000000..a969190a --- /dev/null +++ b/addons/l10n_in_gst/demo/res_company_demo.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/addons/l10n_in_gst/demo/res_partner_demo.xml b/addons/l10n_in_gst/demo/res_partner_demo.xml new file mode 100644 index 00000000..d3097721 --- /dev/null +++ b/addons/l10n_in_gst/demo/res_partner_demo.xml @@ -0,0 +1,126 @@ + + + + + + + + regular + 24ABCDE1234F2Z5 + + + + + + + Demo SGST/CGST Registered Customer + + 1 + Ahmedabad + 380009 + + + 22 Globe Street + 24ANMPD7592B1Z2 + regular + sgst_cgst@yourcompany.example.com + +91 99111 2223 + http://www.sgstcgst.com + + + + + Demo SGST/CGST Unregistered Customer + + 1 + Vadodara + 391510 + + + Ajwa + unregistered + sgst_cgst_ur@yourcompany.example.com + +91 75123 75123 + http://www.sgstcgstur.com + + + + + Demo IGST Registered Customer + + 1 + Delhi + 110018 + + + 15 Ashok Nagar + 07GEOPS0823B2ZH + regular + igst@yourcompany.example.com + +91 99222 5553 + http://www.igst.com + + + + + + Demo IGST Unregistered Customer + + 1 + Darrang + 784527 + + + 16 Natrani Avenue + unregistered + igstur@yourcompany.example.com + +91 95951 95951 + http://www.igstur.com + + + + + + Demo B2B Registered Supplier + + 1 + 1 + Ahmedabad + 380009 + + + 22 Globe Street + 24ANMPDFGH55678 + regular + b2b_supplier@yourcompany.example.com + +91 99111 5454 + http://www.b2bsupplier.com + + + + + Demo B2BUR Unregistered Supplier + + 1 + 1 + Vadodara + 391510 + + + gotri + unregistered + b2b_ur_supplier@yourcompany.example.com + +91 75123 77777 + http://www.b2bur.com + + + + diff --git a/addons/l10n_in_gst/i18n/l10n_in_gst.pot b/addons/l10n_in_gst/i18n/l10n_in_gst.pot new file mode 100644 index 00000000..54bd8ffd --- /dev/null +++ b/addons/l10n_in_gst/i18n/l10n_in_gst.pot @@ -0,0 +1,1121 @@ +# Translation of Flectra Server. +# This file contains the translation of the following modules: +# * l10n_in_gst +# +msgid "" +msgstr "" +"Project-Id-Version: Flectra Server 1.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-04-17 08:40+0000\n" +"PO-Revision-Date: 2018-04-17 08:40+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_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:197 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:318 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:439 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:584 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:729 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:918 +#, python-format +msgid "Amount" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_invoice:0 +msgid "B2B" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:481 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:114 +#, python-format +msgid "B2B Invoices - 4A, 4B, 4C, 6B, 6C" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,help:l10n_in_gst.field_account_invoice_gst_invoice +msgid "B2B Supplies: Taxable supplies made to other registered taxpayers.\n" +"\n" +"B2C Large [For outward supplies]: Taxable outward supplies to consumers where\n" +"a)The place of supply is outside the state where the supplier is registered and b)The total invoice value is more than the limit defined in company B2C lines.\n" +"e.g., If in B2C line, B2CL limit is set to Rs 2,50,000 (for period 01-01-2017 to 31-12-2017) and invoice is of amount Rs 3,00,000 then invoice will be considered as of type B2CL.\n" +"\n" +"B2C Small [For outward supplies]: Supplies made to consumers and unregistered persons of the following nature\n" +"a) Intra-State: any value b) Inter-State: Total invoice value is less than the limit defined in company B2C lines.\n" +"e.g., If in B2C line, B2CS limit is set to Rs 2,50,000 (for period 01-01-2017 to 31-12-2017) for inter state supply and invoice value is Rs 2,00,000 then invoice will be considered as of type B2CS.\n" +"\n" +"B2BUR [For inward supplies]: Inward supplies received from an unregistered supplier \n" +"\n" +"" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_invoice:0 +msgid "B2BUR" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_company_b2c_limit_line +#: model:ir.ui.view,arch_db:l10n_in_gst.view_company_form_gst +msgid "B2C Limit" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:497 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:250 +#, python-format +msgid "B2C(Large) Invoices - 5A, 5B" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:502 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:371 +#, python-format +msgid "B2C(Small) Details - 7" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_invoice:0 +msgid "B2CL" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_b2cl_limit +msgid "B2CL Limit" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_invoice:0 +msgid "B2CS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_b2cs_limit +msgid "B2CS Limit" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_bag +msgid "BAG" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_BAGS +msgid "BAGS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_btl +msgid "BOTTLES" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_bou +msgid "BOU" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_box +msgid "BOX" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_buckles +msgid "BUCKLES" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_bun +msgid "BUNCHES" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_ctn +msgid "CARTON" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:137 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:196 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:267 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:317 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:388 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:438 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:517 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:583 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:662 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:728 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:798 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:867 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:917 +#, python-format +msgid "CESS" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:135 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:194 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:265 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:315 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:386 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:436 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:515 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:581 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:660 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:726 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:796 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:865 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:915 +#, python-format +msgid "CGST" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_ccm +msgid "CUBIC CENTIMETER" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_cin +msgid "CUBIC INCHES" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_cbm +msgid "CUBIC METER" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_cqm +msgid "CUBIC METERS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_code +#: model:ir.model.fields,field_description:l10n_in_gst.field_product_uom_code +msgid "Code" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_res_company +msgid "Companies" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_company_id +msgid "Company" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.view,arch_db:l10n_in_gst.view_res_company_b2c_limit_form +#: model:ir.ui.view,arch_db:l10n_in_gst.view_res_company_b2c_limit_tree +msgid "Company B2C Limit" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_type:0 +#: selection:res.config.settings,gst_type:0 +#: selection:res.partner,gst_type:0 +msgid "Composite" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_res_partner +msgid "Contact" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_config_settings_country_id +msgid "Country" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_create_uid +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_create_uid +msgid "Created by" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_create_date +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_create_date +msgid "Created on" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_account_invoice_refund +msgid "Credit Note" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:507 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:493 +#, python-format +msgid "Credit/Debit Notes(Registered) - 9B" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:641 +#, python-format +msgid "Credit/Debit Notes(Unregistered) - 6C" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:517 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:638 +#, python-format +msgid "Credit/Debit Notes(Unregistered) - 9B" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sdm +msgid "DECAMETER SQUARE" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_drm +msgid "DRUM" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:496 +#, python-format +msgid "Debit/Credit Notes (Registered) - 6C" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/report/gst_report.py:509 +#, python-format +msgid "Debit/Credit Notes(Registered) - 6C" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/report/gst_report.py:519 +#, python-format +msgid "Debit/Credit Notes(Unregistered) - 6C" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:790 +#, python-format +msgid "Description" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_gst_report_display_name +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_display_name +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_display_name +msgid "Display Name" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:509 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:654 +#, python-format +msgid "Document Type" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_partner_e_commerce +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_users_e_commerce +#: model:ir.ui.view,arch_db:l10n_in_gst.view_account_invoice_search +msgid "E-Commerce" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:261 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:382 +#, python-format +msgid "E-Commerce\n" +" GSTIN" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:132 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:862 +#, python-format +msgid "E-Commerce GSTIN" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_e_commerce_partner_id +msgid "E-Commerce Partner" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:10 +#, python-format +msgid "Export XLS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_date_from +msgid "From" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/models/res_company.py:108 +#, python-format +msgid "From date must be lower than to date." +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_ton +msgid "GREAT BRITAIN TON" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_ggr +msgid "GREAT GROSS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_grs +msgid "GROSS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_gyd +msgid "GROSS YARDS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.view,arch_db:l10n_in_gst.res_config_settings_view_form_inherit_l10n_in_gst +msgid "GST" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_config_settings_gst_applied +msgid "GST Applied" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_gst_introduce_date +msgid "GST Introduce Date" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_gst_invoice +#: model:ir.ui.view,arch_db:l10n_in_gst.view_account_invoice_search +msgid "GST Invoice" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.menu,name:l10n_in_gst.menu_gst_reports +msgid "GST Reports" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_gst_type +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_gst_type +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_config_settings_gst_type +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_partner_gst_type +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_users_gst_type +msgid "GST Type" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_vat +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_config_settings_gstin_number +msgid "GSTIN" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/models/res_company.py:41 +#, python-format +msgid "GSTIN length must be of 15 characters!" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:504 +#, python-format +msgid "GSTIN/UIN of Recipient" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/controllers/main.py:40 +#, python-format +msgid "GSTR-1" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.menu,name:l10n_in_gst.l10n_in_gst_report_menu +msgid "GSTR-1 Summary" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/controllers/main.py:42 +#, python-format +msgid "GSTR-2" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.menu,name:l10n_in_gst.l10n_in_gst2_report_menu +msgid "GSTR-2 Summary" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.actions.client,name:l10n_in_gst.l10n_in_gst_report_action +msgid "GSTR1" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.actions.client,name:l10n_in_gst.l10n_in_gstr2_report_action +msgid "GSTR2" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,help:l10n_in_gst.field_account_invoice_vat +msgid "Goods and Services Taxpayer Identification Number" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_hks +msgid "HANKS" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:789 +#, python-format +msgid "HSN" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:586 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:782 +#, python-format +msgid "HSN-Wise Summary of outward Supplies - 12" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_gst_report_id +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_id +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_id +msgid "ID" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:134 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:193 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:264 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:314 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:385 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:435 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:514 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:580 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:659 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:725 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:795 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:864 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:914 +#, python-format +msgid "IGST" +msgstr "" + +#. module: l10n_in_gst +#: selection:res.partner,partner_location:0 +msgid "Inter Country" +msgstr "" + +#. module: l10n_in_gst +#: selection:res.partner,partner_location:0 +msgid "Inter State" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,help:l10n_in_gst.field_res_company_b2c_limit_b2cs_limit +msgid "Inter state maximum limit for B2CS type transactions." +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,help:l10n_in_gst.field_res_company_b2c_limit_b2cl_limit +msgid "Inter state minimum limit for B2CL type transactions." +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/models/res_company.py:38 +#, python-format +msgid "Invalid State Code!" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:130 +#, python-format +msgid "Invoice Type" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:505 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:650 +#, python-format +msgid "Invoice/Advance Receipt Number" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:506 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:651 +#, python-format +msgid "Invoice/Advance Receipt date" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:127 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:258 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:859 +#, python-format +msgid "Invoices Date" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:126 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:257 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:378 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:858 +#, python-format +msgid "Invoices No." +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_partner_gst_company_partner +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_users_gst_company_partner +msgid "Is company partner?" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_kiloltr +msgid "KILOLITER" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_lot +msgid "LOTS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_gst_report___last_update +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason___last_update +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit___last_update +msgid "Last Modified on" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_write_uid +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_write_date +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_write_date +msgid "Last Updated on" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_mts +msgid "METRIC TON" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_mgs +msgid "MILLI GRAMS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_note_issue_reason_name +msgid "Name" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:101 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:238 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:358 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:480 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:625 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:770 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:839 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:958 +#, python-format +msgid "No Record Found" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:67 +#, python-format +msgid "No. of Invoices" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.actions.act_window,name:l10n_in_gst.act_open_note_issue_reason_view +#: model:ir.ui.menu,name:l10n_in_gst.menu_note_issue_reason +#: model:ir.ui.view,arch_db:l10n_in_gst.view_note_issue_reason_form +#: model:ir.ui.view,arch_db:l10n_in_gst.view_note_issue_reason_search +#: model:ir.ui.view,arch_db:l10n_in_gst.view_note_issue_reason_tree +msgid "Note Issue Reasons" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:507 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:652 +#, python-format +msgid "Note/Refund Voucher Number" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:508 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:653 +#, python-format +msgid "Note/Refund Voucher date" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_nos +msgid "Numbers" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_odd +msgid "ODDS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_pac +msgid "PACKS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_prs +msgid "PAIRS" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_partner_location +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_partner_partner_location +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_users_partner_location +msgid "Partner Location" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_pcs +msgid "Pieces" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:511 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:656 +#, python-format +msgid "Place Of Supply" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:128 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:259 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:379 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:860 +#, python-format +msgid "Place of Supply" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/models/account_invoice.py:95 +#, python-format +msgid "Please define B2C limit line in company for current period!" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:518 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:663 +#, python-format +msgid "Pre GST" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:192 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:313 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:434 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:579 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:724 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:913 +#, python-format +msgid "Price" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:190 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:311 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:432 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:577 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:722 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:911 +#, python-format +msgid "Product Name" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_product_uom +msgid "Product Unit of Measure" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:191 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:312 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:433 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:578 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:723 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:912 +#, python-format +msgid "Quantity" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_rol +msgid "ROLLS" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:129 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:260 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:380 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:512 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:657 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:861 +#, python-format +msgid "Rate" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:510 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:655 +#, python-format +msgid "Reason For Issuing document" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_account_invoice_refund_note_issue_reason_id +msgid "Reason for Issuing Note" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:125 +#, python-format +msgid "Receiver GSTIN/UIN" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_type:0 +#: selection:res.config.settings,gst_type:0 +#: selection:res.partner,gst_type:0 +msgid "Regular" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:131 +#, python-format +msgid "Reverse Charges" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_set +msgid "SETS" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:136 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:195 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:266 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:316 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:387 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:437 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:516 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:582 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:661 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:727 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:797 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:866 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:916 +#, python-format +msgid "SGST" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sht +msgid "SHEETS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sqf +msgid "SQUARE FEET" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sqi +msgid "SQUARE INCHES" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sqm +msgid "SQUARE METER" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_sqy +msgid "SQUARE YARDS" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:66 +#, python-format +msgid "Section Name" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_config_settings_state_id +msgid "State" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:59 +#, python-format +msgid "Summary" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:483 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:117 +#, python-format +msgid "Supplies From Registered Suppliers B2B - 3,4A" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/report/gst_report.py:491 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:851 +#, python-format +msgid "Supplies From Unregistered Suppliers B2BUR - 4C" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_tbs +msgid "TABLETS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_thd +msgid "THOUSANDS" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_tol +msgid "TOLA" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_tub +msgid "TUBES" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:133 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:263 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:384 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:513 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:658 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:794 +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:863 +#, python-format +msgid "Taxable Value" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.ui.view,arch_db:l10n_in_gst.invoice_form_gst +msgid "Taxes" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model.fields,field_description:l10n_in_gst.field_res_company_b2c_limit_date_to +msgid "To" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:71 +#, python-format +msgid "Total CESS (₹)" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:68 +#, python-format +msgid "Total Central Tax Amount (₹)" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:70 +#, python-format +msgid "Total Integrated Tax Amount (₹)" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:792 +#, python-format +msgid "Total Quantity" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:69 +#, python-format +msgid "Total State/UT Tax Amount (₹)" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:793 +#, python-format +msgid "Total Value" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:381 +#, python-format +msgid "Type" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:791 +#, python-format +msgid "UQC" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:649 +#, python-format +msgid "UR Type" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_type:0 +#: selection:res.config.settings,gst_type:0 +#: selection:res.partner,gst_type:0 +msgid "Unregistered" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_vls +msgid "Vials" +msgstr "" + +#. module: l10n_in_gst +#. flectra-web +#: code:addons/l10n_in_gst/static/src/xml/gst_report.xml:13 +#, python-format +msgid "View Summary" +msgstr "" + +#. module: l10n_in_gst +#: selection:account.invoice,gst_type:0 +#: selection:res.config.settings,gst_type:0 +#: selection:res.partner,gst_type:0 +msgid "Volunteer" +msgstr "" + +#. module: l10n_in_gst +#: model:product.uom,name:l10n_in_gst.product_uom_yds +msgid "YARDS" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/models/res_company.py:99 +#, python-format +msgid "You cannot have 2 limit lines of same period that overlap for %s!" +msgstr "" + +#. module: l10n_in_gst +#: code:addons/l10n_in_gst/controllers/main.py:43 +#, python-format +msgid "_%s_%s-%s_%s.xlsx" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_gst_report +msgid "gst.report" +msgstr "" + +#. module: l10n_in_gst +#: selection:res.partner,partner_location:0 +msgid "intra State" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_note_issue_reason +msgid "note.issue.reason" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_res_company_b2c_limit +msgid "res.company.b2c.limit" +msgstr "" + +#. module: l10n_in_gst +#: model:ir.model,name:l10n_in_gst.model_res_config_settings +msgid "res.config.settings" +msgstr "" + diff --git a/addons/l10n_in_gst/models/__init__.py b/addons/l10n_in_gst/models/__init__.py new file mode 100644 index 00000000..9b46e182 --- /dev/null +++ b/addons/l10n_in_gst/models/__init__.py @@ -0,0 +1,8 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import res_config_settings +from . import account_invoice +from . import note_issue_reason +from . import product_uom +from . import res_company +from . import res_partner diff --git a/addons/l10n_in_gst/models/account_invoice.py b/addons/l10n_in_gst/models/account_invoice.py new file mode 100644 index 00000000..a49e2ed2 --- /dev/null +++ b/addons/l10n_in_gst/models/account_invoice.py @@ -0,0 +1,123 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra import api, fields, models, _ +from flectra.exceptions import ValidationError + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + gst_invoice = fields.Selection( + [('b2b', 'B2B'), ('b2cl', 'B2CL'), ('b2cs', 'B2CS'), + ('b2bur', 'B2BUR')], string='GST Invoice', + help='B2B Supplies: Taxable supplies made to other registered ' + 'taxpayers.\n\nB2C Large [For outward supplies]: Taxable ' + 'outward ' + 'supplies to consumers where\na)The place of supply is ' + 'outside the state where the supplier is registered and ' + 'b)The ' + 'total invoice value is more than the limit defined in ' + 'company B2C lines.\ne.g., If in B2C line, B2CL limit is ' + 'set to Rs 2,50,000 and invoice is of amount Rs 3,00,000 then' + 'invoice ' + 'will be considered as of type B2CL.\n\nB2C Small ' + '[For outward supplies]: Supplies made to consumers and ' + 'unregistered persons of the following nature\n' + 'a) Intra-State: any value b) Inter-State: Total invoice ' + 'value is' + ' less than the limit defined in company B2C lines.\n' + 'e.g., If in B2C line, B2CS limit is set to Rs 2,50,000 ' + '(for period 01-01-2017 to 31-12-2017) for inter state ' + 'supply ' + 'and invoice value is Rs 2,00,000 then invoice will be ' + 'considered as of type B2CS.\n\nB2BUR [For inward supplies]: ' + 'Inward supplies received from an unregistered supplier \n\n', + copy=False) + e_commerce_partner_id = fields.Many2one('res.partner', + string='E-Commerce Partner') + vat = fields.Char(string='GSTIN', + help='Goods and Services Taxpayer Identification ' + 'Number', size=15, copy=False) + gst_type = fields.Selection( + [('regular', 'Regular'), ('unregistered', 'Unregistered'), + ('composite', 'Composite'), ('volunteer', 'Volunteer')], + string='GST Type', copy=False) + partner_location = fields.Selection( + [('inter_state', 'Inter State'), ('intra_state', 'intra State'), + ('inter_country', 'Inter Country')], + related='partner_id.partner_location', string="Partner Location") + + @api.onchange('partner_id', 'company_id') + def _onchange_partner_id(self): + super(AccountInvoice, self)._onchange_partner_id() + if self.partner_id and not self.partner_id.partner_location: + self.partner_id.partner_location = \ + self.partner_id._get_partner_location_details(self.company_id) + + @api.onchange('fiscal_position_id') + def _onchange_fiscal_position_id(self): + """ Onchange of Fiscal Position update tax values in invoice lines. """ + for line in self.invoice_line_ids: + line._onchange_product_id() + + @api.multi + def action_move_create(self): + """ Do not apply taxes if company has been registered under + composition scheme. """ + for invoice in self: + if invoice.type in ('out_invoice', + 'out_refund') and \ + invoice.company_id.gst_type == 'composite': + for line in invoice.invoice_line_ids: + line.invoice_line_tax_ids = [(6, 0, [])] + line.invoice_id._onchange_invoice_line_ids() + return super(AccountInvoice, self).action_move_create() + + @api.multi + def invoice_validate(self): + """ Apply GST invoice type at the time of invoice validation. """ + for invoice in self: + partner_location = self.partner_id.partner_location + if invoice.partner_id.vat: + invoice.write({ + 'vat': invoice.partner_id.vat, + 'gst_type': invoice.partner_id.gst_type, + 'gst_invoice': 'b2b' + }) + elif invoice.type == 'out_invoice' and partner_location: + b2c_limit = self.env['res.company.b2c.limit'].search( + [('date_from', '<=', invoice.date_invoice), + ('date_to', '>=', invoice.date_invoice), + ('company_id', '=', invoice.company_id.id)]) + if not b2c_limit: + raise ValidationError(_('Please define B2C limit line in ' + 'company for current period!')) + if partner_location == 'inter_state' and \ + invoice.amount_total > b2c_limit.b2cl_limit: + invoice.write({'gst_invoice': 'b2cl'}) + if partner_location == 'intra_state' or partner_location == \ + 'inter_state' and invoice.amount_total < \ + b2c_limit.b2cs_limit: + invoice.write({'gst_invoice': 'b2cs'}) + elif invoice.type == 'in_invoice' and partner_location and \ + partner_location != 'inter_country': + invoice.write({'gst_invoice': 'b2bur'}) + + return super(AccountInvoice, self).invoice_validate() + + @api.model + def _prepare_refund(self, invoice, date_invoice=None, date=None, + description=None, journal_id=None): + """ Refund invoice creation, update value of GST Invoice from + base invoice. """ + result = super(AccountInvoice, self)._prepare_refund( + invoice, date_invoice=date_invoice, date=date, + description=description, journal_id=journal_id) + if result.get('refund_invoice_id'): + invoice = self.env['account.invoice'].browse( + result.get('refund_invoice_id')) + result.update({ + 'gst_invoice': invoice.gst_invoice, 'vat': invoice.vat, + 'gst_type': invoice.gst_type, + }) + return result diff --git a/addons/l10n_in_gst/models/note_issue_reason.py b/addons/l10n_in_gst/models/note_issue_reason.py new file mode 100644 index 00000000..c1c3de1a --- /dev/null +++ b/addons/l10n_in_gst/models/note_issue_reason.py @@ -0,0 +1,23 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +""" Introduce following new models for GST related customization: + * Note Issue Reasons +""" + +from flectra import api, fields, models + + +class NoteIssueReason(models.Model): + _name = 'note.issue.reason' + + name = fields.Char(string='Name', required=True) + code = fields.Char(string='Code', required=True) + + @api.multi + def name_get(self): + """ It will display field data in proper format as specified in this + method """ + result = [] + for record in self: + result.append((record.id, '%s-%s' % (record.code, record.name))) + return result diff --git a/addons/l10n_in_gst/models/product_uom.py b/addons/l10n_in_gst/models/product_uom.py new file mode 100644 index 00000000..e0874c3f --- /dev/null +++ b/addons/l10n_in_gst/models/product_uom.py @@ -0,0 +1,9 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra import fields, models + + +class ProductUomCode(models.Model): + _inherit = 'product.uom' + + code = fields.Char(string='Code') diff --git a/addons/l10n_in_gst/models/res_company.py b/addons/l10n_in_gst/models/res_company.py new file mode 100644 index 00000000..64888673 --- /dev/null +++ b/addons/l10n_in_gst/models/res_company.py @@ -0,0 +1,106 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +import time + +from flectra import api, fields, models, _ +from flectra.exceptions import ValidationError + + +class Company(models.Model): + _inherit = 'res.company' + + vat = fields.Char(string='GSTIN', related='partner_id.vat') + gst_type = fields.Selection([('regular', 'Regular'), + ('unregistered', 'Unregistered'), + ('composite', 'Composite'), + ('volunteer', 'Volunteer')], + string='GST Type', + related='partner_id.gst_type') + gst_introduce_date = fields.Date(string='GST Introduce Date', + default=time.strftime('2017-07-01')) + company_b2c_limit_line = fields.One2many('res.company.b2c.limit', + 'company_id', string='B2C Limit') + + def onchange_state(self, gst_type, vat, state): + result = {'vat': '', 'country_id': False} + if gst_type == 'unregistered' and vat: + result['vat'] = False + if gst_type != 'unregistered': + result['vat'] = state.l10n_in_tin + result['country_id'] = state.country_id and \ + state.country_id.id or False + return result + + @api.multi + @api.constrains('vat', 'state_id') + def _check_gstin_format(self): + """ Validations for GSTIN number format and length """ + for res in self: + if res.state_id and res.vat and res.state_id.l10n_in_tin != \ + res.vat[:2]: + raise ValidationError(_('Invalid State Code!')) + if res.vat and len(res.vat) != 15 and res.gst_type != \ + 'unregistered': + raise ValidationError(_('GSTIN length must be of 15 ' + 'characters!')) + + @api.onchange('state_id', 'country_id') + def _onchange_state_id(self): + """ Set state code as a initial characters of GSTIN """ + result = self.onchange_state(self.gst_type, self.vat, self.state_id) + self.vat = result['vat'] + self.country_id = result['country_id'] + + @api.onchange('gst_type') + def onchange_gst_type(self): + """ If gst type is unregistered then GSTIN Number should be blank""" + if self.gst_type == 'unregistered': + self.vat = False + + @api.model + def create(self, vals): + result = super(Company, self).create(vals) + result.partner_id.gst_company_partner = True + if vals.get('state_id', False): + result.partner_id.state_id = vals['state_id'] + if vals.get('country_id', False): + result.partner_id.country_id = vals['country_id'] + return result + + +class CompanyB2CLimit(models.Model): + _name = 'res.company.b2c.limit' + + date_from = fields.Date(string='From') + date_to = fields.Date(string='To') + b2cl_limit = fields.Float(string='B2CL Limit', default=250000.0, + help='Inter state minimum limit for B2CL type ' + 'transactions.') + b2cs_limit = fields.Float(string='B2CS Limit', default=250000.0, + help='Inter state maximum limit for B2CS type ' + 'transactions.') + company_id = fields.Many2one('res.company', string='Company') + + @api.constrains('date_to', 'date_from', 'company_id') + def _check_sheet_date(self): + for line in self: + self.env.cr.execute(''' + SELECT id + FROM res_company_b2c_limit + WHERE (date_from <= %s and %s <= date_to) + AND company_id=%s + AND id <> %s''', + (line.date_to, line.date_from, + line.company_id.id, line.id)) + if any(self.env.cr.fetchall()): + raise ValidationError(_( + 'You cannot have 2 limit lines of same period that ' + 'overlap for %s!') % (line.company_id and + line.company_id.name)) + + @api.constrains('date_from', 'date_to') + def _check_dates(self): + if any(self.filtered(lambda line: line.date_from and line. + date_to and line.date_from > line.date_to)): + raise ValidationError(_( + 'From date must be lower than to date.')) diff --git a/addons/l10n_in_gst/models/res_config_settings.py b/addons/l10n_in_gst/models/res_config_settings.py new file mode 100644 index 00000000..5b00fc10 --- /dev/null +++ b/addons/l10n_in_gst/models/res_config_settings.py @@ -0,0 +1,72 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra import api, fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + country_id = fields.Many2one('res.country', string='Country', + compute='_get_gst_details', + inverse='_set_gst_details') + state_id = fields.Many2one('res.country.state', string='State', + domain="[('country_id', '=', country_id)]", + compute='_get_gst_details', + inverse='_set_gst_details') + gstin_number = fields.Char(string='GSTIN', size=15, + compute='_get_gst_details', + inverse='_set_gst_details') + gst_type = fields.Selection([('regular', 'Regular'), + ('unregistered', 'Unregistered'), + ('composite', 'Composite'), + ('volunteer', 'Volunteer')], + string='GST Type', + compute='_get_gst_details', + inverse='_set_gst_details') + gst_applied = fields.Boolean(string='GST Applied') + + @api.multi + @api.depends('company_id', 'gst_applied') + def _get_gst_details(self): + """ Get GST configuration details from company """ + self.ensure_one() + self.country_id = self.company_id.country_id.id + self.state_id = self.company_id.state_id.id + self.gstin_number = self.company_id.vat + self.gst_type = self.company_id.gst_type + + @api.multi + def _set_gst_details(self): + """ Set GST configuration details in a company """ + self.ensure_one() + if self.gst_type: + partner = self.company_id.partner_id + partner.write({ + 'country_id': self.country_id.id, + 'state_id': self.state_id.id, + 'vat': self.gstin_number, + 'gst_company_partner': True, + }) + self.company_id.gst_type = self.gst_type + + @api.onchange('company_id') + def onchange_company_id(self): + self.gst_applied = False + if self.company_id and self.company_id.gst_type: + self.gst_applied = True + + @api.onchange('gstin_number', 'country_id') + def get_state(self): + """ Get state value automatically from GSTIN and country """ + if self.gstin_number and self.country_id: + state_code = self.gstin_number[:2] + state_id = self.env['res.country.state'].search([ + ('l10n_in_tin', '=', state_code), + ('country_id', '=', self.country_id.id)]) + self.state_id = state_id + + @api.onchange('gst_type') + def onchange_gst_type(self): + """ If gst type is unregistered then GSTIN Number should be blank""" + if self.gst_type == 'unregistered': + self.gstin_number = False diff --git a/addons/l10n_in_gst/models/res_partner.py b/addons/l10n_in_gst/models/res_partner.py new file mode 100644 index 00000000..e16af3e6 --- /dev/null +++ b/addons/l10n_in_gst/models/res_partner.py @@ -0,0 +1,72 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra import api, fields, models +from flectra.exceptions import ValidationError + + +class Partner(models.Model): + """ Inherit Partner """ + _inherit = 'res.partner' + + gst_company_partner = fields.Boolean(string='Is company partner?') + gst_type = fields.Selection([('regular', 'Regular'), + ('unregistered', 'Unregistered'), + ('composite', 'Composite'), + ('volunteer', 'Volunteer')], + string='GST Type') + e_commerce = fields.Boolean(string='E-Commerce') + partner_location = fields.Selection([('inter_state', 'Inter State'), + ('intra_state', 'intra State'), + ('inter_country', 'Inter Country') + ], "Partner Location") + + @api.multi + @api.constrains('vat', 'state_id') + def _check_gstin_format(self): + for res in self: + if res.state_id and res.vat and res.state_id.l10n_in_tin != \ + res.vat[:2]: + raise ValidationError(_('Invalid State Code!')) + if res.vat and len(res.vat) != 15 and res.gst_type != \ + 'unregistered': + raise ValidationError(_('GSTIN length must be of 15 ' + 'characters!')) + + def _get_partner_location_details(self, company): + partner_location = False + if self.country_id and company.country_id: + partner_location = 'inter_country' + if self.country_id.id == company.country_id.id: + partner_location = 'inter_state' + if self.state_id and company.state_id and self.state_id.id == \ + company.state_id.id: + partner_location = 'intra_state' + return partner_location + + @api.onchange('state_id', 'property_account_position_id', 'country_id') + def _onchange_state_id(self): + """ Set state code as a initial characters of GSTIN """ + result = self.company_id.onchange_state(self.gst_type, self.vat, + self.state_id) + self.vat = result['vat'] + self.country_id = result['country_id'] + self.partner_location = self._get_partner_location_details( + self.company_id) + if self.state_id == self.env.user.company_id.state_id and \ + self.property_account_position_id: + self.property_account_position_id = False + return { + 'warning': { + 'title': 'Warning', + 'message': 'Fiscal Position not needed for ' + 'same state Customers!' + } + } + + @api.onchange('gst_type') + def onchange_gst_type(self): + """ + If gst type is unregistered then GSTIN Number should be blank + """ + if self.gst_type == 'unregistered': + self.vat = False diff --git a/addons/l10n_in_gst/report/__init__.py b/addons/l10n_in_gst/report/__init__.py new file mode 100644 index 00000000..de05287b --- /dev/null +++ b/addons/l10n_in_gst/report/__init__.py @@ -0,0 +1,3 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import gst_report diff --git a/addons/l10n_in_gst/report/gst_report.py b/addons/l10n_in_gst/report/gst_report.py new file mode 100644 index 00000000..75e14079 --- /dev/null +++ b/addons/l10n_in_gst/report/gst_report.py @@ -0,0 +1,1423 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from io import BytesIO +from datetime import datetime + +import xlsxwriter +from flectra import api, models, _ + + +class GSTR1Report(models.AbstractModel): + _name = "gst.report" + + def open_document(self, options, **post): + action_model = options.get('object') + invoice = self.env['account.invoice'].browse(int(options.get('id'))) + view_name = 'view_move_form' + if action_model == 'account.invoice' and invoice: + if invoice.type in ('in_refund', 'in_invoice'): + view_name = 'invoice_supplier_form' + elif invoice.type in ('out_refund', 'out_invoice'): + view_name = 'invoice_form' + view_id = self.env['ir.model.data'].get_object_reference( + 'account', view_name)[1] + return { + 'type': 'ir.actions.act_window', + 'view_type': 'tree', + 'view_mode': 'form', + 'views': [(view_id, 'form')], + 'res_model': action_model, + 'view_id': view_id, + 'res_id': invoice.id, + } + + def _prepare_taxable_line_data(self, line, inv, igst_amount, cgst_amount, + sgst_amount, cess_amount, rate, tax): + return { + 'id': inv.id, + 'taxable_value': line.price_subtotal, + 'cess_amount': cess_amount, + 'rate': rate, + 'place_supply': ('%s-%s') % ( + inv.partner_id.state_id.l10n_in_tin, + inv.partner_id.state_id.name), + 'tax_id': tax.id, + 'igst': igst_amount, + 'cgst': cgst_amount, + 'sgst': sgst_amount, + 'lines': [{ + 'igst_amount': igst_amount, + 'sgst_amount': sgst_amount, + 'cgst_amount': cgst_amount, + 'product_name': line.product_id.name, + 'quantity': line.quantity, + 'price_unit': line.price_unit, + 'amount': line.price_subtotal, + 'cess': cess_amount + }] + } + + def _update_tax_values(self, data, line, cess_amount, igst_amount, + cgst_amount, sgst_amount): + if data and line: + data['taxable_value'] += line.price_subtotal + data['cess_amount'] += cess_amount + data['igst'] += igst_amount + data['cgst'] += cgst_amount + data['sgst'] += sgst_amount + data['lines'].append({ + 'igst_amount': igst_amount, + 'sgst_amount': sgst_amount, + 'cgst_amount': cgst_amount, + 'product_name': line.product_id.name, + 'quantity': line.quantity, + 'price_unit': line.price_unit, + 'amount': line.price_subtotal, + 'cess': cess_amount + }) + + def _update_inv_line_details(self, line, inv, document_type): + line.update({ + 'inv_no': inv.number, + 'refund_invoice_id': inv.refund_invoice_id.id, + 'refund_inv_no': inv.refund_invoice_id.number, + 'refund_date_invoice': datetime.strptime( + inv.refund_invoice_id.date_invoice, '%Y-%m-%d').strftime( + '%d %b %y'), 'document_type': document_type, + 'reason': inv.name or '', + 'pre_gst': inv.date <= inv.company_id.gst_introduce_date and + 'Y' or 'N', + 'inv_date': datetime.strptime( + inv.date_invoice, '%Y-%m-%d').strftime('%d %b %y'), + }) + + def get_data_common(self, data, start=None, end=None, **post): + """ + Common Method for get_data_*(...) + 1. get_data_b2b(...), 2. get_data_b2cl(...), 3. get_data_b2cs(...), + 4. get_data_cdnr(...), 5. get_data_cdnur(...) + """ + result = [] + acc_invoice = self.env['account.invoice'] + acc_tax = self.env['account.tax'] + common_domain = [('date', '>=', data['from_date']), + ('date', '<=', data['to_date']), + ('state', 'not in', ['draft', 'cancel']), + ('company_id', '=', data['company_id'])] + final_invoice_ids = type_domain = refund_domain = final_inv_domain = [] + if data['summary_type'] == 'gstr1': + type_domain = [('type', '=', 'out_invoice')] + refund_domain = [('type', '=', 'out_refund')] + cdnur_domain = [('gst_invoice', 'in', ['b2cl', 'b2cs']), + ('vat', '=', False)] + elif data['summary_type'] == 'gstr2': + type_domain = [('type', '=', 'in_invoice')] + refund_domain = [('type', '=', 'in_refund')] + cdnur_domain = [('gst_invoice', '=', 'b2bur'), + ('vat', '=', False)] + if post.get('gst_invoice') == 'b2b': + final_inv_domain = common_domain + type_domain + [( + 'gst_invoice', '=', 'b2b')] + if post.get('gst_invoice') == 'b2bur': + final_inv_domain = common_domain + type_domain + [ + ('gst_invoice', '=', 'b2bur')] + if post.get('gst_invoice') == 'b2cl': + final_inv_domain = common_domain + type_domain + [( + 'gst_invoice', '=', 'b2cl')] + if post.get('gst_invoice') == 'b2cs': + final_inv_domain = common_domain + type_domain + [ + ('gst_invoice', '=', 'b2cs')] + if post.get('gst_invoice') == 'cdnr': + final_inv_domain = common_domain + refund_domain + [ + ('gst_invoice', '=', 'b2b'), ('vat', '!=', False)] + if post.get('gst_invoice') == 'cdnur': + final_inv_domain = common_domain + refund_domain + cdnur_domain + + final_invoice_ids = acc_invoice.search(final_inv_domain) + for inv in final_invoice_ids: + inv_data_list = [] + tax_list = [] + document_type = None + gst_invoice_type = None + + if post.get('gst_invoice') in ['cdnr', 'cdnur']: + if inv.type == 'out_refund' and inv.amount_total < \ + inv.refund_invoice_id.amount_total: + document_type = 'C' + elif inv.type == 'in_refund' and inv.amount_total < \ + inv.refund_invoice_id.amount_total: + document_type = 'D' + else: + document_type = 'R' + if post.get('gst_invoice') == 'cdnur': + gst_invoice_type = dict(inv.fields_get( + ['gst_invoice'])['gst_invoice']['selection']).get( + inv.gst_invoice) + + for line in inv.invoice_line_ids: + cess_amount = igst_amount = cgst_amount = sgst_amount = 0.0 + + if line.invoice_line_tax_ids: + price_unit = line.price_unit * ( + 1 - (line.discount or 0.0) / 100.0) + taxes = line.invoice_line_tax_ids.compute_all( + price_unit, line.invoice_id.currency_id, + line.quantity, line.product_id, + line.invoice_id.partner_id)['taxes'] + + for tax_data in taxes: + tax = acc_tax.browse(tax_data['id']) + if tax.tax_group_id.name == 'Cess': + cess_amount += tax_data['amount'] + if tax.tax_group_id.name == 'IGST' and (post.get( + 'gst_invoice') != 'b2b' or + tax_data['amount'] > 0): + igst_amount += tax_data['amount'] + if tax.tax_group_id.name == 'CGST' and (post.get( + 'gst_invoice') != 'b2b' or tax_data[ + 'amount'] > 0): + cgst_amount += tax_data['amount'] + if tax.tax_group_id.name == 'SGST' and (post.get( + 'gst_invoice') != 'b2b' or tax_data[ + 'amount'] > 0): + sgst_amount += tax_data['amount'] + + for tax in line.invoice_line_tax_ids: + rate = 0 + if tax.id not in tax_list: + if tax.tax_group_id.name == 'IGST' \ + and tax.amount > 0: + rate = tax.amount + else: + for child in tax.children_tax_ids: + if child.tax_group_id.name == 'IGST' \ + and child.amount > 0: + rate = child.amount + elif child.tax_group_id.name in ['SGST', + 'CGST'] \ + and child.amount > 0: + rate += child.amount + if post.get('gst_invoice') == 'cdnur': + if tax.tax_group_id.name == 'IGST': + rate = tax.amount + else: + for child in tax.children_tax_ids: + if child.tax_group_id.name == 'CGST': + rate += child.amount + if child.tax_group_id.name == 'SGST': + rate += child.amount + if tax.tax_group_id.name != 'Cess': + line_data = self._prepare_taxable_line_data( + line, inv, igst_amount, cgst_amount, + sgst_amount, cess_amount, rate, tax) + + if post.get('gst_invoice') in \ + ['b2b', 'b2cl', 'b2cs', 'b2bur']: + line_data.update({ + 'partner': inv.company_id.name, + 'ecommerce_gstin': + inv.e_commerce_partner_id and + inv.e_commerce_partner_id.vat or + '', + }) + + line_data.update({ + 'gstin_partner': inv.vat, + 'value': inv.amount_total, + }) + + if post.get('gst_invoice') in \ + ['b2b', 'b2cl', 'b2bur']: + line_data.update({ + 'inv_no': inv.number, + 'date': datetime.strptime( + inv.date_invoice, + '%Y-%m-%d').strftime('%d %b %y'), + }) + + if post.get('gst_invoice') == 'b2b': + line_data.update({ + 'inv_type': 'Regular', + 'reverse_charge': 'N', + }) + if post.get('gst_invoice') == 'b2bur': + supply_type = dict(inv.fields_get( + ['partner_location'])[ + 'partner_location']['selection']).get( + inv.partner_location) + line_data.update({ + 'supplier': inv.partner_id.name, + 'supply_type': supply_type if + inv.partner_location != + 'inter_country' else 0.0, + }) + if post.get('gst_invoice') == 'b2cs': + line_data.update({ + 'inv_no': inv.number, + 'type': + inv.e_commerce_partner_id and + 'E' or 'OE', + }) + + if post.get('gst_invoice') in ['cdnr', + 'cdnur']: + self._update_inv_line_details( + line_data, inv, document_type) + + if post.get('gst_invoice') == 'cdnur': + line_data.update({ + 'gst_invoice_type': gst_invoice_type, + }) + + tax_list.append(tax.id) + inv_data_list.append(line_data) + result.append(line_data) + elif tax.id in tax_list: + for data in inv_data_list: + if data['tax_id'] == tax.id: + self._update_tax_values( + data, line, cess_amount, + igst_amount, cgst_amount, + sgst_amount) + # pagination records display + if start and end: + return { + 'data': result[start - 1: end], + 'length': len(result) + } + else: + return result + + @api.multi + def get_data_b2b(self, data, start=None, end=None, **post): + """ B2B data as per month, year and company selection: + - Registered customer invoices details (without reverse charge + applicability) + - Registered supplier invoices details (with reverse charge + applicability) + """ + post['gst_invoice'] = 'b2b' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_b2bur(self, data, start=None, end=None, **post): + """ B2BUR data as per month, year and company selection: + - Unegistered supplier invoices details (with reverse charge + applicability) + """ + post['gst_invoice'] = 'b2bur' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_b2cl(self, data, start=None, end=None, **post): + """ B2CL data as per month, year and company selection: + - Unregistered customers' invoices details where: + (1) The place of supply is outside the state where company is + registered + (2) Total invoice value is more than company's B2CL limit + """ + post['gst_invoice'] = 'b2cl' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_b2cs(self, data, start=None, end=None, **post): + """ B2CS data as per month, year and company selection: + - Unregistered customers' invoices details where: + (1) Intra-State: any value + (2) Inter-State: Total invoice value is less than company's B2CS + limit + """ + post['gst_invoice'] = 'b2cs' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_cdnr(self, data, start=None, end=None, **post): + """ CDNR data as per month, year and company selection: + - Refunds of B2B type invoices + """ + post['gst_invoice'] = 'cdnr' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_cdnur(self, data, start=None, end=None, **post): + """ CDNUR data as per month, year and company selection: + - Refunds of Export and B2CL type invoices + """ + post['gst_invoice'] = 'cdnur' + post['summary_type'] = data['summary_type'] + return self.get_data_common(data=data, start=start, end=end, **post) + + @api.multi + def get_data_hsn(self, data, start=None, end=None, **post): + """ HSN data as per month, year and company selection. + """ + result = [] + list_product = [] + acc_tax = self.env['account.tax'] + hsn_invoice_line_ids = self.env['account.invoice.line'].search([ + ('invoice_id.date', '>=', data['from_date']), + ('invoice_id.date', '<=', data['to_date']), + ('invoice_id.state', 'not in', ['draft', 'cancel']), + ('invoice_id.company_id', '=', data['company_id']), + ('invoice_id.type', '=', 'out_invoice'), + ('invoice_id.gst_invoice', 'in', ('b2b', 'b2cl', 'b2cs'))]) + for line in hsn_invoice_line_ids: + igst_amount = cgst_amount = sgst_amount = cess_amount = 0.0 + if line.invoice_line_tax_ids: + price_unit = line.price_unit * ( + 1 - (line.discount or 0.0) / 100.0) + taxes = line.invoice_line_tax_ids.compute_all( + price_unit, line.invoice_id.currency_id, + line.quantity, line.product_id, + line.invoice_id.partner_id)['taxes'] + for tax in taxes: + tax_id = acc_tax.browse(tax['id']) + if tax_id.tax_group_id.name == 'Cess': + cess_amount += tax['amount'] + elif tax_id.tax_group_id.name == 'IGST': + igst_amount += tax['amount'] + elif tax_id.tax_group_id.name == 'CGST': + cgst_amount += tax['amount'] + elif tax_id.tax_group_id.name == 'SGST': + sgst_amount += tax['amount'] + if line.product_id.id not in list_product: + hsn_data = { + 'product_name': line.product_id.product_tmpl_id.name, + 'hsn': line.product_id.l10n_in_hsn_code, + 'value': (line.price_subtotal + igst_amount + + cgst_amount + sgst_amount + cess_amount), + 'taxable_value': line.price_subtotal, + 'cess_amount': cess_amount, + 'igst_amt': igst_amount, + 'cgst_amt': cgst_amount, + 'sgst_amt': sgst_amount, + 'uqc': ("%s-%s") % (line.product_id.uom_id.code, + line.product_id.uom_id.name), + 'product_main_id': line.product_id.id, + 'total_qty': line.quantity} + list_product.append(line.product_id.id) + result.append(hsn_data) + elif line.product_id.id in list_product: + for l in result: + if l['product_main_id'] == line.product_id.id: + l['value'] += line.price_subtotal + igst_amount + \ + cgst_amount + sgst_amount + cess_amount + l['taxable_value'] += line.price_subtotal + l['cess_amount'] += cess_amount + l['igst_amt'] += igst_amount + l['cgst_amt'] += cgst_amount + l['sgst_amt'] += sgst_amount + l['total_qty'] += line.quantity + # pagination records display + if start and end: + return { + 'data': result[start - 1: end], + 'length': len(result) + } + else: + return result + + def get_data_common_summary(self, result, **post): + """ + Common Method for get_data_*_summary(...) + 1. get_data_b2b_summary(...), 2. get_data_b2cl_summary(...), + 3. get_data_b2cs_summary(...), 4. get_data_cdnr_summary(...), + 5. get_data_cdnur_summary(...), + """ + summary = {} + if result: + invoices_list = [] + recepient_list = [] + taxable_value_total = cess_amt_total = igst_amount = cgst_amount =\ + sgst_amount = 0.0 + no_of_recepient = 0 + + for inv in result: + taxable_value_total += float(inv['taxable_value']) + igst_amount += float(inv['igst']) + sgst_amount += float(inv['sgst']) + cgst_amount += float(inv['cgst']) + + if post.get('gst_invoice') == 'b2b': + if inv['reverse_charge'] == 'N': + cess_amt_total += inv['cess_amount'] + recepient_list.append(inv['gstin_partner']) + if post.get('gst_invoice') in ['b2cl', 'b2cs']: + cess_amt_total += inv['cess_amount'] + if post.get('gst_invoice') in ['cdnr', 'cdnur']: + if inv['document_type'] == 'C': + cess_amt_total -= inv['cess_amount'] + else: + cess_amt_total += inv['cess_amount'] + recepient_list.append(inv['gstin_partner']) + invoices_list.append(inv['inv_no']) + + if post.get('gst_invoice') in ['b2b', 'cdnr', 'cdnur']: + no_of_recepient = len(set(recepient_list)) + + no_of_invoices = len(set(invoices_list)) + invoices_list = set(invoices_list) + invoice_value = 0.0 + for invoice_id in invoices_list: + ids = self.env['account.invoice'].search( + [('number', '=', invoice_id)]) + invoice_value += ids.amount_total + summary.update({ + "no_of_invoices": no_of_invoices, + "taxable_value_total": taxable_value_total, + "cess_amt_total": cess_amt_total, + "invoice_value": invoice_value, + "igst_amount": igst_amount, + "sgst_amount": sgst_amount, + "cgst_amount": cgst_amount, + }) + if post.get('gst_invoice') == 'b2b': + if post.get('summary_type') == 'gstr1': + name = _("B2B Invoices - 4A, 4B, 4C, 6B, 6C") + elif post.get('summary_type') == 'gstr2': + name = _("Supplies From Registered Suppliers B2B - 3,4A") + summary.update({ + "name": name, + "action": "get_data_b2b", + "no_of_recepient": no_of_recepient, + }) + if post.get('gst_invoice') == 'b2bur': + summary.update({ + "name": _("Supplies From Unregistered Suppliers B2BUR - " + "4C"), + "action": "get_data_b2bur", + }) + if post.get('gst_invoice') == 'b2cl': + summary.update({ + "name": _("B2C(Large) Invoices - 5A, 5B"), + "action": "get_data_b2cl", + }) + if post.get('gst_invoice') == 'b2cs': + summary.update({ + "name": _("B2C(Small) Details - 7"), + "action": "get_data_b2cs", + }) + if post.get('gst_invoice') == 'cdnr': + if post.get('summary_type') == 'gstr1': + name = _("Credit/Debit Notes(Registered) - 9B") + elif post.get('summary_type') == 'gstr2': + name = _("Debit/Credit Notes(Registered) - 6C") + summary.update({ + "name": name, + "action": "get_data_cdnr", + "no_of_recepient": no_of_recepient, + }) + if post.get('gst_invoice') == 'cdnur': + if post.get('summary_type') == 'gstr1': + name = _("Credit/Debit Notes(Unregistered) - 9B") + elif post.get('summary_type') == 'gstr2': + name = _("Debit/Credit Notes(Unregistered) - 6C") + summary.update({ + "name": name, + "action": "get_data_cdnur", + "no_of_recepient": no_of_recepient, + }) + return summary + + def get_data_b2b_summary(self, data, **post): + """ B2B summary details and fetch required data """ + post['gst_invoice'] = 'b2b' + post['summary_type'] = data['summary_type'] + result = self.get_data_b2b(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_b2bur_summary(self, data, **post): + post['gst_invoice'] = 'b2bur' + post['summary_type'] = data['summary_type'] + result = self.get_data_b2bur(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_b2cl_summary(self, data, **post): + """ B2CL summary details and fetch required data """ + post['gst_invoice'] = 'b2cl' + post['summary_type'] = data['summary_type'] + result = self.get_data_b2cl(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_b2cs_summary(self, data, **post): + """ B2CS summary details and fetch required data """ + post['gst_invoice'] = 'b2cs' + post['summary_type'] = data['summary_type'] + result = self.get_data_b2cs(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_cdnr_summary(self, data, **post): + """ CDNR summary details and fetch required data """ + post['gst_invoice'] = 'cdnr' + post['summary_type'] = data['summary_type'] + result = self.get_data_cdnr(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_cdnur_summary(self, data, **post): + """ CDNUR summary details and fetch required data """ + post['gst_invoice'] = 'cdnur' + post['summary_type'] = data['summary_type'] + result = self.get_data_cdnur(data=data, **post) + return self.get_data_common_summary(result=result, **post) + + def get_data_hsn_summary(self, data, **post): + """ HSN summary details and fetch required data """ + result = self.get_data_hsn(data, **post) + summary = {} + value_total = 0.0 + no_of_hsn = 0 + taxable_value_total = value_total = 0.0 + cess_amt_total = cgst_total = igst_total = sgst_total = 0.0 + for inv in result: + value_total += inv['value'] + sgst_total += inv['sgst_amt'] + cgst_total += inv['cgst_amt'] + igst_total += inv['igst_amt'] + if inv['hsn']: + no_of_hsn += 1 + taxable_value_total += inv['taxable_value'] + cess_amt_total += inv['cess_amount'] + summary = { + "name": _("HSN-Wise Summary of outward Supplies - 12"), + "no_of_invoices": "", + "no_of_hsn": no_of_hsn, + "taxable_value_total": taxable_value_total, + "cess_amt_total": cess_amt_total, + "action": "get_data_hsn", + "value_total": value_total, + "sgst_amount": sgst_total, + "cgst_amount": cgst_total, + "igst_amount": igst_total + } + return summary + + def get_gstr_summary(self, data, flag=None, **post): + """ GSTR1 Summary """ + summary = { + 'summary': [], + 'companies': {}, + 'summary_type': data.get("summary_type") and data[ + 'summary_type'] or '', + } + b2b_summary = self.get_data_b2b_summary(data=data, **post) + b2bur_summary = self.get_data_b2bur_summary(data=data, **post) + b2cl_summary = self.get_data_b2cl_summary(data=data, **post) + b2cs_summary = self.get_data_b2cs_summary(data=data, **post) + cdnr_summary = self.get_data_cdnr_summary(data=data, **post) + cdnur_summary = self.get_data_cdnur_summary(data=data, **post) + hsn_summary = self.get_data_hsn_summary(data=data, **post) + if b2b_summary: + summary['summary'].append(b2b_summary) + if b2bur_summary and data.get("summary_type") == "gstr2": + summary['summary'].append(b2bur_summary) + if b2cl_summary: + summary['summary'].append(b2cl_summary) + if b2cs_summary: + summary['summary'].append(b2cs_summary) + if cdnr_summary: + summary['summary'].append(cdnr_summary) + if cdnur_summary: + summary['summary'].append(cdnur_summary) + if hsn_summary: + summary['summary'].append(hsn_summary) + res_company = self.env['res.company'].search( + [('gst_type', 'in', ['regular', 'volunteer'])]) + if res_company: + for company in res_company: + summary['companies'].update({ + company.id: company.name, + }) + if flag: + return summary + else: + return summary['summary'] + + def cell_format(self, workbook, **post): + """ Define cell formats """ + return { + 'header_cell_format': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'locked': True, 'align': 'center', 'text_wrap': True, + 'bg_color': '#e5b7a2', 'bottom': 1}), + 'header_cell_format_help': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'locked': True, 'align': 'center', 'text_wrap': True, + 'font_color': '#ff0000', 'bottom': 1, 'underline': True}), + 'borederd_header_cell_format': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'align': 'center', 'text_wrap': True, 'top': 1, + 'bottom': 1, 'left': 1, 'right': 1, 'bold': True, + 'bg_color': '#2a6cb7', 'font_color': '#ffffff'}), + 'regular_cell_format': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'text_wrap': True}), + 'regular_cell_format_center': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'text_wrap': True}), + 'regular_cell_format_right': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'text_wrap': True, 'align': 'right'}), + 'borederd_header_cell_format_count': workbook.add_format({ + 'font_name': 'Times New Roman', 'font_size': 11, + 'text_wrap': True, 'align': 'right' + }), + 'borederd_header_cell_format_right': workbook.add_format({ + 'font_name': 'Times New Roman', 'font_size': 11, + 'align': 'right', 'text_wrap': True, 'top': 1, 'bottom': 1, + 'left': 1, 'right': 1, 'bold': True + }).set_num_format('0.00'), + 'regular_cell_format_date': workbook.add_format( + {'font_name': 'Times New Roman', 'font_size': 11, + 'text_wrap': True, 'num_format': 'dd-mmm-yy', + 'align': 'center'})} + + def set_summary_header(self, worksheet, summary_label, total_cols, row, + col, cell_format): + for col_no in range(0, total_cols): + if col_no == 0: + worksheet.write(row, col, summary_label, + cell_format['borederd_header_cell_format']) + elif col_no == (total_cols - 1): + worksheet.write(row, col + col_no, 'HELP', + cell_format['header_cell_format_help']) + else: + worksheet.write(row, col + col_no, '', + cell_format['regular_cell_format']) + + def write_data_worksheet_header(self, worksheet, header_list, cell_format, + row, col): + """ + Common method to write data into all the worksheets. + :param worksheet: selected worksheet object + :param header_list: list of all the values or headers to be added + :param cell_format: cell format of the perticular cell + :param row: row number + :param col: column number + :param summary: dictionary in case summary value and invoice value + :return: + """ + count = 0 + for header in header_list: + worksheet.write(row, col + count, header, cell_format) + count += 1 + + def write_data_worksheet_values(self, worksheet, values, row, col): + + count = 0 + for values_dict in values: + worksheet.write(row, col + count, values_dict['value'], + values_dict['format']) + count += 1 + + def sheet_b2b(self, data, workbook, **post): + """ Generate excel sheet for 'b2b' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('b2b') + workbook.add_format({'locked': 1}) + worksheet.protect() + worksheet.set_column(0, 20, 20) + inv_ids_b2b = self.get_data_b2b(data=data, **post) + + # Calculation of header + summary = self.get_data_b2b_summary(data=data, **post) + + # formatting + row = 0 + # summary header + self.set_summary_header(worksheet, 'Summary For B2B(4)', 11, + 0, 0, cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = ["No. of Recipients", "No. of Invoices", " ", + "Total Invoice Value", " ", " ", " ", " ", " ", + "Total Taxable Value", "Total Cess"] + self.write_data_worksheet_header(worksheet, header_list, + cell_format[ + 'borederd_header_cell_format'], + row, col) + row += 1 + + col = 0 + if summary: + summary_value = [{ + 'value': summary['no_of_recepient'], + 'format': cell_format['borederd_header_cell_format_count']}, { + 'value': summary['no_of_invoices'], + 'format': cell_format['borederd_header_cell_format_count']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': summary['invoice_value'], + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': " ", + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + row += 1 + + worksheet.set_row(3, 15) + row = 3 + col = 0 + # set main invoice header + invoice_header = ["GSTIN/UIN of Recipient", "Invoice Number", + "Invoice date", "Invoice Value", "Place Of Supply", + "Reverse Charge", "Invoice Type", "E-Commerce GSTIN", + "Rate", "Taxable Value", "Cess Amount"] + self.write_data_worksheet_header( + worksheet, invoice_header, cell_format[ + 'header_cell_format'], row, col) + row += 1 + col = 0 + for inv in inv_ids_b2b: + inv_value = [{ + 'value': inv['gstin_partner'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['date'], '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['place_supply'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['reverse_charge'], + 'format': cell_format['regular_cell_format_center']}, + {'value': inv['inv_type'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['ecommerce_gstin'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['rate'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 else + '', + 'format': cell_format['regular_cell_format_right']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_b2cl(self, data, workbook, **post): + """ Generate excel sheet for 'b2cl' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('b2cl') + workbook.add_format({'locked': 1}) + worksheet.set_column(0, 20, 20) + worksheet.protect() + inv_ids_b2cl = self.get_data_b2cl(data=data, **post) + # Calculation of header + summary = self.get_data_b2cl_summary(data=data, **post) + row = 0 + # summary header + self.set_summary_header(worksheet, 'Summary For B2CL(5)', 8, 0, 0, + cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = ["No. of Invoices", " ", "Total Invoice Value", " ", + " ", "Total Taxable Value", "Total Cess", " "] + self.write_data_worksheet_header( + worksheet, header_list, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + col = 0 + if summary: + summary_value = [{ + 'value': summary['no_of_invoices'], + 'format': cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['invoice_value'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + row += 1 + worksheet.set_row(3, 15) + row = 3 + col = 0 + # set main invoice header + invoice_header = ["Invoice Number", "Invoice date", "Invoice Value", + "Place Of Supply", "Rate", "Taxable Value", + "Cess Amount", "E-Commerce GSTIN"] + self.write_data_worksheet_header( + worksheet, invoice_header, cell_format[ + 'header_cell_format'], row, col) + row += 1 + for inv in inv_ids_b2cl: + inv_value = [{ + 'value': inv['inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['date'], '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['place_supply'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['rate'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 + else 0.0, + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['ecommerce_gstin'], + 'format': cell_format['regular_cell_format']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_b2cs(self, data, workbook, **post): + """ Generate excel sheet for 'b2cs' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('b2cs') + workbook.add_format({'locked': 1}) + worksheet.set_column(0, 20, 20) + worksheet.protect() + inv_ids_b2cs = self.get_data_b2cs(data=data, **post) + # Calculation of header + summary = self.get_data_b2cs_summary(data=data, **post) + row = 0 + # summary header + self.set_summary_header(worksheet, 'Summary For B2CS(7)', 6, 0, 0, + cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = [" ", " ", " ", "Total Taxable Value", "Total Cess", " "] + self.write_data_worksheet_header( + worksheet, header_list, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + col = 0 + if summary: + summary_value = ['', '', '', summary['taxable_value_total'], + summary['cess_amt_total'], ''] + self.write_data_worksheet_header( + worksheet, summary_value, + cell_format['borederd_header_cell_format_right'], + row, col) + + row += 1 + worksheet.set_row(3, 15) + row = 3 + col = 0 + # set main invoice header + invoice_header = ["Type", "Place Of Supply", "Rate", "Taxable Value", + "Cess Amount", "E-Commerce GSTIN"] + self.write_data_worksheet_header( + worksheet, invoice_header, cell_format[ + 'header_cell_format'], row, col) + row += 1 + for inv in inv_ids_b2cs: + inv_value = [{ + 'value': inv['type'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['place_supply'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['rate'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 + else 0.0, + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['ecommerce_gstin'], + 'format': cell_format['regular_cell_format']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_b2bur(self, data, workbook, **post): + """ Generate excel sheet for 'b2cl' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('b2bur') + workbook.add_format({'locked': 1}) + worksheet.set_row(0, 30) + worksheet.set_column(0, 0, 25) + worksheet.set_column(1, 20, 20) + worksheet.protect() + inv_ids_b2bur = self.get_data_b2bur(data=data, **post) + + # Calculation of header + summary = self.get_data_b2bur_summary(data=data, **post) + + # formatting + row = 0 + # summary header + self.set_summary_header(worksheet, + 'Summary of Supplies From Unregistered ' + 'Suppliers B2BUR(4B)', 12, 0, 0, cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = [" ", "No. of Invoices", " ", "Total Invoice Value", + " ", " ", " ", "Total Taxable Value", + "Total Integrated Tax", "Total Central Tax", + "Total State/UT Tax", "Total Cess"] + self.write_data_worksheet_header(worksheet, header_list, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + col = 0 + if summary: + summary_value = [{ + 'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': summary['no_of_invoices'], + 'format': cell_format['borederd_header_cell_format_count'] + }, { + 'value': '', + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': summary['invoice_value'], + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, { + 'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': summary['igst_amount'], + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': summary['cgst_amount'], + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': summary['sgst_amount'], + 'format': cell_format['borederd_header_cell_format_right'] + }, { + 'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + row += 1 + + worksheet.set_row(3, 15) + row = 3 + col = 0 + # set main invoice header + invoice_header = ['Supplier Name', 'Invoice Number', 'Invoice Date', + 'Invoice Value', 'Place Of Supply', 'Supply Type', + 'Rate', 'Taxable Value', 'Integrated Tax Amount', + 'Central Tax Amount', 'State/UT Tax Amount', + 'Cess Amount'] + self.write_data_worksheet_header(worksheet, invoice_header, + cell_format['header_cell_format'], + row, col) + row += 1 + + for inv in inv_ids_b2bur: + inv_value = [{ + 'value': inv['supplier'], + 'format': cell_format['regular_cell_format'] + }, { + 'value': inv['inv_no'], + 'format': cell_format['regular_cell_format'] + }, { + 'value': datetime.strptime(inv['date'], '%d %b %y'), + 'format': cell_format['regular_cell_format_date'] + }, { + 'value': inv['value'], + 'format': cell_format['regular_cell_format_right'] + }, { + 'value': inv['place_supply'], + 'format': cell_format['regular_cell_format'] + }, { + 'value': inv['supply_type'], + 'format': cell_format['regular_cell_format'] + }, { + 'value': inv['rate'], + 'format': cell_format['regular_cell_format_right'] + }, { + 'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right'] + }, { + 'value': inv['igst'] if inv['igst'] > 0.0 else 0.0, + 'format': cell_format['regular_cell_format_right']}, { + 'value': inv['cgst'] if inv['cgst'] > 0.0 else 0.0, + 'format': cell_format['regular_cell_format_right']}, { + 'value': inv['sgst'] if inv['sgst'] > 0.0 else 0.0, + 'format': cell_format['regular_cell_format_right']}, { + 'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 else + '', + 'format': cell_format['regular_cell_format_right']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_cdnr(self, data, workbook, **post): + """ Generate excel sheet for 'cdnr' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('cdnr') + workbook.add_format({'locked': 1}) + worksheet.set_column(0, 20, 25) + worksheet.protect() + inv_ids_cdnr = self.get_data_cdnr(data=data, **post) + row = 0 + # Calculation of header + summary = self.get_data_cdnr_summary(data=data, **post) + # summary header + self.set_summary_header(worksheet, 'Summary For CDNR(9B)', 13, 0, 0, + cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = ["No. of Recipients", "No. of Invoices", " ", + 'No. of Notes/Vouchers', " ", " ", " ", " ", " ", "", + "Total Taxable Value", "Total Cess", " "] + self.write_data_worksheet_header( + worksheet, header_list, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + col = 0 + if summary: + summary_value = [{ + 'value': summary['no_of_recepient'], + 'format': cell_format['borederd_header_cell_format_count']}, + {'value': summary['no_of_invoices'], + 'format':cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['no_of_invoices'], + 'format': cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['invoice_value'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + row += 1 + col = 0 + # set main invoice header + invoice_header = ["GSTIN/UIN of Recipient", + 'Invoice/Advance Receipt Number', + 'Invoice/Advance Receipt date', + 'Note/Refund Voucher date', + 'Note/Refund Voucher Number', 'Document Type', + 'Reason For Issuing document', "Place Of Supply", + 'Note/Refund Voucher Value', + "Rate", "Taxable Value", "Cess Amount", 'Pre GST'] + self.write_data_worksheet_header( + worksheet, invoice_header, cell_format[ + 'header_cell_format'], row, col) + row += 1 + col = 0 + for inv in inv_ids_cdnr: + inv_value = [{ + 'value': inv['gstin_partner'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['refund_inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['refund_date_invoice'], + '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['inv_date'], '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['document_type'], + 'format': cell_format['regular_cell_format_center']}, + {'value': inv['reason'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['place_supply'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['rate'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 else + '', + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['pre_gst'], + 'format': cell_format['regular_cell_format_center']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_cdnur(self, data, workbook, **post): + """ Generate excel sheet for 'cdnur' data """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('cdnur') + workbook.add_format({'locked': 1}) + worksheet.set_column(0, 20, 25) + worksheet.protect() + inv_ids_cdnur = self.get_data_cdnur(data=data, **post) + + # Calculation of header + summary = self.get_data_cdnr_summary(data=data, **post) + + # formatting + row = 0 + # summary header + self.set_summary_header(worksheet, 'Summary For CDNUR(9B)', 13, 0, 0, + cell_format) + row += 1 + col = 0 + # set summary sub header + header_list = ['', 'No. of Notes/Vouchers', '', '', 'No. of Invoices', + '', '', '', 'Total Note Value', '', + "Total Taxable Value", "Total Cess", ''] + self.write_data_worksheet_header( + worksheet, header_list, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + col = 0 + if summary: + summary_value = [{ + 'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['no_of_invoices'], + 'format':cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['no_of_invoices'], + 'format': cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['invoice_value'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + row = 3 + col = 0 + # set main invoice header + invoice_header = ['UR Type', 'Note/Refund Voucher Number', + 'Note/Refund Voucher date', 'Document Type', + 'Invoice/Advance Receipt Number', + 'Invoice/Advance Receipt date', + 'Reason For Issuing document', "Place Of Supply", + 'Note/Refund Voucher Value', "Rate", "Taxable Value", + "Cess Amount", 'Pre GST', ] + self.write_data_worksheet_header(worksheet, invoice_header, + cell_format['header_cell_format'], + row, col) + row += 1 + col = 0 + for inv in inv_ids_cdnur: + inv_value = [{ + 'value': inv['gst_invoice_type'], + 'format': cell_format['regular_cell_format_center']}, + {'value': inv['inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['inv_date'], '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['document_type'], + 'format': cell_format['regular_cell_format_center']}, + {'value': inv['refund_inv_no'], + 'format': cell_format['regular_cell_format']}, + {'value': datetime.strptime(inv['refund_date_invoice'], + '%d %b %y'), + 'format': cell_format['regular_cell_format_date']}, + {'value': inv['reason'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['place_supply'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['rate'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if + inv['cess_amount'] > 0.0 else 0.0, + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['pre_gst'], + 'format': cell_format['regular_cell_format_center']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def sheet_hsn(self, data, workbook, **post): + """ + Generate excel sheet for 'hsn' Data + :param data: + :param workbook: + :param post: + :return: + """ + cell_format = self.cell_format(workbook=workbook, **post) + worksheet = workbook.add_worksheet('hsn') + workbook.add_format({'locked': 1}) + worksheet.set_column(0, 20, 20) + worksheet.protect() + inv_ids_hsn = self.get_data_hsn(data=data, **post) + + # Calculation of header + summary = self.get_data_hsn_summary(data=data, **post) + + # formatting + row = 0 + # summary header + self.set_summary_header(worksheet, 'Summary For HSN(12)', 10, 0, 0, + cell_format) + row += 1 + # total summary header + col = 0 + summary_header = ['No. of HSN', '', '', '', 'Total Value', + 'Total Taxable Value', 'Total Integrated Tax', + 'Total Central Tax', 'Total State/UT Tax', + 'Total Cess'] + self.write_data_worksheet_header( + worksheet, summary_header, cell_format[ + 'borederd_header_cell_format'], row, col) + row += 1 + + col = 0 + if summary: + summary_value = [{ + 'value': summary['no_of_hsn'], + 'format': cell_format['borederd_header_cell_format_count']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': '', + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['taxable_value_total'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['igst_amount'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['cgst_amount'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['sgst_amount'], + 'format': cell_format['borederd_header_cell_format_right']}, + {'value': summary['cess_amt_total'], + 'format': cell_format['borederd_header_cell_format_right']}] + self.write_data_worksheet_values(worksheet, summary_value, row, + col) + worksheet.set_row(3, 15) + row = 3 + col = 0 + # insert hsn main header + hsn_header = ['HSN', 'Description', 'UQC', 'Total Quantity', + 'Total Value', 'Taxable Value', 'Integrated Tax Amount', + 'Central Tax Amount', 'State/UT Tax Amount', + 'Cess Amount'] + self.write_data_worksheet_header(worksheet, hsn_header, cell_format[ + 'header_cell_format'], row, col) + row += 1 + col = 0 + # product wise hsn lines + for inv in inv_ids_hsn: + inv_value = [{ + 'value': inv['hsn'], + 'format': cell_format['regular_cell_format_center']}, + {'value': inv['product_name'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['uqc'], + 'format': cell_format['regular_cell_format']}, + {'value': inv['total_qty'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['taxable_value'], + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['igst_amt'] if inv['igst_amt'] > 0.0 else '', + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cgst_amt'] if inv['cgst_amt'] > 0.0 else '', + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['sgst_amt'] if inv['sgst_amt'] > 0.0 else '', + 'format': cell_format['regular_cell_format_right']}, + {'value': inv['cess_amount'] if inv['cess_amount'] > 0.0 else + '', + 'format': cell_format['regular_cell_format_right']}] + self.write_data_worksheet_values(worksheet, inv_value, row, col) + row += 1 + + def write_data_into_sheets(self, data, response=False, **post): + output_stream = BytesIO() + workbook = xlsxwriter.Workbook(output_stream, {'in_memory': True}) + # b2b + self.sheet_b2b(data=data['form'], workbook=workbook, **post) + if data['form'].get('summary_type') == 'gstr1': + # b2cl + self.sheet_b2cl(data=data['form'], workbook=workbook, **post) + + # b2cs + self.sheet_b2cs(data=data['form'], workbook=workbook, **post) + elif data['form'].get('summary_type') == 'gstr2': + self.sheet_b2bur(data=data['form'], workbook=workbook, **post) + # cdnr + self.sheet_cdnr(data=data['form'], workbook=workbook, **post) + + # cdnur + self.sheet_cdnur(data=data['form'], workbook=workbook, **post) + + # hsn + self.sheet_hsn(data=data['form'], workbook=workbook, **post) + workbook.close() + output_stream.seek(0) + if response: + response.stream.write(output_stream.read()) + output_stream.close() + + @api.multi + def print_report(self, values, flag=None, response=None, **post): + """ Export GSTR1 excel report """ + if flag: + data = {'form': values} + else: + data = { + 'form': { + 'from_date': self.from_date, 'to_date': self.to_date, + 'company_id': + self.company_id and self.company_id.id or False, + } + } + self.write_data_into_sheets(data, response, **post) diff --git a/addons/l10n_in_gst/security/ir.model.access.csv b/addons/l10n_in_gst/security/ir.model.access.csv new file mode 100644 index 00000000..f0a601b3 --- /dev/null +++ b/addons/l10n_in_gst/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_note_issue_reason_all,access_note_issue_reason_all,model_note_issue_reason,account.group_account_manager,1,1,1,1 +access_note_issue_reason,access_note_issue_reason,model_note_issue_reason,,1,0,0,0 +access_res_company_b2c_limit_all,access_res_company_b2c_limit_all,model_res_company_b2c_limit,base.group_system,1,1,1,1 +access_res_company_b2c_limit,access_res_company_b2c_limit,model_res_company_b2c_limit,,1,0,0,0 diff --git a/addons/l10n_in_gst/static/description/company_gst_config.png b/addons/l10n_in_gst/static/description/company_gst_config.png new file mode 100644 index 00000000..5848bbb2 Binary files /dev/null and b/addons/l10n_in_gst/static/description/company_gst_config.png differ diff --git a/addons/l10n_in_gst/static/description/excel_sheet.png b/addons/l10n_in_gst/static/description/excel_sheet.png new file mode 100644 index 00000000..91a96c10 Binary files /dev/null and b/addons/l10n_in_gst/static/description/excel_sheet.png differ diff --git a/addons/l10n_in_gst/static/description/gstr1_summary_view1.png b/addons/l10n_in_gst/static/description/gstr1_summary_view1.png new file mode 100644 index 00000000..cd1d7ef4 Binary files /dev/null and b/addons/l10n_in_gst/static/description/gstr1_summary_view1.png differ diff --git a/addons/l10n_in_gst/static/description/gstr1_summary_view2.png b/addons/l10n_in_gst/static/description/gstr1_summary_view2.png new file mode 100644 index 00000000..0e77dbe0 Binary files /dev/null and b/addons/l10n_in_gst/static/description/gstr1_summary_view2.png differ diff --git a/addons/l10n_in_gst/static/description/icon.png b/addons/l10n_in_gst/static/description/icon.png new file mode 100644 index 00000000..622a317b Binary files /dev/null and b/addons/l10n_in_gst/static/description/icon.png differ diff --git a/addons/l10n_in_gst/static/description/index.html b/addons/l10n_in_gst/static/description/index.html new file mode 100644 index 00000000..7216bb6f --- /dev/null +++ b/addons/l10n_in_gst/static/description/index.html @@ -0,0 +1,92 @@ +
+
+

+ Goods and Services Tax Management for India

+
+

GST module for Flectra enables Indian Organization to use Flectra Accounting in + accordance to GST taxation structure. Providing necessary reporting data for + GSTR-1 filing, Tax Credit etc.

+
+ +
+
+

Accounting settings for GST

+
+ +
+
+
+ +
+
+

Partner configurations for GST

+
+ +
+
+
+ +
+
+

Successfully manage + your invoices according to their classification in GST

+
+ +
+
+
+ +
+
+

Invoice form with improvements related to + GST details

+
+ +
+
+
+ +
+
+

GSTR-1 Monthly Summary

+
+

+ View month, year and company wise GSTR-1 return summary. +

+
+
+ +
+
+
+ +
+
+

GSTR-1 Summary Details

+
+ +
+
+
+ +
+
+

GSTR-1 Excel Export

+
+

+ GSTR-1 excel sheet export feature, this auto generated file + can be imported at GST Offline Utility software without any + modifications. +

+
+
+ +
+
+
diff --git a/addons/l10n_in_gst/static/description/invoice_form.png b/addons/l10n_in_gst/static/description/invoice_form.png new file mode 100644 index 00000000..dda3933e Binary files /dev/null and b/addons/l10n_in_gst/static/description/invoice_form.png differ diff --git a/addons/l10n_in_gst/static/description/invoice_list_groupby.png b/addons/l10n_in_gst/static/description/invoice_list_groupby.png new file mode 100644 index 00000000..3ec0f24d Binary files /dev/null and b/addons/l10n_in_gst/static/description/invoice_list_groupby.png differ diff --git a/addons/l10n_in_gst/static/description/partner_form.png b/addons/l10n_in_gst/static/description/partner_form.png new file mode 100644 index 00000000..a2b4703d Binary files /dev/null and b/addons/l10n_in_gst/static/description/partner_form.png differ diff --git a/addons/l10n_in_gst/static/src/js/gst_report.js b/addons/l10n_in_gst/static/src/js/gst_report.js new file mode 100644 index 00000000..f157fa53 --- /dev/null +++ b/addons/l10n_in_gst/static/src/js/gst_report.js @@ -0,0 +1,389 @@ +flectra.define('l10n_in_gst.gstr1', function (require) { + "use strict"; + + var core = require('web.core'); + var Widget = require('web.Widget'); +// var Model = require('web.Model'); + var rpc = require('web.rpc'); + var session = require('web.session'); + var ControlPanelMixin = require('web.ControlPanelMixin'); + var crash_manager = require('web.crash_manager'); + var framework = require('web.framework'); + + var QWeb = core.qweb; + + var GSTRport = Widget.extend(ControlPanelMixin, { + template: 'GSTReportDashboard', + events: { + "click [data-action]": "open_summary_data", + "click [action]": "trigger_action", + "click .show_subline": "show_subline" + }, + init: function (parent, action) { + this.actionManager = parent; + this.model = action.context.model; // get default model from context + this.summary_type = action.context.summary_type + this.pager_context = { + rec_limit: 10, + rec_start: 1, + rec_end: 10, + rec_length: null, + rec_range: null, + total_page: null, + }; + + this.months = { + 1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", + 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December" + }; + this.gst_report_context = { + 'from_date': null, + 'to_date': null, + 'company_id': session.company_id, + 'year': null, + 'month': null, + 'template': 'ViewSummary', + 'data_action_method': 'get_gstr_summary', + 'summary_type': this.summary_type + }; + this.update_date(); + return this._super.apply(this, arguments); + }, + + start: function () { + var self = this; + var temp = self._rpc({ + model: this.model, + method: this.gst_report_context.data_action_method, + args: [[], this.gst_report_context, 1], + }).then(function (data) { + return data; + }); + return $.when(temp, this._super.apply(this, arguments)).then(function (data) { + self.$el.html(QWeb.render(self.gst_report_context.template, {data: data['summary']})); + self.$button_html = $(QWeb.render('GSTButton', {})); + self.$pager_html = $(QWeb.render('GSTPager', {})); + self.$search_view_html = $(QWeb.render('GSTFilter', { + companies: data['companies'], + months: self.months, + curr_com_id: session.company_id, + curr_month: new Date().getMonth() + 1, + curr_year: new Date().getFullYear() + })); + self.update_cp(); + self.render_control_panel(); + }); + }, + // Update from_date and to_date when change made in month filter + update_date: function () { + var dt; + if (this.gst_report_context.from_date) { + dt = new Date(this.gst_report_context.year + " " + this.gst_report_context.month + " 01"); + } else { + dt = new Date(); + } + var month = dt.getMonth() + 1, + year = dt.getFullYear(); + new Date(year, month, 0).getDate(); + + this.gst_report_context.year = year; + this.gst_report_context.month = month; + this.gst_report_context.from_date = year + '-' + month + '-01'; + this.gst_report_context.to_date = year + '-' + month + '-' + new Date(year, month, 0).getDate(); + }, + // Update control panel Mixin when go back in GST report + do_show: function () { + this._super.apply(this, arguments); + this.update_cp(); + }, + // override method for change control panel mixin + update_cp: function () { + var status = { + breadcrumbs: this.actionManager.get_breadcrumbs(), + cp_content: { + $buttons: this.$button_html, + $searchview_buttons: this.$search_view_html, + $pager: this.$pager_html, + $searchview: this.$searchview + } + }; + return this.update_control_panel(status, {clear: true}); + }, + // update el according user select report type + update_report_data: function () { + var self = this; + if (this.gst_report_context.template == 'ViewSummary') { + self._rpc({ + model: this.model, + method: this.gst_report_context.data_action_method, + args: [[], this.gst_report_context], + }).then(function (data) { + self.$el.html(QWeb.render(self.gst_report_context.template, {data: data})); + }); + } else { + self._rpc({ + model: this.model, + method: this.gst_report_context.data_action_method, + args: [[], this.gst_report_context, this.pager_context.rec_start, this.pager_context.rec_end], + }).then(function (data) { + self.$el.html(QWeb.render(self.gst_report_context.template, {data: data['data'], 'summary_type': + self.gst_report_context.summary_type + })); + $("#pager").removeClass('hidden'); + self.pager_context.rec_length = data['length']; + if (self.pager_context.rec_limit > self.pager_context.rec_length) { + self.pager_context.rec_limit = self.pager_context.rec_length; + } + if (data['length'] > 0) { + self.pager_context.total_page = Math.ceil(data['length'] / self.pager_context.rec_limit); + self.pager_context.rec_end = Math.min(self.pager_context.rec_end, self.pager_context.rec_length); + self.pager_context.offset = (self.pager_context.total_page * self.pager_context.rec_limit) - self.pager_context.rec_length; + if (self.pager_context.rec_start === self.pager_context.rec_end && self.pager_context.rec_limit === 1) { + self.pager_context.rec_range = self.pager_context.rec_start.toString(); + } else if (self.pager_context.rec_start === self.pager_context.rec_end && self.pager_context.rec_limit > 1) { + self.pager_context.rec_range = self.pager_context.rec_start.toString() + '-' + self.pager_context.rec_end.toString(); + } else { + self.pager_context.rec_range = self.pager_context.rec_start.toString() + '-' + self.pager_context.rec_end.toString(); + } + $("#pager .o_pager_value").html(self.pager_context.rec_range); + $("#pager .o_pager_limit").html(self.pager_context.rec_length); + if (self.pager_context.total_page > 1) { + self.$pager_html.find(".o_pager_next").prop('disabled', false); + self.$pager_html.find(".o_pager_previous").prop('disabled', false); + } else { + self.$pager_html.find(".o_pager_next").prop('disabled', true); + self.$pager_html.find(".o_pager_previous").prop('disabled', true); + } + } else { + $("#pager").addClass('hidden'); + } + }); + } + }, + // function of control panel mixin + render_control_panel: function () { + var self = this; + // view summary function + this.$button_html.find('#view_summary_back').click(function (e) { + var view_summary_back_btn = $(this); + self._rpc({ + model: 'gst.report', + method: 'get_gstr_summary', + args: [[], self.gst_report_context], + }).then(function (data) { + self.$el.html(QWeb.render('ViewSummary', {data: data})); + self.gst_report_context.template = 'ViewSummary'; + self.gst_report_context.data_action_method = 'get_gstr_summary'; + view_summary_back_btn.addClass('hidden'); + $("#pager").addClass('hidden'); + $("#export_excel").removeClass('hidden'); + }); + }); + // month filter + this.$search_view_html.find('#filter_month li a').click(function (e) { + if (self.gst_report_context.month != $(this).attr('data-value')) { + $('#filter_month li').removeClass('active'); + $('#filter_month li a span i').removeClass('fa fa-check pull-right'); + $(this).find('i').addClass('fa fa-check pull-right'); + $(this).parent().addClass('active'); + $(this).parent().parent().prev().html($(this).attr('data-string') + ' '); + + self.gst_report_context.month = $(this).attr('data-value'); + self.update_date(); + self._clear_context(); + self.update_report_data(); + } + }); + // res_company filter + this.$search_view_html.find('#res_company li a').click(function (e) { + if (self.gst_report_context.company_id != parseInt($(this).attr('data-id'))) { + $('#res_company li').removeClass('active'); + $('#res_company li a span i').removeClass('fa fa-check pull-right'); + $(this).find('i').addClass('fa fa-check pull-right'); + $(this).parent().addClass('active'); + $(this).parent().parent().prev().html($(this).attr('data-string') + ' '); + + self.gst_report_context.company_id = parseInt($(this).attr('data-id')); + self.update_date(); + self._clear_context(); + self.update_report_data(); + } + }); + // year filter + this.$search_view_html.find('#filter_year').change(function (e) { + if (self.gst_report_context.year != $(this).val()) { + self.gst_report_context.year = $(this).val(); + self.update_date(); + self._clear_context(); + self.update_report_data(); + } + }); + // export excel report + this.$button_html.find('#export_excel').click(function (e) { + var c = crash_manager; + session.get_file({ + url: '/l10n_in_gst/export_excel', + data: self.gst_report_context, + complete: framework.unblockUI, + error: c.rpc_error.bind(c) + }); + }); + + this.$pager_html.find('.o_pager_value').click(function (e) { + var inner_self = this; + var o_pager_value = $(this).html(); + var $input = $('', {type: 'text', value: o_pager_value}); + + $(this).html($input); + $input.focus(); + + // Event handlers + $input.click(function (ev) { + ev.stopPropagation(); // ignore clicks on the input + }); + $input.blur(function (ev) { + //$(inner_self).html($(this).val()); + self._save($(ev.target), $(inner_self)); // save the state when leaving the input + }); + $input.on('keydown', function (ev) { + ev.stopPropagation(); + if (ev.which === $.ui.keyCode.ENTER) { + self._save($(ev.target), $(inner_self)); // save on enter + } else if (ev.which === $.ui.keyCode.ESCAPE) { + $(inner_self).html(o_pager_value); // leave on escape + } + }); + }); + + this.$pager_html.find('[accesskey]').click(function (e) { + var access_key = $(this).attr('accesskey'); + if (access_key == "n") { + self.pager_context.rec_start = self.pager_context.rec_end + 1; + self.pager_context.rec_end = Math.min((self.pager_context.rec_end + self.pager_context.rec_limit), self.pager_context.rec_length); + if (self.pager_context.rec_end < self.pager_context.rec_start) { + self.pager_context.rec_start = 1; + self.pager_context.rec_end = self.pager_context.rec_limit; + } + } else if (access_key == "p") { + self.pager_context.rec_start -= self.pager_context.rec_limit; + self.pager_context.rec_end = Math.max((self.pager_context.rec_start + self.pager_context.rec_limit - 1), 1); + if ((self.pager_context.rec_end == self.pager_context.rec_length) && (self.pager_context.rec_length < (self.pager_context.total_page * self.pager_context.rec_limit))) { + self.pager_context.rec_start = ((self.pager_context.total_page - 2) * self.pager_context.rec_limit) + 1; + self.pager_context.rec_end = self.pager_context.rec_start + self.pager_context.rec_limit; + } else if (self.pager_context.rec_start <= 0) { + self.pager_context.rec_start = ((self.pager_context.total_page - 1) * self.pager_context.rec_limit) + 1; + self.pager_context.rec_end = self.pager_context.rec_length; + } + } + if (self.pager_context.rec_start === self.pager_context.rec_end) { + self.pager_context.rec_range = self.pager_context.rec_start.toString(); + } else { + self.pager_context.rec_range = self.pager_context.rec_start.toString() + '-' + self.pager_context.rec_end.toString(); + } + self.update_report_data(); + }); + }, + // render more details about report + open_summary_data: function (e) { + var data_action = $(e.target).attr('data-action'); + this._clear_context(); + this.gst_report_context.template = data_action.split('_data_')[1].toUpperCase() + 'ViewSummary'; + this.gst_report_context.data_action_method = data_action; + $("#view_summary_back").removeClass('hidden'); + $("#export_excel").addClass('hidden'); + this.update_report_data(); + + }, + // open invoice form + trigger_action: function (e) { + var self = this; + var action = $(e.target).attr('action'); + var data_id = $(e.target).attr('data-id'); + var data_object = $(e.target).attr('data-object'); + if (action) { + return self._rpc({ + model: this.model, + method: action, + args: ['', { + id: data_id, + object: data_object + }], + }).then(function (result) { + return self.do_action(result); + }); + } + }, + // display sub line + show_subline: function (e) { + var tr = $(e.target).parent().parent().next('tr.data_subline'); + if (tr.attr('class').indexOf('hidden') === -1) { + tr.addClass('hidden'); + } else { + tr.removeClass('hidden'); + } + }, + // clear page context + _clear_context: function () { + this.pager_context = { + rec_limit: 10, + rec_start: 1, + rec_end: 10, + rec_length: null, + rec_range: null, + total_page: null, + offset: null + }; + }, + // re-render after made change in pagination filter + _save: function ($input, $o_pager_value) { + var value = $input.val().split("-"); + var start = parseInt(value[0]); + var end = parseInt(value[1]); + var pager_context = _.clone(this.pager_context); + if (!isNaN(start)) { + if ((start <= this.pager_context.rec_length) && (start > 0)) { + if (value.length === 1) { + this.pager_context.rec_end = this.pager_context.rec_start = start; + this.pager_context.rec_limit = 1; + } else { + this.pager_context.rec_start = start; + } + } else { + $o_pager_value.html(this.pager_context.rec_range); + return false; + } + + if (!isNaN(end)) { + if ((end <= this.pager_context.rec_length) && (end > 0) && (end >= this.pager_context.rec_start)) { + this.pager_context.rec_end = end; + this.pager_context.rec_limit = (this.pager_context.rec_end - this.pager_context.rec_start) + 1; + } else { + $o_pager_value.html(this.pager_context.rec_range); + return false; + } + } + + if (this.pager_context.rec_start > this.pager_context.rec_end) { + this.pager_context = pager_context; + } else { + if (this.pager_context.rec_start === this.pager_context.rec_end) { + this.pager_context.rec_range = this.pager_context.rec_start.toString(); + } else { + this.pager_context.rec_range = this.pager_context.rec_start.toString() + '-' + this.pager_context.rec_end.toString(); + } + this.update_report_data(); + } + } else { + $o_pager_value.html(this.pager_context.rec_range); + return false; + } + } + }); + + core.action_registry.add('l10n_in_gst.gstr1', GSTRport); + + return { + GSTRport: GSTRport + }; + +}); diff --git a/addons/l10n_in_gst/static/src/less/gst_report.less b/addons/l10n_in_gst/static/src/less/gst_report.less new file mode 100644 index 00000000..77948c5d --- /dev/null +++ b/addons/l10n_in_gst/static/src/less/gst_report.less @@ -0,0 +1,36 @@ +.table-border-gst { + border-spacing: 2px; + border-collapse: inherit; +} +.table-header-color-gst { + background-color: #027ec7; + color: white; +} +.sub-table-header-color-gst { + background-color: #989896; + color: white; +} +.td-border { + .table { + >tbody { + >tr { + >td { + border: 1px solid #ddd !important; + } + } + } + } +} +.container-fluid { + .container-blank { + background-color: #fff; + } +} +.data_action_flectra_color { + >a { + color: #006eaf !important; + &:hover { + color: #009efb !important; + } + } +} diff --git a/addons/l10n_in_gst/static/src/xml/gst_report.xml b/addons/l10n_in_gst/static/src/xml/gst_report.xml new file mode 100644 index 00000000..5fb152cc --- /dev/null +++ b/addons/l10n_in_gst/static/src/xml/gst_report.xml @@ -0,0 +1,974 @@ + + + + +
+ + + +
+ +
+
+ +
+
+ + + + + + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+ + +
+
+

Summary

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Section NameNo. of InvoicesTotal Central Tax Amount (₹)Total State/UT Tax Amount (₹)Total Integrated Tax Amount (₹)Total CESS (₹)
+ + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+ +

B2B Invoices - 4A, 4B, 4C, 6B, 6C

+
+ +

Supplies From Registered Suppliers B2B - 3,4A

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Receiver GSTIN/UINInvoices No.Invoices DatePlace of SupplyRateInvoice TypeReverse ChargesE-Commerce GSTINTaxable ValueIGSTCGSTSGSTCESS
+ + + + + + + + + % + + + + + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+

B2C(Large) Invoices - 5A, 5B

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Invoices No.Invoices DatePlace of SupplyRateE-Commerce + GSTINTaxable ValueIGSTCGSTSGSTCESS
+ + + + + + + % + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+

B2C(Small) Details - 7

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Invoices No.Place of SupplyRateTypeE-Commerce + GSTINTaxable ValueIGSTCGSTSGSTCESS
+ + + + + % + + + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+ +

Credit/Debit Notes(Registered) - 9B

+
+ +

Debit/Credit Notes (Registered) - 6C

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GSTIN/UIN of RecipientInvoice/Advance Receipt NumberInvoice/Advance Receipt dateNote/Refund Voucher NumberNote/Refund Voucher dateDocument TypeReason For Issuing documentPlace Of SupplyRateTaxable ValueIGSTCGSTSGSTCESSPre GST
+ + + + + + + + + + + + + + + + + % + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+ +

Credit/Debit Notes(Unregistered) - 9B

+
+ +

Credit/Debit Notes(Unregistered) - 6C

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UR TypeInvoice/Advance Receipt NumberInvoice/Advance Receipt dateNote/Refund Voucher NumberNote/Refund Voucher dateDocument TypeReason For Issuing documentPlace Of SupplyRateTaxable ValueIGSTCGSTSGSTCESSPre GST
+ + + + + + + + + + + + + + + + + % + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+ +

HSN-Wise Summary of outward Supplies - 12

+
+ +

HSN-Wise Summary of outward Supplies - 13

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HSNDescriptionUQCTotal QuantityTotal ValueTaxable ValueIGSTCGSTSGSTCESS
+ + + + + + + + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + +
+
+

Supplies From Unregistered Suppliers B2BUR - 4C

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Invoices No.Invoices DatePlace of SupplyRateE-Commerce GSTINTaxable ValueIGSTCGSTSGSTCESS
+ + + + + + + % + + + + + + + + + + + + +
+ No Record Found +
+
+
+ + + diff --git a/addons/l10n_in_gst/tests/__init__.py b/addons/l10n_in_gst/tests/__init__.py new file mode 100644 index 00000000..3bd9e23d --- /dev/null +++ b/addons/l10n_in_gst/tests/__init__.py @@ -0,0 +1,7 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import test_gst_common +from . import test_account_invoice +from . import test_res_partner +from . import test_res_company +from . import test_gst_summary_reports diff --git a/addons/l10n_in_gst/tests/test_account_invoice.py b/addons/l10n_in_gst/tests/test_account_invoice.py new file mode 100644 index 00000000..6e459c12 --- /dev/null +++ b/addons/l10n_in_gst/tests/test_account_invoice.py @@ -0,0 +1,237 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +import logging +from .test_gst_common import TestGSTCommon + + +class TestCreateInvoice(TestGSTCommon): + def setUp(self): + super(TestCreateInvoice, self).setUp() + + def details_of_invoice(self, invoice_id): + logging.info('\n\n') + logging.info('|=== Test case for %s type invoice ===|' % + invoice_id.gst_invoice) + logging.info('Invoice No. : %s' % invoice_id.number) + logging.info('Invoice Type : %s' % invoice_id.gst_invoice) + logging.info('Customer Name : %s' % invoice_id.partner_id.name) + logging.info('Invoice date : %s' % invoice_id.date_invoice) + logging.info('GST Type : %s' % invoice_id.gst_type) + logging.info('GST Number : %s' % (invoice_id.vat or 'N/A')) + logging.info('Journal : %s' % invoice_id.journal_id.name) + logging.info('Account : %s' % invoice_id.account_id.name) + logging.info('Source Doc. : %s' % (invoice_id.origin or '-')) + logging.info('Invoice lines :') + for line in invoice_id.invoice_line_ids: + logging.info('\t\t Product name : %s' % line.product_id.name) + logging.info('\t\t Quantity : %d' % line.quantity) + logging.info('\t\t Price unit : %d' % line.price_unit) + logging.info('\t\t Total : %d' % line.price_subtotal) + logging.info('\t\t Taxes : %s' % + (line.invoice_line_tax_ids.name or 'N/A')) + + def test_invoice_b2b(self): + # Add tax for product + for line in self.account_invoice_b2b.invoice_line_ids: + line.write({ + 'invoice_line_tax_ids': [(4, self.tax_gst_5.id)] + }) + + # Test for state initially + self.assertEquals(self.account_invoice_b2b.state, 'draft') + + # Test for invoice type before validation + assert not self.account_invoice_b2b.gst_invoice, \ + 'Invoice type should be null' + + # Test state of invoice after validation + self.account_invoice_b2b.action_invoice_open() + self.assertEquals(self.account_invoice_b2b.state, 'open') + + # Test for move attachment + assert self.account_invoice_b2b.move_id, \ + 'Move is not created for open invoice' + + # Test for GST Invoice type + if self.account_invoice_b2b.partner_id.vat: + self.assertTrue(self.account_invoice_b2b.gst_invoice == 'b2b', + 'Invoice must be a type B2B') + + # Test GST number of a partner + if self.account_invoice_b2b.partner_id.gst_type != 'unregistered': + assert self.account_invoice_b2b.vat,\ + 'Registered partner must have GST Number' + + self.details_of_invoice(self.account_invoice_b2b) + + # Create refund invoice + self.account_invoice_refund_b2b = self.account_invoice_b2b.refund() + + # Test case for invoice type + assert self.account_invoice_refund_b2b.gst_invoice, \ + 'Invoice type should be null' + + # Test for state initially + self.assertEquals(self.account_invoice_refund_b2b.state, 'draft') + + # Test the state after invoice validation + self.account_invoice_refund_b2b.action_invoice_open() + self.assertEquals(self.account_invoice_refund_b2b.state, 'open') + + # Test whether refund invoice is created + assert self.account_invoice_refund_b2b.refund_invoice_id, \ + 'Refund invoice is not created' + + # Test for refund invoice created for B2B type invoice + self.assertEquals(self.account_invoice_refund_b2b.refund_invoice_id.id, + self.account_invoice_b2b.id, + 'Refund invoice for B2B type is not created') + + # Test refunded amount total + self.assertEquals( + -self.account_invoice_refund_b2b.amount_untaxed_signed, + self.account_invoice_b2b.amount_untaxed_signed, + 'Amount total is wrong in refund') + + self.details_of_invoice(self.account_invoice_refund_b2b) + self.env.ref('l10n_in_gst.l10n_in_gst_report_action') + + def test_invoice_b2cs(self): + # Add tax for product + for line in self.account_invoice_b2cs.invoice_line_ids: + line.write({ + 'invoice_line_tax_ids': [(4, self.tax_gst_18.id)] + }) + + # Test for invoice type before validation + assert not self.account_invoice_b2cs.gst_invoice, \ + 'Invoice type should be null' + + # Test the state of invoice before validation + self.assertEquals(self.account_invoice_b2cs.state, 'draft') + + # Test state of invoice after validation + self.account_invoice_b2cs.action_invoice_open() + self.assertEquals(self.account_invoice_b2cs.state, 'open') + + # Test for move attachment + assert self.account_invoice_b2cs.move_id, \ + 'Move is not created for open invoice' + partner_location = \ + self.account_invoice_b2cs.partner_id.partner_location + + # Test for GST Invoice type + if self.account_invoice_b2cs.partner_id and not self.\ + account_invoice_b2cs.vat and partner_location == \ + 'intra_state' or partner_location == 'inter_state' and \ + self.account_invoice_b2cs.amount_total < \ + self.b2c_limit_b2cs.b2cs_limit: + self.assertTrue(self.account_invoice_b2cs.gst_invoice == 'b2cs', + 'Invoice must be a type B2CS') + + # Test GST number of a partner + if self.account_invoice_b2cs.partner_id.gst_type != 'unregistered': + self.assertTrue(self.account_invoice_b2cs.vat, False, + 'Registered partner must have GST Number') + + self.details_of_invoice(self.account_invoice_b2cs) + + def test_invoice_b2cl(self): + # Add tax for product + for line in self.account_invoice_b2cl.invoice_line_ids: + line.write({ + 'invoice_line_tax_ids': [(4, self.tax_igst_5.id)] + }) + # Test for invoice type before validation + assert not self.account_invoice_b2cl.gst_invoice, \ + 'Invoice type should be null' + + # Test the state of invoice before validation + self.assertEquals(self.account_invoice_b2cl.state, 'draft') + + # Test state of invoice after validation + self.account_invoice_b2cl.action_invoice_open() + self.assertEquals(self.account_invoice_b2cl.state, 'open') + + # Test for move attachment + assert self.account_invoice_b2cl.move_id, \ + 'Move is not created for open invoice' + partner_location = \ + self.account_invoice_b2cl.partner_id.partner_location + # Test for GST Invoice type + if self.account_invoice_b2cl.partner_id and not \ + self.account_invoice_b2cl.vat and \ + partner_location == 'inter_state' and \ + self.account_invoice_b2cl.amount_total > \ + self.b2c_limit_b2cl.b2cl_limit: + self.assertTrue(self.account_invoice_b2cl.gst_invoice == 'b2cl', + 'Invoice must be a type B2CL') + + # Test GST number of a partner + if self.account_invoice_b2cl.partner_id.gst_type != 'unregistered': + self.assertTrue(self.account_invoice_b2cl.vat, False, + 'Registered partner must have GST Number') + + self.details_of_invoice(self.account_invoice_b2cl) + + # Create refund invoice + self.account_invoice_refund_b2cl = self.account_invoice_b2cl.refund() + + # Test for invoice type + assert self.account_invoice_refund_b2cl.gst_invoice, \ + 'Invoice type should be null' + + # Test for state initially + self.assertEquals(self.account_invoice_refund_b2cl.state, 'draft') + + # Test the state after invoice validation + self.account_invoice_refund_b2cl.action_invoice_open() + self.assertEquals(self.account_invoice_refund_b2cl.state, 'open') + + # Test whether refund invoice is created + assert self.account_invoice_refund_b2cl.refund_invoice_id, \ + 'Refund invoice is not created' + + # Test for refund invoice created for B2CL type invoice + self.assertEquals(self.account_invoice_refund_b2cl. + refund_invoice_id.id, self.account_invoice_b2cl.id, + 'Refund invoice for B2CL type is not created') + + # Test refunded amount total + self.assertEquals( + -self.account_invoice_refund_b2cl.amount_untaxed_signed, + self.account_invoice_b2cl.amount_untaxed_signed, + 'Amount total is wrong in refund') + + self.details_of_invoice(self.account_invoice_refund_b2cl) + + def test_invoice_composite(self): + company_id = self.account_invoice_composite.company_id + company_id.write({'gst_type': 'composite'}) + + # Add tax for product + for line in self.account_invoice_b2cl.invoice_line_ids: + line.write({ + 'invoice_line_tax_ids': [(4, self.tax_gst_18.id)] + }) + + # Test for state initially + self.assertEquals(self.account_invoice_composite.state, 'draft') + + # Test for invoice type before validation + assert not self.account_invoice_composite.gst_invoice, \ + 'Invoice type should be null' + + # Test state of invoice after validation + self.account_invoice_composite.action_invoice_open() + self.assertEquals(self.account_invoice_composite.state, 'open') + + # If company is composite then tax computation is not there + if company_id.gst_type == 'composite': + self.assertEquals(len( + self.account_invoice_composite.tax_line_ids.ids), 0, + 'Taxes should not be calculated if company is composite') + + self.details_of_invoice(self.account_invoice_composite) + + company_id.write({'gst_type': 'regular'}) diff --git a/addons/l10n_in_gst/tests/test_gst_common.py b/addons/l10n_in_gst/tests/test_gst_common.py new file mode 100644 index 00000000..e215ac0b --- /dev/null +++ b/addons/l10n_in_gst/tests/test_gst_common.py @@ -0,0 +1,56 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra.tests.common import TransactionCase + + +class TestGSTCommon(TransactionCase): + def setUp(self): + super(TestGSTCommon, self).setUp() + + self.account_invoice_b2b = self.env.ref( + 'l10n_in_gst.demo_invoice_gst9') + + self.account_invoice_b2cs = self.env.ref( + 'l10n_in_gst.demo_invoice_gst10') + self.b2c_limit_b2cs = self.env['res.company.b2c.limit'].search([ + ('date_from', '<=', self.account_invoice_b2cs.date_invoice), + ('date_to', '>=', self.account_invoice_b2cs.date_invoice), + ('company_id', '=', self.account_invoice_b2cs.company_id.id)]) + + self.account_invoice_b2cl = self.env.ref( + 'l10n_in_gst.demo_invoice_gst8') + self.b2c_limit_b2cl = self.env['res.company.b2c.limit'].search([ + ('date_from', '<=', self.account_invoice_b2cl.date_invoice), + ('date_to', '>=', self.account_invoice_b2cl.date_invoice), + ('company_id', '=', self.account_invoice_b2cl.company_id.id)]) + + self.account_invoice_composite = self.env.ref( + 'l10n_in_gst.demo_invoice_gst11') + + self.res_partner_registered = self.env.ref( + 'l10n_in_gst.res_partner_gst_registered') + self.res_partner_unregistered = self.env.ref( + 'l10n_in_gst.res_partner_gst_unregistered') + + self.demo_company = self.env.ref('base.main_company') + + self.tax_gst_5 = self.env['account.tax'].create({ + 'name': 'Test-GST 5%', + 'type_tax_use': 'sale', + 'amount': 5 + }) + self.tax_gst_18 = self.env['account.tax'].create({ + 'name': 'Test-GST 18%', + 'type_tax_use': 'sale', + 'amount': 18 + }) + self.tax_igst_5 = self.env['account.tax'].create({ + 'name': 'Test-IGST 5%', + 'type_tax_use': 'sale', + 'amount': 5 + }) + self.tax_igst_28 = self.env['account.tax'].create({ + 'name': 'Test-IGST 28%', + 'type_tax_use': 'sale', + 'amount': 28 + }) diff --git a/addons/l10n_in_gst/tests/test_gst_summary_reports.py b/addons/l10n_in_gst/tests/test_gst_summary_reports.py new file mode 100644 index 00000000..78b90c99 --- /dev/null +++ b/addons/l10n_in_gst/tests/test_gst_summary_reports.py @@ -0,0 +1,35 @@ +from datetime import datetime +from dateutil.relativedelta import relativedelta +from .test_gst_common import TestGSTCommon + + +class TestGSTSummaryReports(TestGSTCommon): + def test_00_gstr_summary_reports(self): + # call open_document + gst_report_obj = self.env['gst.report'].sudo(self.env.uid) + options = {'object': 'account.invoice', 'id': self.account_invoice_b2b} + gst_report_obj.open_document(options) + + data = { + 'from_date': (datetime.today() - relativedelta(months=1)) + .strftime('%Y-%m-01'), + 'to_date': (datetime.today() - relativedelta(months=1)) + .strftime('%Y-%m-28'), + 'company_id': self.env.user.company_id.id, + 'year': datetime.today().year, + 'month': datetime.today().month, + 'template': 'ViewSummary', + 'data_action_method': 'get_gstr_summary' + } + + # call summary for GSTR1 + data.update({'summary_type': 'gstr1'}) + gst_report_obj.get_gstr_summary(data) + # print excel report for gstr 1 report + gst_report_obj.write_data_into_sheets({'form': data}) + + # call summary for GSTR2 + data.update({'summary_type': 'gstr2'}) + gst_report_obj.get_gstr_summary(data) + # print excel report for gstr 2 report + gst_report_obj.write_data_into_sheets({'form': data}) diff --git a/addons/l10n_in_gst/tests/test_res_company.py b/addons/l10n_in_gst/tests/test_res_company.py new file mode 100644 index 00000000..6d9f0b64 --- /dev/null +++ b/addons/l10n_in_gst/tests/test_res_company.py @@ -0,0 +1,27 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from .test_gst_common import TestGSTCommon + + +class TestResCompany(TestGSTCommon): + def test_res_company(self): + # Test case for regisetered company + if self.demo_company.gst_type == 'regular': + assert self.demo_company.vat,\ + 'Registered company must have GSTIN' + + self.assertEquals(self.demo_company.state_id.l10n_in_tin, + self.demo_company.vat[:2], + 'GST Number is not valid') + + self.assertEquals(len(self.demo_company.vat), 15, + 'GSTIN length must be of 15 characters!') + + # Test case for unregisetered company + if self.demo_company.gst_type == 'unregistered': + assert not self.res_partner_unregistered.vat, \ + 'Unregistered partner does not have GSTIN' + + # Test case for B2C Limit lines + self.assertTrue(len(self.demo_company.company_b2c_limit_line.ids) != 0, + 'Company must have B2C Limit') diff --git a/addons/l10n_in_gst/tests/test_res_partner.py b/addons/l10n_in_gst/tests/test_res_partner.py new file mode 100644 index 00000000..8f6f22d7 --- /dev/null +++ b/addons/l10n_in_gst/tests/test_res_partner.py @@ -0,0 +1,60 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from flectra.osv.orm import except_orm +from .test_gst_common import TestGSTCommon + + +class TestResPartner(TestGSTCommon): + + def test_partner_gstin(self): + # test cases for check constrains on create of partners + with self.assertRaises(except_orm): + self.env['res.partner'].create({ + 'name': 'Demo IGST Unregistered Customer', + 'category_id': self.env.ref('base.res_partner_category_16'), + 'is_company': 1, + 'city': 'Darrang', + 'zip': '784527', + 'state_id': self.env.ref("base.state_in_as").id, + 'country_id': self.env.ref("base.in").id, + 'street': '16 Natrani Avenue', + 'gst_type': 'regular', + 'vat': '18weqqeqe', + 'email': 'igstur@yourcompany.example.com', + 'phone': '+91 95951 95951' + }) + + with self.assertRaises(except_orm): + self.env['res.partner'].create({ + 'name': 'Demo IGST Unregistered Customer', + 'category_id': self.env.ref('base.res_partner_category_16'), + 'is_company': 1, 'city': 'Darrang', 'zip': '784527', + 'state_id': self.env.ref("base.state_in_as").id, + 'country_id': self.env.ref("base.in").id, + 'street': '16 Natrani Avenue', 'gst_type': 'regular', + 'vat': '24weqqeqe45trfg', + 'email': 'igstur@yourcompany.example.com', + 'phone': '+91 95951 95951' + }) + + # Test case for regisetered partner + if self.res_partner_registered.gst_type == 'regular': + assert self.res_partner_registered.vat,\ + 'Registered partner must have GSTIN' + + self.assertEquals(self.res_partner_registered.state_id.l10n_in_tin, + self.res_partner_registered.vat[:2], + 'GST Number is not valid') + + self.assertEquals(len(self.res_partner_registered.vat), 15, + 'GSTIN length must be of 15 characters!') + + if self.res_partner_registered.state_id.id == \ + self.res_partner_registered.company_id.state_id.id: + assert not self.res_partner_registered.\ + property_account_position_id, 'Fiscal position must not be set' + + # Test case for unregisetered partner + if self.res_partner_unregistered.gst_type == 'unregistered': + assert not self.res_partner_unregistered.vat, \ + 'Unregistered partner does not have GSTIN' diff --git a/addons/l10n_in_gst/views/account_invoice_view.xml b/addons/l10n_in_gst/views/account_invoice_view.xml new file mode 100644 index 00000000..ce31a82f --- /dev/null +++ b/addons/l10n_in_gst/views/account_invoice_view.xml @@ -0,0 +1,106 @@ + + + + + + account.invoice.form.inherit.gst.cust + account.invoice + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {'readonly': [('type', '=', 'out_refund')]} + + + + + + + account.invoice.form.inherit.gst + account.invoice + + + + + + + + + + + + + + + + + {'invisible': [('tax_line_ids', '=', [])]} + + + + + + + account.invoice.search.inherit.gst + account.invoice + + + + + + + + + + \ No newline at end of file diff --git a/addons/l10n_in_gst/views/assets.xml b/addons/l10n_in_gst/views/assets.xml new file mode 100644 index 00000000..2afbb165 --- /dev/null +++ b/addons/l10n_in_gst/views/assets.xml @@ -0,0 +1,13 @@ + + + + +