2017-06-21 17:22:38 +05:30
# 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 12:52:30 +05:30
from frappe . custom . doctype . custom_field . custom_field import create_custom_fields
2021-04-01 15:32:37 +05:30
from frappe . custom . doctype . property_setter . property_setter import make_property_setter
2019-01-24 17:55:44 +05:30
from frappe . permissions import add_permission , update_permission_property
2017-06-21 17:22:38 +05:30
from erpnext . regional . india import states
2021-01-14 19:24:30 +05:30
from erpnext . accounts . utils import get_fiscal_year , FiscalYearError
2018-08-01 17:45:05 +05:30
from frappe . utils import today
2017-06-21 17:22:38 +05:30
2017-06-27 18:05:17 +05:30
def setup ( company = None , patch = True ) :
2021-07-12 18:29:52 +05:30
# 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 17:19:56 +05:30
if not patch :
2018-11-13 15:56:15 +05:30
make_fixtures ( company )
2018-11-12 17:19:56 +05:30
# TODO: for all countries
2021-04-13 15:46:01 +05:30
def setup_company_independent_fixtures ( patch = False ) :
2017-06-21 17:22:38 +05:30
make_custom_fields ( )
2021-04-13 15:46:01 +05:30
make_property_setters ( patch = patch )
2017-06-21 17:22:38 +05:30
add_permissions ( )
2017-06-22 16:37:04 +05:30
add_custom_roles_for_reports ( )
2017-09-28 18:55:40 +05:30
frappe . enqueue ( ' erpnext.regional.india.setup.add_hsn_sac_codes ' , now = frappe . flags . in_test )
2020-08-18 14:13:54 +05:30
create_gratuity_rule ( )
2017-07-05 12:58:19 +05:30
add_print_formats ( )
2021-04-30 16:35:52 +05:30
update_accounts_settings_for_taxes ( )
2017-06-22 16:37:04 +05:30
2017-07-13 12:16:04 +05:30
def add_hsn_sac_codes ( ) :
2021-06-11 15:57:01 +05:30
if frappe . flags . in_test and frappe . flags . created_hsn_codes :
return
2017-07-13 12:16:04 +05:30
# HSN codes
2017-06-21 17:22:38 +05:30
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 12:16:04 +05:30
create_hsn_codes ( hsn_codes , code_field = " hsn_code " )
2017-09-04 11:14:04 +05:30
2017-07-13 12:16:04 +05:30
# 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 11:14:04 +05:30
2021-06-11 15:57:01 +05:30
if frappe . flags . in_test :
frappe . flags . created_hsn_codes = True
2017-07-13 12:16:04 +05:30
def create_hsn_codes ( data , code_field ) :
for d in data :
2017-09-27 15:31:30 +05:30
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 12:16:04 +05:30
hsn_code . db_insert ( )
2017-09-27 15:31:30 +05:30
except frappe . DuplicateEntryError :
pass
2017-06-21 17:22:38 +05:30
2017-06-22 16:37:04 +05:30
def add_custom_roles_for_reports ( ) :
for report_name in ( ' GST Sales Register ' , ' GST Purchase Register ' ,
2021-08-20 11:10:46 +05:30
' GST Itemised Sales Register ' , ' GST Itemised Purchase Register ' , ' Eway Bill ' ) :
2017-06-22 16:37:04 +05:30
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 19:17:57 +05:30
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 13:51:26 +05:30
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 17:22:38 +05:30
def add_permissions ( ) :
2021-08-20 11:10:46 +05:30
for doctype in ( ' GST HSN Code ' , ' GST Settings ' , ' GSTR 3B Report ' , ' Lower Deduction Certificate ' ) :
2017-06-21 17:22:38 +05:30
add_permission ( doctype , ' All ' , 0 )
2020-04-04 20:05:17 +05:30
for role in ( ' Accounts Manager ' , ' Accounts User ' , ' System Manager ' ) :
2020-02-03 15:40:35 +05:30
add_permission ( doctype , role , 0 )
update_permission_property ( doctype , role , 0 , ' write ' , 1 )
update_permission_property ( doctype , role , 0 , ' create ' , 1 )
2017-06-21 17:22:38 +05:30
2020-04-04 20:05:17 +05:30
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 12:58:19 +05:30
def add_print_formats ( ) :
frappe . reload_doc ( " regional " , " print_format " , " gst_tax_invoice " )
2017-12-16 10:53:53 +05:30
frappe . reload_doc ( " accounts " , " print_format " , " gst_pos_invoice " )
2021-03-03 12:33:48 +01: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 12:58:19 +05:30
2021-04-13 15:46:01 +05:30
def make_property_setters ( patch = False ) :
2021-04-01 15:32:37 +05:30
# GST rules do not allow for an invoice no. bigger than 16 characters
2021-05-14 12:17:41 +05:30
journal_entry_types = frappe . get_meta ( " Journal Entry " ) . get_options ( " voucher_type " ) . split ( " \n " ) + [ ' Reversal Of ITC ' ]
2021-07-12 18:29:52 +05:30
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 12:17:41 +05:30
2021-04-13 15:46:01 +05:30
if not patch :
2021-07-10 20:23:52 +05:30
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 12:17:41 +05:30
make_property_setter ( ' Journal Entry ' , ' voucher_type ' , ' options ' , ' \n ' . join ( journal_entry_types ) , ' ' )
2021-04-01 15:32:37 +05:30
2018-07-17 18:22:51 +05:30
def make_custom_fields ( update = True ) :
2017-07-06 14:49:34 +05:30
hsn_sac_field = dict ( fieldname = ' gst_hsn_code ' , label = ' HSN/SAC ' ,
2018-11-13 18:19:58 +05:30
fieldtype = ' Data ' , fetch_from = ' item_code.gst_hsn_code ' , insert_after = ' description ' ,
2019-04-01 11:51:54 +05:30
allow_on_submit = 1 , print_hide = 1 , fetch_if_empty = 1 )
2020-04-21 13:13:39 +05:30
nil_rated_exempt = dict ( fieldname = ' is_nil_exempt ' , label = ' Is Nil Rated or Exempted ' ,
2019-03-21 20:47:47 +05:30
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 10:55:43 +05:30
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 20:47:47 +05:30
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 20:56:51 +05:30
fieldtype = ' Select ' , insert_after = ' gst_section ' , print_hide = 1 ,
2019-05-01 14:18:21 +05:30
options = ' \n Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n UIN Holders ' ,
2019-12-10 15:55:05 +05:30
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 20:47:47 +05:30
]
sales_invoice_gst_category = [
2017-08-21 08:28:55 +05:30
dict ( fieldname = ' gst_section ' , label = ' GST Details ' , fieldtype = ' Section Break ' ,
2018-01-30 12:11:13 +05:30
insert_after = ' language ' , print_hide = 1 , collapsible = 1 ) ,
2019-03-21 20:47:47 +05:30
dict ( fieldname = ' gst_category ' , label = ' GST Category ' ,
2019-04-01 20:56:51 +05:30
fieldtype = ' Select ' , insert_after = ' gst_section ' , print_hide = 1 ,
2019-05-01 14:18:21 +05:30
options = ' \n Registered Regular \n Registered Composition \n Unregistered \n SEZ \n Overseas \n Consumer \n Deemed Export \n UIN Holders ' ,
2019-12-10 15:55:05 +05:30
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 20:47:47 +05:30
]
2021-03-29 19:49:52 +05:30
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 20:47:47 +05:30
invoice_gst_fields = [
2017-08-21 08:28:55 +05:30
dict ( fieldname = ' invoice_copy ' , label = ' Invoice Copy ' ,
2019-12-10 15:55:05 +05:30
fieldtype = ' Select ' , insert_after = ' export_type ' , print_hide = 1 , allow_on_submit = 1 ,
2017-08-21 08:28:55 +05:30
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 11:27:22 +05:30
fieldtype = ' Data ' , insert_after = ' export_type ' , print_hide = 1 ) ,
2018-02-14 17:44:06 +05:30
dict ( fieldname = ' gst_col_break ' , fieldtype = ' Column Break ' , insert_after = ' ecommerce_gstin ' ) ,
2018-01-26 11:27:22 +05:30
dict ( fieldname = ' reason_for_issuing_document ' , label = ' Reason For Issuing document ' ,
2018-02-05 16:09:51 +05:30
fieldtype = ' Select ' , insert_after = ' gst_col_break ' , print_hide = 1 ,
2018-02-14 17:44:06 +05:30
depends_on = ' eval:doc.is_return==1 ' ,
2018-02-12 16:54:13 +05:30
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 08:28:55 +05:30
]
2017-09-04 11:14:04 +05:30
2017-08-21 08:28:55 +05:30
purchase_invoice_gst_fields = [
2017-06-21 17:22:38 +05:30
dict ( fieldname = ' supplier_gstin ' , label = ' Supplier GSTIN ' ,
2017-06-22 16:37:04 +05:30
fieldtype = ' Data ' , insert_after = ' supplier_address ' ,
2019-12-10 15:55:05 +05:30
fetch_from = ' supplier_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2017-06-21 17:22:38 +05:30
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
2018-06-05 11:27:53 +05:30
fieldtype = ' Data ' , insert_after = ' shipping_address_display ' ,
2019-12-10 15:55:05 +05:30
fetch_from = ' shipping_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2018-02-05 16:09:51 +05:30
dict ( fieldname = ' place_of_supply ' , label = ' Place of Supply ' ,
fieldtype = ' Data ' , insert_after = ' shipping_address ' ,
2019-12-10 15:55:05 +05:30
print_hide = 1 , read_only = 1 ) ,
2019-01-09 17:09:11 +05:30
]
purchase_invoice_itc_fields = [
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' eligibility_for_itc ' , label = ' Eligibility For ITC ' ,
fieldtype = ' Select ' , insert_after = ' reason_for_issuing_document ' , print_hide = 1 ,
2021-05-14 12:17:41 +05:30
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 13:57:34 +05:30
dict ( fieldname = ' itc_integrated_tax ' , label = ' Availed ITC Integrated Tax ' ,
2021-05-14 12:17:41 +05:30
fieldtype = ' Currency ' , insert_after = ' eligibility_for_itc ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' itc_central_tax ' , label = ' Availed ITC Central Tax ' ,
2021-05-14 12:17:41 +05:30
fieldtype = ' Currency ' , insert_after = ' itc_integrated_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' itc_state_tax ' , label = ' Availed ITC State/UT Tax ' ,
2021-05-14 12:17:41 +05:30
fieldtype = ' Currency ' , insert_after = ' itc_central_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' itc_cess_amount ' , label = ' Availed ITC Cess ' ,
2021-05-14 12:17:41 +05:30
fieldtype = ' Currency ' , insert_after = ' itc_state_tax ' ,
options = ' Company:company:default_currency ' , print_hide = 1 ) ,
2017-08-21 08:28:55 +05:30
]
2017-09-04 11:14:04 +05:30
2017-08-21 08:28:55 +05:30
sales_invoice_gst_fields = [
2017-09-28 11:05:03 +05:30
dict ( fieldname = ' billing_address_gstin ' , label = ' Billing Address GSTIN ' ,
2019-12-10 15:55:05 +05:30
fieldtype = ' Data ' , insert_after = ' customer_address ' , read_only = 1 ,
2018-06-05 11:27:53 +05:30
fetch_from = ' customer_address.gstin ' , print_hide = 1 ) ,
2017-06-21 17:22:38 +05:30
dict ( fieldname = ' customer_gstin ' , label = ' Customer GSTIN ' ,
2018-06-05 11:27:53 +05:30
fieldtype = ' Data ' , insert_after = ' shipping_address_name ' ,
fetch_from = ' shipping_address_name.gstin ' , print_hide = 1 ) ,
2017-08-21 08:28:55 +05:30
dict ( fieldname = ' place_of_supply ' , label = ' Place of Supply ' ,
2018-01-10 17:48:03 +05:30
fieldtype = ' Data ' , insert_after = ' customer_gstin ' ,
2019-12-10 15:55:05 +05:30
print_hide = 1 , read_only = 1 ) ,
2017-06-21 17:22:38 +05:30
dict ( fieldname = ' company_gstin ' , label = ' Company GSTIN ' ,
2017-06-22 16:37:04 +05:30
fieldtype = ' Data ' , insert_after = ' company_address ' ,
2019-12-10 15:55:05 +05:30
fetch_from = ' company_address.gstin ' , print_hide = 1 , read_only = 1 ) ,
2019-01-09 17:09:11 +05:30
]
sales_invoice_shipping_fields = [
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' port_code ' , label = ' Port Code ' ,
fieldtype = ' Data ' , insert_after = ' reason_for_issuing_document ' , print_hide = 1 ,
2019-03-21 20:47:47 +05:30
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' shipping_bill_number ' , label = ' Shipping Bill Number ' ,
fieldtype = ' Data ' , insert_after = ' port_code ' , print_hide = 1 ,
2019-03-21 20:47:47 +05:30
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2018-01-29 13:57:34 +05:30
dict ( fieldname = ' shipping_bill_date ' , label = ' Shipping Bill Date ' ,
fieldtype = ' Date ' , insert_after = ' shipping_bill_number ' , print_hide = 1 ,
2019-03-21 20:47:47 +05:30
depends_on = " eval:doc.gst_category== ' Overseas ' " ) ,
2017-08-21 08:28:55 +05:30
]
2017-09-04 11:14:04 +05:30
2021-05-14 12:17:41 +05:30
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 11:27:53 +05:30
inter_state_gst_field = [
dict ( fieldname = ' is_inter_state ' , label = ' Is Inter State ' ,
2019-12-10 15:55:05 +05:30
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 11:27:53 +05:30
]
2018-10-10 14:51:26 +05:30
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 10:34:31 +05:30
' 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 14:51:26 +05:30
' insert_after ' : ' transporter_name ' ,
2019-07-03 10:34:31 +05:30
' 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 12:28:41 +05:30
} ,
{
' 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 19:49:52 +05:30
}
2019-07-03 10:34:31 +05:30
]
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 14:51:26 +05:30
' fetch_from ' : ' transporter.gst_transporter_id ' ,
2019-07-03 10:34:31 +05:30
' 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 14:51:26 +05:30
' print_hide ' : 1
} ,
2019-07-03 10:34:31 +05:30
{
' 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 14:51:26 +05:30
{
' fieldname ' : ' mode_of_transport ' ,
' label ' : ' Mode of Transport ' ,
' fieldtype ' : ' Select ' ,
' options ' : ' \n Road \n Air \n Rail \n Ship ' ,
2019-07-03 10:34:31 +05:30
' 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 14:51:26 +05:30
' print_hide ' : 1
} ,
{
' fieldname ' : ' gst_vehicle_type ' ,
' label ' : ' GST Vehicle Type ' ,
' fieldtype ' : ' Select ' ,
2019-07-03 10:34:31 +05:30
' options ' : ' Regular \n Over Dimensional Cargo (ODC) ' ,
2018-10-10 14:51:26 +05:30
' depends_on ' : ' eval:(doc.mode_of_transport === " Road " ) ' ,
2019-07-03 10:34:31 +05:30
' default ' : ' Regular ' ,
' insert_after ' : ' lr_date ' ,
' print_hide ' : 1 ,
' translatable ' : 0
} ,
{
' fieldname ' : ' ewaybill ' ,
2020-02-18 12:28:41 +05:30
' label ' : ' E-Way Bill No. ' ,
2019-07-03 10:34:31 +05:30
' fieldtype ' : ' Data ' ,
2021-08-20 11:10:46 +05:30
' depends_on ' : ' eval:(doc.docstatus === 1) ' ,
2019-07-03 10:34:31 +05:30
' allow_on_submit ' : 1 ,
2019-07-14 18:15:19 +05:30
' insert_after ' : ' tax_id ' ,
2019-07-03 10:34:31 +05:30
' translatable ' : 0
2018-10-10 14:51:26 +05:30
}
]
2017-08-21 08:28:55 +05:30
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 16:14:44 +05:30
fieldtype = ' Data ' , insert_after = ' gst_state ' , read_only = 1 ) ,
2017-06-21 17:22:38 +05:30
] ,
2019-03-21 20:47:47 +05:30
' Purchase Invoice ' : purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_fields ,
2019-01-09 17:09:11 +05:30
' Purchase Order ' : purchase_invoice_gst_fields ,
' Purchase Receipt ' : purchase_invoice_gst_fields ,
2021-08-20 11:10:46 +05:30
' Sales Invoice ' : sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields ,
2021-03-29 19:49:52 +05:30
' Delivery Note ' : sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category ,
2021-05-14 12:17:41 +05:30
' Journal Entry ' : journal_entry_fields ,
2019-01-09 17:09:11 +05:30
' Sales Order ' : sales_invoice_gst_fields ,
2019-12-10 15:55:05 +05:30
' Tax Category ' : inter_state_gst_field ,
2017-06-21 17:22:38 +05:30
' Item ' : [
2017-07-06 14:49:34 +05:30
dict ( fieldname = ' gst_hsn_code ' , label = ' HSN/SAC ' ,
2017-06-21 17:22:38 +05:30
fieldtype = ' Link ' , options = ' GST HSN Code ' , insert_after = ' item_group ' ) ,
2020-04-21 13:13:39 +05:30
dict ( fieldname = ' is_nil_exempt ' , label = ' Is Nil Rated or Exempted ' ,
2019-03-21 20:47:47 +05:30
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 17:22:38 +05:30
] ,
2019-03-21 20:47:47 +05:30
' 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 10:55:43 +05:30
' Sales Invoice Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst , taxable_value ] ,
2019-03-21 20:47:47 +05:30
' 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 12:17:41 +05:30
' Purchase Invoice Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst , taxable_value ] ,
2019-04-01 19:38:43 +05:30
' Material Request Item ' : [ hsn_sac_field , nil_rated_exempt , is_non_gst ] ,
2020-06-19 19:17:57 +05:30
' 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 14:54:51 +05:30
' Employee ' : [
2020-06-19 19:17:57 +05:30
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 17:56:16 +05:30
] ,
' Company ' : [
dict ( fieldname = ' hra_section ' , label = ' HRA Settings ' ,
2019-06-14 15:25:57 +05:30
fieldtype = ' Section Break ' , insert_after = ' asset_received_but_not_billed ' , collapsible = 1 ) ,
2018-07-01 16:42:38 +05:30
dict ( fieldname = ' basic_component ' , label = ' Basic Component ' ,
2018-06-14 17:56:16 +05:30
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' hra_section ' ) ,
2018-07-01 16:42:38 +05:30
dict ( fieldname = ' hra_component ' , label = ' HRA Component ' ,
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' basic_component ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' arrear_component ' , label = ' Arrear Component ' ,
2019-05-06 16:24:10 +05:30
fieldtype = ' Link ' , options = ' Salary Component ' , insert_after = ' hra_component ' ) ,
2021-03-11 13:19:44 +05:30
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 ' ) ,
dict ( fieldname = ' pan_details ' , label = ' PAN Number ' ,
fieldtype = ' Data ' , insert_after = ' with_effect_from ' )
2018-06-14 17:56:16 +05:30
] ,
' 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 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' hra_section ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' rented_in_metro_city ' , label = ' Rented in Metro City ' ,
2019-04-25 18:44:10 +05:30
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 17:56:16 +05:30
dict ( fieldname = ' hra_column_break ' , fieldtype = ' Column Break ' ,
2019-04-25 18:44:10 +05:30
insert_after = ' salary_structure_hra ' , depends_on = ' monthly_house_rent ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' annual_hra_exemption ' , label = ' Annual HRA Exemption ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' hra_column_break ' , read_only = 1 , depends_on = ' monthly_house_rent ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' monthly_hra_exemption ' , label = ' Monthly HRA Exemption ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' annual_hra_exemption ' , read_only = 1 , depends_on = ' monthly_house_rent ' )
2018-06-14 17:56:16 +05:30
] ,
' 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 18:44:10 +05:30
fieldtype = ' Check ' , insert_after = ' house_rent_payment_amount ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' rented_from_date ' , label = ' Rented From Date ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Date ' , insert_after = ' rented_in_metro_city ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' rented_to_date ' , label = ' Rented To Date ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Date ' , insert_after = ' rented_from_date ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' hra_column_break ' , fieldtype = ' Column Break ' ,
2019-04-25 18:44:10 +05:30
insert_after = ' rented_to_date ' , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' monthly_house_rent ' , label = ' Monthly House Rent ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' hra_column_break ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' monthly_hra_exemption ' , label = ' Monthly Eligible Amount ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' monthly_house_rent ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' ) ,
2018-06-14 17:56:16 +05:30
dict ( fieldname = ' total_eligible_hra_exemption ' , label = ' Total Eligible HRA Exemption ' ,
2019-04-25 18:44:10 +05:30
fieldtype = ' Currency ' , insert_after = ' monthly_hra_exemption ' , read_only = 1 , depends_on = ' house_rent_payment_amount ' )
2018-10-10 14:51:26 +05:30
] ,
' Supplier ' : [
{
' fieldname ' : ' gst_transporter_id ' ,
' label ' : ' GST Transporter ID ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' supplier_type ' ,
' depends_on ' : ' eval:doc.is_transporter '
2019-03-21 20:47:47 +05:30
} ,
{
' 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 15:55:05 +05:30
} ,
{
' 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 13:18:39 +05:30
' 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 20:47:47 +05:30
}
] ,
' 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 15:55:05 +05:30
} ,
{
' 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 13:18:39 +05:30
' 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 14:51:26 +05:30
}
2020-03-30 18:14:44 +05:30
] ,
2021-03-11 13:19:44 +05:30
' Member ' : [
{
' fieldname ' : ' pan_number ' ,
' label ' : ' PAN Details ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' email_id '
}
] ,
' Donor ' : [
2020-03-30 18:14:44 +05:30
{
' fieldname ' : ' pan_number ' ,
' label ' : ' PAN Details ' ,
' fieldtype ' : ' Data ' ,
' insert_after ' : ' email '
}
2018-06-14 17:56:16 +05:30
]
2017-06-21 17:22:38 +05:30
}
2019-03-21 20:47:47 +05:30
create_custom_fields ( custom_fields , update = update )
2017-07-20 13:32:01 +05:30
2018-05-11 13:16:16 +05:30
def make_fixtures ( company = None ) :
docs = [ ]
2021-05-02 12:22:16 +05:30
company = company or frappe . db . get_value ( " Global Defaults " , None , " default_company " )
2018-05-11 13:16:16 +05:30
set_salary_components ( docs )
2018-07-24 11:07:28 +05:30
set_tds_account ( docs , company )
2017-06-21 17:22:38 +05:30
for d in docs :
try :
doc = frappe . get_doc ( d )
doc . flags . ignore_permissions = True
doc . insert ( )
except frappe . NameError :
2019-05-14 16:21:09 +05:30
frappe . clear_messages ( )
2018-08-01 17:45:05 +05:30
except frappe . DuplicateEntryError :
2019-05-14 16:21:09 +05:30
frappe . clear_messages ( )
2018-05-11 13:16:16 +05:30
2018-08-01 17:45:05 +05:30
# create records for Tax Withholding Category
2018-07-24 11:07:28 +05:30
set_tax_withholding_category ( company )
2021-06-02 13:26:21 +05:30
def update_regional_tax_settings ( country , company ) :
2021-05-02 22:29:48 +05:30
# 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 23:54:51 +05:30
rcm_accounts = [ ' Input Tax CGST RCM ' , ' Input Tax SGST RCM ' , ' Input Tax IGST RCM ' ]
2021-05-02 22:29:48 +05:30
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 23:54:51 +05:30
{ ' company ' : company , ' account_name ' : ( ' in ' , input_account_names +
output_account_names + rcm_accounts ) } , [ ' account_name ' , ' name ' ] , as_list = 1 ) )
2021-05-02 22:29:48 +05:30
2021-05-29 23:54:51 +05:30
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 22:29:48 +05:30
2021-05-29 23:54:51 +05:30
gst_settings . save ( )
2021-05-02 22:29:48 +05:30
2021-05-29 23:54:51 +05:30
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 22:29:48 +05:30
2021-05-29 23:54:51 +05:30
for account in account_names :
# Default Account Added does not exists
2021-05-02 22:29:48 +05:30
if not gst_accounts . get ( account ) :
2021-05-29 23:54:51 +05:30
accounts_not_added = 0
2021-05-02 22:29:48 +05:30
# Check if already added in GST Settings
if gst_accounts . get ( account ) in existing_account_list :
2021-05-29 23:54:51 +05:30
accounts_not_added = 0
2021-05-02 22:29:48 +05:30
2021-05-29 23:54:51 +05:30
if accounts_not_added :
2021-05-02 22:29:48 +05:30
gst_settings . append ( ' gst_accounts ' , {
' company ' : company ,
2021-05-29 23:54:51 +05:30
' 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 22:29:48 +05:30
} )
2018-05-11 13:16:16 +05:30
def set_salary_components ( docs ) :
docs . extend ( [
2020-04-26 17:45:57 +05:30
{ ' 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 13:16:16 +05:30
] )
2018-07-24 11:07:28 +05:30
def set_tax_withholding_category ( company ) :
2018-05-11 13:16:16 +05:30
accounts = [ ]
2021-01-14 19:24:30 +05:30
fiscal_year = None
2018-07-24 11:07:28 +05:30
abbr = frappe . get_value ( " Company " , company , " abbr " )
tds_account = frappe . get_value ( " Account " , ' TDS Payable - {0} ' . format ( abbr ) , ' name ' )
2018-05-11 13:16:16 +05:30
if company and tds_account :
2018-07-24 11:07:28 +05:30
accounts = [ dict ( company = company , account = tds_account ) ]
2018-05-11 13:16:16 +05:30
2021-01-14 19:24:30 +05:30
try :
fiscal_year = get_fiscal_year ( today ( ) , verbose = 0 , company = company ) [ 0 ]
except FiscalYearError :
pass
2018-08-01 17:45:05 +05:30
2021-01-14 19:24:30 +05:30
docs = get_tds_details ( accounts , fiscal_year )
2021-03-11 13:19:44 +05:30
2018-08-01 17:45:05 +05:30
for d in docs :
2021-04-21 20:42:20 +05:30
if not frappe . db . exists ( " Tax Withholding Category " , d . get ( " name " ) ) :
2018-08-01 17:45:05 +05:30
doc = frappe . get_doc ( d )
2021-04-30 16:35:52 +05:30
doc . flags . ignore_validate = True
2018-08-01 17:45:05 +05:30
doc . flags . ignore_permissions = True
2019-02-12 11:28:20 +05:30
doc . flags . ignore_mandatory = True
2018-08-01 17:45:05 +05:30
doc . insert ( )
2021-04-21 20:42:20 +05:30
else :
2021-07-12 18:29:52 +05:30
doc = frappe . get_doc ( " Tax Withholding Category " , d . get ( " name " ) , for_update = True )
2019-03-23 10:30:12 +05:30
if accounts :
doc . append ( " accounts " , accounts [ 0 ] )
2018-08-01 17:45:05 +05:30
2021-01-14 19:24:30 +05:30
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 13:19:44 +05:30
2021-01-14 19:24:30 +05:30
doc . flags . ignore_permissions = True
2021-05-29 23:54:51 +05:30
doc . flags . ignore_validate = True
2021-01-14 19:24:30 +05:30
doc . flags . ignore_mandatory = True
2021-04-30 16:35:52 +05:30
doc . flags . ignore_links = True
2018-08-01 17:45:05 +05:30
doc . save ( )
2018-05-11 13:16:16 +05:30
def set_tds_account ( docs , company ) :
2018-11-20 16:46:25 +05:30
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 17:45:05 +05:30
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 15:03:32 +05:30
]
2020-08-18 14:13:54 +05:30
def create_gratuity_rule ( ) :
2020-08-17 15:03:32 +05:30
# Standard Indain Gratuity Rule
2020-08-18 15:02:32 +05:30
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 15:32:37 +05:30
rule . save ( )
2021-04-30 16:35:52 +05:30
def update_accounts_settings_for_taxes ( ) :
if frappe . db . count ( ' Company ' ) == 1 :
2021-08-10 16:46:44 +05:30
frappe . db . set_value ( ' Accounts Settings ' , None , " add_taxes_from_item_tax_template " , 0 )