"""Pricing catalog CRUD operations.""" import json, sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from lib.db import get_db, new_id, now, row_to_dict, rows_to_list def list_catalogs(): conn = get_db() rows = conn.execute("SELECT * FROM pricing_catalogs ORDER BY created_at DESC").fetchall() conn.close() result = rows_to_list(rows) for r in result: r["labor_rates"] = json.loads(r["labor_rates"]) if r["labor_rates"] else {} r["material_markups"] = json.loads(r["material_markups"]) if r["material_markups"] else {} return {"catalogs": result} def create_catalog(name, labor_rates, material_markups=None): cid = new_id() conn = get_db() conn.execute("INSERT INTO pricing_catalogs (id, name, labor_rates, material_markups, created_at) VALUES (?,?,?,?,?)", (cid, name, json.dumps(labor_rates), json.dumps(material_markups or {}), now())) conn.commit(); conn.close() return {"id": cid, "name": name} def get_catalog(catalog_id): conn = get_db() row = conn.execute("SELECT * FROM pricing_catalogs WHERE id=?", (catalog_id,)).fetchone() conn.close() if not row: return {"error": "not found"} r = row_to_dict(row) r["labor_rates"] = json.loads(r["labor_rates"]) if r["labor_rates"] else {} r["material_markups"] = json.loads(r["material_markups"]) if r["material_markups"] else {} return r def update_catalog(catalog_id, name=None, labor_rates=None, material_markups=None): conn = get_db() if name: conn.execute("UPDATE pricing_catalogs SET name=? WHERE id=?", (name, catalog_id)) if labor_rates: conn.execute("UPDATE pricing_catalogs SET labor_rates=? WHERE id=?", (json.dumps(labor_rates), catalog_id)) if material_markups: conn.execute("UPDATE pricing_catalogs SET material_markups=? WHERE id=?", (json.dumps(material_markups), catalog_id)) conn.commit(); conn.close() return {"ok": True, "id": catalog_id} def delete_catalog(catalog_id): conn = get_db() conn.execute("DELETE FROM pricing_catalogs WHERE id=?", (catalog_id,)) conn.commit(); conn.close() return {"ok": True, "deleted": catalog_id} def seed_default(): """Seed default Kellow Construction pricing catalog.""" existing = list_catalogs() if existing["catalogs"]: return {"ok": True, "msg": "already seeded"} return create_catalog("Kellow Default", { "general_labor": 55, "framing": 85, "electrical": 95, "plumbing": 90, "painting": 65, "drywall": 75, "tile": 80, "flooring": 70, "roofing": 85, "concrete": 75, "demolition": 60, "finish_carpentry": 90, "project_management": 95, "design": 110 }, {"lumber": 1.15, "drywall": 1.20, "tile": 1.25, "plumbing_fixtures": 1.20, "electrical_fixtures": 1.15, "paint": 1.10, "hardware": 1.15, "appliances": 1.10}) if __name__ == "__main__": from lib.db import init_db; init_db() cmd = sys.argv[1] if len(sys.argv) > 1 else "list" if cmd == "list": print(json.dumps(list_catalogs(), indent=2)) elif cmd == "create": print(json.dumps(create_catalog(sys.argv[2], json.loads(sys.argv[3]), json.loads(sys.argv[4]) if len(sys.argv) > 4 else None))) elif cmd == "get": print(json.dumps(get_catalog(sys.argv[2]), indent=2)) elif cmd == "update": print(json.dumps(update_catalog(sys.argv[2], labor_rates=json.loads(sys.argv[3]) if len(sys.argv) > 3 else None))) elif cmd == "delete": print(json.dumps(delete_catalog(sys.argv[2]))) elif cmd == "seed": print(json.dumps(seed_default())) else: print(json.dumps({"error": f"unknown command: {cmd}"}))