big update
This commit is contained in:
parent
6853950cc5
commit
992672b51b
11 changed files with 647 additions and 64 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
from custom_ui.db_utils import build_error_response, build_success_response, process_filters, process_sorting
|
from custom_ui.db_utils import build_error_response, build_success_response, process_filters, process_sorting
|
||||||
|
from custom_ui.services import DbService
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_week_bid_meetings(week_start, week_end):
|
def get_week_bid_meetings(week_start, week_end):
|
||||||
|
|
@ -66,10 +67,10 @@ def get_unscheduled_bid_meetings():
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_bid_meeting(address, notes=""):
|
def create_bid_meeting(address, notes="", company=None, contact=None):
|
||||||
"""Create a new On-Site Meeting with Unscheduled status."""
|
"""Create a new On-Site Meeting with Unscheduled status."""
|
||||||
try:
|
try:
|
||||||
print(f"DEBUG: Creating meeting with address='{address}', notes='{notes}'")
|
print(f"DEBUG: Creating meeting with address='{address}', notes='{notes}', company='{company}'")
|
||||||
|
|
||||||
# Validate address parameter
|
# Validate address parameter
|
||||||
if not address or address == "None" or not address.strip():
|
if not address or address == "None" or not address.strip():
|
||||||
|
|
@ -78,17 +79,23 @@ def create_bid_meeting(address, notes=""):
|
||||||
# Get the address document name from the full address string
|
# Get the address document name from the full address string
|
||||||
address_name = frappe.db.get_value("Address", filters={"full_address": address}, fieldname="name")
|
address_name = frappe.db.get_value("Address", filters={"full_address": address}, fieldname="name")
|
||||||
|
|
||||||
|
|
||||||
print(f"DEBUG: Address lookup result: address_name='{address_name}'")
|
print(f"DEBUG: Address lookup result: address_name='{address_name}'")
|
||||||
|
|
||||||
if not address_name:
|
if not address_name:
|
||||||
return build_error_response(f"Address '{address}' not found in the system.", 404)
|
return build_error_response(f"Address '{address}' not found in the system.", 404)
|
||||||
|
address_doc = DbService.get("Address", address_name)
|
||||||
|
|
||||||
# Create the meeting with Unscheduled status
|
# Create the meeting with Unscheduled status
|
||||||
meeting = frappe.get_doc({
|
meeting = frappe.get_doc({
|
||||||
"doctype": "On-Site Meeting",
|
"doctype": "On-Site Meeting",
|
||||||
"address": address_name,
|
"address": address_doc.name,
|
||||||
"notes": notes or "",
|
"notes": notes or "",
|
||||||
"status": "Unscheduled"
|
"status": "Unscheduled",
|
||||||
|
"company": company,
|
||||||
|
"contact": contact,
|
||||||
|
"party_type": address_doc.customer_type,
|
||||||
|
"party_name": address_doc.customer_name
|
||||||
})
|
})
|
||||||
meeting.flags.ignore_permissions = True
|
meeting.flags.ignore_permissions = True
|
||||||
meeting.insert(ignore_permissions=True)
|
meeting.insert(ignore_permissions=True)
|
||||||
|
|
@ -113,7 +120,9 @@ def update_bid_meeting(name, data):
|
||||||
"end_time": None,
|
"end_time": None,
|
||||||
"notes": None,
|
"notes": None,
|
||||||
"assigned_employee": None,
|
"assigned_employee": None,
|
||||||
"completed_by": None
|
"completed_by": None,
|
||||||
|
"contact": None,
|
||||||
|
"status": None
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,9 @@ def upsert_client(data):
|
||||||
contacts = data.get("contacts", [])
|
contacts = data.get("contacts", [])
|
||||||
|
|
||||||
# Check for existing address
|
# Check for existing address
|
||||||
|
client_doc = check_and_get_client_doc(customer_name)
|
||||||
|
if client_doc:
|
||||||
|
return build_error_response(f"Client with name '{customer_name}' already exists.", 400)
|
||||||
if address_exists(
|
if address_exists(
|
||||||
data.get("address_line1"),
|
data.get("address_line1"),
|
||||||
data.get("address_line2"),
|
data.get("address_line2"),
|
||||||
|
|
@ -268,23 +271,22 @@ def upsert_client(data):
|
||||||
return build_error_response("This address already exists. Please use a different address or search for the address to find the associated client.", 400)
|
return build_error_response("This address already exists. Please use a different address or search for the address to find the associated client.", 400)
|
||||||
|
|
||||||
# Handle customer creation/update
|
# Handle customer creation/update
|
||||||
client_doc = check_and_get_client_doc(customer_name)
|
|
||||||
if not client_doc:
|
print("#####DEBUG: Creating new lead.")
|
||||||
print("#####DEBUG: Creating new lead.")
|
customer_type = data.get("customer_type", "Individual")
|
||||||
customer_type = data.get("customer_type", "Individual")
|
primary_contact = find_primary_contact_or_throw(contacts)
|
||||||
primary_contact = find_primary_contact_or_throw(contacts)
|
lead_data = {
|
||||||
lead_data = {
|
"first_name": primary_contact.get("first_name"),
|
||||||
"first_name": primary_contact.get("first_name"),
|
"last_name": primary_contact.get("last_name"),
|
||||||
"last_name": primary_contact.get("last_name"),
|
"email_id": primary_contact.get("email"),
|
||||||
"email_id": primary_contact.get("email"),
|
"phone": primary_contact.get("phone_number"),
|
||||||
"phone": primary_contact.get("phone_number"),
|
"company": data.get("company"),
|
||||||
"company": data.get("company"),
|
"custom_customer_name": customer_name,
|
||||||
"custom_customer_name": customer_name,
|
"customer_type": customer_type
|
||||||
"customer_type": customer_type
|
}
|
||||||
}
|
if customer_type == "Company":
|
||||||
if customer_type == "Company":
|
lead_data["company_name"] = data.get("customer_name")
|
||||||
lead_data["company_name"] = data.get("customer_name")
|
client_doc = create_lead(lead_data)
|
||||||
client_doc = create_lead(lead_data)
|
|
||||||
print(f"#####DEBUG: {client_doc.doctype}:", client_doc.as_dict())
|
print(f"#####DEBUG: {client_doc.doctype}:", client_doc.as_dict())
|
||||||
|
|
||||||
# Handle address creation
|
# Handle address creation
|
||||||
|
|
@ -295,7 +297,9 @@ def upsert_client(data):
|
||||||
"city": data.get("city"),
|
"city": data.get("city"),
|
||||||
"state": data.get("state"),
|
"state": data.get("state"),
|
||||||
"country": "United States",
|
"country": "United States",
|
||||||
"pincode": data.get("pincode")
|
"pincode": data.get("pincode"),
|
||||||
|
"customer_type": "Lead",
|
||||||
|
"customer_name": client_doc.name
|
||||||
})
|
})
|
||||||
|
|
||||||
#Handle contact creation
|
#Handle contact creation
|
||||||
|
|
@ -330,24 +334,24 @@ def upsert_client(data):
|
||||||
})
|
})
|
||||||
contact_docs.append(contact_doc)
|
contact_docs.append(contact_doc)
|
||||||
|
|
||||||
##### Create links
|
# ##### Create links
|
||||||
# Customer -> Address
|
# # Customer -> Address
|
||||||
if client_doc.doctype == "Customer":
|
# if client_doc.doctype == "Customer":
|
||||||
print("#####DEBUG: Linking address to customer.")
|
# print("#####DEBUG: Linking address to customer.")
|
||||||
client_doc.append("custom_select_address", {
|
# client_doc.append("custom_select_address", {
|
||||||
"address_name": address_doc.name,
|
# "address_name": address_doc.name,
|
||||||
})
|
# })
|
||||||
|
|
||||||
# Customer -> Contact
|
# # Customer -> Contact
|
||||||
print("#####DEBUG: Linking contacts to customer.")
|
# print("#####DEBUG: Linking contacts to customer.")
|
||||||
for contact_doc in contact_docs:
|
# for contact_doc in contact_docs:
|
||||||
client_doc.append("custom_add_contacts", {
|
# client_doc.append("custom_add_contacts", {
|
||||||
"contact": contact_doc.name,
|
# "contact": contact_doc.name,
|
||||||
"email": contact_doc.custom_email,
|
# "email": contact_doc.custom_email,
|
||||||
"phone": contact_doc.phone,
|
# "phone": contact_doc.phone,
|
||||||
"role": contact_doc.role
|
# "role": contact_doc.role
|
||||||
})
|
# })
|
||||||
client_doc.save(ignore_permissions=True)
|
# client_doc.save(ignore_permissions=True)
|
||||||
|
|
||||||
# Address -> Customer/Lead
|
# Address -> Customer/Lead
|
||||||
create_address_links(address_doc, client_doc, contact_docs)
|
create_address_links(address_doc, client_doc, contact_docs)
|
||||||
|
|
|
||||||
|
|
@ -111,14 +111,14 @@ def get_estimate_items():
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_estimate_from_address(full_address):
|
def get_estimate_from_address(full_address):
|
||||||
address_name = frappe.db.get_value("Address", {"full_address": full_address}, "name")
|
address_name = frappe.db.get_value("Address", {"full_address": full_address}, "name")
|
||||||
quotation_name = frappe.db.get_value("Quotation", {"custom_installation_address": address_name}, "name")
|
quotation_name = frappe.db.get_value("Quotation", {"custom_job_address": address_name}, "name")
|
||||||
quotation_doc = frappe.get_doc("Quotation", quotation_name)
|
quotation_doc = frappe.get_doc("Quotation", quotation_name)
|
||||||
return build_success_response(quotation_doc.as_dict())
|
return build_success_response(quotation_doc.as_dict())
|
||||||
# quotation = frappe.db.sql("""
|
# quotation = frappe.db.sql("""
|
||||||
# SELECT q.name, q.custom_installation_address
|
# SELECT q.name, q.custom_job_address
|
||||||
# FROM `tabQuotation` q
|
# FROM `tabQuotation` q
|
||||||
# JOIN `tabAddress` a
|
# JOIN `tabAddress` a
|
||||||
# ON q.custom_installation_address = a.name
|
# ON q.custom_job_address = a.name
|
||||||
# WHERE a.full_address =%s
|
# WHERE a.full_address =%s
|
||||||
# """, (full_address,), as_dict=True)
|
# """, (full_address,), as_dict=True)
|
||||||
# if quotation:
|
# if quotation:
|
||||||
|
|
@ -156,8 +156,8 @@ def send_estimate_email(estimate_name):
|
||||||
primary = next((e for e in party.email_ids if e.is_primary), None)
|
primary = next((e for e in party.email_ids if e.is_primary), None)
|
||||||
email = primary.email_id if primary else party.email_ids[0].email_id
|
email = primary.email_id if primary else party.email_ids[0].email_id
|
||||||
|
|
||||||
if not email and quotation.custom_installation_address:
|
if not email and quotation.custom_job_address:
|
||||||
address = frappe.get_doc("Address", quotation.custom_installation_address)
|
address = frappe.get_doc("Address", quotation.custom_job_address)
|
||||||
email = getattr(address, 'email_id', None)
|
email = getattr(address, 'email_id', None)
|
||||||
if not email:
|
if not email:
|
||||||
return build_error_response("No email found for the customer or address.", 400)
|
return build_error_response("No email found for the customer or address.", 400)
|
||||||
|
|
@ -431,7 +431,8 @@ def upsert_estimate(data):
|
||||||
"customer_address": data.get("address_name"),
|
"customer_address": data.get("address_name"),
|
||||||
"contact_person": data.get("contact_name"),
|
"contact_person": data.get("contact_name"),
|
||||||
"letter_head": data.get("company"),
|
"letter_head": data.get("company"),
|
||||||
"custom_project_template": data.get("project_template", None)
|
"custom_project_template": data.get("project_template", None),
|
||||||
|
"from_onsite_meeting": data.get("onsite_meeting", None)
|
||||||
})
|
})
|
||||||
for item in data.get("items", []):
|
for item in data.get("items", []):
|
||||||
item = json.loads(item) if isinstance(item, str) else item
|
item = json.loads(item) if isinstance(item, str) else item
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,13 @@ def create_job_from_sales_order(sales_order_name):
|
||||||
project_template = frappe.get_doc("Project Template", "SNW Install")
|
project_template = frappe.get_doc("Project Template", "SNW Install")
|
||||||
new_job = frappe.get_doc({
|
new_job = frappe.get_doc({
|
||||||
"doctype": "Project",
|
"doctype": "Project",
|
||||||
"custom_installation_address": sales_order.custom_installation_address,
|
"custom_address": sales_order.custom_job_address,
|
||||||
"project_name": sales_order.custom_installation_address,
|
# "custom_installation_address": sales_order.custom_installation_address,
|
||||||
|
"project_name": sales_order.custom_job_address,
|
||||||
"project_template": project_template,
|
"project_template": project_template,
|
||||||
"custom_warranty_duration_days": 90,
|
"custom_warranty_duration_days": 90,
|
||||||
"sales_order": sales_order
|
"sales_order": sales_order,
|
||||||
|
"custom_company": sales_order.company
|
||||||
})
|
})
|
||||||
new_job.insert()
|
new_job.insert()
|
||||||
return build_success_response(new_job.as_dict())
|
return build_success_response(new_job.as_dict())
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ def get_job_task_table_data(filters={}, sortings={}, page=1, page_size=10):
|
||||||
|
|
||||||
tableRows = []
|
tableRows = []
|
||||||
for task in tasks:
|
for task in tasks:
|
||||||
|
print("DEBUG: Processing task:", task)
|
||||||
tableRow = {}
|
tableRow = {}
|
||||||
tableRow["id"] = task["name"]
|
tableRow["id"] = task["name"]
|
||||||
tableRow["subject"] = task["subject"]
|
tableRow["subject"] = task["subject"]
|
||||||
|
|
|
||||||
7
custom_ui/events/task.py
Normal file
7
custom_ui/events/task.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def before_insert(doc, method):
|
||||||
|
"""Set values before inserting a Task."""
|
||||||
|
project_doc = frappe.get_doc("Project", doc.project)
|
||||||
|
if project_doc.custom_installation_address:
|
||||||
|
doc.custom_property = project_doc.custom_installation_address
|
||||||
|
|
@ -562,8 +562,8 @@
|
||||||
"make_attachments_public": 0,
|
"make_attachments_public": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": null,
|
"menu_index": null,
|
||||||
"migration_hash": "d5c5525a76e0cba00a479f83d71ac74c",
|
"migration_hash": "1db94a5f84dbbad8602c84d9153a9ce5",
|
||||||
"modified": "2026-01-09 09:08:21.281081",
|
"modified": "2026-01-13 03:06:43.486249",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation Template",
|
"name": "Quotation Template",
|
||||||
"naming_rule": "",
|
"naming_rule": "",
|
||||||
|
|
@ -1060,8 +1060,8 @@
|
||||||
"make_attachments_public": 0,
|
"make_attachments_public": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": null,
|
"menu_index": null,
|
||||||
"migration_hash": "d5c5525a76e0cba00a479f83d71ac74c",
|
"migration_hash": "1db94a5f84dbbad8602c84d9153a9ce5",
|
||||||
"modified": "2026-01-09 08:52:19.818789",
|
"modified": "2026-01-13 03:06:43.578733",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation Template Item",
|
"name": "Quotation Template Item",
|
||||||
"naming_rule": "",
|
"naming_rule": "",
|
||||||
|
|
@ -1098,5 +1098,467 @@
|
||||||
"track_views": 0,
|
"track_views": 0,
|
||||||
"translated_doctype": 0,
|
"translated_doctype": 0,
|
||||||
"website_search_field": null
|
"website_search_field": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_assign": null,
|
||||||
|
"_comments": null,
|
||||||
|
"_last_update": null,
|
||||||
|
"_liked_by": null,
|
||||||
|
"_user_tags": null,
|
||||||
|
"actions": [],
|
||||||
|
"allow_auto_repeat": 0,
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"app": null,
|
||||||
|
"autoname": null,
|
||||||
|
"beta": 0,
|
||||||
|
"color": null,
|
||||||
|
"colour": null,
|
||||||
|
"custom": 1,
|
||||||
|
"default_email_template": null,
|
||||||
|
"default_print_format": null,
|
||||||
|
"default_view": null,
|
||||||
|
"description": null,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"documentation": null,
|
||||||
|
"editable_grid": 1,
|
||||||
|
"email_append_to": 0,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"collapsible_depends_on": null,
|
||||||
|
"columns": 0,
|
||||||
|
"default": null,
|
||||||
|
"depends_on": null,
|
||||||
|
"description": null,
|
||||||
|
"documentation_url": null,
|
||||||
|
"fetch_from": null,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_flvp",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"hide_border": 0,
|
||||||
|
"hide_days": 0,
|
||||||
|
"hide_seconds": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_preview": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"label": null,
|
||||||
|
"length": 0,
|
||||||
|
"link_filters": null,
|
||||||
|
"make_attachment_public": 0,
|
||||||
|
"mandatory_depends_on": null,
|
||||||
|
"max_height": null,
|
||||||
|
"no_copy": 0,
|
||||||
|
"non_negative": 0,
|
||||||
|
"oldfieldname": null,
|
||||||
|
"oldfieldtype": null,
|
||||||
|
"options": null,
|
||||||
|
"parent": "Customer Company Link",
|
||||||
|
"parentfield": "fields",
|
||||||
|
"parenttype": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"placeholder": null,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"print_width": null,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_depends_on": null,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"show_dashboard": 0,
|
||||||
|
"show_on_timeline": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"sort_options": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"trigger": null,
|
||||||
|
"unique": 0,
|
||||||
|
"width": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"force_re_route_to_default_view": 0,
|
||||||
|
"grid_page_length": 50,
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"icon": null,
|
||||||
|
"image_field": null,
|
||||||
|
"in_create": 0,
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"is_calendar_and_gantt": 0,
|
||||||
|
"is_published_field": null,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"is_tree": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"make_attachments_public": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"menu_index": null,
|
||||||
|
"migration_hash": "1db94a5f84dbbad8602c84d9153a9ce5",
|
||||||
|
"modified": "2026-01-13 03:06:43.634983",
|
||||||
|
"module": "Custom UI",
|
||||||
|
"name": "Customer Company Link",
|
||||||
|
"naming_rule": "",
|
||||||
|
"nsm_parent_field": null,
|
||||||
|
"parent_node": null,
|
||||||
|
"permissions": [],
|
||||||
|
"print_outline": null,
|
||||||
|
"protect_attached_files": 0,
|
||||||
|
"queue_in_background": 0,
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"recipient_account_field": null,
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"route": null,
|
||||||
|
"row_format": "Dynamic",
|
||||||
|
"rows_threshold_for_grid_search": 20,
|
||||||
|
"search_fields": null,
|
||||||
|
"sender_field": null,
|
||||||
|
"sender_name_field": null,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"show_title_field_in_link": 0,
|
||||||
|
"smallicon": null,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"subject": null,
|
||||||
|
"subject_field": null,
|
||||||
|
"tag_fields": null,
|
||||||
|
"timeline_field": null,
|
||||||
|
"title_field": null,
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0,
|
||||||
|
"translated_doctype": 0,
|
||||||
|
"website_search_field": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_assign": null,
|
||||||
|
"_comments": null,
|
||||||
|
"_last_update": null,
|
||||||
|
"_liked_by": null,
|
||||||
|
"_user_tags": null,
|
||||||
|
"actions": [],
|
||||||
|
"allow_auto_repeat": 0,
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"app": null,
|
||||||
|
"autoname": null,
|
||||||
|
"beta": 0,
|
||||||
|
"color": null,
|
||||||
|
"colour": null,
|
||||||
|
"custom": 1,
|
||||||
|
"default_email_template": null,
|
||||||
|
"default_print_format": null,
|
||||||
|
"default_view": null,
|
||||||
|
"description": null,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"documentation": null,
|
||||||
|
"editable_grid": 1,
|
||||||
|
"email_append_to": 0,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"collapsible_depends_on": null,
|
||||||
|
"columns": 0,
|
||||||
|
"default": null,
|
||||||
|
"depends_on": null,
|
||||||
|
"description": null,
|
||||||
|
"documentation_url": null,
|
||||||
|
"fetch_from": null,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "address",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"hide_border": 0,
|
||||||
|
"hide_days": 0,
|
||||||
|
"hide_seconds": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_preview": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"label": "Address",
|
||||||
|
"length": 0,
|
||||||
|
"link_filters": null,
|
||||||
|
"make_attachment_public": 0,
|
||||||
|
"mandatory_depends_on": null,
|
||||||
|
"max_height": null,
|
||||||
|
"no_copy": 0,
|
||||||
|
"non_negative": 0,
|
||||||
|
"oldfieldname": null,
|
||||||
|
"oldfieldtype": null,
|
||||||
|
"options": "Address",
|
||||||
|
"parent": "Customer Address Link",
|
||||||
|
"parentfield": "fields",
|
||||||
|
"parenttype": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"placeholder": null,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"print_width": null,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_depends_on": null,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"show_dashboard": 0,
|
||||||
|
"show_on_timeline": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"sort_options": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"trigger": null,
|
||||||
|
"unique": 0,
|
||||||
|
"width": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"force_re_route_to_default_view": 0,
|
||||||
|
"grid_page_length": 50,
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"icon": null,
|
||||||
|
"image_field": null,
|
||||||
|
"in_create": 0,
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"is_calendar_and_gantt": 0,
|
||||||
|
"is_published_field": null,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"is_tree": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"make_attachments_public": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"menu_index": null,
|
||||||
|
"migration_hash": null,
|
||||||
|
"modified": "2026-01-13 04:04:51.277600",
|
||||||
|
"module": "Custom UI",
|
||||||
|
"name": "Customer Address Link",
|
||||||
|
"naming_rule": "",
|
||||||
|
"nsm_parent_field": null,
|
||||||
|
"parent_node": null,
|
||||||
|
"permissions": [],
|
||||||
|
"print_outline": null,
|
||||||
|
"protect_attached_files": 0,
|
||||||
|
"queue_in_background": 0,
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"recipient_account_field": null,
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"route": null,
|
||||||
|
"row_format": "Dynamic",
|
||||||
|
"rows_threshold_for_grid_search": 20,
|
||||||
|
"search_fields": null,
|
||||||
|
"sender_field": null,
|
||||||
|
"sender_name_field": null,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"show_title_field_in_link": 0,
|
||||||
|
"smallicon": null,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"subject": null,
|
||||||
|
"subject_field": null,
|
||||||
|
"tag_fields": null,
|
||||||
|
"timeline_field": null,
|
||||||
|
"title_field": null,
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0,
|
||||||
|
"translated_doctype": 0,
|
||||||
|
"website_search_field": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_assign": null,
|
||||||
|
"_comments": null,
|
||||||
|
"_last_update": null,
|
||||||
|
"_liked_by": null,
|
||||||
|
"_user_tags": null,
|
||||||
|
"actions": [],
|
||||||
|
"allow_auto_repeat": 0,
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"app": null,
|
||||||
|
"autoname": null,
|
||||||
|
"beta": 0,
|
||||||
|
"color": null,
|
||||||
|
"colour": null,
|
||||||
|
"custom": 1,
|
||||||
|
"default_email_template": null,
|
||||||
|
"default_print_format": null,
|
||||||
|
"default_view": null,
|
||||||
|
"description": null,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"documentation": null,
|
||||||
|
"editable_grid": 1,
|
||||||
|
"email_append_to": 0,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"collapsible_depends_on": null,
|
||||||
|
"columns": 0,
|
||||||
|
"default": null,
|
||||||
|
"depends_on": null,
|
||||||
|
"description": null,
|
||||||
|
"documentation_url": null,
|
||||||
|
"fetch_from": null,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "contact",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"hide_border": 0,
|
||||||
|
"hide_days": 0,
|
||||||
|
"hide_seconds": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_preview": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"label": "Contact",
|
||||||
|
"length": 0,
|
||||||
|
"link_filters": null,
|
||||||
|
"make_attachment_public": 0,
|
||||||
|
"mandatory_depends_on": null,
|
||||||
|
"max_height": null,
|
||||||
|
"no_copy": 0,
|
||||||
|
"non_negative": 0,
|
||||||
|
"oldfieldname": null,
|
||||||
|
"oldfieldtype": null,
|
||||||
|
"options": "Contact",
|
||||||
|
"parent": "Customer Contact Link",
|
||||||
|
"parentfield": "fields",
|
||||||
|
"parenttype": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"placeholder": null,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"print_width": null,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_depends_on": null,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"show_dashboard": 0,
|
||||||
|
"show_on_timeline": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"sort_options": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"trigger": null,
|
||||||
|
"unique": 0,
|
||||||
|
"width": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"force_re_route_to_default_view": 0,
|
||||||
|
"grid_page_length": 50,
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"icon": null,
|
||||||
|
"image_field": null,
|
||||||
|
"in_create": 0,
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"is_calendar_and_gantt": 0,
|
||||||
|
"is_published_field": null,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"is_tree": 0,
|
||||||
|
"is_virtual": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"make_attachments_public": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"menu_index": null,
|
||||||
|
"migration_hash": null,
|
||||||
|
"modified": "2026-01-13 04:06:36.339054",
|
||||||
|
"module": "Custom UI",
|
||||||
|
"name": "Customer Contact Link",
|
||||||
|
"naming_rule": "",
|
||||||
|
"nsm_parent_field": null,
|
||||||
|
"parent_node": null,
|
||||||
|
"permissions": [],
|
||||||
|
"print_outline": null,
|
||||||
|
"protect_attached_files": 0,
|
||||||
|
"queue_in_background": 0,
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"recipient_account_field": null,
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"route": null,
|
||||||
|
"row_format": "Dynamic",
|
||||||
|
"rows_threshold_for_grid_search": 20,
|
||||||
|
"search_fields": null,
|
||||||
|
"sender_field": null,
|
||||||
|
"sender_name_field": null,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"show_preview_popup": 0,
|
||||||
|
"show_title_field_in_link": 0,
|
||||||
|
"smallicon": null,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"subject": null,
|
||||||
|
"subject_field": null,
|
||||||
|
"tag_fields": null,
|
||||||
|
"timeline_field": null,
|
||||||
|
"title_field": null,
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0,
|
||||||
|
"translated_doctype": 0,
|
||||||
|
"website_search_field": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -174,6 +174,9 @@ doc_events = {
|
||||||
},
|
},
|
||||||
"Sales Order": {
|
"Sales Order": {
|
||||||
"on_submit": "custom_ui.events.sales_order.on_submit",
|
"on_submit": "custom_ui.events.sales_order.on_submit",
|
||||||
|
},
|
||||||
|
"Task": {
|
||||||
|
"before_insert": "custom_ui.events.task.before_insert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,7 +186,10 @@ fixtures = [
|
||||||
"filters": [
|
"filters": [
|
||||||
["name", "in", [
|
["name", "in", [
|
||||||
"Quotation Template",
|
"Quotation Template",
|
||||||
"Quotation Template Item"
|
"Quotation Template Item",
|
||||||
|
"Customer Company Link",
|
||||||
|
"Customer Address Link",
|
||||||
|
"Customer Contact Link"
|
||||||
]]
|
]]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,36 @@ def add_custom_fields():
|
||||||
print("\n🔧 Adding custom fields to doctypes...")
|
print("\n🔧 Adding custom fields to doctypes...")
|
||||||
|
|
||||||
custom_fields = {
|
custom_fields = {
|
||||||
|
"Customer": [
|
||||||
|
dict(
|
||||||
|
fieldname="companies",
|
||||||
|
label="Companies",
|
||||||
|
fieldtype="Table",
|
||||||
|
options="Customer Company Link",
|
||||||
|
insert_after="customer_type"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="from_lead",
|
||||||
|
label="From Lead",
|
||||||
|
fieldname="Link",
|
||||||
|
options="Lead",
|
||||||
|
insert_after="customer_name"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="properties",
|
||||||
|
label="Properties",
|
||||||
|
fieldtype="Table",
|
||||||
|
options="Customer Address Link",
|
||||||
|
insert_after="customer_name"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="contacts",
|
||||||
|
label="Contacts",
|
||||||
|
fieldtype="Table",
|
||||||
|
options="Customer Contact Link",
|
||||||
|
insert_after="properties"
|
||||||
|
)
|
||||||
|
],
|
||||||
"Lead": [
|
"Lead": [
|
||||||
dict(
|
dict(
|
||||||
fieldname="customer_type",
|
fieldname="customer_type",
|
||||||
|
|
@ -139,6 +169,20 @@ def add_custom_fields():
|
||||||
label="Lead Name",
|
label="Lead Name",
|
||||||
fieldtype="Data",
|
fieldtype="Data",
|
||||||
insert_after="custom_customer_to_bill"
|
insert_after="custom_customer_to_bill"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="customer_type",
|
||||||
|
label="Customer Type",
|
||||||
|
fieldtype="Select",
|
||||||
|
options="Customer\nLead",
|
||||||
|
insert_after="lead_name"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="customer_name",
|
||||||
|
label="Customer Name",
|
||||||
|
fieldtype="Dynamic Link",
|
||||||
|
options="customer_type",
|
||||||
|
insert_after="customer_type"
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"Contact": [
|
"Contact": [
|
||||||
|
|
@ -185,6 +229,34 @@ def add_custom_fields():
|
||||||
fieldtype="Link",
|
fieldtype="Link",
|
||||||
options="Employee",
|
options="Employee",
|
||||||
insert_after="status"
|
insert_after="status"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="company",
|
||||||
|
label="Company",
|
||||||
|
fieldtype="Link",
|
||||||
|
options="Company",
|
||||||
|
insert_after="assigned_employee"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="party_type",
|
||||||
|
label="Party Type",
|
||||||
|
fieldtype="Select",
|
||||||
|
options="Customer\nLead",
|
||||||
|
insert_after="company"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="party_name",
|
||||||
|
label="Party Name",
|
||||||
|
fieldtype="Dynamic Link",
|
||||||
|
options="party_type",
|
||||||
|
insert_after="party_type"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="contact",
|
||||||
|
label="Contact",
|
||||||
|
fieldtype="Link",
|
||||||
|
options="Contact",
|
||||||
|
insert_after="party_name"
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"Quotation": [
|
"Quotation": [
|
||||||
|
|
@ -220,6 +292,13 @@ def add_custom_fields():
|
||||||
insert_after="custom_installation_address",
|
insert_after="custom_installation_address",
|
||||||
description="The address where the job will be performed.",
|
description="The address where the job will be performed.",
|
||||||
allow_on_submit=1
|
allow_on_submit=1
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="from_onsite_meeting",
|
||||||
|
label="From On-Site Meeting",
|
||||||
|
fieldtype="Link",
|
||||||
|
options="On-Site Meeting",
|
||||||
|
insert_after="custom_job_address"
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"Sales Order": [
|
"Sales Order": [
|
||||||
|
|
@ -357,10 +436,12 @@ def update_address_fields():
|
||||||
quotations = frappe.get_all("Quotation", pluck="name")
|
quotations = frappe.get_all("Quotation", pluck="name")
|
||||||
addresses = frappe.get_all("Address", pluck="name")
|
addresses = frappe.get_all("Address", pluck="name")
|
||||||
sales_orders = frappe.get_all("Sales Order", pluck="name")
|
sales_orders = frappe.get_all("Sales Order", pluck="name")
|
||||||
|
tasks = frappe.get_all("Task", pluck="name")
|
||||||
total_addresses = len(addresses)
|
total_addresses = len(addresses)
|
||||||
total_quotations = len(quotations)
|
total_quotations = len(quotations)
|
||||||
total_sales_orders = len(sales_orders)
|
total_sales_orders = len(sales_orders)
|
||||||
total_doctypes = total_addresses + total_quotations + total_sales_orders
|
total_tasks = len(tasks)
|
||||||
|
total_doctypes = total_addresses + total_quotations + total_sales_orders + total_tasks
|
||||||
combined_doctypes = []
|
combined_doctypes = []
|
||||||
for sales_order in sales_orders:
|
for sales_order in sales_orders:
|
||||||
combined_doctypes.append({"doctype": "Sales Order", "name": sales_order})
|
combined_doctypes.append({"doctype": "Sales Order", "name": sales_order})
|
||||||
|
|
@ -368,9 +449,10 @@ def update_address_fields():
|
||||||
combined_doctypes.append({"doctype": "Quotation", "name": quotation})
|
combined_doctypes.append({"doctype": "Quotation", "name": quotation})
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
combined_doctypes.append({"doctype": "Address", "name": address})
|
combined_doctypes.append({"doctype": "Address", "name": address})
|
||||||
|
for task in tasks:
|
||||||
|
combined_doctypes.append({"doctype": "Task", "name": task})
|
||||||
|
|
||||||
|
print(f"\n📍 Updating field values for {total_addresses} addresses, {total_quotations} quotations, {total_sales_orders} sales orders, and {total_tasks} tasks...")
|
||||||
print(f"\n📍 Updating field values for {total_addresses} addresses, {total_quotations} quotations, and {total_sales_orders} sales orders...")
|
|
||||||
|
|
||||||
# Field update counters
|
# Field update counters
|
||||||
field_counters = {
|
field_counters = {
|
||||||
|
|
@ -389,7 +471,8 @@ def update_address_fields():
|
||||||
'quotations_updated': 0,
|
'quotations_updated': 0,
|
||||||
'sales_orders_updated': 0,
|
'sales_orders_updated': 0,
|
||||||
'customers_updated': 0,
|
'customers_updated': 0,
|
||||||
'contacts_updated': 0
|
'contacts_updated': 0,
|
||||||
|
'tasks_updated': 0
|
||||||
}
|
}
|
||||||
|
|
||||||
onsite_meta = frappe.get_meta("On-Site Meeting")
|
onsite_meta = frappe.get_meta("On-Site Meeting")
|
||||||
|
|
@ -553,7 +636,16 @@ def update_address_fields():
|
||||||
address_doc.save(ignore_permissions=True)
|
address_doc.save(ignore_permissions=True)
|
||||||
field_counters['address_linked_to_customer'] += 1
|
field_counters['address_linked_to_customer'] += 1
|
||||||
field_counters['total_field_updates'] += 1
|
field_counters['total_field_updates'] += 1
|
||||||
|
if doc['doctype'] == "Task":
|
||||||
|
for task_name in tasks:
|
||||||
|
property = frappe.get_value("Task", task_name, "custom_property")
|
||||||
|
project = frappe.get_value("Task", task_name, "project")
|
||||||
|
project_address = frappe.get_value("Project", project, "custom_installation_address")
|
||||||
|
alt_project_address = frappe.get_value("Project", project, "custom_address")
|
||||||
|
if project_address or alt_project_address:
|
||||||
|
frappe.db.set_value("Task", task_name, "custom_property", project_address if project_address else alt_project_address)
|
||||||
|
field_counters['tasks_updated'] += 1
|
||||||
|
field_counters['total_field_updates'] += 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -570,6 +662,7 @@ def update_address_fields():
|
||||||
print(f" • Sales Orders updated: {field_counters['sales_orders_updated']:,}")
|
print(f" • Sales Orders updated: {field_counters['sales_orders_updated']:,}")
|
||||||
print(f" • Customers updated: {field_counters['customers_updated']:,}")
|
print(f" • Customers updated: {field_counters['customers_updated']:,}")
|
||||||
print(f" • Total field updates: {field_counters['total_field_updates']:,}")
|
print(f" • Total field updates: {field_counters['total_field_updates']:,}")
|
||||||
|
print(f" • Tasks Updated: {field_counters['tasks_updated']:,}")
|
||||||
print(f"\n📝 Field-specific updates:")
|
print(f"\n📝 Field-specific updates:")
|
||||||
print(f" • Full Address: {field_counters['full_address']:,}")
|
print(f" • Full Address: {field_counters['full_address']:,}")
|
||||||
print(f" • On-Site Meeting Status: {field_counters['custom_onsite_meeting_scheduled']:,}")
|
print(f" • On-Site Meeting Status: {field_counters['custom_onsite_meeting_scheduled']:,}")
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,3 @@ class AddressService:
|
||||||
print("DEBUG: Created new Address:", address.as_dict())
|
print("DEBUG: Created new Address:", address.as_dict())
|
||||||
return address
|
return address
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ const FRAPPE_GET_JOB_TASK_LIST_METHOD = "custom_ui.api.db.jobs.get_job_task_tabl
|
||||||
const FRAPPE_GET_INSTALL_PROJECTS_METHOD = "custom_ui.api.db.jobs.get_install_projects";
|
const FRAPPE_GET_INSTALL_PROJECTS_METHOD = "custom_ui.api.db.jobs.get_install_projects";
|
||||||
const FRAPPE_GET_JOB_TEMPLATES_METHOD = "custom_ui.api.db.jobs.get_job_templates";
|
const FRAPPE_GET_JOB_TEMPLATES_METHOD = "custom_ui.api.db.jobs.get_job_templates";
|
||||||
// Task methods
|
// Task methods
|
||||||
const FRAPPE_GET_TASKS_METHOD = "custom_ui.api.db.tasks.get_tasks_table_data";
|
const FRAPPE_GET_TASKS_METHOD = "custom_ui.api.db.tasks.get_job_task_table_data";
|
||||||
// Invoice methods
|
// Invoice methods
|
||||||
const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data";
|
const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data";
|
||||||
const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice";
|
const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue