multiple bid meetings for one cell, final invoice flow.
This commit is contained in:
parent
b3e6e4f6a2
commit
caa4bc2dca
21 changed files with 1132 additions and 1551 deletions
|
|
@ -534,7 +534,7 @@ def upsert_estimate(data):
|
|||
# ClientService.append_link(data.get("customer"), "quotations", "quotation", new_estimate.name)
|
||||
print("DEBUG: New estimate created with name:", new_estimate.name)
|
||||
dict = new_estimate.as_dict()
|
||||
dict["items"] = [ItemService.get_full_dict(item.item_code) for item in new_estimate.items]
|
||||
dict["items"] = [{**ItemService.get_full_dict(item.item_code), **item} for item in new_estimate.items]
|
||||
return build_success_response(dict)
|
||||
except Exception as e:
|
||||
print(f"DEBUG: Error in upsert_estimate: {str(e)}")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import frappe, json
|
||||
from custom_ui.db_utils import process_query_conditions, build_datatable_dict, get_count_or_filters, build_success_response, build_error_response
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||
from custom_ui.services import SalesOrderService, EmailService
|
||||
|
||||
# ===============================================================================
|
||||
# INVOICES API METHODS
|
||||
|
|
@ -10,15 +11,40 @@ from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
|||
@frappe.whitelist()
|
||||
def create_invoice_for_job(job_name):
|
||||
"""Create the invoice from a sales order of a job."""
|
||||
print("DEBUG: create_invoice_for_job called with job_name:", job_name)
|
||||
try:
|
||||
project = frappe.get_doc("Project", job_name)
|
||||
sales_order = project.sales_order
|
||||
invoice = make_sales_invoice(sales_order)
|
||||
invoice.save()
|
||||
sales_order = frappe.get_value("Project", job_name, "sales_order")
|
||||
if not sales_order:
|
||||
return build_error_response("No sales order found for this job.", 404)
|
||||
invoice = SalesOrderService.create_sales_invoice_from_sales_order(sales_order)
|
||||
return build_success_response(invoice.as_dict())
|
||||
except Exception as e:
|
||||
return build_error_response(str(e), 500)
|
||||
|
||||
@frappe.whitelist()
|
||||
def submit_and_send_invoice(invoice_name):
|
||||
"""Submit the invoice and send email to customer."""
|
||||
print("DEBUG: submit_and_send_invoice called with invoice_name:", invoice_name)
|
||||
try:
|
||||
invoice_doc = frappe.get_doc("Sales Invoice", invoice_name)
|
||||
if invoice_doc.docstatus == 0:
|
||||
print("DEBUG: Submitting invoice:", invoice_name)
|
||||
invoice_doc.submit()
|
||||
else:
|
||||
print("DEBUG: Invoice already submitted:", invoice_name)
|
||||
# Send invoice email to customer
|
||||
try:
|
||||
print("DEBUG: Preparing to send invoice email for", invoice_name)
|
||||
EmailService.send_invoice_email(invoice_name)
|
||||
print("DEBUG: Invoice email sent successfully for", invoice_name)
|
||||
frappe.set_value("Project", invoice_doc.project, "invoice_status", "Invoice Sent")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to send invoice email: {str(e)}")
|
||||
# Don't raise the exception - we don't want to block the invoice submission
|
||||
frappe.log_error(f"Failed to send invoice email for {invoice_name}: {str(e)}", "Invoice Email Error")
|
||||
return build_success_response(invoice_doc.as_dict())
|
||||
except Exception as e:
|
||||
return build_error_response(str(e), 500)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_invoices_late_count():
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from datetime import datetime
|
|||
from frappe.utils.data import flt
|
||||
from custom_ui.services import DbService, StripeService, PaymentService
|
||||
from custom_ui.models import PaymentData
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def half_down_stripe_payment(sales_order):
|
||||
|
|
@ -36,7 +37,11 @@ def invoice_stripe_payment(sales_invoice):
|
|||
if si.docstatus != 1:
|
||||
frappe.throw("Sales Invoice must be submitted to proceed with payment.")
|
||||
if si.outstanding_amount <= 0:
|
||||
frappe.throw("This invoice has already been paid.")
|
||||
html = frappe.render_template("custom_ui/templates/invoices/already_paid.html", {
|
||||
"invoice_number": si.name,
|
||||
"company": frappe.get_doc("Company", si.company)
|
||||
})
|
||||
return Response(html, content_type='text/html')
|
||||
stripe_session = StripeService.create_checkout_session(
|
||||
company=si.company,
|
||||
amount=si.outstanding_amount,
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ def on_update_after_submit(doc, method):
|
|||
new_sales_order.customer_address = doc.customer_address
|
||||
# new_sales_order.custom_installation_address = doc.custom_installation_address
|
||||
new_sales_order.custom_job_address = doc.custom_job_address
|
||||
new_sales_order.payment_schedule = []
|
||||
new_sales_order.set("payment_schedule", [])
|
||||
print("DEBUG: Setting payment schedule for Sales Order")
|
||||
new_sales_order.set_payment_schedule()
|
||||
# new_sales_order.set_payment_schedule()
|
||||
print("DEBUG: Inserting Sales Order:", new_sales_order.as_dict())
|
||||
new_sales_order.delivery_date = new_sales_order.transaction_date
|
||||
# backup = new_sales_order.customer_address
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ def after_insert(doc, method):
|
|||
"project_template": doc.project_template
|
||||
})
|
||||
doc.service_appointment = service_apt.name
|
||||
if doc.requires_half_payment:
|
||||
service_apt.ready_to_schedule = 0
|
||||
doc.save(ignore_permissions=True)
|
||||
print("DEBUG: Created Service Appointment:", service_apt.name)
|
||||
except Exception as e:
|
||||
|
|
@ -63,6 +65,9 @@ def before_insert(doc, method):
|
|||
def before_save(doc, method):
|
||||
print("DEBUG: Before Save Triggered for Project:", doc.name)
|
||||
print("DEBUG: Checking status: ", doc.status)
|
||||
if doc.percent_complete == 100.0 and doc.invoice_status == "Not Ready":
|
||||
print("DEBUG: Project is 100% complete and invoice status is Not Ready, setting invoice status to Ready to Invoice")
|
||||
doc.invoice_status = "Ready to Invoice"
|
||||
if doc.expected_start_date and doc.expected_end_date:
|
||||
print("DEBUG: Project has expected start and end dates, marking as scheduled")
|
||||
doc.is_scheduled = 1
|
||||
|
|
@ -82,11 +87,18 @@ def before_save(doc, method):
|
|||
|
||||
def after_save(doc, method):
|
||||
print("DEBUG: After Save Triggered for Project:", doc.name)
|
||||
if doc.status == "Completed":
|
||||
print("DEBUG: Project marked as Completed. Generating and sending final invoice.")
|
||||
sales_order_status = frappe.get_value("Sales Order", doc.sales_order, "billing_status")
|
||||
if sales_order_status == "Not Billed":
|
||||
SalesOrderService.create_sales_invoice_from_sales_order(doc.sales_order)
|
||||
if doc.ready_to_schedule and doc.service_appointment:
|
||||
service_apt_ready_to_schedule = frappe.get_value("Service Address 2", doc.service_appointment, "ready_to_schedule")
|
||||
if not service_apt_ready_to_schedule:
|
||||
print("DEBUG: Project is ready to schedule, setting Service Appointment to ready to schedule.")
|
||||
service_apt_doc = frappe.get_doc("Service Address 2", doc.service_appointment)
|
||||
service_apt_doc.ready_to_schedule = 1
|
||||
service_apt_doc.save(ignore_permissions=True)
|
||||
# if doc.status == "Completed":
|
||||
|
||||
# sales_order_status = frappe.get_value("Sales Order", doc.sales_order, "billing_status")
|
||||
# if sales_order_status == "Not Billed":
|
||||
# SalesOrderService.create_sales_invoice_from_sales_order(doc.sales_order)
|
||||
if doc.ready_to_schedule:
|
||||
service_apt_ready_to_schedule = frappe.get_value("Service Address 2", doc.service_appointment, "ready_to_schedule")
|
||||
if not service_apt_ready_to_schedule:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
import frappe
|
||||
from custom_ui.services.email_service import EmailService
|
||||
from custom_ui.services import ProjectService
|
||||
|
||||
def on_submit(doc, method):
|
||||
print("DEBUG: On Submit Triggered for Sales Invoice:", doc.name)
|
||||
|
||||
# Send invoice email to customer
|
||||
try:
|
||||
print("DEBUG: Preparing to send invoice email for", doc.name)
|
||||
EmailService.send_invoice_email(doc.name)
|
||||
print("DEBUG: Invoice email sent successfully for", doc.name)
|
||||
frappe.set_value("Project", doc.project, "invoice_status", "Invoice Sent")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to send invoice email: {str(e)}")
|
||||
# Don't raise the exception - we don't want to block the invoice submission
|
||||
frappe.log_error(f"Failed to send invoice email for {doc.name}: {str(e)}", "Invoice Email Error")
|
||||
# # Send invoice email to customer
|
||||
# try:
|
||||
# print("DEBUG: Preparing to send invoice email for", doc.name)
|
||||
# EmailService.send_invoice_email(doc.name)
|
||||
# print("DEBUG: Invoice email sent successfully for", doc.name)
|
||||
# frappe.set_value("Project", doc.project, "invoice_status", "Invoice Sent")
|
||||
# except Exception as e:
|
||||
# print(f"ERROR: Failed to send invoice email: {str(e)}")
|
||||
# # Don't raise the exception - we don't want to block the invoice submission
|
||||
# frappe.log_error(f"Failed to send invoice email for {doc.name}: {str(e)}", "Invoice Email Error")
|
||||
|
||||
def after_insert(doc, method):
|
||||
print("DEBUG: After Insert Triggered for Sales Invoice:", doc.name)
|
||||
# Additional logic can be added here if needed after invoice creation
|
||||
frappe.set_value("Project", doc.project, "invoice_status", "Invoice Created")
|
||||
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import frappe
|
||||
from custom_ui.services import DbService, AddressService, ClientService
|
||||
from custom_ui.services import DbService, AddressService, ClientService, EmailService
|
||||
|
||||
|
||||
def before_save(doc, method):
|
||||
|
|
@ -76,7 +76,6 @@ def after_insert(doc, method):
|
|||
if doc.requires_half_payment:
|
||||
try:
|
||||
print("DEBUG: Sales Order requires half payment, preparing to send down payment email")
|
||||
from custom_ui.services.email_service import EmailService
|
||||
|
||||
# Use EmailService to send the down payment email
|
||||
EmailService.send_downpayment_email(doc.name)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ from custom_ui.services import AddressService, ClientService, TaskService
|
|||
def before_insert(doc, method):
|
||||
"""Set values before inserting a Task."""
|
||||
print("DEBUG: Before Insert Triggered for Task")
|
||||
if doc.type:
|
||||
task_type_weight = frappe.get_value("Task Type", doc.type, "weight") or 0
|
||||
print(f"DEBUG: Setting Task weight to {task_type_weight} based on Task Type {doc.type}")
|
||||
doc.task_weight = task_type_weight
|
||||
if doc.status == "Template":
|
||||
print("DEBUG: Task is a Template, skipping project linking")
|
||||
return
|
||||
|
|
@ -52,11 +56,13 @@ def after_save(doc, method):
|
|||
if doc.project and doc.status == "Completed":
|
||||
print("DEBUG: Task is completed, checking if project has calculated 100% Progress.")
|
||||
project_doc = frappe.get_doc("Project", doc.project)
|
||||
if project_doc.percent_complete == 100:
|
||||
print("DEBUG: Current Project percent_complete:", project_doc.percent_complete)
|
||||
if project_doc.percent_complete == 100.0:
|
||||
print("DEBUG: Project percent_complete is 100%, checking if we need to update project status or invoice status.")
|
||||
project_update_required = False
|
||||
if project_doc.status == "Completed" and project_doc.customCompletionDate is None:
|
||||
if project_doc.status == "Completed" and project_doc.custom_completion_date is None:
|
||||
print("DEBUG: Project is marked as Completed but customCompletionDate is not set, updating customCompletionDate.")
|
||||
project_doc.customCompletionDate = frappe.utils.nowdate()
|
||||
project_doc.custom_completion_date = frappe.utils.nowdate()
|
||||
project_update_required = True
|
||||
if project_doc.invoice_status == "Not Ready":
|
||||
project_doc.invoice_status = "Ready to Invoice"
|
||||
|
|
|
|||
|
|
@ -2963,120 +2963,6 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "On-Site Meeting",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "company",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Party Type",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-13 03:06:47.189806",
|
||||
"module": null,
|
||||
"name": "On-Site Meeting-party_type",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Customer\nLead",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Customer",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "from_lead",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "customer_name",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "From Lead",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-13 04:14:35.978839",
|
||||
"module": null,
|
||||
"name": "Customer-from_lead",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Lead",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -3419,6 +3305,120 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "On-Site Meeting",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "company",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Party Type",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-13 03:06:47.189806",
|
||||
"module": null,
|
||||
"name": "On-Site Meeting-party_type",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Customer\nLead",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Customer",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "from_lead",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "customer_name",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "From Lead",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-13 03:39:42.161305",
|
||||
"module": null,
|
||||
"name": "Customer-from_lead",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Lead",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -8070,7 +8070,7 @@
|
|||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-12 02:52:42.307849",
|
||||
"modified": "2026-02-12 04:10:06.712703",
|
||||
"module": null,
|
||||
"name": "Project-requires_half_payment",
|
||||
"no_copy": 0,
|
||||
|
|
@ -8469,7 +8469,7 @@
|
|||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-12 02:52:42.394762",
|
||||
"modified": "2026-02-12 04:10:06.808397",
|
||||
"module": null,
|
||||
"name": "Project-is_half_down_paid",
|
||||
"no_copy": 0,
|
||||
|
|
@ -8754,7 +8754,7 @@
|
|||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-12 02:52:42.235665",
|
||||
"modified": "2026-02-12 04:10:06.643135",
|
||||
"module": null,
|
||||
"name": "Project-is_scheduled",
|
||||
"no_copy": 0,
|
||||
|
|
@ -10179,7 +10179,7 @@
|
|||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-12 02:52:41.808876",
|
||||
"modified": "2026-02-12 04:10:06.196780",
|
||||
"module": null,
|
||||
"name": "Address-latitude",
|
||||
"no_copy": 0,
|
||||
|
|
@ -10293,7 +10293,7 @@
|
|||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-02-12 02:52:41.924704",
|
||||
"modified": "2026-02-12 04:10:06.320979",
|
||||
"module": null,
|
||||
"name": "Address-longitude",
|
||||
"no_copy": 0,
|
||||
|
|
@ -13858,15 +13858,15 @@
|
|||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": null,
|
||||
"depends_on": "accept_payment",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "payment_button_help",
|
||||
"fieldtype": "Text",
|
||||
"fieldname": "payments_cb",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
|
|
@ -13877,16 +13877,16 @@
|
|||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "payment_button_label",
|
||||
"insert_after": "payment_button_help",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Button Help",
|
||||
"label": null,
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.256345",
|
||||
"modified": "2026-01-27 11:11:05.288776",
|
||||
"module": null,
|
||||
"name": "Web Form-payment_button_help",
|
||||
"name": "Web Form-payments_cb",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
|
|
@ -13907,63 +13907,6 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": null,
|
||||
"depends_on": "accept_payment",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "amount",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Currency",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.420470",
|
||||
"module": null,
|
||||
"name": "Web Form-currency",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Currency",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -14021,120 +13964,6 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "accept_payment",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "amount_based_on_field",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "payments_cb",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Amount Based On Field",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.321231",
|
||||
"module": null,
|
||||
"name": "Web Form-amount_based_on_field",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Order",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "exempt_from_sales_tax",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "taxes_and_charges",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Is customer exempted from sales tax?",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2024-04-03 13:53:07.674608",
|
||||
"module": null,
|
||||
"name": "Sales Order-exempt_from_sales_tax",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -14249,6 +14078,120 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": null,
|
||||
"depends_on": "accept_payment",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "amount",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Currency",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.420470",
|
||||
"module": null,
|
||||
"name": "Web Form-currency",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Currency",
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Order",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "exempt_from_sales_tax",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "taxes_and_charges",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Is customer exempted from sales tax?",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2024-04-03 13:53:07.674608",
|
||||
"module": null,
|
||||
"name": "Sales Order-exempt_from_sales_tax",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -14306,6 +14249,63 @@
|
|||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "accept_payment",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "amount_based_on_field",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "payments_cb",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": "Amount Based On Field",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.321231",
|
||||
"module": null,
|
||||
"name": "Web Form-amount_based_on_field",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
"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,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -14371,15 +14371,15 @@
|
|||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"depends_on": "accept_payment",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Web Form",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "payments_cb",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "payment_button_help",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
|
|
@ -14390,16 +14390,16 @@
|
|||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "payment_button_help",
|
||||
"insert_after": "payment_button_label",
|
||||
"is_system_generated": 1,
|
||||
"is_virtual": 0,
|
||||
"label": null,
|
||||
"label": "Button Help",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-01-27 11:11:05.288776",
|
||||
"modified": "2026-01-27 11:11:05.256345",
|
||||
"module": null,
|
||||
"name": "Web Form-payments_cb",
|
||||
"name": "Web Form-payment_button_help",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": null,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -15199,38 +15199,6 @@
|
|||
"row_name": null,
|
||||
"value": "[\"sb_01\", \"custom_column_break_g4zvy\", \"first_name\", \"custom_column_break_hpz5b\", \"middle_name\", \"custom_column_break_3pehb\", \"last_name\", \"email\", \"customer_type\", \"customer_name\", \"addresses\", \"contact_section\", \"links\", \"phone_nos\", \"email_ids\", \"custom_column_break_nfqbi\", \"is_primary_contact\", \"is_billing_contact\", \"custom_service_address\", \"user\", \"unsubscribed\", \"more_info\", \"custom_column_break_sn9hu\", \"full_name\", \"address\", \"company_name\", \"designation\", \"role\", \"department\", \"image\", \"sb_00\", \"custom_column_break_kmlkz\", \"email_id\", \"mobile_no\", \"phone\", \"status\", \"gender\", \"salutation\", \"contact_details\", \"cb_00\", \"custom_test_label\", \"google_contacts\", \"google_contacts_id\", \"sync_with_google_contacts\", \"cb00\", \"pulled_from_google_contacts\", \"custom_column_break_ejxjz\"]"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Project",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-01-26 10:42:06.682515",
|
||||
"module": null,
|
||||
"name": "Project-main-autoname",
|
||||
"property": "autoname",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "format:{project_template}-#-PRO-{#####}-{YYYY}"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Project",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-01-26 10:42:06.862234",
|
||||
"module": null,
|
||||
"name": "Project-main-field_order",
|
||||
"property": "field_order",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "[\"custom_column_break_k7sgq\", \"custom_installation_address\", \"naming_series\", \"project_name\", \"job_address\", \"status\", \"custom_warranty_duration_days\", \"custom_warranty_expiration_date\", \"custom_warranty_information\", \"project_type\", \"percent_complete_method\", \"percent_complete\", \"column_break_5\", \"project_template\", \"expected_start_date\", \"expected_start_time\", \"expected_end_date\", \"expected_end_time\", \"is_scheduled\", \"invoice_status\", \"custom_completion_date\", \"priority\", \"custom_foreman\", \"custom_hidden_fields\", \"department\", \"service_appointment\", \"tasks\", \"is_active\", \"custom_address\", \"custom_section_break_lgkpd\", \"custom_workflow_related_custom_fields__landry\", \"custom_permit_status\", \"custom_utlity_locate_status\", \"custom_crew_scheduling\", \"customer_details\", \"customer\", \"column_break_14\", \"sales_order\", \"users_section\", \"users\", \"copied_from\", \"section_break0\", \"notes\", \"section_break_18\", \"actual_start_date\", \"actual_start_time\", \"actual_time\", \"column_break_20\", \"actual_end_date\", \"actual_end_time\", \"project_details\", \"estimated_costing\", \"total_costing_amount\", \"total_expense_claim\", \"total_purchase_cost\", \"company\", \"column_break_28\", \"total_sales_amount\", \"total_billable_amount\", \"total_billed_amount\", \"total_consumed_material_cost\", \"cost_center\", \"margin\", \"gross_margin\", \"column_break_37\", \"per_gross_margin\", \"monitor_progress\", \"collect_progress\", \"holiday_list\", \"frequency\", \"from_time\", \"to_time\", \"first_email\", \"second_email\", \"daily_time_to_send\", \"day_to_send\", \"weekly_time_to_send\", \"column_break_45\", \"subject\", \"message\"]"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Sales Order",
|
||||
|
|
@ -15262,5 +15230,37 @@
|
|||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "[\"gateway_name\", \"publishable_key\", \"custom_webhook_secret\", \"column_break_3\", \"secret_key\", \"custom_company\", \"custom_account\", \"section_break_5\", \"header_img\", \"column_break_7\", \"redirect_url\"]"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Project",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-02-12 12:21:16.095851",
|
||||
"module": null,
|
||||
"name": "Project-main-autoname",
|
||||
"property": "autoname",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "format:{project_template}-{customer}-PRO-{#####}-{YYYY}"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Project",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-02-12 12:21:16.160749",
|
||||
"module": null,
|
||||
"name": "Project-main-field_order",
|
||||
"property": "field_order",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "[\"custom_column_break_k7sgq\", \"custom_installation_address\", \"naming_series\", \"project_name\", \"job_address\", \"status\", \"custom_warranty_duration_days\", \"custom_warranty_expiration_date\", \"custom_warranty_information\", \"project_type\", \"percent_complete_method\", \"percent_complete\", \"column_break_5\", \"project_template\", \"expected_start_date\", \"expected_start_time\", \"expected_end_date\", \"expected_end_time\", \"requires_half_payment\", \"is_half_down_paid\", \"is_scheduled\", \"invoice_status\", \"custom_completion_date\", \"priority\", \"custom_foreman\", \"custom_hidden_fields\", \"department\", \"service_appointment\", \"tasks\", \"ready_to_schedule\", \"is_active\", \"custom_address\", \"custom_section_break_lgkpd\", \"custom_workflow_related_custom_fields__landry\", \"custom_permit_status\", \"custom_utlity_locate_status\", \"custom_crew_scheduling\", \"customer_details\", \"customer\", \"column_break_14\", \"sales_order\", \"users_section\", \"users\", \"copied_from\", \"section_break0\", \"notes\", \"section_break_18\", \"actual_start_date\", \"actual_start_time\", \"actual_time\", \"column_break_20\", \"actual_end_date\", \"actual_end_time\", \"project_details\", \"estimated_costing\", \"total_costing_amount\", \"total_expense_claim\", \"total_purchase_cost\", \"company\", \"column_break_28\", \"total_sales_amount\", \"total_billable_amount\", \"total_billed_amount\", \"total_consumed_material_cost\", \"cost_center\", \"margin\", \"gross_margin\", \"column_break_37\", \"per_gross_margin\", \"monitor_progress\", \"collect_progress\", \"holiday_list\", \"frequency\", \"from_time\", \"to_time\", \"first_email\", \"second_email\", \"daily_time_to_send\", \"day_to_send\", \"weekly_time_to_send\", \"column_break_45\", \"subject\", \"message\"]"
|
||||
}
|
||||
]
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
"department": null,
|
||||
"depends_on": [],
|
||||
"depends_on_tasks": "",
|
||||
"description": null,
|
||||
"description": "Utility locate request prior to installation start.",
|
||||
"docstatus": 0,
|
||||
"doctype": "Task",
|
||||
"duration": 0,
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
"is_milestone": 0,
|
||||
"is_template": 1,
|
||||
"issue": null,
|
||||
"modified": "2025-04-24 14:57:03.402721",
|
||||
"modified": "2026-02-12 12:31:42.805351",
|
||||
"name": "TASK-2025-00002",
|
||||
"old_parent": "",
|
||||
"parent_task": null,
|
||||
|
|
@ -82,12 +82,12 @@
|
|||
"start": 0,
|
||||
"status": "Template",
|
||||
"subject": "811/Locate call in",
|
||||
"task_weight": 0.0,
|
||||
"task_weight": 7.0,
|
||||
"template_task": null,
|
||||
"total_billing_amount": 0.0,
|
||||
"total_costing_amount": 0.0,
|
||||
"total_expense_claim": 0.0,
|
||||
"type": "Admin"
|
||||
"type": "811/Locate"
|
||||
},
|
||||
{
|
||||
"act_end_date": null,
|
||||
|
|
@ -284,7 +284,7 @@
|
|||
"department": null,
|
||||
"depends_on": [],
|
||||
"depends_on_tasks": "",
|
||||
"description": null,
|
||||
"description": "Task tracking for the main service job.",
|
||||
"docstatus": 0,
|
||||
"doctype": "Task",
|
||||
"duration": 0,
|
||||
|
|
@ -295,7 +295,7 @@
|
|||
"is_milestone": 0,
|
||||
"is_template": 1,
|
||||
"issue": null,
|
||||
"modified": "2025-05-10 05:06:24.653035",
|
||||
"modified": "2026-02-12 12:32:42.996899",
|
||||
"name": "TASK-2025-00004",
|
||||
"old_parent": "",
|
||||
"parent_task": null,
|
||||
|
|
@ -307,12 +307,12 @@
|
|||
"start": 0,
|
||||
"status": "Template",
|
||||
"subject": "Primary Job",
|
||||
"task_weight": 0.0,
|
||||
"task_weight": 25.0,
|
||||
"template_task": null,
|
||||
"total_billing_amount": 0.0,
|
||||
"total_costing_amount": 0.0,
|
||||
"total_expense_claim": 0.0,
|
||||
"type": "Labor"
|
||||
"type": "Main Job"
|
||||
},
|
||||
{
|
||||
"act_end_date": null,
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ doc_events = {
|
|||
"before_insert": "custom_ui.events.task.before_insert",
|
||||
"after_insert": "custom_ui.events.task.after_insert",
|
||||
"before_save": "custom_ui.events.task.before_save",
|
||||
"after_save": "custom_ui.events.task.after_save"
|
||||
"on_update": "custom_ui.events.task.after_save"
|
||||
},
|
||||
"Bid Meeting Note Form": {
|
||||
"after_insert": "custom_ui.events.general.attach_bid_note_form_to_project_template"
|
||||
|
|
@ -210,7 +210,8 @@ doc_events = {
|
|||
"on_submit": "custom_ui.events.payments.on_submit"
|
||||
},
|
||||
"Sales Invoice": {
|
||||
"on_submit": "custom_ui.events.sales_invoice.on_submit"
|
||||
"on_submit": "custom_ui.events.sales_invoice.on_submit",
|
||||
"after_insert": "custom_ui.events.sales_invoice.after_insert"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -485,6 +485,12 @@ def add_custom_fields():
|
|||
default=0,
|
||||
insert_after="custom_installation_address"
|
||||
),
|
||||
dict(
|
||||
fieldname="remarks",
|
||||
label="Remarks",
|
||||
fieldtype="Small Text",
|
||||
insert_after="grand_total"
|
||||
),
|
||||
dict(
|
||||
fieldname="custom_quotation_template",
|
||||
label="Quotation Template",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ class SalesOrderService:
|
|||
def create_sales_invoice_from_sales_order(sales_order_name):
|
||||
try:
|
||||
sales_order_doc = frappe.get_doc("Sales Order", sales_order_name)
|
||||
sales_invoice = make_sales_invoice(sales_order_doc.name)
|
||||
sales_invoice = make_sales_invoice(sales_order_doc.name, ignore_permissions=True)
|
||||
print("DEBUG: Sales Invoice created from Sales Order:", sales_invoice.name)
|
||||
sales_invoice.project = sales_order_doc.project
|
||||
sales_invoice.posting_date = today()
|
||||
sales_invoice.due_date = today()
|
||||
|
|
@ -21,8 +22,9 @@ class SalesOrderService:
|
|||
sales_invoice.calculate_taxes_and_totals()
|
||||
|
||||
sales_invoice.insert()
|
||||
sales_invoice.submit()
|
||||
return sales_invoice.name
|
||||
print("DEBUG: Sales Invoice: ", sales_invoice.as_dict())
|
||||
# sales_invoice.submit()
|
||||
return sales_invoice
|
||||
except Exception as e:
|
||||
print("ERROR creating Sales Invoice from Sales Order:", str(e))
|
||||
return None
|
||||
|
|
@ -56,14 +56,17 @@ class StripeService:
|
|||
Returns:
|
||||
stripe.checkout.Session object
|
||||
"""
|
||||
print(f"DEBUG: Creating Stripe Checkout Session for company with details - Company: {company}, Amount: {amount}, Service: {service}, Order Num: {order_num}, Currency: {currency}, For Advance Payment: {for_advance_payment}, Sales Invoice: {sales_invoice}")
|
||||
stripe.api_key = StripeService.get_api_key(company)
|
||||
|
||||
# Determine payment description
|
||||
if for_advance_payment:
|
||||
description = f"Advance payment for {company}{' - ' + service if service else ''}"
|
||||
else:
|
||||
print("DEBUG: Creating description for full payment")
|
||||
description = f"Invoice payment for {company}{' - ' + service if service else ''}"
|
||||
if sales_invoice:
|
||||
print(f"DEBUG: Sales Invoice provided for full payment: {sales_invoice}")
|
||||
description = f"Invoice {sales_invoice} - {company}"
|
||||
|
||||
# Use custom line items if provided and not an advance payment, otherwise create default line item
|
||||
|
|
@ -88,7 +91,7 @@ class StripeService:
|
|||
if for_advance_payment:
|
||||
metadata["sales_order"] = order_num
|
||||
else:
|
||||
metadata["sales_invoice"] = sales_invoice or order_num
|
||||
metadata["sales_invoice"] = sales_invoice if sales_invoice else order_num
|
||||
if sales_invoice:
|
||||
# Check if there's a related sales order
|
||||
invoice_doc = frappe.get_doc("Sales Invoice", sales_invoice)
|
||||
|
|
|
|||
191
custom_ui/templates/invoices/already_paid.html
Normal file
191
custom_ui/templates/invoices/already_paid.html
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Invoice Already Paid</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.message-container {
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
padding: 50px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
max-width: 500px;
|
||||
width: 90%;
|
||||
position: relative;
|
||||
}
|
||||
.message-icon {
|
||||
font-size: 5rem;
|
||||
color: #00b894;
|
||||
margin-bottom: 30px;
|
||||
animation: checkmarkAnimation 1.5s ease-out;
|
||||
}
|
||||
|
||||
@keyframes checkmarkAnimation {
|
||||
0% {
|
||||
transform: scale(0) rotate(-180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.2) rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
transform: scale(0.9) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 20px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.invoice-number {
|
||||
background-color: #e3f2fd;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0;
|
||||
border-left: 4px solid #2196f3;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.contact-section {
|
||||
background-color: #f8f9fa;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin-top: 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.contact-section h3 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #333;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.contact-section > p {
|
||||
margin: 0 0 15px 0;
|
||||
color: #666;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.contact-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.contact-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.contact-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.contact-label {
|
||||
font-weight: 500;
|
||||
color: #495057;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.contact-value {
|
||||
font-weight: 400;
|
||||
color: #6c757d;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.contact-value a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.contact-value a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message-container">
|
||||
<div class="message-icon">✓</div>
|
||||
<h1 class="message-title">Invoice Already Paid</h1>
|
||||
<p class="message-text">This invoice has already been paid in full.</p>
|
||||
|
||||
{% if invoice_number %}
|
||||
<div class="invoice-number">
|
||||
Invoice #{{ invoice_number }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if company %}
|
||||
<div class="contact-section">
|
||||
<h3>Have Questions?</h3>
|
||||
<p>We're here to help! Contact us if you need assistance.</p>
|
||||
<div class="contact-details">
|
||||
{% if company.company_name %}
|
||||
<div class="contact-row">
|
||||
<span class="contact-label">Company:</span>
|
||||
<span class="contact-value">{{ company.company_name }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if company.phone_no %}
|
||||
<div class="contact-row">
|
||||
<span class="contact-label">Phone:</span>
|
||||
<span class="contact-value">{{ company.phone_no }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if company.email %}
|
||||
<div class="contact-row">
|
||||
<span class="contact-label">Email:</span>
|
||||
<span class="contact-value"><a href="mailto:{{ company.email }}">{{ company.email }}</a></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if company.website %}
|
||||
<div class="contact-row">
|
||||
<span class="contact-label">Website:</span>
|
||||
<span class="contact-value"><a href="{{ company.website }}" target="_blank">{{ company.website }}</a></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue