Sales Module
Overview
The Sales module is responsible for managing all sales-related data, including orders, order lines, time tracking, categorisation and status workflows. It defines how sales are created, processed, and tracked within the system.
Sales is a foundational module and is required for:
- recording customer orders
- processing individual order lines
- managing order statuses and types
- time tracking against orders
- tracking payments, dispatch, and fulfillment
- auditing all sales activity
All operations are tenant-aware and scoped to the current tenant.
Services
The Sales module consists of the following services:
- Sales Orders - customer orders with full details
- Sales Order Lines - individual items within an order
- Sales Order Types - categorisation of orders (e.g., credit or standard)
- Sales Order Categories - grouping/classification for orders
- Sales Order Action Statuses - configurable action status definitions
- Sales Order Action Status Map - status history log per order
- Sales Order Time Task Types - types of billable/trackable work
- Sales Order Time Entries - time logged against an order
Models
This module exposes and consumes the following models:
- Sales Order Model
- Sales Order Line Model
- Sales Order Type Model
- Sales Order Category Model
- Sales Order Action Status Model
- Sales Order Action Status Map Model
- Sales Order Time Task Type Model
- Sales Order Time Entry Model
Sales Order Model
Represents a customer sales order.
Fields:
Id (type: long)- internal identifierOrderNumber (type: string?)- order reference numberEntityId (type: long?)- customer entity identifierStatusId (type: int?)- order statusOrderDate (type: DateTime?)- order creation dateCurrency (type: string?)- order currencyBillingAddressId (type: long?)- billing address referenceShippingAddressId (type: long?)- shipping address referencePriceListId (type: long?)- price list appliedSubtotal (type: decimal?)- subtotal amountTaxTotal (type: decimal?)- tax totalShippingTotal (type: decimal?)- shipping totalGrandTotal (type: decimal?)- final order totalNotes (type: string?)- additional notesCreatedAt (type: DateTime?)- creation timestampPromotionId (type: int?)- applied promotionPaidDate (type: DateTime?)- payment dateCompletedDate (type: DateTime?)- order completion dateDispatchDate (type: DateTime?)- dispatch/shipping dateCourier (type: string?)- courier nameCourierRef (type: string?)- courier reference numberSalesOrderTypeId (type: int?)- order typeSalesOrderCategoryId (type: int?)- order categoryUserId (type: long?)- user who created the orderInProgressDate (type: DateTime?)- date order moved to in-progressPurchaseOrderRef (type: string?)- customer PO referenceAdditionalRef (type: string?)- secondary referenceTags (type: string?)- comma-separated tagsDescription (type: string?)- order description (unlimited length)ActionNotes (type: string?)- internal action notes (unlimited length)Other1 (type: string?)- configurable field 1Other2 (type: string?)- configurable field 2Other3 (type: string?)- configurable field 3OtherNotes (type: string?)- additional notes (unlimited length)BillingSnapshot (type: SalesOrderAddressSnapshotModel?)- stamped billing address at time of orderShippingSnapshot (type: SalesOrderAddressSnapshotModel?)- stamped shipping address at time of order
Validation:
IsReadyToAdd()- requires
EntityId,OrderNumber,OrderDate,Currency,SalesOrderTypeId,GrandTotal >= 0
- requires
IsReadyToUpdate()- requires
Id > 0,EntityId > 0,SalesOrderTypeId > 0
- requires
Sales Order Line Model
Represents an individual line item within a sales order.
Fields:
Id (type: long)- internal identifierSalesOrderId (type: long?)- parent sales orderLineNumber (type: int?)- line sequence numberProductId (type: long?)- ordered product identifierDescription (type: string?)- line descriptionQuantity (type: decimal?)- quantity orderedUnitPrice (type: decimal?)- price per unitDiscountAmount (type: decimal?)- discount appliedTaxAmount (type: decimal?)- tax appliedLineTotal (type: decimal?)- line total after discounts and taxWarehouseId (type: long?)- warehouse referenceEntityUserId (type: long?)- user who created the lineNotes (type: string?)- additional notesQuantityFulfilled (type: decimal?)- fulfilled quantityQuantityReturned (type: decimal?)- returned quantityReturnedDate (type: DateTime?)- date of return
Validation:
IsReadyToAdd()- requires
SalesOrderId,LineNumber,ProductId,Quantity > 0,UnitPrice >= 0,LineTotal >= 0
- requires
IsReadyToUpdate()- requires
Id > 0,SalesOrderId > 0,ProductId > 0,Quantity >= 0,UnitPrice >= 0
- requires
Sales Order Type Model
Represents a category/type of sales order.
Fields:
Id (type: int)- internal identifierTitle (type: string?)- order type nameIsCredit (type: bool?)- indicates if order is credit type
Validation:
IsReadyToAdd()- requiresTitleIsReadyToUpdate()- requiresId > 0,Title
Notes:
- Only one Sales Order Type can exist per title
Sales Order Category Model
Represents a grouping or classification label for sales orders.
Fields:
Id (type: int)- internal identifierName (type: string?)- category nameDescription (type: string?)- optional descriptionSortOrder (type: int)- display orderIsActive (type: bool)- active flagCreatedAt (type: DateTime?)- creation timestamp
Validation:
IsReadyToAdd()- requiresNameIsReadyToUpdate()- requiresId > 0,Name
Notes:
- Only one category can exist per name
Sales Order Action Status Model
Represents a configurable action status that can be applied to a sales order (e.g., Pending Review, Approved, On Hold).
Fields:
Id (type: int)- internal identifierName (type: string?)- status nameDescription (type: string?)- optional descriptionSortOrder (type: int)- display orderIsActive (type: bool)- active flagCreatedAt (type: DateTime?)- creation timestamp
Validation:
IsReadyToAdd()- requiresNameIsReadyToUpdate()- requiresId > 0,Name
Sales Order Action Status Map Model
Represents a status assignment on a specific sales order — acts as a status history log.
Fields:
Id (type: int)- internal identifierSalesOrderId (type: int)- parent sales orderActionStatusId (type: int)- applied action statusNotes (type: string?)- optional notesCreatedByUserId (type: int?)- user who applied the statusCreatedAt (type: DateTime?)- timestamp when applied
Validation:
IsReadyToAdd()- requiresSalesOrderId > 0,ActionStatusId > 0IsReadyToUpdate()- requiresId > 0,SalesOrderId > 0,ActionStatusId > 0
Notes:
- Multiple status entries per order are allowed — full history is preserved
Sales Order Time Task Type Model
Represents a category of work that can be time-tracked against a sales order (e.g., Design, Development, Support).
Fields:
Id (type: int)- internal identifierName (type: string?)- task type nameDescription (type: string?)- optional descriptionSortOrder (type: int)- display orderIsActive (type: bool)- active flagCreatedAt (type: DateTime?)- creation timestamp
Validation:
IsReadyToAdd()- requiresNameIsReadyToUpdate()- requiresId > 0,Name
Sales Order Time Entry Model
Represents a block of time logged by a user against a sales order.
Fields:
Id (type: int)- internal identifierSalesOrderId (type: int)- parent sales orderUserId (type: int)- user who performed the workTaskTypeId (type: int)- type of work performedWorkDate (type: DateOnly?)- date the work was performedTotalMinutes (type: int)- duration in minutesNotes (type: string?)- optional notesCreatedByUserId (type: int?)- user who created the entryCreatedAt (type: DateTime?)- creation timestamp
Validation:
IsReadyToAdd()- requiresSalesOrderId > 0,UserId > 0,TaskTypeId > 0,TotalMinutes > 0,WorkDateIsReadyToUpdate()- requiresId > 0,SalesOrderId > 0,UserId > 0,TaskTypeId > 0