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 # =============================================================================== # ESTIMATES & INVOICES API METHODS # =============================================================================== @frappe.whitelist() def get_estimate_table_data(filters={}, sortings=[], page=1, page_size=10): """Get paginated estimate table data with filtering and sorting support.""" print("DEBUG: Raw estimate options received:", filters, sortings, page, page_size) processed_filters, processed_sortings, is_or, page, page_size = process_query_conditions(filters, sortings, page, page_size) if is_or: count = frappe.db.sql(*get_count_or_filters("Quotation", processed_filters))[0][0] else: count = frappe.db.count("Quotation", filters=processed_filters) print(f"DEBUG: Number of estimates returned: {count}") estimates = frappe.db.get_all( "Quotation", fields=["*"], filters=processed_filters if not is_or else None, or_filters=processed_filters if is_or else None, limit=page_size, start=(page - 1) * page_size, order_by=processed_sortings ) tableRows = [] for estimate in estimates: tableRow = {} tableRow["id"] = estimate["name"] tableRow["name"] = estimate["name"] tableRow["quotation_to"] = estimate.get("quotation_to", "") tableRow["customer"] = estimate.get("party_name", "") tableRow["status"] = estimate.get("custom_current_status", "") tableRow["date"] = estimate.get("transaction_date", "") tableRow["order_type"] = estimate.get("order_type", "") tableRow["items"] = estimate.get("items", "") tableRows.append(tableRow) table_data_dict = build_datatable_dict(data=tableRows, count=count, page=page, page_size=page_size) return build_success_response(table_data_dict) @frappe.whitelist() def get_quotation_items(): """Get all available quotation items.""" try: items = frappe.get_all("Item", fields=["*"], filters={"item_group": "SNW-S"}) return build_success_response(items) except Exception as e: return build_error_response(str(e), 500) @frappe.whitelist() def get_estimate(estimate_name): """Get detailed information for a specific estimate.""" try: estimate = frappe.get_doc("Quotation", estimate_name) return build_success_response(estimate.as_dict()) except Exception as e: return build_error_response(str(e), 500) @frappe.whitelist() def upsert_estimate(data): """Create or update an estimate.""" # TODO: Implement estimate creation/update logic pass @frappe.whitelist() def get_estimate_items(): items = frappe.db.get_all("Quotation Item", fields=["*"]) return build_success_response(items) @frappe.whitelist() def get_estimate_from_address(full_address): quotation = frappe.db.sql(""" SELECT q.name, q.custom_installation_address FROM `tabQuotation` q JOIN `tabAddress` a ON q.custom_installation_address = a.name WHERE a.full_address =%s """, (full_address,), as_dict=True) if quotation: return build_success_response(quotation) else: return build_error_response("No quotation found for the given address.", 404) @frappe.whitelist() def upsert_estimate(data): """Create or update an estimate.""" print("DOIFJSEOFJISLFK") try: data = json.loads(data) if isinstance(data, str) else data print("DEBUG: Retrieved address name:", data.get("address_name")) new_estimate = frappe.get_doc({ "doctype": "Quotation", "custom_installation_address": data.get("address_name"), "contact_email": data.get("contact_email"), "party_name": data.get("contact_name"), "customer_name": data.get("customer_name"), }) for item in data.get("items", []): item = json.loads(item) if isinstance(item, str) else item new_estimate.append("items", { "item_code": item.get("item_code"), "qty": item.get("qty"), }) new_estimate.insert() print("DEBUG: New estimate created with name:", new_estimate.name) return build_success_response(new_estimate.as_dict()) except Exception as e: return build_error_response(str(e), 500)