2017-06-21 11:52:38 +00:00
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe , os , json
2017-09-13 07:22:30 +00:00
from frappe . custom . doctype . custom_field . custom_field import create_custom_fields
2021-04-01 10:02:37 +00:00
from frappe . custom . doctype . property_setter . property_setter import make_property_setter
2019-01-24 12:25:44 +00:00
from frappe . permissions import add_permission , update_permission_property
2017-06-21 11:52:38 +00:00
from erpnext . regional . india import states
2021-01-14 13:54:30 +00:00
from erpnext . accounts . utils import get_fiscal_year , FiscalYearError
2018-08-01 12:15:05 +00:00
from frappe . utils import today
2017-06-21 11:52:38 +00:00
2017-06-27 12:35:17 +00:00
def setup ( company = None , patch = True ) :
2021-07-12 12:59:52 +00:00
# Company independent fixtures should be called only once at the first company setup
if frappe . db . count ( ' Company ' , { ' country ' : ' India ' } ) < = 1 :
setup_company_independent_fixtures ( patch = patch )
2018-11-12 11:49:56 +00:00
if not patch :
2018-11-13 10:26:15 +00:00
make_fixtures ( company )
2018-11-12 11:49:56 +00:00
# TODO: for all countries
2021-04-13 10:16:01 +00:00
def setup_company_independent_fixtures ( patch = False ) :
2017-06-21 11:52:38 +00:00
make_custom_fields ( )
2021-04-13 10:16:01 +00:00
make_property_setters ( patch = patch )
2017-06-21 11:52:38 +00:00
add_permissions ( )
2017-06-22 11:07:04 +00:00
add_custom_roles_for_reports ( )
2017-09-28 13:25:40 +00:00
frappe . enqueue ( ' erpnext.regional.india.setup.add_hsn_sac_codes ' , now = frappe . flags . in_test )
2020-08-18 08:43:54 +00:00
create_gratuity_rule ( )
2017-07-05 07:28:19 +00:00
add_print_formats ( )
2021-04-30 11:05:52 +00:00
update_accounts_settings_for_taxes ( )
2017-06-22 11:07:04 +00:00
2017-07-13 06:46:04 +00:00
def add_hsn_sac_codes ( ) :
2021-06-11 10:27:01 +00:00
if frappe . flags . in_test and frappe . flags . created_hsn_codes :
return
2017-07-13 06:46:04 +00:00
# HSN codes
2017-06-21 11:52:38 +00:00
with open ( os . path . join ( os . path . dirname ( __file__ ) , ' hsn_code_data.json ' ) , ' r ' ) as f :
hsn_codes = json . loads ( f . read ( ) )
2017-07-13 06:46:04 +00:00
create_hsn_codes ( hsn_codes , code_field = " hsn_code " )
2017-09-04 05:44:04 +00:00
2017-07-13 06:46:04 +00:00
# SAC Codes
with open ( os . path . join ( os . path . dirname ( __file__ ) , ' sac_code_data.json ' ) , ' r ' ) as f :
sac_codes = json . loads ( f . read ( ) )
create_hsn_codes ( sac_codes , code_field = " sac_code " )
2017-09-04 05:44:04 +00:00
2021-06-11 10:27:01 +00:00
if frappe . flags . in_test :
frappe . flags . created_hsn_codes = True
2017-07-13 06:46:04 +00:00
def create_hsn_codes ( data , code_field ) :
for d in data :
2017-09-27 10:01:30 +00:00
hsn_code = frappe . new_doc ( ' GST HSN Code ' )
hsn_code . description = d [ " description " ]
hsn_code . hsn_code = d [ code_field ]
hsn_code . name = d [ code_field ]
try :
2017-07-13 06:46:04 +00:00
hsn_code . db_insert ( )
2017-09-27 10:01:30 +00:00
except frappe . DuplicateEntryError :
pass
2017-06-21 11:52:38 +00:00
2017-06-22 11:07:04 +00:00
def add_custom_roles_for_reports ( ) :
for report_name in ( ' GST Sales Register ' , ' GST Purchase Register ' ,
2021-08-20 05:40:46 +00:00
' GST Itemised Sales Register ' , ' GST Itemised Purchase Register ' , ' Eway Bill ' ) :
2017-06-22 11:07:04 +00:00
if not frappe . db . get_value ( ' Custom Role ' , dict ( report = report_name ) ) :
frappe . get_doc ( dict (
doctype = ' Custom Role ' ,
report = report_name ,
roles = [
dict ( role = ' Accounts User ' ) ,
dict ( role = ' Accounts Manager ' )
]
) ) . insert ( )
2020-06-19 13:47:57 +00:00
for report_name in ( ' Professional Tax Deductions ' , ' Provident Fund Deductions ' ) :
if not frappe . db . get_value ( ' Custom Role ' , dict ( report = report_name ) ) :
frappe . get_doc ( dict (
doctype = ' Custom Role ' ,
report = report_name ,
roles = [
dict ( role = ' HR User ' ) ,
dict ( role = ' HR Manager ' ) ,
dict ( role = ' Employee ' )
]
) ) . insert ( )
2020-09-03 08:21:26 +00:00
for report_name in ( ' HSN-wise-summary of outward supplies ' , ' GSTR-1 ' , ' GSTR-2 ' ) :
if not frappe . db . get_value ( ' Custom Role ' , dict ( report = report_name ) ) :
frappe . get_doc ( dict (
doctype = ' Custom Role ' ,
report = report_name ,
roles = [
dict ( role = ' Accounts User ' ) ,
dict ( role = ' Accounts Manager ' ) ,
dict ( role = ' Auditor ' )
]
) ) . insert ( )
2017-06-21 11:52:38 +00:00
def add_permissions ( ) :
2021-08-20 05:40:46 +00:00
for doctype in ( ' GST HSN Code ' , ' GST Settings ' , ' GSTR 3B Report ' , ' Lower Deduction Certificate ' ) :
2017-06-21 11:52:38 +00:00
add_permission ( doctype , ' All ' , 0 )
2020-04-04 14:35:17 +00:00
for role in ( ' Accounts Manager ' , ' Accounts User ' , ' System Manager ' ) :
2020-02-03 10:10:35 +00:00
add_permission ( doctype , role , 0 )
update_permission_property ( doctype , role , 0 , ' write ' , 1 )
update_permission_property ( doctype , role , 0 , ' create ' , 1 )
2017-06-21 11:52:38 +00:00
2020-04-04 14:35:17 +00:00
if doctype == ' GST HSN Code ' :
for role in ( ' Item Manager ' , ' Stock Manager ' ) :
add_permission ( doctype , role , 0 )
update_permission_property ( doctype , role , 0 , ' write ' , 1 )
update_permission_property ( doctype , role , 0 , ' create ' , 1 )
2017-07-05 07:28:19 +00:00
def add_print_formats ( ) :
frappe . reload_doc ( " regional " , " print_format " , " gst_tax_invoice " )
2017-12-16 05:23:53 +00:00
frappe . reload_doc ( " accounts " , " print_format " , " gst_pos_invoice " )
2021-03-03 11:33:48 +00:00
frappe . db . set_value ( " Print Format " , " GST POS Invoice " , " disabled " , 0 )
frappe . db . set_value ( " Print Format " , " GST Tax Invoice " , " disabled " , 0 )
2017-07-05 07:28:19 +00:00
2021-04-13 10:16:01 +00:00
def make_property_setters ( patch = False ) :
2021-04-01 10:02:37 +00:00
# GST rules do not allow for an invoice no. bigger than 16 characters
2021-05-14 06:47:41 +00:00
journal_entry_types = frappe . get_meta ( " Journal Entry " ) . get_options ( " voucher_type " ) . split ( " \n " ) + [ ' Reversal Of ITC ' ]
2021-09-02 16:31:24 +00:00
sales_invoice_series = [ ' SINV-.YY.- ' , ' SRET-.YY.- ' , ' ' ] + frappe . get_meta ( " Sales Invoice " ) . get_options ( " naming_series " ) . split ( " \n " )
purchase_invoice_series = [ ' PINV-.YY.- ' , ' PRET-.YY.- ' , ' ' ] + frappe . get_meta ( " Purchase Invoice " ) . get_options ( " naming_series " ) . split ( " \n " )
2021-05-14 06:47:41 +00:00
2021-04-13 10:16:01 +00:00
if not patch :
2021-07-10 14:53:52 +00:00
make_property_setter ( ' Sales Invoice ' , ' naming_series ' , ' options ' , ' \n ' . join ( sales_invoice_series ) , ' ' )
make_property_setter ( ' Purchase Invoice ' , ' naming_series ' , ' options ' , ' \n ' . join ( purchase_invoice_series ) , ' ' )
2021-05-14 06:47:41 +00:00
make_property_setter ( ' Journal Entry ' , ' voucher_type ' , ' options ' , ' \n ' . join ( journal_entry_types ) , ' ' )
2021-04-01 10:02:37 +00:00
2018-07-17 12:52:51 +00:00
def make_custom_fields ( update = True ) :
2017-07-06 09:19:34 +00:00
hsn_sac_field = dict ( fieldname = ' gst_hsn_code ' , label = ' HSN/SAC ' ,
2018-11-13 12:49:58 +00:00
fieldtype = ' Data ' , fetch_from = ' item_code.gst_hsn_code ' , insert_after = ' description ' ,
2019-04-01 06:21:54 +00:00
allow_on_submit = 1 , print_hide = 1 , fetch_if_empty = 1 )
2020-04-21 07:43:39 +00:00
nil_rated_exempt = dict ( fieldname = ' is_nil_exempt ' , label = ' Is Nil Rated or Exempted ' ,
2019-03-21 15:17:47 +00:00
fieldtype = ' Check ' , fetch_from = ' item_code.is_nil_exempt ' , insert_after = ' gst_hsn_code ' ,
print_hide = 1 )
is_non_gst = dict ( fieldname = ' is_non_gst ' , label = ' Is Non GST ' ,
fieldtype = ' Check ' , fetch_from = ' item_code.is_non_gst ' , insert_after = ' is_nil_exempt ' ,
print_hide = 1 )
2021-04-12 05:25:43 +00:00
taxable_value = dict ( fieldname = ' taxable_value ' , label = ' Taxable Value ' ,
fieldtype = ' Currency ' , insert_after = ' base_net_amount ' , hidden = 1 , options = " Company:company:default_currency " ,
print_hide = 1 )
2019-03-21 15:17:47 +00:00
purchase_invoice_gst_category = [
dict ( fieldname = ' gst_section ' , label = ' GST Details ' , fieldtype = ' Section Break ' ,
insert_after = ' language ' , print_hide = 1 , collapsible = 1 ) ,
dict ( fieldname = ' gst_category ' , label = ' GST Category ' ,
2019-04-01 15:26:51 +00:00
fieldtype = ' Select ' , insert_after = ' gst_section ' , print_hide = 1 ,
2019-05-01 08:48:21 +00:00
options = ' \n Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n UIN Holders ' ,
2019-12-10 10:25:05 +00:00
fetch_from = ' supplier.gst_category ' , fetch_if_empty = 1 ) ,
dict ( fieldname = ' export_type ' , label = ' Export Type ' ,
fieldtype = ' Select ' , insert_after = ' gst_category ' , print_hide = 1 ,
depends_on = ' eval:in_list([ " SEZ " , " Overseas " ], doc.gst_category) ' ,
options = ' \n With Payment of Tax \n Without Payment of Tax ' , fetch_from = ' supplier.export_type ' ,
fetch_if_empty = 1 ) ,
2019-03-21 15:17:47 +00:00
]
sales_invoice_gst_category = [
2017-08-21 02:58:55 +00:00
dict ( fieldname = ' gst_section ' , label = ' GST Details ' , fieldtype = ' Section Break ' ,
2018-01-30 06:41:13 +00:00
insert_after = ' language ' , print_hide = 1 , collapsible = 1 ) ,
2019-03-21 15:17:47 +00:00
dict ( fieldname = ' gst_category ' , label = ' GST Category ' ,
2019-04-01 15:26:51 +00:00
fieldtype = ' Select ' , insert_after = ' gst_section ' , print_hide = 1 ,
2019-05-01 08:48:21 +00:00
options = ' \n Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n Consumer \n Deemed Export \n UIN Holders ' ,
2019-12-10 10:25:05 +00:00
fetch_from = ' customer.gst_category ' , fetch_if_empty = 1 ) ,
dict ( fieldname = ' export_type ' , label = ' Export Type ' ,
fieldtype = ' Select ' , insert_after = ' gst_category ' , print_hide = 1 ,
depends_on = ' eval:in_list([ " SEZ " , " Overseas " , " Deemed Export " ], doc.gst_category) ' ,
options = ' \n With Payment of Tax \n Without Payment of Tax ' , fetch_from = ' customer.export_type ' ,
fetch_if_empty = 1 ) ,
2019-03-21 15:17:47 +00:00
]
2021-03-29 14:19:52 +00:00
delivery_note_gst_category = [
dict ( fieldname = ' gst_category ' , label = ' GST Category ' ,
fieldtype = ' Select ' , insert_after = ' gst_vehicle_type ' , print_hide = 1 ,
options = ' \n Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n Consumer \n Deemed Export \n UIN Holders ' ,
fetch_from = ' customer.gst_category ' , fetch_if_empty = 1 ) ,
]
2019-03-21 15:17:47 +00:00
invoice_gst_fields = [
2017-08-21 02:58:55 +00:00
dict ( fieldname = ' invoice_copy ' , label = ' Invoice Copy ' ,
2019-12-10 10:25:05 +00:00
fieldtype = ' Select ' , insert_after = ' export_type ' , print_hide = 1 , allow_on_submit = 1 ,
2017-08-21 02:58:55 +00:00
options = ' Original for Recipient \n Duplicate for Transporter \n Duplicate for Supplier \n Triplicate for Supplier ' ) ,
dict ( fieldname = ' reverse_charge ' , label = ' Reverse Charge ' ,
fieldtype = ' Select ' , insert_after = ' invoice_copy ' , print_hide = 1 ,
options = ' Y \n N ' , default = ' N ' ) ,
dict ( fieldname = ' ecommerce_gstin ' , label = ' E-commerce GSTIN ' ,
2018-01-26 05:57:22 +00:00
fieldtype = ' Data ' , insert_after = ' export_type ' , print_hide = 1 ) ,
2018-02-14 12:14:06 +00:00
dict ( fieldname = ' gst_col_break ' , fieldtype = ' Column Break ' , insert_after = ' ecommerce_gstin ' ) ,
2018-01-26 05:57:22 +00:00
dict ( fieldname = ' reason_for_issuing_document ' , label = ' Reason For Issuing document ' ,
2018-02-05 10:39:51 +00:00
fieldtype = ' Select ' , insert_after = ' gst_col_break ' , print_hide = 1 ,
2018-02-14 12:14:06 +00:00
depends_on = ' eval:doc.is_return==1 ' ,
2018-02-12 11:24:13 +00:00
options = ' \n 01-Sales Return \n 02-Post Sale Discount \n 03-Deficiency in services \n 04-Correction in Invoice \n 05-Change in POS \n 06-Finalization of Provisional assessment \n 07-Others ' )
2017-08-21 02:58:55 +00:00
]
2017-09-04 05:44:04 +00:00
2017-08-21 02:58:55 +00:00
purchase_invoice_gst_fields = [
2017-06-21 11:52:38 +00:00
dict ( fieldname = ' supplier_gstin ' , label = ' Supplier GSTIN ' ,
2017-06-22 11:07:04 +00:00
fieldtype = ' Data ' , insert_after = ' supplier_address ' ,
2019-12-10 10:25:05 +00:00
fetch_from = ' supplier_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2017-06-21 11:52:38 +00:00
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
2018-06-05 05:57:53 +00:00
fieldtype = ' Data ' , insert_after = ' shipping_address_display ' ,
2019-12-10 10:25:05 +00:00
fetch_from = ' shipping_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2018-02-05 10:39:51 +00:00
dict ( fieldname = ' place_of_supply ' , label = ' Place of Supply ' ,
fieldtype = ' Data ' , insert_after = ' shipping_address ' ,
2019-12-10 10:25:05 +00:00
print_hide = 1 , read_only = 1 ) ,
2019-01-09 11:39:11 +00:00
]
purchase_invoice_itc_fields = [
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' eligibility_for_itc ' , label = ' Eligibility For ITC ' ,
fieldtype = ' Select ' , insert_after = ' reason_for_issuing_document ' , print_hide = 1 ,
2021-05-14 06:47:41 +00:00
options = ' Input Service Distributor \n Import Of Service \n Import Of Capital Goods \n ITC on Reverse Charge \n Ineligible As Per Section 17(5) \n Ineligible Others \n All Other ITC ' ,
default = " All Other ITC " ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' itc_integrated_tax ' , label = ' Availed ITC Integrated Tax ' ,
2021-05-14 06:47:41 +00:00
fieldtype = ' Currency ' , insert_after = ' eligibility_for_itc ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' itc_central_tax ' , label = ' Availed ITC Central Tax ' ,
2021-05-14 06:47:41 +00:00
fieldtype = ' Currency ' , insert_after = ' itc_integrated_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' itc_state_tax ' , label = ' Availed ITC State/UT Tax ' ,
2021-05-14 06:47:41 +00:00
fieldtype = ' Currency ' , insert_after = ' itc_central_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' itc_cess_amount ' , label = ' Availed ITC Cess ' ,
2021-05-14 06:47:41 +00:00
fieldtype = ' Currency ' , insert_after = ' itc_state_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2017-08-21 02:58:55 +00:00
]
2017-09-04 05:44:04 +00:00
2017-08-21 02:58:55 +00:00
sales_invoice_gst_fields = [
2017-09-28 05:35:03 +00:00
dict ( fieldname = ' billing_address_gstin ' , label = ' Billing Address GSTIN ' ,
2019-12-10 10:25:05 +00:00
fieldtype = ' Data ' , insert_after = ' customer_address ' , read_only = 1 ,
2018-06-05 05:57:53 +00:00
fetch_from = ' customer_address.gstin ' , print_hide = 1 ) ,
2017-06-21 11:52:38 +00:00
dict ( fieldname = ' customer_gstin ' , label = ' Customer GSTIN ' ,
2018-06-05 05:57:53 +00:00
fieldtype = ' Data ' , insert_after = ' shipping_address_name ' ,
fetch_from = ' shipping_address_name.gstin ' , print_hide = 1 ) ,
2017-08-21 02:58:55 +00:00
dict ( fieldname = ' place_of_supply ' , label = ' Place of Supply ' ,
2018-01-10 12:18:03 +00:00
fieldtype = ' Data ' , insert_after = ' customer_gstin ' ,
2019-12-10 10:25:05 +00:00
print_hide = 1 , read_only = 1 ) ,
2017-06-21 11:52:38 +00:00
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
2017-06-22 11:07:04 +00:00
fieldtype = ' Data ' , insert_after = ' company_address ' ,
2019-12-10 10:25:05 +00:00
fetch_from = ' company_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2019-01-09 11:39:11 +00:00
]
sales_invoice_shipping_fields = [
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' port_code ' , label = ' Port Code ' ,
fieldtype = ' Data ' , insert_after = ' reason_for_issuing_document ' , print_hide = 1 ,
2019-03-21 15:17:47 +00:00
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' shipping_bill_number ' , label = ' Shipping Bill Number ' ,
fieldtype = ' Data ' , insert_after = ' port_code ' , print_hide = 1 ,
2019-03-21 15:17:47 +00:00
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2018-01-29 08:27:34 +00:00
dict ( fieldname = ' shipping_bill_date ' , label = ' Shipping Bill Date ' ,
fieldtype = ' Date ' , insert_after = ' shipping_bill_number ' , print_hide = 1 ,
2019-03-21 15:17:47 +00:00
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2017-08-21 02:58:55 +00:00
]
2017-09-04 05:44:04 +00:00
2021-05-14 06:47:41 +00:00
journal_entry_fields = [
dict ( fieldname = ' reversal_type ' , label = ' Reversal Type ' ,
fieldtype = ' Select ' , insert_after = ' voucher_type ' , print_hide = 1 ,
options = " As per rules 42 & 43 of CGST Rules \n Others " ,
depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " ,
mandatory_depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " ) ,
dict ( fieldname = ' company_address ' , label = ' Company Address ' ,
fieldtype = ' Link ' , options = ' Address ' , insert_after = ' reversal_type ' ,
print_hide = 1 , depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " ,
mandatory_depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " ) ,
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
fieldtype = ' Data ' , read_only = 1 , insert_after = ' company_address ' , print_hide = 1 ,
fetch_from = ' company_address.gstin ' ,
depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " ,
mandatory_depends_on = " eval:doc.voucher_type== ' Reversal Of ITC ' " )
]
2018-06-05 05:57:53 +00:00
inter_state_gst_field = [
dict ( fieldname = ' is_inter_state ' , label = ' Is Inter State ' ,
2019-12-10 10:25:05 +00:00
fieldtype = ' Check ' , insert_after = ' disabled ' , print_hide = 1 ) ,
dict ( fieldname = ' tax_category_column_break ' , fieldtype = ' Column Break ' ,
insert_after = ' is_inter_state ' ) ,
dict ( fieldname = ' gst_state ' , label = ' Source State ' , fieldtype = ' Select ' ,
options = ' \n ' . join ( states ) , insert_after = ' company ' )
2018-06-05 05:57:53 +00:00
]
2018-10-10 09:21:26 +00:00
ewaybill_fields = [
{
' fieldname ' : ' distance ' ,
' label ' : ' Distance (in km) ' ,
' fieldtype ' : ' Float ' ,
' insert_after ' : ' vehicle_no ' ,
' print_hide ' : 1
} ,
{
' fieldname ' : ' gst_transporter_id ' ,
' label ' : ' GST Transporter ID ' ,
' fieldtype ' : ' Data ' ,
2019-07-03 05:04:31 +00:00
' insert_after ' : ' transporter ' ,
' fetch_from ' : ' transporter.gst_transporter_id ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' mode_of_transport ' ,
' label ' : ' Mode of Transport ' ,
' fieldtype ' : ' Select ' ,
' options ' : ' \n Road \n Air \n Rail \n Ship ' ,
' default ' : ' Road ' ,
2018-10-10 09:21:26 +00:00
' insert_after ' : ' transporter_name ' ,
2019-07-03 05:04:31 +00:00
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' gst_vehicle_type ' ,
' label ' : ' GST Vehicle Type ' ,
' fieldtype ' : ' Select ' ,
' options ' : ' Regular \n Over Dimensional Cargo (ODC) ' ,
' depends_on ' : ' eval:(doc.mode_of_transport === " Road " ) ' ,
' default ' : ' Regular ' ,
' insert_after ' : ' lr_date ' ,
' print_hide ' : 1 ,
' translatable ' : 0
2020-02-18 06:58:41 +00:00
} ,
{
' fieldname ' : ' ewaybill ' ,
' label ' : ' E-Way Bill No. ' ,
' fieldtype ' : ' Data ' ,
' depends_on ' : ' eval:(doc.docstatus === 1) ' ,
' allow_on_submit ' : 1 ,
' insert_after ' : ' customer_name_in_arabic ' ,
' translatable ' : 0 ,
2021-03-29 14:19:52 +00:00
}
2019-07-03 05:04:31 +00:00
]
si_ewaybill_fields = [
{
' fieldname ' : ' transporter_info ' ,
' label ' : ' Transporter Info ' ,
' fieldtype ' : ' Section Break ' ,
' insert_after ' : ' terms ' ,
' collapsible ' : 1 ,
' collapsible_depends_on ' : ' transporter ' ,
' print_hide ' : 1
} ,
{
' fieldname ' : ' transporter ' ,
' label ' : ' Transporter ' ,
' fieldtype ' : ' Link ' ,
' insert_after ' : ' transporter_info ' ,
' options ' : ' Supplier ' ,
' print_hide ' : 1
} ,
{
' fieldname ' : ' gst_transporter_id ' ,
' label ' : ' GST Transporter ID ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' transporter ' ,
2018-10-10 09:21:26 +00:00
' fetch_from ' : ' transporter.gst_transporter_id ' ,
2019-07-03 05:04:31 +00:00
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' driver ' ,
' label ' : ' Driver ' ,
' fieldtype ' : ' Link ' ,
' insert_after ' : ' gst_transporter_id ' ,
' options ' : ' Driver ' ,
' print_hide ' : 1
} ,
{
' fieldname ' : ' lr_no ' ,
' label ' : ' Transport Receipt No ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' driver ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' vehicle_no ' ,
' label ' : ' Vehicle No ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' lr_no ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' distance ' ,
' label ' : ' Distance (in km) ' ,
' fieldtype ' : ' Float ' ,
' insert_after ' : ' vehicle_no ' ,
2018-10-10 09:21:26 +00:00
' print_hide ' : 1
} ,
2019-07-03 05:04:31 +00:00
{
' fieldname ' : ' transporter_col_break ' ,
' fieldtype ' : ' Column Break ' ,
' insert_after ' : ' distance '
} ,
{
' fieldname ' : ' transporter_name ' ,
' label ' : ' Transporter Name ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' transporter_col_break ' ,
' fetch_from ' : ' transporter.name ' ,
' read_only ' : 1 ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
2018-10-10 09:21:26 +00:00
{
' fieldname ' : ' mode_of_transport ' ,
' label ' : ' Mode of Transport ' ,
' fieldtype ' : ' Select ' ,
' options ' : ' \n Road \n Air \n Rail \n Ship ' ,
2019-07-03 05:04:31 +00:00
' insert_after ' : ' transporter_name ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' driver_name ' ,
' label ' : ' Driver Name ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' mode_of_transport ' ,
' fetch_from ' : ' driver.full_name ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' lr_date ' ,
' label ' : ' Transport Receipt Date ' ,
' fieldtype ' : ' Date ' ,
' insert_after ' : ' driver_name ' ,
' default ' : ' Today ' ,
2018-10-10 09:21:26 +00:00
' print_hide ' : 1
} ,
{
' fieldname ' : ' gst_vehicle_type ' ,
' label ' : ' GST Vehicle Type ' ,
' fieldtype ' : ' Select ' ,
2019-07-03 05:04:31 +00:00
' options ' : ' Regular \n Over Dimensional Cargo (ODC) ' ,
2018-10-10 09:21:26 +00:00
' depends_on ' : ' eval:(doc.mode_of_transport === " Road " ) ' ,
2019-07-03 05:04:31 +00:00
' default ' : ' Regular ' ,
' insert_after ' : ' lr_date ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' ewaybill ' ,
2020-02-18 06:58:41 +00:00
' label ' : ' E-Way Bill No. ' ,
2019-07-03 05:04:31 +00:00
' fieldtype ' : ' Data ' ,
2021-08-20 05:40:46 +00:00
' depends_on ' : ' eval:(doc.docstatus === 1) ' ,
2019-07-03 05:04:31 +00:00
' allow_on_submit ' : 1 ,
2019-07-14 12:45:19 +00:00
' insert_after ' : ' tax_id ' ,
2019-07-03 05:04:31 +00:00
' translatable ' : 0
2018-10-10 09:21:26 +00:00
}
]
2021-09-02 13:26:04 +00:00
payment_entry_fields = [
dict ( fieldname = ' gst_section ' , label = ' GST Details ' , fieldtype = ' Section Break ' , insert_after = ' deductions ' ,
print_hide = 1 , collapsible = 1 ) ,
dict ( fieldname = ' company_address ' , label = ' Company Address ' , fieldtype = ' Link ' , insert_after = ' gst_section ' ,
print_hide = 1 , options = ' Address ' ) ,
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
fieldtype = ' Data ' , insert_after = ' company_address ' ,
fetch_from = ' company_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
dict ( fieldname = ' place_of_supply ' , label = ' Place of Supply ' ,
fieldtype = ' Data ' , insert_after = ' company_gstin ' ,
print_hide = 1 , read_only = 1 ) ,
dict ( fieldname = ' gst_column_break ' , fieldtype = ' Column Break ' ,
insert_after = ' place_of_supply ' ) ,
dict ( fieldname = ' customer_address ' , label = ' Customer Address ' , fieldtype = ' Link ' , insert_after = ' gst_column_break ' ,
print_hide = 1 , options = ' Address ' , depends_on = ' eval:doc.party_type == " Customer " ' ) ,
dict ( fieldname = ' customer_gstin ' , label = ' Customer GSTIN ' ,
fieldtype = ' Data ' , insert_after = ' customer_address ' ,
fetch_from = ' customer_address.gstin ' , print_hide = 1 , read_only = 1 )
]
2017-08-21 02:58:55 +00:00
custom_fields = {
' Address ' : [
dict ( fieldname = ' gstin ' , label = ' Party GSTIN ' , fieldtype = ' Data ' ,
insert_after = ' fax ' ) ,
dict ( fieldname = ' gst_state ' , label = ' GST State ' , fieldtype = ' Select ' ,
options = ' \n ' . join ( states ) , insert_after = ' gstin ' ) ,
dict ( fieldname = ' gst_state_number ' , label = ' GST State Number ' ,
2018-09-07 10:44:44 +00:00
fieldtype = ' Data ' , insert_after = ' gst_state ' , read_only = 1 ) ,
2017-06-21 11:52:38 +00:00
] ,
2019-03-21 15:17:47 +00:00
' Purchase Invoice ' : purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_fields ,
2019-01-09 11:39:11 +00:00
' Purchase Order ' : purchase_invoice_gst_fields ,
' Purchase Receipt ' : purchase_invoice_gst_fields ,
2021-08-20 05:40:46 +00:00
' Sales Invoice ' : sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields ,
2021-03-29 14:19:52 +00:00
' Delivery Note ' : sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category ,
2021-07-15 10:06:54 +00:00
' Payment Entry ' : payment_entry_fields ,
2021-05-14 06:47:41 +00:00
' Journal Entry ' : journal_entry_fields ,
2019-01-09 11:39:11 +00:00
' Sales Order ' : sales_invoice_gst_fields ,
2019-12-10 10:25:05 +00:00
' Tax Category ' : inter_state_gst_field ,
2017-06-21 11:52:38 +00:00
' Item ' : [
2017-07-06 09:19:34 +00:00
dict ( fieldname = ' gst_hsn_code ' , label = ' HSN/SAC ' ,
2017-06-21 11:52:38 +00:00
fieldtype = ' Link ' , options = ' GST HSN Code ' , insert_after = ' item_group ' ) ,
2020-04-21 07:43:39 +00:00
dict ( fieldname = ' is_nil_exempt ' , label = ' Is Nil Rated or Exempted ' ,
2019-03-21 15:17:47 +00:00
fieldtype = ' Check ' , insert_after = ' gst_hsn_code ' ) ,
dict ( fieldname = ' is_non_gst ' , label = ' Is Non GST ' ,
fieldtype = ' Check ' , insert_after = ' is_nil_exempt ' )
2017-06-21 11:52:38 +00:00
] ,
2019-03-21 15:17:47 +00:00
' Quotation Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
' Supplier Quotation Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
' Sales Order Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
' Delivery Note Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
2021-04-12 05:25:43 +00:00
' Sales Invoice Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst , taxable_value ] ,
2019-03-21 15:17:47 +00:00
' Purchase Order Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
' Purchase Receipt Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
2021-05-14 06:47:41 +00:00
' Purchase Invoice Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst , taxable_value ] ,
2019-04-01 14:08:43 +00:00
' Material Request Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
2020-06-19 13:47:57 +00:00
' Salary Component ' : [
dict ( fieldname = ' component_type ' ,
label = ' Component Type ' ,
fieldtype = ' Select ' ,
insert_after = ' description ' ,
options = " \n Provident Fund \n Additional Provident Fund \n Provident Fund Loan \n Professional Tax " ,
depends_on = ' eval:doc.type == " Deduction " '
)
] ,
2018-04-05 09:24:51 +00:00
' Employee ' : [
2020-06-19 13:47:57 +00:00
dict ( fieldname = ' ifsc_code ' ,
label = ' IFSC Code ' ,
fieldtype = ' Data ' ,
insert_after = ' bank_ac_no ' ,
print_hide = 1 ,
depends_on = ' eval:doc.salary_mode == " Bank " '
) ,
dict (
fieldname = ' pan_number ' ,
label = ' PAN Number ' ,
fieldtype = ' Data ' ,
insert_after = ' payroll_cost_center ' ,
print_hide = 1
) ,
dict (
fieldname = ' micr_code ' ,
label = ' MICR Code ' ,
fieldtype = ' Data ' ,
insert_after = ' ifsc_code ' ,
print_hide = 1 ,
depends_on = ' eval:doc.salary_mode == " Bank " '
) ,
dict (
fieldname = ' provident_fund_account ' ,
label = ' Provident Fund Account ' ,
fieldtype = ' Data ' ,
insert_after = ' pan_number '
)
2018-06-14 12:26:16 +00:00
] ,
' Company ' : [
dict ( fieldname = ' hra_section ' , label = ' HRA Settings ' ,
2019-06-14 09:55:57 +00:00
fieldtype = ' Section Break ' , insert_after = ' asset_received_but_not_billed ' , collapsible = 1 ) ,
2018-07-01 11:12:38 +00:00
dict ( fieldname = ' basic_component ' , label = ' Basic Component ' ,
2018-06-14 12:26:16 +00:00
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' hra_section ' ) ,
2018-07-01 11:12:38 +00:00
dict ( fieldname = ' hra_component ' , label = ' HRA Component ' ,
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' basic_component ' ) ,
2021-08-24 11:53:14 +00:00
dict ( fieldname = ' hra_column_break ' , fieldtype = ' Column Break ' , insert_after = ' hra_component ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' arrear_component ' , label = ' Arrear Component ' ,
2019-05-06 10:54:10 +00:00
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' hra_component ' ) ,
2021-03-11 07:49:44 +00:00
dict ( fieldname = ' non_profit_section ' , label = ' Non Profit Settings ' ,
fieldtype = ' Section Break ' , insert_after = ' asset_received_but_not_billed ' , collapsible = 1 ) ,
dict ( fieldname = ' company_80g_number ' , label = ' 80G Number ' ,
fieldtype = ' Data ' , insert_after = ' non_profit_section ' ) ,
dict ( fieldname = ' with_effect_from ' , label = ' 80G With Effect From ' ,
fieldtype = ' Date ' , insert_after = ' company_80g_number ' ) ,
2021-08-24 11:53:14 +00:00
dict ( fieldname = ' non_profit_column_break ' , fieldtype = ' Column Break ' , insert_after = ' with_effect_from ' ) ,
2021-03-11 07:49:44 +00:00
dict ( fieldname = ' pan_details ' , label = ' PAN Number ' ,
fieldtype = ' Data ' , insert_after = ' with_effect_from ' )
2018-06-14 12:26:16 +00:00
] ,
' Employee Tax Exemption Declaration ' : [
dict ( fieldname = ' hra_section ' , label = ' HRA Exemption ' ,
fieldtype = ' Section Break ' , insert_after = ' declarations ' ) ,
dict ( fieldname = ' monthly_house_rent ' , label = ' Monthly House Rent ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' hra_section ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' rented_in_metro_city ' , label = ' Rented in Metro City ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Check ' , insert_after = ' monthly_house_rent ' , depends_on = ' monthly_house_rent ' ) ,
dict ( fieldname = ' salary_structure_hra ' , label = ' HRA as per Salary Structure ' ,
fieldtype = ' Currency ' , insert_after = ' rented_in_metro_city ' , read_only = 1 , depends_on = ' monthly_house_rent ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' hra_column_break ' , fieldtype = ' Column Break ' ,
2019-04-25 13:14:10 +00:00
insert_after = ' salary_structure_hra ' , depends_on = ' monthly_house_rent ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' annual_hra_exemption ' , label = ' Annual HRA Exemption ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' hra_column_break ' , read_only = 1 , depends_on = ' monthly_house_rent ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' monthly_hra_exemption ' , label = ' Monthly HRA Exemption ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' annual_hra_exemption ' , read_only = 1 , depends_on = ' monthly_house_rent ' )
2018-06-14 12:26:16 +00:00
] ,
' Employee Tax Exemption Proof Submission ' : [
dict ( fieldname = ' hra_section ' , label = ' HRA Exemption ' ,
fieldtype = ' Section Break ' , insert_after = ' tax_exemption_proofs ' ) ,
dict ( fieldname = ' house_rent_payment_amount ' , label = ' House Rent Payment Amount ' ,
fieldtype = ' Currency ' , insert_after = ' hra_section ' ) ,
dict ( fieldname = ' rented_in_metro_city ' , label = ' Rented in Metro City ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Check ' , insert_after = ' house_rent_payment_amount ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' rented_from_date ' , label = ' Rented From Date ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Date ' , insert_after = ' rented_in_metro_city ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' rented_to_date ' , label = ' Rented To Date ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Date ' , insert_after = ' rented_from_date ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' hra_column_break ' , fieldtype = ' Column Break ' ,
2019-04-25 13:14:10 +00:00
insert_after = ' rented_to_date ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' monthly_house_rent ' , label = ' Monthly House Rent ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' hra_column_break ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' monthly_hra_exemption ' , label = ' Monthly Eligible Amount ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' monthly_house_rent ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 12:26:16 +00:00
dict ( fieldname = ' total_eligible_hra_exemption ' , label = ' Total Eligible HRA Exemption ' ,
2019-04-25 13:14:10 +00:00
fieldtype = ' Currency ' , insert_after = ' monthly_hra_exemption ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' )
2018-10-10 09:21:26 +00:00
] ,
' Supplier ' : [
{
' fieldname ' : ' gst_transporter_id ' ,
' label ' : ' GST Transporter ID ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' supplier_type ' ,
' depends_on ' : ' eval:doc.is_transporter '
2019-03-21 15:17:47 +00:00
} ,
{
' fieldname ' : ' gst_category ' ,
' label ' : ' GST Category ' ,
' fieldtype ' : ' Select ' ,
' insert_after ' : ' gst_transporter_id ' ,
' options ' : ' Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n UIN Holders ' ,
' default ' : ' Unregistered '
2019-12-10 10:25:05 +00:00
} ,
{
' fieldname ' : ' export_type ' ,
' label ' : ' Export Type ' ,
' fieldtype ' : ' Select ' ,
' insert_after ' : ' gst_category ' ,
' depends_on ' : ' eval:in_list([ " SEZ " , " Overseas " ], doc.gst_category) ' ,
2021-08-16 07:48:39 +00:00
' options ' : ' \n With Payment of Tax \n Without Payment of Tax ' ,
' mandatory_depends_on ' : ' eval:in_list([ " SEZ " , " Overseas " ], doc.gst_category) '
2019-03-21 15:17:47 +00:00
}
] ,
' Customer ' : [
{
' fieldname ' : ' gst_category ' ,
' label ' : ' GST Category ' ,
' fieldtype ' : ' Select ' ,
' insert_after ' : ' customer_type ' ,
' options ' : ' Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n Consumer \n Deemed Export \n UIN Holders ' ,
' default ' : ' Unregistered '
2019-12-10 10:25:05 +00:00
} ,
{
' fieldname ' : ' export_type ' ,
' label ' : ' Export Type ' ,
' fieldtype ' : ' Select ' ,
' insert_after ' : ' gst_category ' ,
' depends_on ' : ' eval:in_list([ " SEZ " , " Overseas " , " Deemed Export " ], doc.gst_category) ' ,
2021-08-16 07:48:39 +00:00
' options ' : ' \n With Payment of Tax \n Without Payment of Tax ' ,
' mandatory_depends_on ' : ' eval:in_list([ " SEZ " , " Overseas " , " Deemed Export " ], doc.gst_category) '
2018-10-10 09:21:26 +00:00
}
2020-03-30 12:44:44 +00:00
] ,
2021-03-11 07:49:44 +00:00
' Member ' : [
{
' fieldname ' : ' pan_number ' ,
' label ' : ' PAN Details ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' email_id '
}
] ,
' Donor ' : [
2020-03-30 12:44:44 +00:00
{
' fieldname ' : ' pan_number ' ,
' label ' : ' PAN Details ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' email '
}
2018-06-14 12:26:16 +00:00
]
2017-06-21 11:52:38 +00:00
}
2019-03-21 15:17:47 +00:00
create_custom_fields ( custom_fields , update = update )
2017-07-20 08:02:01 +00:00
2018-05-11 07:46:16 +00:00
def make_fixtures ( company = None ) :
docs = [ ]
2021-05-02 06:52:16 +00:00
company = company or frappe . db . get_value ( " Global Defaults " , None , " default_company " )
2018-05-11 07:46:16 +00:00
set_salary_components ( docs )
2018-07-24 05:37:28 +00:00
set_tds_account ( docs , company )
2017-06-21 11:52:38 +00:00
for d in docs :
try :
doc = frappe . get_doc ( d )
doc . flags . ignore_permissions = True
doc . insert ( )
except frappe . NameError :
2019-05-14 10:51:09 +00:00
frappe . clear_messages ( )
2018-08-01 12:15:05 +00:00
except frappe . DuplicateEntryError :
2019-05-14 10:51:09 +00:00
frappe . clear_messages ( )
2018-05-11 07:46:16 +00:00
2018-08-01 12:15:05 +00:00
# create records for Tax Withholding Category
2018-07-24 05:37:28 +00:00
set_tax_withholding_category ( company )
2021-06-02 07:56:21 +00:00
def update_regional_tax_settings ( country , company ) :
2021-05-02 16:59:48 +00:00
# Will only add default GST accounts if present
input_account_names = [ ' Input Tax CGST ' , ' Input Tax SGST ' , ' Input Tax IGST ' ]
output_account_names = [ ' Output Tax CGST ' , ' Output Tax SGST ' , ' Output Tax IGST ' ]
2021-05-29 18:24:51 +00:00
rcm_accounts = [ ' Input Tax CGST RCM ' , ' Input Tax SGST RCM ' , ' Input Tax IGST RCM ' ]
2021-05-02 16:59:48 +00:00
gst_settings = frappe . get_single ( ' GST Settings ' )
existing_account_list = [ ]
for account in gst_settings . get ( ' gst_accounts ' ) :
for key in [ ' cgst_account ' , ' sgst_account ' , ' igst_account ' ] :
existing_account_list . append ( account . get ( key ) )
gst_accounts = frappe . _dict ( frappe . get_all ( " Account " ,
2021-05-29 18:24:51 +00:00
{ ' company ' : company , ' account_name ' : ( ' in ' , input_account_names +
output_account_names + rcm_accounts ) } , [ ' account_name ' , ' name ' ] , as_list = 1 ) )
2021-05-02 16:59:48 +00:00
2021-05-29 18:24:51 +00:00
add_accounts_in_gst_settings ( company , input_account_names , gst_accounts ,
existing_account_list , gst_settings )
add_accounts_in_gst_settings ( company , output_account_names , gst_accounts ,
existing_account_list , gst_settings )
add_accounts_in_gst_settings ( company , rcm_accounts , gst_accounts ,
existing_account_list , gst_settings , is_reverse_charge = 1 )
2021-05-02 16:59:48 +00:00
2021-05-29 18:24:51 +00:00
gst_settings . save ( )
2021-05-02 16:59:48 +00:00
2021-05-29 18:24:51 +00:00
def add_accounts_in_gst_settings ( company , account_names , gst_accounts ,
existing_account_list , gst_settings , is_reverse_charge = 0 ) :
accounts_not_added = 1
2021-05-02 16:59:48 +00:00
2021-05-29 18:24:51 +00:00
for account in account_names :
# Default Account Added does not exists
2021-05-02 16:59:48 +00:00
if not gst_accounts . get ( account ) :
2021-05-29 18:24:51 +00:00
accounts_not_added = 0
2021-05-02 16:59:48 +00:00
# Check if already added in GST Settings
if gst_accounts . get ( account ) in existing_account_list :
2021-05-29 18:24:51 +00:00
accounts_not_added = 0
2021-05-02 16:59:48 +00:00
2021-05-29 18:24:51 +00:00
if accounts_not_added :
2021-05-02 16:59:48 +00:00
gst_settings . append ( ' gst_accounts ' , {
' company ' : company ,
2021-05-29 18:24:51 +00:00
' cgst_account ' : gst_accounts . get ( account_names [ 0 ] ) ,
' sgst_account ' : gst_accounts . get ( account_names [ 1 ] ) ,
' igst_account ' : gst_accounts . get ( account_names [ 2 ] ) ,
' is_reverse_charge_account ' : is_reverse_charge
2021-05-02 16:59:48 +00:00
} )
2018-05-11 07:46:16 +00:00
def set_salary_components ( docs ) :
docs . extend ( [
2020-04-26 12:15:57 +00:00
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' Professional Tax ' ,
' description ' : ' Professional Tax ' , ' type ' : ' Deduction ' , ' exempted_from_income_tax ' : 1 } ,
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' Provident Fund ' ,
' description ' : ' Provident fund ' , ' type ' : ' Deduction ' , ' is_tax_applicable ' : 1 } ,
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' House Rent Allowance ' ,
' description ' : ' House Rent Allowance ' , ' type ' : ' Earning ' , ' is_tax_applicable ' : 1 } ,
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' Basic ' ,
' description ' : ' Basic ' , ' type ' : ' Earning ' , ' is_tax_applicable ' : 1 } ,
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' Arrear ' ,
' description ' : ' Arrear ' , ' type ' : ' Earning ' , ' is_tax_applicable ' : 1 } ,
{ ' doctype ' : ' Salary Component ' , ' salary_component ' : ' Leave Encashment ' ,
' description ' : ' Leave Encashment ' , ' type ' : ' Earning ' , ' is_tax_applicable ' : 1 }
2018-05-11 07:46:16 +00:00
] )
2018-07-24 05:37:28 +00:00
def set_tax_withholding_category ( company ) :
2018-05-11 07:46:16 +00:00
accounts = [ ]
2021-01-14 13:54:30 +00:00
fiscal_year = None
2018-07-24 05:37:28 +00:00
abbr = frappe . get_value ( " Company " , company , " abbr " )
tds_account = frappe . get_value ( " Account " , ' TDS Payable - {0} ' . format ( abbr ) , ' name ' )
2018-05-11 07:46:16 +00:00
if company and tds_account :
2018-07-24 05:37:28 +00:00
accounts = [ dict ( company = company , account = tds_account ) ]
2018-05-11 07:46:16 +00:00
2021-01-14 13:54:30 +00:00
try :
fiscal_year = get_fiscal_year ( today ( ) , verbose = 0 , company = company ) [ 0 ]
except FiscalYearError :
pass
2018-08-01 12:15:05 +00:00
2021-01-14 13:54:30 +00:00
docs = get_tds_details ( accounts , fiscal_year )
2021-03-11 07:49:44 +00:00
2018-08-01 12:15:05 +00:00
for d in docs :
2021-04-21 15:12:20 +00:00
if not frappe . db . exists ( " Tax Withholding Category " , d . get ( " name " ) ) :
2018-08-01 12:15:05 +00:00
doc = frappe . get_doc ( d )
2021-04-30 11:05:52 +00:00
doc . flags . ignore_validate = True
2018-08-01 12:15:05 +00:00
doc . flags . ignore_permissions = True
2019-02-12 05:58:20 +00:00
doc . flags . ignore_mandatory = True
2018-08-01 12:15:05 +00:00
doc . insert ( )
2021-04-21 15:12:20 +00:00
else :
2021-07-12 12:59:52 +00:00
doc = frappe . get_doc ( " Tax Withholding Category " , d . get ( " name " ) , for_update = True )
2019-03-23 05:00:12 +00:00
if accounts :
doc . append ( " accounts " , accounts [ 0 ] )
2018-08-01 12:15:05 +00:00
2021-01-14 13:54:30 +00:00
if fiscal_year :
# if fiscal year don't match with any of the already entered data, append rate row
fy_exist = [ k for k in doc . get ( ' rates ' ) if k . get ( ' fiscal_year ' ) == fiscal_year ]
if not fy_exist :
doc . append ( " rates " , d . get ( ' rates ' ) [ 0 ] )
2021-03-11 07:49:44 +00:00
2021-01-14 13:54:30 +00:00
doc . flags . ignore_permissions = True
2021-05-29 18:24:51 +00:00
doc . flags . ignore_validate = True
2021-01-14 13:54:30 +00:00
doc . flags . ignore_mandatory = True
2021-04-30 11:05:52 +00:00
doc . flags . ignore_links = True
2018-08-01 12:15:05 +00:00
doc . save ( )
2018-05-11 07:46:16 +00:00
def set_tds_account ( docs , company ) :
2018-11-20 11:16:25 +00:00
parent_account = frappe . db . get_value ( " Account " , filters = { " account_name " : " Duties and Taxes " , " company " : company } )
if parent_account :
docs . extend ( [
{
" doctype " : " Account " ,
" account_name " : " TDS Payable " ,
" account_type " : " Tax " ,
" parent_account " : parent_account ,
" company " : company
}
] )
2018-08-01 12:15:05 +00:00
def get_tds_details ( accounts , fiscal_year ) :
# bootstrap default tax withholding sections
return [
dict ( name = " TDS - 194C - Company " ,
category_name = " Payment to Contractors (Single / Aggregate) " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 2 ,
" single_threshold " : 30000 , " cumulative_threshold " : 100000 } ] ) ,
dict ( name = " TDS - 194C - Individual " ,
category_name = " Payment to Contractors (Single / Aggregate) " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 1 ,
" single_threshold " : 30000 , " cumulative_threshold " : 100000 } ] ) ,
dict ( name = " TDS - 194C - No PAN / Invalid PAN " ,
category_name = " Payment to Contractors (Single / Aggregate) " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 30000 , " cumulative_threshold " : 100000 } ] ) ,
dict ( name = " TDS - 194D - Company " ,
category_name = " Insurance Commission " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 5 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194D - Company Assessee " ,
category_name = " Insurance Commission " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194D - Individual " ,
category_name = " Insurance Commission " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 5 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194D - No PAN / Invalid PAN " ,
category_name = " Insurance Commission " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194DA - Company " ,
category_name = " Non-exempt payments made under a life insurance policy " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 1 ,
" single_threshold " : 100000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194DA - Individual " ,
category_name = " Non-exempt payments made under a life insurance policy " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 1 ,
" single_threshold " : 100000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194DA - No PAN / Invalid PAN " ,
category_name = " Non-exempt payments made under a life insurance policy " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 100000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194H - Company " ,
category_name = " Commission / Brokerage " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 5 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194H - Individual " ,
category_name = " Commission / Brokerage " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 5 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194H - No PAN / Invalid PAN " ,
category_name = " Commission / Brokerage " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 15000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent - Company " ,
category_name = " Rent " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent - Individual " ,
category_name = " Rent " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent - No PAN / Invalid PAN " ,
category_name = " Rent " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent/Machinery - Company " ,
category_name = " Rent-Plant / Machinery " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 2 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent/Machinery - Individual " ,
category_name = " Rent-Plant / Machinery " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 2 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194I - Rent/Machinery - No PAN / Invalid PAN " ,
category_name = " Rent-Plant / Machinery " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 180000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Professional Fees - Company " ,
category_name = " Professional Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 30000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Professional Fees - Individual " ,
category_name = " Professional Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 30000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Professional Fees - No PAN / Invalid PAN " ,
category_name = " Professional Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 30000 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Director Fees - Company " ,
category_name = " Director Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 0 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Director Fees - Individual " ,
category_name = " Director Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 0 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194J - Director Fees - No PAN / Invalid PAN " ,
category_name = " Director Fees " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 0 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194 - Dividends - Company " ,
category_name = " Dividends " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 2500 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194 - Dividends - Individual " ,
category_name = " Dividends " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 10 ,
" single_threshold " : 2500 , " cumulative_threshold " : 0 } ] ) ,
dict ( name = " TDS - 194 - Dividends - No PAN / Invalid PAN " ,
category_name = " Dividends " ,
doctype = " Tax Withholding Category " , accounts = accounts ,
rates = [ { " fiscal_year " : fiscal_year , " tax_withholding_rate " : 20 ,
" single_threshold " : 2500 , " cumulative_threshold " : 0 } ] )
2020-08-17 09:33:32 +00:00
]
2020-08-18 08:43:54 +00:00
def create_gratuity_rule ( ) :
2020-08-17 09:33:32 +00:00
# Standard Indain Gratuity Rule
2020-08-18 09:32:32 +00:00
if not frappe . db . exists ( " Gratuity Rule " , " Indian Standard Gratuity Rule " ) :
rule = frappe . new_doc ( " Gratuity Rule " )
rule . name = " Indian Standard Gratuity Rule "
rule . calculate_gratuity_amount_based_on = " Current Slab "
rule . work_experience_calculation_method = " Round Off Work Experience "
rule . minimum_year_for_gratuity = 5
fraction = 15 / 26
rule . append ( " gratuity_rule_slabs " , {
" from_year " : 0 ,
" to_year " : 0 ,
" fraction_of_applicable_earnings " : fraction
} )
rule . flags . ignore_mandatory = True
2021-04-01 10:02:37 +00:00
rule . save ( )
2021-04-30 11:05:52 +00:00
def update_accounts_settings_for_taxes ( ) :
if frappe . db . count ( ' Company ' ) == 1 :
2021-08-10 11:16:44 +00:00
frappe . db . set_value ( ' Accounts Settings ' , None , " add_taxes_from_item_tax_template " , 0 )