update calendar
This commit is contained in:
parent
7395d3e048
commit
e67805c01f
10 changed files with 848 additions and 325 deletions
|
|
@ -404,7 +404,7 @@ def upsert_estimate(data):
|
|||
# estimate.custom_job_address = data.get("address_name")
|
||||
# estimate.party_name = data.get("customer")
|
||||
# estimate.contact_person = data.get("contact_name")
|
||||
estimate.custom_requires_half_payment = data.get("requires_half_payment", 0)
|
||||
estimate.requires_half_payment = data.get("requires_half_payment", 0)
|
||||
estimate.custom_project_template = project_template
|
||||
estimate.custom_quotation_template = data.get("quotation_template", None)
|
||||
# estimate.company = data.get("company")
|
||||
|
|
@ -427,6 +427,7 @@ def upsert_estimate(data):
|
|||
})
|
||||
|
||||
estimate.save()
|
||||
frappe.db.commit()
|
||||
estimate_dict = estimate.as_dict()
|
||||
estimate_dict["history"] = get_doc_history("Quotation", estimate_name)
|
||||
print(f"DEBUG: Estimate updated: {estimate.name}")
|
||||
|
|
@ -444,7 +445,7 @@ def upsert_estimate(data):
|
|||
# print("DEBUG: No billing address found for client:", client_doc.name)
|
||||
new_estimate = frappe.get_doc({
|
||||
"doctype": "Quotation",
|
||||
"custom_requires_half_payment": data.get("requires_half_payment", 0),
|
||||
"requires_half_payment": data.get("requires_half_payment", 0),
|
||||
"custom_job_address": data.get("address_name"),
|
||||
"custom_current_status": "Draft",
|
||||
"contact_email": data.get("contact_email"),
|
||||
|
|
|
|||
|
|
@ -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 custom_ui.services import AddressService, ClientService
|
||||
from frappe.utils import getdate
|
||||
|
||||
# ===============================================================================
|
||||
# JOB MANAGEMENT API METHODS
|
||||
|
|
@ -177,21 +178,26 @@ def upsert_job(data):
|
|||
return {"status": "error", "message": str(e)}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_projects_for_calendar(date, company=None, project_templates=[]):
|
||||
def get_projects_for_calendar(start_date, end_date, company=None, project_templates=[]):
|
||||
"""Get install projects for the calendar."""
|
||||
# Parse project_templates if it's a JSON string
|
||||
if isinstance(project_templates, str):
|
||||
project_templates = json.loads(project_templates)
|
||||
|
||||
# put some emojis in the print to make it stand out
|
||||
print("📅📅📅", date, "company:", company, "project_templates:", project_templates, "type:", type(project_templates))
|
||||
print("📅📅📅", start_date, end_date, " company:", company, "project_templates:", project_templates, "type:", type(project_templates))
|
||||
try:
|
||||
filters = {"company": company} if company else {}
|
||||
filters = {
|
||||
"company": company
|
||||
} if company else {}
|
||||
if project_templates and len(project_templates) > 0:
|
||||
filters["project_template"] = ["in", project_templates]
|
||||
unscheduled_filters = filters.copy()
|
||||
unscheduled_filters["is_scheduled"] = 0
|
||||
filters["expected_start_date"] = date
|
||||
|
||||
# add to filter for if expected_start_date is between start_date and end_date OR expected_end_date is between start_date and end_date
|
||||
filters["expected_start_date"] = ["<=", getdate(end_date)]
|
||||
filters["expected_end_date"] = [">=", getdate(start_date)]
|
||||
# If date range provided, we could filter, but for now let's fetch all open/active ones
|
||||
# or maybe filter by status not Closed/Completed if we want active ones.
|
||||
# The user said "unscheduled" are those with status "Open" (and no date).
|
||||
|
|
@ -206,3 +212,22 @@ def get_projects_for_calendar(date, company=None, project_templates=[]):
|
|||
return build_success_response({ "projects": projects, "unscheduled_projects": unscheduled_projects })
|
||||
except Exception as e:
|
||||
return build_error_response(str(e), 500)
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_job_scheduled_dates(job_name: str, new_start_date: str = None, new_end_date: str = None, foreman_name: str = None):
|
||||
"""Update job (project) schedule dates."""
|
||||
print("DEBUG: Updating job schedule:", job_name, new_start_date, new_end_date, foreman_name)
|
||||
try:
|
||||
project = frappe.get_doc("Project", job_name)
|
||||
project.expected_start_date = getdate(new_start_date) if new_start_date else None
|
||||
project.expected_end_date = getdate(new_end_date) if new_end_date else None
|
||||
if new_start_date and new_end_date:
|
||||
project.is_scheduled = 1
|
||||
else:
|
||||
project.is_scheduled = 0
|
||||
if foreman_name:
|
||||
project.custom_foreman = foreman_name
|
||||
project.save()
|
||||
return build_success_response(project.as_dict())
|
||||
except Exception as e:
|
||||
return build_error_response(str(e), 500)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import frappe
|
||||
from custom_ui.services import AddressService, ClientService
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
def after_insert(doc, method):
|
||||
print("DEBUG: After Insert Triggered for Project")
|
||||
|
|
@ -30,8 +30,13 @@ def before_insert(doc, method):
|
|||
def before_save(doc, method):
|
||||
print("DEBUG: Before Save Triggered for Project:", doc.name)
|
||||
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
|
||||
else:
|
||||
while frappe.db.exists("Holiday", {"holiday_date": doc.expected_end_date}):
|
||||
print("DEBUG: Expected end date falls on a holiday, extending end date by 1 day")
|
||||
doc.expected_end_date += timedelta(days=1)
|
||||
elif not doc.expected_start_date or not doc.expected_end_date:
|
||||
print("DEBUG: Project missing expected start or end date, marking as unscheduled")
|
||||
doc.is_scheduled = 0
|
||||
|
||||
def after_save(doc, method):
|
||||
|
|
@ -44,8 +49,10 @@ def after_save(doc, method):
|
|||
"Closed": "Completed"
|
||||
}
|
||||
new_status = status_mapping.get(doc.status, "In Progress")
|
||||
AddressService.update_value(
|
||||
doc.job_address,
|
||||
"job_status",
|
||||
new_status
|
||||
)
|
||||
if frappe.db.get_value("Address", doc.job_address, "job_status") != new_status:
|
||||
print("DEBUG: Updating Address job_status to:", new_status)
|
||||
AddressService.update_value(
|
||||
doc.job_address,
|
||||
"job_status",
|
||||
new_status
|
||||
)
|
||||
|
|
@ -178,8 +178,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": null,
|
||||
"modified": "2026-01-19 18:10:16.782664",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:39.681180",
|
||||
"module": "Custom UI",
|
||||
"name": "Customer Task Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -396,8 +396,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": null,
|
||||
"modified": "2026-01-19 18:10:02.359022",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:39.752798",
|
||||
"module": "Custom UI",
|
||||
"name": "Address Task Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -550,8 +550,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.097017",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:39.827207",
|
||||
"module": "Custom",
|
||||
"name": "Lead Companies Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -768,8 +768,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.150584",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:39.914772",
|
||||
"module": "Custom",
|
||||
"name": "Address Project Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -986,8 +986,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.203403",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.049882",
|
||||
"module": "Custom",
|
||||
"name": "Address Quotation Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1204,8 +1204,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.255846",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.145083",
|
||||
"module": "Custom",
|
||||
"name": "Address On-Site Meeting Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1422,8 +1422,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.309600",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.270888",
|
||||
"module": "Custom",
|
||||
"name": "Address Sales Order Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1576,8 +1576,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.361237",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.346187",
|
||||
"module": "Custom",
|
||||
"name": "Contact Address Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -1730,8 +1730,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.412683",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.418889",
|
||||
"module": "Custom",
|
||||
"name": "Lead On-Site Meeting Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -2332,8 +2332,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.483924",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.507246",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Template",
|
||||
"naming_rule": "",
|
||||
|
|
@ -2830,8 +2830,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.558008",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.595751",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Template Item",
|
||||
"naming_rule": "",
|
||||
|
|
@ -2984,8 +2984,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.609372",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.676141",
|
||||
"module": "Custom UI",
|
||||
"name": "Customer Company Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3138,8 +3138,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.660893",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.749303",
|
||||
"module": "Custom UI",
|
||||
"name": "Customer Address Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3292,8 +3292,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.712878",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.836296",
|
||||
"module": "Custom UI",
|
||||
"name": "Customer Contact Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3446,8 +3446,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.765849",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.900156",
|
||||
"module": "Custom",
|
||||
"name": "Address Contact Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3600,8 +3600,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.818352",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:40.986399",
|
||||
"module": "Custom",
|
||||
"name": "Customer On-Site Meeting Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3754,8 +3754,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.870984",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.054749",
|
||||
"module": "Custom",
|
||||
"name": "Customer Project Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -3908,8 +3908,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.922695",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.114144",
|
||||
"module": "Custom",
|
||||
"name": "Customer Quotation Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -4062,8 +4062,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:17.975165",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.170115",
|
||||
"module": "Custom",
|
||||
"name": "Customer Sales Order Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -4216,8 +4216,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:18.027046",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.226997",
|
||||
"module": "Custom",
|
||||
"name": "Lead Address Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -4370,8 +4370,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:18.078476",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.283969",
|
||||
"module": "Custom",
|
||||
"name": "Lead Contact Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -4524,8 +4524,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:18.170095",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.344731",
|
||||
"module": "Custom",
|
||||
"name": "Lead Quotation Link",
|
||||
"naming_rule": "",
|
||||
|
|
@ -4678,8 +4678,8 @@
|
|||
"make_attachments_public": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": null,
|
||||
"migration_hash": "0df0ede31f640435231ba887f40eca91",
|
||||
"modified": "2026-01-19 20:52:18.238066",
|
||||
"migration_hash": "9792f2dfc070efd283d24244c612c2d4",
|
||||
"modified": "2026-01-20 12:56:41.401007",
|
||||
"module": "Custom",
|
||||
"name": "Address Company Link",
|
||||
"naming_rule": "",
|
||||
|
|
|
|||
|
|
@ -263,7 +263,8 @@ fixtures = [
|
|||
"dt": "Property Setter",
|
||||
"filters": [
|
||||
["doc_type", "=", "Lead"],
|
||||
["doc_type", "=", "Project"]
|
||||
["doc_type", "=", "Project"],
|
||||
["doc_type", "=", "Address"]
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -598,6 +598,12 @@ def add_custom_fields():
|
|||
options="Company",
|
||||
insert_after="project_type",
|
||||
description="The company associated with this project template."
|
||||
),
|
||||
dict(
|
||||
fieldname="calendar_color",
|
||||
label="Calendar Color",
|
||||
fieldtype="Color",
|
||||
insert_after="company"
|
||||
)
|
||||
],
|
||||
"Task": [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue