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 json
|
||||
from custom_ui.db_utils import build_error_response, build_success_response, process_filters, process_sorting
|
||||
from custom_ui.services import DbService
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_week_bid_meetings(week_start, week_end):
|
||||
|
|
@ -66,10 +67,10 @@ def get_unscheduled_bid_meetings():
|
|||
|
||||
|
||||
@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."""
|
||||
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
|
||||
if not address or address == "None" or not address.strip():
|
||||
|
|
@ -77,18 +78,24 @@ def create_bid_meeting(address, notes=""):
|
|||
|
||||
# Get the address document name from the full address string
|
||||
address_name = frappe.db.get_value("Address", filters={"full_address": address}, fieldname="name")
|
||||
|
||||
|
||||
print(f"DEBUG: Address lookup result: address_name='{address_name}'")
|
||||
|
||||
|
||||
if not address_name:
|
||||
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
|
||||
meeting = frappe.get_doc({
|
||||
"doctype": "On-Site Meeting",
|
||||
"address": address_name,
|
||||
"address": address_doc.name,
|
||||
"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.insert(ignore_permissions=True)
|
||||
|
|
@ -113,7 +120,9 @@ def update_bid_meeting(name, data):
|
|||
"end_time": None,
|
||||
"notes": None,
|
||||
"assigned_employee": None,
|
||||
"completed_by": None
|
||||
"completed_by": None,
|
||||
"contact": None,
|
||||
"status": None
|
||||
}
|
||||
try:
|
||||
if isinstance(data, str):
|
||||
|
|
|
|||
|
|
@ -258,6 +258,9 @@ def upsert_client(data):
|
|||
contacts = data.get("contacts", [])
|
||||
|
||||
# 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(
|
||||
data.get("address_line1"),
|
||||
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)
|
||||
|
||||
# Handle customer creation/update
|
||||
client_doc = check_and_get_client_doc(customer_name)
|
||||
if not client_doc:
|
||||
print("#####DEBUG: Creating new lead.")
|
||||
customer_type = data.get("customer_type", "Individual")
|
||||
primary_contact = find_primary_contact_or_throw(contacts)
|
||||
lead_data = {
|
||||
"first_name": primary_contact.get("first_name"),
|
||||
"last_name": primary_contact.get("last_name"),
|
||||
"email_id": primary_contact.get("email"),
|
||||
"phone": primary_contact.get("phone_number"),
|
||||
"company": data.get("company"),
|
||||
"custom_customer_name": customer_name,
|
||||
"customer_type": customer_type
|
||||
}
|
||||
if customer_type == "Company":
|
||||
lead_data["company_name"] = data.get("customer_name")
|
||||
client_doc = create_lead(lead_data)
|
||||
|
||||
print("#####DEBUG: Creating new lead.")
|
||||
customer_type = data.get("customer_type", "Individual")
|
||||
primary_contact = find_primary_contact_or_throw(contacts)
|
||||
lead_data = {
|
||||
"first_name": primary_contact.get("first_name"),
|
||||
"last_name": primary_contact.get("last_name"),
|
||||
"email_id": primary_contact.get("email"),
|
||||
"phone": primary_contact.get("phone_number"),
|
||||
"company": data.get("company"),
|
||||
"custom_customer_name": customer_name,
|
||||
"customer_type": customer_type
|
||||
}
|
||||
if customer_type == "Company":
|
||||
lead_data["company_name"] = data.get("customer_name")
|
||||
client_doc = create_lead(lead_data)
|
||||
print(f"#####DEBUG: {client_doc.doctype}:", client_doc.as_dict())
|
||||
|
||||
# Handle address creation
|
||||
|
|
@ -295,7 +297,9 @@ def upsert_client(data):
|
|||
"city": data.get("city"),
|
||||
"state": data.get("state"),
|
||||
"country": "United States",
|
||||
"pincode": data.get("pincode")
|
||||
"pincode": data.get("pincode"),
|
||||
"customer_type": "Lead",
|
||||
"customer_name": client_doc.name
|
||||
})
|
||||
|
||||
#Handle contact creation
|
||||
|
|
@ -330,24 +334,24 @@ def upsert_client(data):
|
|||
})
|
||||
contact_docs.append(contact_doc)
|
||||
|
||||
##### Create links
|
||||
# Customer -> Address
|
||||
if client_doc.doctype == "Customer":
|
||||
print("#####DEBUG: Linking address to customer.")
|
||||
client_doc.append("custom_select_address", {
|
||||
"address_name": address_doc.name,
|
||||
})
|
||||
# ##### Create links
|
||||
# # Customer -> Address
|
||||
# if client_doc.doctype == "Customer":
|
||||
# print("#####DEBUG: Linking address to customer.")
|
||||
# client_doc.append("custom_select_address", {
|
||||
# "address_name": address_doc.name,
|
||||
# })
|
||||
|
||||
# Customer -> Contact
|
||||
print("#####DEBUG: Linking contacts to customer.")
|
||||
for contact_doc in contact_docs:
|
||||
client_doc.append("custom_add_contacts", {
|
||||
"contact": contact_doc.name,
|
||||
"email": contact_doc.custom_email,
|
||||
"phone": contact_doc.phone,
|
||||
"role": contact_doc.role
|
||||
})
|
||||
client_doc.save(ignore_permissions=True)
|
||||
# # Customer -> Contact
|
||||
# print("#####DEBUG: Linking contacts to customer.")
|
||||
# for contact_doc in contact_docs:
|
||||
# client_doc.append("custom_add_contacts", {
|
||||
# "contact": contact_doc.name,
|
||||
# "email": contact_doc.custom_email,
|
||||
# "phone": contact_doc.phone,
|
||||
# "role": contact_doc.role
|
||||
# })
|
||||
# client_doc.save(ignore_permissions=True)
|
||||
|
||||
# Address -> Customer/Lead
|
||||
create_address_links(address_doc, client_doc, contact_docs)
|
||||
|
|
|
|||
|
|
@ -111,14 +111,14 @@ def get_estimate_items():
|
|||
@frappe.whitelist()
|
||||
def get_estimate_from_address(full_address):
|
||||
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)
|
||||
return build_success_response(quotation_doc.as_dict())
|
||||
# quotation = frappe.db.sql("""
|
||||
# SELECT q.name, q.custom_installation_address
|
||||
# SELECT q.name, q.custom_job_address
|
||||
# FROM `tabQuotation` q
|
||||
# JOIN `tabAddress` a
|
||||
# ON q.custom_installation_address = a.name
|
||||
# ON q.custom_job_address = a.name
|
||||
# WHERE a.full_address =%s
|
||||
# """, (full_address,), as_dict=True)
|
||||
# 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)
|
||||
email = primary.email_id if primary else party.email_ids[0].email_id
|
||||
|
||||
if not email and quotation.custom_installation_address:
|
||||
address = frappe.get_doc("Address", quotation.custom_installation_address)
|
||||
if not email and quotation.custom_job_address:
|
||||
address = frappe.get_doc("Address", quotation.custom_job_address)
|
||||
email = getattr(address, 'email_id', None)
|
||||
if not email:
|
||||
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"),
|
||||
"contact_person": data.get("contact_name"),
|
||||
"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", []):
|
||||
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")
|
||||
new_job = frappe.get_doc({
|
||||
"doctype": "Project",
|
||||
"custom_installation_address": sales_order.custom_installation_address,
|
||||
"project_name": sales_order.custom_installation_address,
|
||||
"custom_address": sales_order.custom_job_address,
|
||||
# "custom_installation_address": sales_order.custom_installation_address,
|
||||
"project_name": sales_order.custom_job_address,
|
||||
"project_template": project_template,
|
||||
"custom_warranty_duration_days": 90,
|
||||
"sales_order": sales_order
|
||||
"sales_order": sales_order,
|
||||
"custom_company": sales_order.company
|
||||
})
|
||||
new_job.insert()
|
||||
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 = []
|
||||
for task in tasks:
|
||||
print("DEBUG: Processing task:", task)
|
||||
tableRow = {}
|
||||
tableRow["id"] = task["name"]
|
||||
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,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "d5c5525a76e0cba00a479f83d71ac74c",
|
||||
"modified": "2026-01-09 09:08:21.281081",
|
||||
"migration_hash": "1db94a5f84dbbad8602c84d9153a9ce5",
|
||||
"modified": "2026-01-13 03:06:43.486249",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Template",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1060,8 +1060,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "d5c5525a76e0cba00a479f83d71ac74c",
|
||||
"modified": "2026-01-09 08:52:19.818789",
|
||||
"migration_hash": "1db94a5f84dbbad8602c84d9153a9ce5",
|
||||
"modified": "2026-01-13 03:06:43.578733",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Template Item",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1098,5 +1098,467 @@
|
|||
"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": "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": {
|
||||
"on_submit": "custom_ui.events.sales_order.on_submit",
|
||||
},
|
||||
"Task": {
|
||||
"before_insert": "custom_ui.events.task.before_insert"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +186,10 @@ fixtures = [
|
|||
"filters": [
|
||||
["name", "in", [
|
||||
"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...")
|
||||
|
||||
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": [
|
||||
dict(
|
||||
fieldname="customer_type",
|
||||
|
|
@ -139,6 +169,20 @@ def add_custom_fields():
|
|||
label="Lead Name",
|
||||
fieldtype="Data",
|
||||
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": [
|
||||
|
|
@ -185,6 +229,34 @@ def add_custom_fields():
|
|||
fieldtype="Link",
|
||||
options="Employee",
|
||||
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": [
|
||||
|
|
@ -220,6 +292,13 @@ def add_custom_fields():
|
|||
insert_after="custom_installation_address",
|
||||
description="The address where the job will be performed.",
|
||||
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": [
|
||||
|
|
@ -357,10 +436,12 @@ def update_address_fields():
|
|||
quotations = frappe.get_all("Quotation", pluck="name")
|
||||
addresses = frappe.get_all("Address", pluck="name")
|
||||
sales_orders = frappe.get_all("Sales Order", pluck="name")
|
||||
tasks = frappe.get_all("Task", pluck="name")
|
||||
total_addresses = len(addresses)
|
||||
total_quotations = len(quotations)
|
||||
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 = []
|
||||
for sales_order in sales_orders:
|
||||
combined_doctypes.append({"doctype": "Sales Order", "name": sales_order})
|
||||
|
|
@ -368,9 +449,10 @@ def update_address_fields():
|
|||
combined_doctypes.append({"doctype": "Quotation", "name": quotation})
|
||||
for address in addresses:
|
||||
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, and {total_sales_orders} sales orders...")
|
||||
print(f"\n📍 Updating field values for {total_addresses} addresses, {total_quotations} quotations, {total_sales_orders} sales orders, and {total_tasks} tasks...")
|
||||
|
||||
# Field update counters
|
||||
field_counters = {
|
||||
|
|
@ -389,7 +471,8 @@ def update_address_fields():
|
|||
'quotations_updated': 0,
|
||||
'sales_orders_updated': 0,
|
||||
'customers_updated': 0,
|
||||
'contacts_updated': 0
|
||||
'contacts_updated': 0,
|
||||
'tasks_updated': 0
|
||||
}
|
||||
|
||||
onsite_meta = frappe.get_meta("On-Site Meeting")
|
||||
|
|
@ -537,7 +620,7 @@ def update_address_fields():
|
|||
updates['custom_payment_received_status'] = payment_received
|
||||
field_counters['custom_payment_received_status'] += 1
|
||||
field_counters['total_field_updates'] += 1
|
||||
|
||||
|
||||
if updates:
|
||||
frappe.db.set_value("Address", doc['name'], updates)
|
||||
field_counters['addresses_updated'] += 1
|
||||
|
|
@ -553,7 +636,16 @@ def update_address_fields():
|
|||
address_doc.save(ignore_permissions=True)
|
||||
field_counters['address_linked_to_customer'] += 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" • Customers updated: {field_counters['customers_updated']:,}")
|
||||
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" • Full Address: {field_counters['full_address']:,}")
|
||||
print(f" • On-Site Meeting Status: {field_counters['custom_onsite_meeting_scheduled']:,}")
|
||||
|
|
|
|||
|
|
@ -76,6 +76,4 @@ class AddressService:
|
|||
address.insert(ignore_permissions=True)
|
||||
print("DEBUG: Created new Address:", address.as_dict())
|
||||
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_JOB_TEMPLATES_METHOD = "custom_ui.api.db.jobs.get_job_templates";
|
||||
// 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
|
||||
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";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue