Skip to content

2026-05-29 MSP Invoice Line CRM Implementation Plan

Snapshot date: 2026-05-29. Updated: 2026-06-25 for Product default price/account-code behavior.

Objective

Make MSP_Invoice_Lines easy to manage in Zoho CRM while keeping billing and accounting rules in middleware.

CRM users edit controlled source data, including invoice-line billing dates:

  • Start_Date
  • End_Date

Line_Type is removed from the operational process. Invoice behavior is derived from the linked Product.

Middleware Changes To Deploy First

Deploy the app version containing these endpoints:

  • POST /zoho/msp-invoices/reconcile-line
  • POST /zoho/msp-invoices/reconcile-plan-lines

Both routes use the existing inbound auth:

Authorization: Bearer <MIDDLEWARE_API_TOKEN>

The app now:

  • derives invoice line behavior from Product code, not Line_Type;
  • treats invoice-line Start_Date / End_Date as the source of truth for monthly applicability;
  • excludes lines missing Start_Date and reports them for review;
  • leaves Start_Date and End_Date unchanged during reconciliation;
  • leaves price and Xero account-code override fields unchanged so blank values use linked Product defaults.

CRM Variables

Confirm these CRM variables exist:

  • MIDDLEWARE_BASE_URL
  • MIDDLEWARE_API_TOKEN

MIDDLEWARE_BASE_URL should not have a trailing slash.

Deluge Functions

Create or update these standalone functions from zoho_crm/deluge/:

  • standalone.reconcile_msp_invoice_line
  • standalone.reconcile_msp_plan_invoice_lines

Create these automation wrapper functions:

  • automation.call_reconcile_msp_invoice_line
  • automation.call_reconcile_msp_plan_invoice_lines

The wrappers only pass the CRM record ID to middleware. Do not add billing logic to Deluge.

Product Module Setup

Confirm Products have:

  • Product_Code
  • Default_Invoice_Label
  • Unit_Price
  • Xero_Account_Code

Product-level Unit_Price and Xero_Account_Code are generation defaults. Invoice-line override fields win only when filled.

Expected product defaults:

Product group Default account
MSP-BASE 202.5
MSP-DEVICE 202.5
MSP-DISCOUNT 202.5
MSP-NFP-DISCOUNT 220
License/security/subscription products 211

MSP Invoice Lines Layout

Expose these fields to staff:

  • Name
  • Plan
  • Start_Date
  • End_Date
  • Product
  • Quantity
  • Unit_Price_Override
  • Description_Override
  • Sort_Order
  • Xero_Account_Code_Override

Remove Active and Line_Type from the layout and process. If Zoho allows safe deletion, delete them after confirming the middleware deployment is live. Otherwise leave them hidden until a later cleanup.

Recommended defaults:

  • Start_Date: the first month the line should invoice
  • End_Date: blank
  • Unit_Price_Override: blank unless this line needs a custom price
  • Xero_Account_Code_Override: blank unless this line needs a custom account

Blank price/account-code override fields are preserved so invoice generation can use Product defaults.

MSP Invoice Line Workflow

Create a workflow rule on MSP_Invoice_Lines.

Trigger:

  • on create;
  • on edit when any of these fields changes:
    • Plan
    • Start_Date
    • End_Date
    • Product
    • Quantity
    • Unit_Price_Override
    • Description_Override
    • Sort_Order
    • Xero_Account_Code_Override

Action:

  • custom function: automation.call_reconcile_msp_invoice_line
  • argument: current record ID

The middleware route is idempotent and should return skipped when there is no line-level compatibility work to do. Date reconciliation is now a compatibility no-op; invoice generation reads the operator-maintained date range directly.

Managed Services Plan Workflow

Create a workflow rule on Managed_Services_Plans.

Trigger:

  • on edit when Plan_Type changes.

Action:

  • custom function: automation.call_reconcile_msp_plan_invoice_lines
  • argument: current record ID

The middleware no longer updates account-code override fields from this route. Blank override fields use Product defaults during invoice generation.

Price and Account Rules

Invoice generation resolves price and account code in this order:

Value First source Fallback source
Unit price MSP_Invoice_Lines.Unit_Price_Override Product Unit_Price
Account code MSP_Invoice_Lines.Xero_Account_Code_Override Product Xero_Account_Code

If a line has no override and the linked Product is missing the matching default, generation returns needs_review and does not guess.

Date Rules

Staff manage invoice-line billing dates directly.

  • Start_Date is required. Invoice lines missing Start_Date are excluded and reported for review.
  • End_Date is optional. Blank End_Date means ongoing.
  • Invoice generation includes a line only when its Start_Date / End_Date range overlaps the invoice month.
  • Middleware does not set or clear invoice-line dates.

This does not create historical replacement lines. It is intentionally the simple workflow agreed for now.

Acceptance Tests

After deployment and CRM setup:

  1. Create an MSP_Invoice_Lines record for an L2 plan using MSP-BASE. Confirm middleware does not set or clear Start_Date or End_Date, and price/account-code overrides stay blank unless staff entered them.
  2. Leave Start_Date blank and generate a preview. Confirm the line is excluded and reported for review.
  3. Set Start_Date inside the invoice month and leave End_Date blank. Confirm the line is included.
  4. Set End_Date before the invoice month. Confirm the line is excluded.
  5. Create a license/security/subscription line linked to a Product whose Xero_Account_Code is 211. Leave both override fields blank.
  6. Generate or refresh a draft MSP invoice. Confirm the line uses the Product price and account code and there are no missing product price/account-code review issues.

Rollback

If a workflow misbehaves:

  1. Disable the two new CRM workflow rules.
  2. Leave generated line data in place.
  3. Fix middleware or Deluge wrapper.
  4. Re-enable workflows and run a manual edit/save on affected records, or call the reconcile endpoint directly for the impacted record IDs.