Who this report is for
A Salesforce CPQ + Salesforce Billing deployment, live for six years, quoting and billing a subscription and usage-based SaaS portfolio across three regions and four currencies. The org carries 1,246 products, 96 bundles, 187 price rules, 8,412 active subscriptions and roughly 14,800 quotes a year, with Salesforce Billing generating ~4,100 invoices per month into an ERP via middleware. Salesforce CPQ's end-of-sale path and the business's move toward attribute-driven packaging have triggered the decision to migrate to Revenue Cloud Advanced (RCA) and Revenue Cloud Billing (RCB).
Every module was run as a standalone discovery pass — metadata inspection plus record-level data analysis — before any Revenue Cloud solutioning. This report consolidates the 21 module outputs into seven domains, each closing with a legacy-to-RCA/RCB mapping and a disposition (retire, refactor, or carry forward) for what discovery surfaced.
Quote-to-Cash, Reconstructed From the CPQ Build
Before any module-level analysis, discovery reassembled the end-to-end process the org actually runs — from metadata, automation and twelve months of record data, not from process documentation. Twelve steps across two motions: the selling motion in CPQ and the billing motion in Salesforce Billing. The coloured top edge on each step shows what discovery found there.
What we found
Six years of CPQ has left this SaaS business with a revenue engine that works — quotes go out, invoices get paid — and a configuration estate that has quietly tripled past what the business actually uses. Roughly half the pricing logic never fires, a third of the bundles haven't been quoted in a year, and 61 Apex components hold the whole thing together. That estate is the migration: RCA is not a lift-and-shift target, and the single biggest risk in this program is migrating dead configuration instead of retiring it. The good news runs the other way too — because so much is dormant, the true migration surface is roughly half the apparent one.
The estate in numbers
Headline findings
- The pricing engine is a black box — 187 price rules, 9 calculator plugin scripts and 44 discount schedules interact in an order nobody can fully explain; 52 active rules have not fired in 12 months and pricing behaviour is verified by "quote it and see".
- Amendments and renewals run on contract-centric logic RCA doesn't have — 3,150 amendments a year flow through SBQQ__Subscription__c and contract-based amendment quotes; RCA's asset-centric model (Asset / AssetAction / AssetStatePeriod) is a re-architecture, not a mapping.
- Revenue recognition lives in legacy Revenue Schedules — 82% of revenue is ratable and recognised through constructs RCB deliberately replaces with GL Journal Entry Rules; finance's month-end process is built on objects that will not exist post-migration.
- Two-thirds of the catalog is noise — 858 of 1,246 products are inactive or unquoted in 24 months, 31 of 96 bundles have zero recent usage, and 12% of products have no PricebookEntry at all. Migrating this as-is would pour six years of drift into a clean platform.
- Bundle nesting exceeds RCA's sweet spot — 14 bundles nest three to four levels deep with option-constraint chains; RCA's flatter ProductRelatedComponent model needs these redesigned, not transplanted.
- Quote templates don't come along — 18 CPQ quote templates (5 active) have no native RCA equivalent; document generation must be re-implemented on Document Builder or an equivalent before cutover, or reps lose the ability to send quotes on day one.
- The org's real logic is in code — 61 Apex classes and triggers reference SBQQ objects, including twin-field sync, a quote calculator plugin and renewal uplift logic. Each needs an explicit retire / refactor / retain decision against RCA's Expression Set and CML framework.
Module heatmap — all 21 discovery modules at a glance
Product Catalog & Selling Models
The catalog is where RCA's model differs most visibly from CPQ: subscription behaviour moves off Product2 checkbox fields and into Product Selling Models, and configuration moves into attributes. Discovery found a catalog three times larger than the sold portfolio, five subscription-type variants doing the work of three, and a pricebook structure that has accreted one book per pricing experiment.
What discovery found
- 1,246 Product2 records: 388 active, 858 inactive or with no quote line in 24 months. 149 products (12%) have no PricebookEntry in any pricebook — unquotable by definition.
- Subscription behaviour is driven by SBQQ__SubscriptionType__c (5 values in use, including two legacy variants of "Renewable"), SBQQ__SubscriptionPricing__c and SBQQ__SubscriptionTerm__c defaults of 12/24/36 months.
- Portfolio split by billing behaviour: 61% recurring subscription, 24% one-time (services, onboarding), 15% usage-rated (API calls, consumption tiers).
- 7 pricebooks beyond Standard — regional (ANZ, EMEA, Americas), a partner book, and three "promo" books last updated over two years ago. Multi-currency active across AUD, USD, EUR, GBP with 214 currency-specific PricebookEntry overrides.
Catalog activity, visualised
Product2 — actually sellable?
Six years of SKU experiments, none archived. Only the violet slice migrates; the rest is a retirement list.
Portfolio by billing behaviour
Five legacy SubscriptionType values collapse into three RCA Product Selling Models — simpler than today.
Legacy → RCA mapping
| Legacy CPQ Construct | RCA Target | Disposition & Notes |
|---|---|---|
| SBQQ__SubscriptionType__c (5 values) | ProductSellingModel — Term-Defined / One-Time / Evergreen | Refactor — collapse 5 legacy values to 3 selling models; two "Renewable" variants merge |
| SBQQ__SubscriptionPricing__c / SBQQ__SubscriptionTerm__c | ProductSellingModelOption term definitions | Refactor — term defaults (12/24/36) become selling model options per product |
| SBQQ__BillingType__c / SBQQ__PricingMethod__c | PricebookEntry + Pricing Procedure inputs | Refactor — billing behaviour moves to RCB billing treatments, not product flags |
| SBQQ__Component__c bundle flags | Product2.Type = Bundle Product + ProductRelatedComponent | Refactor — see Domain 02 |
| Product Family (11 values) | ProductCategory + Product Classification hierarchy | Carry forward — families map 1:1 to categories; classifications added for attribute inheritance |
| Standard + 7 custom pricebooks | RCA Price Books (per selling model) | Partially retire — 3 stale promo books retired; regional + partner books carry forward |
| 149 products with no PricebookEntry | — | Retire — unquotable today, not migrated |
Recommendations
- Run a catalog rationalisation sprint before any RCA build: confirm the 388-product active set with product management, archive the rest with a documented restore path.
- Define the three Product Selling Models and their term options as the first RCA build artefact — everything downstream (pricing, bundles, assets, billing) hangs off them.
- Rebuild the pricebook estate as four books (three regional + partner) with currency coverage validated against the 214 existing overrides.
- Move edition/tier variants (Starter / Pro / Enterprise duplicated as separate SKUs) to attribute-driven products where the variant count justifies it.
Bundles, Configuration & Product Rules
CPQ's Feature/Option model and RCA's ProductRelatedComponent model solve the same problem with different shapes — and this org's bundles have grown into shapes RCA won't accept as-is. Discovery found deep nesting, constraint logic split across three mechanisms, and a rule estate where nearly one in five rules is dormant.
What discovery found
- 96 bundle products carrying 412 SBQQ__ProductFeature__c records and 1,830 SBQQ__ProductOption__c records; selection methods split between Click (78%) and Add (22%).
- 14 bundles nest 3–4 levels deep (bundle-in-bundle-in-bundle), all in the enterprise platform family; the deepest chains exist to reuse option sets rather than to reflect how the product is actually sold.
- 65 bundles were quoted in the trailing 12 months; 31 have zero usage. Average options selected per bundle instance: 4.2 of an average 11 available.
- 214 SBQQ__ProductRule__c records: 118 Validation, 61 Selection, 35 Alert. 38 rules (18%) have not fired in 12 months; 9 pairs of rules overlap or contradict on the same products. Option visibility logic additionally lives in 47 SBQQ__ConfigurationRule__c records and 3 Apex validation classes — three mechanisms for one job.
The rule estate — firing or dormant?
Rule firing inferred from quote error logs and rule-evaluation history. Dormant rules migrate as documentation, not configuration.
Legacy → RCA mapping
| Legacy CPQ Construct | RCA Target | Disposition & Notes |
|---|---|---|
| SBQQ__ProductFeature__c (min/max, selection method) | ProductRelatedComponent Group with min/max constraints | Refactor — feature groups map cleanly where nesting is ≤2 levels |
| SBQQ__ProductOption__c (component / optional / qty scale) | ProductRelatedComponent (required vs optional, quantity rules) | Refactor — 1,830 options reduce to ~700 after zero-usage bundle retirement |
| 3–4 level nested bundles (14 products) | Flattened component model + AttributeDefinition/AttributePicklist | Redesign — deep nests become attribute-driven selection; workshop per bundle required |
| Product Rules — Validation (118) | Constraint Rules via CML constraint() in Configuration Procedure | Refactor 96 / retire 22 — using @(virtual = true) quote containers where legacy Summary Variables were used |
| Product Rules — Selection (61) | Component eligibility rules / attribute-based defaults | Refactor 52 / retire 9 |
| Configuration Rules (47) + 3 Apex validators | Consolidated into Context Definitions + constraint rules | Redesign — three mechanisms collapse to one; watch Context Definition activation and field-mapping risks seen in prior RCA builds |
Recommendations
- Retire the 31 zero-usage bundles and 38 dormant rules before mapping begins — they are 30% of the apparent configuration surface and 0% of revenue.
- Run a bundle redesign workshop per deep-nested product with product management: the target is RCA's flatter component model reflecting how the product is sold today.
- Consolidate all option-visibility logic into the constraint-rule layer during rebuild; do not recreate the three-mechanism split in RCA.
- Resolve the 9 contradictory rule pairs with sales ops before migration — RCA's constraint engine will surface conflicts CPQ silently tolerated.
Pricing Engine & Discounting
Pricing is the domain the business trusts least and the migration must get most right. Discovery found a rule estate where the majority of logic never executes, a calculator plugin carrying the pricing behaviour nobody dares touch, and a discounting culture where manual overrides — not schedules — set nearly a third of street prices.
What discovery found
- 187 SBQQ__PriceRule__c records (evaluation events: 41 on-load, 88 on-change, 58 on-save) with 512 Price Conditions and 391 Price Actions. Only 74 rules fired on quotes in the trailing 12 months; 52 active rules never fired; 61 are inactive but unretired.
- One SBQQ__CalculatorPlugin__c (~1,900 lines of JavaScript) implements currency-rounding, margin-floor enforcement and ramp pricing. It is undocumented and its author has left the business.
- 44 Discount Schedules: 29 volume-tiered, 11 term-based, 4 block. 12 schedules apply to products with zero recent quote activity.
- Discount distribution across 168,300 quote lines: 46% schedule-driven, 31% manual (SBQQ__AdditionalDiscount__c or SBQQ__SpecialPrice__c), 23% list price. Manual discounts cluster at 10/15/20% — anchor-point discounting rather than governed exceptions.
187 price rules — what actually runs
Only the green bar migrates. The pricing procedure rebuild targets 74 rules plus the calculator plugin's three behaviours — not 187 rules.
How street price is actually set
Nearly one line in three is priced by a rep typing a number. RCA's Manual Adjustment framework supports this — but the migration is the moment to decide whether it should.
Discounts land on round anchors, not deal economics — a sign that governed, tiered adjustment schedules could replace most manual discounting without slowing reps down.
Legacy → RCA mapping
| Legacy CPQ Construct | RCA Target | Disposition & Notes |
|---|---|---|
| Price Rules / Conditions / Actions (74 live) | Pricing Procedure + CPQ Calculation Procedure steps | Refactor — rule logic re-expressed as procedure steps; 113 dormant rules retired |
| Calculator Plugin (rounding, margin floor, ramps) | Expression Set / CML expressions; Apex Plugin only if CML insufficient | Redesign — three behaviours re-specified from observed quote outcomes, not from JS reverse-engineering alone |
| Discount Schedules (32 in use) | Price Adjustment Schedules (tiered/volume) + Attribute-Based Pricing | Refactor — 12 zero-usage schedules retired |
| SBQQ__AdditionalDiscount__c / SBQQ__SpecialPrice__c | RCA Manual Adjustment at Quote Line | Carry forward with governance — pair with tightened approval thresholds (Domain 04) |
| Currency-specific PricebookEntry overrides (214) | Multi-currency price book entries per selling model | Carry forward — validated per currency in the pricing test pack |
| Pricing verified by "quote it and see" | Pricing regression pack (ProcedurePlanDefinitionVersion-pinned) | New — 200-scenario golden-quote suite run against both engines pre-cutover |
Recommendations
- Specify pricing behaviour from evidence, not code: derive the calculator plugin's actual effects from 12 months of quote outcomes, then implement that specification in CML.
- Build the golden-quote regression pack (top 200 quote shapes by revenue) and run it against CPQ and RCA in parallel — pricing parity is the cutover gate.
- Retire the 113 non-firing/inactive rules and 12 dead schedules now, in CPQ, so parallel-run comparisons are clean.
- Use the migration to shift the 10/15/20% manual anchor discounts into governed adjustment tiers with approval thresholds preserved.
Quote-to-Order Lifecycle
The quoting motion itself is healthy — reps quote daily, approvals turn around in under three days, and orders flow. The migration risk is in the plumbing: 63 twin fields syncing quote data to opportunities, templates with no RCA equivalent, and an approval framework that must be rebuilt on native tooling because RCA doesn't ship CPQ's.
What discovery found
- 14,800 quotes/year averaging 11.4 lines; 41 custom fields on SBQQ__Quote__c and 58 on SBQQ__QuoteLine__c; Quote Line Groups used on 34% of quotes (multi-year ramps and multi-product phases).
- 63 Twin Field mappings sync quote data to Opportunity/OpportunityLineItem; sync failures logged on 2.1% of quotes, mostly on high-line-count ramp deals.
- Quote status distribution (12 mo): 48% Won-linked, 24% Lost-linked, 22% abandoned drafts, 6% in flight. 18 quote templates exist; 5 are actively used, with conditional sections for region, currency and T&C variants; DocuSign is the e-signature layer.
- 4 approval processes route on discount %, deal size, payment terms and non-standard T&Cs: 6,900 submissions/year, 2.6-day average approval, 9% rejection. Orders: ~640/month generated from won quotes, auto-contracted on activation.
Where 14,800 quotes a year end up
A 22% draft-abandonment rate is a UX signal: reps use quote creation as a pricing calculator. The RCA quote experience should give them a cheaper way to explore price.
Legacy → RCA mapping
| Legacy CPQ Construct | RCA Target | Disposition & Notes |
|---|---|---|
| SBQQ__Quote__c / SBQQ__QuoteLine__c (+99 custom fields) | Native Quote / QuoteLineItem | Refactor — 61 of 99 custom fields map to standard RCA fields; 38 re-created as extensions |
| Quote Line Groups (ramps, phases) | RCA quote line grouping equivalent | Refactor — ramp deals re-tested explicitly; highest sync-failure cohort today |
| 63 Twin Field mappings | Native Quote ↔ Opportunity Product integration | Retire the mechanism — RCA's native sync replaces twin-field automation; field parity validated per mapping |
| 18 Quote Templates (5 active) + DocuSign | Document Builder / Flow-based generation; DocuSign carried forward | Redesign — no native template migration exists; 5 active templates rebuilt, 13 retired |
| 4 Approval Processes (SBQQ.Approval submission) | Native Approval Processes / Flow approvals on RCA Quote | Refactor — entry criteria re-pointed at RCA fields; thresholds tightened per Domain 03 discount findings |
| Quote-to-Order + auto-contract on activation | Native Order/OrderItem generation from RCA Quote | Refactor — order creation stays manual in Phase 1 per established pattern; asset creation triggers differ (Domain 05) |
Recommendations
- Rebuild only the 5 active templates on Document Builder and get DocuSign touchpoints working before UAT — a rep who can't send a quote on day one defines the migration's reputation.
- Validate the 63 twin-field mappings as a field-parity checklist against RCA's native sync; retire the automation, keep the reporting fields.
- Re-implement approval entry criteria against RCA quote fields, folding in the tightened discount governance from Domain 03.
- Design the RCA quote screen around the "pricing calculator" behaviour — a price-preview path that doesn't create an abandoned quote record.
Contracts, Amendments, Renewals & the Asset Model
This is the structural centre of the migration. CPQ amends contracts; RCA amends assets. Every subscription, amendment and renewal process this business runs — 8,412 active subscriptions, 3,150 amendments a year, auto-generated renewals with uplift — must be re-expressed in the Asset / AssetAction / AssetStatePeriod model. It is a re-architecture with a data migration inside it.
What discovery found
- 8,412 active SBQQ__Subscription__c records across 2,140 contracts. Term distribution: 58% 12-month, 14% 24-month, 9% 36-month, 19% evergreen (auto-renewing monthly).
- 3,150 amendment quotes/year: 54% upsell (seats/modules), 21% term extension or co-term, 12% downsell, 13% administrative (entity, billing details). Co-termination is used on 41% of multi-product accounts.
- Renewal quote auto-generation succeeds on 87% of eligible contracts; the 13% failure cohort is dominated by evergreen subscriptions and contracts with manually edited end dates. Renewal uplift (default 5%, overridable) is applied by a custom Apex routine, not standard fields.
- Mid-term amendment proration is standard CPQ day-based proration plus one custom Apex override for a legacy customer cohort on calendar-month proration.
The subscription book, by term
Term-defined subscriptions map cleanly to RCA asset lifecycles. The 19% evergreen book — 1,598 subscriptions — needs an explicit Evergreen selling model and a custom renewal-processing decision, and it is today's renewal-failure hotspot.
Every one of these becomes an initiateAmendment flow producing AssetActions with CanRollBack support — a cleaner audit trail than amendment quotes, once the asset book is migrated correctly.
Legacy → RCA mapping
| Legacy CPQ Construct | RCA Target | Disposition & Notes |
|---|---|---|
| SBQQ__Subscription__c (8,412 active) | Asset + AssetStatePeriod (lifecycle-managed) | Migrate — the single most consequential data migration in the program; reconciled against contract and billing data before cutover |
| Contract-centric Amendment Quotes | initiateAmendment flow → AssetAction (with CanRollBack) | Redesign — amendment UX retrained; audit trail improves |
| Renewal Quote/Opportunity auto-generation | Asset-based renewal processing | Refactor — the 13% failure cohort (evergreen, edited end-dates) fixed in data before migration, not after |
| Custom Apex renewal uplift (default 5%) | Renewal term/uplift on Asset renewal fields + procedure logic | Refactor — uplift becomes declarative; override path preserved |
| Co-termination logic (41% of multi-product accounts) | Asset-based co-term processing | Refactor — co-term dates validated in the asset reconciliation pass |
| Evergreen handling (1,598 subscriptions) | Evergreen ProductSellingModel + custom Asset lifecycle rule | Redesign — explicit design decision required; flagged as the domain's open risk |
| Custom calendar-month proration (legacy cohort) | AssetStatePeriod-driven proration + CML/Apex plugin for the exception | Refactor — decide whether the legacy cohort converts to standard proration at migration |
Recommendations
- Treat subscription-to-asset conversion as a formal data migration workstream: extraction, transformation rules, three reconciliation passes (counts, MRR by account, term dates) and a signed-off cutover snapshot.
- Resolve the evergreen design first — it shapes selling models (Domain 01), renewal processing, and billing schedules (Domain 07).
- Clean the 13% renewal-failure cohort in CPQ before migration; migrating broken end-dates makes them RCA's problem.
- Sunset the calendar-month proration exception at migration if commercially possible — one proration model, one set of test cases.
Custom Code, Integrations, Security & UX
Sixty-one Apex components reference SBQQ objects, and every one of them breaks the day CPQ is uninstalled. Discovery produced a disposition for each: retire where RCA has a native equivalent, refactor where the logic survives but the objects don't, retain where the code never really depended on CPQ. The ERP middleware and the permission model get the same treatment.
What discovery found
- 61 Apex classes/triggers referencing SBQQ__* objects: twin-field sync helpers, the calculator plugin, renewal uplift, quote-line rollups to Opportunity, contract activation hooks, and integration serialisers. Error logging shows 3 classes account for 84% of CPQ-related Apex exceptions.
- Outbound integrations: ERP middleware consuming Order/Invoice payloads keyed to legacy Billing objects; a data warehouse extract reading SBQQ__Subscription__c nightly; a CS platform webhook on contract activation. One dormant marketing integration has failed silently for 14 months.
- Security: 6 permission sets grant CPQ object access; 240 quote-creating users in the trailing 90 days; sharing on Quote follows Opportunity. Page layouts and the quote line editor carry 9 UX customisations reps rely on daily (column sets, custom actions).
Disposition of 61 Apex components
Every component has a decision, not a hope
Two in five components need no rebuild at all — RCA natively covers what the org paid Apex to do. The refactor set is dominated by the pricing plugin and renewal logic already covered in Domains 03 and 05.
Legacy → RCA mapping
| Legacy Component | RCA Target | Disposition & Notes |
|---|---|---|
| Twin-field sync helpers (7 classes) | Native Quote ↔ Opportunity integration | Retire — parity validated per field (Domain 04) |
| Calculator plugin (JS) + pricing helpers (5) | Expression Set / CML in Pricing Procedure; Apex Plugin fallback | Refactor — evidence-based re-spec (Domain 03) |
| Renewal uplift & co-term Apex (4) | Asset renewal fields + procedure logic | Refactor (Domain 05) |
| ERP middleware (Order/Invoice payloads) | Re-pointed at RCB Invoice / GL Journal Entry objects | Refactor — field-level remapping workshop with ERP owner; contract tests both sides |
| Data warehouse nightly extract (SBQQ__Subscription__c) | Asset / AssetStatePeriod extract | Refactor — BI dashboards re-based; run both extracts in parallel one cycle |
| CS platform webhook (contract activation) | Asset activation event | Refactor — trigger point moves; payload contract preserved |
| Dormant marketing integration (failed 14 months) | — | Retire — formally, this time |
| 6 CPQ permission sets · 9 quote-screen UX customisations | RCA permission sets · RCA Quote Lightning experience | Refactor — access re-baselined by role; the 9 UX behaviours are adoption-critical and rebuilt deliberately |
Recommendations
- Freeze the disposition register as a governed artefact — every one of the 61 components has an owner, a target, and a test before cutover.
- Run the ERP remapping as a joint workshop with the middleware owner early in Phase 1; integration lead times, not Salesforce build, set this domain's critical path.
- Parallel-run the data warehouse extract on both schemas for one full cycle so finance reporting never goes dark.
- Rebuild the 9 quote-screen UX behaviours in the RCA quote experience before UAT — they are what "feels the same" means to a rep.
Billing, Payments & Revenue Recognition
Salesforce Billing runs the company's cash engine: 4,100 invoices a month, gateway payments, Avalara tax, and ratable revenue recognition feeding the ERP's GL. RCB replaces this with different constructs in exactly the places finance is most conservative — and the established architecture decision to move deferred revenue off legacy Revenue Schedules onto GL Journal Entry Rules makes this a finance-process change, not just a platform swap.
What discovery found
- ~4,100 invoices/month from scheduled batch runs; 3.2% require manual correction (wrong billing period, mid-cycle amendment timing, currency rounding). Invoice line grouping is customised to group by product family for enterprise accounts.
- Payments: 71% gateway-processed (tokenised cards / direct debit), 29% invoice-and-remit. Gateway success rate 96.8%; failures concentrate in expired tokens on evergreen subscriptions.
- Revenue recognition: 82% ratable over term via legacy Revenue Schedules, 18% point-in-time (services, one-time). 940 credit notes/year, top reasons: mid-term downgrades, billing-period errors, goodwill. Avalara handles tax across four jurisdictions with 312 exemption certificates on file.
- Usage-based billing: usage summaries rated monthly for the consumption portfolio (15% of products); rating exceptions on 1.9% of cycles, mostly late-arriving usage files. GL: middleware posts summarised journals to the ERP nightly; ~$18K/month average unreconciled variance absorbed at month-end, plus a recurring manual journal for deferred revenue true-ups.
The cash engine, visualised
Payment collection mix
Gateway compatibility and token re-authentication are cutover-critical: 71% of cash collection depends on payment methods surviving the migration intact.
Revenue recognition pattern
Four-fifths of revenue is recognised through constructs RCB replaces. The GL Journal Entry Rule design must be signed off by finance against a full parallel month of journals.
Legacy → RCB mapping
| Legacy Billing Construct | RCB Target | Disposition & Notes |
|---|---|---|
| Invoice / Invoice Line + scheduling batches | RCB Invoice / Invoice Line + Billing Schedules | Refactor — invoice generation and posting stay manual for Phase 1 per established pattern; automation follows one clean cycle |
| Custom invoice line grouping (product family) | RCB invoice grouping equivalent | Refactor — enterprise invoice format preserved; validated against top-20 accounts' current invoices |
| Payment Methods / Gateway config / tokens | RCB Payment + Payment Gateway framework | Carry forward — gateway compatibility confirmed; token re-auth plan for the evergreen cohort; Unapplied Payment pattern for deposits/prepayments |
| Legacy Revenue Schedules (82% of revenue) | GL Journal Entry Rules + Revenue Recognition Treatments | Redesign — per the established RCA/RCB architecture decision; finance sign-off and one parallel month of journals as the gate |
| Credit / Debit Notes (940/yr, reason codes) | RCB Credit Memo / Debit Memo | Refactor — reason-code taxonomy and approval routing preserved |
| Avalara tax integration + 312 exemptions | RCB-compatible Avalara connector | Carry forward — connector version validated; exemption certificates re-verified in migration |
| Usage summaries + monthly rating | RCB Usage-Based Pricing + consumption schedules, rated by RCA attribute-based pricing | Refactor — late-file handling redesigned with a rating exception queue |
| ERP journal middleware + manual deferred-revenue true-ups | GL Journal Entry Rule outputs → remapped middleware | Refactor — the $18K/month variance and the manual true-up are targets to eliminate, not migrate |
Recommendations
- Run a full parallel billing month: RCB generates shadow invoices and journals alongside production Billing, reconciled line-by-line for the top 50 accounts and in aggregate for the rest — this is the program's hardest gate and its best insurance.
- Design the GL Journal Entry Rule set with finance in the room, mapping every current recognition treatment and the deferred-revenue true-up it should eliminate.
- Pre-migrate payment token re-authentication for the evergreen cohort — the current failure hotspot — before cutover, not during.
- Keep invoice posting manual for the first cycle post-cutover, then automate once reconciliation is clean two cycles running.
Migration Risk & 12-Week Program Plan
The migration's shape follows from discovery: rationalise first, rebuild the revenue engine second, and move the asset book and billing last — behind a pricing parity gate and a parallel billing month. Sequenced this way, the program fits a twelve-week window with three overlapping phases and two hard gates.
Migration risk register
| Risk | Severity | Mitigation Built Into the Plan |
|---|---|---|
| Pricing behaviour lost in translation — calculator plugin undocumented, 31% of lines manually priced | Critical | Evidence-based re-specification plus a 200-scenario golden-quote parity pack; pricing parity is the Phase 2 exit gate |
| Subscription-to-asset conversion errors corrupt renewals and billing downstream | Critical | Formal data migration workstream with three reconciliation passes and a signed cutover snapshot |
| Revenue recognition change (Schedules → GL Journal Entry Rules) surprises finance at month-end | Critical | Finance co-designs the rule set; one full parallel month of shadow journals before cutover |
| Reps can't send quotes on day one — templates and approvals are rebuild-from-scratch | High | Document generation and approvals rebuilt in Phase 2 and included in UAT with real deal shapes |
| ERP middleware remapping slips — external lead times outside Salesforce control | High | ERP remapping workshop in week 1; contract tests on both sides; middleware on the program's critical path from day one |
| Evergreen book (1,598 subscriptions) has no default RCA behaviour | High | Evergreen design decision forced in Phase 1 before it can block asset migration |
| Migrating dormant configuration inflates build and test scope | High | Rationalisation is Phase 1's first deliverable: 858 products, 31 bundles, 113 rules and 13 templates retired before build |
Migration project plan
A twelve-week, three-phase program. Phases overlap deliberately — the pricing rebuild starts on the rationalised catalog while foundation work completes, and the billing parallel run begins as soon as the asset model is stable.
Rationalise & Found
Catalog rationalisation locks the 388-product active set and retires 858 products, 31 bundles, 113 price rules and 13 templates. Product Selling Models, Product Classifications and the four-book pricebook estate are built. The evergreen design decision is forced, the Apex disposition register is frozen, and the ERP remapping workshop runs in week one so middleware lead times start immediately.
Rebuild the Revenue Engine
Bundles rebuilt on the ProductRelatedComponent model with consolidated constraint rules in CML. Pricing Procedures implement the evidence-based specification of the 74 live rules and the calculator plugin's behaviours. Quote experience, Document Builder templates, DocuSign and native approvals come up together. The phase exits through Gate 1: the 200-scenario golden-quote pack prices identically on CPQ and RCA.
Assets, Billing & Cutover
The subscription book converts to Assets with three reconciliation passes; amendment and renewal flows go live on AssetActions. RCB billing schedules, payment gateway, Avalara, credit memos and GL Journal Entry Rules run a full parallel billing month — shadow invoices and journals reconciled with finance. Gate 2 passed, cutover executes with order creation and invoice posting manual for the first cycle.
Net assessment
This is a healthier migration than most CPQ estates present. The business's revenue motion is genuinely simpler than its configuration — three selling models, one real pricing engine a third the size of the one on disk, and amendment patterns that map naturally onto RCA's asset model. The hard parts are concentrated and known: an undocumented pricing plugin, a contract-to-asset re-architecture, and a revenue recognition change that finance must own rather than receive.
The discipline that decides the outcome is subtraction. Every dormant product, rule and bundle retired in week one is configuration that never needs building, testing, or explaining in RCA.