diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 6b4e8c4dd..f38f081cc 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -18,7 +18,7 @@ jobs:
- name: Deploy to dev
uses: appleboy/ssh-action@master
with:
- host: ${{ secrets.DEV_HOST }}
+ host: ${{ secrets.UAT_HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.DEV_KEY }}
port: 22
diff --git a/beams/api/api.py b/beams/api/api.py
index b02671625..d5092b74f 100644
--- a/beams/api/api.py
+++ b/beams/api/api.py
@@ -1,21 +1,21 @@
-import frappe
import json
import re
-from frappe import _
+
+import frappe
from frappe.utils import getdate, now_datetime, time_diff
from hrms.api.roster import get_shifts
@frappe.whitelist(allow_guest=True)
def response(message, data, success, status_code):
- '''
- method to generates responses of an API
- args:
+ """
+ method to generates responses of an API
+ args:
message : response message string
data : json object of the data
success : True or False depending on the API response
status_code : status of the request
- '''
+ """
frappe.clear_messages()
frappe.local.response["message"] = message
frappe.local.response["data"] = data
@@ -23,44 +23,46 @@ def response(message, data, success, status_code):
frappe.local.response["http_status_code"] = status_code
return
+
@frappe.whitelist(allow_guest=True)
def login(login_id, password):
- '''
- API for user login
- args:
+ """
+ API for user login
+ args:
login_id : username/email of the user
password : user password
- '''
+ """
try:
login_manager = frappe.auth.LoginManager()
login_manager.authenticate(user=login_id, pwd=password)
login_manager.post_login()
except frappe.exceptions.AuthenticationError:
- return response( "Authentication Error!",{},False,400)
+ return response("Authentication Error!", {}, False, 400)
api_generate = generate_keys(frappe.session.user)
user = frappe.get_doc("User", frappe.session.user)
roles = frappe.get_roles(frappe.session.user)
frappe.local.response["message"] = {
- "success_key":1,
- "sid": frappe.session.sid,
- "api_key": user.api_key,
- "api_secret": api_generate,
- "is_active": user.enabled,
- "user_id": user.username,
- "name": user.full_name,
- "roles": roles,
- "msg": "Authentication Success"
- }
+ "success_key": 1,
+ "sid": frappe.session.sid,
+ "api_key": user.api_key,
+ "api_secret": api_generate,
+ "is_active": user.enabled,
+ "user_id": user.username,
+ "name": user.full_name,
+ "roles": roles,
+ "msg": "Authentication Success",
+ }
+
def generate_keys(user):
- '''
- method generates api secret for a user
- args:
+ """
+ method generates api secret for a user
+ args:
user : username of the user
- '''
+ """
user_details = frappe.get_doc("User", user)
- api_secret = frappe.generate_hash(length=15)
+ api_secret = frappe.generate_hash(length=15)
if not user_details.api_key:
api_key = frappe.generate_hash(length=15)
@@ -71,640 +73,938 @@ def generate_keys(user):
return api_secret
+
def strip_html_tags(text):
- '''
- Helper function to strip HTML tags from a string
- '''
+ """
+ Helper function to strip HTML tags from a string
+ """
from bs4 import BeautifulSoup
+
return BeautifulSoup(text, "html.parser").text
+
@frappe.whitelist()
def get_region_list(start=0, page_length=20, region=None):
- '''
- API to get List of Region
- '''
- region_fields = ['name as region_id', 'region']
+ """
+ API to get List of Region
+ """
+ region_fields = ["name as region_id", "region"]
if region:
- region_list = frappe.db.get_all('Region', filters={ 'region':['like', '%{0}%'.format(region)] }, fields=region_fields, start=start, page_length=page_length)
+ region_list = frappe.db.get_all(
+ "Region",
+ filters={"region": ["like", "%{0}%".format(region)]},
+ fields=region_fields,
+ start=start,
+ page_length=page_length,
+ )
else:
- region_list = frappe.db.get_all('Region', fields=region_fields, start=start, page_length=page_length)
+ region_list = frappe.db.get_all(
+ "Region", fields=region_fields, start=start, page_length=page_length
+ )
if region_list:
- return response('Data get successfully', region_list, True, 200)
+ return response("Data get successfully", region_list, True, 200)
else:
- return response('No Regions found', region_list, True, 200)
+ return response("No Regions found", region_list, True, 200)
+
@frappe.whitelist()
def get_agency_list(start=0, page_length=20, agency_name=None):
- '''
- API to get List of Agency
- '''
- agency_fields = ['name as agency_id', 'customer_name as agency_name', 'region', 'gstin', 'pan as pan_no', 'default_currency as currency', 'is_edited']
- filters = { 'is_agent':1 }
+ """
+ API to get List of Agency
+ """
+ agency_fields = [
+ "name as agency_id",
+ "customer_name as agency_name",
+ "region",
+ "gstin",
+ "pan as pan_no",
+ "default_currency as currency",
+ "is_edited",
+ ]
+ filters = {"is_agent": 1}
if agency_name:
- filters = { 'is_agent':1, 'customer_name':['like', '%{0}%'.format(agency_name)] }
- agency_list = frappe.db.get_all('Customer', filters=filters, fields=agency_fields, start=start, page_length=page_length)
+ filters = {
+ "is_agent": 1,
+ "customer_name": ["like", "%{0}%".format(agency_name)],
+ }
+ agency_list = frappe.db.get_all(
+ "Customer",
+ filters=filters,
+ fields=agency_fields,
+ start=start,
+ page_length=page_length,
+ )
if agency_list:
- return response('Data get successfully', get_customer_address(agency_list, 1), True, 200)
+ return response(
+ "Data get successfully", get_customer_address(agency_list, 1), True, 200
+ )
else:
- return response('No Agencies found', agency_list, True, 200)
+ return response("No Agencies found", agency_list, True, 200)
+
@frappe.whitelist()
def get_client_list(start=0, page_length=20, client_name=None):
- '''
- API to get List of Client
- '''
- client_fields = ['name as client_id', 'customer_name as client_name', 'region', 'gstin', 'pan as pan_no', 'default_currency as currency', 'is_edited']
- filters = { 'is_agent':0 }
+ """
+ API to get List of Client
+ """
+ client_fields = [
+ "name as client_id",
+ "customer_name as client_name",
+ "region",
+ "gstin",
+ "pan as pan_no",
+ "default_currency as currency",
+ "is_edited",
+ ]
+ filters = {"is_agent": 0}
if client_name:
- filters = { 'is_agent':0, 'customer_name':['like', '%{0}%'.format(client_name)] }
- client_list = frappe.db.get_all('Customer', filters=filters, fields=client_fields, start=start, page_length=page_length)
+ filters = {
+ "is_agent": 0,
+ "customer_name": ["like", "%{0}%".format(client_name)],
+ }
+ client_list = frappe.db.get_all(
+ "Customer",
+ filters=filters,
+ fields=client_fields,
+ start=start,
+ page_length=page_length,
+ )
if client_list:
- return response('Data get successfully', get_customer_address(client_list), True, 200)
+ return response(
+ "Data get successfully", get_customer_address(client_list), True, 200
+ )
else:
- return response('No Clients found', client_list, True, 200)
+ return response("No Clients found", client_list, True, 200)
+
@frappe.whitelist()
def get_customer_address(customer_list, agency=0):
- '''
- Method fetches address of customer and add it to the list
- Args:
+ """
+ Method fetches address of customer and add it to the list
+ Args:
customer_list (list): list of dicts fo customers
agency (int, optional): denotes whether the customer list of agents or not. Defaults to 0.
- Returns:
+ Returns:
list of dicts: customer list of dicts with address keys
- '''
+ """
for customer in customer_list:
- dynamic_link = frappe.db.exists('Dynamic Link', { 'parenttype':'Address', 'link_doctype':'Customer', 'link_name':customer.get('client_id') if not agency else customer.get('agency_id')})
- address = "" if not dynamic_link else frappe.db.get_value('Dynamic Link', dynamic_link, 'parent')
+ dynamic_link = frappe.db.exists(
+ "Dynamic Link",
+ {
+ "parenttype": "Address",
+ "link_doctype": "Customer",
+ "link_name": (
+ customer.get("client_id")
+ if not agency
+ else customer.get("agency_id")
+ ),
+ },
+ )
+ address = (
+ ""
+ if not dynamic_link
+ else frappe.db.get_value("Dynamic Link", dynamic_link, "parent")
+ )
address_data = {
"address_line_1": "",
"address_line_2": "",
"address_line_3": "",
"address_line_4": "",
- "pincode": ""
+ "pincode": "",
}
if address:
- address_data = frappe.db.get_all('Address', filters={ 'name':address }, fields=['address_line1 as address_line_1', 'address_line2 as address_line_2', 'city as address_line_3', 'state as address_line_4', 'pincode'])[0]
- customer["address_line_1"] = address_data.get('address_line_1')
- customer["address_line_2"] = address_data.get('address_line_2')
- customer["address_line_3"] = address_data.get('address_line_3')
- customer["address_line_4"] = address_data.get('address_line_4')
- customer["pincode"] = address_data.get('pincode')
+ address_data = frappe.db.get_all(
+ "Address",
+ filters={"name": address},
+ fields=[
+ "address_line1 as address_line_1",
+ "address_line2 as address_line_2",
+ "city as address_line_3",
+ "state as address_line_4",
+ "pincode",
+ ],
+ )[0]
+ customer["address_line_1"] = address_data.get("address_line_1")
+ customer["address_line_2"] = address_data.get("address_line_2")
+ customer["address_line_3"] = address_data.get("address_line_3")
+ customer["address_line_4"] = address_data.get("address_line_4")
+ customer["pincode"] = address_data.get("pincode")
return customer_list
+
def get_sales_taxes_and_charges_template(tax_rate, tax_category):
- '''
- Method to get Sales Taxes and Charges Template
- args:
+ """
+ Method to get Sales Taxes and Charges Template
+ args:
tax_rate : Tax Percentage
tax_category : Tax Category
- '''
+ """
tax_template = None
- tax_row = frappe.db.exists('Albatross GST Mapping', {
- "parent": "Albatross Settings",
- "tax_rate": int(tax_rate),
- "tax_category": tax_category,
- })
+ tax_row = frappe.db.exists(
+ "Albatross GST Mapping",
+ {
+ "parent": "Albatross Settings",
+ "tax_rate": int(tax_rate),
+ "tax_category": tax_category,
+ },
+ )
if tax_row:
- tax_template = frappe.db.get_value('Albatross GST Mapping', tax_row, 'tax_template')
+ tax_template = frappe.db.get_value(
+ "Albatross GST Mapping", tax_row, "tax_template"
+ )
return tax_template
+
@frappe.whitelist()
def get_currency_list(start=0, page_length=20, currency=None):
- '''
- API to get List of Currency
- '''
- currency_fields = ['currency_name', 'symbol']
+ """
+ API to get List of Currency
+ """
+ currency_fields = ["currency_name", "symbol"]
if currency:
- currency_list = frappe.db.get_all('Currency', filters={ 'currency_name':['like', '%{0}%'.format(currency)], 'enabled':1 }, fields=currency_fields, start=start, page_length=page_length)
+ currency_list = frappe.db.get_all(
+ "Currency",
+ filters={"currency_name": ["like", "%{0}%".format(currency)], "enabled": 1},
+ fields=currency_fields,
+ start=start,
+ page_length=page_length,
+ )
else:
- currency_list = frappe.db.get_all('Currency', filters={ 'enabled':1 }, fields=currency_fields, start=start, page_length=page_length)
+ currency_list = frappe.db.get_all(
+ "Currency",
+ filters={"enabled": 1},
+ fields=currency_fields,
+ start=start,
+ page_length=page_length,
+ )
if currency_list:
- return response('Data get successfully', currency_list, True, 200)
+ return response("Data get successfully", currency_list, True, 200)
else:
- return response('No Currency found', currency_list, True, 200)
+ return response("No Currency found", currency_list, True, 200)
+
@frappe.whitelist()
def get_employee_list(start=0, page_length=20, employee_name=None):
- '''
- API to get List of Employee
- '''
- employee_fields = ['name as employee_id', 'employee_name']
+ """
+ API to get List of Employee
+ """
+ employee_fields = ["name as employee_id", "employee_name"]
if employee_name:
- employee_list = frappe.db.get_all('Employee', filters={ 'employee_name':['like', '%{0}%'.format(employee_name)], 'status':'Active' }, fields=employee_fields, start=start, page_length=page_length)
+ employee_list = frappe.db.get_all(
+ "Employee",
+ filters={
+ "employee_name": ["like", "%{0}%".format(employee_name)],
+ "status": "Active",
+ },
+ fields=employee_fields,
+ start=start,
+ page_length=page_length,
+ )
else:
- employee_list = frappe.db.get_all('Employee', filters={ 'status':'Active' }, fields=employee_fields, start=start, page_length=page_length)
+ employee_list = frappe.db.get_all(
+ "Employee",
+ filters={"status": "Active"},
+ fields=employee_fields,
+ start=start,
+ page_length=page_length,
+ )
if employee_list:
- return response('Data get successfully', employee_list, True, 200)
+ return response("Data get successfully", employee_list, True, 200)
else:
- return response('No Employees found', employee_list, True, 200)
+ return response("No Employees found", employee_list, True, 200)
+
@frappe.whitelist()
def create_release_order():
- '''
- API to create Release Order
- args:
+ """
+ API to create Release Order
+ args:
JSON string of RO data like
{
- "ror_no": "M1/0142/2024-25",
- "ror_date": "2024-06-01",
- "ro_no": "766",
- "ro_date": "2024-05-31",
- "client_id": "Dias Idea Incubators",
- "agency_id": "efeone",
- "currency": "INR",
- "bill_to": "A",
- "option": "Associate Sponsorship",
- "product_name": "P M S College",
- "program_name": "News At 9",
- "no_of_eps": 0,
- "commission_per": 15,
- "fct_total": 50,
- "amount": 50000,
- "region": "Trivandrum",
- "executive_id": "HR-EMP-00012",
- "region_revenue_percentage": 100
+ "ror_no": "M1/0142/2024-25",
+ "ror_date": "2024-06-01",
+ "ro_no": "766",
+ "ro_date": "2024-05-31",
+ "client_id": "Dias Idea Incubators",
+ "agency_id": "efeone",
+ "currency": "INR",
+ "bill_to": "A",
+ "option": "Associate Sponsorship",
+ "product_name": "P M S College",
+ "program_name": "News At 9",
+ "no_of_eps": 0,
+ "commission_per": 15,
+ "fct_total": 50,
+ "amount": 50000,
+ "region": "Trivandrum",
+ "executive_id": "HR-EMP-00012",
+ "region_revenue_percentage": 100
}
- '''
+ """
try:
input_data = frappe.form_dict
- if input_data.get('cmd'):
- input_data.pop('cmd')
+ if input_data.get("cmd"):
+ input_data.pop("cmd")
- albatross_service_item = frappe.db.get_single_value('Albatross Settings', 'albatross_service_item')
+ albatross_service_item = frappe.db.get_single_value(
+ "Albatross Settings", "albatross_service_item"
+ )
if not albatross_service_item:
- return response('`albatross_service_item` is not configured in Albatross Settings', {}, False, 400)
-
- if not input_data.get('bill_to'):
- return response('`bill_to` is reuqired to create Release Order', {}, False, 400)
+ return response(
+ "`albatross_service_item` is not configured in Albatross Settings",
+ {},
+ False,
+ 400,
+ )
+
+ if not input_data.get("bill_to"):
+ return response(
+ "`bill_to` is reuqired to create Release Order", {}, False, 400
+ )
else:
- if not input_data.get('bill_to') in ['A', 'C']:
- return response('`bill_to` should be either `A` or `C`', {}, False, 400)
+ if input_data.get("bill_to") not in ["A", "C"]:
+ return response("`bill_to` should be either `A` or `C`", {}, False, 400)
# Checking Mandatory fields
- if not input_data.get('client_id'):
- return response('`client_id` is reuqired to create Release Order', {}, False, 400)
+ if not input_data.get("client_id"):
+ return response(
+ "`client_id` is reuqired to create Release Order", {}, False, 400
+ )
else:
- if not frappe.db.exists('Customer', input_data.get('client_id')):
- return response('Client : `{0}` does not exists'.format(input_data.get('client_id')), {}, False, 404)
-
- if input_data.get('bill_to') == 'A':
- if not input_data.get('agency_id'):
- return response('`agency_id` is reuqired to create Release Order', {}, False, 400)
+ if not frappe.db.exists("Customer", input_data.get("client_id")):
+ return response(
+ "Client : `{0}` does not exists".format(
+ input_data.get("client_id")
+ ),
+ {},
+ False,
+ 404,
+ )
+
+ if input_data.get("bill_to") == "A":
+ if not input_data.get("agency_id"):
+ return response(
+ "`agency_id` is reuqired to create Release Order", {}, False, 400
+ )
else:
- if not frappe.db.exists('Customer', input_data.get('agency_id')):
- return response('Agency : `{0}` does not exists'.format(input_data.get('agency_id')), {}, False, 404)
-
- if not input_data.get('ror_no'):
- return response('`ror_no` is reuqired to create Release Order', {}, False, 400)
-
- if not input_data.get('ror_date'):
- return response('`ror_date` is reuqired to create Release Order', {}, False, 400)
-
- if not input_data.get('ro_date'):
- return response('`ror_date` is reuqired to create Release Order', {}, False, 400)
-
- if not input_data.get('option'):
- return response('`option` is reuqired to create Release Order', {}, False, 400)
-
- if input_data.get('executive_id') and not frappe.db.exists('Employee', input_data.get('executive_id')):
- return response('Employee : `{0}` does not exists'.format(input_data.get('executive_id')), {}, False, 400)
-
- if not input_data.get('region_revenue_percentage'):
- return response('`region_revenue_percentage` is reuqired to create Release Order', {}, False, 400)
-
- if input_data.get('region') and not frappe.db.exists('Region', input_data.get('region')):
- return response('Region : `{0}` does not exists'.format(input_data.get('region')), {}, False, 400)
-
- if input_data.get('currency') and not frappe.db.exists('Currency', input_data.get('currency')):
- return response('Currency : `{0}` does not exists'.format(input_data.get('currency')), {}, False, 400)
+ if not frappe.db.exists("Customer", input_data.get("agency_id")):
+ return response(
+ "Agency : `{0}` does not exists".format(
+ input_data.get("agency_id")
+ ),
+ {},
+ False,
+ 404,
+ )
+
+ if not input_data.get("ror_no"):
+ return response(
+ "`ror_no` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if not input_data.get("ror_date"):
+ return response(
+ "`ror_date` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if not input_data.get("ro_date"):
+ return response(
+ "`ror_date` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if not input_data.get("option"):
+ return response(
+ "`option` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if input_data.get("executive_id") and not frappe.db.exists(
+ "Employee", input_data.get("executive_id")
+ ):
+ return response(
+ "Employee : `{0}` does not exists".format(
+ input_data.get("executive_id")
+ ),
+ {},
+ False,
+ 400,
+ )
+
+ if not input_data.get("region_revenue_percentage"):
+ return response(
+ "`region_revenue_percentage` is reuqired to create Release Order",
+ {},
+ False,
+ 400,
+ )
+
+ if input_data.get("region") and not frappe.db.exists(
+ "Region", input_data.get("region")
+ ):
+ return response(
+ "Region : `{0}` does not exists".format(input_data.get("region")),
+ {},
+ False,
+ 400,
+ )
+
+ if input_data.get("currency") and not frappe.db.exists(
+ "Currency", input_data.get("currency")
+ ):
+ return response(
+ "Currency : `{0}` does not exists".format(input_data.get("currency")),
+ {},
+ False,
+ 400,
+ )
# Creating Release Order
- ro_doc = frappe.new_doc('Quotation')
- ro_doc.transaction_date = getdate(input_data.get('ror_date'))
- ro_doc.quotation_to = 'Customer'
- if input_data.get('bill_to') == 'A':
- ro_doc.party_name = input_data.get('agency_id')
- ro_doc.actual_customer = input_data.get('client_id')
- elif input_data.get('bill_to') == 'C':
- ro_doc.party_name = input_data.get('client_id')
- ro_doc.region = input_data.get('region')
- ro_doc.executive = input_data.get('executive_id') or ''
- ro_doc.executive_name = input_data.get('executive_name') or ''
- ro_doc.albatross_ro_id = input_data.get('ror_no') or ''
- ro_doc.ro_no = input_data.get('ro_no') or ''
- ro_doc.ro_date = getdate(input_data.get('ro_date'))
- ro_doc.product_name = input_data.get('product_name') or ''
- ro_doc.program_name = input_data.get('program_name') or ''
- ro_doc.ro_option = input_data.get('option') or ''
- ro_doc.no_of_eps = input_data.get('no_of_eps') or 0
- ro_doc.commission_per = input_data.get('commission_per') or 0
- ro_doc.fct_total = input_data.get('fct_total') or 0
- ro_doc.region_revenue_percentage = input_data.get('region_revenue_percentage') or 0
- ro_item_row = ro_doc.append('items')
+ ro_doc = frappe.new_doc("Quotation")
+ ro_doc.transaction_date = getdate(input_data.get("ror_date"))
+ ro_doc.quotation_to = "Customer"
+ if input_data.get("bill_to") == "A":
+ ro_doc.party_name = input_data.get("agency_id")
+ ro_doc.actual_customer = input_data.get("client_id")
+ elif input_data.get("bill_to") == "C":
+ ro_doc.party_name = input_data.get("client_id")
+ ro_doc.region = input_data.get("region")
+ ro_doc.executive = input_data.get("executive_id") or ""
+ ro_doc.executive_name = input_data.get("executive_name") or ""
+ ro_doc.albatross_ro_id = input_data.get("ror_no") or ""
+ ro_doc.ro_no = input_data.get("ro_no") or ""
+ ro_doc.ro_date = getdate(input_data.get("ro_date"))
+ ro_doc.product_name = input_data.get("product_name") or ""
+ ro_doc.program_name = input_data.get("program_name") or ""
+ ro_doc.ro_option = input_data.get("option") or ""
+ ro_doc.no_of_eps = input_data.get("no_of_eps") or 0
+ ro_doc.commission_per = input_data.get("commission_per") or 0
+ ro_doc.fct_total = input_data.get("fct_total") or 0
+ ro_doc.region_revenue_percentage = (
+ input_data.get("region_revenue_percentage") or 0
+ )
+ ro_item_row = ro_doc.append("items")
ro_item_row.qty = 1
ro_item_row.item_code = albatross_service_item
- ro_item_row.rate = float(input_data.get('amount') or 0)
- ro_item_row.base_rate = float(input_data.get('amount') or 0)
+ ro_item_row.rate = float(input_data.get("amount") or 0)
+ ro_item_row.base_rate = float(input_data.get("amount") or 0)
ro_doc.ignore_mandatory = True
ro_doc.save(ignore_permissions=True)
frappe.clear_messages()
- return response('Created Release Order Successfully', ro_doc.as_dict(), True, 201)
+ return response(
+ "Created Release Order Successfully", ro_doc.as_dict(), True, 201
+ )
except frappe.exceptions.CharacterLengthExceededError as e:
- frappe.log_error("Character Length Exceeded", "Error in Release Order creation: " + str(e)[:120])
- return response('Character Length Exceeded in Error Log', {}, False, 400)
+ frappe.log_error(
+ "Character Length Exceeded",
+ "Error in Release Order creation: " + str(e)[:120],
+ )
+ return response("Character Length Exceeded in Error Log", {}, False, 400)
except Exception as exception:
frappe.log_error(frappe.get_traceback(), "Release Order Creation Error")
clean_exception_message = strip_html_tags(str(exception))
return response(f"An error occurred: {clean_exception_message}", {}, False, 400)
+
@frappe.whitelist()
def create_sales_order():
- '''
- API to create Sales Order
- args:
+ """
+ API to create Sales Order
+ args:
JSON string of Sales Order data like
{
- "date": "30-10-2024",
- "invoice_no": "LB/138",
- "client_id": "Dias Idea Incubators",
- "currency": "INR",
- "executive_id": "HR-EMP-00012",
- "taxable_value": 170000,
- "gst_rate": 18,
- "sgst": 15300,
- "cgst": 15300,
- "igst": 0,
- "ro_no": "CCPL/32/2024-25",
- "ref_no": "M1/0139/2024-25",
- "region": "Trivandrum"
+ "date": "30-10-2024",
+ "invoice_no": "LB/138",
+ "client_id": "Dias Idea Incubators",
+ "currency": "INR",
+ "executive_id": "HR-EMP-00012",
+ "taxable_value": 170000,
+ "gst_rate": 18,
+ "sgst": 15300,
+ "cgst": 15300,
+ "igst": 0,
+ "ro_no": "CCPL/32/2024-25",
+ "ref_no": "M1/0139/2024-25",
+ "region": "Trivandrum"
}
- '''
+ """
try:
input_data = frappe.form_dict
- if input_data.get('cmd'):
- input_data.pop('cmd')
+ if input_data.get("cmd"):
+ input_data.pop("cmd")
- albatross_service_item = frappe.db.get_single_value('Albatross Settings', 'albatross_service_item')
+ albatross_service_item = frappe.db.get_single_value(
+ "Albatross Settings", "albatross_service_item"
+ )
if not albatross_service_item:
- return response('`albatross_service_item` is not configured in Albatross Settings', {}, False, 400)
+ return response(
+ "`albatross_service_item` is not configured in Albatross Settings",
+ {},
+ False,
+ 400,
+ )
# Checking Mandatory fields
- if not input_data.get('date'):
- return response('`date` is reuqired to create Release Order', {}, False, 400)
-
- if not input_data.get('client_id'):
- return response('`client_id` is reuqired to create Release Order', {}, False, 400)
+ if not input_data.get("date"):
+ return response(
+ "`date` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if not input_data.get("client_id"):
+ return response(
+ "`client_id` is reuqired to create Release Order", {}, False, 400
+ )
else:
- if not frappe.db.exists('Customer', input_data.get('client_id')):
- return response('Client : `{0}` does not exists'.format(input_data.get('client_id')), {}, False, 404)
-
- if not input_data.get('taxable_value'):
- return response('`taxable_value` is reuqired to create Release Order', {}, False, 400)
-
- if input_data.get('currency') and not frappe.db.exists('Currency', input_data.get('currency')):
- return response('Currency : `{0}` does not exists'.format(input_data.get('currency')), {}, False, 400)
-
- if input_data.get('region') and not frappe.db.exists('Region', input_data.get('region')):
- return response('Region : `{0}` does not exists'.format(input_data.get('region')), {}, False, 400)
+ if not frappe.db.exists("Customer", input_data.get("client_id")):
+ return response(
+ "Client : `{0}` does not exists".format(
+ input_data.get("client_id")
+ ),
+ {},
+ False,
+ 404,
+ )
+
+ if not input_data.get("taxable_value"):
+ return response(
+ "`taxable_value` is reuqired to create Release Order", {}, False, 400
+ )
+
+ if input_data.get("currency") and not frappe.db.exists(
+ "Currency", input_data.get("currency")
+ ):
+ return response(
+ "Currency : `{0}` does not exists".format(input_data.get("currency")),
+ {},
+ False,
+ 400,
+ )
+
+ if input_data.get("region") and not frappe.db.exists(
+ "Region", input_data.get("region")
+ ):
+ return response(
+ "Region : `{0}` does not exists".format(input_data.get("region")),
+ {},
+ False,
+ 400,
+ )
sales_taxes_and_charges_template = None
tax_category = None
- if input_data.get('gst_rate'):
- if input_data.get('igst_rate'):
- tax_category_field_name = 'out_state_tax_category'
+ if input_data.get("gst_rate"):
+ if input_data.get("igst_rate"):
+ tax_category_field_name = "out_state_tax_category"
else:
- tax_category_field_name = 'in_state_tax_category'
- tax_category = frappe.db.get_single_value('Albatross Settings', tax_category_field_name)
- tax_rate = float(input_data.get('gst_rate'))
- sales_taxes_and_charges_template = get_sales_taxes_and_charges_template(tax_rate, tax_category)
+ tax_category_field_name = "in_state_tax_category"
+ tax_category = frappe.db.get_single_value(
+ "Albatross Settings", tax_category_field_name
+ )
+ tax_rate = float(input_data.get("gst_rate"))
+ sales_taxes_and_charges_template = get_sales_taxes_and_charges_template(
+ tax_rate, tax_category
+ )
# Creating Sales Order
- ro_doc = frappe.new_doc('Sales Order')
- ro_doc.transaction_date = getdate(input_data.get('date'))
- ro_doc.delivery_date = getdate(input_data.get('date'))
- ro_doc.customer = input_data.get('client_id')
- ro_doc.region = input_data.get('region')
- ro_doc.executive = input_data.get('executive_id') or ''
- ro_doc.reference_id = get_quotation_from_ro_id(input_data.get('ref_no')) or ''
- ro_item_row = ro_doc.append('items')
+ ro_doc = frappe.new_doc("Sales Order")
+ ro_doc.transaction_date = getdate(input_data.get("date"))
+ ro_doc.delivery_date = getdate(input_data.get("date"))
+ ro_doc.customer = input_data.get("client_id")
+ ro_doc.region = input_data.get("region")
+ ro_doc.executive = input_data.get("executive_id") or ""
+ ro_doc.reference_id = get_quotation_from_ro_id(input_data.get("ref_no")) or ""
+ ro_item_row = ro_doc.append("items")
ro_item_row.qty = 1
ro_item_row.item_code = albatross_service_item
- ro_item_row.rate = float(input_data.get('taxable_value'))
- ro_item_row.base_rate = float(input_data.get('taxable_value'))
+ ro_item_row.rate = float(input_data.get("taxable_value"))
+ ro_item_row.base_rate = float(input_data.get("taxable_value"))
if sales_taxes_and_charges_template:
ro_doc.taxes_and_charges = sales_taxes_and_charges_template
else:
- ro_doc.taxes_and_charges = ''
+ ro_doc.taxes_and_charges = ""
if tax_category:
ro_doc.tax_category = tax_category
else:
- ro_doc.tax_category = ''
+ ro_doc.tax_category = ""
ro_doc.ignore_mandatory = True
ro_doc.save(ignore_permissions=True)
frappe.clear_messages()
- return response('Created Sales Order Successfully', ro_doc.as_dict(), True, 201)
+ return response("Created Sales Order Successfully", ro_doc.as_dict(), True, 201)
except frappe.exceptions.CharacterLengthExceededError as e:
- frappe.log_error("Character Length Exceeded", "Error in Release Order creation: " + str(e)[:120])
- return response('Character Length Exceeded in Error Log', {}, False, 400)
+ frappe.log_error(
+ "Character Length Exceeded",
+ "Error in Release Order creation: " + str(e)[:120],
+ )
+ return response("Character Length Exceeded in Error Log", {}, False, 400)
except Exception as exception:
frappe.log_error(frappe.get_traceback(), "Release Order Creation Error")
clean_exception_message = strip_html_tags(str(exception))
return response(f"An error occurred: {clean_exception_message}", {}, False, 400)
+
@frappe.whitelist()
def get_quotation_from_ro_id(albatross_ro_id):
- '''
- Method to get Quotation using albatross_ro_id
- '''
+ """
+ Method to get Quotation using albatross_ro_id
+ """
quotation = None
- if frappe.db.exists('Quotation', { 'albatross_ro_id':albatross_ro_id }):
- quotation = frappe.db.get_value('Quotation', { 'albatross_ro_id':albatross_ro_id })
+ if frappe.db.exists("Quotation", {"albatross_ro_id": albatross_ro_id}):
+ quotation = frappe.db.get_value(
+ "Quotation", {"albatross_ro_id": albatross_ro_id}
+ )
return quotation
+
@frappe.whitelist()
def get_employees(employee_id=None, department=None):
- '''
- Fetch all employees from the same department.
-
- Args:
- employee_id: Fetch employees belonging to the same department as this employee.
- department: Fetch employees from a specific department.
- '''
- try:
- employees = []
- fields = ['employee', 'employee_name', 'department']
- filters = {}
- if employee_id:
- emp_department = frappe.get_value('Employee', employee_id, 'department')
- if not emp_department:
- return response(f'Employee {employee_id} not found', {}, False, 404)
- filters['department'] = emp_department
- elif department:
- filters['department'] = department
- employees = frappe.get_all('Employee', fields=fields, filters=filters)
- if employees:
- return response('Employees retrieved successfully', employees, True, 200)
- else:
- return response('No employees found', employees, False, 200)
- except Exception as exception:
- frappe.log_error(frappe.get_traceback())
- clean_exception_message = strip_html_tags(str(exception))
- return response(clean_exception_message, {}, False, 401)
+ """
+ Fetch all employees from the same department.
+
+ Args:
+ employee_id: Fetch employees belonging to the same department as this employee.
+ department: Fetch employees from a specific department.
+ """
+ try:
+ employees = []
+ fields = ["employee", "employee_name", "department"]
+ filters = {}
+ if employee_id:
+ emp_department = frappe.get_value("Employee", employee_id, "department")
+ if not emp_department:
+ return response(f"Employee {employee_id} not found", {}, False, 404)
+ filters["department"] = emp_department
+ elif department:
+ filters["department"] = department
+
+ employees = frappe.db.get_all("Employee", fields=fields, filters=filters)
+
+ if employees:
+ return response("Employees retrieved successfully", employees, True, 200)
+ else:
+ return response("No employees found", employees, False, 200)
+ except Exception as exception:
+ frappe.log_error(frappe.get_traceback())
+ clean_exception_message = strip_html_tags(str(exception))
+ return response(clean_exception_message, {}, False, 401)
+
@frappe.whitelist()
def get_employee_shift(employee: str, date: str):
- '''
- Fetch the shift details of an employee for a specific date.
+ """
+ Fetch the shift details of an employee for a specific date.
- :param employee: Employee ID (e.g., "EMP-0001")
- :param date: Date in YYYY-MM-DD format
- :return: Shift details if found, else an empty dictionary
- '''
+ :param employee: Employee ID (e.g., "EMP-0001")
+ :param date: Date in YYYY-MM-DD format
+ :return: Shift details if found, else an empty dictionary
+ """
- # Define filters
- employee_filters = {"name": employee}
- shift_filters = {}
+ # Define filters
+ employee_filters = {"name": employee}
+ shift_filters = {}
- shifts = get_shifts(date, date, employee_filters, shift_filters)
+ shifts = get_shifts(date, date, employee_filters, shift_filters)
+
+ # Return the shift details if found
+ return shifts.get(employee, [])
- # Return the shift details if found
- return shifts.get(employee, [])
@frappe.whitelist()
def get_doc(doctype, docname, with_history=False, method=None):
- '''
- API to get the data of a document along with attached files
- args:
- doctype : doctype of the document
- docname : name of the document
- with_history : returns document history when true
- method : returns the data object instead of response when true
- '''
- try:
- doc = frappe.get_doc(doctype, docname)
- values = {'doctype':doctype, 'docname':docname}
- attached_files = frappe.db.sql('''
- SELECT
- file_name,
- file_url
- FROM
- tabFile
- WHERE
- attached_to_doctype = %(doctype)s AND
- attached_to_name = %(docname)s
- ''', values=values, as_dict=1)
- comments = get_comments(doctype, docname)
- data = doc.__dict__
- data['meta'] = []
- if data.get('meta'):
- data.pop('meta')
- if data.get('flags'):
- data.pop('flags')
- if data.get('_table_fieldnames'):
- data.pop('_table_fieldnames')
- data['_comments'] = comments
- data['attachments'] = attached_files
- if with_history:
- data['history'] = get_doc_history(doctype, docname)
- if not method:
- data = [data]
- return response('Successfully got data of {doctype} {docname}'.format(doctype = doctype, docname = docname), data, True, 200)
- else:
- return data
- except Exception as exception:
- frappe.log_error(frappe.get_traceback())
- return response(exception, {}, False, 400)
+ """
+ API to get the data of a document along with attached files
+ args:
+ doctype : doctype of the document
+ docname : name of the document
+ with_history : returns document history when true
+ method : returns the data object instead of response when true
+ """
+ try:
+ doc = frappe.get_doc(doctype, docname)
+ values = {"doctype": doctype, "docname": docname}
+ attached_files = frappe.db.sql(
+ """
+ SELECT
+ file_name,
+ file_url
+ FROM
+ tabFile
+ WHERE
+ attached_to_doctype = %(doctype)s AND
+ attached_to_name = %(docname)s
+ """,
+ values=values,
+ as_dict=1,
+ )
+ comments = get_comments(doctype, docname)
+ data = doc.__dict__
+ data["meta"] = []
+ if data.get("meta"):
+ data.pop("meta")
+ if data.get("flags"):
+ data.pop("flags")
+ if data.get("_table_fieldnames"):
+ data.pop("_table_fieldnames")
+ data["_comments"] = comments
+ data["attachments"] = attached_files
+ if with_history:
+ data["history"] = get_doc_history(doctype, docname)
+ if not method:
+ data = [data]
+ return response(
+ "Successfully got data of {doctype} {docname}".format(
+ doctype=doctype, docname=docname
+ ),
+ data,
+ True,
+ 200,
+ )
+ else:
+ return data
+ except Exception as exception:
+ frappe.log_error(frappe.get_traceback())
+ return response(exception, {}, False, 400)
+
def get_comments(doctype, docname):
- '''method gets comments of a document, removes html elements from it and then returns it
- args:
- doctype : doctype of the document
- docname : name of the document'''
- values = {'doctype':doctype, 'docname':docname}
- comments = frappe.db.sql('''
- SELECT
- owner,
- comment_type,
- content
- FROM
- tabComment
- WHERE
- reference_doctype = %(doctype)s
- AND
- reference_name = %(docname)s
- ORDER BY
- modified desc
- ''', values=values, as_dict=1)
- for comment in comments:
- comment.content = convert_message(comment.content)
- return comments
+ """method gets comments of a document, removes html elements from it and then returns it
+ args:
+ doctype : doctype of the document
+ docname : name of the document
+ """
+ values = {"doctype": doctype, "docname": docname}
+ comments = frappe.db.sql(
+ """
+ SELECT
+ owner,
+ comment_type,
+ content
+ FROM
+ tabComment
+ WHERE
+ reference_doctype = %(doctype)s
+ AND
+ reference_name = %(docname)s
+ ORDER BY
+ modified desc
+ """,
+ values=values,
+ as_dict=1,
+ )
+ for comment in comments:
+ comment.content = convert_message(comment.content)
+ return comments
+
def convert_message(message):
- '''
- method removes html elements from string
- args:
- message: string to be converted
- '''
- CLEANR = re.compile('<.*?>')
- cleanmessage = re.sub(CLEANR, "",message)
- return cleanmessage
+ """
+ method removes html elements from string
+ args:
+ message: string to be converted
+ """
+ CLEANR = re.compile("<.*?>")
+ cleanmessage = re.sub(CLEANR, "", message)
+ return cleanmessage
+
def get_doc_history(doctype, docname):
- '''
- method to get the histroy of a document
- args:
- doctype : doctype of the document
- docname : name of the document
- '''
- history = []
- values = {'doctype':doctype, 'docname':docname}
- view_log = frappe.db.sql('''
- SELECT
- viewed_by as user,
- creation as time
- FROM
- `tabView Log`
- WHERE
- reference_doctype = %(doctype)s
- AND
- reference_name = %(docname)s
- ORDER BY
- creation asc
- ''', values = values, as_dict=1)
- for log in view_log:
- user = set_current_user_as_you_str(log.user)
- log['log'] = '{0} viewed this {1}'.format(user, get_time_diff_in_words(log.time))
- history += view_log
- versions = frappe.db.sql('''
- SELECT
- owner as user,
- creation as time,
- data
- FROM
- tabVersion
- WHERE
- ref_doctype = %(doctype)s
- AND
- docname = %(docname)s
- ''', values = values, as_dict=1)
- for version in versions:
- user = set_current_user_as_you_str(version.user)
- data = json.loads(version.data)
- time_modifier = get_time_diff_in_words(version['time'])
- if data['added']:
- version['log'] = '{0} added rows for {1} - {2}'.format(user, generate_changes_message(data['added'], 'added'), time_modifier)
- elif data['changed']:
- version['log'] = '{0} changed values for {1} - {2}'.format(user, generate_changes_message(data['changed'], 'changed'), time_modifier)
- elif data['removed']:
- version['log'] = '{0} removed rows for {1} - {2}'.format(user, generate_changes_message(data['removed'], 'removed'), time_modifier)
- elif data['row_changed']:
- version['log'] = '{0} changed values for {1} - {2}'.format(user, generate_changes_message(data['row_changed'], 'row_changed', doctype), time_modifier)
- version.pop('data')
- history += versions
-
- history.sort(key=return_keys_of_doct_history_list)
-
- doc = frappe.get_doc(doctype, docname)
- creation_dict = {
- 'user': doc.owner,
- 'time': doc.creation,
- 'log': '{0} created this {1}'.format(set_current_user_as_you_str(doc.owner), get_time_diff_in_words(doc.creation))
- }
- modifi_dict = {
- 'user': doc.modified_by,
- 'time': doc.modified,
- 'log': '{0} edited this {1}'.format(set_current_user_as_you_str(doc.modified_by), get_time_diff_in_words(doc.modified))
- }
- history = [creation_dict, modifi_dict] + history
-
- return history
+ """
+ method to get the histroy of a document
+ args:
+ doctype : doctype of the document
+ docname : name of the document
+ """
+ history = []
+ values = {"doctype": doctype, "docname": docname}
+ view_log = frappe.db.sql(
+ """
+ SELECT
+ viewed_by as user,
+ creation as time
+ FROM
+ `tabView Log`
+ WHERE
+ reference_doctype = %(doctype)s
+ AND
+ reference_name = %(docname)s
+ ORDER BY
+ creation asc
+ """,
+ values=values,
+ as_dict=1,
+ )
+ for log in view_log:
+ user = set_current_user_as_you_str(log.user)
+ log["log"] = "{0} viewed this {1}".format(
+ user, get_time_diff_in_words(log.time)
+ )
+ history += view_log
+ versions = frappe.db.sql(
+ """
+ SELECT
+ owner as user,
+ creation as time,
+ data
+ FROM
+ tabVersion
+ WHERE
+ ref_doctype = %(doctype)s
+ AND
+ docname = %(docname)s
+ """,
+ values=values,
+ as_dict=1,
+ )
+ for version in versions:
+ user = set_current_user_as_you_str(version.user)
+ data = json.loads(version.data)
+ time_modifier = get_time_diff_in_words(version["time"])
+ if data["added"]:
+ version["log"] = "{0} added rows for {1} - {2}".format(
+ user, generate_changes_message(data["added"], "added"), time_modifier
+ )
+ elif data["changed"]:
+ version["log"] = "{0} changed values for {1} - {2}".format(
+ user,
+ generate_changes_message(data["changed"], "changed"),
+ time_modifier,
+ )
+ elif data["removed"]:
+ version["log"] = "{0} removed rows for {1} - {2}".format(
+ user,
+ generate_changes_message(data["removed"], "removed"),
+ time_modifier,
+ )
+ elif data["row_changed"]:
+ version["log"] = "{0} changed values for {1} - {2}".format(
+ user,
+ generate_changes_message(data["row_changed"], "row_changed", doctype),
+ time_modifier,
+ )
+ version.pop("data")
+ history += versions
+
+ history.sort(key=return_keys_of_doct_history_list)
+
+ doc = frappe.get_doc(doctype, docname)
+ creation_dict = {
+ "user": doc.owner,
+ "time": doc.creation,
+ "log": "{0} created this {1}".format(
+ set_current_user_as_you_str(doc.owner), get_time_diff_in_words(doc.creation)
+ ),
+ }
+ modifi_dict = {
+ "user": doc.modified_by,
+ "time": doc.modified,
+ "log": "{0} edited this {1}".format(
+ set_current_user_as_you_str(doc.modified_by),
+ get_time_diff_in_words(doc.modified),
+ ),
+ }
+ history = [creation_dict, modifi_dict] + history
+
+ return history
+
def return_keys_of_doct_history_list(log_dict):
- '''key generator for history lsit sort'''
- return log_dict['time']
+ """key generator for history lsit sort"""
+ return log_dict["time"]
+
def get_time_diff_in_words(time):
- '''
- method used to get the time difference between current time and given time in words
- args:
- time : datetime object of time to be calculated
- '''
- now = now_datetime()
- diff = time_diff(now, time)
- days = int(diff.days)
- if not days:
- hours = int(diff.seconds/3600)
- if not hours:
- minutes = int(diff.seconds/60)
- if not minutes:
- return 'just now'
- elif minutes == 1:
- return '1 minute ago'
- return '{0} minutes ago'.format(minutes)
- if hours == 1:
- return '1 hour ago'
- return '{0} hours ago'.format(hours)
- elif days < 7:
- if days == 1:
- return '1 day ago'
- return '{0} days ago'.format(days)
- if time.month == now.month:
- weeks = int(days/7)
- if weeks > 1:
- return '{0} weeks ago'.format(weeks)
- return '1 week ago'
- years = now.year - time.year
- if not years:
- months = diff_month(now, time)
- if months == 1:
- return '1 month ago'
- return '{0} months ago'.format(months)
- if years == 1:
- return '1 year ago'
- return '{0} years ago'.format(years)
+ """
+ method used to get the time difference between current time and given time in words
+ args:
+ time : datetime object of time to be calculated
+ """
+ now = now_datetime()
+ diff = time_diff(now, time)
+ days = int(diff.days)
+ if not days:
+ hours = int(diff.seconds / 3600)
+ if not hours:
+ minutes = int(diff.seconds / 60)
+ if not minutes:
+ return "just now"
+ elif minutes == 1:
+ return "1 minute ago"
+ return "{0} minutes ago".format(minutes)
+ if hours == 1:
+ return "1 hour ago"
+ return "{0} hours ago".format(hours)
+ elif days < 7:
+ if days == 1:
+ return "1 day ago"
+ return "{0} days ago".format(days)
+ if time.month == now.month:
+ weeks = int(days / 7)
+ if weeks > 1:
+ return "{0} weeks ago".format(weeks)
+ return "1 week ago"
+ years = now.year - time.year
+ if not years:
+ months = diff_month(now, time)
+ if months == 1:
+ return "1 month ago"
+ return "{0} months ago".format(months)
+ if years == 1:
+ return "1 year ago"
+ return "{0} years ago".format(years)
+
def diff_month(d1, d2):
- '''
- method to get the month difference between two dates
- args:
- d1, d2: datetime objects of dates
- '''
- return (d1.year - d2.year) * 12 + d1.month - d2.month
+ """
+ method to get the month difference between two dates
+ args:
+ d1, d2: datetime objects of dates
+ """
+ return (d1.year - d2.year) * 12 + d1.month - d2.month
+
def set_current_user_as_you_str(user):
- '''
- method used to return self addressal if the user in question is the current user
- args:
- user : email of the user
- '''
- if frappe.session.user == user:
- return 'You'
- return user
-
-def generate_changes_message(changes, type, doctype = None):
- '''
- method used to generate the messages for document history
- args:
- changes : a list object contatining the version data
- type : type of change happened
- '''
- changes_list = []
- for change in changes:
- if type == 'changed':
- changes_list.append('{0} from {1} to {2}'.format(change[0], change[1], change[2]))
- elif type in ['added', 'removed']:
- label = frappe.get_meta(change[1]['parenttype']).get_field(change[1]['parentfield']).label
- changes_list.append(label)
- elif type == 'row_changed':
- field_meta = frappe.get_meta(doctype).get_field(change[0])
- label = field_meta.label
- for value_change in change[3]:
- child_label = frappe.get_meta(field_meta.options).get_field(value_change[0]).label
- changes_list.append('{0} from {1} to {2} in row #{3}'.format(child_label, value_change[1], value_change[2], change[1]))
- changes_str = ', '.join(changes_list)
- return changes_str
+ """
+ method used to return self addressal if the user in question is the current user
+ args:
+ user : email of the user
+ """
+ if frappe.session.user == user:
+ return "You"
+ return user
+
+
+def generate_changes_message(changes, type, doctype=None):
+ """
+ method used to generate the messages for document history
+ args:
+ changes : a list object contatining the version data
+ type : type of change happened
+ """
+ changes_list = []
+ for change in changes:
+ if type == "changed":
+ changes_list.append(
+ "{0} from {1} to {2}".format(change[0], change[1], change[2])
+ )
+ elif type in ["added", "removed"]:
+ label = (
+ frappe.get_meta(change[1]["parenttype"])
+ .get_field(change[1]["parentfield"])
+ .label
+ )
+ changes_list.append(label)
+ elif type == "row_changed":
+ field_meta = frappe.get_meta(doctype).get_field(change[0])
+ label = field_meta.label
+ for value_change in change[3]:
+ child_label = (
+ frappe.get_meta(field_meta.options).get_field(value_change[0]).label
+ )
+ changes_list.append(
+ "{0} from {1} to {2} in row #{3}".format(
+ child_label, value_change[1], value_change[2], change[1]
+ )
+ )
+ changes_str = ", ".join(changes_list)
+ return changes_str
diff --git a/beams/beams/custom_scripts/appraisal/appraisal.py b/beams/beams/custom_scripts/appraisal/appraisal.py
index a903db4d2..80c66569e 100644
--- a/beams/beams/custom_scripts/appraisal/appraisal.py
+++ b/beams/beams/custom_scripts/appraisal/appraisal.py
@@ -201,31 +201,25 @@ def get_categories_table():
return categories_html
@frappe.whitelist()
-def add_to_category_details(parent_docname, category, remarks):
- """
- Adds a new row with category details (category, remarks, employee, designation)
- to the category_details child table of an Appraisal document and saves it.
- """
+def add_to_category_details(parent_docname, category, remarks, employee, designation):
+ '''
+ Adds a new row with category details (category, remarks, employee, designation) to the category_details child table of an Appraisal document and saves it.
+ '''
try:
parent_doc = frappe.get_doc("Appraisal", parent_docname)
- employee = parent_doc.employee
- designation = parent_doc.designation
-
- parent_doc.append("category_details", {
+ child_row = parent_doc.append("category_details", {
"category": category,
"remarks": remarks,
"employee": employee,
"designation": designation
})
+ parent_doc.save()
- parent_doc.save(ignore_permissions=True)
return "Success"
except Exception as e:
frappe.log_error(frappe.get_traceback(), "Add to Category Details Error")
return "Failed"
-
-
@frappe.whitelist()
def map_appraisal_to_event(source_name):
'''
@@ -288,52 +282,112 @@ def check_existing_event(appraisal_reference):
event = frappe.db.get_value("Event", {"appraisal_reference": appraisal_reference}, "name")
return event if event else None
+
@frappe.whitelist()
-def assign_tasks_sequentially(doc):
+def assign_tasks_sequentially(doc=None, employee_id=None):
"""
- Sends an email notification to the assessment officer to review the appraisal.
+ Assign tasks sequentially to assessment officers listed in the Appraisal Template.
+ Args:
+ doc (str/dict): The Appraisal document instance (JSON or dict format).
+ method (str): The method context in which the function is called (e.g., "on_update").
"""
- appraisal = frappe.get_doc("Appraisal", doc)
- assessment_officer_id = frappe.db.get_value("Employee", appraisal.employee, "assessment_officer")
+ try:
+ if not doc:
+ frappe.throw("Missing document data.")
- if not assessment_officer_id:
- frappe.throw(f"Assessment Officer not set for employee {appraisal.employee}")
+ # If doc is an ID string, fetch the full document
+ if isinstance(doc, str) and not doc.startswith('{'):
+ appraisal_doc = frappe.get_doc("Appraisal", doc)
+ else:
+ appraisal_doc = doc
- user_id, officer_name = frappe.db.get_value("Employee", assessment_officer_id, ["user_id", "employee_name"])
+ if not appraisal_doc:
+ frappe.throw("Invalid Appraisal document.")
- if not user_id:
- frappe.throw(f"No User ID found for assessment officer {assessment_officer_id}")
+ appraisal_template_name = appraisal_doc.appraisal_template
- # Get email template
- template_name = frappe.db.get_single_value("Beams HR Settings", "assessment_reminder_template")
- if not template_name:
- frappe.throw("Please set 'Assessment Reminder Template' in Beams HR Settings.")
+ if not appraisal_template_name:
+ return
- template = frappe.get_doc("Email Template", template_name)
+ # Fetch Appraisal Template and assessment officers
+ appraisal_template_doc = frappe.get_doc("Appraisal Template", appraisal_template_name)
+ assessment_officers = appraisal_template_doc.get("assessment_officers")
- context = {
- "doc": appraisal,
- "employee_name": appraisal.employee_name,
- "officer_name": officer_name,
- }
- subject = frappe.render_template(template.subject or '', context)
- message = frappe.render_template(template.response or template.message or '', context)
+ if not assessment_officers:
+ frappe.log_error("No assessment officers defined in the appraisal template.")
+ return
+
+ # Find the next officer to assign a task to
+ assigned_officers = {row.designation for row in appraisal_doc.category_details}
+
+ for officer in assessment_officers:
+ designation = officer.designation
+
+ # Skip if task is already completed for this designation
+ if designation in assigned_officers:
+ continue
- frappe.sendmail(recipients=frappe.db.get_value("User", user_id, "email"), subject=subject, message=message)
+ # Fetch employees for the designation
+ employees = frappe.get_all(
+ "Employee",
+ filters={"designation": designation, "status": "Active"},
+ fields=["name", "user_id", "employee_name"]
+ )
- frappe.get_doc({
- "doctype": "Notification Log",
- "subject": subject,
- "for_user": user_id,
- "type": "Alert",
- "document_type": "Appraisal",
- "document_name": appraisal,
- "from_user": frappe.session.user,
- "email_content": message
- }).insert(ignore_permissions=True)
+ if not employees:
+ continue
+
+ # Assign task to the first available employee with a user ID
+ for employee in employees:
+ if employee.get("user_id"):
+ try:
+ add_assign({
+ "assign_to": [employee.user_id],
+ "doctype": appraisal_doc.doctype,
+ "name": appraisal_doc.name,
+ "description": f"Please add Category for {employee_id}.",
+ })
+
+ # Send Notification
+ frappe.sendmail(
+ recipients=[employee.user_id],
+ subject="New Category Task Assigned",
+ message=f"A new category task has been assigned to you for designation: {designation}."
+ )
+
+ return
+ except Exception as e:
+ frappe.log_error(f"Failed to assign task to {employee.user_id}: {str(e)}", "Task Assignment")
+
+ return 0
+
+ except Exception as e:
+ frappe.log_error(f"Error in task assignment: {str(e)}", "Task Assignment")
+ frappe.throw(str(e))
+
+
+
+def send_notification(user_id, appraisal_doc):
+ """
+ Sends an email notification to the assigned officer.
+
+ Args:
+ user_id (str): The user ID of the officer.
+ appraisal_doc (frappe.Document): The Appraisal document instance.
+ """
+ try:
+ subject = f"Appraisal Notification: {appraisal_doc.name}"
+ message = f"""
+ Dear Officer,
+ You have been assigned to review the appraisal {appraisal_doc.name}.
+ Please take the necessary action.
+ Regards.
+ """
+ frappe.sendmail(recipients=user_id, subject=subject, message=message)
+
+ except Exception as e:
+ frappe.log_error("Notification Error", f"Failed to send notification to {user_id}: {str(e)}")
- frappe.msgprint(f"Notification sent to {officer_name} for appraisal review.")
- return {"status": "ok"}
@frappe.whitelist()
def get_appraisal_template_criteria(appraisal_template_name):
@@ -432,59 +486,3 @@ def set_category_based_on_marks(doc, method):
# Update the Appraisal document
if category:
doc.category_based_on_marks = category
-
-
-@frappe.whitelist()
-def send_assessment_reminder(doc):
- """
- Sends an email notification and Notification Log to the Assessment Officer to review the appraisal.
- """
- appraisal = frappe.get_doc("Appraisal", doc)
- assessment_officer_id = frappe.db.get_value("Employee", appraisal.employee, "assessment_officer")
-
- if not assessment_officer_id:
- frappe.throw(f"Assessment Officer not set for employee {appraisal.employee}")
-
- user_id, officer_name = frappe.db.get_value("Employee", assessment_officer_id, ["user_id", "employee_name"])
- if not user_id:
- frappe.throw(f"No User ID found for assessment officer {assessment_officer_id}")
-
- email_id = frappe.db.get_value("User", user_id, "email")
- if not email_id:
- frappe.throw(f"No Email ID found for user {user_id}")
-
- # Fetch Email Template from settings
- template_name = frappe.db.get_single_value("Beams HR Settings", "assessment_reminder_template")
- if not template_name:
- frappe.throw("Please set 'Assessment Reminder Template' in Beams HR Settings.")
-
- template = frappe.get_doc("Email Template", template_name)
- context = {
- "doc": appraisal,
- "employee_name": appraisal.employee_name,
- "officer_name": officer_name,
- }
- subject = frappe.render_template(template.subject or '', context)
- message = frappe.render_template(template.response or template.message or '', context)
-
- # Send Email
- frappe.sendmail(
- recipients=email_id,
- subject=subject,
- message=message
- )
-
- # Notification Log
- frappe.get_doc({
- "doctype": "Notification Log",
- "subject": subject,
- "for_user": user_id,
- "type": "Alert",
- "document_type": "Appraisal",
- "document_name": appraisal.name,
- "from_user": frappe.session.user,
- "email_content": message
- }).insert(ignore_permissions=True)
-
- frappe.msgprint(f"Notification sent to {officer_name} for appraisal review.")
- return {"status": "ok"}
diff --git a/beams/beams/custom_scripts/asset_movement/asset_movement.py b/beams/beams/custom_scripts/asset_movement/asset_movement.py
index f7a099dac..81717e6bb 100644
--- a/beams/beams/custom_scripts/asset_movement/asset_movement.py
+++ b/beams/beams/custom_scripts/asset_movement/asset_movement.py
@@ -1,99 +1,106 @@
import frappe
-from frappe.utils import flt
+
def update_issued_quantity(doc, method):
- """
- Updates Issued Quantity in 'Required Items Detail' of an Equipment Request,
- and updates or inserts corresponding rows in Project's Allocated Item Details,
- based on the Asset Movement.
- """
- if not doc.assets:
- frappe.throw("No assets found in this Asset Movement.")
-
- reference_name = doc.reference_name
- if not reference_name:
- return
-
- required_items = frappe.get_all(
- "Required Items Detail",
- filters={"parent": reference_name},
- fields=["name", "required_item", "issued_quantity", "required_quantity"]
- )
-
- if not required_items:
- return
-
- asset_count = {}
- for asset in doc.assets:
- if not asset.asset_name:
- frappe.throw(f"Asset Name not set for Asset {asset.asset}.")
- asset_count[asset.asset_name] = asset_count.get(asset.asset_name, 0) + 1
-
- for req in required_items:
- item = req.required_item
- if item in asset_count:
- new_issued_qty = (req.issued_quantity or 0) + asset_count[item]
- frappe.db.set_value("Required Items Detail", req.name, "issued_quantity", new_issued_qty)
-
- project_name = frappe.db.get_value("Equipment Request", reference_name, "project")
- if not project_name:
- return
-
- project_doc = frappe.get_doc("Project", project_name)
-
- for req in required_items:
- item = req.required_item
- if item in asset_count:
- for row in project_doc.allocated_item_details:
- if row.required_item == item:
- row.issued_quantity = (row.issued_quantity or 0) + asset_count[item]
- break
- else:
- project_doc.append("allocated_item_details", {
- "required_item": item,
- "required_quantity": req.required_quantity,
- "issued_quantity": asset_count[item],
- })
-
- project_doc.save(ignore_permissions=True)
+ """
+ Updates Issued Quantity in 'Required Items Detail' of an Equipment Request,
+ and updates or inserts corresponding rows in Project's Allocated Item Details,
+ based on the Asset Movement.
+ """
+ if not doc.assets:
+ frappe.throw("No assets found in this Asset Movement.")
+
+ reference_name = doc.reference_name
+ if not reference_name:
+ return
+
+ required_items = frappe.get_all(
+ "Required Items Detail",
+ filters={"parent": reference_name},
+ fields=["name", "required_item", "issued_quantity", "required_quantity"],
+ )
+
+ if not required_items:
+ return
+
+ asset_count = {}
+ for asset in doc.assets:
+ if not asset.asset_name:
+ frappe.throw(f"Asset Name not set for Asset {asset.asset}.")
+ asset_count[asset.asset_name] = asset_count.get(asset.asset_name, 0) + 1
+
+ for req in required_items:
+ item = req.required_item
+ if item in asset_count:
+ new_issued_qty = (req.issued_quantity or 0) + asset_count[item]
+ frappe.db.set_value(
+ "Required Items Detail", req.name, "issued_quantity", new_issued_qty
+ )
+
+ project_name = frappe.db.get_value("Equipment Request", reference_name, "project")
+ if not project_name:
+ return
+
+ project_doc = frappe.get_doc("Project", project_name)
+
+ for req in required_items:
+ item = req.required_item
+ if item in asset_count:
+ for row in project_doc.allocated_item_details:
+ if row.required_item == item:
+ row.issued_quantity = (row.issued_quantity or 0) + asset_count[item]
+ break
+ else:
+ project_doc.append(
+ "allocated_item_details",
+ {
+ "required_item": item,
+ "required_quantity": req.required_quantity,
+ "issued_quantity": asset_count[item],
+ },
+ )
+
+ project_doc.save(ignore_permissions=True)
+
def before_save(doc, method):
- if doc.assets:
- first_asset = doc.assets[0]
- if first_asset.to_employee:
- doc.new_custodian = first_asset.to_employee
+ if doc.assets:
+ first_asset = doc.assets[0]
+ if first_asset.to_employee:
+ doc.new_custodian = first_asset.to_employee
+
+ new_custodian_doc = frappe.get_doc("Employee", doc.new_custodian)
+ if new_custodian_doc.user_id:
+ doc.user_id = new_custodian_doc.user_id
- new_custodian_doc = frappe.get_doc("Employee", doc.new_custodian)
- if new_custodian_doc.user_id:
- doc.user_id = new_custodian_doc.user_id
@frappe.whitelist()
def update_asset_location_from_movement(doc, method=None):
- """
- Updates the location and physical storage details (room, shelf, row, bin)
- of assets listed in an Asset Movement document.
- If any of these fields are empty in the movement record, they will also be cleared in the Asset.
- """
- if isinstance(doc, str):
- doc = frappe.get_doc("Asset Movement", doc)
-
- for item in doc.assets:
- if not item.asset:
- continue
-
- asset = frappe.get_doc("Asset", item.asset)
- updated = False
-
- if item.target_location:
- asset.location = item.target_location
- updated = True
- else:
- return
-
- for field in ["room", "shelf", "row", "bin"]:
- item_value = getattr(item, field, None)
- setattr(asset, field, item_value if item_value is not None else "")
- updated = True
-
- if updated:
- asset.save(ignore_permissions=True)
+ """
+ Updates the location and physical storage details (room, shelf, row, bin)
+ of assets listed in an Asset Movement document.
+ If any of these fields are empty in the movement record, they will also be cleared in the Asset.
+ """
+ if isinstance(doc, str):
+ doc = frappe.get_doc("Asset Movement", doc)
+
+ for item in doc.assets:
+ if not item.asset:
+ continue
+
+ asset = frappe.get_doc("Asset", item.asset)
+ updated = False
+
+ if item.target_location:
+ asset.location = item.target_location
+ updated = True
+ else:
+ return
+
+ for field in ["room", "shelf", "row", "bin"]:
+ item_value = getattr(item, field, None)
+ setattr(asset, field, item_value if item_value is not None else "")
+ updated = True
+
+ if updated:
+ asset.save(ignore_permissions=True)
diff --git a/beams/beams/custom_scripts/attendance_request/attendance_request.py b/beams/beams/custom_scripts/attendance_request/attendance_request.py
index 2df125a82..d055d1acf 100644
--- a/beams/beams/custom_scripts/attendance_request/attendance_request.py
+++ b/beams/beams/custom_scripts/attendance_request/attendance_request.py
@@ -7,43 +7,47 @@
class AttendanceRequestOverride(AttendanceRequest):
def create_or_update_attendance(self, date: str):
- '''
- Method to Create or Update Attendance from Attendance Request
- '''
+ """
+ Method to Create or Update Attendance from Attendance Request
+ """
attendance_name = self.get_attendance_record(date)
status = self.get_attendance_status(date)
if attendance_name:
# Update existing attendance record
- doc = frappe.get_doc('Attendance', attendance_name)
+ doc = frappe.get_doc("Attendance", attendance_name)
old_status = doc.status
- doc.db_set('attendance_request', self.name)
- checkin_time, checkout_time = get_checkin_checkout_time(doc.employee, doc.attendance_date)
+ doc.db_set("attendance_request", self.name)
+ checkin_time, checkout_time = get_checkin_checkout_time(
+ doc.employee, doc.attendance_date
+ )
if not doc.in_time and checkin_time:
- doc.db_set('in_time', checkin_time)
+ doc.db_set("in_time", checkin_time)
if not doc.out_time and checkout_time:
- doc.db_set('out_time', checkout_time)
+ doc.db_set("out_time", checkout_time)
if old_status != status:
- doc.db_set({'status': status})
- text = _('changed the status from {0} to {1} via Attendance Regularisation').format(
- frappe.bold(old_status), frappe.bold(status)
- )
- doc.add_comment(comment_type='Info', text=text)
+ doc.db_set({"status": status})
+ text = _(
+ "changed the status from {0} to {1} via Attendance Regularisation"
+ ).format(frappe.bold(old_status), frappe.bold(status))
+ doc.add_comment(comment_type="Info", text=text)
frappe.msgprint(
- _('Updated status from {0} to {1} for date {2} in the attendance record {3}').format(
+ _(
+ "Updated status from {0} to {1} for date {2} in the attendance record {3}"
+ ).format(
frappe.bold(old_status),
frappe.bold(status),
frappe.bold(format_date(date)),
- get_link_to_form('Attendance', doc.name),
+ get_link_to_form("Attendance", doc.name),
),
- title=_('Attendance Updated'),
+ title=_("Attendance Updated"),
)
else:
# Create a new attendance record
- doc = frappe.new_doc('Attendance')
+ doc = frappe.new_doc("Attendance")
doc.employee = self.employee
doc.attendance_date = date
doc.shift = self.shift
@@ -53,87 +57,111 @@ def create_or_update_attendance(self, date: str):
doc.insert(ignore_permissions=True)
doc.submit()
+
def get_checkin_checkout_time(employee, attendance_date):
- '''
- Method to get First Checkin and Last Checkout Time based on attednace date and employee
- '''
+ """
+ Method to get First Checkin and Last Checkout Time based on attednace date and employee
+ """
checkin_time, checkout_time = None, None
- if frappe.db.exists('Attendance', { 'attendance_date':attendance_date, 'employee':employee }):
- attendance_doc = frappe.get_doc('Attendance', { 'attendance_date':attendance_date, 'employee':employee })
+ if frappe.db.exists(
+ "Attendance", {"attendance_date": attendance_date, "employee": employee}
+ ):
+ attendance_doc = frappe.get_doc(
+ "Attendance", {"attendance_date": attendance_date, "employee": employee}
+ )
if attendance_doc.in_time and not attendance_doc.out_time:
- checkin_record = frappe.db.get_value('Employee Checkin', { 'attendance':attendance_doc.name, 'time':attendance_doc.in_time })
+ checkin_record = frappe.db.get_value(
+ "Employee Checkin",
+ {"attendance": attendance_doc.name, "time": attendance_doc.in_time},
+ )
checkout_time = get_checkout_time(employee, checkin_record)
if attendance_doc.out_time and not attendance_doc.in_time:
- checkout_record = frappe.db.get_value('Employee Checkin', { 'attendance':attendance_doc.name, 'time':attendance_doc.out_time })
+ checkout_record = frappe.db.get_value(
+ "Employee Checkin",
+ {"attendance": attendance_doc.name, "time": attendance_doc.out_time},
+ )
checkin_time = get_checkin_time(employee, checkout_record)
return checkin_time, checkout_time
+
def get_checkout_time(employee, checkin_record):
- '''
- Fetches the last checkout time for an employee after the provided checkin record.
- '''
+ """
+ Fetches the last checkout time for an employee after the provided checkin record.
+ """
checkout_time = None
- if frappe.db.exists('Employee Checkin', checkin_record):
- checkin_time = frappe.db.get_value('Employee Checkin', checkin_record, 'time')
+ if frappe.db.exists("Employee Checkin", checkin_record):
+ checkin_time = frappe.db.get_value("Employee Checkin", checkin_record, "time")
checkins = frappe.get_all(
- 'Employee Checkin',
+ "Employee Checkin",
fields=[
- 'name',
- 'employee',
- 'log_type',
- 'time',
- 'shift',
- 'shift_start',
- 'shift_end',
- 'shift_actual_start',
- 'shift_actual_end'
+ "name",
+ "employee",
+ "log_type",
+ "time",
+ "shift",
+ "shift_start",
+ "shift_end",
+ "shift_actual_start",
+ "shift_actual_end",
],
filters={
- 'skip_auto_attendance': 0,
- 'employee': employee,
- 'attendance': ('is', 'not set'),
- 'time': ('>=', checkin_time)
+ "skip_auto_attendance": 0,
+ "employee": employee,
+ "attendance": ("is", "not set"),
+ "time": (">=", checkin_time),
},
- order_by='time',
+ order_by="time",
)
for checkin in checkins:
- if checkin.log_type == 'OUT' and not checkin.shift:
+ if checkin.log_type == "OUT" and not checkin.shift:
checkout_time = checkin.time
if checkout_time and checkin.shift:
return checkout_time
return checkout_time
+
def get_checkin_time(employee, checkout_record):
- '''
- Fetches the first check-in time for an employee before the provided checkout record.
- '''
+ """
+ Fetches the first check-in time for an employee before the provided checkout record.
+ """
checkin_time = None
- if frappe.db.exists('Employee Checkin', checkout_record):
- checkout_time = frappe.db.get_value('Employee Checkin', checkout_record, 'time')
+ if frappe.db.exists("Employee Checkin", checkout_record):
+ checkout_time = frappe.db.get_value("Employee Checkin", checkout_record, "time")
checkins = frappe.get_all(
- 'Employee Checkin',
+ "Employee Checkin",
fields=[
- 'name',
- 'employee',
- 'log_type',
- 'time',
- 'shift',
- 'shift_start',
- 'shift_end',
- 'shift_actual_start',
- 'shift_actual_end'
+ "name",
+ "employee",
+ "log_type",
+ "time",
+ "shift",
+ "shift_start",
+ "shift_end",
+ "shift_actual_start",
+ "shift_actual_end",
],
filters={
- 'skip_auto_attendance': 0,
- 'employee': employee,
- 'attendance': ('is', 'not set'),
- 'time': ('<=', checkout_time)
+ "skip_auto_attendance": 0,
+ "employee": employee,
+ "attendance": ("is", "not set"),
+ "time": ("<=", checkout_time),
},
- order_by='time desc',
+ order_by="time desc",
)
for checkin in checkins:
- if checkin.log_type == 'IN' and not checkin.shift:
+ if checkin.log_type == "IN" and not checkin.shift:
checkin_time = checkin.time
if checkin_time and checkin.shift:
return checkin_time
return checkin_time
+
+
+@frappe.whitelist()
+def validate_to_date(doc, method):
+ """
+ Validates that the 'to_date' field in the Attendance Regularisation doctype
+ is not set to a future date.
+ """
+ if doc.to_date:
+ if doc.to_date > today():
+ frappe.throw(_("To Date cannot be a Future date"))
diff --git a/beams/beams/custom_scripts/employee_checkin/employee_checkin.py b/beams/beams/custom_scripts/employee_checkin/employee_checkin.py
index 7380d479e..e15a4326e 100644
--- a/beams/beams/custom_scripts/employee_checkin/employee_checkin.py
+++ b/beams/beams/custom_scripts/employee_checkin/employee_checkin.py
@@ -5,99 +5,108 @@
def handle_employee_checkin_out(doc, method):
- """
- Handles Employee Checkin with type OUT:
- - Creates or updates Leave Allocation.
- - Triggers Compensatory Leave Log creation in Leave Allocation logic.
- """
- if doc.log_type != "OUT":
- return
-
- # Fetch Compensatory Leave Type
- compensatory_leave_type = frappe.db.get_single_value("Beams HR Settings", "compensatory_leave_type")
- if not compensatory_leave_type:
- return
-
- # Parse time from the Employee Checkin log
- doc_time = datetime.strptime(doc.time, "%Y-%m-%d %H:%M:%S") if isinstance(doc.time, str) else doc.time
- start_date = doc_time.date()
- end_date = add_days(start_date, 30)
- today_date = today()
-
- # Verify Shift Assignment with roster_type 'OT'
- shift_assignment = frappe.db.sql("""
- SELECT name FROM `tabShift Assignment`
- WHERE employee = %s
- AND roster_type = 'Double Shift'
- AND %s BETWEEN start_date AND end_date
- """, (doc.employee, today_date), as_dict=True)
-
- if not shift_assignment:
- return
-
- # Fetch Leave Allocation
- leave_allocation = frappe.get_all(
- "Leave Allocation",
- filters={"employee": doc.employee, "leave_type": compensatory_leave_type},
- fields=["name", "to_date", "new_leaves_allocated"],
- limit=1
- )
-
- if leave_allocation:
- # Update existing Leave Allocation
- allocation = frappe.get_doc("Leave Allocation", leave_allocation[0].name)
- if allocation.to_date < end_date:
- allocation.to_date = end_date
- allocation.new_leaves_allocated += 1
- allocation.flags.ignore_permissions = True
- allocation.save()
- else:
- # Create new Leave Allocation
- leave_allocation_doc = frappe.new_doc("Leave Allocation")
- leave_allocation_doc.update({
- "employee": doc.employee,
- "leave_type": compensatory_leave_type,
- "from_date": start_date,
- "to_date": end_date,
- "new_leaves_allocated": 1,
- })
- leave_allocation_doc.insert(ignore_permissions=True)
- leave_allocation_doc.submit()
+ """
+ Handles Employee Checkin with type OUT:
+ - Creates or updates Leave Allocation.
+ - Triggers Compensatory Leave Log creation in Leave Allocation logic.
+ """
+ if doc.log_type != "OUT":
+ return
+
+ # Fetch Compensatory Leave Type
+ compensatory_leave_type = frappe.db.get_single_value(
+ "Beams HR Settings", "compensatory_leave_type"
+ )
+ if not compensatory_leave_type:
+ return
+
+ # Parse time from the Employee Checkin log
+ doc_time = (
+ datetime.strptime(doc.time, "%Y-%m-%d %H:%M:%S")
+ if isinstance(doc.time, str)
+ else doc.time
+ )
+ start_date = doc_time.date()
+ end_date = add_days(start_date, 30)
+ today_date = today()
+
+ # Verify Shift Assignment with roster_type 'OT'
+ shift_assignment = frappe.db.sql(
+ """
+ SELECT name FROM `tabShift Assignment`
+ WHERE employee = %s
+ AND roster_type = 'Double Shift'
+ AND %s BETWEEN start_date AND end_date
+ """,
+ (doc.employee, today_date),
+ as_dict=True,
+ )
+
+ if not shift_assignment:
+ return
+
+ # Fetch Leave Allocation
+ leave_allocation = frappe.get_all(
+ "Leave Allocation",
+ filters={"employee": doc.employee, "leave_type": compensatory_leave_type},
+ fields=["name", "to_date", "new_leaves_allocated"],
+ limit=1,
+ )
+
+ if leave_allocation:
+ # Update existing Leave Allocation
+ allocation = frappe.get_doc("Leave Allocation", leave_allocation[0].name)
+ if allocation.to_date < end_date:
+ allocation.to_date = end_date
+ allocation.new_leaves_allocated += 1
+ allocation.flags.ignore_permissions = True
+ allocation.save()
+ else:
+ # Create new Leave Allocation
+ leave_allocation_doc = frappe.new_doc("Leave Allocation")
+ leave_allocation_doc.update(
+ {
+ "employee": doc.employee,
+ "leave_type": compensatory_leave_type,
+ "from_date": start_date,
+ "to_date": end_date,
+ "new_leaves_allocated": 1,
+ }
+ )
+ leave_allocation_doc.insert(ignore_permissions=True)
+ leave_allocation_doc.submit()
-def set_hd_agent_active_status(doc, method=None):
- """Update HD Agent's active status based on today's latest employee check-in"""
-
- employee = doc.employee
-
- # Get user linked to the employee
- user = frappe.db.get_value("Employee", {"name": employee}, "user_id")
-
- if not user:
- return
-
- start = get_datetime(nowdate() + " 00:00:00")
- end = get_datetime(nowdate() + " 23:59:59")
-
- # Get the latest check-in today
- latest_checkin = frappe.db.get_all(
- "Employee Checkin",
- filters={
- "employee": employee,
- "time": ["between", [start, end]]
- },
- fields=["name", "log_type", "time"],
- order_by="time desc",
- limit=1
- )
-
- if latest_checkin:
- latest_log_type = latest_checkin[0].log_type
- new_status = 1 if latest_log_type == "IN" else 0
- else:
- # No check-ins today
- new_status = 0
-
- # Update HD Agent status
- if frappe.db.exists("HD Agent", {"user": user}):
- frappe.db.set_value("HD Agent", {"user": user}, "is_active", new_status)
+def set_hd_agent_active_status(doc, method=None):
+ """Update HD Agent's active status based on today's latest employee check-in"""
+
+ employee = doc.employee
+
+ # Get user linked to the employee
+ user = frappe.db.get_value("Employee", {"name": employee}, "user_id")
+
+ if not user:
+ return
+
+ start = get_datetime(nowdate() + " 00:00:00")
+ end = get_datetime(nowdate() + " 23:59:59")
+
+ # Get the latest check-in today
+ latest_checkin = frappe.db.get_all(
+ "Employee Checkin",
+ filters={"employee": employee, "time": ["between", [start, end]]},
+ fields=["name", "log_type", "time"],
+ order_by="time desc",
+ limit=1,
+ )
+
+ if latest_checkin:
+ latest_log_type = latest_checkin[0].log_type
+ new_status = 1 if latest_log_type == "IN" else 0
+ else:
+ # No check-ins today
+ new_status = 0
+
+ # Update HD Agent status
+ if frappe.db.exists("HD Agent", {"user": user}):
+ frappe.db.set_value("HD Agent", {"user": user}, "is_active", new_status)
diff --git a/beams/beams/custom_scripts/job_applicant/job_applicant.js b/beams/beams/custom_scripts/job_applicant/job_applicant.js
index 66df2a947..2f73d851f 100644
--- a/beams/beams/custom_scripts/job_applicant/job_applicant.js
+++ b/beams/beams/custom_scripts/job_applicant/job_applicant.js
@@ -27,6 +27,22 @@ frappe.ui.form.on('Job Applicant', {
// Clear location if checkbox is unchecked
frm.set_value('location', '');
}
+ },
+ validate: function (frm) {
+ const resume_attachment = frm.doc.resume_attachment;
+ if (resume_attachment) {
+ const allowed_extensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx'];
+ const file_extension = resume_attachment.split('.').pop().toLowerCase();
+
+ if (!allowed_extensions.includes(file_extension)) {
+ frappe.msgprint({
+ title: __('Validation for Resume'),
+ message: __('Only PDF, DOC, DOCX, XLS, and XLSX files are allowed'),
+ indicator: 'red'
+ });
+ frappe.validated = false;
+ }
+ }
}
});
diff --git a/beams/beams/custom_scripts/project/project.py b/beams/beams/custom_scripts/project/project.py
index 12e4fe549..f87a65960 100644
--- a/beams/beams/custom_scripts/project/project.py
+++ b/beams/beams/custom_scripts/project/project.py
@@ -1,11 +1,10 @@
import json
+
import frappe
from erpnext.accounts.utils import get_fiscal_year
from frappe import _
from frappe.model.mapper import get_mapped_doc
-from frappe.utils import nowdate
-from frappe.utils import now
-from frappe.utils import cint, now
+from frappe.utils import cint, now, nowdate
def validate_project(doc, method):
@@ -215,7 +214,6 @@ def create_technical_request(project_id):
project = frappe.get_doc('Project', project_id)
-
doc = frappe.get_doc({
'doctype': 'Technical Request',
'project': project_id,
@@ -653,7 +651,7 @@ def auto_return_vehicles_on_project_completion(doc, method):
updated = True
else:
- print(f" - Skipped (already returned or reason provided)")
+ print(" - Skipped (already returned or reason provided)")
if updated:
log_doc.save(ignore_permissions=True)
diff --git a/beams/beams/custom_scripts/project_dashboard/project_dashboard.py b/beams/beams/custom_scripts/project_dashboard/project_dashboard.py
index 6c3af4dce..8ad42be9d 100644
--- a/beams/beams/custom_scripts/project_dashboard/project_dashboard.py
+++ b/beams/beams/custom_scripts/project_dashboard/project_dashboard.py
@@ -17,6 +17,5 @@ def get_data(data=None):
{"label": _("Budgets"), "items": ["Budget", "Adhoc Budget"]},
{"label": _("Programs"), "items": ["Equipment Hire Request", "Equipment Request", "Transportation Request", "Technical Request","External Resource Request"]},
{"label": _("Transactions"), "items": ["Equipment Transaction Log", "Vehicle Transaction Log","Manpower Transaction Log"]}
-
],
}
diff --git a/beams/beams/doctype/allocated_resource_detail/__init__.py b/beams/beams/doctype/allocated_resource_detail/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.json b/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.json
new file mode 100644
index 000000000..8d854488b
--- /dev/null
+++ b/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.json
@@ -0,0 +1,62 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2025-01-18 12:03:23.303907",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "department",
+ "designation",
+ "employee",
+ "hired_personnel",
+ "hired_personnel_contact_info"
+ ],
+ "fields": [
+ {
+ "fieldname": "designation",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Designation",
+ "options": "Designation"
+ },
+ {
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Employee",
+ "options": "Employee"
+ },
+ {
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Department",
+ "options": "Department"
+ },
+ {
+ "fieldname": "hired_personnel",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Hired Personnel"
+ },
+ {
+ "fieldname": "hired_personnel_contact_info",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Hired Personnel Contact Info"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2025-03-19 14:32:56.747852",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Allocated Resource Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.py b/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.py
new file mode 100644
index 000000000..13a3eacd3
--- /dev/null
+++ b/beams/beams/doctype/allocated_resource_detail/allocated_resource_detail.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class AllocatedResourceDetail(Document):
+ pass
diff --git a/beams/beams/doctype/batta_claim/batta_claim.js b/beams/beams/doctype/batta_claim/batta_claim.js
index 289a0b81a..2e7d6da75 100644
--- a/beams/beams/doctype/batta_claim/batta_claim.js
+++ b/beams/beams/doctype/batta_claim/batta_claim.js
@@ -2,59 +2,89 @@
// For license information, please see license.txt
frappe.ui.form.on('Batta Claim', {
- onload: function (frm) {
+ validate: function(frm) {
+ calculate_total_distance_travelled(frm);
+ calculate_total_daily_batta(frm);
+ update_all_daily_batta(frm);
+ calculate_batta(frm);
+ calculate_total_hours(frm);
+ },
+ batta: function(frm) {
+ update_all_daily_batta(frm);
+ },
+ ot_batta: function(frm) {
+ update_all_daily_batta(frm);
+ },
+ onload: function(frm) {
+ handle_designation_based_on_batta_type(frm);
+ },
+ batta_type: function(frm) {
+ handle_designation_based_on_batta_type(frm);
set_batta_based_on_options(frm);
- calculate_totals(frm);
- calculate_batta_totals(frm);
+ },
+ employee: function(frm) {
+ handle_designation_based_on_batta_type(frm);
},
room_rent_batta: function(frm) {
- calculate_batta_totals(frm);
- },
- daily_batta_with_overnight_stay: function(frm) {
- calculate_batta_totals(frm);
- },
- daily_batta_without_overnight_stay: function(frm) {
- calculate_batta_totals(frm);
- },
- food_allowance: function(frm) {
- calculate_batta_totals(frm);
- },
- origin: function(frm) {
- update_work_detail(frm);
+ calculate_batta(frm);
+ if (frm.doc.room_rent_batta < 0) {
+ frappe.msgprint({
+ message: "Room Rent Batta cannot be negative.",
+ indicator: "red"
+ });
+ frm.set_value("room_rent_batta", 0);
+ }
+ },
+ daily_batta_without_overnight_stay: function(frm) {
+ calculate_batta(frm);
+ if (frm.doc.daily_batta_without_overnight_stay < 0) {
+ frappe.msgprint({
+ message: "Daily Batta Without Overnight Stay cannot be negative.",
+ indicator: "red"
+ });
+ frm.set_value("daily_batta_without_overnight_stay", 0);
+ }
},
- destination: function(frm) {
- update_work_detail(frm);
+ daily_batta_with_overnight_stay: function(frm) {
+ calculate_batta(frm);
+ if (frm.doc.daily_batta_with_overnight_stay < 0) {
+ frappe.msgprint({
+ message: "Daily Batta With Overnight Stay cannot be negative.",
+ indicator: "red"
+ });
+ frm.set_value("daily_batta_with_overnight_stay", 0);
+ }
},
- designation: function(frm) {
- frm.trigger('calculate_batta');
+ total_distance_travelled_km: function(frm) {
+ calculate_allowance(frm);
+ },
+ total_hours: function(frm) {
+ calculate_allowance(frm);
},
is_travelling_outside_kerala: function(frm) {
- frm.trigger('calculate_batta');
+ update_all_daily_batta(frm);
+ calculate_allowance(frm);
},
is_overnight_stay: function(frm) {
- frm.trigger('calculate_batta');
+ update_all_daily_batta(frm);
+ calculate_allowance(frm);
+ frm.doc.work_detail.forEach(row => {
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ })
},
is_avail_room_rent: function(frm) {
- frm.trigger('calculate_batta');
+ update_all_daily_batta(frm);
+ calculate_allowance(frm);
},
- total_distance_travelled_km: function(frm) {
- frm.trigger('calculate_batta');
+ is_delhi_bureau: function(frm) {
+ frm.doc.work_detail.forEach(row => {
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ })
},
- work_detail_add: function(frm, cdt, cdn) {
- calculate_total_distance_travelled(frm);
- },
- work_detail_onform_render: function(frm, cdt, cdn) {
- calculate_total_distance_travelled(frm);
- },
- work_detail_remove: function(frm, cdt, cdn) {
- calculate_total_distance_travelled(frm);
- },
- refresh: function (frm) {
- set_batta_based_on_options(frm);
- calculate_totals(frm);
- calculate_total_distance_travelled(frm);
- calculate_batta_totals(frm);
-
+ //fetching policy values and setting fields read-only accordingly
+ refresh: function(frm) {
frappe.call({
method: "beams.beams.doctype.batta_claim.batta_claim.get_batta_policy_values",
callback: function(response) {
@@ -68,110 +98,212 @@ frappe.ui.form.on('Batta Claim', {
frm.set_df_property('daily_batta_without_overnight_stay', 'read_only', is_actual_daily_batta_without_overnight_stay == 0);
frm.set_df_property('daily_batta_with_overnight_stay', 'read_only', is_actual_daily_batta_with_overnight_stay == 0);
frm.set_df_property('room_rent_batta', 'read_only', is_actual_room_rent_batta == 0);
- frm.set_df_property('food_allowance', 'read_only', is_actual_food_allowance == 0);
// Refresh the fields to reflect the changes
frm.refresh_field('daily_batta_without_overnight_stay');
frm.refresh_field('daily_batta_with_overnight_stay');
frm.refresh_field('room_rent_batta');
- frm.refresh_field('food_allowance');
+
+ frm.fields_dict['work_detail'].grid.update_docfield_property('breakfast', 'read_only', is_actual_food_allowance == 0);
+ frm.fields_dict['work_detail'].grid.update_docfield_property('lunch', 'read_only', is_actual_food_allowance == 0);
+ frm.fields_dict['work_detail'].grid.update_docfield_property('dinner', 'read_only', is_actual_food_allowance == 0);
+
+ // Refresh child table
+ frm.refresh_field('work_detail');
}
}
});
+ }
+});
+
+frappe.ui.form.on('Work Detail', {
+ distance_travelled_km: function(frm, cdt, cdn) {
+ calculate_total_distance_travelled(frm);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
},
- batta_type: function(frm) {
- set_batta_based_on_options(frm);
- frm.doc.work_detail.forEach(function(row) {
- frappe.model.set_value(row.doctype, row.name, 'batta_type', frm.doc.batta_type);
- });
- frm.refresh_field('work_detail');
- set_batta_based_on_options(frm);
- handle_designation_based_on_batta_type(frm);
- frm.set_value('batta', 0);
- },
- employee: function (frm) {
- handle_designation_based_on_batta_type(frm);
+ daily_batta: function(frm, cdt, cdn) {
+ calculate_total_batta(frm, cdt, cdn);
},
- batta: function (frm) {
- // Loop through each row in the work_detail child table to calculate the row values based on the updated batta
- frm.doc.work_detail.forEach(function(row) {
- if (frm.doc.batta_based_on === 'Daily') {
- row.number_of_days = Math.ceil(row.total_hours / 24);
- row.daily_batta = row.number_of_days * frm.doc.batta;
- } else if (frm.doc.batta_based_on === 'Hours') {
- row.daily_batta = (row.total_hours - row.ot_hours) * frm.doc.batta;
- }
-
- row.ot_batta = row.ot_hours * frm.doc.ot_batta;
+ breakfast: function(frm, cdt, cdn) {
+ let child = locals[cdt][cdn];
+ if (child.breakfast < 0) {
+ frappe.msgprint({
+ message: "Breakfast cannot be negative.",
+ indicator: "red"
+ });
- // Refresh the fields for each row in the child table
- frm.refresh_field('work_detail');
- });
- // After updating all the rows, recalculate the total values
- calculate_totals(frm);
+ frappe.model.set_value(cdt, cdn, "breakfast", 0); // Reset to 0
+ }
+ calculate_total_food_allowance(frm, cdt, cdn);
+ calculate_total_batta(frm, cdt, cdn);
},
- calculate_batta: function(frm) {
- // Ensure designation and total distance are filled before calling the function
- if (frm.doc.designation && frm.doc.total_distance_travelled_km) {
- // Sum up total_hours from the work_detail child table
- let total_hours = 0;
- if (frm.doc.work_detail) {
- frm.doc.work_detail.forEach(row => {
- total_hours += row.total_hours || 0;
- });
- }
+ lunch: function(frm, cdt, cdn) {
+ let child = locals[cdt][cdn];
+ if (child.lunch < 0) {
+ frappe.msgprint({
+ message: "Lunch cannot be negative.",
+ indicator: "red"
+ });
- frappe.call({
- method: "beams.beams.doctype.batta_claim.batta_claim.calculate_batta_allowance",
- args: {
- designation: frm.doc.designation,
- is_travelling_outside_kerala: frm.doc.is_travelling_outside_kerala,
- is_avail_room_rent: frm.doc.is_avail_room_rent,
- is_overnight_stay: frm.doc.is_overnight_stay,
- total_distance_travelled_km: frm.doc.total_distance_travelled_km,
- total_hours: total_hours,
- },
- callback: function(r) {
- if (r.message) {
- // Set batta values in the form
- frm.set_value('batta', r.message.batta);
- frm.set_value('room_rent_batta', r.message.room_rent_batta);
- frm.set_value('daily_batta_with_overnight_stay', r.message.daily_batta_with_overnight_stay);
- frm.set_value('daily_batta_without_overnight_stay', r.message.daily_batta_without_overnight_stay);
- frm.set_value('food_allowance', r.message.food_allowance);
- }
- }
+ frappe.model.set_value(cdt, cdn, "lunch", 0); // Reset to 0
+ }
+ calculate_total_food_allowance(frm, cdt, cdn);
+ calculate_total_batta(frm, cdt, cdn);
+ },
+ dinner: function(frm, cdt, cdn) {
+ let child = locals[cdt][cdn];
+ if (child.dinner < 0) {
+ frappe.msgprint({
+ message: "Dinner cannot be negative.",
+ indicator: "red"
});
+
+ frappe.model.set_value(cdt, cdn, "dinner", 0); // Reset to 0
}
- }
-});
+ calculate_total_food_allowance(frm, cdt, cdn);
+ calculate_total_batta(frm, cdt, cdn);
+ },
+ total_batta: function(frm, cdt, cdn) {
+ calculate_total_daily_batta(frm, cdt, cdn);
+ },
+ total_food_allowance: function(frm, cdt, cdn) {
+ calculate_total_batta(frm, cdt, cdn);
+ },
+ work_detail_add: function(frm, cdt, cdn) {
+ const { origin, destination } = frm.doc;
+ frappe.model.set_value(cdt, cdn, 'origin', origin);
+ frappe.model.set_value(cdt, cdn, 'destination', destination);
-frappe.ui.form.on('Work Detail', {
- from_date_and_time: function (frm, cdt, cdn) {
- validate_dates_and_calculate(frm, cdt, cdn);
+ calculate_total_distance_travelled(frm);
+ calculate_total_daily_batta(frm);
+ calculate_total_hours(frm);
+ setTimeout(() => {
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
},
- to_date_and_time: function (frm, cdt, cdn) {
- validate_dates_and_calculate(frm, cdt, cdn);
+ work_detail_remove: function(frm, cdt, cdn) {
+ calculate_total_distance_travelled(frm);
+ calculate_total_daily_batta(frm);
+ calculate_total_hours(frm);
+ setTimeout(() => {
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
+ },
+ total_hours: function(frm, cdt, cdn) {
+ calculate_daily_batta(frm, cdt, cdn);
+ calculate_total_hours(frm,cdt,cdn);
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ },
+ ot_hours: function(frm, cdt, cdn) {
+ calculate_daily_batta(frm, cdt, cdn);
},
- origin: function(frm) {
- update_work_detail(frm);
+ from_date_and_time: function(frm, cdt, cdn) {
+ calculate_hours(frm, cdt, cdn);
+ calculate_daily_batta(frm, cdt, cdn);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 500);
},
- destination: function(frm) {
- update_work_detail(frm);
+ to_date_and_time: function(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+
+ if (row.from_date_and_time && row.to_date_and_time) {
+ let from_date = new Date(row.from_date_and_time);
+ let to_date = new Date(row.to_date_and_time);
+
+ if (to_date <= from_date) {
+ frappe.msgprint(__('To Date & Time must be greater than From Date & Time'));
+ frappe.model.set_value(cdt, cdn, 'to_date_and_time', null);
+ return;
+ }
+ calculate_hours(frm, cdt, cdn);
+ calculate_daily_batta(frm, cdt, cdn);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 500);
}
+ }
});
-/* Function to set options for Batta Based On field based on Batta Type */
-function set_batta_based_on_options(frm) {
- if (frm.doc.batta_type === 'External') {
- frm.set_df_property('batta_based_on', 'options', 'Hours');
- frm.set_value('batta_based_on', 'Hours');
- } else {
- frm.set_df_property('batta_based_on', 'options', ['Daily']);
- frm.set_value('batta_based_on', 'Daily');
+/*
+ Calculates the total distance traveled based on all work detail entries.
+*/
+function calculate_total_distance_travelled(frm) {
+ let totalDistance = 0;
+ frm.doc.work_detail.forEach(row => {
+ totalDistance += row.distance_travelled_km || 0;
+ });
+ frm.set_value('total_distance_travelled_km', totalDistance);
+}
+
+/*
+ Calculates the total hours worked based on all work detail entries.
+*/
+function calculate_total_hours(frm) {
+ let totalHours = 0;
+ frm.doc.work_detail.forEach(row => {
+ totalHours += row.total_hours || 0;
+ });
+ frm.set_value('total_hours', totalHours);
+}
+
+/*
+ Calculates hours worked for a specific row based on the from and to date/time fields.
+*/
+function calculate_hours(frm, cdt, cdn) {
+ let row = frappe.get_doc(cdt, cdn);
+ if (row.from_date_and_time && row.to_date_and_time) {
+ let total_hours = (new Date(row.to_date_and_time) - new Date(row.from_date_and_time)) / (1000 * 60 * 60);
+ frappe.model.set_value(cdt, cdn, 'total_hours', total_hours.toFixed(2));
+ }
+}
+
+/*
+ Calculates the daily batta based on the total hours worked and the batta type.
+*/
+function calculate_daily_batta(frm, cdt, cdn) {
+ let row = frappe.get_doc(cdt, cdn);
+
+ if (!row.total_hours) row.total_hours = 0;
+
+ let number_of_days = Math.max(1, Math.ceil(row.total_hours / 24)); // Ensure at least 1 day
+ let daily_batta = 0;
+
+ if (frm.doc.batta_based_on === 'Daily') {
+ daily_batta = number_of_days * (frm.doc.batta || 0);
+ }
+
+ frappe.model.set_value(cdt, cdn, 'number_of_days', number_of_days);
+ frappe.model.set_value(cdt, cdn, 'daily_batta', daily_batta);
+}
+
+/*
+ Updates daily batta for all child rows in the work detail table.
+*/
+function update_all_daily_batta(frm) {
+ if (frm.doc.work_detail) {
+ frm.doc.work_detail.forEach(row => {
+ calculate_daily_batta(frm, row.doctype, row.name);
+ });
}
}
+/*
+ Calculates the total daily batta across all work detail entries.
+*/
+function calculate_total_daily_batta(frm) {
+ let totalDailyBatta = 0;
+ frm.doc.work_detail.forEach(row => {
+ totalDailyBatta += row.total_batta || 0;
+ });
+ frm.set_value('total_daily_batta', totalDailyBatta);
+}
+
/* Function to handle designation field based on batta_type */
function handle_designation_based_on_batta_type(frm) {
if (frm.doc.batta_type === 'Internal' && frm.doc.employee) {
@@ -183,148 +315,121 @@ function handle_designation_based_on_batta_type(frm) {
frappe.msgprint(__('Designation not found for the selected employee.'));
}
});
- // Clear designation for External
} else if (frm.doc.batta_type === 'External') {
frm.set_value('designation', '');
}
}
-
-/* Function to validate dates and perform calculations */
-function validate_dates_and_calculate(frm, cdt, cdn) {
- let row = locals[cdt][cdn];
-
- if (row.from_date_and_time && row.to_date_and_time) {
- let from_time = new Date(row.from_date_and_time);
- let to_time = new Date(row.to_date_and_time);
-
- // Validation: From date should not be greater than to date
- if (from_time > to_time) {
- frappe.msgprint(__('From Date and Time cannot be greater than To Date and Time'));
- frappe.model.set_value(cdt, cdn, 'to_date_and_time', '');
- return;
- }
- calculate_hours_and_totals(frm, cdt, cdn);
- }
-}
-
-/* Function to calculate hours and batta */
-function calculate_hours_and_totals(frm, cdt, cdn) {
- let row = locals[cdt][cdn];
-
- if (row.from_date_and_time && row.to_date_and_time) {
- let from_time = new Date(row.from_date_and_time);
- let to_time = new Date(row.to_date_and_time);
- let diff = (to_time - from_time) / (1000 * 60 * 60); // Difference in hours
-
- if (diff >= 0) {
- frappe.db.get_single_value('Beams Accounts Settings', 'default_working_hours')
- .then(default_working_hours => {
- row.total_hours = diff;
- row.ot_hours = diff > default_working_hours ? diff - default_working_hours : 0;
-
- if (frm.doc.batta_based_on === 'Daily') {
- row.number_of_days = Math.ceil(row.total_hours / 24);
- row.daily_batta = row.number_of_days * frm.doc.batta;
- } else if (frm.doc.batta_based_on === 'Hours') {
- row.number_of_days = Math.ceil(row.total_hours / 24);
- row.daily_batta = (row.total_hours - row.ot_hours) * frm.doc.batta;
- }
-
- row.ot_batta = row.ot_hours * frm.doc.ot_batta;
-
- frm.refresh_field('work_detail');
- calculate_totals(frm);
- });
- }
+/* Sets the batta-based options based on the selected batta type.*/
+function set_batta_based_on_options(frm) {
+ if (frm.doc.batta_type === 'External') {
+ frm.set_df_property('batta_based_on', 'options', 'Hours');
+ frm.set_value('batta_based_on', 'Hours');
+ } else {
+ frm.set_df_property('batta_based_on', 'options', ['Daily']);
+ frm.set_value('batta_based_on', 'Daily');
}
}
-/* Function to calculate total batta values */
-function calculate_totals(frm) {
- frm.call({
- method: "calculate_total_batta",
- doc: frm.doc,
- callback: function(response) {
- // Update the form fields with the calculated totals
- frm.set_value({
- 'total_daily_batta': response.message.total_daily_batta,
- 'total_ot_batta': response.message.total_ot_batta,
- 'total_driver_batta': response.message.total_driver_batta
- });
+/* Calculates total batta based on room rent, daily batta with and without overnight stay.*/
+function calculate_batta(frm) {
+ let total_batta = (frm.doc.room_rent_batta || 0)
+ + (frm.doc.daily_batta_without_overnight_stay || 0)
+ + (frm.doc.daily_batta_with_overnight_stay || 0);
- // Refresh the fields to update totals
- frm.refresh_field(['total_daily_batta', 'total_ot_batta', 'total_driver_batta']);
- }
- });
+ frm.set_value('batta', total_batta);
}
-/* Function to calculate batta values */
-function calculate_batta_totals(frm) {
- frm.call({
- method: "calculate_batta", // Replace with actual path to the Python function
- doc: frm.doc,
- callback: function(response) {
- // Update the form fields with the calculated totals from the Python method
- frm.set_value({
- 'room_rent_batta': response.message.room_rent_batta,
- 'daily_batta_with_overnight_stay': response.message.daily_batta_with_overnight_stay,
- 'daily_batta_without_overnight_stay': response.message.daily_batta_without_overnight_stay,
- 'food_allowance': response.message.food_allowance,
- 'batta': response.message.batta // Assuming 'batta' is the total batta field
- });
+function calculate_allowance(frm) {
+ if (!frm.doc.designation.length) {
+ frappe.msgprint(__("Please select a designation."));
+ return;
+ }
- // Refresh the fields to display updated totals
- frm.refresh_field(['room_rent_batta', 'daily_batta_with_overnight_stay', 'daily_batta_without_overnight_stay', 'food_allowance', 'batta']);
+ frappe.call({
+ method: "beams.beams.doctype.batta_claim.batta_claim.calculate_batta_allowance",
+ args: {
+ designation: frm.doc.designation,
+ is_travelling_outside_kerala: frm.doc.is_travelling_outside_kerala || 0,
+ is_overnight_stay: frm.doc.is_overnight_stay || 0,
+ is_avail_room_rent: frm.doc.is_avail_room_rent || 0,
+ total_distance_travelled_km: frm.doc.total_distance_travelled_km || 0,
+ total_hours: frm.doc.total_hours || 0
+ },
+ callback: function(r) {
+ if (r.message) {
+ frm.set_value("room_rent_batta", r.message.room_rent_batta);
+ frm.set_value("daily_batta_with_overnight_stay", r.message.daily_batta_with_overnight_stay);
+ frm.set_value("daily_batta_without_overnight_stay", r.message.daily_batta_without_overnight_stay);
+ frm.set_value("batta", r.message.batta);
+ }
}
});
}
-frappe.ui.form.on('Batta Claim', {
- origin: update_child_table,
- destination: update_child_table
-});
-
-function update_child_table(frm) {
- if (!frm.doc.work_detail) return;
-
- frm.doc.work_detail.forEach(row => {
- frappe.model.set_value(row.doctype, row.name, 'origin', frm.doc.origin || '');
- frappe.model.set_value(row.doctype, row.name, 'destination', frm.doc.destination || '');
- });
-}
+/* Determines eligibility for food allowance and updates fields accordingly.*/
+function set_batta_for_food_allowance(frm, cdt, cdn) {
+ let child = locals[cdt][cdn];
+ let designation = frm.doc.designation;
+ let is_overnight_stay = frm.doc.is_overnight_stay;
+ let is_delhi_bureau = frm.doc.is_delhi_bureau;
-frappe.ui.form.on('Work Detail', {
- work_detail_add: function(frm, cdt, cdn) {
- frappe.model.set_value(cdt, cdn, 'origin', frm.doc.origin || '');
- frappe.model.set_value(cdt, cdn, 'destination', frm.doc.destination || '');
+ if (designation.length <= 0) {
+ return;
}
-});
+ let is_eligible = false;
-function calculate_total_distance_travelled(frm) {
- let totalDistance = 0;
- // Sum all distance_travelled_km from the Work Detail child table
- frm.doc.work_detail.forEach(function(row) {
- if (row.distance_travelled_km) {
- totalDistance += row.distance_travelled_km;
+ if (is_delhi_bureau) {
+ if (child.distance_travelled_km >= 30 && child.total_hours > 4) {
+ is_eligible = true;
}
- });
- // Set the total_distance_travelled_km field with the calculated sum
- frm.set_value('total_distance_travelled_km', totalDistance);
+ } else {
+ if (child.distance_travelled_km >= 50 && child.distance_travelled_km < 100 && child.total_hours > 6) {
+ is_eligible = true;
+ }
+ }
+
+ if (is_overnight_stay) {
+ frappe.model.set_value(child.doctype, child.name, "breakfast", 0);
+ frappe.model.set_value(child.doctype, child.name, "lunch", 0);
+ frappe.model.set_value(child.doctype, child.name, "dinner", 0);
+ frappe.model.set_value(child.doctype, child.name, "total_food_allowance", 0);
+ return;
+ }
+ else if (is_eligible && !is_overnight_stay) {
+ frappe.call({
+ method: "beams.beams.doctype.batta_claim.batta_claim.get_batta_for_food_allowance",
+ args: {
+ designation: designation,
+ from_date_time: child.from_date_and_time,
+ to_date_time: child.to_date_and_time,
+ total_hrs: child.total_hours,
+ is_delhi_bureau: is_delhi_bureau
+ },
+ callback: function (r) {
+ if (r && r.message) {
+ let response = r.message;
+ frappe.model.set_value(child.doctype, child.name, "breakfast", response.break_fast);
+ frappe.model.set_value(child.doctype, child.name, "lunch", response.lunch);
+ frappe.model.set_value(child.doctype, child.name, "dinner", response.dinner);
+ frappe.model.set_value(child.doctype, child.name, "total_food_allowance", response.break_fast + response.lunch + response.dinner);
+ }
+ }
+ });
+ }
}
-function update_work_detail(frm) {
- const { origin, destination, work_detail } = frm.doc;
+/* Calculation of Total Food Allowance. */
+function calculate_total_food_allowance(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+ row.total_food_allowance = (row.breakfast || 0) + (row.lunch || 0) + (row.dinner || 0);
- // Update existing child rows with parent values
- work_detail.forEach((row, index) => {
- if (index >= 0) {
- if (!row.origin || !row.destination) {
- frappe.model.set_value(row.doctype, row.name, 'origin', origin);
- frappe.model.set_value(row.doctype, row.name, 'destination', destination);
- }
- }
- });
+ frm.refresh_field("work_detail");
+}
- frm.refresh_field('work_detail');
+/* Calculation of total batta based on daily batta and food allowance. */
+function calculate_total_batta(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+ frappe.model.set_value(cdt, cdn, "total_batta", (row.daily_batta || 0) + (row.total_food_allowance || 0));
+ frm.refresh_field("work_detail");
}
diff --git a/beams/beams/doctype/batta_claim/batta_claim.json b/beams/beams/doctype/batta_claim/batta_claim.json
index ef8c66c49..670440e60 100644
--- a/beams/beams/doctype/batta_claim/batta_claim.json
+++ b/beams/beams/doctype/batta_claim/batta_claim.json
@@ -15,6 +15,7 @@
"designation",
"company",
"bureau",
+ "is_delhi_bureau",
"purpose",
"column_break_lgjy",
"cost_centre",
@@ -32,19 +33,17 @@
"column_break_gbiv",
"daily_batta_with_overnight_stay",
"daily_batta_without_overnight_stay",
- "batta",
"column_break_jwtq",
- "food_allowance",
+ "batta",
"ot_batta",
"section_break_osak",
"work_detail",
+ "section_break_ozsf",
"total_distance_travelled_km",
+ "column_break_fxzl",
+ "total_hours",
"section_break_nsff",
- "total_daily_batta",
- "column_break_vksq",
- "total_ot_batta",
- "column_break_ofhv",
- "total_driver_batta"
+ "total_daily_batta"
],
"fields": [
{
@@ -65,7 +64,7 @@
"fieldname": "batta_type",
"fieldtype": "Select",
"label": "Batta Type",
- "options": "External\nInternal"
+ "options": "Internal\nExternal"
},
{
"depends_on": "eval:doc.batta_type == \"Internal\"\n",
@@ -89,7 +88,8 @@
"fieldname": "designation",
"fieldtype": "Link",
"label": "Designation",
- "options": "Designation"
+ "options": "Designation",
+ "read_only": 1
},
{
"depends_on": "eval:doc.batta_type == \"External\"\n",
@@ -116,6 +116,7 @@
{
"fieldname": "batta_based_on",
"fieldtype": "Select",
+ "hidden": 1,
"label": "Batta Based On",
"options": "Daily\nHours"
},
@@ -139,30 +140,9 @@
{
"fieldname": "total_daily_batta",
"fieldtype": "Currency",
- "label": "Total Daily Batta",
- "read_only": 1
- },
- {
- "depends_on": "eval:doc.batta_type == \"External\"",
- "fieldname": "total_ot_batta",
- "fieldtype": "Currency",
- "label": "Total OT Batta",
- "read_only": 1
- },
- {
- "fieldname": "total_driver_batta",
- "fieldtype": "Currency",
- "label": "Total Driver Batta",
+ "label": "Total Batta",
"read_only": 1
},
- {
- "fieldname": "column_break_vksq",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "column_break_ofhv",
- "fieldtype": "Column Break"
- },
{
"fieldname": "work_detail",
"fieldtype": "Table",
@@ -205,12 +185,6 @@
"fieldtype": "Small Text",
"label": "Purpose"
},
- {
- "fieldname": "total_distance_travelled_km",
- "fieldtype": "Float",
- "label": "Total Distance Travelled (KM)",
- "read_only": 1
- },
{
"depends_on": "eval: doc.batta_type == 'Internal'",
"fieldname": "mode_of_travelling",
@@ -266,13 +240,6 @@
"label": "Daily Batta Without Overnight Stay",
"precision": "2"
},
- {
- "depends_on": "eval:doc.batta_type == \"Internal\"",
- "fieldname": "food_allowance",
- "fieldtype": "Currency",
- "label": "Food Allowance",
- "precision": "2"
- },
{
"fieldname": "attach",
"fieldtype": "Attach",
@@ -284,6 +251,32 @@
"fieldname": "is_avail_room_rent",
"fieldtype": "Check",
"label": "Is Avail Room Rent"
+ },
+ {
+ "fieldname": "section_break_ozsf",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "column_break_fxzl",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_hours",
+ "fieldtype": "Float",
+ "label": "Total Hours",
+ "read_only": 1
+ },
+ {
+ "fieldname": "total_distance_travelled_km",
+ "fieldtype": "Float",
+ "label": "Total Distance Travelled(KM)",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "is_delhi_bureau",
+ "fieldtype": "Check",
+ "label": "Is Delhi Bureau"
}
],
"index_web_pages_for_search": 1,
@@ -298,7 +291,7 @@
"link_fieldname": "batta_claim_reference"
}
],
- "modified": "2025-03-21 15:21:24.428732",
+ "modified": "2025-03-27 13:44:09.312155",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Batta Claim",
diff --git a/beams/beams/doctype/batta_claim/batta_claim.py b/beams/beams/doctype/batta_claim/batta_claim.py
index a2e6e6fa3..8d10ddc14 100644
--- a/beams/beams/doctype/batta_claim/batta_claim.py
+++ b/beams/beams/doctype/batta_claim/batta_claim.py
@@ -3,6 +3,8 @@
import frappe
import json
+import re
+from frappe.utils import getdate, get_datetime, date_diff, add_days
from frappe.model.document import Document
@@ -15,21 +17,10 @@ def on_submit(self):
self.create_journal_entry_from_batta_claim()
def validate(self):
- # Call the method to calculate the total distance travelled
self.calculate_total_distance_travelled()
-
- def calculate_total_distance_travelled(self):
- total_distance = 0
-
- # Loop through the rows in the 'work_detail' child table
- if self.work_detail:
- for row in self.work_detail:
- if row.distance_travelled_km:
- total_distance += row.distance_travelled_km
-
- # Set the 'total_distance_travelled_km' field with the calculated sum
- self.total_distance_travelled_km = total_distance
-
+ self.calculate_total_daily_batta()
+ self.calculate_batta()
+ self.calculate_total_hours()
def create_purchase_invoice_from_batta_claim(self):
'''
@@ -72,64 +63,83 @@ def create_journal_entry_from_batta_claim(self):
'account': batta_payable_account,
'party_type': 'Employee',
'party': self.employee,
- 'debit_in_account_currency': self.total_driver_batta,
+ 'debit_in_account_currency': self.total_daily_batta,
'credit_in_account_currency': 0,
})
journal_entry.append('accounts', {
'account': batta_expense_account,
'debit_in_account_currency': 0,
- 'credit_in_account_currency': self.total_driver_batta,
+ 'credit_in_account_currency': self.total_daily_batta,
})
journal_entry.insert()
journal_entry.submit()
frappe.msgprint(f"Journal Entry {journal_entry.name} has been created successfully.", alert=True,indicator="green")
- @frappe.whitelist()
- def calculate_total_batta(doc):
- '''Function to calculate the Total Daily Batta based on data in work detail child table
- and batta
+ def calculate_total_distance_travelled(self):
+ '''
+ Calculation of Total Distance Travelled(km)
+ '''
+ total_distance = 0
+
+ if self.work_detail:
+ for row in self.work_detail:
+ if row.distance_travelled_km:
+ total_distance += row.distance_travelled_km
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_distance_travelled_km = total_distance
+
+ def calculate_total_hours(self):
+ '''
+ Calculation Of Total Hours
+ '''
+ total_hours = 0
+
+ if self.work_detail:
+ for row in self.work_detail:
+ if row.total_hours:
+ total_hours += float(row.total_hours)
+
+ self.total_hours = total_hours
+
+ def calculate_total_daily_batta(self):
+ '''
+ Calculation of Total Daily Batta
'''
total_daily_batta = 0
- total_ot_batta = 0
-
- # Loop through the work_detail child table and ensure default values are integers
- for row in doc.get('work_detail', []):
- total_daily_batta += row.get('daily_batta', 0) or 0
- total_ot_batta += row.get('ot_batta', 0) or 0
-
- # Total batta is the sum of total_daily_batta and total_ot_batta
- total_driver_batta = total_daily_batta + total_ot_batta
- return {
- 'total_daily_batta': total_daily_batta,
- 'total_ot_batta': total_ot_batta,
- 'total_driver_batta': total_driver_batta
- }
-
- @frappe.whitelist()
- def calculate_batta(doc):
- # Ensure that all fields default to 0 if they are None
- room_rent_batta = doc.get('room_rent_batta', 0) or 0
- daily_batta_with_overnight_stay = doc.get('daily_batta_with_overnight_stay', 0) or 0
- daily_batta_without_overnight_stay = doc.get('daily_batta_without_overnight_stay', 0) or 0
- food_allowance = doc.get('food_allowance', 0) or 0
-
- # Calculate the total batta
- batta = room_rent_batta + daily_batta_with_overnight_stay + daily_batta_without_overnight_stay + food_allowance
-
- return {
- 'room_rent_batta': room_rent_batta,
- 'daily_batta_with_overnight_stay': daily_batta_with_overnight_stay,
- 'daily_batta_without_overnight_stay': daily_batta_without_overnight_stay,
- 'food_allowance': food_allowance,
- 'batta': batta
- }
-
-# Batta Policy
+
+ if self.work_detail:
+ for row in self.work_detail:
+ if row.total_batta:
+ total_daily_batta += row.total_batta
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_daily_batta = total_daily_batta
+
+ def calculate_batta(self):
+ '''
+ Calculation of Total Batta based on room rent batta,daily batta with overnight stay and daily batta without Overnight stay
+ '''
+ self.batta = (self.room_rent_batta or 0) \
+ + (self.daily_batta_without_overnight_stay or 0) \
+ + (self.daily_batta_with_overnight_stay or 0)
+
@frappe.whitelist()
-def calculate_batta_allowance(designation, is_travelling_outside_kerala, is_overnight_stay,is_avail_room_rent, total_distance_travelled_km, total_hours):
- # Ensure distance and total_hours are floats or 0
- total_distance_travelled_km = float(total_distance_travelled_km or 0)
- total_hours = float(total_hours or 0)
+def calculate_batta_allowance(designation=None, is_travelling_outside_kerala=0, is_overnight_stay=0, is_avail_room_rent=0, total_distance_travelled_km=0, total_hours=0):
+ '''
+ Calculation Of Total Batta Allowance based on Batta Policy
+ '''
+ # Convert inputs to proper types
+ def sanitize_number(value):
+ """Extract a valid float from a string by keeping only the first valid decimal number."""
+ if isinstance(value, str):
+ match = re.search(r'\d+(\.\d+)?', value)
+ return float(match.group()) if match else 0.0
+ return float(value or 0.0)
+
+ # Convert inputs safely
+ total_distance_travelled_km = sanitize_number(total_distance_travelled_km)
+ total_hours = sanitize_number(total_hours)
# Fetch the Batta Policy for the given designation
batta_policy = frappe.get_all('Batta Policy', filters={'designation': designation}, fields=['*'])
@@ -138,78 +148,104 @@ def calculate_batta_allowance(designation, is_travelling_outside_kerala, is_over
return {"batta": 0}
policy = batta_policy[0]
- is_actual_room_rent = policy.get('is_actual') # Checkbox for Room Rent for Overnight Stay
- is_actual_daily_batta_with_overnight_stay = policy.get('is_actual_') # Checkbox for Daily Batta With Overnight Stay
- is_actual_daily_batta_without_overnight_stay = policy.get('is_actual__') # Checkbox for Daily Batta Without Overnight Stay
- is_actual_food_allowance = policy.get('is_actual___') # Get the first (and only) policy for the designation
- total_batta = 0
- # Safely handle NoneType by using a function
- def safe_add(value):
- return float(value) if value is not None else 0
+ # Get policy checkbox values
+ is_actual_room_rent = policy.get('is_actual') or 0 # Room Rent Checkbox
+ is_actual_daily_batta = policy.get('is_actual_') or 0 # Daily Batta with Overnight Stay Checkbox
+ is_actual_daily_batta_without_overnight = policy.get('is_actual__') or 0 # Daily Batta Without Overnight Stay Checkbox
- # Convert inputs to booleans
+ # Convert inputs to boolean
is_travelling_outside_kerala = bool(int(is_travelling_outside_kerala or 0))
is_overnight_stay = bool(int(is_overnight_stay or 0))
is_avail_room_rent = bool(int(is_avail_room_rent or 0))
- # Initialize daily batta and room rent variables
- daily_batta_without_overnight_stay = 0
+ # Initialize batta values
room_rent_batta = 0
daily_batta_with_overnight_stay = 0
- food_allowance = 0
-
- # Add Daily Batta (Inside Kerala) if distance >= 50 km and total_hours >= 8
- if total_distance_travelled_km >= 50 and total_hours >= 8:
- if is_actual_daily_batta_without_overnight_stay == 0:
- if not is_overnight_stay: # Ensure the 'is_overnight_stay' checkbox is not checked
- if is_travelling_outside_kerala:
- outside_kerala_batta = safe_add(policy.get('outside_kerala'))
- daily_batta_without_overnight_stay += outside_kerala_batta
- else:
- inside_kerala_batta = safe_add(policy.get('inside_kerala'))
- daily_batta_without_overnight_stay += inside_kerala_batta
-
- # Add to total_batta
- total_batta += daily_batta_without_overnight_stay
-
- if is_overnight_stay:
- if is_avail_room_rent:
- # Handle room rent addition
- if is_actual_room_rent == 0: # Add room rent only if checkbox is unchecked (value is 0)
- if is_travelling_outside_kerala:
- room_rent = safe_add(policy.get('outside_kerala_'))
- else:
- room_rent = safe_add(policy.get('inside_kerala_'))
- room_rent_batta += room_rent # Add room rent value to room_rent_batta
+ daily_batta_without_overnight_stay = 0
- # Handle daily batta with overnight stay addition
- if is_actual_daily_batta_with_overnight_stay == 0: # Add daily batta only if checkbox is unchecked (value is 0)
+ # Calculate Room Rent Batta
+ if is_overnight_stay and is_avail_room_rent:
+ if not is_actual_room_rent: # Check if policy is not actual
if is_travelling_outside_kerala:
- daily_batta_with_overnight_stay = safe_add(policy.get('outside_kerala__'))
+ room_rent_batta = float(policy.get('outside_kerala_', 0))
else:
- daily_batta_with_overnight_stay = safe_add(policy.get('inside_kerala__'))
+ room_rent_batta = float(policy.get('inside_kerala_', 0))
- # Add Room Rent and Daily Batta with Overnight Stay to total_batta
- total_batta += room_rent_batta
- total_batta += daily_batta_with_overnight_stay
+ # Calculate Daily Batta with Overnight Stay
+ if not is_actual_daily_batta: # Check if policy is not actual
+ if is_overnight_stay:
+ if is_travelling_outside_kerala:
+ daily_batta_with_overnight_stay = float(policy.get('outside_kerala__', 0))
+ else:
+ daily_batta_with_overnight_stay = float(policy.get('inside_kerala__', 0))
- # Add Food Allowance if total distance is >= 25 km and total_hours >= 6
- if total_distance_travelled_km >= 25 and total_hours >= 6:
- if is_actual_food_allowance == 0:
- food_allowance = safe_add(policy.get('break_fast')) + safe_add(policy.get('lunch')) + safe_add(policy.get('dinner'))
- total_batta += food_allowance
+ # Calculate Daily Batta without Overnight Stay
+ if not is_actual_daily_batta_without_overnight: # Check if policy is not actual
+ if not is_overnight_stay: # Ensure overnight stay is NOT checked
+ if total_distance_travelled_km >= 100 and total_hours >= 8: # Additional condition
+ if is_travelling_outside_kerala:
+ daily_batta_without_overnight_stay = float(policy.get('outside_kerala', 0))
+ else:
+ daily_batta_without_overnight_stay = float(policy.get('inside_kerala', 0))
- # Return all relevant values in a single dictionary
return {
"room_rent_batta": room_rent_batta,
"daily_batta_with_overnight_stay": daily_batta_with_overnight_stay,
- "daily_batta_without_overnight_stay": daily_batta_without_overnight_stay,
- "food_allowance": food_allowance,
- "batta": total_batta
+ "daily_batta_without_overnight_stay": daily_batta_without_overnight_stay
}
@frappe.whitelist()
def get_batta_policy_values():
+ '''
+ Fetch and return the batta policy values from the 'Batta Policy' doctype
+ '''
result = frappe.db.get_value('Batta Policy', {}, ['is_actual', 'is_actual_', 'is_actual__', 'is_actual___'], as_dict=True)
return result
+
+@frappe.whitelist()
+def get_batta_for_food_allowance(designation, from_date_time, to_date_time, total_hrs, is_delhi_bureau=False):
+ '''
+ Method to get Batta for Food
+ '''
+ values = { 'break_fast': 0, 'lunch': 0, 'dinner': 0 }
+ batta_policy = frappe.db.exists('Batta Policy', { 'designation': designation })
+ from_date_time = get_datetime(from_date_time)
+ to_date_time = get_datetime(to_date_time)
+ required_hours = 4 if is_delhi_bureau else 6
+
+ if batta_policy and float(total_hrs) > required_hours:
+ is_actual = frappe.db.get_value('Batta Policy', batta_policy, 'is_actual___')
+ if is_actual:
+ return values
+
+ break_fast, lunch, dinner = frappe.db.get_value('Batta Policy', batta_policy, ['break_fast', 'lunch', 'dinner'])
+
+ current_date = getdate(from_date_time)
+ end_date = getdate(to_date_time)
+
+ while current_date <= end_date:
+ # Define meal timings for the current day
+ break_fast_start_time = get_datetime(f'{current_date} 04:00')
+ break_fast_end_time = get_datetime(f'{current_date} 09:00')
+ lunch_start_time = get_datetime(f'{current_date} 12:30')
+ lunch_end_time = get_datetime(f'{current_date} 14:00')
+ dinner_start_time = get_datetime(f'{current_date} 18:00')
+ dinner_end_time = get_datetime(f'{current_date} 21:00')
+
+ # Check Breakfast
+ if (from_date_time <= break_fast_start_time <= to_date_time) or (from_date_time <= break_fast_end_time <= to_date_time):
+ values['break_fast'] += break_fast
+
+ # Check Lunch
+ if (from_date_time <= lunch_start_time <= to_date_time) or (from_date_time <= lunch_end_time <= to_date_time):
+ values['lunch'] += lunch
+
+ # Check Dinner
+ if (from_date_time <= dinner_start_time <= to_date_time) or (from_date_time <= dinner_end_time <= to_date_time):
+ values['dinner'] += dinner
+
+ # Move to the next day
+ current_date = add_days(current_date, 1)
+
+ return values
diff --git a/beams/beams/doctype/batta_policy/batta_policy.json b/beams/beams/doctype/batta_policy/batta_policy.json
index de7457081..5cbd58b39 100644
--- a/beams/beams/doctype/batta_policy/batta_policy.json
+++ b/beams/beams/doctype/batta_policy/batta_policy.json
@@ -57,7 +57,7 @@
{
"fieldname": "room_rent_overnightbills_section",
"fieldtype": "Section Break",
- "label": "Room Rent for OverNight Stay"
+ "label": "Room Rent for Overnight Stay"
},
{
"depends_on": "eval:doc.is_actual__ == \"0\"",
@@ -91,7 +91,7 @@
{
"fieldname": "daily_batta_with_overnight_stay_section",
"fieldtype": "Section Break",
- "label": " Daily Batta With OverNight Stay"
+ "label": " Daily Batta With Overnight Stay"
},
{
"fieldname": "column_break_xaxj",
@@ -110,10 +110,10 @@
"label": "Inside Kerala"
},
{
- "description": "Travel 50 kms with minimum 8 hours.\n",
+ "description": "Travel 100 kms with minimum 8 hours.\n",
"fieldname": "daily_batta_without_over_night_stay_section",
"fieldtype": "Section Break",
- "label": "Daily Batta Without OverNight Stay"
+ "label": "Daily Batta Without Overnight Stay"
},
{
"fieldname": "column_break_ixxb",
@@ -126,7 +126,7 @@
"label": "Inside Kerala"
},
{
- "description": "Travel 25 kms with minimum 6 hours ",
+ "description": "Travel 50 kms with minimum 6 hours",
"fieldname": "food_allowance_section",
"fieldtype": "Section Break",
"label": "Food Allowance "
@@ -188,7 +188,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2024-10-04 15:14:47.080979",
+ "modified": "2025-03-22 13:42:15.306374",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Batta Policy",
diff --git a/beams/beams/doctype/bureau_trip_details/__init__.py b/beams/beams/doctype/bureau_trip_details/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/bureau_trip_details/bureau_trip_details.json b/beams/beams/doctype/bureau_trip_details/bureau_trip_details.json
new file mode 100644
index 000000000..8d1e4ec42
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_details/bureau_trip_details.json
@@ -0,0 +1,210 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2025-06-19 10:01:52.888802",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "origin",
+ "destination",
+ "distance_travelled_km",
+ "number_of_days",
+ "batta_type",
+ "column_break_aerg",
+ "from_date_and_time",
+ "to_date_and_time",
+ "on_air_date",
+ "section_break_ikdi",
+ "breakfast",
+ "column_break_vnsw",
+ "lunch",
+ "column_break_atwg",
+ "dinner",
+ "column_break_gaok",
+ "total_food_allowance",
+ "section_break_wigg",
+ "daily_batta",
+ "column_break_uihk",
+ "ot_batta",
+ "column_break_cjsx",
+ "total_batta",
+ "section_break_elqj",
+ "purpose",
+ "total_hours",
+ "ot_hours"
+ ],
+ "fields": [
+ {
+ "fieldname": "origin",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Origin",
+ "options": "Location"
+ },
+ {
+ "fieldname": "destination",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Destination ",
+ "options": "Location"
+ },
+ {
+ "fieldname": "distance_travelled_km",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Distance Travelled(km) "
+ },
+ {
+ "fieldname": "number_of_days",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Number of Days",
+ "read_only": 1
+ },
+ {
+ "fieldname": "batta_type",
+ "fieldtype": "Select",
+ "hidden": 1,
+ "in_list_view": 1,
+ "label": "Batta Type",
+ "options": "External\nInternal",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_aerg",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "from_date_and_time",
+ "fieldtype": "Datetime",
+ "in_list_view": 1,
+ "label": "Start Date and Time"
+ },
+ {
+ "fieldname": "to_date_and_time",
+ "fieldtype": "Datetime",
+ "in_list_view": 1,
+ "label": "End Date and Time"
+ },
+ {
+ "fieldname": "on_air_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "On Air date"
+ },
+ {
+ "fieldname": "section_break_ikdi",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "breakfast",
+ "fieldtype": "Currency",
+ "label": "BreakFast",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_vnsw",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "lunch",
+ "fieldtype": "Currency",
+ "label": "Lunch",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_atwg",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "dinner",
+ "fieldtype": "Currency",
+ "label": "Dinner",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_gaok",
+ "fieldtype": "Column Break",
+ "read_only": 1
+ },
+ {
+ "fieldname": "total_food_allowance",
+ "fieldtype": "Currency",
+ "label": "Total Food Allowance",
+ "precision": "2"
+ },
+ {
+ "fieldname": "section_break_wigg",
+ "fieldtype": "Section Break"
+ },
+ {
+ "description": "Daily Batta Without Food Allowance",
+ "fieldname": "daily_batta",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": " Batta",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_uihk",
+ "fieldtype": "Column Break"
+ },
+ {
+ "depends_on": "eval:doc.batta_type == 'External'",
+ "fieldname": "ot_batta",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "OT Batta",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_cjsx",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_batta",
+ "fieldtype": "Currency",
+ "label": "Total Batta",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_elqj",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "purpose",
+ "fieldtype": "Small Text",
+ "label": "Purpose"
+ },
+ {
+ "fieldname": "total_hours",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Total Hours",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval:doc.batta_type == 'External'",
+ "fieldname": "ot_hours",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "OT Hours",
+ "read_only": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2025-06-19 10:36:52.888802",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Bureau Trip Details",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
diff --git a/beams/beams/doctype/bureau_trip_details/bureau_trip_details.py b/beams/beams/doctype/bureau_trip_details/bureau_trip_details.py
new file mode 100644
index 000000000..7d739b1ac
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_details/bureau_trip_details.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class BureauTripDetails(Document):
+ pass
diff --git a/beams/beams/doctype/bureau_trip_sheet/__init__.py b/beams/beams/doctype/bureau_trip_sheet/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.js b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.js
new file mode 100644
index 000000000..e112e39b9
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.js
@@ -0,0 +1,417 @@
+// Copyright (c) 2024, efeone and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Bureau Trip Details', {
+ from_date_and_time: function (frm, cdt, cdn) {
+ calculate_hours_and_days(frm, cdt, cdn);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 200);
+ },
+ to_date_and_time: function (frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+
+ if (row.from_date_and_time && row.to_date_and_time) {
+ let from_date = new Date(row.from_date_and_time);
+ let to_date = new Date(row.to_date_and_time);
+
+ if (to_date <= from_date) {
+ frappe.msgprint(__('To Date & Time must be greater than From Date & Time'));
+ frappe.model.set_value(cdt, cdn, 'to_date_and_time', null);
+ return;
+ }
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 200);
+ }
+
+ calculate_hours_and_days(frm, cdt, cdn);
+ },
+ total_hours: function (frm, cdt, cdn) {
+ calculate_daily_batta(frm, cdt, cdn);
+ calculate_ot_batta(frm, cdt, cdn);
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ },
+ ot_hours: function (frm, cdt, cdn) {
+ calculate_ot_batta(frm, cdt, cdn);
+ },
+ breakfast: function (frm, cdt, cdn) {
+ calculate_total_food_allowance(frm, cdt, cdn);
+ },
+ lunch: function (frm, cdt, cdn) {
+ calculate_total_food_allowance(frm, cdt, cdn);
+ },
+ dinner: function (frm, cdt, cdn) {
+ calculate_total_food_allowance(frm, cdt, cdn);
+ },
+ distance_travelled_km: function(frm, cdt, cdn) {
+ calculate_total_distance_travelled(frm, cdt, cdn);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
+ },
+ work_details_add: function(frm, cdt, cdn) {
+
+ calculate_total_distance_travelled(frm, cdt, cdn);
+
+ calculate_hours(frm, cdt, cdn);
+
+ calculate_total_daily_batta(frm, cdt, cdn);
+
+ calculate_total_ot_batta(frm, cdt, cdn);
+
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
+ },
+ work_details_remove: function(frm, cdt, cdn) {
+ calculate_total_distance_travelled(frm, cdt, cdn);
+ calculate_hours(frm, cdt, cdn);
+ calculate_total_daily_batta(frm, cdt, cdn);
+ calculate_total_ot_batta(frm, cdt, cdn);
+ setTimeout(() => {
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ calculate_batta(frm, cdt, cdn);
+ }, 30);
+ },
+ total_hours: function(frm, cdt, cdn) {
+ calculate_hours(frm, cdt, cdn);
+ set_batta_for_food_allowance(frm, cdt, cdn);
+ },
+ daily_batta: function(frm, cdt, cdn) {
+ calculate_total_food_allowance(frm, cdt, cdn);
+ },
+ total_batta: function(frm, cdt, cdn) {
+ calculate_total_daily_batta(frm, cdt, cdn);
+ },
+ ot_batta: function(frm, cdt, cdn) {
+ calculate_total_ot_batta(frm, cdt, cdn);
+ }
+
+});
+
+frappe.ui.form.on("Bureau Trip Sheet", {
+ refresh: function (frm) {
+ filter_supplier_field(frm);
+ update_all_daily_batta(frm);
+ update_all_ot_batta(frm);
+ calculate_allowance(frm);
+ },
+ validate: function (frm) {
+ update_all_daily_batta(frm);
+ update_all_ot_batta(frm);
+ calculate_batta(frm);
+ calculate_total_distance_travelled(frm);
+ calculate_hours(frm);
+ calculate_total_daily_batta(frm);
+ calculate_total_ot_batta(frm);
+ },
+ batta: function (frm) {
+ update_all_daily_batta(frm);
+ },
+ ot_batta: function (frm) {
+ update_all_ot_batta(frm);
+ },
+ daily_batta_with_overnight_stay: function (frm) {
+ calculate_batta(frm);
+ },
+ daily_batta_without_overnight_stay: function (frm) {
+ calculate_batta(frm);
+ },
+ total_daily_batta: function (frm) {
+ calculate_total_driver_batta(frm);
+ },
+ total_ot_batta: function (frm) {
+ calculate_total_driver_batta(frm);
+ },
+ is_overnight_stay: function (frm) {
+ calculate_allowance(frm);
+ calculate_daily_batta(frm);
+ },
+ is_travelling_outside_kerala: function (frm) {
+ calculate_allowance(frm);
+ calculate_daily_batta(frm);
+ },
+ total_distance_travelled_km: function (frm) {
+ calculate_allowance(frm);
+ },
+ total_hours: function(frm) {
+ calculate_allowance(frm);
+ },
+ is_overnight_stay: function(frm) {
+ calculate_allowance(frm);
+ frm.doc.work_details.forEach(row => {
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ set_batta_for_food_allowance(frm, row["doctype"], row["name"]);
+ })
+
+ },
+ refresh: function(frm) {
+ // Fetch Batta Policy values and set read-only properties
+ frappe.call({
+ method: "beams.beams.doctype.bureau_trip_sheet.bureau_trip_sheet.get_batta_policy_values",
+ callback: function(response) {
+ if (response.message) {
+ let is_actual_daily_batta_without_overnight_stay = response.message.is_actual__;
+ let is_actual_daily_batta_with_overnight_stay = response.message.is_actual_;
+ let is_actual_food_allowance = response.message.is_actual___;
+
+ // Set read-only properties
+ frm.set_df_property('daily_batta_without_overnight_stay', 'read_only', is_actual_daily_batta_without_overnight_stay == 0);
+ frm.set_df_property('daily_batta_with_overnight_stay', 'read_only', is_actual_daily_batta_with_overnight_stay == 0);
+
+ // Refresh fields
+ frm.refresh_field('daily_batta_without_overnight_stay');
+ frm.refresh_field('daily_batta_with_overnight_stay');
+
+ frm.fields_dict['work_details'].grid.update_docfield_property('breakfast', 'read_only', is_actual_food_allowance == 0);
+ frm.fields_dict['work_details'].grid.update_docfield_property('lunch', 'read_only', is_actual_food_allowance == 0);
+ frm.fields_dict['work_details'].grid.update_docfield_property('dinner', 'read_only', is_actual_food_allowance == 0);
+
+ // Refresh child table
+ frm.refresh_field('work_details');
+ }
+ }
+ });
+
+ // Call the supplier filter function
+ filter_supplier_field(frm);
+ },
+
+ onload: function(frm) {
+ // Ensure the filter is applied on form load as well
+ filter_supplier_field(frm);
+ }
+});
+
+/* Set filter for supplier field */
+function filter_supplier_field(frm) {
+ frm.set_query("supplier", function () {
+ return {
+ filters: {
+ is_transporter: 1
+ }
+ };
+ });
+}
+
+/* Calculate total hours, number of days, and overtime hours */
+function calculate_hours_and_days(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+
+ if (row.from_date_and_time && row.to_date_and_time) {
+ let from_date = new Date(row.from_date_and_time);
+ let to_date = new Date(row.to_date_and_time);
+
+ let total_hours = (to_date - from_date) / (1000 * 60 * 60);
+ let number_of_days = Math.ceil(total_hours / 24);
+
+ frappe.db.get_single_value('Beams Accounts Settings', 'default_working_hours')
+ .then(default_hours => {
+ default_hours = parseFloat(default_hours) || 0;
+ let ot_hours = Math.max(0, total_hours - default_hours);
+
+ frappe.model.set_value(cdt, cdn, 'total_hours', total_hours.toFixed(2));
+ frappe.model.set_value(cdt, cdn, 'ot_hours', ot_hours.toFixed(2));
+ frappe.model.set_value(cdt, cdn, 'number_of_days', number_of_days);
+
+ frm.refresh_field("work_details");
+ setTimeout(() => {
+ calculate_daily_batta(frm, cdt, cdn);
+ calculate_ot_batta(frm, cdt, cdn);
+ }, 200);
+ });
+ }
+}
+
+/* Calculate daily batta based on number of days and batta rate */
+function calculate_daily_batta(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+
+ let total_hours = row.total_hours || 0;
+ let number_of_days = Math.ceil(total_hours / 24);
+ let daily_batta = number_of_days * (frm.doc.batta || 0);
+
+ frappe.model.set_value(cdt, cdn, 'daily_batta', daily_batta);
+ frm.refresh_field('work_details');
+}
+
+/* Calculate overtime batta based on OT hours and OT batta rate */
+function calculate_ot_batta(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+
+ let ot_hours = row.ot_hours || 0;
+ let ot_batta = ot_hours * (frm.doc.ot_batta || 0);
+
+ frappe.model.set_value(cdt, cdn, 'ot_batta', ot_batta);
+ frm.refresh_field('work_details');
+}
+
+/* Update daily batta for all work details rows */
+function update_all_daily_batta(frm) {
+ if (frm.doc.work_details) {
+ frm.doc.work_details.forEach(row => {
+ calculate_daily_batta(frm, row.doctype, row.name);
+ });
+ setTimeout(() => {
+ frm.refresh_field('work_details');
+ calculate_daily_batta(frm, cdt, cdn);
+ calculate_ot_batta(frm, cdt, cdn);
+ }, 200);
+
+ }
+}
+
+
+/* Update OT batta for all work details rows */
+function update_all_ot_batta(frm) {
+ if (frm.doc.work_details) {
+ frm.doc.work_details.forEach(row => {
+ calculate_ot_batta(frm, row.doctype, row.name);
+ });
+ setTimeout(() => {
+ frm.refresh_field('work_details');
+ }, 200);
+ }
+}
+
+/* Calculate total batta by summing daily batta values */
+function calculate_batta(frm) {
+ let total_batta = (frm.doc.daily_batta_with_overnight_stay || 0) +
+ (frm.doc.daily_batta_without_overnight_stay || 0);
+
+ frappe.model.set_value(frm.doctype, frm.docname, 'batta', total_batta);
+}
+
+/* Calculate total food allowance and total batta for a row */
+function calculate_total_food_allowance(frm, cdt, cdn) {
+ let row = locals[cdt][cdn];
+ row.total_food_allowance = (row.breakfast || 0) + (row.lunch || 0) + (row.dinner || 0);
+ row.total_batta = row.total_food_allowance + (row.daily_batta || 0);
+
+ frm.refresh_field("work_details");
+
+ let total_batta_sum = frm.doc.work_details.reduce((sum, r) => sum + (r.total_batta || 0), 0);
+ frm.set_value("total_daily_batta", total_batta_sum);
+}
+
+/* Calculate total distance travelled across all work details rows */
+function calculate_total_distance_travelled(frm) {
+ let total_distance = 0;
+ frm.doc.work_details.forEach(row => {
+ total_distance += row.distance_travelled_km || 0;
+ });
+ frm.set_value('total_distance_travelled_km', total_distance);
+ frm.refresh_field("total_distance_travelled_km");
+}
+
+/* Calculate total hours from all work details rows */
+function calculate_hours(frm) {
+ let total_hours = 0;
+ frm.doc.work_details.forEach(row => {
+ total_hours += row.total_hours || 0;
+ });
+ frm.set_value('total_hours', total_hours);
+ frm.refresh_field("total_hours");
+}
+
+/* Calculate total daily batta for all work details rows */
+function calculate_total_daily_batta(frm) {
+ let total_batta = 0;
+ frm.doc.work_details.forEach(row => {
+ total_batta += row.total_batta || 0;
+ });
+ frm.set_value('total_daily_batta', total_batta);
+ frm.refresh_field("total_daily_batta");
+}
+
+/* Calculate total OT batta for all work details rows */
+function calculate_total_ot_batta(frm) {
+ let total_ot_batta = 0;
+ frm.doc.work_details.forEach(row => {
+ total_ot_batta += row.ot_batta || 0;
+ });
+ frm.set_value('total_ot_batta', total_ot_batta);
+ frm.refresh_field("total_ot_batta");
+}
+
+/* Calculate total driver batta as the sum of total daily batta and total OT batta */
+function calculate_total_driver_batta(frm) {
+ let total_daily_batta = frm.doc.total_daily_batta || 0;
+ let total_ot_batta = frm.doc.total_ot_batta || 0;
+
+ frm.set_value('total_driver_batta', total_daily_batta + total_ot_batta);
+ frm.refresh_field("total_driver_batta");
+}
+
+
+/* Determines eligibility for food allowance and updates fields accordingly.*/
+function set_batta_for_food_allowance(frm, cdt, cdn) {
+ let child = locals[cdt][cdn];
+
+ let designation = "Driver";
+ let is_overnight_stay = frm.doc.is_overnight_stay;
+
+ let is_eligible = false;
+ if (child.distance_travelled_km >= 50 && child.distance_travelled_km <= 100 && child.total_hours > 6) {
+ is_eligible = true;
+ }
+
+ if (is_overnight_stay) {
+ frappe.model.set_value(child.doctype, child.name, "breakfast", 0);
+ frappe.model.set_value(child.doctype, child.name, "lunch", 0);
+ frappe.model.set_value(child.doctype, child.name, "dinner", 0);
+ frappe.model.set_value(child.doctype, child.name, "total_food_allowance", 0);
+ return;
+ }
+
+ else if (is_eligible && !is_overnight_stay) {
+ frappe.call({
+ method: "beams.beams.doctype.bureau_trip_sheet.bureau_trip_sheet.get_batta_for_food_allowance",
+ args: {
+ designation: designation,
+ from_date_time: child.from_date_and_time,
+ to_date_time: child.to_date_and_time,
+ total_hrs: child.total_hours,
+ },
+ callback: function (r) {
+ if (r && r.message) {
+ let response = r.message;
+ frappe.model.set_value(child.doctype, child.name, "breakfast", response.break_fast);
+ frappe.model.set_value(child.doctype, child.name, "lunch", response.lunch);
+ frappe.model.set_value(child.doctype, child.name, "dinner", response.dinner);
+ frappe.model.set_value(child.doctype, child.name, "total_food_allowance", response.break_fast + response.lunch + response.dinner);
+ }
+ }
+ });
+ }
+}
+
+function calculate_allowance(frm) {
+ if (!frm.doc.supplier.length) {
+ frappe.msgprint(__("Please select a supplier."));
+ return;
+ }
+
+ frappe.call({
+ method: "beams.beams.doctype.bureau_trip_sheet.bureau_trip_sheet.calculate_batta_allowance",
+ args: {
+ designation: frm.doc.designation,
+ is_travelling_outside_kerala: frm.doc.is_travelling_outside_kerala || 0,
+ is_overnight_stay: frm.doc.is_overnight_stay || 0,
+ total_distance_travelled_km: frm.doc.total_distance_travelled_km || 0,
+ total_hours: frm.doc.total_hours || 0
+ },
+ callback: function(r) {
+ if (r.message) {
+ frm.set_value("daily_batta_with_overnight_stay", r.message.daily_batta_with_overnight_stay);
+ frm.set_value("daily_batta_without_overnight_stay", r.message.daily_batta_without_overnight_stay);
+ frm.set_value("batta", r.message.batta);
+ }
+ }
+ });
+}
diff --git a/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.json b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.json
new file mode 100644
index 000000000..05e80f149
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.json
@@ -0,0 +1,248 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:BTS-{YY}-{####}",
+ "creation": "2025-03-24 15:17:02.532199",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "section_break_qq5d",
+ "supplier",
+ "bureau",
+ "column_break_psaw",
+ "company",
+ "section_break_qavf",
+ "is_overnight_stay",
+ "is_travelling_outside_kerala",
+ "daily_batta_with_overnight_stay",
+ "daily_batta_without_overnight_stay",
+ "column_break_hzfr",
+ "ot_batta",
+ "batta",
+ "section_break_tjbr",
+ "work_details",
+ "section_break_xxsb",
+ "total_distance_travelled_km",
+ "column_break_fgob",
+ "total_hours",
+ "trip_details_section",
+ "departure_location",
+ "destination_location",
+ "column_break_cdph",
+ "starting_date_and_time",
+ "ending_date_and_time",
+ "amended_from",
+ "section_break_dwds",
+ "total_daily_batta",
+ "column_break_zjgd",
+ "total_ot_batta",
+ "column_break_jevl",
+ "total_driver_batta"
+ ],
+ "fields": [
+ {
+ "fieldname": "section_break_qq5d",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Supplier",
+ "options": "Supplier",
+ "reqd": 1
+ },
+ {
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company"
+ },
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "label": "Bureau",
+ "options": "Bureau"
+ },
+ {
+ "fieldname": "section_break_qavf",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fetch_from": "supplier.ot_batta",
+ "fieldname": "ot_batta",
+ "fieldtype": "Currency",
+ "label": "OT Batta",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval:doc.is_overnight_stay ==0",
+ "fieldname": "daily_batta_without_overnight_stay",
+ "fieldtype": "Currency",
+ "label": "Daily Batta Without Overnight Stay"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_overnight_stay",
+ "fieldtype": "Check",
+ "label": "Is Overnight Stay"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_travelling_outside_kerala",
+ "fieldtype": "Check",
+ "label": " Is Travelling Outside Kerala"
+ },
+ {
+ "depends_on": "eval:doc.is_overnight_stay ==1",
+ "fieldname": "daily_batta_with_overnight_stay",
+ "fieldtype": "Currency",
+ "label": "Daily Batta With Overnight Stay"
+ },
+ {
+ "fieldname": "batta",
+ "fieldtype": "Currency",
+ "label": "Batta",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_hzfr",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_tjbr",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "work_details",
+ "fieldtype": "Table",
+ "label": "Work Details",
+ "options": "Bureau Trip Details"
+ },
+ {
+ "fieldname": "trip_details_section",
+ "fieldtype": "Section Break",
+ "label": "Trip Details"
+ },
+ {
+ "fieldname": "departure_location",
+ "fieldtype": "Link",
+ "label": "Departure Location",
+ "options": "Location"
+ },
+ {
+ "fieldname": "destination_location",
+ "fieldtype": "Link",
+ "label": "Destination Location",
+ "options": "Location"
+ },
+ {
+ "fieldname": "ending_date_and_time",
+ "fieldtype": "Datetime",
+ "in_list_view": 1,
+ "label": "Ending Date and Time "
+ },
+ {
+ "fieldname": "starting_date_and_time",
+ "fieldtype": "Datetime",
+ "in_list_view": 1,
+ "label": "Starting Date and Time "
+ },
+ {
+ "fieldname": "column_break_cdph",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "column_break_psaw",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Bureau Trip Sheet",
+ "print_hide": 1,
+ "read_only": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "section_break_xxsb",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "total_distance_travelled_km",
+ "fieldtype": "Float",
+ "label": "Total Distance Travelled(KM)",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_fgob",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_hours",
+ "fieldtype": "Float",
+ "label": "Total Hours",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_dwds",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "total_daily_batta",
+ "fieldtype": "Currency",
+ "label": "Total Batta",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_zjgd",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_ot_batta",
+ "fieldtype": "Currency",
+ "label": "Total Ot Batta",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_jevl",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_driver_batta",
+ "fieldtype": "Currency",
+ "label": "Total Driver Batta",
+ "read_only": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2025-06-19 10:05:11.106938",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Bureau Trip Sheet",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.py b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.py
new file mode 100644
index 000000000..b6c386131
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_sheet/bureau_trip_sheet.py
@@ -0,0 +1,182 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe.model.document import Document
+from frappe.utils import get_datetime, getdate
+
+
+class BureauTripSheet(Document):
+ def validate(self):
+ self.calculate_batta()
+ self.calculate_total_distance_travelled()
+ self.calculate_hours()
+ self.calculate_total_daily_batta()
+ self.calculate_total_ot_batta()
+
+ def calculate_batta(self):
+ '''
+ Calculate the total batta (allowance) based on daily batta amounts.
+ '''
+ self.batta = (self.daily_batta_without_overnight_stay or 0) \
+ + (self.daily_batta_with_overnight_stay or 0)
+
+ def calculate_total_distance_travelled(self):
+ '''
+ Calculate the total distance travelled by summing up the
+ distance_travelled_km' values from work details.
+ '''
+ total_distance = 0
+
+ if self.work_details:
+ for row in self.work_details:
+ if row.distance_travelled_km:
+ total_distance += row.distance_travelled_km
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_distance_travelled_km = total_distance
+
+ def calculate_hours(self):
+ '''
+ Calculate the total hours worked by summing up the 'total_hours' values from work details.
+ '''
+ total_hours = 0
+
+ if self.work_details:
+ for row in self.work_details:
+ if row.hrs:
+ total_hours += float(row.hrs)
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_hours = total_hours
+
+ def calculate_total_daily_batta(self):
+ '''
+ Calculate the total daily batta by summing up the 'total_batta' values from work details.
+ '''
+ total_batta = 0
+
+ if self.work_details:
+ for row in self.work_details:
+ if row.total_batta:
+ total_batta += row.total_batta
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_daily_batta = total_batta
+
+ def calculate_total_ot_batta(self):
+ """
+ Calculate the total OT batta by summing up the 'ot_batta' values from work details.
+ """
+ total_ot_batta = 0
+
+ if self.work_details:
+ for row in self.work_details:
+ if row.ot_batta:
+ total_ot_batta += row.ot_batta
+
+ # Set the 'total_distance_travelled_km' field with the calculated sum
+ self.total_ot_batta = total_ot_batta
+
+@frappe.whitelist()
+def get_batta_for_food_allowance(designation, from_date_time, to_date_time, total_hrs):
+ '''
+ Method to get Batta for Food
+ '''
+ values = {'break_fast': 0, 'lunch': 0, 'dinner': 0}
+ batta_policy = frappe.db.exists('Batta Policy', {'designation': designation})
+ from_date_time = get_datetime(from_date_time)
+ to_date_time = get_datetime(to_date_time)
+ required_hours = 6
+
+ if batta_policy and float(total_hrs) > required_hours:
+ break_fast, lunch, dinner = frappe.db.get_value('Batta Policy', batta_policy, ['break_fast', 'lunch', 'dinner'])
+ same_date = getdate(from_date_time) == getdate(to_date_time)
+
+ meal_times = {
+ 'break_fast': ('04:00', '09:00', break_fast),
+ 'lunch': ('12:30', '14:00', lunch),
+ 'dinner': ('18:00', '21:00', dinner)
+ }
+
+ for meal, (start_time, end_time, allowance) in meal_times.items():
+ if same_date:
+ date_threshold = getdate(from_date_time)
+ if check_meal_time(from_date_time, to_date_time, date_threshold, start_time, end_time):
+ values[meal] = allowance
+ else:
+ # Check for both start and end dates
+ for date_threshold in [getdate(from_date_time), getdate(to_date_time)]:
+ if check_meal_time(from_date_time, to_date_time, date_threshold, start_time, end_time):
+ values[meal] += allowance
+
+ return values
+
+def check_meal_time(from_date_time, to_date_time, date_threshold, start_time, end_time):
+ start_datetime = get_datetime('{} {}'.format(date_threshold, start_time))
+ end_datetime = get_datetime('{} {}'.format(date_threshold, end_time))
+ return (from_date_time <= start_datetime <= to_date_time) or (from_date_time <= end_datetime <= to_date_time)
+
+@frappe.whitelist()
+def calculate_batta_allowance(designation=None, is_travelling_outside_kerala=0, is_overnight_stay=0, total_distance_travelled_km=0, total_hours=0):
+ '''
+ Calculation Of Total Batta Allowance based on Batta Policy
+ '''
+ #Convert inputs to proper types
+ def sanitize_number(value):
+ try:
+ return float(value)
+ except:
+ return 0
+ total_distance_travelled_km = sanitize_number(total_distance_travelled_km)
+ total_hours = sanitize_number(total_hours)
+
+ # Fetch the Batta Policy for the given designation
+ batta_policy = frappe.get_all('Batta Policy', filters={'designation': 'Driver'}, fields=['*'])
+ if not batta_policy:
+ frappe.throw(f"No Batta Policy found for the designation: {designation}")
+ return {"batta": 0}
+
+ policy = batta_policy[0]
+
+ # Get policy checkbox values
+ is_actual_daily_batta = policy.get('is_actual_') or 0 # Daily Batta with Overnight Stay Checkbox
+ is_actual_daily_batta_without_overnight = policy.get('is_actual__') or 0 # Daily Batta Without Overnight Stay Checkbox
+
+ # Convert inputs to boolean
+ is_travelling_outside_kerala = bool(int(is_travelling_outside_kerala or 0))
+ is_overnight_stay = bool(int(is_overnight_stay or 0))
+
+ # Initialize batta values
+ daily_batta_with_overnight_stay = 0
+ daily_batta_without_overnight_stay = 0
+
+ # Calculate Daily Batta with Overnight Stay
+ if not is_actual_daily_batta: # Check if policy is not actual
+ if is_overnight_stay:
+ if is_travelling_outside_kerala:
+ daily_batta_with_overnight_stay = float(policy.get('outside_kerala__', 0))
+ else:
+ daily_batta_with_overnight_stay = float(policy.get('inside_kerala__', 0))
+
+ # Calculate Daily Batta without Overnight Stay
+ if not is_actual_daily_batta_without_overnight: # Check if policy is not actual
+ if not is_overnight_stay: # Ensure overnight stay is NOT checked
+ if total_distance_travelled_km > 100 and total_hours >= 8: # Additional condition
+ if is_travelling_outside_kerala:
+ daily_batta_without_overnight_stay = float(policy.get('outside_kerala', 0))
+ else:
+ daily_batta_without_overnight_stay = float(policy.get('inside_kerala', 0))
+
+ return {
+ "daily_batta_with_overnight_stay": daily_batta_with_overnight_stay,
+ "daily_batta_without_overnight_stay": daily_batta_without_overnight_stay
+ }
+
+@frappe.whitelist()
+def get_batta_policy_values():
+ '''
+ Fetch and return the batta policy values from the 'Batta Policy' doctype
+ '''
+ result = frappe.db.get_value('Batta Policy', {}, ['is_actual', 'is_actual_', 'is_actual__', 'is_actual___'], as_dict=True)
+ return result
diff --git a/beams/beams/doctype/bureau_trip_sheet/test_bureau_trip_sheet.py b/beams/beams/doctype/bureau_trip_sheet/test_bureau_trip_sheet.py
new file mode 100644
index 000000000..e2d01c208
--- /dev/null
+++ b/beams/beams/doctype/bureau_trip_sheet/test_bureau_trip_sheet.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestBureauTripSheet(FrappeTestCase):
+ pass
diff --git a/beams/beams/doctype/company_kra/__init__.py b/beams/beams/doctype/company_kra/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/company_kra/company_kra.json b/beams/beams/doctype/company_kra/company_kra.json
new file mode 100644
index 000000000..54b981531
--- /dev/null
+++ b/beams/beams/doctype/company_kra/company_kra.json
@@ -0,0 +1,46 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-12-09 14:46:30.575713",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "kra",
+ "rating_by_ao",
+ "weightage"
+ ],
+ "fields": [
+ {
+ "fieldname": "kra",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "KRA",
+ "options": "KRA"
+ },
+ {
+ "fieldname": "rating_by_ao",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Rating by AO"
+ },
+ {
+ "fieldname": "weightage",
+ "fieldtype": "Percent",
+ "in_list_view": 1,
+ "label": "Weightage"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-12-10 15:22:00.264851",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Company KRA",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/company_kra/company_kra.py b/beams/beams/doctype/company_kra/company_kra.py
new file mode 100644
index 000000000..cf43b8bfb
--- /dev/null
+++ b/beams/beams/doctype/company_kra/company_kra.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class CompanyKRA(Document):
+ pass
diff --git a/beams/beams/doctype/department_cost_center/__init__.py b/beams/beams/doctype/department_cost_center/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/department_cost_center/department_cost_center.json b/beams/beams/doctype/department_cost_center/department_cost_center.json
new file mode 100644
index 000000000..1065541eb
--- /dev/null
+++ b/beams/beams/doctype/department_cost_center/department_cost_center.json
@@ -0,0 +1,33 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2025-03-22 15:52:56.514541",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "cost_center"
+ ],
+ "fields": [
+ {
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Cost Center",
+ "options": "Cost Center"
+ }
+ ],
+ "grid_page_length": 50,
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2025-03-22 15:56:38.422227",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Department Cost Center",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/department_cost_center/department_cost_center.py b/beams/beams/doctype/department_cost_center/department_cost_center.py
new file mode 100644
index 000000000..f464043ee
--- /dev/null
+++ b/beams/beams/doctype/department_cost_center/department_cost_center.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class DepartmentCostCenter(Document):
+ pass
diff --git a/beams/beams/doctype/department_kra/__init__.py b/beams/beams/doctype/department_kra/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/department_kra/department_kra.json b/beams/beams/doctype/department_kra/department_kra.json
new file mode 100644
index 000000000..3bbda6dc2
--- /dev/null
+++ b/beams/beams/doctype/department_kra/department_kra.json
@@ -0,0 +1,53 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-12-09 14:18:12.147592",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "parameter_name",
+ "rating",
+ "maximum_marks",
+ "maximum_marks_awarded_by_ao"
+ ],
+ "fields": [
+ {
+ "fieldname": "parameter_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Parameter Name "
+ },
+ {
+ "fieldname": "rating",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Rating",
+ "options": "\nOutstanding\nVery Good\nGood\nAverage\nBelow Average\nUnsatisfactory)"
+ },
+ {
+ "fieldname": "maximum_marks",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Maximum Marks"
+ },
+ {
+ "fieldname": "maximum_marks_awarded_by_ao",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Maximum Marks Awarded by AO"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-12-09 14:20:59.215655",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Department KRA",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/department_kra/department_kra.py b/beams/beams/doctype/department_kra/department_kra.py
new file mode 100644
index 000000000..3242363be
--- /dev/null
+++ b/beams/beams/doctype/department_kra/department_kra.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class DepartmentKRA(Document):
+ pass
diff --git a/beams/beams/doctype/employee_kra/__init__.py b/beams/beams/doctype/employee_kra/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/employee_kra/employee_kra.json b/beams/beams/doctype/employee_kra/employee_kra.json
new file mode 100644
index 000000000..cdad93a09
--- /dev/null
+++ b/beams/beams/doctype/employee_kra/employee_kra.json
@@ -0,0 +1,60 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-12-09 12:31:12.065337",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "kra",
+ "goals",
+ "marks_by_employee",
+ "maximum_marks",
+ "marks_awarded_by_ao"
+ ],
+ "fields": [
+ {
+ "fieldname": "kra",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "KRA",
+ "options": "KRA"
+ },
+ {
+ "fieldname": "goals",
+ "fieldtype": "Long Text",
+ "in_list_view": 1,
+ "label": "Goals"
+ },
+ {
+ "fieldname": "marks_by_employee",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Marks by Employee"
+ },
+ {
+ "fieldname": "marks_awarded_by_ao",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Marks Awarded by AO"
+ },
+ {
+ "fieldname": "maximum_marks",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Maximum Marks"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-12-10 12:35:10.081353",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Employee KRA",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/employee_kra/employee_kra.py b/beams/beams/doctype/employee_kra/employee_kra.py
new file mode 100644
index 000000000..215074d4b
--- /dev/null
+++ b/beams/beams/doctype/employee_kra/employee_kra.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class EmployeeKRA(Document):
+ pass
diff --git a/beams/beams/doctype/employees/__init__.py b/beams/beams/doctype/employees/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/employees/employees.json b/beams/beams/doctype/employees/employees.json
new file mode 100644
index 000000000..6a0fdf8e1
--- /dev/null
+++ b/beams/beams/doctype/employees/employees.json
@@ -0,0 +1,35 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:EMP-{####}",
+ "creation": "2025-01-31 17:30:40.328297",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "employee"
+ ],
+ "fields": [
+ {
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Employee",
+ "options": "Employee",
+ "reqd": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2025-03-17 13:38:54.789466",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Employees",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/employees/employees.py b/beams/beams/doctype/employees/employees.py
new file mode 100644
index 000000000..ac2b852b0
--- /dev/null
+++ b/beams/beams/doctype/employees/employees.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class Employees(Document):
+ pass
diff --git a/beams/beams/doctype/employees_left/__init__.py b/beams/beams/doctype/employees_left/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/employees_left/employees_left.json b/beams/beams/doctype/employees_left/employees_left.json
new file mode 100644
index 000000000..8f655ee38
--- /dev/null
+++ b/beams/beams/doctype/employees_left/employees_left.json
@@ -0,0 +1,33 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-10-05 14:32:59.679775",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "employee"
+ ],
+ "fields": [
+ {
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Employee",
+ "options": "Employee",
+ "reqd": 1
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-10-05 15:32:02.009067",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Employees Left",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/employees_left/employees_left.py b/beams/beams/doctype/employees_left/employees_left.py
new file mode 100644
index 000000000..d5f4a8aeb
--- /dev/null
+++ b/beams/beams/doctype/employees_left/employees_left.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class EmployeesLeft(Document):
+ pass
diff --git a/beams/beams/doctype/outward_pass/outward_pass.js b/beams/beams/doctype/outward_pass/outward_pass.js
index 95ca4de54..0d7be9177 100644
--- a/beams/beams/doctype/outward_pass/outward_pass.js
+++ b/beams/beams/doctype/outward_pass/outward_pass.js
@@ -111,4 +111,3 @@ function mergeArrays(arr1, arr2, key) {
);
return unique;
}
-
diff --git a/beams/beams/doctype/petty_cash_request/petty_cash_request.js b/beams/beams/doctype/petty_cash_request/petty_cash_request.js
index 50c7613da..fda8d9cbe 100644
--- a/beams/beams/doctype/petty_cash_request/petty_cash_request.js
+++ b/beams/beams/doctype/petty_cash_request/petty_cash_request.js
@@ -36,6 +36,15 @@ frappe.ui.form.on("Petty Cash Request", {
}
}
});
+ },
+ validate: function (frm) {
+ if (frm.doc.requested_amount <= 0) {
+ frappe.throw({
+ title: __("Invalid Amount"),
+ message: __("Requested Amount should be greater than 0. Please enter a valid amount."),
+ indicator: "red"
+ });
+ }
}
});
diff --git a/beams/beams/doctype/petty_cash_request/petty_cash_request.json b/beams/beams/doctype/petty_cash_request/petty_cash_request.json
index 2d70f5d93..133d779d1 100644
--- a/beams/beams/doctype/petty_cash_request/petty_cash_request.json
+++ b/beams/beams/doctype/petty_cash_request/petty_cash_request.json
@@ -14,7 +14,8 @@
"column_break_pflc",
"petty_cash_account",
"account",
- "requested_amount"
+ "requested_amount",
+ "reason"
],
"fields": [
{
@@ -71,12 +72,17 @@
"fieldtype": "Link",
"label": "Petty Cash Account",
"options": "Mode of Payment"
+ },
+ {
+ "fieldname": "reason",
+ "fieldtype": "Small Text",
+ "label": "Reason"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2025-03-21 15:48:04.534573",
+ "modified": "2025-03-24 16:15:48.424785",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Petty Cash Request",
diff --git a/beams/beams/doctype/reference_document/__init__.py b/beams/beams/doctype/reference_document/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/reference_document/reference_document.json b/beams/beams/doctype/reference_document/reference_document.json
new file mode 100644
index 000000000..093a1e158
--- /dev/null
+++ b/beams/beams/doctype/reference_document/reference_document.json
@@ -0,0 +1,40 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:RD-{YY}-{####}",
+ "creation": "2025-01-21 16:03:27.737629",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "remarks",
+ "document"
+ ],
+ "fields": [
+ {
+ "fieldname": "remarks",
+ "fieldtype": "Small Text",
+ "in_list_view": 1,
+ "label": "Remarks"
+ },
+ {
+ "fieldname": "document",
+ "fieldtype": "Attach",
+ "in_list_view": 1,
+ "label": "Document"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2025-03-17 13:26:18.899356",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Reference Document",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/reference_document/reference_document.py b/beams/beams/doctype/reference_document/reference_document.py
new file mode 100644
index 000000000..e0da2888a
--- /dev/null
+++ b/beams/beams/doctype/reference_document/reference_document.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2025, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class ReferenceDocument(Document):
+ pass
diff --git a/beams/beams/doctype/revenue_account/revenue_account.json b/beams/beams/doctype/revenue_account/revenue_account.json
index 79ea86538..f815aff60 100644
--- a/beams/beams/doctype/revenue_account/revenue_account.json
+++ b/beams/beams/doctype/revenue_account/revenue_account.json
@@ -8,8 +8,11 @@
"field_order": [
"revenue_centre",
"account",
+ "revenue_group",
"column_break_quzd",
+ "revenue_region",
"revenue_amount",
+ "description",
"monthly_amount_distribution_section",
"april",
"may",
@@ -24,7 +27,23 @@
"december",
"january",
"february",
- "march"
+ "march",
+ "monthly_amount_distributioninr_section",
+ "april_inr",
+ "may_inr",
+ "june_inr",
+ "july_inr",
+ "column_break_ulxk",
+ "august_inr",
+ "september_inr",
+ "october_inr",
+ "november_inr",
+ "column_break_poio",
+ "december_inr",
+ "january_inr",
+ "february_inr",
+ "march_inr",
+ "revenue_amount_inr"
],
"fields": [
{
@@ -41,6 +60,7 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Revenue Amount",
+ "options": "company_currency",
"precision": "2",
"reqd": 1
},
@@ -123,17 +143,158 @@
"label": "December"
},
{
+ "fetch_from": "revenue_centre.account",
"fieldname": "account",
"fieldtype": "Link",
"label": "Account",
"options": "Account",
+ "read_only": 1,
"reqd": 1
+ },
+ {
+ "fieldname": "revenue_group",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Revenue Group",
+ "options": "Revenue Group",
+ "reqd": 1
+ },
+ {
+ "fieldname": "revenue_region",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Finance Region",
+ "options": "National\nGCC",
+ "reqd": 1
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "monthly_amount_distributioninr_section",
+ "fieldtype": "Section Break",
+ "label": "Monthly Amount Distribution (INR)"
+ },
+ {
+ "fieldname": "may_inr",
+ "fieldtype": "Currency",
+ "label": "May (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "june_inr",
+ "fieldtype": "Currency",
+ "label": "June (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "july_inr",
+ "fieldtype": "Currency",
+ "label": "July (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_ulxk",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "august_inr",
+ "fieldtype": "Currency",
+ "label": "August (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "september_inr",
+ "fieldtype": "Currency",
+ "label": "September (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "october_inr",
+ "fieldtype": "Currency",
+ "label": "October (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "november_inr",
+ "fieldtype": "Currency",
+ "label": "November (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_poio",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "december_inr",
+ "fieldtype": "Currency",
+ "label": "December (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "january_inr",
+ "fieldtype": "Currency",
+ "label": "January (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "february_inr",
+ "fieldtype": "Currency",
+ "label": "February (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "march_inr",
+ "fieldtype": "Currency",
+ "label": "March (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "revenue_amount_inr",
+ "fieldtype": "Currency",
+ "label": "Revenue Amount (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "april_inr",
+ "fieldtype": "Currency",
+ "label": "April (INR)",
+ "options": "default_currency",
+ "precision": "2",
+ "read_only": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2025-03-18 11:44:42.181253",
+ "modified": "2025-04-07 17:24:47.191935",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Revenue Account",
diff --git a/beams/beams/doctype/revenue_budget/revenue_budget.js b/beams/beams/doctype/revenue_budget/revenue_budget.js
index 61df55d20..c25d87d0e 100644
--- a/beams/beams/doctype/revenue_budget/revenue_budget.js
+++ b/beams/beams/doctype/revenue_budget/revenue_budget.js
@@ -6,6 +6,42 @@ frappe.ui.form.on("Revenue Budget", {
},
company: function (frm) {
set_filters(frm);
+ fetch_template(frm);
+ },
+ revenue_category: function (frm) {
+ set_filters(frm);
+ fetch_template(frm);
+ },
+ /* Fetch Revenue Template Items in to Revenue Accounts when a Revenue Template is Selected */
+ revenue_template: function(frm) {
+ if (frm.doc.revenue_template) {
+ frappe.call({
+ method: 'frappe.client.get',
+ args: {
+ doctype: 'Revenue Template',
+ name: frm.doc.revenue_template
+ },
+ callback: function (response) {
+ if (response.message) {
+ let revenue_template = response.message;
+
+ frm.clear_table('revenue_accounts');
+
+ // Loop through the revenue_template_item child table
+ let template_items = revenue_template.revenue_template_item || [];
+ template_items.forEach(function (item) {
+ let row = frm.add_child('revenue_accounts');
+ row.revenue_group = item.revenue_group;
+ row.account = item.account;
+ row.revenue_region = item.revenue_region;
+ row.revenue_centre = item.revenue_centre;
+ });
+
+ frm.refresh_field('revenue_accounts');
+ }
+ }
+ });
+ }
}
});
function set_filters(frm) {
@@ -16,6 +52,14 @@ function set_filters(frm) {
}
};
});
+ frm.set_query('revenue_template', function () {
+ return {
+ filters: {
+ company: frm.doc.company,
+ revenue_category: frm.doc.revenue_category
+ }
+ };
+ });
}
frappe.ui.form.on('Revenue Account', {
@@ -85,3 +129,22 @@ function calculate_revenue_amount(frm, cdt, cdn) {
frappe.model.set_value(cdt, cdn, 'revenue_amount', total);
frm.refresh_field('revenue_account');
}
+/* Fetch Revenue Template in Revenue Budget based on Revenue category and Selected company */
+function fetch_template(frm) {
+ if (frm.doc.revenue_category && frm.doc.company) {
+ frappe.call({
+ method: 'beams.beams.doctype.revenue_budget.revenue_budget.get_revenue_template',
+ args: {
+ revenue_category: frm.doc.revenue_category,
+ company: frm.doc.company
+ },
+ callback: function(r) {
+ if (r.message) {
+ frm.set_value('revenue_template', r.message);
+ } else {
+ frm.set_value('revenue_template', '');
+ }
+ }
+ });
+ }
+}
diff --git a/beams/beams/doctype/revenue_budget/revenue_budget.json b/beams/beams/doctype/revenue_budget/revenue_budget.json
index 7d18f1f5b..4753de269 100644
--- a/beams/beams/doctype/revenue_budget/revenue_budget.json
+++ b/beams/beams/doctype/revenue_budget/revenue_budget.json
@@ -1,18 +1,20 @@
{
"actions": [],
"allow_rename": 1,
- "autoname": "format:{revenue_group}-{revenue_region}/{fiscal_year}/{###}",
+ "autoname": "format:{revenue_category} {fiscal_year}-{abbreviation}",
"creation": "2025-01-29 09:40:07.549966",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"section_break_epzm",
"company",
- "revenue_group",
+ "abbreviation",
"revenue_category",
+ "default_currency",
+ "company_currency",
"column_break_wemo",
"fiscal_year",
- "revenue_region",
+ "revenue_template",
"naming_series",
"total_amount",
"section_break",
@@ -75,12 +77,38 @@
"read_only": 1
},
{
- "fieldname": "revenue_group",
+ "fieldname": "amended_from",
"fieldtype": "Link",
- "in_list_view": 1,
- "label": "Revenue Group",
- "options": "Revenue Group",
- "reqd": 1
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Revenue Budget",
+ "print_hide": 1,
+ "read_only": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "revenue_template",
+ "fieldtype": "Link",
+ "label": "Revenue Template",
+ "options": "Revenue Template"
+ },
+ {
+ "default": "INR",
+ "fieldname": "default_currency",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Default Currency",
+ "options": "Currency",
+ "read_only": 1
+ },
+ {
+ "fetch_from": "company.default_currency",
+ "fieldname": "company_currency",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Company Currency",
+ "options": "Currency",
+ "read_only": 1
},
{
"fieldname": "revenue_category",
@@ -90,27 +118,19 @@
"reqd": 1
},
{
- "fieldname": "revenue_region",
- "fieldtype": "Select",
- "label": "Revenue Region",
- "options": "National\nGCC",
- "reqd": 1
- },
- {
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "label": "Amended From",
- "no_copy": 1,
- "options": "Revenue Budget",
- "print_hide": 1,
- "read_only": 1,
- "search_index": 1
+ "fetch_from": "company.abbr",
+ "fieldname": "abbreviation",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Abbreviation",
+ "read_only": 1
}
],
+ "grid_page_length": 50,
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2025-03-18 12:09:29.003630",
+ "modified": "2025-04-07 15:00:03.238147",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Revenue Budget",
diff --git a/beams/beams/doctype/revenue_budget/revenue_budget.py b/beams/beams/doctype/revenue_budget/revenue_budget.py
index 59b21cf17..ae0aa53e2 100644
--- a/beams/beams/doctype/revenue_budget/revenue_budget.py
+++ b/beams/beams/doctype/revenue_budget/revenue_budget.py
@@ -5,10 +5,49 @@
from frappe.model.document import Document
class RevenueBudget(Document):
-
def before_save(self):
self.calculate_total_amount()
+ def validate(self):
+ self.convert_currency()
+
def calculate_total_amount(self):
total = sum([row.revenue_amount for row in self.get("revenue_accounts") if row.revenue_amount])
self.total_amount = total
+
+ def convert_currency(self):
+ """Convert Revenue amounts for non-INR companies"""
+ company_currency = frappe.db.get_value("Company", self.company, "default_currency")
+ exchange_rate = 1
+
+ if company_currency != "INR":
+ exchange_rate = frappe.db.get_value("Company", self.company, "exchange_rate_to_inr")
+ if not exchange_rate:
+ frappe.throw(
+ f"Please set Exchange Rate from {company_currency} to INR for {self.company}",
+ title="Message",
+ )
+
+ months = [
+ "january", "february", "march", "april", "may", "june",
+ "july", "august", "september", "october", "november", "december"
+ ]
+
+ def apply_conversion(row):
+ """Apply exchange rate conversion to a revenue row"""
+ row.revenue_amount_inr = row.revenue_amount * exchange_rate
+ for month in months:
+ setattr(row, f"{month}_inr", (getattr(row, month, 0) or 0) * exchange_rate)
+
+ for row in self.revenue_accounts:
+ apply_conversion(row)
+
+@frappe.whitelist()
+def get_revenue_template(revenue_category, company):
+ """Get Revenue Template based on Revenue category and selected Company"""
+ template = frappe.db.get_value(
+ "Revenue Template",
+ {"revenue_category": revenue_category, "company": company},
+ "name"
+ )
+ return template
diff --git a/beams/beams/doctype/revenue_centre/revenue_centre.js b/beams/beams/doctype/revenue_centre/revenue_centre.js
index 9dc746d1c..7991458b1 100644
--- a/beams/beams/doctype/revenue_centre/revenue_centre.js
+++ b/beams/beams/doctype/revenue_centre/revenue_centre.js
@@ -1,8 +1,14 @@
// Copyright (c) 2025, efeone and contributors
// For license information, please see license.txt
-// frappe.ui.form.on("Revenue Centre", {
-// refresh(frm) {
-
-// },
-// });
+frappe.ui.form.on("Revenue Centre", {
+ onload: function(frm) {
+ frm.set_query("account", function() {
+ return {
+ filters: {
+ account_type: "Income Account"
+ }
+ };
+ });
+ }
+});
diff --git a/beams/beams/doctype/revenue_centre/revenue_centre.json b/beams/beams/doctype/revenue_centre/revenue_centre.json
index 5193f51d0..8ec048246 100644
--- a/beams/beams/doctype/revenue_centre/revenue_centre.json
+++ b/beams/beams/doctype/revenue_centre/revenue_centre.json
@@ -6,19 +6,30 @@
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
- "revenue_centre"
+ "revenue_centre",
+ "account"
],
"fields": [
{
"fieldname": "revenue_centre",
"fieldtype": "Data",
+ "in_list_view": 1,
"label": "Revenue Centre",
+ "reqd": 1,
"unique": 1
+ },
+ {
+ "fieldname": "account",
+ "fieldtype": "Link",
+ "label": "Account",
+ "options": "Account",
+ "reqd": 1
}
],
+ "grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2025-03-18 11:35:03.479904",
+ "modified": "2025-04-07 10:10:07.817821",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Revenue Centre",
diff --git a/beams/beams/doctype/revenue_template/revenue_template.json b/beams/beams/doctype/revenue_template/revenue_template.json
index 5089290b6..4606a9729 100644
--- a/beams/beams/doctype/revenue_template/revenue_template.json
+++ b/beams/beams/doctype/revenue_template/revenue_template.json
@@ -1,24 +1,19 @@
{
"actions": [],
"allow_rename": 1,
- "autoname": "field:template_title",
+ "autoname": "format:{revenue_category} - {abbreviation}",
"creation": "2025-02-17 14:10:03.498118",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
- "template_title",
"company",
+ "abbreviation",
+ "column_break_ofsa",
+ "revenue_category",
"section_break_ybn1",
"revenue_template_item"
],
"fields": [
- {
- "fieldname": "template_title",
- "fieldtype": "Data",
- "label": "Template Title",
- "reqd": 1,
- "unique": 1
- },
{
"fieldname": "company",
"fieldtype": "Link",
@@ -36,15 +31,35 @@
"fieldtype": "Table",
"label": "Revenue Template Item",
"options": "Revenue Template Item"
+ },
+ {
+ "fieldname": "revenue_category",
+ "fieldtype": "Link",
+ "label": "Revenue Category",
+ "options": "Revenue Category",
+ "reqd": 1
+ },
+ {
+ "fetch_from": "company.abbr",
+ "fieldname": "abbreviation",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Abbreviation",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_ofsa",
+ "fieldtype": "Column Break"
}
],
+ "grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2025-02-21 13:33:27.864251",
+ "modified": "2025-04-07 14:45:56.321830",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Revenue Template",
- "naming_rule": "By fieldname",
+ "naming_rule": "Expression",
"owner": "Administrator",
"permissions": [
{
diff --git a/beams/beams/doctype/revenue_template_item/revenue_template_item.json b/beams/beams/doctype/revenue_template_item/revenue_template_item.json
index cca68e269..c2640ef10 100644
--- a/beams/beams/doctype/revenue_template_item/revenue_template_item.json
+++ b/beams/beams/doctype/revenue_template_item/revenue_template_item.json
@@ -7,9 +7,9 @@
"engine": "InnoDB",
"field_order": [
"revenue_centre",
- "revenue_group",
+ "account",
"column_break_vrbs",
- "revenue_category",
+ "revenue_group",
"revenue_region"
],
"fields": [
@@ -18,39 +18,44 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Revenue Group",
- "options": "Revenue Group"
- },
- {
- "fieldname": "revenue_category",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Revenue Category",
- "options": "Revenue Category"
+ "options": "Revenue Group",
+ "reqd": 1
},
{
"fieldname": "revenue_centre",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Revenue Centre",
- "options": "Account",
+ "options": "Revenue Centre",
"reqd": 1
},
{
"fieldname": "revenue_region",
- "fieldtype": "Link",
+ "fieldtype": "Select",
"in_list_view": 1,
- "label": "Revenue Region",
- "options": "Region"
+ "label": "Finance Region",
+ "options": "National\nGCC",
+ "reqd": 1
},
{
"fieldname": "column_break_vrbs",
"fieldtype": "Column Break"
+ },
+ {
+ "fetch_from": "revenue_centre.account",
+ "fieldname": "account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Account",
+ "options": "Account",
+ "reqd": 1
}
],
+ "grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2025-02-21 13:33:45.317169",
+ "modified": "2025-04-07 16:38:54.754188",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Revenue Template Item",
diff --git a/beams/beams/doctype/stringer_bill_date/__init__.py b/beams/beams/doctype/stringer_bill_date/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/beams/beams/doctype/stringer_bill_date/stringer_bill_date.json b/beams/beams/doctype/stringer_bill_date/stringer_bill_date.json
new file mode 100644
index 000000000..1865d1953
--- /dev/null
+++ b/beams/beams/doctype/stringer_bill_date/stringer_bill_date.json
@@ -0,0 +1,31 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-08-31 09:56:58.447444",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "date"
+ ],
+ "fields": [
+ {
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "Date"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2024-08-31 09:57:24.841923",
+ "modified_by": "Administrator",
+ "module": "BEAMS",
+ "name": "Stringer Bill Date",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/beams/beams/doctype/stringer_bill_date/stringer_bill_date.py b/beams/beams/doctype/stringer_bill_date/stringer_bill_date.py
new file mode 100644
index 000000000..c4933c2ad
--- /dev/null
+++ b/beams/beams/doctype/stringer_bill_date/stringer_bill_date.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, efeone and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class StringerBillDate(Document):
+ pass
diff --git a/beams/beams/doctype/trip_details/trip_details.json b/beams/beams/doctype/trip_details/trip_details.json
index 0244c0564..3b2279144 100644
--- a/beams/beams/doctype/trip_details/trip_details.json
+++ b/beams/beams/doctype/trip_details/trip_details.json
@@ -70,4 +70,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
-}
\ No newline at end of file
+}
diff --git a/beams/beams/doctype/vehicle_hire_request/vehicle_hire_request.py b/beams/beams/doctype/vehicle_hire_request/vehicle_hire_request.py
index 4c2fc6cfc..7c82a6327 100644
--- a/beams/beams/doctype/vehicle_hire_request/vehicle_hire_request.py
+++ b/beams/beams/doctype/vehicle_hire_request/vehicle_hire_request.py
@@ -78,7 +78,6 @@ def generate_external_vehicle_details_from_hire_request(self):
"""
Generate External Vehicle Details records from the Vehicle Hire Request child table
"""
- project = frappe.get_doc("Project", self.project)
for vehicle in self.required_vehicles:
external_vehicle_detail = frappe.new_doc("External Vehicle Details")
diff --git a/beams/beams/doctype/work_detail/work_detail.json b/beams/beams/doctype/work_detail/work_detail.json
index a7a4605b1..60ced23c0 100644
--- a/beams/beams/doctype/work_detail/work_detail.json
+++ b/beams/beams/doctype/work_detail/work_detail.json
@@ -15,23 +15,33 @@
"from_date_and_time",
"to_date_and_time",
"on_air_date",
+ "section_break_ikdi",
+ "breakfast",
+ "column_break_vnsw",
+ "lunch",
+ "column_break_atwg",
+ "dinner",
+ "column_break_gaok",
+ "total_food_allowance",
"section_break_wigg",
"daily_batta",
"column_break_uihk",
- "ot_batta",
+ "column_break_cjsx",
+ "total_batta",
"section_break_elqj",
"purpose",
- "total_hours",
- "ot_hours"
+ "total_hours"
],
"fields": [
{
+ "columns": 2,
"fieldname": "from_date_and_time",
"fieldtype": "Datetime",
"in_list_view": 1,
"label": "Start Date and Time"
},
{
+ "columns": 2,
"fieldname": "to_date_and_time",
"fieldtype": "Datetime",
"in_list_view": 1,
@@ -45,26 +55,11 @@
"read_only": 1
},
{
- "depends_on": "eval:doc.batta_type == 'External'",
- "fieldname": "ot_hours",
- "fieldtype": "Float",
- "in_list_view": 1,
- "label": "OT Hours",
- "read_only": 1
- },
- {
+ "description": "Daily Batta Without Food Allowance",
"fieldname": "daily_batta",
"fieldtype": "Currency",
"in_list_view": 1,
- "label": " Daily Batta",
- "read_only": 1
- },
- {
- "depends_on": "eval:doc.batta_type == 'External'",
- "fieldname": "ot_batta",
- "fieldtype": "Currency",
- "in_list_view": 1,
- "label": "OT Batta",
+ "label": " Batta",
"read_only": 1
},
{
@@ -89,6 +84,7 @@
"label": "Purpose"
},
{
+ "columns": 1,
"fieldname": "origin",
"fieldtype": "Link",
"in_list_view": 1,
@@ -96,6 +92,7 @@
"options": "Location"
},
{
+ "columns": 1,
"fieldname": "destination",
"fieldtype": "Link",
"in_list_view": 1,
@@ -103,6 +100,7 @@
"options": "Location"
},
{
+ "columns": 2,
"fieldname": "distance_travelled_km",
"fieldtype": "Float",
"in_list_view": 1,
@@ -129,12 +127,65 @@
{
"fieldname": "column_break_uihk",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_ikdi",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "breakfast",
+ "fieldtype": "Currency",
+ "label": "Breakfast",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_vnsw",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "lunch",
+ "fieldtype": "Currency",
+ "label": "Lunch",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_atwg",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "dinner",
+ "fieldtype": "Currency",
+ "label": "Dinner",
+ "precision": "2"
+ },
+ {
+ "fieldname": "column_break_gaok",
+ "fieldtype": "Column Break",
+ "read_only": 1
+ },
+ {
+ "fieldname": "total_food_allowance",
+ "fieldtype": "Currency",
+ "label": "Total Food Allowance",
+ "precision": "2",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_cjsx",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_batta",
+ "fieldtype": "Currency",
+ "label": "Total Batta",
+ "precision": "2",
+ "read_only": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2024-09-25 11:27:06.396834",
+ "modified": "2025-03-26 11:50:57.516655",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Work Detail",
diff --git a/beams/beams/overrides/queries.py b/beams/beams/overrides/queries.py
new file mode 100644
index 000000000..3954fd887
--- /dev/null
+++ b/beams/beams/overrides/queries.py
@@ -0,0 +1,91 @@
+import frappe
+from erpnext.controllers.queries import get_fields
+from frappe.desk.reportview import get_filters_cond, get_match_cond
+from frappe.desk.reportview import build_match_conditions, get_filters_cond
+
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
+def get_cost_center_list(doctype, txt, searchfield, start, page_len, filters=None, as_dict=False):
+ from erpnext.controllers.queries import get_fields
+ conditions = []
+ fields = ["name"]
+
+ fields = get_fields("Cost Center", fields)
+
+ searchfields = frappe.get_meta(doctype).get_search_fields()
+ searchfields = " or ".join(field + " like %(txt)s" for field in searchfields)
+
+ bureau_user = False
+ department_user = False
+ departments = False
+ cost_center_filter = False
+
+ # Get permitted bureaus
+ bureau_list = frappe.db.get_all(
+ 'User Permission',
+ filters = {
+ 'user': frappe.session.user,
+ 'allow': 'Bureau'
+ },
+ fields = ['for_value']
+ )
+ if len(bureau_list) > 0:
+ bureaus = tuple(d['for_value'] for d in bureau_list)
+ cost_center_filter = frappe.get_all(
+ 'Bureau',
+ filters={'name': ['in', bureaus]},
+ fields=['cost_center']
+ )
+
+ else:
+ department_list = frappe.db.get_all(
+ 'User Permission',
+ filters = {
+ 'user': frappe.session.user, 'allow': 'Department'
+ },
+ fields = ['for_value']
+ )
+ if len(department_list) > 0:
+ departments = tuple(d['for_value'] for d in department_list)
+ cost_center_filter = frappe.get_all(
+ 'Department Cost Center',
+ filters={
+ 'parent': ['in', departments],
+ 'parenttype': 'Department',
+ },
+ fields=['cost_center'],
+ )
+
+ cost_center_filter_cond = ""
+ if cost_center_filter:
+ cost_center_filter = ', '.join("'"+d['cost_center']+"'" for d in cost_center_filter)
+ cost_center_filter_cond = " and name in ({0})".format(cost_center_filter)
+
+ query = '''
+ select
+ {fields}
+ from
+ `tabCost Center`
+ where
+ docstatus < 2
+ {cost_center_filter_cond}
+ and ({scond}) and disabled != 1
+ {fcond} {mcond}
+ order by
+ idx desc, name
+ limit %(page_len)s offset %(start)s
+ '''
+
+ return frappe.db.sql(
+ query.format(
+ **{
+ "fields": ", ".join(fields),
+ "scond": searchfields,
+ "mcond": get_match_cond(doctype),
+ "cost_center_filter_cond": cost_center_filter_cond,
+ "fcond": get_filters_cond(doctype, filters, conditions).replace("%", "%%")
+ }
+ ),
+ {"txt": "%%%s%%" % txt, "_txt": txt.replace("%", ""), "start": start, "page_len": page_len},
+ as_dict=as_dict,
+ )
diff --git a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.js b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.js
index 319065368..bc62d5517 100644
--- a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.js
+++ b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.js
@@ -111,7 +111,13 @@ frappe.query_reports["Detailed Budget Allocation Report"] = {
fieldtype: "Select",
options: "ASC\nDESC",
default: "DESC"
- }
+ },
+ {
+ fieldname: "budget_amount_only",
+ label: "Budget Amount Only",
+ fieldtype: "Check",
+ default: 1
+ },
],
tree: true,
treeView: true,
diff --git a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.json b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.json
index 3b9e104bf..8aa3f82c7 100644
--- a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.json
+++ b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.json
@@ -1,5 +1,6 @@
{
- "add_total_row": 1,
+ "add_total_row": 0,
+ "add_translate_data": 0,
"columns": [],
"creation": "2025-03-05 20:54:32.054081",
"disabled": 0,
@@ -9,7 +10,7 @@
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
- "modified": "2025-03-14 15:16:01.173074",
+ "modified": "2025-03-27 15:14:45.563936",
"modified_by": "Administrator",
"module": "BEAMS",
"name": "Detailed Budget Allocation Report",
diff --git a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.py b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.py
index 0d1a2073f..c7922b6d0 100644
--- a/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.py
+++ b/beams/beams/report/detailed_budget_allocation_report/detailed_budget_allocation_report.py
@@ -63,6 +63,18 @@ def get_columns(filters):
columns.append(
{'label': _('Total Budget'), 'fieldtype': 'Currency', 'fieldname': 'total_budget', 'width': 200}
)
+
+ if not filters.get("budget_amount_only"):
+ fields = [
+ {'label': _('Finance Group'), 'fieldtype': 'Link', 'fieldname': 'finance_group', 'options': 'Finance Group', 'width': 200},
+ {'label': _('Department'), 'fieldtype': 'Link', 'fieldname': 'department', 'options': 'Department', 'width': 200},
+ {'label': _('Division'), 'fieldtype': 'Link', 'fieldname': 'division', 'options': 'Division', 'width': 200},
+ {'label': _('Cost Head'), 'fieldtype': 'Link', 'fieldname': 'cost_head', 'options': 'Cost Head', 'width': 200},
+ {'label': _('Cost Subhead'), 'fieldtype': 'Link', 'fieldname': 'cost_subhead', 'options': 'Cost Subhead', 'width': 200}
+ ]
+ # Insert all fields at index 1 in one step
+ columns[1:1] = fields
+
filters["currency_fields"] = currency_fields
return columns
@@ -151,6 +163,16 @@ def get_data(filters):
'account': cost_details.get('account', ''),
'total_budget': total_budget
}
+
+ if not filters.get("budget_amount_only"):
+ csh_row.update({
+ 'finance_group': fg,
+ 'department': dept,
+ 'division': div,
+ 'cost_head': ch,
+ 'cost_subhead': csh,
+ })
+
if period != 'Yearly':
budget_column_data = get_budget_column_data(period, months_order, row_id)
csh_row.update(budget_column_data)
@@ -158,17 +180,33 @@ def get_data(filters):
# Accumulate child budget into its parent
for field in currency_fields:
+ budget_map[ch_id].update({
+ 'finance_group': fg,
+ 'department': dept,
+ 'division': div,
+ 'cost_head': ch,
+ })
budget_map[ch_id][field] += csh_row.get(field, 0)
# Propagate cost head budget to department
for field in currency_fields:
+ budget_map[div].update({
+ 'finance_group': fg,
+ 'department': dept,
+ 'division': div,
+ })
budget_map[div][field] += budget_map[ch_id][field]
# Propagate division budget to departments
for field in currency_fields:
+ budget_map[dept].update({
+ 'finance_group': fg,
+ 'department': dept,
+ })
budget_map[dept][field] += budget_map[div][field]
# Propagate department budget to finance group
for field in currency_fields:
+ budget_map[fg_id]['finance_group'] = fg
budget_map[fg_id][field] += budget_map[dept][field]
# Propagate finance group budget to company
diff --git a/beams/patches.txt b/beams/patches.txt
index f2e2afa5e..c2e1371cf 100644
--- a/beams/patches.txt
+++ b/beams/patches.txt
@@ -1,4 +1,6 @@
[pre_model_sync]
+
+beams.patches.delete_employee_fields #25-02-2024
beams.patches.rename_hod_role #30-10-2024
beams.patches.delete_custom_fields #26-11-2024-1
beams.patches.no_of_children_patch #06-03-2025
diff --git a/beams/patches/delete_employee_fields.py b/beams/patches/delete_employee_fields.py
new file mode 100644
index 000000000..97ace3cb6
--- /dev/null
+++ b/beams/patches/delete_employee_fields.py
@@ -0,0 +1,14 @@
+import frappe
+
+fields_to_remove = [
+ {
+ 'dt':'Employee',
+ 'fieldname':'bureau'
+ }
+]
+
+def execute():
+ for field in fields_to_remove:
+ if frappe.db.exists('Custom Field', field):
+ frappe.db.delete('Custom Field', field)
+ frappe.db.commit()
diff --git a/beams/setup.py b/beams/setup.py
index 6519b3f17..f6c10ad52 100644
--- a/beams/setup.py
+++ b/beams/setup.py
@@ -4,3276 +4,3432 @@
def after_install():
- #Creating BEAMS specific custom fields
- create_custom_fields(get_customer_custom_fields(), ignore_validate=True)
- create_custom_fields(get_sales_invoice_custom_fields(), ignore_validate=True)
- create_custom_fields(get_quotation_custom_fields(), ignore_validate=True)
- create_custom_fields(get_purchase_invoice_custom_fields(), ignore_validate=True)
- create_custom_fields(get_supplier_custom_fields(), ignore_validate=True)
- create_custom_fields(get_item_custom_fields(), ignore_validate=True)
- create_custom_fields(get_driver_custom_fields(), ignore_validate=True)
- create_custom_fields(get_employee_custom_fields(), ignore_validate=True)
- create_custom_fields(get_purchase_order_custom_fields(),ignore_validate=True)
- create_custom_fields(get_material_request_custom_fields(), ignore_validate=True)
- create_custom_fields(get_sales_order_custom_fields(), ignore_validate=True)
- create_custom_fields(get_employee_advance_custom_fields(), ignore_validate=True)
- create_custom_fields(get_journal_entry_custom_fields(), ignore_validate=True)
- create_custom_fields(get_voucher_entry_custom_fields(), ignore_validate=True)
- create_custom_fields(get_contract_custom_fields(),ignore_validate=True)
- create_custom_fields(get_department_custom_fields(),ignore_validate=True)
- create_custom_fields(get_job_requisition_custom_fields(),ignore_validate=True)
- create_custom_fields(get_job_opening_custom_fields(),ignore_validate=True)
- create_custom_fields(get_expected_skill_set_custom_fields(),ignore_validate=True)
- create_custom_fields(get_interview_round_custom_fields(),ignore_validate=True)
- create_custom_fields(get_job_applicant_custom_fields(),ignore_validate=True)
- create_custom_fields(get_budget_custom_fields(),ignore_validate=True)
- create_custom_fields(get_interview_feedback_custom_fields(),ignore_validate=True)
- create_custom_fields(get_skill_assessment_custom_fields(), ignore_validate=True)
- create_custom_fields(get_job_offer_custom_fields(), ignore_validate=True)
- create_custom_fields(get_company_custom_fields(), ignore_validate=True)
- create_custom_fields(get_training_event_employee_custom_fields(), ignore_validate=True)
- create_custom_fields(get_attendance_request_custom_fields(),ignore_validate=True)
- create_custom_fields(get_shift_assignment_custom_fields(),ignore_validate=True)
- create_custom_fields(get_leave_type_custom_fields(),ignore_validate=True)
- create_custom_fields(get_leave_application_custom_fields(),ignore_validate=True)
- create_custom_fields(get_employee_performance_feedback(),ignore_validate=True)
- create_custom_fields(get_employment_type(),ignore_validate=True)
- create_custom_fields(get_appointment_letter(),ignore_validate=True)
- create_custom_fields(get_employment_type_custom_fields(),ignore_validate=True)
- create_custom_fields(get_employee_separation_custom_fields(),ignore_validate=True)
- create_custom_fields(get_appraisal_template_custom_fields(),ignore_validate=True)
- create_custom_fields(get_employee_feedback_rating_custom_fields(),ignore_validate=True)
- create_custom_fields(get_appraisal_custom_fields(),ignore_validate=True)
- create_custom_fields(get_appraisal_kra_custom_fields(),ignore_validate=True)
- create_custom_fields(get_event_custom_fields(),ignore_validate=True)
- create_custom_fields(get_project_custom_fields(),ignore_validate=True)
- create_custom_fields(get_Payroll_Settings_custom_fields(),ignore_validate=True)
- create_custom_fields(get_asset_custom_fields(),ignore_validate=True)
- create_custom_fields(get_vehicle_custom_fields(),ignore_validate=True)
- create_custom_fields(get_interview_custom_fields(),ignore_validate=True)
- create_custom_fields(get_item_group_custom_fields(),ignore_validate=True)
- create_custom_fields(get_hr_settings_custom_fields(),ignore_validate=True)
- create_custom_fields(get_asset_category_custom_fields(),ignore_validate=True)
- create_custom_fields(get_asset_movement_custom_fields(),ignore_validate=True)
- create_custom_fields(get_full_and_final_statement_custom_fields(),ignore_validate=True)
- create_custom_fields(get_expense_claim_custom_fields(),ignore_validate=True)
- create_custom_fields(get_hd_ticket_custom_fields(),ignore_validate=True)
- create_custom_fields(get_hd_ticket_type_custom_fields(),ignore_validate=True)
- create_custom_fields(get_expense_claim_type_custom_fields(),ignore_validate=True)
- create_custom_fields(get_supplier_quotation_custom_fields(), ignore_validate=True)
-
-
- #Creating BEAMS specific Property Setters
- create_property_setters(get_property_setters())
-
- #Creating BEAMS specific Roles
- create_custom_roles(get_beams_roles())
-
- #Creating BEAMS specific Translations
- create_translations(get_custom_translations())
-
- #Creating BEAMS specific Email Template
- create_email_templates(get_email_templates())
+ # Creating BEAMS specific custom fields
+ create_custom_fields(get_customer_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_sales_invoice_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_quotation_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_purchase_invoice_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_supplier_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_item_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_driver_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_employee_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_purchase_order_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_material_request_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_sales_order_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_employee_advance_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_journal_entry_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_voucher_entry_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_contract_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_department_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_job_requisition_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_job_opening_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_expected_skill_set_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_interview_round_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_job_applicant_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_budget_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_interview_feedback_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_skill_assessment_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_job_offer_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_company_custom_fields(), ignore_validate=True)
+ create_custom_fields(
+ get_training_event_employee_custom_fields(), ignore_validate=True
+ )
+ create_custom_fields(get_attendance_request_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_shift_assignment_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_leave_type_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_leave_application_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_employee_performance_feedback(), ignore_validate=True)
+ create_custom_fields(get_employment_type(), ignore_validate=True)
+ create_custom_fields(get_appointment_letter(), ignore_validate=True)
+ create_custom_fields(get_employment_type_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_employee_separation_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_appraisal_template_custom_fields(), ignore_validate=True)
+ create_custom_fields(
+ get_employee_feedback_rating_custom_fields(), ignore_validate=True
+ )
+ create_custom_fields(get_appraisal_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_appraisal_kra_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_event_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_project_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_Payroll_Settings_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_asset_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_vehicle_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_interview_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_item_group_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_hr_settings_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_asset_category_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_asset_movement_custom_fields(), ignore_validate=True)
+ create_custom_fields(
+ get_full_and_final_statement_custom_fields(), ignore_validate=True
+ )
+ create_custom_fields(get_expense_claim_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_hd_ticket_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_hd_ticket_type_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_expense_claim_type_custom_fields(), ignore_validate=True)
+ create_custom_fields(get_supplier_quotation_custom_fields(), ignore_validate=True)
-def after_migrate():
- after_install()
+ # Creating BEAMS specific Property Setters
+ create_property_setters(get_property_setters())
-def before_uninstall():
- delete_custom_fields(get_customer_custom_fields())
- delete_custom_fields(get_sales_invoice_custom_fields())
- delete_custom_fields(get_quotation_custom_fields())
- delete_custom_fields(get_purchase_invoice_custom_fields())
- delete_custom_fields(get_supplier_custom_fields())
- delete_custom_fields(get_item_custom_fields())
- delete_custom_fields(get_purchase_order_custom_fields())
- delete_custom_fields(get_driver_custom_fields())
- delete_custom_fields(get_material_request_custom_fields())
- delete_custom_fields(get_sales_order_custom_fields())
- delete_custom_fields(get_employee_advance_custom_fields())
- delete_custom_fields(get_employee_custom_fields())
- delete_custom_fields(get_journal_entry_custom_fields())
- delete_custom_fields(get_voucher_entry_custom_fields())
- delete_custom_fields(get_contract_custom_fields())
- delete_custom_fields(get_department_custom_fields())
- delete_custom_fields(get_job_requisition_custom_fields())
- delete_custom_fields(get_job_opening_custom_fields())
- delete_custom_fields(get_job_applicant_custom_fields())
- delete_custom_fields(get_budget_custom_fields())
- delete_custom_fields(get_expected_skill_set_custom_fields())
- delete_custom_fields(get_interview_round_custom_fields())
- delete_custom_fields(get_skill_assessment_custom_fields())
- delete_custom_fields(get_job_offer_custom_fields())
- delete_custom_fields(get_company_custom_fields())
- delete_custom_fields(get_training_event_employee_custom_fields())
- delete_custom_fields(get_attendance_request_custom_fields())
- delete_custom_fields(get_shift_assignment_custom_fields())
- delete_custom_fields(get_leave_type_custom_fields())
- delete_custom_fields(get_leave_application_custom_fields())
- delete_custom_fields(get_employee_performance_feedback())
- delete_custom_fields(get_employment_type())
- delete_custom_fields(get_appointment_letter())
- delete_custom_fields(get_employment_type_custom_fields())
- delete_custom_fields(get_employee_separation_custom_fields())
- delete_custom_fields(get_appraisal_template_custom_fields())
- delete_custom_fields(get_employee_feedback_rating_custom_fields())
- delete_custom_fields(get_appraisal_custom_fields())
- delete_custom_fields(get_appraisal_kra_custom_fields())
- delete_custom_fields(get_event_custom_fields())
- delete_custom_fields(get_project_custom_fields())
- delete_custom_fields(get_Payroll_Settings_custom_fields())
- delete_custom_fields(get_asset_custom_fields())
- delete_custom_fields(get_vehicle_custom_fields())
- delete_custom_fields(get_interview_custom_fields())
- delete_custom_fields(get_item_group_custom_fields())
- delete_custom_fields(get_hr_settings_custom_fields())
- delete_custom_fields(get_asset_category_custom_fields())
- delete_custom_fields(get_asset_movement_custom_fields())
- delete_custom_fields(get_full_and_final_statement_custom_fields())
- delete_custom_fields(get_expense_claim_custom_fields())
- delete_custom_fields(get_hd_ticket_custom_fields())
- delete_custom_fields(get_hd_ticket_type_custom_fields())
- delete_custom_fields(get_expense_claim_type_custom_fields())
- delete_custom_fields(get_supplier_quotation_custom_fields())
+ # Creating BEAMS specific Roles
+ create_custom_roles(get_beams_roles())
+ # Creating BEAMS specific Translations
+ create_translations(get_custom_translations())
-def delete_custom_fields(custom_fields: dict):
- '''
- Method to Delete custom fields
- args:
- custom_fields: a dict like `{'Task': [{fieldname: 'your_fieldname', ...}]}`
- '''
- for doctype, fields in custom_fields.items():
- frappe.db.delete(
- "Custom Field",
- {
- "fieldname": ("in", [field["fieldname"] for field in fields]),
- "dt": doctype,
- },
- )
- frappe.clear_cache(doctype=doctype)
+ # Creating BEAMS specific Email Template
+ create_email_templates(get_email_templates())
-def get_shift_assignment_custom_fields():
- '''
- Custom fields that need to be added to the Shift Assignment DocType
- '''
- return {
- "Shift Assignment": [
- {
- "fieldname": "roster_type",
- "fieldtype": "Select",
- "label": "Roster Type",
- "options":"\nRegular\nDouble Shift",
- "insert_after": "shift_type"
- },
- {
- "fieldname": "user_id",
- "label": "User ID",
- "fieldtype": "Data",
- "insert_after": "end_date",
- "options": "Email",
- "hidden": 1
-
- }
-
- ]
- }
-
-def get_hd_ticket_type_custom_fields():
- '''
- Custom fields that need to be added to the HD Ticket Type DocType
- '''
- return {
- "HD Ticket Type": [
- {
- "fieldname": "team_name",
- "fieldtype": "Link",
- "label": "Team Name",
- "options":"HD Team",
- "insert_after": "is_system"
- }
- ]
- }
-def get_Payroll_Settings_custom_fields():
- '''
- Custom fields that need to be added to the Payroll Settings Doctype
- '''
- return {
- "Payroll Settings": [
- {
- "fieldname": "provident_fund_section",
- "fieldtype": "Section Break",
- "label": "Provident Fund",
- "insert_after": "show_leave_balances_in_salary_slip"
- },
- {
- "fieldname": "employer_pf_contribution",
- "label": "Employer PF Contribution",
- "fieldtype": "Percent",
- "insert_after": "provident_fund_section"
- },
- {
- "fieldname": "column_break_pf",
- "fieldtype": "Column Break",
- "insert_after": "employer_pf_contribution"
- },
- {
- "fieldname": "pf_expense_account",
- "label": "PF Expense Account",
- "fieldtype": "Link",
- "options": "Account",
- "insert_after": "column_break_pf"
- },
- {
- "fieldname": "esi_section",
- "fieldtype": "Section Break",
- "label": "Employees State Insurance",
- "insert_after": "pf_expense_account"
- },
- {
- "fieldname": "esi_employer_contribution",
- "label": "ESI Employer Contribution",
- "fieldtype": "Percent",
- "insert_after": "esi_section"
- },
- {
- "fieldname": "column_break_esi",
- "fieldtype": "Column Break",
- "insert_after": "esi_employer_contribution"
- },
- {
- "fieldname": "esi_expense_account",
- "label": "ESI Expense Account",
- "fieldtype": "Link",
- "options": "Account",
- "insert_after": "column_break_esi"
- }
- ]
- }
+def after_migrate():
+ after_install()
-def get_project_custom_fields():
- '''
- Custom fields that need to be added to the Project Doctype
- '''
- return {
- "Project": [
- {
- "fieldname": "program_section",
- "fieldtype": "Section Break",
- "label": "Program Details",
- "collapsible": 1,
- "insert_after": "sales_order"
- },
- {
- "fieldname": "program_request",
- "label": "Program Request",
- "fieldtype": "Link",
- "options": "Program Request",
- "insert_after": "program_section"
- },
- {
- "fieldname": "bureau",
- "label": "Bureau",
- "fieldtype": "Link",
- "options":"Bureau",
- "insert_after": "expected_revenue",
- "fetch_from": "program_request.bureau",
- "read_only": 1
-
- },
- {
- "fieldname": "column_break_program",
- "fieldtype": "Column Break",
- "insert_after": "generates_revenue"
- },
- {
- "fieldname": "program_type",
- "label": "Program Type",
- "fieldtype": "Link",
- "options": "Program Type",
- "insert_after": "column_break_program",
- "fetch_from": "program_request.program_type",
- "read_only": 1
- },
- {
- "fieldname": "budget_expense_types",
- "fieldtype": "Table MultiSelect",
- "label": "Budget Expense Types",
- 'options':"Project Expense Type",
- "insert_after": "program_type"
- },
- {
- "fieldname": "generates_revenue",
- "fieldtype": "Check",
- "label": "Generates Revenue",
- "read_only": 1,
- "fetch_from": "program_request.generates_revenue",
- "insert_after": "program_request"
- },
- {
- "fieldname": "expected_revenue",
- "fieldtype": "Float",
- "label": "Expected Revenue",
- "read_only": 1,
- "fetch_from": "program_request.expected_revenue",
- "insert_after": "generates_revenue"
- },
- {
- "fieldname": "allocated_resources_details_section",
- "fieldtype": "Section Break",
- "label": " Allocated Resource Details",
- "collapsible": 1,
- "insert_after": "program_request"
- },
- {
- "fieldname": "allocated_manpower_details",
- "fieldtype": "Table",
- "label": "Allocated Manpower Detail",
- "options":"Allocated Manpower Detail",
- "insert_after":"allocated_item_details"
- },
- {
- "fieldname": "allocated_item_details",
- "fieldtype": "Table",
- "label": "Allocated Item Details",
- "options":"Required Items Detail",
- "insert_after":"allocated_resources_details_section"
- },
- {
- "fieldname": "approved_budget",
- "fieldtype": "Currency",
- "label": "Approved Budget",
- "insert_after":"budget_expense_types",
- "read_only": 1
-
- },
- {
- "fieldname": "estimated_budget",
- "fieldtype": "Currency",
- "label": "Estimated Budget",
- "fetch_from": "program_request.estimated_budget",
- "insert_after":"approved_budget",
- "read_only": 1
- },
- {
- "fieldname": "description",
- "fieldtype": "Small Text",
- "label": "Description",
- "fetch_from":"program_request.description",
- "insert_after": "bureau"
- },
- {
- "fieldname": "requirements",
- "fieldtype": "Text Editor",
- "label": "Requirements",
- "fetch_from":"program_request.requirements",
- "insert_after": "description"
- },
- {
- "fieldname": "location",
- "fieldtype": "Link",
- "label": "Location",
- "options":"Location",
- "fetch_from":"program_request.location",
- "insert_after": "department",
- "fetch_on_save_if_empty":1
- },
- {
- "fieldname": "requirements_details",
- "fieldtype": "Section Break",
- "label": "Requirements Details",
- "collapsible": 1,
- "insert_after": "estimated_budget"
- },
- {
- "fieldname": "required_items",
- "fieldtype": "Table",
- "label": "Required Items",
- "options": "Required Items Table",
- "insert_after": "requirements_details"
- },
- {
- "fieldname": "required_manpower_details",
- "fieldtype": "Table",
- "label": "Required Manpower Details",
- "options": "Required Manpower Details",
- "insert_after": "required_items"
- },
- {
- "fieldname": "required_vehicle_details",
- "fieldtype": "Table",
- "label": "Required Vehicle Details",
- "options": "Required Vehicle Details",
- "insert_after": "required_manpower_details"
- },
- {
- "fieldname": "allocated_vehicle_details",
- "fieldtype": "Table",
- "label": "Allocated Vehicle Details",
- "options": "Allocated Vehicle Details",
- "insert_after": "allocated_manpower_details"
- },
- {
- "fieldname": "asset_location",
- "fieldtype": "Link",
- "label": "Asset Location",
- "options":"Location",
- "insert_after": "estimated_budget"
- }
-
-
-
- ]
- }
+def before_uninstall():
+ delete_custom_fields(get_customer_custom_fields())
+ delete_custom_fields(get_sales_invoice_custom_fields())
+ delete_custom_fields(get_quotation_custom_fields())
+ delete_custom_fields(get_purchase_invoice_custom_fields())
+ delete_custom_fields(get_supplier_custom_fields())
+ delete_custom_fields(get_item_custom_fields())
+ delete_custom_fields(get_purchase_order_custom_fields())
+ delete_custom_fields(get_driver_custom_fields())
+ delete_custom_fields(get_material_request_custom_fields())
+ delete_custom_fields(get_sales_order_custom_fields())
+ delete_custom_fields(get_employee_advance_custom_fields())
+ delete_custom_fields(get_employee_custom_fields())
+ delete_custom_fields(get_journal_entry_custom_fields())
+ delete_custom_fields(get_voucher_entry_custom_fields())
+ delete_custom_fields(get_contract_custom_fields())
+ delete_custom_fields(get_department_custom_fields())
+ delete_custom_fields(get_job_requisition_custom_fields())
+ delete_custom_fields(get_job_opening_custom_fields())
+ delete_custom_fields(get_job_applicant_custom_fields())
+ delete_custom_fields(get_budget_custom_fields())
+ delete_custom_fields(get_expected_skill_set_custom_fields())
+ delete_custom_fields(get_interview_round_custom_fields())
+ delete_custom_fields(get_skill_assessment_custom_fields())
+ delete_custom_fields(get_job_offer_custom_fields())
+ delete_custom_fields(get_company_custom_fields())
+ delete_custom_fields(get_training_event_employee_custom_fields())
+ delete_custom_fields(get_attendance_request_custom_fields())
+ delete_custom_fields(get_shift_assignment_custom_fields())
+ delete_custom_fields(get_leave_type_custom_fields())
+ delete_custom_fields(get_leave_application_custom_fields())
+ delete_custom_fields(get_employee_performance_feedback())
+ delete_custom_fields(get_employment_type())
+ delete_custom_fields(get_appointment_letter())
+ delete_custom_fields(get_employment_type_custom_fields())
+ delete_custom_fields(get_employee_separation_custom_fields())
+ delete_custom_fields(get_appraisal_template_custom_fields())
+ delete_custom_fields(get_employee_feedback_rating_custom_fields())
+ delete_custom_fields(get_appraisal_custom_fields())
+ delete_custom_fields(get_appraisal_kra_custom_fields())
+ delete_custom_fields(get_event_custom_fields())
+ delete_custom_fields(get_project_custom_fields())
+ delete_custom_fields(get_Payroll_Settings_custom_fields())
+ delete_custom_fields(get_asset_custom_fields())
+ delete_custom_fields(get_vehicle_custom_fields())
+ delete_custom_fields(get_interview_custom_fields())
+ delete_custom_fields(get_item_group_custom_fields())
+ delete_custom_fields(get_hr_settings_custom_fields())
+ delete_custom_fields(get_asset_category_custom_fields())
+ delete_custom_fields(get_asset_movement_custom_fields())
-def get_employment_type_custom_fields():
- '''
- Custom fields that need to be added to the Employment Type DocType
- '''
- return {
- "Employment Type": [
- {
- "fieldname": "penalty_leave_type",
- "fieldtype": "Link",
- "label": "Penalty Leave Type",
- "options": "Leave Type",
- "insert_after": "employee_type_name"
- }
- ]
- }
-def get_event_custom_fields():
- '''
- Custom fields to be added to the Event Doctype
- '''
- return {
- "Event": [
- {
- "fieldname": "contribution_of_employee",
- "fieldtype": "Small Text",
- "label": "Contribution of Employee",
- "insert_after": "description",
- "depends_on": "eval:doc.event_category == 'One to One Meeting'"
- },
- {
- "fieldname": "improvement_of_employee",
- "fieldtype": "Small Text",
- "label": "Areas of Improvement of Employee",
- "insert_after": "contribution_of_employee",
- "depends_on": "eval:doc.event_category == 'One to One Meeting'"
- },
- {
- "fieldname": "training_needs_of_employee",
- "fieldtype": "Small Text",
- "label": "Training Needs of Employee",
- "insert_after": "improvement_of_employee",
- "depends_on": "eval:doc.event_category == 'One to One Meeting'"
- },
- {
- "fieldname": "is_employee_eligible_for_promotion",
- "fieldtype": "Select",
- "label": "Is Employee Eligible for Promotion",
- "options": "\nYes\nNo",
- "insert_after": "training_needs_of_employee",
- "depends_on": "eval:doc.event_category == 'One to One Meeting'"
- },
- {
- "fieldname": "remarks_for_promotion",
- "fieldtype": "Small Text",
- "label": "Remarks",
- "insert_after": "is_employee_eligible_for_promotion",
- "depends_on": "eval:(doc.is_employee_eligible_for_promotion == 'Yes' || doc.is_employee_eligible_for_promotion == 'No') && doc.event_category == 'One to One Meeting'"
- },
- {
- "fieldname": "appraisal_reference",
- "fieldtype": "Link",
- "label": "Appraisal Reference",
- "options": "Appraisal",
- "insert_after": "status"
- },
- {
- "fieldname": "assign_service_unit",
- "fieldtype": "Check",
- "label": "Assign Service Unit",
- "insert_after": "add_video_conferencing"
- },
- {
- "fieldname": "meeting_room",
- "fieldtype": "Link",
- "label": "Meeting Room",
- "options": "Service Unit",
- "depends_on": "eval:doc.assign_service_unit == 1",
- "mandatory_depends_on": "eval:doc.assign_service_unit == 1",
- "insert_after": "assign_service_unit"
- },
- {
- "fieldname": "section_break_epd",
- "fieldtype": "Section Break",
- "label": " ",
- "insert_after": "sunday"
- },
- {
- "fieldname": "external_participants",
- "fieldtype": "Table",
- "label": "External Participants",
- "options": "External Participants Detail",
- "insert_after": "section_break_epd"
- },
- {
- "fieldname": "reason_for_rejection",
- "fieldtype": "Small Text",
- "label": "Reason for Rejection",
- "insert_after": "repeat_this_event"
- }
- ]
- }
+def delete_custom_fields(custom_fields: dict):
+ """
+ Method to Delete custom fields
+ args:
+ custom_fields: a dict like `{'Task': [{fieldname: 'your_fieldname', ...}]}`
+ """
+ for doctype, fields in custom_fields.items():
+ frappe.db.delete(
+ "Custom Field",
+ {
+ "fieldname": ("in", [field["fieldname"] for field in fields]),
+ "dt": doctype,
+ },
+ )
+ frappe.clear_cache(doctype=doctype)
-def get_leave_application_custom_fields():
- '''
- Custom fields that need to be added to the Leave Application Doctype
- '''
- return {
- "Leave Application": [
- {
- "fieldname": "medical_certificate",
- "fieldtype": "Attach",
- "label": "Medical Certificate",
- "hidden": 1,
- "insert_after": "leave_type"
- }
-
- ]
- }
-def get_attendance_request_custom_fields():
- """
- Custom fields that need to be added to the Attendance Request DocType.
- """
- return {
- "Attendance Request": [
- {
- "fieldname": "reports_to",
- "fieldtype": "Link",
- "label": "Reports To",
- "options": "Employee",
- "fetch_from":"employee.reports_to",
- "insert_after": "reason"
- },
- {
- "fieldname": "reports_to_name",
- "fieldtype": "Data",
- "label": "Reports To Name",
- "insert_after": "reports_to",
- "fetch_from": "reports_to.employee_name"
- },
- {
- "fieldname": "reports_to_user",
- "fieldtype": "Link",
- "label": "Reports To User",
- "options": "User",
- "insert_after": "reports_to_name",
- "fetch_from": "reports_to.user_id"
- }
- ]
- }
-def get_customer_custom_fields():
- '''
- Custom fields that need to be added to the Customer Doctype
- '''
- return {
- "Customer": [
- {
- "fieldname": "msme_status",
- "fieldtype": "Select",
- "label": "MSME Status",
- "options":"\nMSME\nNon-MSME",
- "insert_after": "customer_group"
- },
- {
- "fieldname": "msme_number",
- "fieldtype": "Int",
- "label": "MSME Number",
- "insert_after":"msme_status"
- },
- {
- "fieldname": "region",
- "fieldtype": "Link",
- "label": "Region",
- "options": "Region",
- "reqd": 1,
- "insert_after": "msme_number"
- },
- {
- "fieldname": "is_agent",
- "fieldtype": "Check",
- "label": "Is Agency",
- "insert_after": "region"
- },
- {
- "fieldname": "is_edited",
- "fieldtype": "Check",
- "label": "Is Edited",
- "hidden": 1,
- "default": 0,
- "no_copy":1,
- "insert_after": "is_agent"
- }
- ]
- }
+def get_shift_assignment_custom_fields():
+ """
+ Custom fields that need to be added to the Shift Assignment DocType
+ """
+ return {
+ "Shift Assignment": [
+ {
+ "fieldname": "roster_type",
+ "fieldtype": "Select",
+ "label": "Roster Type",
+ "options": "\nRegular\nDouble Shift",
+ "insert_after": "shift_type",
+ },
+ {
+ "fieldname": "user_id",
+ "label": "User ID",
+ "fieldtype": "Data",
+ "insert_after": "end_date",
+ "options": "Email",
+ "hidden": 1,
+ },
+ ]
+ }
-def get_department_custom_fields():
- '''
- Custom fields that need to be added to the Department Doctype
- '''
- return {
- "Department": [
- {
- "fieldname": "head_of_department",
- "fieldtype": "Link",
- "label": "Head Of Department",
- "options":"Employee",
- "insert_after": "department_name"
- },
- {
- "fieldname": "head_of_department_name",
- "fieldtype": "Data",
- "label": "Head Of Department(Name)",
- "insert_after": "head_of_department",
- "fetch_from": "head_of_department.employee_name",
- "read_only": 1
- },
- {
- "fieldname": "abbreviation",
- "fieldtype": "Data",
- "label": "Abbreviation",
- "reqd":1,
- "unique":1,
- "insert_after": "head_of_department_name"
- },
- {
- "fieldname": "threshold_amount",
- "fieldtype": "Float",
- "label": "Threshold Amount",
- "insert_after": "parent_department"
- },
- {
- "fieldname": "finance_group",
- "fieldtype": "Link",
- "label": "Finance Group",
- "options":"Finance Group",
- "insert_after": "company"
- }
- ]
- }
-def get_driver_custom_fields():
- '''
- Custom fields that need to be added to the Driver DocType
- '''
- return {
- "Driver": [
- {
- "fieldname": "is_internal",
- "fieldtype": "Check",
- "label": "Is Internal",
- "insert_after": "transporter",
- "reqd": 0
- },
- ]
- }
+def get_hd_ticket_type_custom_fields():
+ """
+ Custom fields that need to be added to the HD Ticket Type DocType
+ """
+ return {
+ "HD Ticket Type": [
+ {
+ "fieldname": "team_name",
+ "fieldtype": "Link",
+ "label": "Team Name",
+ "options": "HD Team",
+ "insert_after": "is_system",
+ }
+ ]
+ }
-def get_asset_custom_fields():
- '''
- Custom fields that need to be added to the Asset DocType
- '''
- return {
- "Asset": [
- {
- "fieldname": "bureau",
- "fieldtype": "Link",
- "options":"Bureau",
- "label": "Bureau",
- "insert_after": "location"
- },
- {
- "fieldname": "in_transit",
- "fieldtype": "Check",
- "label": "In Transit",
- "insert_after": "is_composite_asset",
- "allow_on_submit": 1,
- "read_only":1
-
- },
- {
- "fieldname": "warranty_details_section",
- "fieldtype": "Section Break",
- "label": "Warranty Details Section",
- "insert_after": "comprehensive_insurance",
- "collapsible": 1
- },
- {
- "fieldname": "warranty_reference_no",
- "fieldtype": "Data",
- "label": "Warranty Reference No",
- "insert_after": "warranty_details_section"
- },
- {
- "fieldname": "warranty_till",
- "fieldtype": "Date",
- "label": "Warranty Till",
- "insert_after": "warranty_reference_no"
- },
- {
- "fieldname": "qr_code",
- "fieldtype": "Attach Image",
- "label": "QR code",
- "insert_after": "department"
- },
- {
- "fieldname": "asset_details",
- "fieldtype": "Attach Image",
- "label": "Asset Details",
- "insert_after": "qr_code"
- },
- {
- "fieldname": "room",
- "fieldtype": "Link",
- "label": "Room",
- "options":"Service Unit",
- "allow_on_submit": 1,
- "insert_after": "journal_entry_for_scrap"
- },
- {
- "fieldname": "shelf",
- "fieldtype": "Link",
- "label": "Shelf",
- "options":"Shelf",
- "allow_on_submit": 1,
- "insert_after": "room"
- },
- {
- "fieldname": "row",
- "fieldtype": "Link",
- "label": "Row",
- "options":"Row",
- "allow_on_submit": 1,
- "insert_after": "shelf"
- },
- {
- "fieldname": "bin",
- "fieldtype": "Link",
- "label": "Bin",
- "options":"Container",
- "allow_on_submit": 1,
- "insert_after": "row"
- }
- ]
- }
-def get_job_offer_custom_fields():
- '''
- Custom fields that need to be added to the Job Offer DocType
- '''
- return {
- "Job Offer": [
- {
- "fieldname": "job_proposal",
- "fieldtype": "Link",
- "label": "Job Proposal",
- "options":"Job Proposal",
- "insert_after": "applicant_email",
- "read_only":1
- },
- {
- "fieldname": "ctc",
- "fieldtype": "Currency",
- "label": "CTC",
- "insert_after": "job_proposal",
- "fetch_from" : "job_proposal.proposed_ctc"
- }
- ]
- }
+def get_Payroll_Settings_custom_fields():
+ """
+ Custom fields that need to be added to the Payroll Settings Doctype
+ """
+ return {
+ "Payroll Settings": [
+ {
+ "fieldname": "provident_fund_section",
+ "fieldtype": "Section Break",
+ "label": "Provident Fund",
+ "insert_after": "show_leave_balances_in_salary_slip",
+ },
+ {
+ "fieldname": "employer_pf_contribution",
+ "label": "Employer PF Contribution",
+ "fieldtype": "Percent",
+ "insert_after": "provident_fund_section",
+ },
+ {
+ "fieldname": "column_break_pf",
+ "fieldtype": "Column Break",
+ "insert_after": "employer_pf_contribution",
+ },
+ {
+ "fieldname": "pf_expense_account",
+ "label": "PF Expense Account",
+ "fieldtype": "Link",
+ "options": "Account",
+ "insert_after": "column_break_pf",
+ },
+ {
+ "fieldname": "esi_section",
+ "fieldtype": "Section Break",
+ "label": "Employees State Insurance",
+ "insert_after": "pf_expense_account",
+ },
+ {
+ "fieldname": "esi_employer_contribution",
+ "label": "ESI Employer Contribution",
+ "fieldtype": "Percent",
+ "insert_after": "esi_section",
+ },
+ {
+ "fieldname": "column_break_esi",
+ "fieldtype": "Column Break",
+ "insert_after": "esi_employer_contribution",
+ },
+ {
+ "fieldname": "esi_expense_account",
+ "label": "ESI Expense Account",
+ "fieldtype": "Link",
+ "options": "Account",
+ "insert_after": "column_break_esi",
+ },
+ ]
+ }
-def get_purchase_order_custom_fields():
- '''
- Custom fields that need to be added to the Purchase Order DocType
- '''
- return {
- "Purchase Order": [
- {
- "fieldname": "is_budget_exceed",
- "fieldtype": "Check",
- "label": "Is Budget Exceed",
- "insert_after": "items_section",
- "read_only":1,
- "no_copy":1,
- "depends_on": "eval:doc.is_budget_exceed == 1"
-
- },
- {
- "fieldname": "attach",
- "fieldtype": "Attach",
- "label": "Attachments",
- "insert_after": "base_net_total"
- }
- ],
- "Purchase Order Item": [
- {
- "fieldname": "reference_doctype",
- "fieldtype": "Link",
- "label": "Reference DocType",
- "options":"DocType",
- "insert_after": "blanket_order_rate"
- },
- {
-
- "fieldname": "reference_document",
- "fieldtype": "Dynamic Link",
- "label": "Reference Document",
- "options":"reference_doctype",
- "insert_after": "reference_doctype"
- }
- ]
- }
-def get_budget_custom_fields():
- '''
- Custom fields that need to be added to the Budget DocType
- '''
- return {
- "Budget": [
- {
- "fieldname": "department",
- "fieldtype": "Link",
- "label": "Department",
- "options":"Department",
- "reqd": 1,
- "insert_after": "company"
- },
- {
- "fieldname": "finance_group",
- "fieldtype": "Link",
- "label": "Finance Group",
- "options":"Finance Group",
- "insert_after": "department",
- "read_only":1,
- "fetch_from": "department.finance_group"
- },
- {
- "fieldname": "division",
- "fieldtype": "Link",
- "label": "Division",
- "options":"Division",
- "reqd": 1,
- "insert_after": "department"
- },
- {
- "fieldname": "region",
- "fieldtype": "Link",
- "label": "Region",
- "options":"Region",
- "insert_after": "budget_template"
- },
- {
- "fieldname": "budget_template",
- "fieldtype": "Link",
- "label": "Budget Template",
- "options":"Budget Template",
- "insert_after": "fiscal_year"
- },
- {
- "fieldname": "rejection_feedback",
- "fieldtype": "Table",
- "label": "Rejection Feedback",
- "options":"Rejection Feedback",
- "insert_after": "december",
- "depends_on": "eval: doc.workflow_state.includes('Rejected')"
- },
- {
- "fieldname": "total_amount",
- "fieldtype": "Currency",
- "label": "Total Amount",
- "read_only": 1,
- "insert_after": "region",
- "options": "company_currency"
- },
- {
- "fieldname": "budget_accounts_custom",
- "fieldtype": "Table",
- "label": "Budget Accounts",
- "options": "Budget Account",
- "insert_after": "accounts"
- },
- {
- "fieldname": "budget_accounts_hr",
- "fieldtype": "Table",
- "label": "Budget Accounts(HR Overheads)",
- "options": "Budget Account",
- "insert_after": "budget_accounts_custom"
- },
- {
- "fieldname": "default_currency",
- "fieldtype": "Link",
- "label": "Default Currency",
- "options": "Currency",
- "read_only": 1,
- "hidden":1,
- "insert_after": "budget_accounts_hr",
- "default": "INR"
- },
- {
- "fieldname": "company_currency",
- "fieldtype": "Link",
- "label": "Company Currency",
- "options": "Currency",
- "read_only": 1,
- "hidden":1,
- "insert_after": "default_currency",
- "fetch_from": "company.default_currency"
- },
- ],
- "Budget Account": [
- {
- "fieldname": "cost_head",
- "fieldtype": "Link",
- "label": "Cost Head",
- "options":"Cost Head",
- "insert_before": "cost_subhead",
- "in_list_view":1
- },
- {
- "fieldname": "cost_subhead",
- "fieldtype": "Link",
- "label": "Cost Sub Head",
- "options":"Cost Subhead",
- "insert_after": "cost_head",
- "in_list_view":1
- },
- {
- "fieldname": "cost_category",
- "fieldtype": "Link",
- "label": "Cost Category",
- "options":"Cost Category",
- "insert_after": "account",
- "in_list_view":1
- },
- {
- "fieldname": "column_break_cd",
- "fieldtype": "Column Break",
- "label": " ",
- "insert_after": "cost_category"
- },
- {
- "fieldname": "cost_description",
- "fieldtype": "Small Text",
- "label": "Cost Description",
- "insert_after": "column_break_cd"
- },
- {
- "fieldname": "equal_monthly_distribution",
- "fieldtype": "Check",
- "label": "Equal Monthly Distribution ",
- "insert_after": "cost_description"
- },
- {
- "fieldname": "section_break_ab",
- "fieldtype": "Section Break",
- "label": "Monthly Amount Distribution",
- "insert_after": "budget_amount"
- },
- {
- "fieldname": "january",
- "fieldtype": "Currency",
- "label": "January",
- "insert_after": "section_break_ab"
- },
- {
- "fieldname": "february",
- "fieldtype": "Currency",
- "label": "February",
- "insert_after": "january"
- },
- {
- "fieldname": "march",
- "fieldtype": "Currency",
- "label": "March",
- "insert_after": "february"
- },
- {
- "fieldname": "april",
- "fieldtype": "Currency",
- "label": "April",
- "insert_after": "march"
- },
- {
- "fieldname": "column_break_bc",
- "fieldtype": "Column Break",
- "label": " ",
- "insert_after": "april"
- },
- {
- "fieldname": "may",
- "fieldtype": "Currency",
- "label": "May",
- "insert_after": "column_break_bc"
- },
- {
- "fieldname": "june",
- "fieldtype": "Currency",
- "label": "June",
- "insert_after": "may"
- },
- {
- "fieldname": "july",
- "fieldtype": "Currency",
- "label": "July",
- "insert_after": "june"
- },
- {
- "fieldname": "august",
- "fieldtype": "Currency",
- "label": "August",
- "insert_after": "july"
- },
- {
- "fieldname": "column_break_ab",
- "fieldtype": "Column Break",
- "label": " ",
- "insert_after": "august"
- },
- {
- "fieldname": "september",
- "fieldtype": "Currency",
- "label": "September",
- "insert_after": "column_break_ab"
- },
- {
- "fieldname": "october",
- "fieldtype": "Currency",
- "label": "October",
- "insert_after": "september"
- },
- {
- "fieldname": "november",
- "fieldtype": "Currency",
- "label": "November",
- "insert_after": "october"
- },
- {
- "fieldname": "december",
- "fieldtype": "Currency",
- "label": "December",
- "insert_after": "november"
- },
- {
- "fieldname": "section_break_inr",
- "fieldtype": "Section Break",
- "label": "Monthly Amount Distribution (INR)",
- "insert_after": "december",
- "collapsible": 1,
- "read_only": 1
- },
- {
- "fieldname": "january_inr",
- "fieldtype": "Currency",
- "label": "January (INR)",
- "insert_after": "section_break_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "february_inr",
- "fieldtype": "Currency",
- "label": "February (INR)",
- "insert_after": "january_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "march_inr",
- "fieldtype": "Currency",
- "label": "March (INR)",
- "insert_after": "february_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "april_inr",
- "fieldtype": "Currency",
- "label": "April (INR)",
- "insert_after": "march_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "column_break_zz1",
- "fieldtype": "Column Break",
- "label": " ",
- "insert_after": "april_inr"
- },
- {
- "fieldname": "may_inr",
- "fieldtype": "Currency",
- "label": "May (INR)",
- "insert_after": "column_break_zz1",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "june_inr",
- "fieldtype": "Currency",
- "label": "June (INR)",
- "insert_after": "may_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "july_inr",
- "fieldtype": "Currency",
- "label": "July (INR)",
- "insert_after": "june_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "august_inr",
- "fieldtype": "Currency",
- "label": "August (INR)",
- "insert_after": "july_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "column_break_zz2",
- "fieldtype": "Column Break",
- "label": " ",
- "insert_after": "july_inr"
- },
- {
- "fieldname": "september_inr",
- "fieldtype": "Currency",
- "label": "September (INR)",
- "insert_after": "column_break_zz2",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "october_inr",
- "fieldtype": "Currency",
- "label": "October (INR)",
- "insert_after": "september_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "november_inr",
- "fieldtype": "Currency",
- "label": "November (INR)",
- "insert_after": "october_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "december_inr",
- "fieldtype": "Currency",
- "label": "December (INR)",
- "insert_after": "november_inr",
- "read_only": 1,
- "options": "default_currency"
- },
- {
- "fieldname": "budget_amount_inr",
- "fieldtype": "Currency",
- "label": "Budget Amount (INR)",
- "insert_after": "budget_amount",
- "options": "default_currency",
- "read_only": 1
- },
- ]
- }
+def get_project_custom_fields():
+ """
+ Custom fields that need to be added to the Project Doctype
+ """
+ return {
+ "Project": [
+ {
+ "fieldname": "program_section",
+ "fieldtype": "Section Break",
+ "label": "Program Details",
+ "collapsible": 1,
+ "insert_after": "sales_order",
+ },
+ {
+ "fieldname": "program_request",
+ "label": "Program Request",
+ "fieldtype": "Link",
+ "options": "Program Request",
+ "insert_after": "program_section",
+ },
+ {
+ "fieldname": "bureau",
+ "label": "Bureau",
+ "fieldtype": "Link",
+ "options": "Bureau",
+ "insert_after": "expected_revenue",
+ "fetch_from": "program_request.bureau",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "column_break_program",
+ "fieldtype": "Column Break",
+ "insert_after": "generates_revenue",
+ },
+ {
+ "fieldname": "program_type",
+ "label": "Program Type",
+ "fieldtype": "Link",
+ "options": "Program Type",
+ "insert_after": "column_break_program",
+ "fetch_from": "program_request.program_type",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "budget_expense_types",
+ "fieldtype": "Table MultiSelect",
+ "label": "Budget Expense Types",
+ "options": "Project Expense Type",
+ "insert_after": "program_type",
+ },
+ {
+ "fieldname": "generates_revenue",
+ "fieldtype": "Check",
+ "label": "Generates Revenue",
+ "read_only": 1,
+ "fetch_from": "program_request.generates_revenue",
+ "insert_after": "program_request",
+ },
+ {
+ "fieldname": "expected_revenue",
+ "fieldtype": "Float",
+ "label": "Expected Revenue",
+ "read_only": 1,
+ "fetch_from": "program_request.expected_revenue",
+ "insert_after": "generates_revenue",
+ },
+ {
+ "fieldname": "allocated_resources_details_section",
+ "fieldtype": "Section Break",
+ "label": " Allocated Resource Details",
+ "collapsible": 1,
+ "insert_after": "program_request",
+ },
+ {
+ "fieldname": "allocated_manpower_details",
+ "fieldtype": "Table",
+ "label": "Allocated Manpower Detail",
+ "options": "Allocated Manpower Detail",
+ "insert_after": "allocated_item_details",
+ },
+ {
+ "fieldname": "allocated_item_details",
+ "fieldtype": "Table",
+ "label": "Allocated Item Details",
+ "options": "Required Items Detail",
+ "insert_after": "allocated_resources_details_section",
+ },
+ {
+ "fieldname": "approved_budget",
+ "fieldtype": "Currency",
+ "label": "Approved Budget",
+ "insert_after": "budget_expense_types",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "estimated_budget",
+ "fieldtype": "Currency",
+ "label": "Estimated Budget",
+ "fetch_from": "program_request.estimated_budget",
+ "insert_after": "approved_budget",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description",
+ "fetch_from": "program_request.description",
+ "insert_after": "bureau",
+ },
+ {
+ "fieldname": "requirements",
+ "fieldtype": "Text Editor",
+ "label": "Requirements",
+ "fetch_from": "program_request.requirements",
+ "insert_after": "description",
+ },
+ {
+ "fieldname": "location",
+ "fieldtype": "Link",
+ "label": "Location",
+ "options": "Location",
+ "fetch_from": "program_request.location",
+ "insert_after": "department",
+ "fetch_on_save_if_empty": 1,
+ },
+ {
+ "fieldname": "requirements_details",
+ "fieldtype": "Section Break",
+ "label": "Requirements Details",
+ "collapsible": 1,
+ "insert_after": "estimated_budget",
+ },
+ {
+ "fieldname": "required_items",
+ "fieldtype": "Table",
+ "label": "Required Items",
+ "options": "Required Items Table",
+ "insert_after": "requirements_details",
+ },
+ {
+ "fieldname": "required_manpower_details",
+ "fieldtype": "Table",
+ "label": "Required Manpower Details",
+ "options": "Required Manpower Details",
+ "insert_after": "required_items",
+ },
+ {
+ "fieldname": "required_vehicle_details",
+ "fieldtype": "Table",
+ "label": "Required Vehicle Details",
+ "options": "Required Vehicle Details",
+ "insert_after": "required_manpower_details",
+ },
+ {
+ "fieldname": "allocated_vehicle_details",
+ "fieldtype": "Table",
+ "label": "Allocated Vehicle Details",
+ "options": "Allocated Vehicle Details",
+ "insert_after": "allocated_manpower_details",
+ },
+ {
+ "fieldname": "asset_location",
+ "fieldtype": "Link",
+ "label": "Asset Location",
+ "options": "Location",
+ "insert_after": "estimated_budget",
+ },
+ ]
+ }
-def get_sales_invoice_custom_fields():
- '''
- Custom fields that need to be added to the Sales Invoice Doctype
- '''
- return {
- "Sales Invoice": [
- {
- "fieldname": "actual_customer",
- "fieldtype": "Link",
- "label": "Actual Customer",
- "options": "Customer",
- "depends_on": "eval:doc.is_agent == 1",
- "insert_after": "is_agent"
- },
- {
- "fieldname": "is_agent",
- "fieldtype": "Check",
- "label": "Is Agency",
- "read_only":1,
- "fetch_from": "customer.is_agent",
- "depends_on": "eval:doc.is_agent",
- "insert_after": "customer"
- },
- {
- "fieldname": "actual_customer_group",
- "fieldtype": "Link",
- "label": "Actual Customer Group",
- "options": "Customer Group",
- "read_only": 1,
- "fetch_from": "actual_customer.customer_group",
- "insert_after": "actual_customer"
- },
- {
- "fieldname": "include_in_ibf",
- "fieldtype": "Check",
- "label": "Include in IBF",
- "read_only": 1,
- "insert_after": "actual_customer_group"
- },
- {
- "fieldname": "region",
- "fieldtype": "Link",
- "options": "Region",
- "label": "Region",
- "insert_after": "is_reverse_charge"
- },
- {
- "fieldname": "executive",
- "fieldtype": "Link",
- "options": "Employee",
- "label": "Executive",
- "insert_after": "due_date"
- },
- {
- "fieldname": "executive_name",
- "fieldtype": "Data",
- "label": "Executive Name",
- "insert_after": "executive",
- "fetch_from": "executive.employee_name",
- "read_only": 1
- },
- {
- "fieldname": "is_barter_invoice",
- "fieldtype": "Check",
- "label": "Is Barter Invoice",
- "read_only": 1,
- "insert_after": "include_in_ibf",
- "fetch_from": "reference_id.is_barter"
- },
- {
- "fieldname": "reference_id",
- "fieldtype": "Link",
- "options":"Quotation",
- "label": "Quotation",
- "read_only":1,
- "insert_after": "naming_series"
- },
- {
- "fieldname": "sales_type",
- "fieldtype": "Link",
- "label": "Sales Type",
- "insert_after": "naming_series",
- "options": "Sales Type"
- }
- ]
- }
-def get_quotation_custom_fields():
- '''
- Custom fields that need to be added to the Quotation DocType
- '''
- return {
- "Quotation": [
- {
- "fieldname": "is_agent",
- "fieldtype": "Check",
- "label": "Is Agency",
- "read_only":1,
- "fetch_from": "party_name.is_agent",
- "depends_on": "eval:doc.is_agent",
- "insert_after": "party_name"
- },
- {
- "fieldname": "actual_customer",
- "fieldtype": "Link",
- "label": "Actual Customer",
- "options": "Customer",
- "depends_on": "eval:doc.is_agent == 1",
- "insert_after": "is_agent"
- },
- {
- "fieldname": "actual_customer_group",
- "fieldtype": "Link",
- "label": "Actual Customer Group",
- "options": "Customer Group",
- "read_only": 1,
- "fetch_from": "actual_customer.customer_group",
- "insert_after": "actual_customer"
- },
- {
- "fieldname": "customer_purchase_order_reference",
- "fieldtype": "Data",
- "label": "Customer Purchase Order Reference",
- "insert_after": "valid_till"
- },
- {
- "fieldname": "executive",
- "fieldtype": "Link",
- "label": "Executive",
- "options":"Employee",
- "insert_after": "customer_purchase_order_reference"
- },
- {
- "fieldname": "executive_name",
- "fieldtype": "Data",
- "label": "Executive Name",
- "insert_after": "executive",
- "fetch_from": "executive.employee_name",
- "read_only":1
- },
- {
- "fieldname": "is_barter",
- "fieldtype": "Check",
- "label": "Is Barter",
- "insert_after": "amended_from"
- },
- {
- "fieldname": "purchase_order",
- "fieldtype": "Link",
- "label": "Purchase Order",
- "insert_after": "is_barter",
- "depends_on": "eval:doc.is_barter",
- "options": "Purchase Order"
- },
- {
- "fieldname": "sales_type",
- "fieldtype": "Link",
- "label": "Default Sales Type",
- "insert_after": "purchase_order",
- "options": "Sales Type"
- },
- {
- "fieldname": "region",
- "fieldtype": "Link",
- "label": "Region",
- "insert_after": "customer_name",
- "options": "Region"
- },
- {
- "fieldname": "albatross_details_section",
- "fieldtype": "Section Break",
- "label": "Albatross Details",
- "insert_after": "is_barter"
- },
- {
- "fieldname": "albatross_ro_id",
- "fieldtype": "Data",
- "label": "Albatross RO ID",
- "insert_after": "albatross_details_section",
- "read_only":1
- },
- {
- "fieldname": "ro_no",
- "fieldtype": "Data",
- "label": "RO No",
- "insert_after": "albatross_ro_id",
- "read_only":1
- },
- {
- "fieldname": "ro_date",
- "fieldtype": "Date",
- "label": "RO Date",
- "insert_after": "ro_no",
- "read_only":1
- },
- {
- "fieldname": "ro_option",
- "fieldtype": "Data",
- "label": "RO Option",
- "insert_after": "ro_date",
- "read_only":1
- },
- {
- "fieldname": "region_revenue_percentage",
- "fieldtype": "Percent",
- "label": "Region Revenue Percentage",
- "insert_after": "ro_option",
- "read_only":1
- },
- {
- "fieldname": "albatross_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "region_revenue_percentage"
- },
- {
- "fieldname": "product_name",
- "fieldtype": "Data",
- "label": "Product Name",
- "insert_after": "albatross_column_break",
- "read_only":1
- },
- {
- "fieldname": "program_name",
- "fieldtype": "Data",
- "label": "Program Name",
- "insert_after": "product_name",
- "read_only":1
- },
- {
- "fieldname": "no_of_eps",
- "fieldtype": "Data",
- "label": "No of Episodes",
- "insert_after": "program_name",
- "read_only":1
- },
- {
- "fieldname": "commission_per",
- "fieldtype": "Float",
- "label": "Commission Per",
- "insert_after": "no_of_eps",
- "read_only":1
- },
- {
- "fieldname": "fct_total",
- "fieldtype": "Float",
- "label": "FCT Total",
- "insert_after": "commission_per",
- "read_only":1
- }
- ],
- "Quotation Item": [
- {
- "fieldname": "sales_type",
- "fieldtype": "Link",
- "label": "Sales Type",
- "options": "Sales Type",
- "insert_after": "item_name"
- }
- ]
- }
+def get_employment_type_custom_fields():
+ """
+ Custom fields that need to be added to the Employment Type DocType
+ """
+ return {
+ "Employment Type": [
+ {
+ "fieldname": "penalty_leave_type",
+ "fieldtype": "Link",
+ "label": "Penalty Leave Type",
+ "options": "Leave Type",
+ "insert_after": "employee_type_name",
+ }
+ ]
+ }
-def get_purchase_invoice_custom_fields():
- '''
- Custom fields that need to be added to the Purchase Invoice Doctype
- '''
- return {
- "Purchase Invoice": [
- {
- "fieldname": "barter_invoice",
- "fieldtype": "Check",
- "label": "Barter Invoice",
- "read_only": 1,
- "fetch_from": "quotation.is_barter",
- "insert_after": "supplier"
- },
- {
- "fieldname": "quotation",
- "fieldtype": "Link",
- "label": "Quotation",
- "read_only": 1,
- "options": "Quotation",
- "insert_after": "barter_invoice"
-
- },
- {
- "fieldname": "invoice_type",
- "fieldtype": "Select",
- "options": "Normal\nStringer Bill",
- "default": "Normal",
- "label": "Invoice Type",
- "insert_after": "naming_series",
- "read_only": 1
- },
- {
- "fieldname": "purchase_order_id",
- "fieldtype": "Link",
- "label": "Purchase Order",
- "options": "Purchase Order",
- "insert_after": "naming_series"
- },
- {
- "fieldname": "stringer_bill_reference",
- "fieldtype": "Link",
- "label": "Stringer Bill Reference",
- "options": "Stringer Bill",
- "depends_on": "eval:doc.invoice_type == 'Stringer Bill' ",
- "read_only": 1,
- "insert_after": "purchase_order_id"
- },
- {
- "fieldname": "batta_claim_reference",
- "fieldtype": "Link",
- "label": "Batta Claim Reference",
- "read_only": 1,
- "options": "Batta Claim",
- "insert_after": "stringer_bill_reference"
- },
- {
- "fieldname": "bureau",
- "fieldtype": "Link",
- "label": "Bureau",
- "read_only": 1,
- "options": "Bureau",
- "insert_after": "supplier"
- },
- {
- "fieldname": "attach",
- "fieldtype": "Attach",
- "label": "Attachments",
- "insert_after": "base_net_total"
- }
- ]
- }
-def get_supplier_custom_fields():
- '''
- Custom fields that need to be added to the Supplier Doctype
- '''
- return {
- "Supplier": [
- {
- "fieldname": "is_stringer",
- "fieldtype": "Check",
- "label": "Is Stringer",
- "insert_after": "supplier_name"
- },
- {
- "fieldname": "bureau",
- "fieldtype": "Link",
- "label": "Bureau",
- "options": "Bureau",
- "depends_on": "eval:doc.is_stringer == 1",
- "insert_after": "is_stringer"
-
- },
- {
- "fieldname": "area",
- "fieldtype": "Data",
- "label": "Area",
- "depends_on": "eval:doc.is_stringer == 1",
- "insert_after": "bureau"
-
- },
- {
- "fieldname": "designation",
- "fieldtype": "Link",
- "label": "Designation",
- "options": "Designation",
- "insert_after": "country"
-
- }
- ]
- }
+def get_event_custom_fields():
+ """
+ Custom fields to be added to the Event Doctype
+ """
+ return {
+ "Event": [
+ {
+ "fieldname": "contribution_of_employee",
+ "fieldtype": "Small Text",
+ "label": "Contribution of Employee",
+ "insert_after": "description",
+ "depends_on": "eval:doc.event_category == 'One to One Meeting'",
+ },
+ {
+ "fieldname": "improvement_of_employee",
+ "fieldtype": "Small Text",
+ "label": "Areas of Improvement of Employee",
+ "insert_after": "contribution_of_employee",
+ "depends_on": "eval:doc.event_category == 'One to One Meeting'",
+ },
+ {
+ "fieldname": "training_needs_of_employee",
+ "fieldtype": "Small Text",
+ "label": "Training Needs of Employee",
+ "insert_after": "improvement_of_employee",
+ "depends_on": "eval:doc.event_category == 'One to One Meeting'",
+ },
+ {
+ "fieldname": "is_employee_eligible_for_promotion",
+ "fieldtype": "Select",
+ "label": "Is Employee Eligible for Promotion",
+ "options": "\nYes\nNo",
+ "insert_after": "training_needs_of_employee",
+ "depends_on": "eval:doc.event_category == 'One to One Meeting'",
+ },
+ {
+ "fieldname": "remarks_for_promotion",
+ "fieldtype": "Small Text",
+ "label": "Remarks",
+ "insert_after": "is_employee_eligible_for_promotion",
+ "depends_on": "eval:(doc.is_employee_eligible_for_promotion == 'Yes' || doc.is_employee_eligible_for_promotion == 'No') && doc.event_category == 'One to One Meeting'",
+ },
+ {
+ "fieldname": "appraisal_reference",
+ "fieldtype": "Link",
+ "label": "Appraisal Reference",
+ "options": "Appraisal",
+ "insert_after": "status",
+ },
+ {
+ "fieldname": "assign_service_unit",
+ "fieldtype": "Check",
+ "label": "Assign Service Unit",
+ "insert_after": "add_video_conferencing",
+ },
+ {
+ "fieldname": "meeting_room",
+ "fieldtype": "Link",
+ "label": "Meeting Room",
+ "options": "Service Unit",
+ "depends_on": "eval:doc.assign_service_unit == 1",
+ "mandatory_depends_on": "eval:doc.assign_service_unit == 1",
+ "insert_after": "assign_service_unit",
+ },
+ {
+ "fieldname": "section_break_epd",
+ "fieldtype": "Section Break",
+ "label": " ",
+ "insert_after": "sunday",
+ },
+ {
+ "fieldname": "external_participants",
+ "fieldtype": "Table",
+ "label": "External Participants",
+ "options": "External Participants Detail",
+ "insert_after": "section_break_epd",
+ },
+ {
+ "fieldname": "reason_for_rejection",
+ "fieldtype": "Small Text",
+ "label": "Reason for Rejection",
+ "insert_after": "repeat_this_event",
+ },
+ ]
+ }
-def get_item_group_custom_fields():
- '''
- Custom fields that need to be added to the Quotation Item Doctype
- '''
- return {
- "Item Group": [
- {
- "fieldname": "hireable",
- "fieldtype": "Check",
- "label": "Hireable",
- "fetch_from":"parent_item_group.hireable",
- "set_only_once":1,
- "fetch_if_empty":1,
- "insert_after": "gst_hsn_code"
- }
-
- ]
- }
-def get_item_custom_fields():
- '''
- Custom fields that need to be added to the Quotation Item Doctype
- '''
- return {
- "Item": [
- {
- "fieldname": "is_production_item",
- "fieldtype": "Check",
- "label": "Is Production Item",
- "insert_after": "stock_uom"
- },
- {
- "fieldname": "sales_type",
- "fieldtype": "Link",
- "label": "Sales Type",
- "options": "Sales Type",
- "insert_after": "is_production_item"
- },
- {
- "fieldname": "hireable",
- "fieldtype": "Check",
- "label": "Hireable",
- "fetch_from":"item_group.hireable",
- "set_only_once":1,
- "insert_after": "gst_hsn_code"
- },
- {
- "fieldname": "service_item",
- "fieldtype": "Link",
- "label": "Service Item",
- "options": "Item",
- "read_only":1,
- "insert_after": "item_group"
- },
- {
- "fieldname": "item_audit_notification",
- "fieldtype": "Check",
- "label": "Periodic Notification for Asset Auditing ",
- "depends_on": "eval:doc.is_fixed_asset == 1",
- "insert_after": "asset_category"
- },
- {
- "fieldname": "item_notification_frequency",
- "fieldtype": "Select",
- "label": "Notification Frequency",
- "options":"\nMonthly\nTrimonthly\nQuarterly\nHalf Yearly\nYearly",
- "depends_on": "eval:doc.item_audit_notification == 1",
- "insert_after": "item_audit_notification"
- } ,
- {
- "fieldname": "item_notification_template",
- "fieldtype": "Link",
- "label": "Notification Template",
- "options":"Email Template",
- "depends_on": "eval:doc.item_audit_notification == 1",
- "insert_after": "item_notification_frequency"
- },
- {
- "fieldname": "start_notification_from",
- "fieldtype": "Select",
- "label": "Start Notification From",
- "options":"\nJanuary\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember",
- "depends_on": "eval:doc.item_audit_notification == 1",
- "insert_after": "item_audit_notification"
- },
- {
- "fieldname": "is_makeup_item",
- "fieldtype": "Check",
- "label": "Is Makeup Item",
- "insert_after": "is_exempt"
- }
- ]
- }
+def get_leave_application_custom_fields():
+ """
+ Custom fields that need to be added to the Leave Application Doctype
+ """
+ return {
+ "Leave Application": [
+ {
+ "fieldname": "medical_certificate",
+ "fieldtype": "Attach",
+ "label": "Medical Certificate",
+ "hidden": 1,
+ "insert_after": "leave_type",
+ }
+ ]
+ }
-def get_employee_custom_fields():
- '''
- Custom fields that need to be added to the Employee Doctype
- '''
- return {
- "Employee": [
- {
- "fieldname": "bureau",
- "fieldtype": "Link",
- "options": "Bureau",
- "label": "Bureau",
- "insert_after": "last_name"
- },
- {
- "fieldname": "stringer_type",
- "fieldtype": "Link",
- "options": "Stringer Type",
- "label": "Stringer Type",
- "insert_after": "Bureau"
- },
- {
- "fieldname": "leave_policy",
- "fieldtype": "Link",
- "options": "Leave Policy",
- "label": "Leave Policy",
- "insert_after": "attendance_device_id"
- },
- {
- "fieldname": "leave_policy_name",
- "fieldtype": "Data",
- "label": "Title",
- "fetch_from": "leave_policy.title",
- "insert_after": "leave_policy",
- "read_only": 1
- },
- {
- "fieldname": "name_of_father",
- "fieldtype": "Data",
- "label": "Father's Name",
- "insert_after": "date_of_birth"
- },
- {
- "fieldname": "name_of_spouse",
- "fieldtype": "Data",
- "label": "Spouse's Name",
- "insert_after": "name_of_father"
- },
- {
- "fieldname": "pincode",
- "fieldtype": "Data",
- "label": "Pincode",
- "insert_after": "address_section"
- },
- {
- "fieldname": "aadhar_id",
- "fieldtype": "Data",
- "label": "Aadhar Id",
- "insert_after": "marital_status"
- },
- {
- "fieldname": "date_of_appointment",
- "fieldtype": "Date",
- "label": "Date of Appointment",
- "insert_after": "date_of_joining"
- },
- {
- "fieldname": "nominee_details_section",
- "fieldtype": "Section Break",
- "label": "Nominee Details",
- "insert_after": "iban"
- },
- {
- "fieldname": "nominee_details",
- "fieldtype": "Table",
- "label": "Nominee Details",
- "options":"Nominee Details",
- "insert_after":"nominee_details_section"
- },
- {
- "fieldname": "additional_information_section",
- "fieldtype": "Section Break",
- "label": _("Additional Information"),
- "insert_after": "place_of_issue",
- "collapsible": 1
- },
- {
- "fieldname": "physical_disabilities",
- "fieldtype": "Select",
- "label": "Do you have a physical disability",
- "options":"Yes\nNo",
- "default": "No",
- "insert_after": "additional_information_section"
- },
- {
- "fieldname": "disabilities",
- "fieldtype": "Data",
- "label": "Please specify the disability",
- "insert_after": "physical_disabilities",
- "depends_on": "eval:doc.physical_disabilities == 'Yes'"
- },
- {
- "fieldname": "marital_indebtness",
- "fieldtype": "Select",
- "options":"Yes\nNo",
- "default": "No",
- "label": "Do you have marital indebtedness",
- "insert_after": "disabilities"
- },
- {
- "fieldname": "training_status",
- "fieldtype": "Select",
- "options":"Not Started\nIn Progress\nCompleted\nNot Completed\nPartially Completed",
- "label": "Training Status",
- "insert_after": "status"
- },
- {
- "fieldname": "court_proceedings",
- "fieldtype": "Select",
- "options":"Yes\nNo",
- "default": "No",
- "label": "Are there any ongoing court proceedings",
- "insert_after": "marital_indebtness",
- },
- {
- "fieldname": "court_proceedings_details",
- "fieldtype": "Small Text",
- "label": "Court Proceedings Details",
- "insert_after": "court_proceedings",
- "depends_on": "eval:doc.court_proceedings == 'Yes'"
- },
- {
- "fieldname": "column_break_travel",
- "fieldtype": "Column Break",
- "insert_after": "court_proceedings_details"
- },
- {
- "fieldname": "are_you_willing_to_travel",
- "label": "Are you willing to travel",
- "fieldtype": "Check",
- "insert_after": "column_break_travel",
- },
- {
- "fieldname": "in_india",
- "label": "In India",
- "fieldtype": "Select",
- "options":"Yes\nNo",
- "default":"No",
- "insert_after": "are_you_willing_to_travel",
- "depends_on": "eval:doc.are_you_willing_to_travel == 1"
- },
- {
- "fieldname": "abroad",
- "label": "Abroad",
- "fieldtype": "Select",
- "options":"Yes\nNo",
- "default":"No",
- "insert_after": "in_india",
- "depends_on": "eval:doc.are_you_willing_to_travel == 1"
- },
- {
- "fieldname": "state_restrictions_problems",
- "label": "State Restrictions/Problems if any",
- "fieldtype": "Data",
- "insert_after": "abroad",
- "depends_on": "eval:doc.are_you_willing_to_travel == 1"
- },
- {
- "fieldname": "places_to_travel",
- "label": "Places/Countries of your choice where you'd like to travel on job",
- "fieldtype": "Data",
- "insert_after": "state_restrictions_problems",
- },
- {
- "fieldname": "are_you_related_to_employee",
- "label": "Are you related to any of our employees",
- "fieldtype": "Check",
- "insert_after": "places_to_travel"
- },
- {
- "fieldname": "related_employee_name",
- "label": "Related Employee Name",
- "fieldtype": "Data",
- "insert_after": "are_you_related_to_employee",
- "depends_on": "eval:doc.are_you_related_to_employee == 1",
- },
- {
- "fieldname": "documents_tab",
- "fieldtype": "Tab Break",
- "label": "Documents",
- "insert_after": "internal_work_history"
- },
- {
- "fieldname": "employee_documents",
- "fieldtype": "Table",
- "label": "Employee Documents",
- "options":"Employee Documents",
- "insert_after":"documents_tab"
- },
- {
- "fieldname": "no_of_children",
- "fieldtype": "Int",
- "label": "No.of Children",
- "insert_after":"marital_status"
- },
- {
- "fieldname": "company_number",
- "fieldtype": "Data",
- "label": "Company Mobile Number",
- "options":"Phone",
- "insert_after":"cell_number"
- },
- {
- "fieldname": "landmark",
- "fieldtype": "Data",
- "label": "Landmark",
- "insert_after":"current_address"
- },
- {
- "fieldname": "landmark_per",
- "fieldtype": "Data",
- "label": "Landmark",
- "insert_after":"permanent_address"
- },
- {
- "fieldname": "emergency_contact_name",
- "fieldtype": "Data",
- "label": "Emergency Contact Name",
- "insert_after":"person_to_be_contacted"
- },
- {
- "fieldname": "emergency_phone",
- "fieldtype": "Data",
- "label": "Emergency Phone",
- "insert_after":"emergency_phone_number"
- },
- {
- "fieldname": "relation_emergency",
- "fieldtype": "Data",
- "label": "Relation",
- "insert_after":"relation"
- },
- {
- "fieldname": "assessment_officer",
- "fieldtype": "Link",
- "options": "Employee",
- "label": "Assessment Officer",
- "insert_after": "reports_to"
- }
-
- ],
-
- "Employee External Work History":[
- {
- "fieldname": "period_from",
- "fieldtype": "Date",
- "label": "Period From",
- "insert_after": "designation"
- },
- {
- "fieldname": "period_to",
- "fieldtype": "Date",
- "label": "Period To",
- "insert_after": "period_from"
- },
- {
- "fieldname": "last_position_held",
- "fieldtype": "Data",
- "label": "Last Position Held",
- "insert_after": "period_to"
- },
- {
- "fieldname": "job_responsibility",
- "fieldtype": "Small Text",
- "label": "Job Responsibility",
- "insert_after": "last_position_held"
- },
- {
- "fieldname": "designation_of_immediate_superior",
- "fieldtype": "Data",
- "label": "Designation Of Immediate Superior",
- "insert_after": "job_responsibility"
- },
- {
- "fieldname": "gross_salary_drawn",
- "fieldtype": "Float",
- "label": "Gross Salary Drawn ",
- "insert_after": "designation_of_immediate_superior"
- },
- {
- "fieldname": "reason_for_leaving",
- "fieldtype": "Small Text",
- "label": "Reason For Leaving",
- "insert_after": "gross_salary_drown"
- }
- ]
- }
-def get_voucher_entry_custom_fields():
- '''
- Custom fields that need to be added to the Employee Doctype
- '''
- return {
- "Voucher Entry": [
- {
- "fieldname": "bureau",
- "fieldtype": "Link",
- "options": "Bureau",
- "label": "Bureau",
- "insert_after": "balance"
- }
- ]
- }
+def get_attendance_request_custom_fields():
+ """
+ Custom fields that need to be added to the Attendance Request DocType.
+ """
+ return {
+ "Attendance Request": [
+ {
+ "fieldname": "reports_to",
+ "fieldtype": "Link",
+ "label": "Reports To",
+ "options": "Employee",
+ "fetch_from": "employee.reports_to",
+ "insert_after": "reason",
+ },
+ {
+ "fieldname": "reports_to_name",
+ "fieldtype": "Data",
+ "label": "Reports To Name",
+ "insert_after": "reports_to",
+ "fetch_from": "reports_to.employee_name",
+ },
+ {
+ "fieldname": "reports_to_user",
+ "fieldtype": "Link",
+ "label": "Reports To User",
+ "options": "User",
+ "insert_after": "reports_to_name",
+ "fetch_from": "reports_to.user_id",
+ },
+ ]
+ }
-def get_expected_skill_set_custom_fields():
- '''
- Custom fields that need to be added to the Expected Skill Set Doctype
- '''
- return {
- "Expected Skill Set": [
- {
- "fieldname": "weight",
- "fieldtype": "Float",
- "label": "Weight",
- "insert_after": "description"
- }
- ]
- }
-def get_hd_ticket_custom_fields():
- '''
- Custom fields to be added to the HD Ticket Doctype
- '''
- return {
- "HD Ticket": [
- {
- "fieldname": "ticket_section_break",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "ticket_split_from"
- },
- {
- "fieldname": "spare_part_needed",
- "fieldtype": "Check",
- "label": "Spare Part Needed",
- "insert_after": "ticket_section_break"
- },
- {
- "fieldname": "spare_part_item_table",
- "fieldtype": "Table",
- "label": "Spare Part Items",
- "insert_after": "spare_part_needed",
- "options": "Spare Part Item",
- "depends_on": "eval:doc.spare_part_needed == 1"
- },
- {
- "fieldname": "raised_for",
- "fieldtype": "Link",
- "options": "User",
- "label": "Raised For (Email)",
- "insert_after": "raised_by"
- },
- {
- "fieldname": "attach",
- "fieldtype": "Attach",
- "label": "Attachments",
- "insert_after": "agent_group"
- }
- ]
- }
+def get_customer_custom_fields():
+ """
+ Custom fields that need to be added to the Customer Doctype
+ """
+ return {
+ "Customer": [
+ {
+ "fieldname": "msme_status",
+ "fieldtype": "Select",
+ "label": "MSME Status",
+ "options": "\nMSME\nNon-MSME",
+ "insert_after": "customer_group",
+ },
+ {
+ "fieldname": "msme_number",
+ "fieldtype": "Int",
+ "label": "MSME Number",
+ "insert_after": "msme_status",
+ },
+ {
+ "fieldname": "region",
+ "fieldtype": "Link",
+ "label": "Region",
+ "options": "Region",
+ "reqd": 1,
+ "insert_after": "msme_number",
+ },
+ {
+ "fieldname": "is_agent",
+ "fieldtype": "Check",
+ "label": "Is Agency",
+ "insert_after": "region",
+ },
+ {
+ "fieldname": "is_edited",
+ "fieldtype": "Check",
+ "label": "Is Edited",
+ "hidden": 1,
+ "default": 0,
+ "no_copy": 1,
+ "insert_after": "is_agent",
+ },
+ ]
+ }
-def get_interview_round_custom_fields():
- '''
- Custom fields that need to be added to the Interview Round Child Table
- '''
- return {
- "Interview Round": [
- {
- "fieldname": "expected_questions",
- "fieldtype": "Table",
- "label": "Interview Questions",
- "options":"Interview Questions",
- "insert_after":"expected_skill_set"
- }
- ]
- }
+def get_department_custom_fields():
+ """
+ Custom fields that need to be added to the Department Doctype
+ """
+ return {
+ "Department": [
+ {
+ "fieldname": "head_of_department",
+ "fieldtype": "Link",
+ "label": "Head Of Department",
+ "options": "Employee",
+ "insert_after": "department_name",
+ },
+ {
+ "fieldname": "head_of_department_name",
+ "fieldtype": "Data",
+ "label": "Head Of Department(Name)",
+ "insert_after": "head_of_department",
+ "fetch_from": "head_of_department.employee_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "abbreviation",
+ "fieldtype": "Data",
+ "label": "Abbreviation",
+ "reqd": 1,
+ "unique": 1,
+ "insert_after": "head_of_department_name",
+ },
+ {
+ "fieldname": "threshold_amount",
+ "fieldtype": "Float",
+ "label": "Threshold Amount",
+ "insert_after": "parent_department",
+ },
+ {
+ "fieldname": "finance_group",
+ "fieldtype": "Link",
+ "label": "Finance Group",
+ "options": "Finance Group",
+ "insert_after": "company",
+ },
+ {
+ "fieldname": "depart_cost_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "leave_block_list",
+ },
+ {
+ "fieldname": "department_cost_center",
+ "fieldtype": "Table",
+ "label": "Cost Center",
+ "options": "Department Cost Center",
+ "insert_after": "depart_cost_section",
+ },
+ ]
+ }
-def get_interview_custom_fields():
- '''
- Custom fields that need to be added to the Interview Doctype
- '''
- return {
- "Interview": [
- {
- "fieldname": "department",
- "fieldtype": "Link",
- "options": "Department",
- "label": "Department",
- "insert_after": "applicant_name",
- "fetch_from": "job_applicant.department"
- },
- {
- "fieldname": "applicant_name",
- "fieldtype": "Data",
- "label": "Applicant Name",
- "insert_after": "job_applicant",
- "fetch_from": "job_applicant.applicant_name",
- "read_only": 1
-
- },
- {
- "fieldname": "applicant_email",
- "fieldtype": "Data",
- "label": "Applicant Email ID",
- "insert_after": "job_applicant",
- "fetch_from": "job_applicant.email_id",
- "hidden": 1
- }
-
- ]
- }
-def get_job_requisition_custom_fields():
- '''
- Custom fields that need to be added to the Job Requisition Doctype
- '''
- return {
- "Job Requisition": [
- {
- "fieldname": "work_details",
- "fieldtype": "Section Break",
- "label": "Work Details",
- "insert_after": "requested_by_designation"
- },
- {
- "fieldname": "employment_type",
- "fieldtype": "Link",
- "options": "Employment Type",
- "label": "Employment Type",
- "insert_after": "department",
- "permlevel": 1
- },
-
- {
- "fieldname": "no_of_days_off",
- "fieldtype": "Int",
- "label": "Number of Days Off",
- "description": "Number Of Days Off within a 30-day Period",
- "insert_after": "work_details",
- "permlevel": 1
- },
- {
- "fieldname": "work_details_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "min_experience"
- },
- {
- "fieldname": "is_work_shift_needed",
- "fieldtype": "Check",
- "label": "Is Shift Work Needed",
- "insert_after": "work_details_column_break",
- "permlevel": 1
- },
- {
- "fieldname": "travel_required",
- "fieldtype": "Check",
- "label": "Travel required for the position",
- "insert_after": "is_work_shift_needed",
- "permlevel": 1
- },
- {
- "fieldname": "driving_license_needed",
- "fieldtype": "Check",
- "label": "Driving License Needed for this Position",
- "depends_on": "eval:doc.travel_required == 1",
- "insert_after": "travel_required",
- "permlevel": 1
- },
- {
- "fieldname": "license_type",
- "fieldtype": "Link",
- "label": "License Type",
- "options": "License Type",
- "depends_on": "eval:doc.driving_license_needed == 1",
- "mandatory_depends_on":"eval:doc.driving_license_needed == 1",
- "insert_after": "driving_license_needed",
- "permlevel": 1
- },
- {
- "fieldname": "education",
- "fieldtype": "Section Break",
- "label": "Education and Qualification Details",
- "insert_after": "license_type"
- },
- {
- "fieldname": "min_education_qual",
- "fieldtype": "Table MultiSelect",
- "label": "Preferred Educational Qualification",
- 'options':"Educational Qualifications",
- "insert_after": "education",
- "permlevel": 1
- },
- {
- "fieldname": "min_experience",
- "fieldtype": "Float",
- "label": "Minimum Experience Required (Years)",
- "insert_after": "no_of_days_off",
- "permlevel": 1
- },
- {
- "fieldname": "reset_column",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "license_type"
- },
- {
- "fieldname": "language_proficiency",
- "fieldtype": "Table",
- "options": "Language Proficiency",
- "label": "Language Proficiency",
- "insert_after": "reset_column",
- "permlevel": 1
- },
- {
- "fieldname": "skill_proficiency",
- "fieldtype": "Table",
- "options": "Skill Proficiency",
- "label": "Skill Proficiency",
- "description": "Proficency selected here is the minimum proficency needed.",
- "insert_after": "language_proficiency"
- },
- {
- "fieldname": "job_description_template",
- "fieldtype": "Link",
- "label": "Job Description Template",
- "options": "Job Description Template",
- "insert_after": "job_description_tab",
- "permlevel": 1
- },
- {
- "fieldname": "request_for",
- "label": "Request For",
- "fieldtype": "Select",
- "options": "Employee Replacement\nExisting Vacancy\nNew Vacancy",
- "insert_after": "naming_series"
- },
- {
- "fieldname": "employee_left",
- "label": "Employees Who Replaced",
- "fieldtype": "Link",
- "options": "Employee",
- "insert_after": "request_for",
- "depends_on": "eval:doc.request_for == 'Employee Replacement'"
- },
- {
- "fieldname": "relieving_date",
- "fieldtype": "Date",
- "label": "Relieving Date",
- "insert_after": "employee_left",
- "fetch_from":"employee_left.relieving_date",
- "depends_on":"eval:doc.request_for == 'Employee Replacement'",
- "read_only": 1
- },
- {
- "fieldname": "interview",
- "fieldtype": "Section Break",
- "label": "Interview Details",
- "insert_after": "requested_by_designation"
- },
- {
- "fieldname": "interview_rounds",
- "fieldtype": "Table MultiSelect",
- "options": "Interview Rounds",
- "label": "Interview Rounds",
- "insert_after": "interview",
- "permlevel": 1
- },
-
- {
- "fieldname": "location",
- "label": "Preferred Location",
- "fieldtype": "Link",
- "options": "Location",
- "insert_after": "employment_type",
- "permlevel": 1
- },
- {
- "fieldname": "job_title",
- "fieldtype": "Data",
- "label": "Job Title",
- "insert_after": "job_description_template",
- "reqd": 1,
- },
- {
- "fieldname": "suggested_designation",
- "fieldtype": "Link",
- "label": "Suggested Designation",
- "options": "Designation",
- "insert_after": "request_for",
- "permlevel": 2,
- "depends_on": "eval:doc.request_for == 'New Vacancy'"
- },
- {
- "fieldname": "suggestions",
- "fieldtype": "Small Text",
- "label": "Suggestions/Feedback",
- "insert_after": "description",
- "permlevel": 3
- },
- {
- "fieldname": "publish_on_job_section",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "requested_by_designation"
- },
- {
- "fieldname": "publish_on_job_opening",
- "fieldtype": "Check",
- "default": "1",
- "label": "Publish on Job Opening",
- "insert_after": "publish_on_job_section",
- "permlevel":4
- }
- ]
- }
+def get_driver_custom_fields():
+ """
+ Custom fields that need to be added to the Driver DocType
+ """
+ return {
+ "Driver": [
+ {
+ "fieldname": "is_internal",
+ "fieldtype": "Check",
+ "label": "Is Internal",
+ "insert_after": "transporter",
+ "reqd": 0,
+ },
+ ]
+ }
-def get_job_applicant_custom_fields():
- '''
- Custom fields that need to be added to the Job Applicant Doctype
- '''
- return {
- "Job Applicant": [
- {
- "fieldname": "date_of_birth",
- "fieldtype": "Date",
- "label": "Date of Birth",
- "insert_after": "email_id"
- },
- {
- "fieldname": "gender",
- "fieldtype": "Link",
- "label": "Gender",
- "options": "Gender",
- "insert_after": "date_of_birth"
- },
- {
- "fieldname": "willing_to_work_on_location",
- "fieldtype": "Check",
- "label": "Willing to Work in the Selected Location?",
- "insert_after": "country"
- },
- {
- "fieldname": "father_name",
- "fieldtype": "Data",
- "label": "Father's Name",
- "insert_after": "job_title"
- },
- {
- "fieldname": "marital_status",
- "fieldtype": "Select",
- "label": "Marital Status",
- "options": "\nSingle\nMarried\nDivorced\nWidowed",
- "insert_after": "location"
- },
- {
- "fieldname": "current_address_session_break",
- "fieldtype": "Section Break",
- "label": "Current Address",
- "insert_after": "marital_status"
- },
- {
- "fieldname": "current_address",
- "fieldtype": "Small Text",
- "label": "Current Address",
- "insert_after": "current_address_session_break"
- },
- {
- "fieldname": "current_mobile_no",
- "fieldtype": "Data",
- "options": "Phone",
- "label": "Mobile Number",
- "insert_after": "current_address"
- },
- {
- "fieldname": "current_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "current_mobile_no"
- },
- {
- "fieldname": "permanent_address_session_break",
- "fieldtype": "Section Break",
- "label": "Permanent Address",
- "insert_after": "current_column_break"
- },
- {
- "fieldname": "permanent_address",
- "fieldtype": "Small Text",
- "label": "Permanent Address",
- "insert_after": "permanent_address_session_break"
- },
- {
- "fieldname": "permanent_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "permanent_address"
- },
- {
- "fieldname": "email_address_session_break",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "permanent_column_break"
- },
- {
- "fieldname": "email_id_1",
- "fieldtype": "Data",
- "options": "Email",
- "label": "Email ID",
- "insert_after": "email_address_session_break"
- },
- {
- "fieldname": "min_education_qual",
- "fieldtype": "Link",
- "label": "Educational Qualification",
- 'options':"Educational Qualification",
- "insert_after": "details"
- },
- {
- "fieldname": "details",
- "fieldtype": "Section Break",
- "label": "Qualification Details",
- "insert_after": "applicant_rating"
- },
- {
- "fieldname": "department",
- "fieldtype": "Link",
- "label": "Department",
- "options": "Department",
- "insert_after": "designation"
- },
- {
- "fieldname": "min_experience",
- "fieldtype": "Float",
- "label": "Work Experience (Years)",
- "insert_after": "details_column_break",
- },
- {
- "fieldname": "details_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "min_education_qual"
- },
- {
- "fieldname": "reset_column",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "min_experience"
- },
-
- {
- "fieldname": "language_proficiency",
- "fieldtype": "Table",
- "options": "Language Proficiency",
- "label": "Language Proficiency",
- "insert_after": "min_experience"
- },
- {
- "fieldname": "skill_proficiency",
- "fieldtype": "Table",
- "options": "Skill Proficiency",
- "label": "Skill Proficiency",
- "insert_after": "language_proficiency"
- },
- {
- "fieldname": "education_qualification",
- "fieldtype": "Table",
- "options": "Education Qualification",
- "label": "Education Qualification",
- "insert_after": "applicant_interview_rounds"
- },
- {
- "fieldname": "professional_certification",
- "fieldtype": "Table",
- "options": "Professional Certification",
- "label": "Professional Certification",
- "insert_after": "education_qualification"
- },
- {
- "fieldname": "location",
- "label": "Location",
- "fieldtype": "Link",
- "options": "Location",
- "insert_after": "status"
- },
- {
- "fieldname": "interview_process_break",
- "fieldtype": "Section Break",
- "label": "Interview Process",
- "insert_after": "skill_proficiency"
- },
- {
- "fieldname": "applicant_interview_rounds",
- "fieldtype": "Table",
- "options": "Applicant Interview Round",
- "label": "Interview Rounds",
- "insert_after": "interview_process_break"
- },
- {
- "fieldname": "current_employer_tab_break",
- "fieldtype": "Tab Break",
- "label": "Current Employer Details",
- "insert_after": "upper_range"
- },
- {
- "fieldname": "current_employer",
- "fieldtype": "Section Break",
- "label": "Current Employer / Immediate Previous Employer",
- "insert_after": "current_employer_tab_break"
- },
- {
- "fieldname": "name_of_employer",
- "fieldtype": "Data",
- "label": "Name of Employer",
- "insert_after": "current_employer"
- },
- {
- "fieldname": "employment_period_from",
- "fieldtype": "Int",
- "label": "Employment Period From",
- "insert_after": "name_of_employer"
- },
- {
- "fieldname": "employment_period_to",
- "fieldtype": "Int",
- "label": "Employment Period To",
- "insert_after": "employment_period_from"
- },
- {
- "fieldname": "current_employer_1_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "employment_period_to"
- },
- {
- "fieldname": "current_designation",
- "fieldtype": "Data",
- "label": "Designation",
- "insert_after": "current_employer_1_column_break"
- },
- {
- "fieldname": "reference_taken",
- "fieldtype": "Select",
- "label": "Can I take Reference Now?",
- "options": "\nYes\nNo",
- "insert_after": "current_designation"
- },
- {
- "fieldname": "was_this_position",
- "fieldtype": "Select",
- "label": "Was this Position Permanent,Temporary,Contractual?",
- "options": "\nPermanent\nTemporary\nContractual",
- "insert_after": "reference_taken"
- },
- {
- "fieldname": "duties_and_reponsibilities",
- "fieldtype": "Small Text",
- "label": "Duties and Responsibilities",
- "insert_after": "column_break_agency"
- },
- {
- "fieldname": "current_employer_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "was_this_position"
- },
- {
- "fieldname": "current_department",
- "fieldtype": "Data",
- "label": "Department",
- "insert_after": "current_employer_column_break"
- },
- {
- "fieldname": "manager_name",
- "fieldtype": "Data",
- "label": "Manager's Name",
- "insert_after": "current_department"
- },
- {
- "fieldname": "manager_contact_no",
- "fieldtype": "Data",
- "options": "Phone",
- "label": "Manager's Contact No",
- "insert_after": "manager_name"
- },
- {
- "fieldname": "manager_email",
- "fieldtype": "Data",
- "options": "Email",
- "label": "Manager's Email",
- "insert_after": "manager_contact_no"
- },
- {
- "fieldname": "reason_for_leaving",
- "fieldtype": "Small Text",
- "label": "Reason For Leaving",
- "insert_after": "duties_and_reponsibilities"
- },
- {
- "fieldname": "agency_details",
- "fieldtype": "Small Text",
- "label": "Agency Details (if Temporary or Contractual)",
- "insert_after": "address_of_employer"
- },
- {
- "fieldname": "column_break_agency",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "agency_details"
- },
- {
- "fieldname": "previous_emp",
- "fieldtype": "Section Break",
- "insert_after": "manager_email"
- },
- {
- "fieldname": "address_of_employer",
- "fieldtype": "Small Text",
- "label": "Address of Employer",
- "insert_after": "previous_emp"
- },
- {
- "fieldname": "previous_emplyoment",
- "fieldtype": "Section Break",
- "label": "Previous Employment History",
- "insert_after": "previous_emp"
- },
- {
- "fieldname": "prev_emp_his",
- "fieldtype": "Table",
- "options": "Previous Employment History",
- "insert_after": "previous_emplyoment"
- },
- {
- "fieldname": "more_details_tab_break",
- "fieldtype": "Tab Break",
- "label": "More Details",
- "insert_after": "prev_emp_his"
- },
- {
- "fieldname": "current_salary",
- "fieldtype": "Currency",
- "label": "Current Salary",
- "insert_after": "more_details_tab_break"
- },
- {
- "fieldname": "current_salary_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "current_salary"
- },
- {
- "fieldname": "expected_salary",
- "fieldtype": "Currency",
- "label": "Expected Salary",
- "insert_after": "current_salary_column_break"
- },
- {
- "fieldname": "expected_salary_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "expected_salary"
- },
- {
- "fieldname": "telephone_number",
- "fieldtype": "Data",
- "options": "Phone",
- "label": "Telephone Number",
- "insert_after": "expected_salary_column_break"
- },
- {
- "fieldname": "other_achievments_session_break",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "current_employer_tab_break"
- },
- {
- "fieldname": "other_achievments",
- "fieldtype": "Small Text",
- "label": "Please add details of Professional and other achievements,awards and accomplishments,if any",
- "insert_after": "other_achievments_session_break"
- },
- {
- "fieldname": "interviewed_session_break",
- "fieldtype": "Section Break",
- "label": "Have you been interviewed before by Madhyamam Group?If yes, Please give details below :",
- "insert_after": "other_achievments"
- },
- {
- "fieldname": "position",
- "fieldtype": "Data",
- "label": "Position",
- "insert_after": "interviewed_session_break"
- },
- {
- "fieldname": "interviewed_date",
- "fieldtype": "Date",
- "label": "Date",
- "insert_after": "position"
- },
- {
- "fieldname": "interviewed_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "interviewed_date"
- },
- {
- "fieldname": "interviewed_location",
- "fieldtype": "Link",
- "options": "Location",
- "label": "Location",
- "insert_after": "interviewed_column_break"
- },
- {
- "fieldname": "interviewed_outcome",
- "fieldtype": "Data",
- "label": "Outcome",
- "insert_after": "interviewed_location"
- },
- {
- "fieldname": "travel_session_break",
- "fieldtype": "Section Break",
- "label": "Are you willing to travel :",
- "insert_after": "interviewed_outcome"
- },
- {
- "fieldname": "in_india",
- "fieldtype": "Check",
- "label": "In India",
- "insert_after": "travel_session_break"
- },
- {
- "fieldname": "state_restriction",
- "fieldtype": "Data",
- "label": "State Restriction If any",
- "depends_on": "eval:doc.in_india",
- "insert_after": "in_india"
- },
- {
- "fieldname": "india_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "state_restriction"
- },
- {
- "fieldname": "abroad",
- "fieldtype": "Check",
- "label": "Abroad",
- "insert_after": "india_column_break"
- },
- {
- "fieldname": "related_session_break",
- "fieldtype": "Section Break",
- "label": "Are you related to any of employee of the Madhyamam Group? If yes,please give details :",
- "insert_after": "state_restriction"
- },
- {
- "fieldname": "related_employee",
- "fieldtype": "Data",
- "label": "Name",
- "insert_after": "related_session_break"
- },
- {
- "fieldname": "related_employee_org",
- "fieldtype": "Data",
- "label": "Organization",
- "insert_after": "related_employee"
- },
- {
- "fieldname": "related_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "related_employee_org"
- },
- {
- "fieldname": "related_employee_pos",
- "fieldtype": "Data",
- "label": "Position",
- "insert_after": "related_column_break",
- },
- {
- "fieldname": "related_employee_rel",
- "fieldtype": "Data",
- "label": "Relationship",
- "insert_after": "related_employee_pos"
- },
- {
- "fieldname": "prof_session_break",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "related_employee_rel"
- },
- {
- "fieldname": "professional_org",
- "fieldtype": "Small Text",
- "label": "Are you a member of any Professional Organization? If yes, Please give details :",
- "insert_after": "prof_session_break"
- },
- {
- "fieldname": "political_org",
- "fieldtype": "Small Text",
- "label": "Are you a member of any Political Organization? If yes, Please give details :",
- "insert_after": "professional_org"
- },
- {
- "fieldname": "specialised_training",
- "fieldtype": "Small Text",
- "label": "Have you attended any specialised training program?If yes, Please give detais :",
- "insert_after": "political_org"
- },
- {
- "fieldname": "is_form_submitted",
- "fieldtype": "Check",
- "label": "Is Form Submitted",
- "read_only":1,
- "insert_after": "specialised_training"
- },
- {
- "fieldname": "payslip_month_1",
- "fieldtype": "Attach",
- "label": "Payslip - Month 1",
- "insert_after": "section_break_001"
- },
- {
- "fieldname": "break_oo1",
- "fieldtype": "Column Break",
- "insert_after": "payslip_month_1"
- },
- {
- "fieldname": "payslip_month_2",
- "fieldtype": "Attach",
- "label": "Payslip - Month 2",
- "insert_after": "break_oo1"
- },
- {
- "fieldname": "section_break_001",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "prev_emp_his"
- },
- {
- "fieldname": "break_oo2",
- "fieldtype": "Column Break",
- "insert_after": "payslip_month_2"
- },
- {
- "fieldname": "payslip_month_3",
- "fieldtype": "Attach",
- "label": "Payslip - Month 3",
- "insert_after": "break_oo2"
- }
- ]
- }
-def get_contract_custom_fields():
- '''
- Custom fields that need to be added to the Contract Doctype
- '''
- return {
- "Contract": [
- {
- "fieldname": "services_section",
- "fieldtype": "Section Break",
- "label": "Services",
- "insert_after": "ip_address"
- },
- {
- "fieldname": "services",
- "fieldtype": "Table",
- "options": "Services",
- "label": "Services",
- "insert_after": "services_section",
- "depends_on": "eval:doc.party_type == 'Supplier'"
- },
- {
- "fieldname": "total_amount",
- "fieldtype": "Currency",
- "label": "Total Amount",
- "insert_after": "services",
- "read_only":1,
- "no_copy":1
- }
- ]
- }
+def get_asset_custom_fields():
+ """
+ Custom fields that need to be added to the Asset DocType
+ """
+ return {
+ "Asset": [
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "options": "Bureau",
+ "label": "Bureau",
+ "insert_after": "location",
+ },
+ {
+ "fieldname": "in_transit",
+ "fieldtype": "Check",
+ "label": "In Transit",
+ "insert_after": "is_composite_asset",
+ "allow_on_submit": 1,
+ "read_only": 1,
+ },
+ {
+ "fieldname": "warranty_details_section",
+ "fieldtype": "Section Break",
+ "label": "Warranty Details Section",
+ "insert_after": "comprehensive_insurance",
+ "collapsible": 1,
+ },
+ {
+ "fieldname": "warranty_reference_no",
+ "fieldtype": "Data",
+ "label": "Warranty Reference No",
+ "insert_after": "warranty_details_section",
+ },
+ {
+ "fieldname": "warranty_till",
+ "fieldtype": "Date",
+ "label": "Warranty Till",
+ "insert_after": "warranty_reference_no",
+ },
+ {
+ "fieldname": "qr_code",
+ "fieldtype": "Attach Image",
+ "label": "QR code",
+ "insert_after": "department",
+ },
+ {
+ "fieldname": "asset_details",
+ "fieldtype": "Attach Image",
+ "label": "Asset Details",
+ "insert_after": "qr_code",
+ },
+ {
+ "fieldname": "room",
+ "fieldtype": "Link",
+ "label": "Room",
+ "options": "Service Unit",
+ "allow_on_submit": 1,
+ "insert_after": "journal_entry_for_scrap",
+ },
+ {
+ "fieldname": "shelf",
+ "fieldtype": "Link",
+ "label": "Shelf",
+ "options": "Shelf",
+ "allow_on_submit": 1,
+ "insert_after": "room",
+ },
+ {
+ "fieldname": "row",
+ "fieldtype": "Link",
+ "label": "Row",
+ "options": "Row",
+ "allow_on_submit": 1,
+ "insert_after": "shelf",
+ },
+ {
+ "fieldname": "bin",
+ "fieldtype": "Link",
+ "label": "Bin",
+ "options": "Container",
+ "allow_on_submit": 1,
+ "insert_after": "row",
+ },
+ ]
+ }
-def get_job_opening_custom_fields():
- '''
- Custom fields that need to be added to the Job Opening Doctype
- '''
- return {
- "Job Opening": [
- {
- "fieldname": "job_details",
- "fieldtype": "Section Break",
- "label": "Job Details",
- "insert_after": "location"
- },
- {
- "fieldname": "no_of_positions",
- "fieldtype": "Int",
- "label": "No of.Positions",
- "insert_after": "employment_type",
- },
- {
- "fieldname": "no_of_days_off",
- "fieldtype": "Int",
- "label": "Number of Days Off",
- "insert_after": "job_details",
- "non_negative": 1
- },
- {
- "fieldname": "preffered_location",
- "label": "Preffered Location",
- "fieldtype": "Link",
- "options": "Location",
- "insert_after": "no_of_days_off"
- },
- {
- "fieldname": "job_details_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "preffered_location"
- },
- {
- "fieldname": "travel_required",
- "fieldtype": "Check",
- "label": "Travel required for the position",
- "insert_after": "job_details_column_break"
- },
- {
- "fieldname": "driving_license_needed",
- "fieldtype": "Check",
- "label": "Driving License Needed for this Position",
- "depends_on": "eval:doc.travel_required == 1",
- "insert_after": "travel_required"
- },
- {
- "fieldname": "license_type",
- "fieldtype": "Link",
- "label": "License Type",
- "options": "License Type",
- "depends_on": "eval:doc.driving_license_needed == 1",
- "insert_after": "driving_license_needed"
- },
- {
- "fieldname": "is_work_shift_needed",
- "fieldtype": "Check",
- "label": "Is Shift Work Needed",
- "insert_after": "license_type"
- },
- {
- "fieldname": "qualification_details",
- "fieldtype": "Section Break",
- "label": "Education and Qualification Details",
- "insert_after": "license_type",
- },
- {
- "fieldname": "min_education_qual",
- "fieldtype": "Table MultiSelect",
- "label": "Preferred Educational Qualification",
- 'options':"Educational Qualifications",
- "insert_after": "qualification_details"
- },
- {
- "fieldname": "qualification_details_column_break",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "min_education_qual"
- },
- {
- "fieldname": "min_experience",
- "fieldtype": "Float",
- "label": "Minimum Experience Required (Years)",
- "insert_after": "is_work_shift_needed"
- },
- {
- "fieldname": "proficiency_break",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "min_experience"
- },
- {
- "fieldname": "language_proficiency",
- "fieldtype": "Table",
- "options": "Language Proficiency",
- "label": "Language Proficiency",
- "insert_after": "proficiency_break",
- "description": "Proficency selected here is the minimum proficency needed"
- },
- {
- "fieldname": "skill_proficiency",
- "fieldtype": "Table",
- "options": "Skill Proficiency",
- "label": "Skill Proficiency",
- "insert_after": "language_proficiency",
- "description": "Proficency selected here is the minimum proficency needed"
- },
- {
- "fieldname": "interview_details_sb",
- "fieldtype": "Section Break",
- "label": "Interview Details",
- "insert_after": "skill_proficiency"
- },
- {
- "fieldname": "interview_rounds",
- "fieldtype": "Table MultiSelect",
- "label": "Interview Rounds",
- 'options':"Interview Rounds",
- "insert_after": "interview_details_sb"
- }
- ]
- }
-def get_company_custom_fields():
- '''
- Custom fields that need to be added to the Company Doctype
- '''
- return {
- "Company": [
- {
- "fieldname": "company_policy_tab",
- "fieldtype": "Tab Break",
- "label": "Company Policy",
- "insert_after": "dashboard_tab"
- },
- {
- "fieldname": "company_policy",
- "fieldtype": "Text Editor",
- "label": "Company Policy",
- "insert_after": "company_policy_tab"
- },
- {
- "fieldname": "exception_budget_column",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "exception_budget_approver_role"
- },
- {
- "fieldname": "exchange_rate_to_inr",
- "fieldtype": "Float",
- "label": "Budget Exchange Rate to INR",
- "insert_after": "exception_budget_column",
- "description": "1 Unit of Company Currency = [?] INR"
- }
- ]
- }
+def get_job_offer_custom_fields():
+ """
+ Custom fields that need to be added to the Job Offer DocType
+ """
+ return {
+ "Job Offer": [
+ {
+ "fieldname": "job_proposal",
+ "fieldtype": "Link",
+ "label": "Job Proposal",
+ "options": "Job Proposal",
+ "insert_after": "applicant_email",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "ctc",
+ "fieldtype": "Currency",
+ "label": "CTC",
+ "insert_after": "job_proposal",
+ "fetch_from": "job_proposal.proposed_ctc",
+ },
+ ]
+ }
+
+
+def get_purchase_order_custom_fields():
+ """
+ Custom fields that need to be added to the Purchase Order DocType
+ """
+ return {
+ "Purchase Order": [
+ {
+ "fieldname": "is_budget_exceed",
+ "fieldtype": "Check",
+ "label": "Is Budget Exceed",
+ "insert_after": "items_section",
+ "read_only": 1,
+ "no_copy": 1,
+ "depends_on": "eval:doc.is_budget_exceed == 1",
+ },
+ {
+ "fieldname": "attach",
+ "fieldtype": "Attach",
+ "label": "Attachments",
+ "insert_after": "base_net_total",
+ },
+ ],
+ "Purchase Order Item": [
+ {
+ "fieldname": "reference_doctype",
+ "fieldtype": "Link",
+ "label": "Reference DocType",
+ "options": "DocType",
+ "insert_after": "blanket_order_rate",
+ },
+ {
+ "fieldname": "reference_document",
+ "fieldtype": "Dynamic Link",
+ "label": "Reference Document",
+ "options": "reference_doctype",
+ "insert_after": "reference_doctype",
+ },
+ ],
+ }
+
+
+def get_budget_custom_fields():
+ """
+ Custom fields that need to be added to the Budget DocType
+ """
+ return {
+ "Budget": [
+ {
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "label": "Department",
+ "options": "Department",
+ "reqd": 1,
+ "insert_after": "company",
+ },
+ {
+ "fieldname": "finance_group",
+ "fieldtype": "Link",
+ "label": "Finance Group",
+ "options": "Finance Group",
+ "insert_after": "department",
+ "read_only": 1,
+ "fetch_from": "department.finance_group",
+ },
+ {
+ "fieldname": "division",
+ "fieldtype": "Link",
+ "label": "Division",
+ "options": "Division",
+ "reqd": 1,
+ "insert_after": "department",
+ },
+ {
+ "fieldname": "region",
+ "fieldtype": "Link",
+ "label": "Region",
+ "options": "Region",
+ "insert_after": "budget_template",
+ },
+ {
+ "fieldname": "budget_template",
+ "fieldtype": "Link",
+ "label": "Budget Template",
+ "options": "Budget Template",
+ "insert_after": "fiscal_year",
+ },
+ {
+ "fieldname": "rejection_feedback",
+ "fieldtype": "Table",
+ "label": "Rejection Feedback",
+ "options": "Rejection Feedback",
+ "insert_after": "december",
+ "depends_on": "eval: doc.workflow_state.includes('Rejected')",
+ },
+ {
+ "fieldname": "total_amount",
+ "fieldtype": "Currency",
+ "label": "Total Amount",
+ "read_only": 1,
+ "insert_after": "region",
+ "options": "company_currency",
+ },
+ {
+ "fieldname": "budget_accounts_custom",
+ "fieldtype": "Table",
+ "label": "Budget Accounts",
+ "options": "Budget Account",
+ "insert_after": "accounts",
+ },
+ {
+ "fieldname": "budget_accounts_hr",
+ "fieldtype": "Table",
+ "label": "Budget Accounts(HR Overheads)",
+ "options": "Budget Account",
+ "insert_after": "budget_accounts_custom",
+ },
+ {
+ "fieldname": "default_currency",
+ "fieldtype": "Link",
+ "label": "Default Currency",
+ "options": "Currency",
+ "read_only": 1,
+ "hidden": 1,
+ "insert_after": "budget_accounts_hr",
+ "default": "INR",
+ },
+ {
+ "fieldname": "company_currency",
+ "fieldtype": "Link",
+ "label": "Company Currency",
+ "options": "Currency",
+ "read_only": 1,
+ "hidden": 1,
+ "insert_after": "default_currency",
+ "fetch_from": "company.default_currency",
+ },
+ ],
+ "Budget Account": [
+ {
+ "fieldname": "cost_head",
+ "fieldtype": "Link",
+ "label": "Cost Head",
+ "options": "Cost Head",
+ "insert_before": "cost_subhead",
+ "in_list_view": 1,
+ },
+ {
+ "fieldname": "cost_subhead",
+ "fieldtype": "Link",
+ "label": "Cost Sub Head",
+ "options": "Cost Subhead",
+ "insert_after": "cost_head",
+ "in_list_view": 1,
+ },
+ {
+ "fieldname": "cost_category",
+ "fieldtype": "Link",
+ "label": "Cost Category",
+ "options": "Cost Category",
+ "insert_after": "account",
+ "in_list_view": 1,
+ },
+ {
+ "fieldname": "column_break_cd",
+ "fieldtype": "Column Break",
+ "label": " ",
+ "insert_after": "cost_category",
+ },
+ {
+ "fieldname": "cost_description",
+ "fieldtype": "Small Text",
+ "label": "Cost Description",
+ "insert_after": "column_break_cd",
+ },
+ {
+ "fieldname": "equal_monthly_distribution",
+ "fieldtype": "Check",
+ "label": "Equal Monthly Distribution ",
+ "insert_after": "cost_description",
+ },
+ {
+ "fieldname": "section_break_ab",
+ "fieldtype": "Section Break",
+ "label": "Monthly Amount Distribution",
+ "insert_after": "budget_amount",
+ },
+ {
+ "fieldname": "january",
+ "fieldtype": "Currency",
+ "label": "January",
+ "insert_after": "section_break_ab",
+ },
+ {
+ "fieldname": "february",
+ "fieldtype": "Currency",
+ "label": "February",
+ "insert_after": "january",
+ },
+ {
+ "fieldname": "march",
+ "fieldtype": "Currency",
+ "label": "March",
+ "insert_after": "february",
+ },
+ {
+ "fieldname": "april",
+ "fieldtype": "Currency",
+ "label": "April",
+ "insert_after": "march",
+ },
+ {
+ "fieldname": "column_break_bc",
+ "fieldtype": "Column Break",
+ "label": " ",
+ "insert_after": "april",
+ },
+ {
+ "fieldname": "may",
+ "fieldtype": "Currency",
+ "label": "May",
+ "insert_after": "column_break_bc",
+ },
+ {
+ "fieldname": "june",
+ "fieldtype": "Currency",
+ "label": "June",
+ "insert_after": "may",
+ },
+ {
+ "fieldname": "july",
+ "fieldtype": "Currency",
+ "label": "July",
+ "insert_after": "june",
+ },
+ {
+ "fieldname": "august",
+ "fieldtype": "Currency",
+ "label": "August",
+ "insert_after": "july",
+ },
+ {
+ "fieldname": "column_break_ab",
+ "fieldtype": "Column Break",
+ "label": " ",
+ "insert_after": "august",
+ },
+ {
+ "fieldname": "september",
+ "fieldtype": "Currency",
+ "label": "September",
+ "insert_after": "column_break_ab",
+ },
+ {
+ "fieldname": "october",
+ "fieldtype": "Currency",
+ "label": "October",
+ "insert_after": "september",
+ },
+ {
+ "fieldname": "november",
+ "fieldtype": "Currency",
+ "label": "November",
+ "insert_after": "october",
+ },
+ {
+ "fieldname": "december",
+ "fieldtype": "Currency",
+ "label": "December",
+ "insert_after": "november",
+ },
+ {
+ "fieldname": "section_break_inr",
+ "fieldtype": "Section Break",
+ "label": "Monthly Amount Distribution (INR)",
+ "insert_after": "december",
+ "collapsible": 1,
+ "read_only": 1,
+ },
+ {
+ "fieldname": "january_inr",
+ "fieldtype": "Currency",
+ "label": "January (INR)",
+ "insert_after": "section_break_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "february_inr",
+ "fieldtype": "Currency",
+ "label": "February (INR)",
+ "insert_after": "january_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "march_inr",
+ "fieldtype": "Currency",
+ "label": "March (INR)",
+ "insert_after": "february_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "april_inr",
+ "fieldtype": "Currency",
+ "label": "April (INR)",
+ "insert_after": "march_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "column_break_zz1",
+ "fieldtype": "Column Break",
+ "label": " ",
+ "insert_after": "april_inr",
+ },
+ {
+ "fieldname": "may_inr",
+ "fieldtype": "Currency",
+ "label": "May (INR)",
+ "insert_after": "column_break_zz1",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "june_inr",
+ "fieldtype": "Currency",
+ "label": "June (INR)",
+ "insert_after": "may_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "july_inr",
+ "fieldtype": "Currency",
+ "label": "July (INR)",
+ "insert_after": "june_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "august_inr",
+ "fieldtype": "Currency",
+ "label": "August (INR)",
+ "insert_after": "july_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "column_break_zz2",
+ "fieldtype": "Column Break",
+ "label": " ",
+ "insert_after": "july_inr",
+ },
+ {
+ "fieldname": "september_inr",
+ "fieldtype": "Currency",
+ "label": "September (INR)",
+ "insert_after": "column_break_zz2",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "october_inr",
+ "fieldtype": "Currency",
+ "label": "October (INR)",
+ "insert_after": "september_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "november_inr",
+ "fieldtype": "Currency",
+ "label": "November (INR)",
+ "insert_after": "october_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "december_inr",
+ "fieldtype": "Currency",
+ "label": "December (INR)",
+ "insert_after": "november_inr",
+ "read_only": 1,
+ "options": "default_currency",
+ },
+ {
+ "fieldname": "budget_amount_inr",
+ "fieldtype": "Currency",
+ "label": "Budget Amount (INR)",
+ "insert_after": "budget_amount",
+ "options": "default_currency",
+ "read_only": 1,
+ },
+ ],
+ }
+
+
+def get_sales_invoice_custom_fields():
+ """
+ Custom fields that need to be added to the Sales Invoice Doctype
+ """
+ return {
+ "Sales Invoice": [
+ {
+ "fieldname": "actual_customer",
+ "fieldtype": "Link",
+ "label": "Actual Customer",
+ "options": "Customer",
+ "depends_on": "eval:doc.is_agent == 1",
+ "insert_after": "is_agent",
+ },
+ {
+ "fieldname": "is_agent",
+ "fieldtype": "Check",
+ "label": "Is Agency",
+ "read_only": 1,
+ "fetch_from": "customer.is_agent",
+ "depends_on": "eval:doc.is_agent",
+ "insert_after": "customer",
+ },
+ {
+ "fieldname": "actual_customer_group",
+ "fieldtype": "Link",
+ "label": "Actual Customer Group",
+ "options": "Customer Group",
+ "read_only": 1,
+ "fetch_from": "actual_customer.customer_group",
+ "insert_after": "actual_customer",
+ },
+ {
+ "fieldname": "include_in_ibf",
+ "fieldtype": "Check",
+ "label": "Include in IBF",
+ "read_only": 1,
+ "insert_after": "actual_customer_group",
+ },
+ {
+ "fieldname": "region",
+ "fieldtype": "Link",
+ "options": "Region",
+ "label": "Region",
+ "insert_after": "is_reverse_charge",
+ },
+ {
+ "fieldname": "executive",
+ "fieldtype": "Link",
+ "options": "Employee",
+ "label": "Executive",
+ "insert_after": "due_date",
+ },
+ {
+ "fieldname": "executive_name",
+ "fieldtype": "Data",
+ "label": "Executive Name",
+ "insert_after": "executive",
+ "fetch_from": "executive.employee_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "is_barter_invoice",
+ "fieldtype": "Check",
+ "label": "Is Barter Invoice",
+ "read_only": 1,
+ "insert_after": "include_in_ibf",
+ "fetch_from": "reference_id.is_barter",
+ },
+ {
+ "fieldname": "reference_id",
+ "fieldtype": "Link",
+ "options": "Quotation",
+ "label": "Quotation",
+ "read_only": 1,
+ "insert_after": "naming_series",
+ },
+ {
+ "fieldname": "sales_type",
+ "fieldtype": "Link",
+ "label": "Sales Type",
+ "insert_after": "naming_series",
+ "options": "Sales Type",
+ },
+ ]
+ }
+
+
+def get_quotation_custom_fields():
+ """
+ Custom fields that need to be added to the Quotation DocType
+ """
+ return {
+ "Quotation": [
+ {
+ "fieldname": "is_agent",
+ "fieldtype": "Check",
+ "label": "Is Agency",
+ "read_only": 1,
+ "fetch_from": "party_name.is_agent",
+ "depends_on": "eval:doc.is_agent",
+ "insert_after": "party_name",
+ },
+ {
+ "fieldname": "actual_customer",
+ "fieldtype": "Link",
+ "label": "Actual Customer",
+ "options": "Customer",
+ "depends_on": "eval:doc.is_agent == 1",
+ "insert_after": "is_agent",
+ },
+ {
+ "fieldname": "actual_customer_group",
+ "fieldtype": "Link",
+ "label": "Actual Customer Group",
+ "options": "Customer Group",
+ "read_only": 1,
+ "fetch_from": "actual_customer.customer_group",
+ "insert_after": "actual_customer",
+ },
+ {
+ "fieldname": "customer_purchase_order_reference",
+ "fieldtype": "Data",
+ "label": "Customer Purchase Order Reference",
+ "insert_after": "valid_till",
+ },
+ {
+ "fieldname": "executive",
+ "fieldtype": "Link",
+ "label": "Executive",
+ "options": "Employee",
+ "insert_after": "customer_purchase_order_reference",
+ },
+ {
+ "fieldname": "executive_name",
+ "fieldtype": "Data",
+ "label": "Executive Name",
+ "insert_after": "executive",
+ "fetch_from": "executive.employee_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "is_barter",
+ "fieldtype": "Check",
+ "label": "Is Barter",
+ "insert_after": "amended_from",
+ },
+ {
+ "fieldname": "purchase_order",
+ "fieldtype": "Link",
+ "label": "Purchase Order",
+ "insert_after": "is_barter",
+ "depends_on": "eval:doc.is_barter",
+ "options": "Purchase Order",
+ },
+ {
+ "fieldname": "sales_type",
+ "fieldtype": "Link",
+ "label": "Default Sales Type",
+ "insert_after": "purchase_order",
+ "options": "Sales Type",
+ },
+ {
+ "fieldname": "region",
+ "fieldtype": "Link",
+ "label": "Region",
+ "insert_after": "customer_name",
+ "options": "Region",
+ },
+ {
+ "fieldname": "albatross_details_section",
+ "fieldtype": "Section Break",
+ "label": "Albatross Details",
+ "insert_after": "is_barter",
+ },
+ {
+ "fieldname": "albatross_ro_id",
+ "fieldtype": "Data",
+ "label": "Albatross RO ID",
+ "insert_after": "albatross_details_section",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "ro_no",
+ "fieldtype": "Data",
+ "label": "RO No",
+ "insert_after": "albatross_ro_id",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "ro_date",
+ "fieldtype": "Date",
+ "label": "RO Date",
+ "insert_after": "ro_no",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "ro_option",
+ "fieldtype": "Data",
+ "label": "RO Option",
+ "insert_after": "ro_date",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "region_revenue_percentage",
+ "fieldtype": "Percent",
+ "label": "Region Revenue Percentage",
+ "insert_after": "ro_option",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "albatross_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "region_revenue_percentage",
+ },
+ {
+ "fieldname": "product_name",
+ "fieldtype": "Data",
+ "label": "Product Name",
+ "insert_after": "albatross_column_break",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "program_name",
+ "fieldtype": "Data",
+ "label": "Program Name",
+ "insert_after": "product_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "no_of_eps",
+ "fieldtype": "Data",
+ "label": "No of Episodes",
+ "insert_after": "program_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "commission_per",
+ "fieldtype": "Float",
+ "label": "Commission Per",
+ "insert_after": "no_of_eps",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "fct_total",
+ "fieldtype": "Float",
+ "label": "FCT Total",
+ "insert_after": "commission_per",
+ "read_only": 1,
+ },
+ ],
+ "Quotation Item": [
+ {
+ "fieldname": "sales_type",
+ "fieldtype": "Link",
+ "label": "Sales Type",
+ "options": "Sales Type",
+ "insert_after": "item_name",
+ }
+ ],
+ }
+
+
+def get_purchase_invoice_custom_fields():
+ """
+ Custom fields that need to be added to the Purchase Invoice Doctype
+ """
+ return {
+ "Purchase Invoice": [
+ {
+ "fieldname": "barter_invoice",
+ "fieldtype": "Check",
+ "label": "Barter Invoice",
+ "read_only": 1,
+ "fetch_from": "quotation.is_barter",
+ "insert_after": "supplier",
+ },
+ {
+ "fieldname": "quotation",
+ "fieldtype": "Link",
+ "label": "Quotation",
+ "read_only": 1,
+ "options": "Quotation",
+ "insert_after": "barter_invoice",
+ },
+ {
+ "fieldname": "invoice_type",
+ "fieldtype": "Select",
+ "options": "Normal\nStringer Bill",
+ "default": "Normal",
+ "label": "Invoice Type",
+ "insert_after": "naming_series",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "purchase_order_id",
+ "fieldtype": "Link",
+ "label": "Purchase Order",
+ "options": "Purchase Order",
+ "insert_after": "naming_series",
+ },
+ {
+ "fieldname": "stringer_bill_reference",
+ "fieldtype": "Link",
+ "label": "Stringer Bill Reference",
+ "options": "Stringer Bill",
+ "depends_on": "eval:doc.invoice_type == 'Stringer Bill' ",
+ "read_only": 1,
+ "insert_after": "purchase_order_id",
+ },
+ {
+ "fieldname": "batta_claim_reference",
+ "fieldtype": "Link",
+ "label": "Batta Claim Reference",
+ "read_only": 1,
+ "options": "Batta Claim",
+ "insert_after": "stringer_bill_reference",
+ },
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "label": "Bureau",
+ "read_only": 1,
+ "options": "Bureau",
+ "insert_after": "supplier",
+ },
+ {
+ "fieldname": "attach",
+ "fieldtype": "Attach",
+ "label": "Attachments",
+ "insert_after": "base_net_total",
+ },
+ ]
+ }
+
+
+def get_supplier_custom_fields():
+ """
+ Custom fields that need to be added to the Supplier Doctype
+ """
+ return {
+ "Supplier": [
+ {
+ "fieldname": "is_stringer",
+ "fieldtype": "Check",
+ "label": "Is Stringer",
+ "insert_after": "supplier_name",
+ },
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "label": "Bureau",
+ "options": "Bureau",
+ "depends_on": "eval:doc.is_stringer == 1",
+ "insert_after": "is_stringer",
+ },
+ {
+ "fieldname": "area",
+ "fieldtype": "Data",
+ "label": "Area",
+ "depends_on": "eval:doc.is_stringer == 1",
+ "insert_after": "bureau",
+ },
+ {
+ "fieldname": "designation",
+ "fieldtype": "Link",
+ "label": "Designation",
+ "options": "Designation",
+ "insert_after": "country",
+ },
+ {
+ "fieldname": "ot_batta",
+ "fieldtype": "Currency",
+ "label": "OT Batta",
+ "depends_on": "eval:doc.is_transporter == 1",
+ "insert_after": "is_transporter",
+ },
+ ]
+ }
+
+
+def get_item_group_custom_fields():
+ """
+ Custom fields that need to be added to the Quotation Item Doctype
+ """
+ return {
+ "Item Group": [
+ {
+ "fieldname": "hireable",
+ "fieldtype": "Check",
+ "label": "Hireable",
+ "fetch_from": "parent_item_group.hireable",
+ "set_only_once": 1,
+ "fetch_if_empty": 1,
+ "insert_after": "gst_hsn_code",
+ }
+ ]
+ }
+
+
+def get_item_custom_fields():
+ """
+ Custom fields that need to be added to the Quotation Item Doctype
+ """
+ return {
+ "Item": [
+ {
+ "fieldname": "is_production_item",
+ "fieldtype": "Check",
+ "label": "Is Production Item",
+ "insert_after": "stock_uom",
+ },
+ {
+ "fieldname": "sales_type",
+ "fieldtype": "Link",
+ "label": "Sales Type",
+ "options": "Sales Type",
+ "insert_after": "is_production_item",
+ },
+ {
+ "fieldname": "hireable",
+ "fieldtype": "Check",
+ "label": "Hireable",
+ "fetch_from": "item_group.hireable",
+ "set_only_once": 1,
+ "insert_after": "gst_hsn_code",
+ },
+ {
+ "fieldname": "service_item",
+ "fieldtype": "Link",
+ "label": "Service Item",
+ "options": "Item",
+ "read_only": 1,
+ "insert_after": "item_group",
+ },
+ {
+ "fieldname": "item_audit_notification",
+ "fieldtype": "Check",
+ "label": "Periodic Notification for Asset Auditing ",
+ "depends_on": "eval:doc.is_fixed_asset == 1",
+ "insert_after": "asset_category",
+ },
+ {
+ "fieldname": "item_notification_frequency",
+ "fieldtype": "Select",
+ "label": "Notification Frequency",
+ "options": "\nMonthly\nTrimonthly\nQuarterly\nHalf Yearly\nYearly",
+ "depends_on": "eval:doc.item_audit_notification == 1",
+ "insert_after": "item_audit_notification",
+ },
+ {
+ "fieldname": "item_notification_template",
+ "fieldtype": "Link",
+ "label": "Notification Template",
+ "options": "Email Template",
+ "depends_on": "eval:doc.item_audit_notification == 1",
+ "insert_after": "item_notification_frequency",
+ },
+ {
+ "fieldname": "start_notification_from",
+ "fieldtype": "Select",
+ "label": "Start Notification From",
+ "options": "\nJanuary\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember",
+ "depends_on": "eval:doc.item_audit_notification == 1",
+ "insert_after": "item_audit_notification",
+ },
+ {
+ "fieldname": "is_makeup_item",
+ "fieldtype": "Check",
+ "label": "Is Makeup Item",
+ "insert_after": "is_exempt",
+ },
+ ]
+ }
+
+
+def get_employee_custom_fields():
+ """
+ Custom fields that need to be added to the Employee Doctype
+ """
+ return {
+ "Employee": [
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "options": "Bureau",
+ "label": "Bureau",
+ "insert_after": "last_name",
+ },
+ {
+ "fieldname": "stringer_type",
+ "fieldtype": "Link",
+ "options": "Stringer Type",
+ "label": "Stringer Type",
+ "insert_after": "Bureau",
+ },
+ {
+ "fieldname": "leave_policy",
+ "fieldtype": "Link",
+ "options": "Leave Policy",
+ "label": "Leave Policy",
+ "insert_after": "attendance_device_id",
+ },
+ {
+ "fieldname": "leave_policy_name",
+ "fieldtype": "Data",
+ "label": "Title",
+ "fetch_from": "leave_policy.title",
+ "insert_after": "leave_policy",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "name_of_father",
+ "fieldtype": "Data",
+ "label": "Father's Name",
+ "insert_after": "date_of_birth",
+ },
+ {
+ "fieldname": "name_of_spouse",
+ "fieldtype": "Data",
+ "label": "Spouse's Name",
+ "insert_after": "name_of_father",
+ },
+ {
+ "fieldname": "pincode",
+ "fieldtype": "Data",
+ "label": "Pincode",
+ "insert_after": "address_section",
+ },
+ {
+ "fieldname": "aadhar_id",
+ "fieldtype": "Data",
+ "label": "Aadhar Id",
+ "insert_after": "marital_status",
+ },
+ {
+ "fieldname": "date_of_appointment",
+ "fieldtype": "Date",
+ "label": "Date of Appointment",
+ "insert_after": "date_of_joining",
+ },
+ {
+ "fieldname": "nominee_details_section",
+ "fieldtype": "Section Break",
+ "label": "Nominee Details",
+ "insert_after": "iban",
+ },
+ {
+ "fieldname": "nominee_details",
+ "fieldtype": "Table",
+ "label": "Nominee Details",
+ "options": "Nominee Details",
+ "insert_after": "nominee_details_section",
+ },
+ {
+ "fieldname": "additional_information_section",
+ "fieldtype": "Section Break",
+ "label": _("Additional Information"),
+ "insert_after": "place_of_issue",
+ "collapsible": 1,
+ },
+ {
+ "fieldname": "physical_disabilities",
+ "fieldtype": "Select",
+ "label": "Do you have a physical disability",
+ "options": "Yes\nNo",
+ "default": "No",
+ "insert_after": "additional_information_section",
+ },
+ {
+ "fieldname": "disabilities",
+ "fieldtype": "Data",
+ "label": "Please specify the disability",
+ "insert_after": "physical_disabilities",
+ "depends_on": "eval:doc.physical_disabilities == 'Yes'",
+ },
+ {
+ "fieldname": "marital_indebtness",
+ "fieldtype": "Select",
+ "options": "Yes\nNo",
+ "default": "No",
+ "label": "Do you have marital indebtedness",
+ "insert_after": "disabilities",
+ },
+ {
+ "fieldname": "training_status",
+ "fieldtype": "Select",
+ "options": "Not Started\nIn Progress\nCompleted\nNot Completed\nPartially Completed",
+ "label": "Training Status",
+ "insert_after": "status",
+ },
+ {
+ "fieldname": "court_proceedings",
+ "fieldtype": "Select",
+ "options": "Yes\nNo",
+ "default": "No",
+ "label": "Are there any ongoing court proceedings",
+ "insert_after": "marital_indebtness",
+ },
+ {
+ "fieldname": "court_proceedings_details",
+ "fieldtype": "Small Text",
+ "label": "Court Proceedings Details",
+ "insert_after": "court_proceedings",
+ "depends_on": "eval:doc.court_proceedings == 'Yes'",
+ },
+ {
+ "fieldname": "column_break_travel",
+ "fieldtype": "Column Break",
+ "insert_after": "court_proceedings_details",
+ },
+ {
+ "fieldname": "are_you_willing_to_travel",
+ "label": "Are you willing to travel",
+ "fieldtype": "Check",
+ "insert_after": "column_break_travel",
+ },
+ {
+ "fieldname": "in_india",
+ "label": "In India",
+ "fieldtype": "Select",
+ "options": "Yes\nNo",
+ "default": "No",
+ "insert_after": "are_you_willing_to_travel",
+ "depends_on": "eval:doc.are_you_willing_to_travel == 1",
+ },
+ {
+ "fieldname": "abroad",
+ "label": "Abroad",
+ "fieldtype": "Select",
+ "options": "Yes\nNo",
+ "default": "No",
+ "insert_after": "in_india",
+ "depends_on": "eval:doc.are_you_willing_to_travel == 1",
+ },
+ {
+ "fieldname": "state_restrictions_problems",
+ "label": "State Restrictions/Problems if any",
+ "fieldtype": "Data",
+ "insert_after": "abroad",
+ "depends_on": "eval:doc.are_you_willing_to_travel == 1",
+ },
+ {
+ "fieldname": "places_to_travel",
+ "label": "Places/Countries of your choice where you'd like to travel on job",
+ "fieldtype": "Data",
+ "insert_after": "state_restrictions_problems",
+ },
+ {
+ "fieldname": "are_you_related_to_employee",
+ "label": "Are you related to any of our employees",
+ "fieldtype": "Check",
+ "insert_after": "places_to_travel",
+ },
+ {
+ "fieldname": "related_employee_name",
+ "label": "Related Employee Name",
+ "fieldtype": "Data",
+ "insert_after": "are_you_related_to_employee",
+ "depends_on": "eval:doc.are_you_related_to_employee == 1",
+ },
+ {
+ "fieldname": "documents_tab",
+ "fieldtype": "Tab Break",
+ "label": "Documents",
+ "insert_after": "internal_work_history",
+ },
+ {
+ "fieldname": "employee_documents",
+ "fieldtype": "Table",
+ "label": "Employee Documents",
+ "options": "Employee Documents",
+ "insert_after": "documents_tab",
+ },
+ {
+ "fieldname": "no_of_children",
+ "fieldtype": "Int",
+ "label": "No.of Children",
+ "insert_after": "marital_status",
+ },
+ {
+ "fieldname": "company_number",
+ "fieldtype": "Data",
+ "label": "Company Mobile Number",
+ "options": "Phone",
+ "insert_after": "cell_number",
+ },
+ {
+ "fieldname": "landmark",
+ "fieldtype": "Data",
+ "label": "Landmark",
+ "insert_after": "current_address",
+ },
+ {
+ "fieldname": "landmark_per",
+ "fieldtype": "Data",
+ "label": "Landmark",
+ "insert_after": "permanent_address",
+ },
+ {
+ "fieldname": "emergency_contact_name",
+ "fieldtype": "Data",
+ "label": "Emergency Contact Name",
+ "insert_after": "person_to_be_contacted",
+ },
+ {
+ "fieldname": "emergency_phone",
+ "fieldtype": "Data",
+ "label": "Emergency Phone",
+ "insert_after": "emergency_phone_number",
+ },
+ {
+ "fieldname": "relation_emergency",
+ "fieldtype": "Data",
+ "label": "Relation",
+ "insert_after": "relation",
+ },
+ {
+ "fieldname": "assessment_officer",
+ "fieldtype": "Link",
+ "options": "Employee",
+ "label": "Assessment Officer",
+ "insert_after": "reports_to",
+ },
+ ],
+ "Employee External Work History": [
+ {
+ "fieldname": "period_from",
+ "fieldtype": "Date",
+ "label": "Period From",
+ "insert_after": "designation",
+ },
+ {
+ "fieldname": "period_to",
+ "fieldtype": "Date",
+ "label": "Period To",
+ "insert_after": "period_from",
+ },
+ {
+ "fieldname": "last_position_held",
+ "fieldtype": "Data",
+ "label": "Last Position Held",
+ "insert_after": "period_to",
+ },
+ {
+ "fieldname": "job_responsibility",
+ "fieldtype": "Small Text",
+ "label": "Job Responsibility",
+ "insert_after": "last_position_held",
+ },
+ {
+ "fieldname": "designation_of_immediate_superior",
+ "fieldtype": "Data",
+ "label": "Designation Of Immediate Superior",
+ "insert_after": "job_responsibility",
+ },
+ {
+ "fieldname": "gross_salary_drawn",
+ "fieldtype": "Float",
+ "label": "Gross Salary Drawn ",
+ "insert_after": "designation_of_immediate_superior",
+ },
+ {
+ "fieldname": "reason_for_leaving",
+ "fieldtype": "Small Text",
+ "label": "Reason For Leaving",
+ "insert_after": "gross_salary_drown",
+ },
+ ],
+ }
+
+
+def get_voucher_entry_custom_fields():
+ """
+ Custom fields that need to be added to the Employee Doctype
+ """
+ return {
+ "Voucher Entry": [
+ {
+ "fieldname": "bureau",
+ "fieldtype": "Link",
+ "options": "Bureau",
+ "label": "Bureau",
+ "insert_after": "balance",
+ },
+ {
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "options": "Department",
+ "label": "Department",
+ "insert_after": "company",
+ },
+ ]
+ }
+
+
+def get_expected_skill_set_custom_fields():
+ """
+ Custom fields that need to be added to the Expected Skill Set Doctype
+ """
+ return {
+ "Expected Skill Set": [
+ {
+ "fieldname": "weight",
+ "fieldtype": "Float",
+ "label": "Weight",
+ "insert_after": "description",
+ }
+ ]
+ }
+
+
+def get_hd_ticket_custom_fields():
+ """
+ Custom fields to be added to the HD Ticket Doctype
+ """
+ return {
+ "HD Ticket": [
+ {
+ "fieldname": "ticket_section_break",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "ticket_split_from",
+ },
+ {
+ "fieldname": "spare_part_needed",
+ "fieldtype": "Check",
+ "label": "Spare Part Needed",
+ "insert_after": "ticket_section_break",
+ },
+ {
+ "fieldname": "spare_part_item_table",
+ "fieldtype": "Table",
+ "label": "Spare Part Items",
+ "insert_after": "spare_part_needed",
+ "options": "Spare Part Item",
+ "depends_on": "eval:doc.spare_part_needed == 1",
+ },
+ {
+ "fieldname": "raised_for",
+ "fieldtype": "Link",
+ "options": "User",
+ "label": "Raised For (Email)",
+ "insert_after": "raised_by",
+ },
+ {
+ "fieldname": "attach",
+ "fieldtype": "Attach",
+ "label": "Attachments",
+ "insert_after": "agent_group",
+ },
+ ]
+ }
+
+
+def get_interview_round_custom_fields():
+ """
+ Custom fields that need to be added to the Interview Round Child Table
+ """
+ return {
+ "Interview Round": [
+ {
+ "fieldname": "expected_questions",
+ "fieldtype": "Table",
+ "label": "Interview Questions",
+ "options": "Interview Questions",
+ "insert_after": "expected_skill_set",
+ }
+ ]
+ }
+
+
+def get_interview_custom_fields():
+ """
+ Custom fields that need to be added to the Interview Doctype
+ """
+ return {
+ "Interview": [
+ {
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "options": "Department",
+ "label": "Department",
+ "insert_after": "applicant_name",
+ "fetch_from": "job_applicant.department",
+ },
+ {
+ "fieldname": "applicant_name",
+ "fieldtype": "Data",
+ "label": "Applicant Name",
+ "insert_after": "job_applicant",
+ "fetch_from": "job_applicant.applicant_name",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "applicant_email",
+ "fieldtype": "Data",
+ "label": "Applicant Email ID",
+ "insert_after": "job_applicant",
+ "fetch_from": "job_applicant.email_id",
+ "hidden": 1,
+ },
+ ]
+ }
+
+
+def get_job_requisition_custom_fields():
+ """
+ Custom fields that need to be added to the Job Requisition Doctype
+ """
+ return {
+ "Job Requisition": [
+ {
+ "fieldname": "work_details",
+ "fieldtype": "Section Break",
+ "label": "Work Details",
+ "insert_after": "requested_by_designation",
+ },
+ {
+ "fieldname": "employment_type",
+ "fieldtype": "Link",
+ "options": "Employment Type",
+ "label": "Employment Type",
+ "insert_after": "department",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "no_of_days_off",
+ "fieldtype": "Int",
+ "label": "Number of Days Off",
+ "description": "Number Of Days Off within a 30-day Period",
+ "insert_after": "work_details",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "work_details_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "min_experience",
+ },
+ {
+ "fieldname": "is_work_shift_needed",
+ "fieldtype": "Check",
+ "label": "Is Shift Work Needed",
+ "insert_after": "work_details_column_break",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "travel_required",
+ "fieldtype": "Check",
+ "label": "Travel required for the position",
+ "insert_after": "is_work_shift_needed",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "driving_license_needed",
+ "fieldtype": "Check",
+ "label": "Driving License Needed for this Position",
+ "depends_on": "eval:doc.travel_required == 1",
+ "insert_after": "travel_required",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "license_type",
+ "fieldtype": "Link",
+ "label": "License Type",
+ "options": "License Type",
+ "depends_on": "eval:doc.driving_license_needed == 1",
+ "mandatory_depends_on": "eval:doc.driving_license_needed == 1",
+ "insert_after": "driving_license_needed",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "education",
+ "fieldtype": "Section Break",
+ "label": "Education and Qualification Details",
+ "insert_after": "license_type",
+ },
+ {
+ "fieldname": "min_education_qual",
+ "fieldtype": "Table MultiSelect",
+ "label": "Preferred Educational Qualification",
+ "options": "Educational Qualifications",
+ "insert_after": "education",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "min_experience",
+ "fieldtype": "Float",
+ "label": "Minimum Experience Required (Years)",
+ "insert_after": "no_of_days_off",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "reset_column",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "license_type",
+ },
+ {
+ "fieldname": "language_proficiency",
+ "fieldtype": "Table",
+ "options": "Language Proficiency",
+ "label": "Language Proficiency",
+ "insert_after": "reset_column",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "skill_proficiency",
+ "fieldtype": "Table",
+ "options": "Skill Proficiency",
+ "label": "Skill Proficiency",
+ "description": "Proficency selected here is the minimum proficency needed.",
+ "insert_after": "language_proficiency",
+ },
+ {
+ "fieldname": "job_description_template",
+ "fieldtype": "Link",
+ "label": "Job Description Template",
+ "options": "Job Description Template",
+ "insert_after": "job_description_tab",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "request_for",
+ "label": "Request For",
+ "fieldtype": "Select",
+ "options": "Employee Replacement\nExisting Vacancy\nNew Vacancy",
+ "insert_after": "naming_series",
+ },
+ {
+ "fieldname": "employee_left",
+ "label": "Employees Who Replaced",
+ "fieldtype": "Link",
+ "options": "Employee",
+ "insert_after": "request_for",
+ "depends_on": "eval:doc.request_for == 'Employee Replacement'",
+ },
+ {
+ "fieldname": "relieving_date",
+ "fieldtype": "Date",
+ "label": "Relieving Date",
+ "insert_after": "employee_left",
+ "fetch_from": "employee_left.relieving_date",
+ "depends_on": "eval:doc.request_for == 'Employee Replacement'",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "interview",
+ "fieldtype": "Section Break",
+ "label": "Interview Details",
+ "insert_after": "requested_by_designation",
+ },
+ {
+ "fieldname": "interview_rounds",
+ "fieldtype": "Table MultiSelect",
+ "options": "Interview Rounds",
+ "label": "Interview Rounds",
+ "insert_after": "interview",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "location",
+ "label": "Preferred Location",
+ "fieldtype": "Link",
+ "options": "Location",
+ "insert_after": "employment_type",
+ "permlevel": 1,
+ },
+ {
+ "fieldname": "job_title",
+ "fieldtype": "Data",
+ "label": "Job Title",
+ "insert_after": "job_description_template",
+ "reqd": 1,
+ },
+ {
+ "fieldname": "suggested_designation",
+ "fieldtype": "Link",
+ "label": "Suggested Designation",
+ "options": "Designation",
+ "insert_after": "request_for",
+ "permlevel": 2,
+ "depends_on": "eval:doc.request_for == 'New Vacancy'",
+ },
+ {
+ "fieldname": "suggestions",
+ "fieldtype": "Small Text",
+ "label": "Suggestions/Feedback",
+ "insert_after": "description",
+ "permlevel": 3,
+ },
+ {
+ "fieldname": "publish_on_job_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "requested_by_designation",
+ },
+ {
+ "fieldname": "publish_on_job_opening",
+ "fieldtype": "Check",
+ "default": "1",
+ "label": "Publish on Job Opening",
+ "insert_after": "publish_on_job_section",
+ "permlevel": 4,
+ },
+ ]
+ }
+
+
+def get_job_applicant_custom_fields():
+ """
+ Custom fields that need to be added to the Job Applicant Doctype
+ """
+ return {
+ "Job Applicant": [
+ {
+ "fieldname": "date_of_birth",
+ "fieldtype": "Date",
+ "label": "Date of Birth",
+ "insert_after": "email_id",
+ },
+ {
+ "fieldname": "gender",
+ "fieldtype": "Link",
+ "label": "Gender",
+ "options": "Gender",
+ "insert_after": "date_of_birth",
+ },
+ {
+ "fieldname": "willing_to_work_on_location",
+ "fieldtype": "Check",
+ "label": "Willing to Work in the Selected Location?",
+ "insert_after": "country",
+ },
+ {
+ "fieldname": "father_name",
+ "fieldtype": "Data",
+ "label": "Father's Name",
+ "insert_after": "job_title",
+ },
+ {
+ "fieldname": "marital_status",
+ "fieldtype": "Select",
+ "label": "Marital Status",
+ "options": "\nSingle\nMarried\nDivorced\nWidowed",
+ "insert_after": "location",
+ },
+ {
+ "fieldname": "current_address_session_break",
+ "fieldtype": "Section Break",
+ "label": "Current Address",
+ "insert_after": "marital_status",
+ },
+ {
+ "fieldname": "current_address",
+ "fieldtype": "Small Text",
+ "label": "Current Address",
+ "insert_after": "current_address_session_break",
+ },
+ {
+ "fieldname": "current_mobile_no",
+ "fieldtype": "Data",
+ "options": "Phone",
+ "label": "Mobile Number",
+ "insert_after": "current_address",
+ },
+ {
+ "fieldname": "current_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "current_mobile_no",
+ },
+ {
+ "fieldname": "permanent_address_session_break",
+ "fieldtype": "Section Break",
+ "label": "Permanent Address",
+ "insert_after": "current_column_break",
+ },
+ {
+ "fieldname": "current_period_from",
+ "fieldtype": "Int",
+ "label": "Period of From stay",
+ "insert_after": "current_column_break",
+ },
+ {
+ "fieldname": "current_period_to",
+ "fieldtype": "Int",
+ "label": "Period of To stay",
+ "insert_after": "current_period_from",
+ },
+ {
+ "fieldname": "current_residence_no",
+ "fieldtype": "Int",
+ "label": "Residence Number",
+ "insert_after": "current_period_to",
+ },
+ {
+ "fieldname": "permanent_address_session_break",
+ "fieldtype": "Section Break",
+ "label": "Permanent Address",
+ "insert_after": "current_residence_no",
+ },
+ {
+ "fieldname": "permanent_address",
+ "fieldtype": "Small Text",
+ "label": "Permanent Address",
+ "insert_after": "permanent_address_session_break",
+ },
+ {
+ "fieldname": "permanent_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "permanent_address",
+ },
+ {
+ "fieldname": "permanent_residence_no",
+ "fieldtype": "Int",
+ "label": "Residence Number",
+ "insert_after": "permanent_address",
+ },
+ {
+ "fieldname": "permanent_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "permanent_residence_no",
+ },
+ {
+ "fieldname": "permanent_period_from",
+ "fieldtype": "Int",
+ "label": "Period of From stay",
+ "insert_after": "permanent_column_break",
+ },
+ {
+ "fieldname": "permanent_period_to",
+ "fieldtype": "Int",
+ "label": "Period of To stay",
+ "insert_after": "permanent_period_from",
+ },
+ {
+ "fieldname": "permananet_email_id",
+ "fieldtype": "Data",
+ "options": "Email",
+ "label": "Email ID",
+ "insert_after": "permanent_period_to",
+ },
+ {
+ "fieldname": "email_address_session_break",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "permanent_column_break",
+ },
+ {
+ "fieldname": "email_id_1",
+ "fieldtype": "Data",
+ "options": "Email",
+ "label": "Email ID",
+ "insert_after": "email_address_session_break",
+ },
+ {
+ "fieldname": "min_education_qual",
+ "fieldtype": "Link",
+ "label": "Educational Qualification",
+ "options": "Educational Qualification",
+ "insert_after": "details",
+ },
+ {
+ "fieldname": "details",
+ "fieldtype": "Section Break",
+ "label": "Qualification Details",
+ "insert_after": "applicant_rating",
+ },
+ {
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "label": "Department",
+ "options": "Department",
+ "insert_after": "designation",
+ },
+ {
+ "fieldname": "min_experience",
+ "fieldtype": "Float",
+ "label": "Work Experience (Years)",
+ "insert_after": "details_column_break",
+ },
+ {
+ "fieldname": "details_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "min_education_qual",
+ },
+ {
+ "fieldname": "reset_column",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "min_experience",
+ },
+ {
+ "fieldname": "language_proficiency",
+ "fieldtype": "Table",
+ "options": "Language Proficiency",
+ "label": "Language Proficiency",
+ "insert_after": "min_experience",
+ },
+ {
+ "fieldname": "skill_proficiency",
+ "fieldtype": "Table",
+ "options": "Skill Proficiency",
+ "label": "Skill Proficiency",
+ "insert_after": "language_proficiency",
+ },
+ {
+ "fieldname": "education_qualification",
+ "fieldtype": "Table",
+ "options": "Education Qualification",
+ "label": "Education Qualification",
+ "insert_after": "applicant_interview_rounds",
+ },
+ {
+ "fieldname": "professional_certification",
+ "fieldtype": "Table",
+ "options": "Professional Certification",
+ "label": "Professional Certification",
+ "insert_after": "education_qualification",
+ },
+ {
+ "fieldname": "location",
+ "label": "Location",
+ "fieldtype": "Link",
+ "options": "Location",
+ "insert_after": "status",
+ },
+ {
+ "fieldname": "interview_process_break",
+ "fieldtype": "Section Break",
+ "label": "Interview Process",
+ "insert_after": "skill_proficiency",
+ },
+ {
+ "fieldname": "applicant_interview_rounds",
+ "fieldtype": "Table",
+ "options": "Applicant Interview Round",
+ "label": "Interview Rounds",
+ "insert_after": "interview_process_break",
+ },
+ {
+ "fieldname": "current_employer_tab_break",
+ "fieldtype": "Tab Break",
+ "label": "Current Employer Details",
+ "insert_after": "upper_range",
+ },
+ {
+ "fieldname": "current_employer",
+ "fieldtype": "Section Break",
+ "label": "Current Employer / Immediate Previous Employer",
+ "insert_after": "current_employer_tab_break",
+ },
+ {
+ "fieldname": "name_of_employer",
+ "fieldtype": "Data",
+ "label": "Name of Employer",
+ "insert_after": "current_employer",
+ },
+ {
+ "fieldname": "employment_period_from",
+ "fieldtype": "Int",
+ "label": "Employment Period From",
+ "insert_after": "name_of_employer",
+ },
+ {
+ "fieldname": "employee_code",
+ "fieldtype": "Data",
+ "label": "Employee Code",
+ "insert_after": "name_of_employer",
+ },
+ {
+ "fieldname": "telephone_no",
+ "fieldtype": "Data",
+ "options": "Phone",
+ "label": "Telephone No",
+ "insert_after": "employee_code",
+ },
+ {
+ "fieldname": "employment_period_from",
+ "fieldtype": "Int",
+ "label": "Employment Period From",
+ "insert_after": "telephone_no",
+ },
+ {
+ "fieldname": "employment_period_to",
+ "fieldtype": "Int",
+ "label": "Employment Period To",
+ "insert_after": "employment_period_from",
+ },
+ {
+ "fieldname": "current_employer_1_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "employment_period_to",
+ },
+ {
+ "fieldname": "address_of_employer",
+ "fieldtype": "Small Text",
+ "label": "Address of Employer",
+ "insert_after": "employment_period_to",
+ },
+ {
+ "fieldname": "current_employer_1_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "address_of_employer",
+ },
+ {
+ "fieldname": "first_salary_drawn",
+ "fieldtype": "Currency",
+ "label": "First Salary Drawn",
+ "insert_after": "current_employer_1_column_break",
+ },
+ {
+ "fieldname": "last_salary_drawn",
+ "fieldtype": "Currency",
+ "label": "Last Salary Drawn",
+ "insert_after": "first_salary_drawn",
+ },
+ {
+ "fieldname": "current_designation",
+ "fieldtype": "Data",
+ "label": "Designation",
+ "insert_after": "current_employer_1_column_break",
+ },
+ {
+ "fieldname": "reference_taken",
+ "fieldtype": "Select",
+ "label": "Can I take Reference Now?",
+ "options": "\nYes\nNo",
+ "insert_after": "current_designation",
+ },
+ {
+ "fieldname": "was_this_position",
+ "fieldtype": "Select",
+ "label": "Was this Position Permanent,Temporary,Contractual?",
+ "options": "\nPermanent\nTemporary\nContractual",
+ "insert_after": "reference_taken",
+ },
+ {
+ "fieldname": "duties_and_reponsibilities",
+ "fieldtype": "Small Text",
+ "label": "Duties and Responsibilities",
+ "insert_after": "column_break_agency",
+ },
+ {
+ "fieldname": "current_employer_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "was_this_position",
+ },
+ {
+ "fieldname": "current_department",
+ "fieldtype": "Data",
+ "label": "Department",
+ "insert_after": "current_employer_column_break",
+ },
+ {
+ "fieldname": "manager_name",
+ "fieldtype": "Data",
+ "label": "Manager's Name",
+ "insert_after": "current_department",
+ },
+ {
+ "fieldname": "manager_contact_no",
+ "fieldtype": "Data",
+ "options": "Phone",
+ "label": "Manager's Contact No",
+ "insert_after": "manager_name",
+ },
+ {
+ "fieldname": "manager_email",
+ "fieldtype": "Data",
+ "options": "Email",
+ "label": "Manager's Email",
+ "insert_after": "manager_contact_no",
+ },
+ {
+ "fieldname": "reason_for_leaving",
+ "fieldtype": "Small Text",
+ "label": "Reason For Leaving",
+ "insert_after": "duties_and_reponsibilities",
+ },
+ {
+ "fieldname": "agency_details",
+ "fieldtype": "Small Text",
+ "label": "Agency Details (if Temporary or Contractual)",
+ "insert_after": "address_of_employer",
+ },
+ {
+ "fieldname": "column_break_agency",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "agency_details",
+ },
+ {
+ "fieldname": "previous_emp",
+ "fieldtype": "Section Break",
+ "insert_after": "manager_email",
+ },
+ {
+ "fieldname": "address_of_employer",
+ "fieldtype": "Small Text",
+ "label": "Address of Employer",
+ "insert_after": "previous_emp",
+ },
+ {
+ "fieldname": "previous_emplyoment",
+ "fieldtype": "Section Break",
+ "label": "Previous Employment History",
+ "insert_after": "previous_emp",
+ },
+ {
+ "fieldname": "prev_emp_his",
+ "fieldtype": "Table",
+ "options": "Previous Employment History",
+ "insert_after": "previous_emplyoment",
+ },
+ {
+ "fieldname": "more_details_tab_break",
+ "fieldtype": "Tab Break",
+ "label": "More Details",
+ "insert_after": "prev_emp_his",
+ },
+ {
+ "fieldname": "current_salary",
+ "fieldtype": "Currency",
+ "label": "Current Salary",
+ "insert_after": "more_details_tab_break",
+ },
+ {
+ "fieldname": "current_salary_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "current_salary",
+ },
+ {
+ "fieldname": "expected_salary",
+ "fieldtype": "Currency",
+ "label": "Expected Salary",
+ "insert_after": "current_salary_column_break",
+ },
+ {
+ "fieldname": "expected_salary_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "expected_salary",
+ },
+ {
+ "fieldname": "telephone_number",
+ "fieldtype": "Data",
+ "options": "Phone",
+ "label": "Telephone Number",
+ "insert_after": "expected_salary_column_break",
+ },
+ {
+ "fieldname": "other_achievments_session_break",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "current_employer_tab_break",
+ },
+ {
+ "fieldname": "other_achievments",
+ "fieldtype": "Small Text",
+ "label": "Please add details of Professional and other achievements,awards and accomplishments,if any",
+ "insert_after": "other_achievments_session_break",
+ },
+ {
+ "fieldname": "interviewed_session_break",
+ "fieldtype": "Section Break",
+ "label": "Have you been interviewed before by Madhyamam Group?If yes, Please give details below :",
+ "insert_after": "other_achievments",
+ },
+ {
+ "fieldname": "position",
+ "fieldtype": "Data",
+ "label": "Position",
+ "insert_after": "interviewed_session_break",
+ },
+ {
+ "fieldname": "interviewed_date",
+ "fieldtype": "Date",
+ "label": "Date",
+ "insert_after": "position",
+ },
+ {
+ "fieldname": "interviewed_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "interviewed_date",
+ },
+ {
+ "fieldname": "interviewed_location",
+ "fieldtype": "Link",
+ "options": "Location",
+ "label": "Location",
+ "insert_after": "interviewed_column_break",
+ },
+ {
+ "fieldname": "interviewed_outcome",
+ "fieldtype": "Data",
+ "label": "Outcome",
+ "insert_after": "interviewed_location",
+ },
+ {
+ "fieldname": "travel_session_break",
+ "fieldtype": "Section Break",
+ "label": "Are you willing to travel :",
+ "insert_after": "interviewed_outcome",
+ },
+ {
+ "fieldname": "in_india",
+ "fieldtype": "Check",
+ "label": "In India",
+ "insert_after": "travel_session_break",
+ },
+ {
+ "fieldname": "state_restriction",
+ "fieldtype": "Data",
+ "label": "State Restriction If any",
+ "depends_on": "eval:doc.in_india",
+ "insert_after": "in_india",
+ },
+ {
+ "fieldname": "india_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "state_restriction",
+ },
+ {
+ "fieldname": "abroad",
+ "fieldtype": "Check",
+ "label": "Abroad",
+ "insert_after": "india_column_break",
+ },
+ {
+ "fieldname": "related_session_break",
+ "fieldtype": "Section Break",
+ "label": "Are you related to any of employee of the Madhyamam Group? If yes,please give details :",
+ "insert_after": "state_restriction",
+ },
+ {
+ "fieldname": "related_employee",
+ "fieldtype": "Data",
+ "label": "Name",
+ "insert_after": "related_session_break",
+ },
+ {
+ "fieldname": "related_employee_org",
+ "fieldtype": "Data",
+ "label": "Organization",
+ "insert_after": "related_employee",
+ },
+ {
+ "fieldname": "related_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "related_employee_org",
+ },
+ {
+ "fieldname": "related_employee_pos",
+ "fieldtype": "Data",
+ "label": "Position",
+ "insert_after": "related_column_break",
+ },
+ {
+ "fieldname": "related_employee_rel",
+ "fieldtype": "Data",
+ "label": "Relationship",
+ "insert_after": "related_employee_pos",
+ },
+ {
+ "fieldname": "prof_session_break",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "related_employee_rel",
+ },
+ {
+ "fieldname": "professional_org",
+ "fieldtype": "Small Text",
+ "label": "Are you a member of any Professional Organization? If yes, Please give details :",
+ "insert_after": "prof_session_break",
+ },
+ {
+ "fieldname": "political_org",
+ "fieldtype": "Small Text",
+ "label": "Are you a member of any Political Organization? If yes, Please give details :",
+ "insert_after": "professional_org",
+ },
+ {
+ "fieldname": "specialised_training",
+ "fieldtype": "Small Text",
+ "label": "Have you attended any specialised training program?If yes, Please give detais :",
+ "insert_after": "political_org",
+ },
+ {
+ "fieldname": "is_form_submitted",
+ "fieldtype": "Check",
+ "label": "Is Form Submitted",
+ "read_only": 1,
+ "insert_after": "specialised_training",
+ },
+ {
+ "fieldname": "payslip_month_1",
+ "fieldtype": "Attach",
+ "label": "Payslip - Month 1",
+ "insert_after": "section_break_001",
+ },
+ {
+ "fieldname": "break_oo1",
+ "fieldtype": "Column Break",
+ "insert_after": "payslip_month_1",
+ },
+ {
+ "fieldname": "payslip_month_2",
+ "fieldtype": "Attach",
+ "label": "Payslip - Month 2",
+ "insert_after": "break_oo1",
+ },
+ {
+ "fieldname": "section_break_001",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "prev_emp_his",
+ },
+ {
+ "fieldname": "break_oo2",
+ "fieldtype": "Column Break",
+ "insert_after": "payslip_month_2",
+ },
+ {
+ "fieldname": "payslip_month_3",
+ "fieldtype": "Attach",
+ "label": "Payslip - Month 3",
+ "insert_after": "break_oo2",
+ },
+ ]
+ }
+
+
+def get_contract_custom_fields():
+ """
+ Custom fields that need to be added to the Contract Doctype
+ """
+ return {
+ "Contract": [
+ {
+ "fieldname": "services_section",
+ "fieldtype": "Section Break",
+ "label": "Services",
+ "insert_after": "ip_address",
+ },
+ {
+ "fieldname": "services",
+ "fieldtype": "Table",
+ "options": "Services",
+ "label": "Services",
+ "insert_after": "services_section",
+ "depends_on": "eval:doc.party_type == 'Supplier'",
+ },
+ {
+ "fieldname": "total_amount",
+ "fieldtype": "Currency",
+ "label": "Total Amount",
+ "insert_after": "services",
+ "read_only": 1,
+ "no_copy": 1,
+ },
+ ]
+ }
+
+
+def get_job_opening_custom_fields():
+ """
+ Custom fields that need to be added to the Job Opening Doctype
+ """
+ return {
+ "Job Opening": [
+ {
+ "fieldname": "job_details",
+ "fieldtype": "Section Break",
+ "label": "Job Details",
+ "insert_after": "location",
+ },
+ {
+ "fieldname": "no_of_positions",
+ "fieldtype": "Int",
+ "label": "No of.Positions",
+ "insert_after": "employment_type",
+ },
+ {
+ "fieldname": "no_of_days_off",
+ "fieldtype": "Int",
+ "label": "Number of Days Off",
+ "insert_after": "job_details",
+ "non_negative": 1,
+ },
+ {
+ "fieldname": "preffered_location",
+ "label": "Preffered Location",
+ "fieldtype": "Link",
+ "options": "Location",
+ "insert_after": "no_of_days_off",
+ },
+ {
+ "fieldname": "job_details_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "preffered_location",
+ },
+ {
+ "fieldname": "travel_required",
+ "fieldtype": "Check",
+ "label": "Travel required for the position",
+ "insert_after": "job_details_column_break",
+ },
+ {
+ "fieldname": "driving_license_needed",
+ "fieldtype": "Check",
+ "label": "Driving License Needed for this Position",
+ "depends_on": "eval:doc.travel_required == 1",
+ "insert_after": "travel_required",
+ },
+ {
+ "fieldname": "license_type",
+ "fieldtype": "Link",
+ "label": "License Type",
+ "options": "License Type",
+ "depends_on": "eval:doc.driving_license_needed == 1",
+ "insert_after": "driving_license_needed",
+ },
+ {
+ "fieldname": "is_work_shift_needed",
+ "fieldtype": "Check",
+ "label": "Is Shift Work Needed",
+ "insert_after": "license_type",
+ },
+ {
+ "fieldname": "qualification_details",
+ "fieldtype": "Section Break",
+ "label": "Education and Qualification Details",
+ "insert_after": "license_type",
+ },
+ {
+ "fieldname": "min_education_qual",
+ "fieldtype": "Table MultiSelect",
+ "label": "Preferred Educational Qualification",
+ "options": "Educational Qualifications",
+ "insert_after": "qualification_details",
+ },
+ {
+ "fieldname": "qualification_details_column_break",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "min_education_qual",
+ },
+ {
+ "fieldname": "min_experience",
+ "fieldtype": "Float",
+ "label": "Minimum Experience Required (Years)",
+ "insert_after": "is_work_shift_needed",
+ },
+ {
+ "fieldname": "proficiency_break",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "min_experience",
+ },
+ {
+ "fieldname": "language_proficiency",
+ "fieldtype": "Table",
+ "options": "Language Proficiency",
+ "label": "Language Proficiency",
+ "insert_after": "proficiency_break",
+ "description": "Proficency selected here is the minimum proficency needed",
+ },
+ {
+ "fieldname": "skill_proficiency",
+ "fieldtype": "Table",
+ "options": "Skill Proficiency",
+ "label": "Skill Proficiency",
+ "insert_after": "language_proficiency",
+ "description": "Proficency selected here is the minimum proficency needed",
+ },
+ {
+ "fieldname": "interview_details_sb",
+ "fieldtype": "Section Break",
+ "label": "Interview Details",
+ "insert_after": "skill_proficiency",
+ },
+ {
+ "fieldname": "interview_rounds",
+ "fieldtype": "Table MultiSelect",
+ "label": "Interview Rounds",
+ "options": "Interview Rounds",
+ "insert_after": "interview_details_sb",
+ },
+ ]
+ }
+
+
+def get_company_custom_fields():
+ """
+ Custom fields that need to be added to the Company Doctype
+ """
+ return {
+ "Company": [
+ {
+ "fieldname": "company_policy_tab",
+ "fieldtype": "Tab Break",
+ "label": "Company Policy",
+ "insert_after": "dashboard_tab",
+ },
+ {
+ "fieldname": "company_policy",
+ "fieldtype": "Text Editor",
+ "label": "Company Policy",
+ "insert_after": "company_policy_tab",
+ },
+ {
+ "fieldname": "exception_budget_column",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "exception_budget_approver_role",
+ },
+ {
+ "fieldname": "exchange_rate_to_inr",
+ "fieldtype": "Float",
+ "label": "Budget Exchange Rate to INR",
+ "insert_after": "exception_budget_column",
+ },
+ {
+ "fieldname": "exchange_rate_to_inr",
+ "fieldtype": "Float",
+ "label": "Exchange Rate to INR",
+ "insert_after": "exchange_gain_loss_account",
+ "description": "1 Unit of Company Currency = [?] INR",
+ },
+ ]
+ }
+
+
+def get_employee_performance_feedback():
+ """Custom fields that need to be added to
+ Employee Performance Feedback doctype
+ """
+ return {
+ "Employee Performance Feedback": [
+ {
+ "fieldname": "employee_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "feedback_ratings",
+ },
+ {
+ "fieldname": "employee_total_score",
+ "fieldtype": "Float",
+ "label": "Total Score",
+ "insert_after": "employee_section",
+ },
+ {
+ "fieldname": "employee_column",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "employee_total_score",
+ },
+ {
+ "fieldname": "employee_average_score",
+ "fieldtype": "Float",
+ "label": "Average Score",
+ "insert_after": "employee_column",
+ },
+ {
+ "fieldname": "emp_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "employee_average_score",
+ },
+ {
+ "fieldname": "company_criteria",
+ "fieldtype": "Table",
+ "options": "Employee Feedback Rating",
+ "label": "Company Criteria",
+ "insert_after": "emp_section",
+ },
+ {
+ "fieldname": "company_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "company_criteria",
+ },
+ {
+ "fieldname": "company_total_score",
+ "fieldtype": "Float",
+ "label": "Total Score",
+ "insert_after": "company_section",
+ },
+ {
+ "fieldname": "company_column",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "company_total_score",
+ },
+ {
+ "fieldname": "company_average_score",
+ "fieldtype": "Float",
+ "label": "Average Score",
+ "insert_after": "company_column",
+ },
+ {
+ "fieldname": "dept_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "company_average_score",
+ },
+ {
+ "fieldname": "department_criteria",
+ "fieldtype": "Table",
+ "options": "Employee Feedback Rating",
+ "label": "Department Criteria",
+ "insert_after": "dept_section",
+ },
+ {
+ "fieldname": "dept_section1",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "department_criteria",
+ },
+ {
+ "fieldname": "department_total_score",
+ "fieldtype": "Float",
+ "label": "Total Score",
+ "insert_after": "dept_section1",
+ },
+ {
+ "fieldname": "dept_column",
+ "fieldtype": "Column Break",
+ "label": "",
+ "insert_after": "department_total_score",
+ },
+ {
+ "fieldname": "department_average_score",
+ "fieldtype": "Float",
+ "label": "Average Score",
+ "insert_after": "dept_column",
+ },
+ ]
+ }
-def get_employee_performance_feedback():
- '''Custom fields that need to be added to
- Employee Performance Feedback doctype
- '''
- return {
- "Employee Performance Feedback" : [
- {
- "fieldname": "employee_section",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "feedback_ratings"
- },
- {
- "fieldname": "employee_total_score",
- "fieldtype": "Float",
- "label": "Total Score",
- "insert_after": "employee_section"
- },
- {
- "fieldname": "employee_column",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "employee_total_score"
- },
- {
- "fieldname": "employee_average_score",
- "fieldtype": "Float",
- "label": "Average Score",
- "insert_after": "employee_column"
- },
- {
- "fieldname": "emp_section",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "employee_average_score"
- },
- {
- "fieldname": "company_criteria",
- "fieldtype": "Table",
- "options": "Employee Feedback Rating",
- "label": "Company Criteria",
- "insert_after": "emp_section"
- },
- {
- "fieldname": "company_section",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "company_criteria"
- },
- {
- "fieldname": "company_total_score",
- "fieldtype": "Float",
- "label": "Total Score",
- "insert_after": "company_section"
- },
- {
- "fieldname": "company_column",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "company_total_score"
- },
- {
- "fieldname": "company_average_score",
- "fieldtype": "Float",
- "label": "Average Score",
- "insert_after": "company_column"
- },
- {
- "fieldname": "dept_section",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "company_average_score"
- },
- {
- "fieldname": "department_criteria",
- "fieldtype": "Table",
- "options": "Employee Feedback Rating",
- "label": "Department Criteria",
- "insert_after": "dept_section"
- },
- {
- "fieldname": "dept_section1",
- "fieldtype": "Section Break",
- "label": "",
- "insert_after": "department_criteria"
- },
- {
- "fieldname": "department_total_score",
- "fieldtype": "Float",
- "label": "Total Score",
- "insert_after": "dept_section1"
- },
- {
- "fieldname": "dept_column",
- "fieldtype": "Column Break",
- "label": "",
- "insert_after": "department_total_score"
- },
- {
- "fieldname": "department_average_score",
- "fieldtype": "Float",
- "label": "Average Score",
- "insert_after": "dept_column"
- }
- ]
- }
def get_leave_type_custom_fields():
- '''
- Custom fields that need to be added to the Leave Type Doctype
- '''
- return {
- "Leave Type": [
- {
- "fieldname": "min_advance_days",
- "fieldtype": "Int",
- "label": "Minimum Advance Days",
- "description": "Specifies the minimum number of days required to apply for this leave.",
- "insert_after": "max_continuous_days_allowed"
- },
- {
- "fieldname": "is_proof_document",
- "fieldtype": "Check",
- "label": "Is Proof Document Required",
- "insert_after": "is_optional_leave"
-
- },
- {
- "fieldname": "medical_leave_required",
- "fieldtype": "Float",
- "label": "Medical Leave Required for Days",
- "depends_on": "eval:doc.is_proof_document",
- "insert_after": "is_proof_document"
- },
- {
- "fieldname": "allow_in_notice_period",
- "fieldtype": "Check",
- "label": "Allow in Notice Period",
- "insert_after": "is_compensatory"
-
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Leave Type Doctype
+ """
+ return {
+ "Leave Type": [
+ {
+ "fieldname": "min_advance_days",
+ "fieldtype": "Int",
+ "label": "Minimum Advance Days",
+ "description": "Specifies the minimum number of days required to apply for this leave.",
+ "insert_after": "max_continuous_days_allowed",
+ },
+ {
+ "fieldname": "is_proof_document",
+ "fieldtype": "Check",
+ "label": "Is Proof Document Required",
+ "insert_after": "is_optional_leave",
+ },
+ {
+ "fieldname": "medical_leave_required",
+ "fieldtype": "Float",
+ "label": "Medical Leave Required for Days",
+ "depends_on": "eval:doc.is_proof_document",
+ "insert_after": "is_proof_document",
+ },
+ {
+ "fieldname": "allow_in_notice_period",
+ "fieldtype": "Check",
+ "label": "Allow in Notice Period",
+ "insert_after": "is_compensatory",
+ },
+ ]
+ }
+
def get_employee_separation_custom_fields():
- '''
- Custom fields that need to be added to the Employee Separation Doctype
- '''
- return {
- "Employee Separation": [
- {
- "fieldname": "employee_clearance",
- "fieldtype": "Table",
- "label": "Employee Clearance",
- "options": "Employee Clearance",
- "insert_after": "activities"
-
- },
- {
- "fieldname": "employee_exit_status",
- "fieldtype": "Select",
- "label": "Employee Exit Clearance Status",
- "options":"Pending\nCompleted",
- "insert_after": "employee_clearance"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Employee Separation Doctype
+ """
+ return {
+ "Employee Separation": [
+ {
+ "fieldname": "employee_clearance",
+ "fieldtype": "Table",
+ "label": "Employee Clearance",
+ "options": "Employee Clearance",
+ "insert_after": "activities",
+ },
+ {
+ "fieldname": "employee_exit_status",
+ "fieldtype": "Select",
+ "label": "Employee Exit Clearance Status",
+ "options": "Pending\nCompleted",
+ "insert_after": "employee_clearance",
+ },
+ ]
+ }
+
def get_appraisal_template_custom_fields():
- '''
- Custom fields that need to be added to the Appraisal Template doctype
- '''
- return {
- "Appraisal Template": [
- {
- "fieldname": "department_rating_criteria",
- "fieldtype": " Table",
- "options": "Employee Feedback Rating",
- "label": "Department Rating Criteria",
- "insert_after": "rating_criteria"
- },
- {
- "fieldname": "company_rating_criteria",
- "fieldtype": " Table",
- "options": "Employee Feedback Rating",
- "label": "Company Rating Criteria",
- "insert_after": "label_for_department_kra"
- },
- {
- "fieldname": "label_for_department_kra",
- "fieldtype": "Data",
- "label": "Label for Department KRA",
- "insert_after": "department_rating_criteria"
- },
- {
- "fieldname": "label_for_company_kra",
- "fieldtype": "Data",
- "label": "Label for Company KRA",
- "insert_after": "company_rating_criteria"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Appraisal Template doctype
+ """
+ return {
+ "Appraisal Template": [
+ {
+ "fieldname": "department_rating_criteria",
+ "fieldtype": " Table",
+ "options": "Employee Feedback Rating",
+ "label": "Department Rating Criteria",
+ "insert_after": "rating_criteria",
+ },
+ {
+ "fieldname": "company_rating_criteria",
+ "fieldtype": " Table",
+ "options": "Employee Feedback Rating",
+ "label": "Company Rating Criteria",
+ "insert_after": "label_for_department_kra",
+ },
+ {
+ "fieldname": "label_for_department_kra",
+ "fieldtype": "Data",
+ "label": "Label for Department KRA",
+ "insert_after": "department_rating_criteria",
+ },
+ {
+ "fieldname": "label_for_company_kra",
+ "fieldtype": "Data",
+ "label": "Label for Company KRA",
+ "insert_after": "company_rating_criteria",
+ },
+ {
+ "fieldname": "designation_section",
+ "fieldtype": "Section Break",
+ "label": "",
+ "insert_after": "label_for_company_kra",
+ },
+ {
+ "fieldname": "assessment_officers",
+ "fieldtype": "Table",
+ "options": "Assessment Officer",
+ "label": "Assessment Officers",
+ "insert_after": "designation_section",
+ },
+ ]
+ }
+
def get_employee_feedback_rating_custom_fields():
- '''
- Custom fields that need to be added to the Employee Feedback Rating doctype
- '''
- return {
- "Employee Feedback Rating": [
- {
- "fieldname": "marks",
- "fieldtype": " Float",
- "label": "Marks out of 5",
- "insert_after": "per_weightage"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Employee Feedback Rating doctype
+ """
+ return {
+ "Employee Feedback Rating": [
+ {
+ "fieldname": "marks",
+ "fieldtype": " Float",
+ "label": "Marks out of 5",
+ "insert_after": "per_weightage",
+ }
+ ]
+ }
+
def get_appraisal_custom_fields():
- '''
- Custom fields that need to be added to the Appraisal doctype
- '''
- return {
- "Appraisal": [
- {
- "fieldname": "appraisal_summary_tab_break",
- "fieldtype": "Tab Break",
- "label": "Appraisal Summary",
- "insert_after": "amended_from"
- },
- {
- "fieldname": "appraisal_summary",
- "fieldtype": "HTML",
- "label": "Appraisal Summary",
- "insert_after": "appraisal_summary_tab_break"
- },
- {
+ """
+ Custom fields that need to be added to the Appraisal doctype
+ """
+ return {
+ "Appraisal": [
+ {
+ "fieldname": "appraisal_summary_tab_break",
+ "fieldtype": "Tab Break",
+ "label": "Appraisal Summary",
+ "insert_after": "amended_from",
+ },
+ {
+ "fieldname": "appraisal_summary",
+ "fieldtype": "HTML",
+ "label": "Appraisal Summary",
+ "insert_after": "appraisal_summary_tab_break",
+ },
+ {
"fieldname": "final_assesment_tab_break",
"fieldtype": "Tab Break",
"label": "Final Assesment",
- "insert_after": "appraisal_summary"
+ "insert_after": "appraisal_summary",
},
{
"fieldname": "category_html",
"fieldtype": "HTML",
"label": "Appraisal Summary",
- "insert_after": "final_assesment_tab_break"
+ "insert_after": "final_assesment_tab_break",
},
- {
+ {
"fieldname": "category_based_on_marks",
"fieldtype": "Link",
- "options": "Appraisal Category",
+ "options": "Appraisal Category",
"label": "Category based on marks",
"insert_after": "category_html",
- "read_only": 1
+ "read_only": 1,
},
{
"fieldname": "category_details",
@@ -3282,1447 +3438,1532 @@ def get_appraisal_custom_fields():
"options": "Category Details",
"insert_after": "category_based_on_marks",
"allow_on_submit": 1,
- "read_only": 1
- },
- {
- "fieldname": "employee_self_kra_rating",
- "fieldtype": "Table",
- "label": "Employee Rating",
- "options": "Employee Feedback Rating",
- "insert_after": "self_score",
- },
- {
- "fieldname": "total_employee_self_kra_rating",
- "fieldtype": "Float",
- "label": "Total Employee Self Score",
- "insert_after": "employee_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "avg_employee_self_kra_rating",
- "fieldtype": "Float",
- "label": "Average Employee Self Score",
- "insert_after": "total_employee_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "dept_self_kra_rating",
- "fieldtype": "Table",
- "label": "Department Rating",
- "options": "Employee Feedback Rating",
- "insert_after": "avg_employee_self_kra_rating",
- },
- {
- "fieldname": "total_dept_self_kra_rating",
- "fieldtype": "Float",
- "label": "Total Department Self Score",
- "insert_after": "dept_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "avg_dept_self_kra_rating",
- "fieldtype": "Float",
- "label": "Average Department Self Score",
- "insert_after": "total_dept_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "company_self_kra_rating",
- "fieldtype": "Table",
- "label": "Company Rating",
- "options": "Employee Feedback Rating",
- "insert_after": "avg_dept_self_kra_rating",
- },
- {
- "fieldname": "total_company_self_kra_rating",
- "fieldtype": "Float",
- "label": "Total Company Self Score",
- "insert_after": "company_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "avg_company_self_kra_rating",
- "fieldtype": "Float",
- "label": "Average Company Self Score",
- "insert_after": "total_company_self_kra_rating",
- "read_only": 1
- },
- {
- "fieldname": "final_average_score",
- "fieldtype": "Float",
- "label": "Final Average Score",
- "insert_after": "employee_image",
- "precision": 3
- }
- ]
- }
+ "read_only": 1,
+ },
+ {
+ "fieldname": "employee_self_kra_rating",
+ "fieldtype": "Table",
+ "label": "Employee Rating",
+ "options": "Employee Feedback Rating",
+ "insert_after": "self_score",
+ },
+ {
+ "fieldname": "total_employee_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Total Employee Self Score",
+ "insert_after": "employee_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "avg_employee_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Average Employee Self Score",
+ "insert_after": "total_employee_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "dept_self_kra_rating",
+ "fieldtype": "Table",
+ "label": "Department Rating",
+ "options": "Employee Feedback Rating",
+ "insert_after": "avg_employee_self_kra_rating",
+ },
+ {
+ "fieldname": "total_dept_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Total Department Self Score",
+ "insert_after": "dept_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "avg_dept_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Average Department Self Score",
+ "insert_after": "total_dept_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "company_self_kra_rating",
+ "fieldtype": "Table",
+ "label": "Company Rating",
+ "options": "Employee Feedback Rating",
+ "insert_after": "avg_dept_self_kra_rating",
+ },
+ {
+ "fieldname": "total_company_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Total Company Self Score",
+ "insert_after": "company_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "avg_company_self_kra_rating",
+ "fieldtype": "Float",
+ "label": "Average Company Self Score",
+ "insert_after": "total_company_self_kra_rating",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "final_average_score",
+ "fieldtype": "Float",
+ "label": "Final Average Score",
+ "insert_after": "employee_image",
+ "precision": 3,
+ },
+ ]
+ }
+
def get_appraisal_kra_custom_fields():
- '''
+ """
Custom fields that need to be added to the Appraisal KRA doctype
- '''
+ """
return {
- "Appraisal KRA":[
- {
- "fieldname": "kra_goals",
- "fieldtype": "Text Editor",
- "label": "Goals",
- "insert_after": "goal_score",
- "in_list_view":1
- }
- ]
+ "Appraisal KRA": [
+ {
+ "fieldname": "kra_goals",
+ "fieldtype": "Text Editor",
+ "label": "Goals",
+ "insert_after": "goal_score",
+ "in_list_view": 1,
+ }
+ ]
}
+
def create_property_setters(property_setter_datas):
- '''
- Method to create custom property setters
- args:
- property_setter_datas : list of dict of property setter obj
- '''
- for property_setter_data in property_setter_datas:
- if frappe.db.exists("Property Setter", property_setter_data):
- continue
- property_setter = frappe.new_doc("Property Setter")
- property_setter.update(property_setter_data)
- property_setter.flags.ignore_permissions = True
- property_setter.insert()
+ """
+ Method to create custom property setters
+ args:
+ property_setter_datas : list of dict of property setter obj
+ """
+ for property_setter_data in property_setter_datas:
+ if frappe.db.exists("Property Setter", property_setter_data):
+ continue
+ property_setter = frappe.new_doc("Property Setter")
+ property_setter.update(property_setter_data)
+ property_setter.flags.ignore_permissions = True
+ property_setter.insert()
+
def get_property_setters():
- '''
- BEAMS specific property setters that need to be added to the Customer ,Account and Supplier DocTypes
- '''
- return [
-
- {
- "doctype_or_field": "DocField",
- "doc_type": "Customer",
- "field_name": "disabled",
- "property": "default",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal Template",
- "field_name": "rating_criteria",
- "property": "label",
- "value": "Employee Criteria"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Feedback Rating",
- "field_name": "rating_criteria",
- "property": "read_only",
- "property_type": "Table",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "status",
- "property": "read_only",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Leave Allocation",
- "field_name": "to_date",
- "property": "allow_on_submit",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Customer",
- "field_name": "disabled",
- "property": "read_only",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Account",
- "field_name": "disabled",
- "property": "default",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Account",
- "field_name": "disabled",
- "property": "read_only",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Supplier",
- "field_name": "disabled",
- "property": "default",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Supplier",
- "field_name": "disabled",
- "property": "read_only",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Advance",
- "field_name": "purpose",
- "property": "hidden",
- "property_type": "Small Text",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Purchase Invoice",
- "field_name": "update_stock",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Customer",
- "field_name": "sales_team_tab",
- "property": "hidden",
- "property_type": "TabBreak",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Purchase Invoice",
- "field_name": "is_subcontracted",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Purchase Invoice",
- "field_name": "scan_barcode",
- "property": "hidden",
- "property_type": "Data",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Advance",
- "field_name": "naming_series",
- "property": "hidden",
- "property_type": "Data",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Item",
- "field_name": "grant_commission",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "scan_barcode",
- "property": "hidden",
- "property_type": "Data",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "shipping_rule",
- "property": "hidden",
- "property_type": "Link",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "incoterm",
- "property": "hidden",
- "property_type": "Link",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Customer",
- "field_name": "dn_required",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Item",
- "field_name": "include_item_in_manufacturing",
- "property": "default",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Item",
- "field_name": "inspection_required_before_delivery",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Item",
- "field_name": "manufacturing",
- "property": "depends_on",
- "property_type": "TabBreak",
- "value": "eval:doc.is_stock_item == 0"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Applicant",
- "field_name": "status",
- "property": "options",
- "value": "Open\nReplied\nRejected\nShortlisted from Interview\nLocal Enquiry Started\nLocal Enquiry Completed\nLocal Enquiry Rejected\nLocal Enquiry Approved\nSelected\nHold\nAccepted\nTraining Completed\nJob Proposal Created\nJob Proposal Accepted\nInterview Scheduled\nInterview Ongoing\nInterview Completed\nShortlisted\nPending Document Upload\nDocument Uploaded"
- },
- {
- "doctype_or_field": "DocType",
- "doc_type": "Item",
- "property": "quick_entry",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "posting_date",
- "property": "read_only",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Leave Application",
- "field_name": "posting_date",
- "property": "read_only",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "status",
- "property": "options",
- "value": "Pending\nOpen & Approved\nRejected\nOn Hold\nCancelled"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Event",
- "field_name": "event_category",
- "property": "options",
- "value": "Event\nMeeting\nCall\nSent/Received Email\nOne to One Meeting\nOther"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Opening",
- "field_name": "location",
- "property": "hidden",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Boarding Activity",
- "field_name": "required_for_employee_creation",
- "property": "hidden",
- "property_type": "Check",
- "value":1
- },
- {
- "doctype_or_field":"DocField",
- "doc_type": "Attendance Request",
- "field_name": "reason",
- "property": "options",
- "value": "\nWork From Home\nOn Duty\nOn Deputation\nForgot to Checkin\nForgot to Checkout\nPermitted Late Arrival\nPermitted Early Exit"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Skill Assessment",
- "field_name": "rating",
- "property": "reqd",
- "property_type": "Check",
- "value":0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Skill Assessment",
- "field_name": "rating",
- "property": "read_only",
- "property_type": "Check",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee External Work History",
- "field_name": "designation",
- "property": "label",
- "value":"Designation At The Time Of Joining"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Project",
- "field_name": "expected_start_date",
- "property": "fieldtype",
- "value":"Datetime"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Project",
- "field_name": "expected_end_date",
- "property": "fieldtype",
- "value":"Datetime"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "designation",
- "property": "fetch_from",
- "property_type": "Link",
- "value":"employee_left.designation"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "department",
- "property": "fetch_from",
- "property_type": "Link",
- "value":"employee_left.department"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Performance Feedback",
- "field_name": "total_score",
- "property": "hidden",
- "property_type": "Float",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Feedback Rating",
- "field_name": "Rating",
- "property": "read_only",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Performance Feedback",
- "field_name": "feedback_ratings",
- "property": "label",
- "property_type": "Table",
- "value":"Employee Criteria"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "rate_goals_manually",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "goal_score_percentage",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "total_score",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal KRA",
- "field_name": "goal_completion",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal KRA",
- "field_name": "goal_score",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Feedback Rating",
- "field_name": "rating",
- "property": "read_only",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "goals",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "appraisal_kra",
- "property": "label",
- "property_type": "Table",
- "value":"KRA's",
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Applicant",
- "field_name": "resume_link",
- "property": "hidden",
- "property_type": "Data",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "self_ratings",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Appraisal",
- "field_name": "self_score",
- "property": "hidden",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Budget",
- "field_name": "monthly_distribution",
- "property": "hidden",
- "property_type": "Link",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "designation",
- "property": "reqd",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Vehicle",
- "field_name": "insurance_details",
- "property": "hidden",
- "property_type": "Section Break",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Interview",
- "field_name": "resume_link",
- "property": "hidden",
- "property_type": "",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "HR Settings",
- "field_name": "emp_created_by",
- "property": "depends_on",
- "property_type": "Code",
- "value": "eval: doc.employee_naming_by_department === 0 "
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Budget Account",
- "field_name": "account",
- "property": "read_only",
- "property_type": "Link",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "no_of_positions",
- "property": "reqd",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "expected_compensation",
- "property": "reqd",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "expected_compensation",
- "property": "default",
- "value": 0.0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "expected_compensation",
- "property": "mandatory_depends_on",
- "value": "eval: frappe.user_roles.includes('HR Manager')"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "expected_compensation",
- "property": "depends_on",
- "value": "eval: frappe.user_roles.includes('HR Manager')"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "employee_left",
- "property": "ignore_user_permissions",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "requested_by",
- "property": "ignore_user_permissions",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "swap_with_employee",
- "property": "ignore_user_permissions",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "start_date",
- "property": "read_only_depends_on",
- "value": "eval:doc.docstatus == 1"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "end_date",
- "property": "read_only_depends_on",
- "value": "eval:doc.docstatus == 1"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "start_date",
- "property": "allow_on_submit",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "end_date",
- "property": "allow_on_submit",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Shift Assignment",
- "field_name": "employee",
- "property": "ignore_user_permissions",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "designation",
- "property": "reqd",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "department",
- "property_type": "Check",
- "property": "reqd",
- "value": 0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "section_break_7",
- "property": "collapsible",
- "property_type": "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Job Requisition",
- "field_name": "designation",
- "property": "depends_on",
- "value": "eval: !(doc.workflow_state == 'Draft' && doc.request_for == 'New Vacancy')"
- },
- {
- "doctype_or_field": "DocType",
- "doc_type": "Job Applicant",
- "property": "show_title_field_in_link",
- "property_type" : "Check",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee",
- "field_name": "permanent_accommodation_type",
- "property": "hidden",
- "property_type": "Select",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Attendance Request",
- "field_name": "reports_to",
- "property": "ignore_user_permissions",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee",
- "field_name": "current_accommodation_type",
- "property": "hidden",
- "property_type": "Select",
- "value": 1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee",
- "field_name": "cell_number",
- "property": "label",
- "value": "Personal Mobile Number"
- },
- {
- "doctype_or_field": "DocType",
- "doc_type": "Employee Feedback Rating",
- "property": "field_order",
- "value": "[\"criteria\", \"per_weightage\", \"marks\", \"rating\"]"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Employee Feedback Rating",
- "field_name": "rating",
- "property": "in_list_view",
- "property_type": "Check",
- "value": 0
- },
- {
- "doctype_or_field": "DocType",
- "doc_type": "Job Applicant",
- "property": "show_title_field_in_link",
- "property_type" : "Check",
- "value": 1
- },
- {
- "doc_type": "Sales Order",
- "doctype_or_field": "DocField",
- "field_name": "set_warehouse",
- "property": "hidden",
- "property_type": "Link",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Sales Order",
- "field_name": "scan_barcode",
- "property": "hidden",
- "property_type": "Data",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "quotation_to",
- "property": "default",
- "property_type": "Link",
- "value":"Customer"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "quotation_to",
- "property": "read_only",
- "property_type": "Link",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "order_type",
- "property": "default",
- "property_type": "Link",
- "value":"Sales"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "order_type",
- "property": "read_only",
- "property_type": "Link",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation Item",
- "field_name": "shopping_cart_section",
- "property": "hidden",
- "property_type": "Section Break",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation Item",
- "field_name": "item_weight_details",
- "property": "hidden",
- "property_type": "Section Break",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation Item",
- "field_name": "available_quantity_section",
- "property": "hidden",
- "property_type": "Section Break",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation Item",
- "field_name": "gst_details_section",
- "property": "hidden",
- "property_type": "Section Break",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation Item",
- "field_name": "item_code",
- "property": "label",
- "property_type": "Link",
- "value":"Service Item"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Quotation",
- "field_name": "coupon_code",
- "property": "hidden",
- "property_type": "Link",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Budget",
- "field_name": "accounts",
- "property": "hidden",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Budget",
- "field_name": "accounts",
- "property": "read_only",
- "value":1
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Budget",
- "field_name": "accounts",
- "property": "reqd",
- "value":0
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Payment Entry",
- "field_name": "party_type",
- "property": "default",
- "property_type": "Link",
- "value":"Employee"
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Voucher Entry",
- "field_name": "bureau",
- "property": "in_standard_filter",
- "property_type": "Check",
- "value":1
- },
- {
- "doctype_or_field": "DocType",
- "doc_type": "Job Requisition",
- "property": "field_order",
- "value": '["workflow_state", "naming_series", "request_for", "employee_left", "relieving_date", "suggested_designation", "designation", "department", "location", "employment_type", "column_break_qkna", "no_of_positions", "expected_compensation", "reason_for_requesting", "column_break_4", "company", "status", "section_break_7", "requested_by", "requested_by_name", "column_break_10", "requested_by_dept", "requested_by_designation", "interview", "interview_rounds", "work_details", "no_of_days_off", "min_experience", "work_details_column_break", "is_work_shift_needed", "travel_required", "driving_license_needed", "license_type", "education", "min_education_qual", "reset_column", "language_proficiency", "skill_proficiency", "publish_on_job_section", "publish_on_job_opening", "timelines_tab", "posting_date", "completed_on", "column_break_15", "expected_by", "time_to_fill", "job_description_tab", "job_description_template", "job_title", "description", "suggestions", "connections_tab"]'
- },
- {
- "doctype_or_field": "DocField",
- "doc_type": "Asset",
- "field_name": "location",
- "property": "allow_on_submit",
- "value": 1
- }
- ]
+ """
+ BEAMS specific property setters that need to be added to the Customer ,Account and Supplier DocTypes
+ """
+ return [
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Customer",
+ "field_name": "disabled",
+ "property": "default",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal Template",
+ "field_name": "rating_criteria",
+ "property": "label",
+ "value": "Employee Criteria",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Feedback Rating",
+ "field_name": "rating_criteria",
+ "property": "read_only",
+ "property_type": "Table",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "status",
+ "property": "read_only",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Leave Allocation",
+ "field_name": "to_date",
+ "property": "allow_on_submit",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Customer",
+ "field_name": "disabled",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Account",
+ "field_name": "disabled",
+ "property": "default",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Account",
+ "field_name": "disabled",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Supplier",
+ "field_name": "disabled",
+ "property": "default",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Supplier",
+ "field_name": "disabled",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Advance",
+ "field_name": "purpose",
+ "property": "hidden",
+ "property_type": "Small Text",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Purchase Invoice",
+ "field_name": "update_stock",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Customer",
+ "field_name": "sales_team_tab",
+ "property": "hidden",
+ "property_type": "TabBreak",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Purchase Invoice",
+ "field_name": "is_subcontracted",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Purchase Invoice",
+ "field_name": "scan_barcode",
+ "property": "hidden",
+ "property_type": "Data",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Advance",
+ "field_name": "naming_series",
+ "property": "hidden",
+ "property_type": "Data",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Item",
+ "field_name": "grant_commission",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "scan_barcode",
+ "property": "hidden",
+ "property_type": "Data",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "shipping_rule",
+ "property": "hidden",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "incoterm",
+ "property": "hidden",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Customer",
+ "field_name": "dn_required",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Item",
+ "field_name": "include_item_in_manufacturing",
+ "property": "default",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Item",
+ "field_name": "inspection_required_before_delivery",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Item",
+ "field_name": "manufacturing",
+ "property": "depends_on",
+ "property_type": "TabBreak",
+ "value": "eval:doc.is_stock_item == 0",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Applicant",
+ "field_name": "status",
+ "property": "options",
+ "value": "Open\nReplied\nRejected\nShortlisted from Interview\nLocal Enquiry Started\nLocal Enquiry Completed\nLocal Enquiry Rejected\nLocal Enquiry Approved\nSelected\nHold\nAccepted\nTraining Completed\nJob Proposal Created\nJob Proposal Accepted\nInterview Scheduled\nInterview Ongoing\nInterview Completed\nShortlisted\nPending Document Upload\nDocument Uploaded",
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Item",
+ "property": "quick_entry",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "posting_date",
+ "property": "read_only",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Leave Application",
+ "field_name": "posting_date",
+ "property": "read_only",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "status",
+ "property": "options",
+ "value": "Pending\nOpen & Approved\nRejected\nOn Hold\nCancelled",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Event",
+ "field_name": "event_category",
+ "property": "options",
+ "value": "Event\nMeeting\nCall\nSent/Received Email\nOne to One Meeting\nOther",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Opening",
+ "field_name": "location",
+ "property": "hidden",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Boarding Activity",
+ "field_name": "required_for_employee_creation",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Attendance Request",
+ "field_name": "reason",
+ "property": "options",
+ "value": "\nWork From Home\nOn Duty\nOn Deputation\nForgot to Checkin\nForgot to Checkout\nPermitted Late Arrival\nPermitted Early Exit",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Skill Assessment",
+ "field_name": "rating",
+ "property": "reqd",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Skill Assessment",
+ "field_name": "rating",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee External Work History",
+ "field_name": "designation",
+ "property": "label",
+ "value": "Designation At The Time Of Joining",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Project",
+ "field_name": "expected_start_date",
+ "property": "fieldtype",
+ "value": "Datetime",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Project",
+ "field_name": "expected_end_date",
+ "property": "fieldtype",
+ "value": "Datetime",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "designation",
+ "property": "fetch_from",
+ "property_type": "Link",
+ "value": "employee_left.designation",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "department",
+ "property": "fetch_from",
+ "property_type": "Link",
+ "value": "employee_left.department",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Performance Feedback",
+ "field_name": "total_score",
+ "property": "hidden",
+ "property_type": "Float",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Feedback Rating",
+ "field_name": "Rating",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Performance Feedback",
+ "field_name": "feedback_ratings",
+ "property": "label",
+ "property_type": "Table",
+ "value": "Employee Criteria",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "rate_goals_manually",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "goal_score_percentage",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "total_score",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal KRA",
+ "field_name": "goal_completion",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal KRA",
+ "field_name": "goal_score",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Feedback Rating",
+ "field_name": "rating",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "goals",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "appraisal_kra",
+ "property": "label",
+ "property_type": "Table",
+ "value": "KRA's",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "designation",
+ "property": "reqd",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Applicant",
+ "field_name": "resume_link",
+ "property": "hidden",
+ "property_type": "Data",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "self_ratings",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Appraisal",
+ "field_name": "self_score",
+ "property": "hidden",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Budget",
+ "field_name": "monthly_distribution",
+ "property": "hidden",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "designation",
+ "property": "reqd",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Vehicle",
+ "field_name": "insurance_details",
+ "property": "hidden",
+ "property_type": "Section Break",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Interview",
+ "field_name": "resume_link",
+ "property": "hidden",
+ "property_type": "",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "HR Settings",
+ "field_name": "emp_created_by",
+ "property": "depends_on",
+ "property_type": "Code",
+ "value": "eval: doc.employee_naming_by_department === 0 ",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Budget Account",
+ "field_name": "account",
+ "property": "read_only",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "no_of_positions",
+ "property": "reqd",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "expected_compensation",
+ "property": "reqd",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "expected_compensation",
+ "property": "default",
+ "value": 0.0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "expected_compensation",
+ "property": "mandatory_depends_on",
+ "value": "eval: frappe.user_roles.includes('HR Manager')",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "expected_compensation",
+ "property": "depends_on",
+ "value": "eval: frappe.user_roles.includes('HR Manager')",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "employee_left",
+ "property": "ignore_user_permissions",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "requested_by",
+ "property": "ignore_user_permissions",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "swap_with_employee",
+ "property": "ignore_user_permissions",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "start_date",
+ "property": "read_only_depends_on",
+ "value": "eval:doc.docstatus == 1",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "end_date",
+ "property": "read_only_depends_on",
+ "value": "eval:doc.docstatus == 1",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "start_date",
+ "property": "allow_on_submit",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "end_date",
+ "property": "allow_on_submit",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Shift Assignment",
+ "field_name": "employee",
+ "property": "ignore_user_permissions",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "designation",
+ "property": "reqd",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "department",
+ "property": "hidden",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "department",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "department",
+ "property_type": "Check",
+ "property": "reqd",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "section_break_7",
+ "property": "collapsible",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Job Requisition",
+ "field_name": "designation",
+ "property": "depends_on",
+ "value": "eval: !(doc.workflow_state == 'Draft' && doc.request_for == 'New Vacancy')",
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Job Requisition",
+ "property": "field_order",
+ "value": '["naming_series", "request_for", "employee_left", "relieving_date", "suggested_designation", "designation", "department", "employment_type", "location", "column_break_qkna", "no_of_positions", "expected_compensation", "reason_for_requesting", "column_break_4", "company", "status", "interview", "interview_rounds", "work_details", "no_of_days_off", "work_details_column_break", "is_work_shift_needed", "travel_required", "driving_license_needed", "license_type", "education", "min_education_qual", "education_column_break", "min_experience", "reset_column", "language_proficiency", "skill_proficiency", "section_break_7", "requested_by", "requested_by_name", "column_break_10", "requested_by_dept", "requested_by_designation", "timelines_tab", "posting_date", "completed_on", "column_break_15", "expected_by", "time_to_fill", "job_description_tab", "job_description_template", "job_title", "description", "suggestions", "connections_tab"]',
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Job Applicant",
+ "property": "show_title_field_in_link",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee",
+ "field_name": "permanent_accommodation_type",
+ "property": "hidden",
+ "property_type": "Select",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Attendance Request",
+ "field_name": "reports_to",
+ "property": "ignore_user_permissions",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee",
+ "field_name": "current_accommodation_type",
+ "property": "hidden",
+ "property_type": "Select",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee",
+ "field_name": "cell_number",
+ "property": "label",
+ "value": "Personal Mobile Number",
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Employee Feedback Rating",
+ "property": "field_order",
+ "value": '["criteria", "per_weightage", "marks", "rating"]',
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Employee Feedback Rating",
+ "field_name": "rating",
+ "property": "in_list_view",
+ "property_type": "Check",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Job Applicant",
+ "property": "show_title_field_in_link",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Job Requisition",
+ "property": "field_order",
+ "value": '["basic_details_tab", "basic_information", "employee", "naming_series", "salutation", "first_name", "middle_name", "last_name", "bureau", "stringer_type", "employee_name", "column_break_9", "gender", "date_of_birth", "name_of_father", "name_of_spouse", "column_break1", "date_of_joining", "date_of_appointment", "image", "status", "training_status", "erpnext_user", "user_id", "create_user", "create_user_permission", "company_details_section", "company", "department", "employee_number", "column_break_25", "designation", "reports_to", "column_break_18", "branch", "grade", "employment_details", "job_applicant", "scheduled_confirmation_date", "column_break_32", "final_confirmation_date", "contract_end_date", "col_break_22", "notice_number_of_days", "date_of_retirement", "contact_details", "cell_number", "company_number", "column_break_40", "personal_email", "company_email", "column_break4", "prefered_contact_email", "prefered_email", "unsubscribed", "address_section", "pincode", "current_address", "landmark", "current_accommodation_type", "column_break_46", "permanent_address", "landmark_per", "permanent_accommodation_type", "emergency_contact_details", "person_to_be_contacted", "emergency_contact_name", "column_break_55", "emergency_phone_number", "emergency_phone", "column_break_19", "relation", "relation_emergency", "attendance_and_leave_details", "attendance_device_id", "leave_policy", "leave_policy_name", "column_break_44", "holiday_list", "default_shift", "approvers_section", "expense_approver", "leave_approver", "column_break_45", "shift_request_approver", "leave_approver_name", "expense_approver_name", "salary_information", "ctc", "salary_currency", "salary_mode", "salary_cb", "payroll_cost_center", "pan_number", "provident_fund_account", "bank_details_section", "bank_name", "column_break_heye", "bank_ac_no", "bank_cb", "ifsc_code", "micr_code", "iban", "nominee_details_section", "nominee_details", "personal_details", "marital_status", "aadhar_id", "no_of_children", "family_background", "column_break6", "blood_group", "health_details", "health_insurance_section", "health_insurance_provider", "health_insurance_no", "passport_details_section", "passport_number", "valid_upto", "column_break_73", "date_of_issue", "place_of_issue", "additional_information_section", "physical_disabilities", "disabilities", "marital_indebtness", "court_proceedings", "court_proceedings_details", "column_break_travel", "are_you_willing_to_travel", "in_india", "abroad", "state_restrictions_problems", "places_to_travel", "are_you_related_to_employee", "related_employee_name", "profile_tab", "bio", "educational_qualification", "education", "previous_work_experience", "external_work_history", "history_in_company", "internal_work_history", "documents_tab", "employee_documents", "exit", "resignation_letter_date", "relieving_date", "exit_interview_details", "held_on", "new_workplace", "column_break_99", "leave_encashed", "encashment_date", "feedback_section", "reason_for_leaving", "column_break_104", "feedback", "lft", "rgt", "old_parent", "connections_tab"]',
+ },
+ {
+ "doc_type": "Sales Order",
+ "doctype_or_field": "DocField",
+ "field_name": "set_warehouse",
+ "property": "hidden",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Sales Order",
+ "field_name": "scan_barcode",
+ "property": "hidden",
+ "property_type": "Data",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "quotation_to",
+ "property": "default",
+ "property_type": "Link",
+ "value": "Customer",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "quotation_to",
+ "property": "read_only",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "order_type",
+ "property": "default",
+ "property_type": "Link",
+ "value": "Sales",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "order_type",
+ "property": "read_only",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation Item",
+ "field_name": "shopping_cart_section",
+ "property": "hidden",
+ "property_type": "Section Break",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation Item",
+ "field_name": "item_weight_details",
+ "property": "hidden",
+ "property_type": "Section Break",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation Item",
+ "field_name": "available_quantity_section",
+ "property": "hidden",
+ "property_type": "Section Break",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation Item",
+ "field_name": "gst_details_section",
+ "property": "hidden",
+ "property_type": "Section Break",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation Item",
+ "field_name": "item_code",
+ "property": "label",
+ "property_type": "Link",
+ "value": "Service Item",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Quotation",
+ "field_name": "coupon_code",
+ "property": "hidden",
+ "property_type": "Link",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Budget",
+ "field_name": "accounts",
+ "property": "hidden",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Budget",
+ "field_name": "accounts",
+ "property": "read_only",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Budget",
+ "field_name": "accounts",
+ "property": "reqd",
+ "value": 0,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Payment Entry",
+ "field_name": "party_type",
+ "property": "default",
+ "property_type": "Link",
+ "value": "Employee",
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Voucher Entry",
+ "field_name": "bureau",
+ "property": "in_standard_filter",
+ "property_type": "Check",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocType",
+ "doc_type": "Job Requisition",
+ "property": "field_order",
+ "value": '["workflow_state", "naming_series", "request_for", "employee_left", "relieving_date", "suggested_designation", "designation", "department", "location", "employment_type", "column_break_qkna", "no_of_positions", "expected_compensation", "reason_for_requesting", "column_break_4", "company", "status", "section_break_7", "requested_by", "requested_by_name", "column_break_10", "requested_by_dept", "requested_by_designation", "interview", "interview_rounds", "work_details", "no_of_days_off", "min_experience", "work_details_column_break", "is_work_shift_needed", "travel_required", "driving_license_needed", "license_type", "education", "min_education_qual", "reset_column", "language_proficiency", "skill_proficiency", "publish_on_job_section", "publish_on_job_opening", "timelines_tab", "posting_date", "completed_on", "column_break_15", "expected_by", "time_to_fill", "job_description_tab", "job_description_template", "job_title", "description", "suggestions", "connections_tab"]',
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Asset",
+ "field_name": "location",
+ "property": "allow_on_submit",
+ "value": 1,
+ },
+ {
+ "doctype_or_field": "DocField",
+ "doc_type": "Voucher Entry",
+ "field_name": "total_amount",
+ "property": "read_only",
+ "property_type": "Check",
+ "value": 1,
+ },
+ ]
+
def get_material_request_custom_fields():
- '''
- Custom fields that need to be added to the Material Request Doctype
- '''
- return {
- "Material Request": [
- {
- "fieldname": "budget_exceeded",
- "fieldtype": "Check",
- "label": "Budget Exceeded",
- "insert_after": "schedule_date",
- "read_only":1,
- "no_copy":1,
- "depends_on": "eval:doc.budget_exceeded == 1"
-
- },
- {
- "fieldname": "requested_by",
- "fieldtype": "Link",
- "label": "Requested By",
- "insert_after": "material_request_type",
- "options": "Employee"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Material Request Doctype
+ """
+ return {
+ "Material Request": [
+ {
+ "fieldname": "budget_exceeded",
+ "fieldtype": "Check",
+ "label": "Budget Exceeded",
+ "insert_after": "schedule_date",
+ "read_only": 1,
+ "no_copy": 1,
+ "depends_on": "eval:doc.budget_exceeded == 1",
+ },
+ {
+ "fieldname": "requested_by",
+ "fieldtype": "Link",
+ "label": "Requested By",
+ "insert_after": "material_request_type",
+ "options": "Employee",
+ },
+ ]
+ }
+
def get_sales_order_custom_fields():
- '''
- Custom fields that need to be added to the Sales Order Doctype
- '''
- return {
- "Sales Order": [
- {
- "fieldname": "sales_type",
- "fieldtype": "Link",
- "label": "Sales Type",
- "insert_after": "naming_series",
- "options": "Sales Type"
- },
- {
- "fieldname": "actual_customer",
- "fieldtype": "Link",
- "label": "Actual Customer",
- "options": "Customer",
- "depends_on": "eval:doc.is_agent == 1",
- "insert_after": "is_agent"
- },
- {
- "fieldname": "is_agent",
- "fieldtype": "Check",
- "label": "Is Agency",
- "read_only":1,
- "fetch_from": "customer.is_agent",
- "depends_on": "eval:doc.is_agent",
- "insert_after": "customer"
- },
- {
- "fieldname": "actual_customer_group",
- "fieldtype": "Link",
- "label": "Actual Customer Group",
- "options": "Customer Group",
- "read_only": 1,
- "fetch_from": "actual_customer.customer_group",
- "insert_after": "actual_customer"
- },
- {
- "fieldname": "include_in_ibf",
- "fieldtype": "Check",
- "label": "Include in IBF",
- "read_only": 1,
- "insert_after": "actual_customer_group"
- },
- {
- "fieldname": "region",
- "fieldtype": "Link",
- "label": "Region",
- "options": "Region",
- "insert_after": "is_reverse_charge"
- },
- {
- "fieldname": "executive",
- "fieldtype": "Link",
- "label": "Executive",
- "options": "Employee",
- "insert_after": "delivery_date"
- },
- {
- "fieldname": "executive_name",
- "fieldtype": "Data",
- "label": "Executive Name",
- "fetch_from": "executive.employee_name",
- "insert_after": "executive",
- "read_only": 1
- },
- {
- "fieldname": "is_barter_invoice",
- "fieldtype": "Check",
- "label": "Is Barter Invoice",
- "read_only": 1,
- "insert_after": "include_in_ibf",
- "fetch_from": "reference_id.is_barter"
- },
- {
- "fieldname": "reference_id",
- "fieldtype": "Link",
- "options":"Quotation",
- "label": "Quotation",
- "read_only":1,
- "insert_after": "naming_series"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Sales Order Doctype
+ """
+ return {
+ "Sales Order": [
+ {
+ "fieldname": "sales_type",
+ "fieldtype": "Link",
+ "label": "Sales Type",
+ "insert_after": "naming_series",
+ "options": "Sales Type",
+ },
+ {
+ "fieldname": "actual_customer",
+ "fieldtype": "Link",
+ "label": "Actual Customer",
+ "options": "Customer",
+ "depends_on": "eval:doc.is_agent == 1",
+ "insert_after": "is_agent",
+ },
+ {
+ "fieldname": "is_agent",
+ "fieldtype": "Check",
+ "label": "Is Agency",
+ "read_only": 1,
+ "fetch_from": "customer.is_agent",
+ "depends_on": "eval:doc.is_agent",
+ "insert_after": "customer",
+ },
+ {
+ "fieldname": "actual_customer_group",
+ "fieldtype": "Link",
+ "label": "Actual Customer Group",
+ "options": "Customer Group",
+ "read_only": 1,
+ "fetch_from": "actual_customer.customer_group",
+ "insert_after": "actual_customer",
+ },
+ {
+ "fieldname": "include_in_ibf",
+ "fieldtype": "Check",
+ "label": "Include in IBF",
+ "read_only": 1,
+ "insert_after": "actual_customer_group",
+ },
+ {
+ "fieldname": "region",
+ "fieldtype": "Link",
+ "label": "Region",
+ "options": "Region",
+ "insert_after": "is_reverse_charge",
+ },
+ {
+ "fieldname": "executive",
+ "fieldtype": "Link",
+ "label": "Executive",
+ "options": "Employee",
+ "insert_after": "delivery_date",
+ },
+ {
+ "fieldname": "executive_name",
+ "fieldtype": "Data",
+ "label": "Executive Name",
+ "fetch_from": "executive.employee_name",
+ "insert_after": "executive",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "is_barter_invoice",
+ "fieldtype": "Check",
+ "label": "Is Barter Invoice",
+ "read_only": 1,
+ "insert_after": "include_in_ibf",
+ "fetch_from": "reference_id.is_barter",
+ },
+ {
+ "fieldname": "reference_id",
+ "fieldtype": "Link",
+ "options": "Quotation",
+ "label": "Quotation",
+ "read_only": 1,
+ "insert_after": "naming_series",
+ },
+ ]
+ }
+
def get_employee_advance_custom_fields():
- '''
- Custom fields that need to be added to the Employee Advance Doctype
- '''
- return {
- "Employee Advance": [
- {
- "fieldname": "purpose",
- "fieldtype": "Link",
- "label": "Purpose",
- "options": "Employee Advance Purpose",
- "insert_after":"currency"
- },
- {
- "fieldname": "purpose",
- "fieldtype": "Link",
- "label": "Purpose",
- "options": "Employee Advance Purpose",
- "insert_after": "currency",
- "reqd": 1
- }
-
- ]
- }
+ """
+ Custom fields that need to be added to the Employee Advance Doctype
+ """
+ return {
+ "Employee Advance": [
+ {
+ "fieldname": "purpose",
+ "fieldtype": "Link",
+ "label": "Purpose",
+ "options": "Employee Advance Purpose",
+ "insert_after": "currency",
+ },
+ {
+ "fieldname": "purpose",
+ "fieldtype": "Link",
+ "label": "Purpose",
+ "options": "Employee Advance Purpose",
+ "insert_after": "currency",
+ "reqd": 1,
+ },
+ ]
+ }
+
def get_journal_entry_custom_fields():
- '''
- Custom fields that need to be added to the Journal Entry Doctype.
- '''
- return {
- "Journal Entry": [
- {
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "label": "Cost Center",
- "read_only": 1,
- "options": "Cost Center",
- "in_list_view": 1,
- "insert_after": "naming_series"
- },
- {
- "fieldname": "batta_claim_reference",
- "fieldtype": "Link",
- "label": "Batta Claim Reference",
- "read_only": 1,
- "options": "Batta Claim",
- "insert_after": "voucher_type"
- },
- {
- "fieldname": "substitute_booking_reference",
- "fieldtype": "Link",
- "label": "Substitute Booking Reference",
- "read_only": 1,
- "options": "Substitute Booking",
- "insert_after": "batta_claim_reference"
- },
- {
- "fieldname": "employee_travel_request",
- "fieldtype": "Link",
- "label": "Employee Travel Request",
- "options": "Employee Travel Request",
- "insert_after":"posting_date",
- "read_only": 1
- }
-
- ]
- }
+ """
+ Custom fields that need to be added to the Journal Entry Doctype.
+ """
+ return {
+ "Journal Entry": [
+ {
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "label": "Cost Center",
+ "read_only": 1,
+ "options": "Cost Center",
+ "in_list_view": 1,
+ "insert_after": "naming_series",
+ },
+ {
+ "fieldname": "batta_claim_reference",
+ "fieldtype": "Link",
+ "label": "Batta Claim Reference",
+ "read_only": 1,
+ "options": "Batta Claim",
+ "insert_after": "voucher_type",
+ },
+ {
+ "fieldname": "substitute_booking_reference",
+ "fieldtype": "Link",
+ "label": "Substitute Booking Reference",
+ "read_only": 1,
+ "options": "Substitute Booking",
+ "insert_after": "batta_claim_reference",
+ },
+ {
+ "fieldname": "employee_travel_request",
+ "fieldtype": "Link",
+ "label": "Employee Travel Request",
+ "options": "Employee Travel Request",
+ "insert_after": "posting_date",
+ "read_only": 1,
+ },
+ ]
+ }
+
def create_custom_roles(roles):
- '''
- Method to create custom Role
- args:
- roles : Role List (list of string)
- example:
- ["HOD", "Manager"]
- '''
- for role in roles:
- if not frappe.db.exists("Role", role):
- role_doc = frappe.get_doc({
- "doctype": "Role",
- "role_name": role
- })
- role_doc.insert(ignore_permissions=True)
- frappe.db.commit()
+ """
+ Method to create custom Role
+ args:
+ roles : Role List (list of string)
+ example:
+ ["HOD", "Manager"]
+ """
+ for role in roles:
+ if not frappe.db.exists("Role", role):
+ role_doc = frappe.get_doc({"doctype": "Role", "role_name": role})
+ role_doc.insert(ignore_permissions=True)
+ frappe.db.commit()
+
def create_translations(translations):
- for translation in translations:
- if not frappe.db.exists(translation):
- frappe.get_doc(translation).insert(ignore_permissions=True)
- frappe.db.commit()
+ for translation in translations:
+ if not frappe.db.exists(translation):
+ frappe.get_doc(translation).insert(ignore_permissions=True)
+ frappe.db.commit()
+
def create_email_templates(email_templates):
- '''
- Method to Create Email Template
- args:
- email_templates : Email Template List
- '''
- for email_template in email_templates:
- if not frappe.db.exists('Email Template', email_template.get('name')):
- frappe.get_doc(email_template).insert(ignore_permissions=True)
- frappe.db.commit()
+ """
+ Method to Create Email Template
+ args:
+ email_templates : Email Template List
+ """
+ for email_template in email_templates:
+ if not frappe.db.exists("Email Template", email_template.get("name")):
+ frappe.get_doc(email_template).insert(ignore_permissions=True)
+ frappe.db.commit()
+
def get_interview_feedback_custom_fields():
- '''
- Custom fields that need to be added to the Interview Feedback
- '''
- return {
- "Interview Feedback": [
- {
- "fieldname": "interview_question_result",
- "label": "Interview Question Result",
- "fieldtype": "Table",
- "options": "Interview Question Result",
- "insert_after": "skill_assessment"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Interview Feedback
+ """
+ return {
+ "Interview Feedback": [
+ {
+ "fieldname": "interview_question_result",
+ "label": "Interview Question Result",
+ "fieldtype": "Table",
+ "options": "Interview Question Result",
+ "insert_after": "skill_assessment",
+ }
+ ]
+ }
+
def get_skill_assessment_custom_fields():
- '''
- Custom fields that need to be added to the Skill Assessment Child Table
- '''
- return {
- "Skill Assessment": [
- {
- "fieldname": "score",
- "fieldtype": "Float",
- "label": "Score (Out of 10)",
- "reqd": 1,
- "insert_after":"skill",
- "in_list_view": 1
- },
- {
- "fieldname": "remarks",
- "fieldtype": "Small Text",
- "label": "Remarks",
- "insert_after":"score"
- },
- {
- "fieldname": "weight",
- "fieldtype": "Float",
- "label": "Weight",
- "insert_after":"remarks"
- }
-
- ]
- }
+ """
+ Custom fields that need to be added to the Skill Assessment Child Table
+ """
+ return {
+ "Skill Assessment": [
+ {
+ "fieldname": "score",
+ "fieldtype": "Float",
+ "label": "Score (Out of 10)",
+ "reqd": 1,
+ "insert_after": "skill",
+ "in_list_view": 1,
+ },
+ {
+ "fieldname": "remarks",
+ "fieldtype": "Small Text",
+ "label": "Remarks",
+ "insert_after": "score",
+ },
+ {
+ "fieldname": "weight",
+ "fieldtype": "Float",
+ "label": "Weight",
+ "insert_after": "remarks",
+ },
+ ]
+ }
+
def get_training_event_employee_custom_fields():
- '''
- Custom fields to be added to the Training Event Employee Doctype
- '''
- return {
- "Training Event Employee": [
- {
- "fieldname": "training_request",
- "fieldtype": "Link",
- "label": "Training Request",
- "options": "Training Request",
- "insert_after": "employee_name",
- "in_list_view": 1,
- "width": 2
- }
- ]
- }
+ """
+ Custom fields to be added to the Training Event Employee Doctype
+ """
+ return {
+ "Training Event Employee": [
+ {
+ "fieldname": "training_request",
+ "fieldtype": "Link",
+ "label": "Training Request",
+ "options": "Training Request",
+ "insert_after": "employee_name",
+ "in_list_view": 1,
+ "width": 2,
+ }
+ ]
+ }
+
def get_beams_roles():
- '''
- Method to get BEAMS specific roles
- '''
- return ['Production Manager', 'CEO', 'Company Secretary', 'HOD','Enquiry Officer','Enquiry Manager','Shift Publisher','Program Producer','Operations Head','Operations User','Admin','Driver','Budget User','Technical Store Head','Budget Verifier','Budget Verifier Finance','Budget Approver','Admin User','Bureau User','Coordinating Editor','News Coordinator','Security']
+ """
+ Method to get BEAMS specific roles
+ """
+ return [
+ "Production Manager",
+ "CEO",
+ "Company Secretary",
+ "HOD",
+ "Enquiry Officer",
+ "Enquiry Manager",
+ "Shift Publisher",
+ "Program Producer",
+ "Operations Head",
+ "Operations User",
+ "Admin",
+ "Driver",
+ "Budget User",
+ "Technical Store Head",
+ "Budget Verifier",
+ "Budget Verifier Finance",
+ "Budget Approver",
+ "Admin User",
+ "Bureau User",
+ "Coordinating Editor",
+ "News Coordinator",
+ "Security",
+ ]
+
def get_custom_translations():
- '''
- Method to get Translations
- '''
- return [
- {
- 'doctype': 'Translation',
- 'source_text': 'Quotation To',
- 'translated_text': 'Release Order To',
- 'language': 'en'
- },
- {
- 'doctype': 'Translation',
- 'source_text': 'Quotation',
- 'translated_text': 'Release Order',
- 'language': 'en'
- },
- {
- 'doctype': 'Translation',
- 'source_text':'Attendance Request',
- 'translated_text':'Attendance Regularisation',
- 'language':'en'
- }
- ]
+ """
+ Method to get Translations
+ """
+ return [
+ {
+ "doctype": "Translation",
+ "source_text": "Quotation To",
+ "translated_text": "Release Order To",
+ "language": "en",
+ },
+ {
+ "doctype": "Translation",
+ "source_text": "Quotation",
+ "translated_text": "Release Order",
+ "language": "en",
+ },
+ {
+ "doctype": "Translation",
+ "source_text": "Attendance Request",
+ "translated_text": "Attendance Regularisation",
+ "language": "en",
+ },
+ ]
+
def get_email_templates():
- '''
- Method to get Email Templates
- '''
- return [
- {
- 'doctype': 'Email Template',
- 'name': 'Job Applicant Follow Up',
- 'subject': "{{applicant_name}}, Complete your Application",
- 'response': """Dear {{ applicant_name }},
- We're excited to move forward with your application!
- To continue, please upload the required documents by clicking the link: Click Here.
- Thank you for your interest in joining us!
- If you have any questions, feel free to reach out.
- Best regards,
- HR Manager"""
- }
-]
+ """
+ Method to get Email Templates
+ """
+ return [
+ {
+ "doctype": "Email Template",
+ "name": "Job Applicant Follow Up",
+ "subject": "{{applicant_name}}, Complete your Application",
+ "response": """Dear {{ applicant_name }},
+ We're excited to move forward with your application!
+ To continue, please upload the required documents by clicking the link: Click Here.
+ Thank you for your interest in joining us!
+ If you have any questions, feel free to reach out.
+ Best regards,
+ HR Manager""",
+ }
+ ]
+
def get_employment_type():
- '''
- Custom fields to be added to the Employment Type Doctype
- '''
- return {
- "Employment Type": [
- {
- "fieldname": "notice_period",
- "fieldtype": "Int",
- "label": "Notice Period",
- "insert_after": "employment_type"
- }
- ]
- }
+ """
+ Custom fields to be added to the Employment Type Doctype
+ """
+ return {
+ "Employment Type": [
+ {
+ "fieldname": "notice_period",
+ "fieldtype": "Int",
+ "label": "Notice Period",
+ "insert_after": "employment_type",
+ }
+ ]
+ }
+
def get_appointment_letter():
- '''
- Custom fields that need to be added to the Appointment Letter DocType
- '''
- return {
- "Appointment Letter": [
- {
- "fieldname": "notice_period",
- "fieldtype": "Int",
- "label": "Notice Period",
- "insert_after": "applicant_name"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Appointment Letter DocType
+ """
+ return {
+ "Appointment Letter": [
+ {
+ "fieldname": "notice_period",
+ "fieldtype": "Int",
+ "label": "Notice Period",
+ "insert_after": "applicant_name",
+ }
+ ]
+ }
+
def get_vehicle_custom_fields():
- '''
- Custom fields that need to be added to the Vehicle DocType
- '''
- return {
- "Vehicle": [
- {
- "fieldname": "vehicle_section_break",
- "fieldtype": "Section Break",
- "label": "Vehicle Details",
- "insert_after": "doors"
- },
- {
- "fieldname": "vehicle_documents",
- "fieldtype": "Table",
- "label": "Vehicle Documents",
- "options": "Vehicle Documents",
- "insert_after": "vehicle_section_break"
- },
- {
- "fieldname": "vehicle_safety_inspection",
- "fieldtype": "Link",
- "label": "Vehicle Safety Inspection",
- "options": "Vehicle Safety Inspection",
- "insert_after": "carbon_check_date"
- }
-
- ]
- }
+ """
+ Custom fields that need to be added to the Vehicle DocType
+ """
+ return {
+ "Vehicle": [
+ {
+ "fieldname": "vehicle_section_break",
+ "fieldtype": "Section Break",
+ "label": "Vehicle Details",
+ "insert_after": "doors",
+ },
+ {
+ "fieldname": "vehicle_documents",
+ "fieldtype": "Table",
+ "label": "Vehicle Documents",
+ "options": "Vehicle Documents",
+ "insert_after": "vehicle_section_break",
+ },
+ {
+ "fieldname": "vehicle_safety_inspection",
+ "fieldtype": "Link",
+ "label": "Vehicle Safety Inspection",
+ "options": "Vehicle Safety Inspection",
+ "insert_after": "carbon_check_date",
+ },
+ ]
+ }
+
def get_hr_settings_custom_fields():
- '''
- Custom fields that need to be added to the HR Settings DocType
- '''
- return {
- "HR Settings": [
- {
- "fieldname": "employee_naming_by_department",
- "fieldtype": "Check",
- "label": "Employee Naming By Department",
- "insert_after": "employee_settings"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the HR Settings DocType
+ """
+ return {
+ "HR Settings": [
+ {
+ "fieldname": "employee_naming_by_department",
+ "fieldtype": "Check",
+ "label": "Employee Naming By Department",
+ "insert_after": "employee_settings",
+ }
+ ]
+ }
+
+
def get_asset_movement_custom_fields():
- '''
- Custom fields that need to be added to the Asset Movement DocType
- '''
- return {
- "Asset Movement": [
- {
- "fieldname": "new_custodian",
- "fieldtype": "Link",
- "label": "New Custodian",
- "options": "Employee",
- "insert_after": "assets",
- "read_only": 1
- },
- {
- "fieldname": "user_id",
- "label": "User ID",
- "fieldtype": "Data",
- "insert_after": "new_custodian",
- "options": "Email",
- "read_only": 1
- }
- ],
- "Asset Movement Item": [
- {
- "fieldname": "room",
- "fieldtype": "Link",
- "label": "Room",
- "options":"Service Unit",
- "allow_on_submit": 1,
- "insert_after": "from_employee"
- },
- {
- "fieldname": "shelf",
- "fieldtype": "Link",
- "label": "Shelf",
- "options":"Shelf",
- "allow_on_submit": 1,
- "insert_after": "room"
- },
- {
- "fieldname": "row",
- "fieldtype": "Link",
- "label": "Row",
- "options":"Row",
- "allow_on_submit": 1,
- "insert_after": "to_employee"
- },
- {
- "fieldname": "bin",
- "fieldtype": "Link",
- "label": "Bin",
- "options":"Container",
- "allow_on_submit": 1,
- "insert_after": "row"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Asset Movement DocType
+ """
+ return {
+ "Asset Movement": [
+ {
+ "fieldname": "new_custodian",
+ "fieldtype": "Link",
+ "label": "New Custodian",
+ "options": "Employee",
+ "insert_after": "assets",
+ "read_only": 1,
+ },
+ {
+ "fieldname": "user_id",
+ "label": "User ID",
+ "fieldtype": "Data",
+ "insert_after": "new_custodian",
+ "options": "Email",
+ "read_only": 1,
+ },
+ ],
+ "Asset Movement Item": [
+ {
+ "fieldname": "room",
+ "fieldtype": "Link",
+ "label": "Room",
+ "options": "Service Unit",
+ "allow_on_submit": 1,
+ "insert_after": "from_employee",
+ },
+ {
+ "fieldname": "shelf",
+ "fieldtype": "Link",
+ "label": "Shelf",
+ "options": "Shelf",
+ "allow_on_submit": 1,
+ "insert_after": "room",
+ },
+ {
+ "fieldname": "row",
+ "fieldtype": "Link",
+ "label": "Row",
+ "options": "Row",
+ "allow_on_submit": 1,
+ "insert_after": "to_employee",
+ },
+ {
+ "fieldname": "bin",
+ "fieldtype": "Link",
+ "label": "Bin",
+ "options": "Container",
+ "allow_on_submit": 1,
+ "insert_after": "row",
+ },
+ ],
+ }
+
+
def get_asset_category_custom_fields():
- '''
- Custom fields that need to be added to the Asset Category DocType
- '''
- return {
- "Asset Category": [
- {
- "fieldname": "parent_asset_category",
- "fieldtype": "Link",
- "label": "Parent Asset Category",
- "options": "Asset Category",
- "insert_after": "asset_category_name"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Asset Category DocType
+ """
+ return {
+ "Asset Category": [
+ {
+ "fieldname": "parent_asset_category",
+ "fieldtype": "Link",
+ "label": "Parent Asset Category",
+ "options": "Asset Category",
+ "insert_after": "asset_category_name",
+ }
+ ]
+ }
+
+
def get_full_and_final_statement_custom_fields():
- '''
- Custom fields that need to be added to the Full and Final Statement DocType
- '''
- return {
- "Full and Final Statement": [
- {
- "fieldname": "allocated_bundles",
- "fieldtype": "Table",
- "label": "Allocated Bundles",
- "options": "Full and Final Bundle",
- "insert_after": "assets_allocated"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Full and Final Statement DocType
+ """
+ return {
+ "Full and Final Statement": [
+ {
+ "fieldname": "allocated_bundles",
+ "fieldtype": "Table",
+ "label": "Allocated Bundles",
+ "options": "Full and Final Bundle",
+ "insert_after": "assets_allocated",
+ }
+ ]
+ }
+
def get_expense_claim_custom_fields():
- '''
- Custom fields that need to be added to the Expense Claim DocType
- '''
- return {
- "Expense Claim": [
- {
- "fieldname": "travel_request",
- "fieldtype": "Link",
- "label": "Travel Request",
- "options": "Employee Travel Request",
- "insert_after": "approval_status",
- "read_only": 1
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Expense Claim DocType
+ """
+ return {
+ "Expense Claim": [
+ {
+ "fieldname": "travel_request",
+ "fieldtype": "Link",
+ "label": "Travel Request",
+ "options": "Employee Travel Request",
+ "insert_after": "approval_status",
+ "read_only": 1,
+ }
+ ]
+ }
+
def get_expense_claim_type_custom_fields():
- '''
- Custom fields that need to be added to the Expense Claim Type DocType
- '''
- return {
- "Expense Claim Type": [
- {
- "fieldname": "vehicle_against",
- "fieldtype": "Check",
- "label": "For Vehicle Incident",
- "insert_after": "deferred_expense_account"
- }
- ]
- }
+ """
+ Custom fields that need to be added to the Expense Claim Type DocType
+ """
+ return {
+ "Expense Claim Type": [
+ {
+ "fieldname": "vehicle_against",
+ "fieldtype": "Check",
+ "label": "For Vehicle Incident",
+ "insert_after": "deferred_expense_account",
+ }
+ ]
+ }
+
def get_supplier_quotation_custom_fields():
- '''
- Custom fields that need to be added to the Supplier Quotation DocType
- '''
- return {
- "Supplier Quotation": [
- {
- "fieldname": "attach",
- "fieldtype": "Attach",
- "label": "Attachments",
- "insert_after": "base_net_total"
- }
- ]
- }
\ No newline at end of file
+ """
+ Custom fields that need to be added to the Supplier Quotation DocType
+ """
+ return {
+ "Supplier Quotation": [
+ {
+ "fieldname": "attach",
+ "fieldtype": "Attach",
+ "label": "Attachments",
+ "insert_after": "base_net_total",
+ }
+ ]
+ }
diff --git a/beams/www/job_application_upload/upload_doc.html b/beams/www/job_application_upload/upload_doc.html
index cef94f453..41f3c3069 100644
--- a/beams/www/job_application_upload/upload_doc.html
+++ b/beams/www/job_application_upload/upload_doc.html
@@ -86,7 +86,16 @@
| + | |||||||
| In India | ++ | Abroad | ++ | State Restrictions if any | ++ | ||