Access4 / Sasboss Integration - User Guide

Access4 / Sasboss Integration - User Guide

Access4 / Sasboss Integration

The Access4 integration automatically pulls your Access4 (Sasboss) enterprise, service, DID, and billing data into PracBill so you can bill your customers without manual data entry.

What Gets Synced

Data

Source

Destination

Data

Source

Destination

Enterprise → Customer

Sasboss Enterprise

PracBill Customer

DID numbers (individual or blocks)

Sasboss DID numbers

PracBill Engineering (DID) records

Service accounts (endpoints, huntgroups, etc.)

Sasboss Service Accounts

PracBill Engineering (license) records

Wholesale cost

Sasboss billing charges

Engineering cost field

Retail price

PricingService (see Pricing below)

Engineering monthlyfee field

Setup fees

Sasboss billing charges

Engineering iItems (unbilled line items)

The sync runs automatically every night at 00:30. It is idempotent — re-running it does not create duplicates.

How Services Are Created

Each enterprise produces two types of engineering records:

DID Records (number rentals)

One engineering record per DID number (or per DID block for 10/100 number ranges). The block size comes directly from Sasboss's didNumberGroupSize field — PracBill never guesses ranges.

  • Individual DIDs (groupSize=1) → one record per number

  • 10-blocks (groupSize=10) → one record per block

  • 100-blocks (groupSize=100) → one record per block

DID records carry the DID rental charge from the billing API (e.g. $0.35/month per number).

Service Account Records (user licenses)

One engineering record per provisioned service account — endpoints, huntgroups, ring groups, IVRs, call centres, fax lines, etc. These are created regardless of whether the service account has a DID attached.

Service account records carry the user license charge from the billing API (e.g. $35/month for an Executive User). When a service account has multiple charges (e.g. Executive User + Collaboration User add-on), the cost is the sum of all charges on that serviceId.

This means a DID with an attached endpoint produces two engineering records: one for the number rental and one for the endpoint license. This matches how Access4 bills — DID charges and user license charges are separate line items.

Pricing Model

PracBill uses a three-tier pricing hierarchy to determine the retail price (monthlyfee) for each engineering record:

1. Price Book Override (highest priority)

If the customer has a price_book_id set, PracBill looks up the price book for a service-type-specific override. This lets you set custom retail prices per customer.

2. Service Type List Price

If the service type (eng_typeservices) has a list_price set, that value is used as the retail price. For example, you might set list_price = $1.00 on the "DID Number" service type to charge $1/month per DID regardless of the wholesale cost.

3. Wholesale Pass-Through (default)

If neither a price book override nor a service type list price exists, the retail price equals the wholesale cost from Access4. This ensures you never undercharge — at worst you break even.

How to Set Pricing

For most services: Leave list_price empty on the service type. The sync will charge retail = wholesale automatically. If Access4 changes their wholesale price, your retail updates on the next sync.

To charge more than wholesale: Set list_price on the service type (e.g. DID Numbers at $1.00 when wholesale is $0.35). This is a one-time setup.

For customer-specific pricing: Create a price book, set per-service-type prices, and assign the price book to the customer.

Important: The sync never auto-sets list_price when creating new service types. New products always start with wholesale pass-through until you explicitly set a list price.

Service Types and Products

Each Access4 billing product (identified by productId) maps to a PracBill service type via the vendor_product_id field. The sync auto-creates service types when it encounters new products.

Common products and their typical wholesale ranges:

Product

Description

Wholesale Range

Product

Description

Wholesale Range

6408

Executive User

$15 – $35

6414

Collaboration User

$25 – $40

6405

Office User

$10 – $25

6492

DID Number (1)

$0.35 – $1.00

6495

DID Number Block (10)

$3.51 – $10

6498

DID Number Block (100)

$35 – $39

6486

Business Trunk

$8.97 – $50

Customer Mapping

Default: One PracBill Customer per Enterprise (Rollup Mode)

By default, each Sasboss enterprise becomes a single PracBill customer. All groups, sites, and services under that enterprise roll up to that single customer. This is what you want for the vast majority of customers — one bill, one customer record.

Opt-In: Split by Group (One PracBill Customer per Site)

Some customers have multiple sites/branches/locations in Access4 (configured as "groups" in Sasboss) and want each site billed as its own PracBill customer. For these cases, you enable the split by group option on the parent customer.

When enabled:

  • The parent (enterprise) customer still exists

  • Each Sasboss group creates its own PracBill customer, named Enterprise Name - Group Name

  • DID blocks and service accounts are attached to the group customer they belong to

  • Any DIDs/services that aren't tied to a specific group stay on the parent customer

How to Enable Split-by-Group

Option 1 — By customer name (easiest)

php artisan access4:enable-split-by-group {deptId} "Customer Name 1" "Customer Name 2"

Example:

php artisan access4:enable-split-by-group 165 "Melbourne Racing Club" "Estia" "Iron Mountain" "Calvary Health"

The command will:

  1. Authenticate with Sasboss and fetch the enterprise list

  2. For each name, find the matching Sasboss enterprise (case-insensitive substring match)

  3. Find or create the Access4 enterprise mapping

  4. Insert a config mapping with external_source = 'access4_config' and external_id = 'split_by_group'

Option 2 — By customer ID

php artisan access4:enable-split-by-group 165 --cid=7088777

Disabling Split-by-Group

php artisan access4:enable-split-by-group 165 "Melbourne Racing Club" --disable

Important: When you disable split-by-group, the next sync rolls everything back under the parent customer. Group customer services get terminated and re-created on the parent.

After Changing Configuration

After enabling/disabling split-by-group or changing service type pricing, run the sync to apply:

# Single enterprise (fast) php artisan access4:sync-services 165 --enterprise-id=5656 # Full sync php artisan access4:sync-services 165

Cleanup Command

Roll back group customers that were created incorrectly:

# Preview php artisan access4:cleanup-group-customers 165 --dry-run # Apply php artisan access4:cleanup-group-customers 165

Safety features:

  • Skips customers with invoices or quotes

  • Re-homes engineering records to the parent enterprise customer

  • Soft-deletes the group customer and mapping

Billing Gap Report

Compare what Access4 bills you vs what PracBill has captured:

php artisan access4:billing-gap-report 165 --top=20 php artisan access4:billing-gap-report 165 --csv=gap_report.csv

Typical Setup Checklist

  1. Ensure the Access4 integration is configured and credentials are valid

  2. Set list_price on service types where you want to charge more than wholesale (e.g. DID Numbers at $1.00)

  3. Run access4:sync-services {deptId} to import all services

  4. Review the billing gap report to verify totals match

  5. For multi-site customers, run access4:enable-split-by-group as needed

  6. Done — nightly sync keeps everything current

Troubleshooting

Symptom

Cause

Fix

Symptom

Cause

Fix

Retail = wholesale for all services

No list_price set on service type

This is correct default behaviour. Set list_price where you want higher retail

Customer has too many engineering records

Groups are being split per-site

Check if split_by_group is enabled; disable if not needed

Missing services after sync

New product type not yet matched

Check if a new service type was auto-created; set pricing if needed

Duplicate customers

Access4 name differs from import name

Use the cleanup command or manually merge

Auth fails (HTTP 401)

Credentials expired or APP_KEY changed

Re-save credentials in the Integrations UI

Reference

  • Enterprise mapping: external_source = 'access4', external_id = 'enterprise:{id}'

  • Group mapping: external_source = 'access4', external_id = 'group:{id}'

  • Split-by-group flag: external_source = 'access4_config', external_id = 'split_by_group'

  • Nightly schedule: 00:30 daily via access4:sync-all

  • Pricing resolution: Price book → Service type list_price → Wholesale pass-through