v3.0
11 August 2026 · First production release
Rebuilt as a three-way toolbox — 6 Aug 2026 · Platform selector (Azure / AWS / Combined) and independent entity selector (BUI or First Horizon, either platform) replace the single Azure-only tool. Pricing engine reused from v1.2 unchanged (10%/15% of spend, ZAR 25,000 floor, per-currency cap, 30% GP) — now also applies to AWS spend and to combined Azure+AWS spend as a single pooled figure with one shared rate, per Paul's instruction. First Horizon added to ENTITIES using brand/entities.md v2.2 (jurisdiction-neutral tax wording, same address/BBBEE/directors as BUI ZA). Proposal generation rewritten to assemble Sections 1–13 from a single parameterised template rather than three separate copies, branching on platform (Microsoft-only / AWS-only / both) and entity, reusing content approved in the individually-reviewed Azure, AWS, and Combined Phase 1 drafts.
Scope trimmed from v1.2 — 6 Aug 2026 · Multi-year escalation (term selector, per-year compounding, TCV) and the fixed margin-uplift field were not carried over into this rebuild, to keep the toolbox build controlled. Discount simplified to percentage-only (the amount-based option is dropped). Flagged for Paul: confirm whether multi-year and uplift should be added back before this replaces v1.2 in production.
Essential tier removed — 6 Aug 2026 · Briefly added a tier selector (Essential/Premium), then removed it on Paul's instruction — a2zManaged is Premium only, no tier choice in this tool.
SOW generation added — 7 Aug 2026 · New "Generate SOW" button alongside "Generate Proposal", built from the standalone a2zManaged-SOW-generator-v0.1 draft. The SOW's Commercial Schedule (platform, rate, fee, discount) is pulled directly from this tool's own pricing engine (window._calc) rather than re-entered, so the proposal and SOW can never disagree on the number. Uses this tool's own logo assets (already-patched BUI "B" glyph), not the separate unpatched copy in the standalone generator. Fee escalation clauses (1.3/10.4) merged per Paul's instruction: CPI applies every year as a minimum floor; the annual consumption-based review can push the fee higher than that floor but never lower. 12/24/36-month Initial Period + auto-renewal kept from the SOW draft. SOW discount capped at 30% by reusing this tool's existing discount engine rather than the SOW draft's separate 100%-cap field. Confirmed P1–P3 (not P1–P4) priority levels are already consistent between the proposal and the SOW draft — no fix needed there.
Target price, contract term, payment type, and annual increases added — 8 Aug 2026 · All four fields added to the Configuration panel, below the spend boxes. Target price: floor-only, back-solves the core sell so the total lands on the target; hint label switches between "monthly sell" and "annual sell" with payment type; effective margin shown when active. Contract term (1/2/3 year) and payment type (Monthly Billing / Annual Upfront) feed window._calc for SOW assembly. Multi-year terms reveal a two-field Annual Increases row: CPI % (floor, default 5%) and Escalation % (quoted to customer, default 7%). Warning fires when escalation is set below CPI. window._calc now carries term, payment, escPct, cpiPct.
Currency conversion bug fix — 8 Aug 2026 · Two related bugs found and fixed. (1) fmtZAR was multiplying ZAR values by the ZAR-per-currency rate instead of dividing, so switching to USD showed ~18× the correct figure (e.g. a R25,000 floor was displaying as $462,500 instead of ~$1,351). (2) The cap logic was reading per-currency cap values from CAPS[currentCurrency] (already in that currency) and then dividing by the rate when converting to ZAR, giving a ~342× error in the opposite direction. Both are now correct: fmtZAR divides by RATES_ZAR_PER[currency], and cap conversion multiplies CAPS[currency] values by RATES_ZAR_PER[currency] to arrive at the ZAR equivalent.
Azure Proposal wired to extracted template — 10 Aug 2026 · buildProposal() now branches on platform: Azure resolves the standalone proposal-azure.html template (PROPOSAL_AZURE_TEMPLATE, filled by fillProposalAzureTemplate()) via the standard [[TOKEN]] pattern, carrying the rewritten Introduction and Service Overview copy with cost-of-inaction framing. AWS and Combined are unchanged, still assembled inline in buildProposal() below the Azure branch, pending the same treatment. First step of the planned per-document-file architecture noted in references/architecture.md.
Fee basis disclosed in the Proposal — 10 Aug 2026 · The Proposal's Commercial Schedule previously showed only the resulting fee, with no mention that it is spend-based. New feeBasisText() helper adds a plain-language note (platform-aware: Azure spend / AWS spend / combined Azure and AWS spend) stating the fee is based on the Customer's average spend over the preceding 3 months, fixed for the initial term, subject to a monthly floor and cap per the Service Description. Wired into both the new Azure template (as [[FEE_BASIS]]) and the inline AWS/Combined path, so all three platforms are consistent. The SOW already disclosed this; the Proposal did not.
Target Price gated behind approval — 10 Aug 2026 · Target Price was previously an always-visible number field with no gate. It now follows the same approval-gated toggle pattern as Strategic Discount: a toggle switch opens an in-page modal (reusing the .disc-modal CSS classes, per the established escalation-modal precedent) describing what Target Price does and requiring confirmation of written Sales Senior Management approval before the price field is revealed. getTgtPriceSell() now returns 0 whenever the toggle is off, regardless of any stale value left in the field, so an unapproved figure can never reach pricing. feeBasisText() takes useTgt as a parameter: when Target Price is active, the Proposal's Commercial Schedule drops all mention of average spend and instead states the fee is a fixed monthly fee for the Initial Term, since a target-priced deal is no longer consumption-based. Flagged for Paul: the SOW's Commercial Schedule and Section 10.4 escalation clause still describe every deal as consumption-based and would need the same useTgt branch if a target-priced deal ever reaches SOW stage.
Spend boxes hidden when Target Price is active; pricing panel now payment-type-aware — 10 Aug 2026 · New updateSpendVisibility() helper hides the Azure/AWS spend boxes the moment the Target Price toggle is switched on (even before the approval modal is confirmed), since a target-priced deal is no longer spend-based; they reappear if the toggle is switched off or the modal is cancelled. Wired into setPlatform(), handleTgtToggle(), tgtModalCancel(), tgtModalConfirm(), and the top of recalc() so it stays correct regardless of which control triggers the change. Separately, the pricing panel's hero stat and secondary stat now swap by payment type: Monthly Billing shows the monthly fee up top (hero-fee-lbl) with the annual figure below (secondary-fee-lbl), Annual Upfront flips this, showing the annual fee up top and the monthly equivalent below. Verified end to end against the live HTML/JS via jsdom, not just extracted fragments.
AWS and Combined Proposal copy brought in line with the Azure template — 10 Aug 2026 · Sections 1 and 2 of the inline AWS/Combined buildProposal() path were still running the older, thinner copy from before the Azure rewrite. Ported the cost-of-inaction framing across: new proposalIntroOpening() and serviceOverviewOpening() helpers generate the platform-aware risk-framing opening lines (Running AWS well day to day / Running Azure and AWS well day to day; environment is already live or being newly deployed), and Introduction now carries the same additional paragraphs as Azure (BUI as global technology consultancy, consultative outcome-driven methodology, team/CV note, confident closing) rather than the shorter four-paragraph version. credentialLine() upgraded from a flat capability statement to the same customer-benefit framing as the Azure template (direct access to leading <vendor> expertise, already knows the right technical questions to ask), now takes d as a parameter to reach the company name; AWS and Combined variants written to mirror Azure's language exactly, substituting First Horizon / AWS or BUI Group / both platforms as appropriate. Azure itself is untouched, it does not call any of these, it still resolves entirely from PROPOSAL_AZURE_TEMPLATE. Verified via jsdom against the live HTML/JS for both AWS and Combined: no leftover tokens, correct platform-specific substitutions, Azure regression-checked unchanged.
First Horizon Proposal cover matched to BUI's dark cover band — 10 Aug 2026 · The cover's cp-top band was previously white for First Horizon proposals (isFH ? '#fff' : '#535657') and dark grey for BUI, because brand/first-horizon.md flags that no white/reversed logo variant has been supplied and the wordmark's dark charcoal text risked disappearing on the dark band. Decoded and rendered FIRST_HORIZON_LOGO_SVG against #535657 to check before changing anything: the orange "First" renders at full contrast, and the charcoal "Horizon" (#2b2e2c on #535657) is legible but noticeably softer than BUI's white wordmark, since it relies on a modest luminance gap rather than a colour change. Judged acceptable per Paul's explicit request; both TOP_BG resolutions (PROPOSAL_AZURE_TEMPLATE's fillProposalAzureTemplate, and the inline AWS/Combined cp-top) now always use #535657 regardless of entity, so the cover looks identical to the BUI version with only the logo swapped, across all three platforms. If the softer contrast is a problem in printed output, a white/reversed First Horizon logo variant would fix it, flagged for Paul rather than assumed.
Fee basis and tax note combined into one small note, order swapped — 10 Aug 2026 · The Commercial Schedule previously showed the fee basis sentence in normal body text followed by the entity tax line in small grey text (8pt, #777) as two separate paragraphs. Per Paul's instruction, swapped the order (entity tax first, fee basis second) and merged both into a single small-grey paragraph, so the fee basis note is no longer visually emphasised above the tax disclaimer. Applied identically in PROPOSAL_AZURE_TEMPLATE and the inline AWS/Combined path. Verified via jsdom across Azure, AWS, Combined, and the Target Price active case: single 8pt/#777 paragraph, tax sentence first, fee basis (or fixed-fee note, when Target Price is active) second, no leftover tokens.
Tax note and fee basis split back into two lines; spend boxes default to the floor — 10 Aug 2026 · Reverted the single merged paragraph from the previous change: the tax note ("All prices are exclusive of applicable taxes.") now sits on its own line directly under the price table, both still small grey (8pt, #777), and the fee basis sentence follows as its own paragraph below it with normal paragraph spacing between them. Applied to PROPOSAL_AZURE_TEMPLATE and the inline AWS/Combined path identically. Separately, the six spend inputs (az-m1/m2/m3, aws-m1/m2/m3) now default to 250,000 (ZAR) each instead of 0, so a fresh Azure or AWS calculation opens at exactly the floor: 250,000 average x the default 10% partner rate = R25,000/month, R300,000/year, landing exactly on the floor without triggering the floor-applied warning (rawFee equals FLOOR, not below it). Flagged for Paul: this is a per-platform default, not a per-deal one, so opening directly on Combined shows R50,000/month (both defaults pooled, 500,000 average x 10%), not the floor. There is no single default that lands both the individual platforms and Combined on the floor simultaneously, since Combined always sums the two. Verified via jsdom: Azure and AWS both land on exactly R25,000/R300,000 with no floor warning; Combined pools to R50,000/R600,000 as expected.
Spend box defaults nudged above the floor breakeven, to 260,000 — 10 Aug 2026 · The previous default of 250,000 sits exactly on the floor breakeven (250,000 x 10% partner rate = R25,000, the floor value itself), so opening a fresh calculation didn't visibly demonstrate that the fee scales with consumption once spend clears the floor. Bumped all six spend inputs (az-m1/m2/m3, aws-m1/m2/m3) from 250,000 to 260,000, so the default now shows R26,000/month, R312,000/year, driven by the spend figure rather than pinned to the floor. Verified via jsdom: both Azure and AWS defaults now show R26,000/R312,000 with no floor warning.
Tax note right-aligned under the final price — 10 Aug 2026 · The "All prices are exclusive of applicable taxes." line now uses text-align:right, so it sits directly under the Total for Initial Term figure in the price table's right-hand column rather than flush left against the page margin. Fee basis paragraph below it left unchanged (still left-aligned). Applied to PROPOSAL_AZURE_TEMPLATE and the inline AWS/Combined path. Verified via jsdom across Azure and AWS.
Bigger gap before "Yours sincerely," in the Introduction sign-off — 10 Aug 2026 · The sign-off paragraph sat directly against the closing "I am confident..." line with only the standard 9pt paragraph margin between them. Added margin-top:36pt (roughly three blank lines) to the "Yours sincerely," paragraph so it reads as a clear, separated sign-off block rather than running straight on from the section body. Applied to PROPOSAL_AZURE_TEMPLATE and the inline AWS/Combined Introduction section identically. Verified via jsdom across Azure and AWS.
Em dashes removed from the Contracting Entity dropdown — 10 Aug 2026 · The entity dropdown's six option labels used an em dash between entity name and country (e.g. "BUI (PTY) LTD — South Africa"). Per Paul's avoid-list on em dashes, replaced with a comma across all six options (BUI ZA, First Horizon, BUI UK, BUI US, BUI Ireland, MTOM Kenya).
SOW now Target-Price-aware: fee basis text, clause 10.4, and the fee amount itself — 10 Aug 2026 · This was the pending gap flagged when Target Price was gated behind approval: the SOW still described every deal as consumption-based, and worse, the Commercial Schedule's fee line was found to be silently wrong under Target Price. The fee amount was computed from the natural consumption-calculated fee rather than the actual target-priced total, so a R200,000 target-priced deal would have shown R26,000 as the Monthly Service Fee. Fixed three things: (1) the fee amount now uses the target-priced total when Target Price is active, so the fee row shows the real approved figure; (2) the discount percentage is forced to zero when Target Price is active, since Target Price overrides and the discount row is no longer meaningful; (3) new sowFeeBasisNote(useTgt) and sow104Clause(useTgt) helpers replace the hardcoded consumption-based text — when Target Price is active, the Commercial Schedule note reads as a fixed fee under an approved Target Price arrangement subject only to CPI review, and clause 10.4 explicitly states the consumption-based review does not apply, only the CPI escalation in clause 1.3 does. Verified via jsdom against the live calculator end to end: a R200,000 target-priced Azure deal now shows R200,000 in the fee row, the fixed-fee note, and the Target Price 10.4 text; the non-target consumption path is unchanged and still shows the original wording and the natural fee.
Commencement date and Expires added as editable pickers in the wizard — 10 Aug 2026 · Ported from the older v1.3 modal flow, per Paul's request: step 3 of the Generate wizard (Reference/Details) now shows an editable Commencement date picker for both Proposal and SOW, and an editable Expires picker for the Proposal only, defaulting to the same auto-calculated values as before (first day of next month; 30 days out) but overridable by the seller. qDownload() now reads formData['q-commence'] and formData['q-expiry'] when present, falling back to the original auto-calculation only if a field is left empty. Entity selection stays on the main page as before, untouched by this change.
Step 3 review summary restyled and expanded to match the v1.3 look — 10 Aug 2026 · Paul flagged that the older v1.3 tool's download/review page looked better. Ported its pricing-summary styling (header line via <strong>, a border under every row, bold Rajdhani-styled values via .ps-val, final row bolded) and expanded the summary content from three rows (Platform, Entity, Monthly fee) to the same richness as v1.3, adapted to this tool's current deal shape: document type, customer, contact, entity (full name), platform, spend or Target Price (whichever applies), discount row (only shown when active, suppressed under Target Price), monthly fee, annual fee, term and payment type, commencement date, and reference. New fmtDateLong() helper formats the commencement picker's ISO value for display. Verified via jsdom for Proposal and SOW, and separately for the discount-active case: all rows render with correct values, no exceptions, no leftover tokens.
Redundant Target Price wording removed from the SOW fee basis note — 10 Aug 2026 · sowFeeBasisNote(useTgt) previously read "...a fixed monthly fee for the Initial Term, fixed under an approved Target Price arrangement." Per Paul's instruction, dropped the trailing "fixed under an approved Target Price arrangement" clause as redundant; the sentence now reads "...a fixed monthly fee for the Initial Term. The fee is subject to CPI-based annual review as set out in Section 10." The same wording in sow104Clause(useTgt) was left untouched, it's a different sentence with different grammar (comma, not full stop) and was not the one flagged.
Full changelog history restored from v1.3, and Seller Card link brought back — 10 Aug 2026 · This tool's changelog previously compressed everything before v1.2 into six generic bullets under one mislabeled "v1.2" heading, silently dropping the v1.3, v1.1, and v1.0 detail that v1.3's own changelog still carried, and misattributing several v1.0/v1.1 items (per-currency cap, multi-currency support, strategic discount, initial build) to v1.2. Pulled the full verbatim history from a2zManaged-Calculator-v1_3.html and restored it as four correctly-labelled blocks: v1.3, v1.2, v1.1 (9 items), v1.0 (11 items). Separately, this rebuild never carried over the Seller Card link from v1.3 at all, there was no way to reach the companion battlecard from this tool. Added a second toolbar button next to Changelog, wired to openSellerCard(), reusing v1.3's target URL (https://tools.bui.systems/a2zmanaged/a2z-seller-card.html) since both files deploy to the same directory. Flagged for Paul: that seller card was built for the old Azure-only tool, it may need a pass to reflect the three-platform (Azure/AWS/Combined) rebuild before this link goes live.
Full-review fixes: Target Price line item, term/escalation, invoicing, and multi-year TCV — 10 Aug 2026 · End-to-end review across 108 platform/entity/term/payment/discount/target/EES combinations (jsdom, live HTML) surfaced four issues, all now fixed. (1) Target Price line-item contradiction: the Proposal Commercial Schedule's line item showed the natural consumption fee (e.g. R30,000) while the totals below showed the target (e.g. R200,000), openly contradicting itself; the fee row now uses c.coreSellZ (the back-solved target core) instead of c.msFee minus discount, in both the Azure template ([[MS_FEE]]) and the inline AWS/Combined path. This also correctly folds the discount into the line item for non-target deals, since coreSellZ already nets the discount. (2) Term and escalation were hardcoded to "12 Months" and "CPI" in the Proposal regardless of the config panel; new termMonthsText(), escalationText_c(), and totalTermLabel() helpers drive [[INITIAL_TERM]], [[ESCALATION]], and the totals-row label off window._calc.term / escPct, so a 3-year deal now reads "36 Months" and "7% per annum". Single-year still reads "12 Months / CPI". (3) Invoicing wording said "monthly in arrears" even for Annual Upfront and contradicted the SOW (which invoices in advance); new invoicingSentence() switches between "monthly in advance" and "annually in advance" by payment type, matching the SOW. (4) "Total for Initial Term" showed one year's fee even on multi-year deals; recalc() now computes tcvZ (total contract value with escalation compounded per year after Year 1), the totals row shows it as "Total Contract Value (N years)" for multi-year and "Total for Initial Term" for single-year, and the Proposal end date now spans the full term rather than always +1 year. Verified: 3yr @ 7% on R360k/yr = R1,157,364 TCV, exact. All 108 combinations generate both Proposal and SOW with zero leftover tokens and no exceptions.
Document Version field added to Proposal wizard; Version and date now on cover — 11 Aug 2026 · Per Paul's request: (1) the Proposal wizard step 3 (Reference / Details) now includes a Document Version field, matching the SOW which already had one. Defaults to 1. (2) Both the Azure template cover and the inline AWS/Combined cover now show a "Version" row immediately below "Dated", so the cover carries both the issue date and the document version as standard. Wired via [[VERSION]] token in the Azure template and d.version in the inline path. saveStep() and the qDownload deal object updated accordingly. Verified across all three platforms: no leftover tokens, Version row present on cover.
Target Price now warns when it doesn't bind, instead of silently reverting to consumption — 10 Aug 2026 · Paul hit a case where a Combined deal with Target Price selected still produced a consumption-based SOW fee note. Root cause: Target Price is a floor-only override, so when the entered target lands at or below the natural fee, useTgt silently stays false with no feedback. Added a warning under the Target Price field (same orange field-note pattern as the CPI/escalation warning) that fires when the toggle is on with a value that fails to bind. Shows the entered target as a monthly-equivalent, the consumption-calculated fee it needs to exceed, and, when Annual Upfront is active, a note explaining the annual interpretation. Verified across six cases: warning fires only when it should, hidden otherwise.
Content read-through: SOW now honours term/escalation/payment; invoicing reconciled to "in arrears" — 10 Aug 2026 · Full read of all four rendered documents. First Horizon/BUI Group AWS split confirmed intentional. Invoicing reconciled to in arrears throughout. SOW initial period now derived from Contract term (single source of truth); sow13Clause()/sow102Clause() helpers drive clause 1.3 and 10.2 from config. 108-combination sweep clean.
First Horizon branding: hardcoded BUI references removed from all Proposal paths — 11 Aug 2026 · When First Horizon is selected as the entity, all Proposal copy now uses the First Horizon brand throughout. Previously, body text in the Introduction, Service Overview, Operating Model, and Why sections was hardcoded to "BUI" regardless of entity, so a First Horizon AWS or Combined proposal still read as a BUI document. Fixes applied across both the Azure static template ([[SELLER_NAME]] tokens) and the inline AWS/Combined buildProposal() path (${sellerName} substitutions). Specific fixes: intro consultancy and methodology paragraphs; "a2zManaged is BUI's consolidated offer" line; credential line in Service Overview; all four body paragraphs in the Why section; escalation paragraph in Operating Model; Service Description references in Sections 2 and 3. Additionally: the About table's Website row now resolves to www.firsthorizon.cloud for First Horizon (www.bui.co for BUI), and the Proposal Acceptance T&C URL resolves to https://www.firsthorizon.cloud/ for First Horizon (https://www.bui.co/ for BUI) in both the Azure template ([[WEBSITE]], [[TERMS_URL]] tokens) and the inline path (isFH ternary). Cover page and signature block were already correct, using entity.name and sellerName throughout.
Version removed from cover; Reference renamed to Deal ID and made mandatory — 11 Aug 2026 · (1) The document version row ("Version / 1") has been removed from the cover page of both the Proposal and the SOW, in both the Azure static template and the inline AWS/Combined path. Version is still collected in the wizard and used in the document reference code (SOW) but no longer displayed on the cover. (2) The Reference field in the Generate wizard step 3 has been renamed to "Deal ID (required)" with a placeholder instructing the seller to enter the CRM deal ID. The test-mode auto-population (A2Z-AZURE-2026-001) has been removed so the field starts blank and must be filled. Validation in qDownload() blocks PDF generation if the field is empty, showing "Deal ID is required." The review summary row is also updated from "Ref" to "Deal ID".
Wizard split to 4 steps; Document Version removed entirely — 11 Aug 2026 · The Generate wizard has been restructured from 3 steps to 4. Step 3 (previously "Proposal Details" / "SOW Details") now contains only the editable fields: Deal ID, Commencement date, and Expires (Proposal) or Initial Period read-only display (SOW). Step 4 is a new dedicated Summary page showing the full deal confirmation before download. Previously both lived on the same page. Separately, the Document Version field has been removed entirely: gone from the wizard UI (both Proposal and SOW paths), test-mode pre-population, the [[VERSION]] cover token in the Azure template, the inline cover, the proposal deal object, and the SOW document code (now hardcoded to V1). The step bar and Next/Download button visibility updated to reflect the 4-step flow.
v1.1
Prior tool — Azure only
US tax language fix — 23 Jun 2026 · taxLabel() was called with s.entityKey (calculator state) which never carries the entity field, always resolved to undefined, always fell through to "ex VAT". Fixed to d.entityKey (modal deal object) across all four call sites: single-year tfoot, multi-year tfoot, vat-note div, and proposal note paragraph.
Per-currency cap with real COS — 23 Jun 2026 · Cap is now currency-specific from the rate card (ZAR, USD, GBP, EUR, CAD, AUD), not a converted ZAR figure. Once the sliding fee would exceed the selected currency's cap, the fee locks to that currency's cap sell and the COS locks to the rate-card cap cost (not 70% of sell). Floor stays ZAR 25,000 converted dynamically. CAD and AUD added to the currency bar. Breakdown, multi-year table, and PDF cap figures all use the currency-native cap.
Currency cents restored — 23 Jun 2026 · fmt() was rounding to whole numbers, stripping cents from all output including the PDF. Restored 2-decimal display. ZAR shows actual cents; converted currencies round up to a whole unit then show .00.
GP% column added — 23 Jun 2026 · Breakdown and multi-year tables now show GP as a percentage alongside the rand figure. Turns red when GP is negative.
Calculation breakdown rebuilt — 23 Jun 2026 · Per-line-item table with COS, Sell, GP columns. COS is 70% of fee (delivery allocation). Full erosion: discount holds COS fixed and comes straight off GP, so GP can go negative and shows red. EES included on the same 30/70 basis. Multi-year schedule carries the same COS and GP columns per year.
Payment type added — 23 Jun 2026 · Monthly Billing or Annual Upfront selector after contract term. Flows into the proposal commercial schedule as a Payment terms line.
Multi-currency support — 23 Jun 2026 · Full-width currency pill bar above the layout (ZAR, USD, EUR, GBP) with live rates from open.er-api.com and fallback. Base calculation stays in ZAR; inputs convert to ZAR before floor/cap logic; all display and PDF amounts convert out via fmt(). Spend and discount input labels update to the selected currency. SOW Currency field and proposal floor/cap note now dynamic.
US tax language — 23 Jun 2026 · Commercial schedule shows "excl. taxes" / "All prices exclusive of applicable taxes" for the US entity instead of "ex VAT". Driven by taxLabel() off the entity key.
Date defaults — 23 Jun 2026 · Commencement date defaults to first of next month, expires to 30 days out. Both editable via date picker, both respect values already entered.
Author fields pre-populate — 23 Jun 2026 · Name and email populate immediately from the MSAL account object; position enriches from Graph /me when User.Read is consented. Was previously blocking all three on the Graph call.
EES opt-in toggle — 23 Jun 2026 · EES changed from an always-visible hours field to an opt-in toggle. Hours input revealed only when selected; toggling off clears EES from all calculations and PDFs.
Discount label — 23 Jun 2026 · Customer-facing proposal line item reads "Discount" rather than "Strategic discount (5%)". SOW retains the full label.
Proposal page flow — 23 Jun 2026 · Terms and Conditions, Customer Responsibilities, and Onboarding merged into a single continuous block. Removes forced page breaks between sections 5, 6, and 7.
SSO hub-redirect pattern — 23 Jun 2026 · Auth handled at the proposaltools hub. No session on load redirects to the hub; cached session loads the tool directly. Removes the per-tool sign-in gate and the need to register this tool's URL for SSO.
v1.0
Prior tool — Azure only
Seller card extracted — 20 Jun 2026 · Seller card moved from embedded template literal to standalone file (BUI_a2zManaged_BattleCard_v1.0.html). Calculator Seller Card button opens companion file via window.open. Both files deploy to the same directory on tools.bui.systems/a2zmanaged.
Microsoft Entra ID SSO — 20 Jun 2026 · MSAL.js auth gate added. SSO_ENABLED flag controls gate. After sign-in, Graph /me call pre-populates author name, position, and email in the generate modal. User pill with sign-out in toolbar. localStorage cache, sign in once, session shared across all tools on tools.bui.systems.
EES opt-in toggle — 20 Jun 2026 · EES input changed from always-visible number field to opt-in checkbox toggle. Hours input revealed only when selected. Toggling off resets hours to 0 and clears EES from all calculations and PDFs.
Discount label — 20 Jun 2026 · Customer-facing line item in proposal PDF changed from "Strategic discount (5%)" to "Discount". SOW retains full label.
Proposal page flow — 20 Jun 2026 · Terms and Conditions, Customer Responsibilities, and Onboarding sections merged into a single continuous .sec block. Removes forced page breaks between sections 5, 6, and 7.
Cover logo sizing confirmed — 20 Jun 2026 · width:775px on .cp-logo with padding:40px 5px on .cp-top, confirmed against A4 PDF output.
SOW rendering fixes (test PDF 1) — 16 Jun 2026 · Three fixes: (1) Footer on cover suppressed, moved footer to Puppeteer footerTemplate with page-1 visibility:hidden script, same pattern as Proposal. Header also moved to Puppeteer headerTemplate (grey logo + tagline), suppressed on cover page. Inline header divs removed from body sections. @page margins set to 14mm top/bottom, 18mm left/right for non-cover pages; @page:first margin:0 for cover. (2) TCV table split across pages fixed, page-break-inside:avoid added to table.yr. (3) Margin_top and margin_bottom set to 0 (Puppeteer manages margins via header/footer templates).
SOW generator added — 16 Jun 2026 · buildSOW() and generateSOWPDF() added. Generates a complete a2zManaged Statement of Work from calculator state: cover (Prepared For/By tables, schedule number), S1 Agreement Term, S2 Commercial Schedule with per-year fee table and TCV, S3 Service Overview with offering summary table, S4 Responsibilities (BUI/Customer/Licensing), S5-S10 (Onboarding, Reporting, Service Levels, Escalation, Personnel, Fees/Payment), S11 Signatures. Running header and footer per SOW pattern.
Proposal rendering fixes — 14 Jun 2026 · Cover footer suppressed via .sec{page-break-after:always}. Section content overflow fixed. Cover logo confirmed at correct sizing.
Strategic discount — 14 Jun 2026 · Approval-gated discount toggle added. Fires approval modal before revealing fields. Supports percentage (max 30%) or fixed monthly amount (capped at 30% of MS fee). Applies to managed service fee only, never EES. Discount escalates per year on multi-year deals.
Contract term upgrade — 14 Jun 2026 · Multi-year PDF table uses per-year columns (Year 1, Year 2, Year 3). Escalation compounding applied per year. TCV stat card added. End date auto-calculated from commencement + term.
Initial build and PDF generation — 12 Jun 2026 · Spend-based pricing calculator for a2zManaged Premium. Proposal PDF via html2pdf.app. Inputs: 3-month Azure spend, non-CSP toggle, term selector, escalation with approval gate, EES add-on. Outputs: monthly fee with floor/cap logic, seller GP at 30%, multi-year schedule.