#!/usr/bin/env python3 """Premium customer-facing proposal PDF, v4. Real Stratix Systems brand: logo (white on dark cover, color on light pages), brand palette sampled from the logo (#231f20 ink, #ab1a2d red). Real company facts (founded 1970, 130+ IT pros, 6,500+ organizations, 5 offices, We Make It Right Guarantee). Structure: dark cover -> Why Stratix showcase -> Needs/Answer mapping + investment -> timeline + acceptance. Dense, no blank space. Customer NEVER sees: costs, margins, factors, internal notes. Template uses {{TOKENS}} replaced at the end (no % formatting pitfalls). """ import os, re, datetime, html as htmllib BASE = os.path.dirname(os.path.abspath(__file__)) STRATIX = { "rep": "Sean Mattsson", "title": "Account Relationship Manager", "company": "Stratix Systems", "phone": "(610) 374-1936", "direct": "(484) 214-3895", "address": "200 North Park Road", "city": "Wyomissing, PA 19610", } INK = "#231f20" RED = "#ab1a2d" DARK = "#1a1718" LIGHT = "#f6f3ef" GREY = "#5c5652" def _logo_b64(name): import base64 p = os.path.join(BASE, "assets", name + ".png") with open(p, "rb") as f: return "data:image/png;base64," + base64.b64encode(f.read()).decode() def esc(s): return htmllib.escape(str(s or "")) def money(v): return "$%s" % format(round(v, 2), ",.2f") def raw(p, key): return (p.get("intake", {}).get("raw", {}) or {}).get(key, "") def _lcfirst(s): s = str(s).strip().rstrip(".") return (s[0].lower() + s[1:]) if s else s def capabilities(p): r = lambda k: raw(p, k) it = r("itSupport").lower() interests = r("interests").lower() challenge = r("workflowChallenge") no_it = any(w in it for w in ["no ", "part-time", "break", "none", "myself", "owner"]) blocks = [] blocks.append(("Imaging & Printing", "Commercial-grade Ricoh systems, proactively serviced. One monthly payment covers the device, all toner, parts, labor, and on-site service.", True)) if no_it or "managed it" in interests: blocks.append(("Managed IT", "Your network, endpoints, and uptime handled by a local team. " + ("With %s, technology stops being your second job." % _lcfirst(it) if it else "Technology stops being a distraction."), True)) else: blocks.append(("Managed IT", "Co-managed or fully managed IT that works alongside your team, from helpdesk to infrastructure.", False)) if challenge or "document" in interests: desc = "Scan, route, store, and retrieve documents without the manual work." if challenge: desc += " Built around your reality: %s." % _lcfirst(challenge) blocks.append(("Document Management", desc, True)) else: blocks.append(("Document Management", "We design the document flow around how your office actually operates, cutting the busywork.", False)) if "cyber" in interests or "security" in interests: blocks.append(("Cybersecurity", "Multi-layer protection for your network, data, and confidential information, so threats never reach your business.", True)) else: blocks.append(("Cybersecurity", "Device-level security and best practices built into every Stratix deployment.", False)) blocks.sort(key=lambda b: (not b[2], b[0])) return [(t, d) for t, d, _ in blocks] def needs_map(p): r = lambda k: raw(p, k) acc = ", ".join(a["name"] for a in p.get("accessories", [])) vols = " / ".join(v for v in [r("bwVolume"), r("colorVolume")] if v) triples = [] if r("reason"): triples.append(("Why you're looking", _lcfirst(r("reason")), "A current-generation Ricoh platform, not another aging box")) if r("priority") or r("timing"): t = " and ".join(x for x in [r("priority"), ("needed " + r("timing").lower()) if r("timing") else ""] if x) ans = "Built for %s" % r("timing").lower() if r("timing") else "Speed-first configuration" triples.append(("What matters most", t, ans)) if r("workflowChallenge"): ans = "Configured to attack it" + (" with " + acc if acc else "") triples.append(("Biggest frustration", _lcfirst(r("workflowChallenge")), ans)) if r("minSpeed"): triples.append(("Speed requirement", "%s minimum" % r("minSpeed"), "Performance matched to your %s floor" % r("minSpeed"))) if r("largestJob"): triples.append(("Heaviest workload", r("largestJob"), "Volume-rated%s" % (" for " + vols if vols else ""))) if r("scanType") or r("scanVolume"): s = "; ".join(x for x in [r("scanType"), r("scanVolume")] if x) dest = r("scanDestination") triples.append(("Scanning", s, "Direct scan%s baked into the setup" % (" to " + dest.lower() if dest else ""))) if r("currentModel"): cur = r("currentModel") if p.get("current_lease"): cur += " at %s/mo" % money(p["current_lease"]) triples.append(("Today", cur, "All-in %s/mo, one agreement" % money(p["total_monthly"]))) return triples def faq(p): """Preemptive objection handling, tailored to this customer's answers.""" r = lambda k: raw(p, k) qa = [] qa.append(( "Why lease instead of buying outright?", "A 63-month FMV lease keeps your cost at %s/month with zero upfront capital, and builds in an upgrade " "path at the end. Buying ties up capital on day one and leaves every future toner order, part, and " "service call on you." % money(p["total_monthly"]))) incl = ["the %s" % p["model"]] + [a["name"] for a in p.get("accessories", [])] vols = " / ".join(v for v in [r("bwVolume"), r("colorVolume")] if v) qa.append(( "What exactly is included in the monthly payment?", "Everything: %s, all toner, all parts, all labor, on-site service, and Proactive monitoring with " "automatic meter reads and toner replenishment. The only variable is pages beyond your stated %s, " "billed at the disclosed per-page rates." % (", ".join(incl), vols if vols else "volumes"))) qa.append(( "What happens when something breaks?", "Stratix is the only Pros Elite 100 certified service organization in the region, ranked among the top " "100 in the country, with local technicians operating out of Bethlehem and Wyomissing. Proactive " "monitoring often flags issues before you notice them, and everything is backed by the We Make It Right Guarantee.")) if r("monthsLeft"): qa.append(( "We still have %s left on our current lease. Now what?" % r("monthsLeft"), "We handle that directly. Buyout and rollover options are built into your timeline, and your Stratix " "agreement is structured so you are never paying double.")) elif r("currentModel"): qa.append(( "What happens to our current %s?" % r("currentModel"), "We coordinate the transition: removal, data sanitization, and timing that avoids any gap in your office.")) qa.append(( "Are there any hidden fees?", "No. Your monthly total is %s. Lease payment, maintenance, and supplies are all inside that number." % money(p["total_monthly"]))) qa.append(( "Why Stratix instead of a cheaper online seller?", "An online seller ships you a box. Stratix installs the system, configures your scan workflows, monitors " "it proactively, replenishes toner automatically, services it locally, and answers when you call. One " "partner, one agreement, one point of accountability.")) if r("payment") and "lease" in r("payment").lower(): qa.append(( "What happens at the end of the 63 months?", "With a Fair Market Value lease you choose: upgrade to current technology, extend at a reduced rate, " "or purchase at fair market value. Most clients upgrade, which is exactly the point.")) return qa def why_points(p): r = lambda k: raw(p, k) out = [] if r("minSpeed"): out.append("Delivers the %s speed you asked for" % r("minSpeed")) if r("scanType"): out.append("Scanning built for your workflow: %s" % _lcfirst(r("scanType"))) if r("workflowChallenge"): out.append("Takes direct aim at your bottleneck: %s" % _lcfirst(r("workflowChallenge"))) for a in p.get("accessories", []): out.append("%s included" % a["name"]) if r("payment"): out.append("Structured as a %s, as you preferred" % r("payment").lower()) vols = " / ".join(v for v in [r("bwVolume"), r("colorVolume")] if v) if vols: out.append("Sized for your %s monthly pages" % vols) return out def build_proposal_html(p): c = p["customer"] valid_until = p.get("valid_until", "") today = datetime.date.today().strftime("%B %d, %Y") logo_w = _logo_b64("stratix-logo-white") logo_c = _logo_b64("stratix-logo") maint_parts = [] if p.get("bw_pages"): maint_parts.append("%s B&W" % money(p["bw_maint"])) if p.get("color_pages"): maint_parts.append("%s Color" % money(p["color_maint"])) maint_str = " / ".join(maint_parts) if maint_parts else "Included" caps = capabilities(p) rows = [] for i in range(0, len(caps), 2): cells = "".join( '
%s
%s
' % (esc(t), esc(d)) for t, d in caps[i:i+2]) rows.append('
%s
' % cells) capgrid = '
%s
' % "".join(rows) nm = needs_map(p) need_rows = "".join( '%s%s→' '%s' % (esc(need), esc(detail), esc(answer)) for need, detail, answer in nm) inv_rows = ( 'Lease payment — %s (63-mo FMV)%s / mo' % ( esc(p["model"]), money(p["lease_monthly"])) + 'Maintenance & supplies, all-inclusive%s / mo' % maint_str) if p.get("current_lease"): inv_rows += ('You pay today%s / mo' % money(p["current_lease"])) inv_rows += ('Total monthly investment%s / mo' % money(p["total_monthly"])) tl = "".join( '%s%s' % (esc(k), esc(v)) for k, v in p.get("timeline", {}).items()) pills = "".join('%s' % s for s in ["Managed IT", "Cybersecurity", "Document Management", "Imaging & Printing"]) stats = "".join( '
%s
%s
' % s for s in [("1970", "Serving businesses
for 50+ years"), ("150+", "IT professionals
on staff"), ("8,000+", "Client organizations
served"), ("#1", "Pros Elite 100 dealer
in the region")]) diffs = "".join( '
\u2713 %s %s
' % d for d in [ ("The only Pros Elite 100 dealer in the region,", "ranked among the top 100 service organizations in the country."), ("Ricoh Circle of Excellence and Ricoh USA President's Award,", "plus Inc. 5000 recognition for growth."), ("Proactive monitoring, free with every agreement:", "automatic meter reads and toner replenishment, so you never think about supplies."), ("Local, accountable, single-source:", "technicians out of Bethlehem and Wyomissing, one agreement covering print, IT, documents, and security."), ]) faq_html = "".join( '
%s
%s
' % (esc(q), esc(a)) for q, a in faq(p)) tpl = """

Managed Print
Solution Proposal

One partner for your print, IT, documents, and security.
{{PILLS}}
Prepared for{{COMPANY}}
Attn: {{CONTACT}}
{{REP}}, {{TITLE}}  |  P: {{PHONE}}  |  Direct: {{DIRECT}}
{{ADDRESS}}, {{CITY}}
Prepared {{TODAY}}  |  Valid until {{VALID}}

Why Stratix Systems

{{STATS}}

A single-source technology partner with the presence and responsiveness of a local company. Offices in Wyomissing, Bethlehem, King of Prussia, York, and Edison, NJ.

The Stratix We Make It Right Guarantee
“If you are not happy with our equipment, service, supplies, billing — or anything at all — let us know, and we will make it right, right away.”

What makes Stratix different

{{DIFFS}}
{{CAPGRID}}

Your Needs, Our Answer

{{NEEDS}}

What this means for {{COMPANY}}

Recommendation: the {{MODEL}} on a 63-month FMV lease with all-inclusive service — {{TOTAL}} / month

Investment Summary

{{INV}}

FMV (Fair Market Value) lease. Maintenance & supplies covers all toner, parts, labor, and service for the volumes shown.

Questions you are probably asking

{{FAQ}}

Proposed Timeline

{{TIMELINE}}

Customer Acceptance

The undersigned accepts this proposal and authorizes Stratix Systems to proceed, subject to final credit approval and site survey.

Signature / DatePrint Name / Title

This is a proposal for review and quotation. It is not an order. Final equipment, software, services, lease terms, and pricing require confirmation and credit approval.

""" out = tpl out = out.replace("{{INK}}", INK).replace("{{RED}}", RED) out = out.replace("{{DARK}}", DARK).replace("{{LIGHT}}", LIGHT).replace("{{GREY}}", GREY) out = out.replace("{{LOGOW}}", logo_w).replace("{{LOGOC}}", logo_c) out = out.replace("{{PILLS}}", pills) out = out.replace("{{STATS}}", stats) out = out.replace("{{DIFFS}}", diffs) out = out.replace("{{FAQ}}", faq_html) out = out.replace("{{CAPGRID}}", capgrid) out = out.replace("{{COMPANY}}", esc(c.get("company", ""))) out = out.replace("{{CONTACT}}", esc(c.get("contact_name", ""))) out = out.replace("{{REP}}", STRATIX["rep"]).replace("{{TITLE}}", STRATIX["title"]) out = out.replace("{{PHONE}}", STRATIX["phone"]).replace("{{DIRECT}}", STRATIX["direct"]) out = out.replace("{{ADDRESS}}", STRATIX["address"]).replace("{{CITY}}", STRATIX["city"]) out = out.replace("{{TODAY}}", today).replace("{{VALID}}", valid_until) out = out.replace("{{WHY}}", "".join("
  • %s
  • " % esc(w) for w in why_points(p))) out = out.replace("{{NEEDS}}", need_rows) out = out.replace("{{MODEL}}", esc(p["model"])) out = out.replace("{{TOTAL}}", money(p["total_monthly"])) out = out.replace("{{INV}}", inv_rows) out = out.replace("{{TIMELINE}}", tl) return out def slugify(s): s = re.sub(r"[^a-z0-9]+", "-", s.lower()).strip("-") return s or "proposal" def save_proposal_pdf(p, out_dir=None): from weasyprint import HTML out_dir = out_dir or os.path.join(BASE, "proposals") os.makedirs(out_dir, exist_ok=True) fname = "%s-proposal-%s.pdf" % ( slugify(p["customer"].get("company", "customer")), datetime.date.today().strftime("%Y%m%d")) path = os.path.join(out_dir, fname) HTML(string=build_proposal_html(p)).write_pdf(path) return path if __name__ == "__main__": import json, sys p = json.load(open(sys.argv[1])) print(save_proposal_pdf(p))