Custom Reports

Configure custom data export reports with flexible column mapping, data types, and role-based access control.

Overview

Custom Reports allow you to define tailored data export configurations for various entity types in Omnium. Each custom report specifies which data columns to include, how to format them, and where the report should be available. Reports can be exported in multiple formats including Excel, CSV, HTML, and PDF.

Custom Reports are configured in Tenant Settings under Report Settings and appear in context menus throughout the application wherever data export is available.


Configuration Model

Custom Reports are stored in the ReportSettings.CustomReports section of Tenant Settings. Each custom report is defined by a CustomReport object with the following properties:

CustomReport Properties

PropertyTypeRequiredDescription
IdstringYesUnique identifier for the report (typically a UUID)
ReportNamestringYesDisplay name shown in the UI
ReportNameTranslationKeystringNoTranslation key for localized report name
DescriptionstringNoDescription of the report's purpose
DescriptionTranslateKeystringNoTranslation key for localized description
ReportTypestringYesThe entity type this report exports (see Report Types below)
ReportAreasList<string>YesUI areas where this report is available (see Report Areas below)
ReportPropertiesList<CustomReportProperty>YesColumn definitions for the report
OptionalDataList<string>NoAdditional related data to include (see Optional Data below)
RolesList<string>NoRole restrictions for accessing this report

CustomReportProperty Properties

Each column in the report is defined by a CustomReportProperty:

PropertyTypeRequiredDescription
PropertystringYesProperty path to export (e.g., Order.OrderNumber, Order.Properties.CustomField)
NamestringYesColumn header display name
TranslationKeystringNoTranslation key for localized column header
DataTypestringNoData type for formatting: String, Number, Date, or Formula
DataFormatstringNoFormat specification (e.g., timezone for dates)
WidthintNoColumn width in Excel export (default: 35)
PrefixstringNoText prefix to prepend to values

Report Types

The ReportType property determines which entity the report exports and which properties are available. Supported report types:

Report TypeDescription
OrderOrder header data
OrderLineIndividual order line items
OrderErrorOrder error records (one row per error)
ShipmentShipment-level data
ReturnReturn order data
ReturnOrderLineReturn order line items
ProductProduct master data
VariantProduct variant data
PricePrice information
AssetDigital assets
StoreStore/location data
EmployeeEmployee data
CartShopping cart data
CartShipmentCart shipment data
CartOrderLineCart line items
BusinessCustomerB2B customer data
ContactPersonBusiness customer contacts
PrivateCustomerB2C customer data
ConsentCustomer consent records
ProjectProject data
PurchaseOrderPurchase order headers
PurchaseOrderLinePurchase order lines
InventoryItemInventory stock data
InventoryTransactionInventory movement history
DeliveryDelivery data
DeliveryLineDelivery line items
AnalyticsOrderLineAnalytics-specific order line data
ProductSalesProduct data combined with sales analytics and inventory KPIs for a date range
GiftCardGift card data

ProductSales Report Type

The ProductSales report type is a specialized report that combines product master data with sales analytics and inventory metrics for a selected date range. It produces one row per SKU (either a product with IsSku = true or individual variants of a parent product) and computes a wide range of KPIs useful for merchandising, purchasing, logistics, and finance.

How it works

  1. When exporting, the user is prompted to select a date range (From / To)
  2. The report iterates all products matching the current search filters
  3. For each SKU, it queries analytics order lines (grouped by SkuId) and inventory transactions for the start and end of the selected period
  4. Calculated KPIs are derived from these data sources

The report is available in the ProductList area.

Available Properties

All properties use the prefix ProductWithSalesDataViewModel. in the property path configuration.

Product Attributes

PropertyTypeDescription
ProductIdStringProduct identifier (falls back to parent if empty on variant)
NameStringProduct name (falls back to parent)
SkuIdStringSKU identifier
EanStringEAN / barcode (falls back to parent)
CatalogStringTop-level catalog name (falls back to parent)
SubCatalogStringCatalog nodes joined by comma (falls back to parent)
MainCategoryNameStringPrimary category name (falls back to parent)
BrandStringBrand name (falls back to parent)
SupplierStringSupplier name (falls back to parent)
SupplierIdStringSupplier identifier (falls back to parent)
SupplierSkuIdStringSupplier's article number (falls back to parent)
ColorStringColor attribute (falls back to parent)
SizeStringSize attribute (falls back to parent)
GenderStringGender attribute (falls back to parent)
SeasonStringSeason code (falls back to parent)
CountryOfOriginStringCountry of origin (falls back to parent)
WeightNumberProduct weight (falls back to parent)
IsActiveBooleanWhether the product is active
CostNumberUnit cost price
ListPriceNumberList price from default price or first price entry
ReorderMinQuantityNumberReorder point / minimum stock level
LeadTimeNumberLead time in days (falls back to parent)
SupplierLeadTimeNumberSupplier lead time in days (falls back to parent)
CreatedDateProduct creation date (falls back to parent)
PublishedDateProduct publication date (falls back to parent)
DiscontinuedDateDiscontinuation date (falls back to parent)

Sales Metrics

These values come from analytics order lines grouped by SKU for the selected date range.

PropertyTypeDescription
RevenueExTaxNumberTotal revenue excluding tax
RevenueIncTaxNumberTotal revenue including tax
TotalUnitsSoldNumberTotal units ordered
TotalUnitsReturnedNumberTotal units returned
TotalUnitsCancelledNumberTotal units cancelled
DeliveredQuantityNumberTotal units delivered
CogsNumberCost of goods sold (total cost from order lines)
GrossProfitNumberGross profit (from analytics)
AverageOrderValueNumberAverage order value for orders containing this SKU
CurrencyStringCurrency code from order data

Inventory Metrics

Inventory data is derived from inventory transactions at the start and end of the selected period.

PropertyTypeDescription
InventoryNumberInventory quantity at end of period
InventoryAtStartOfPeriodNumberInventory quantity at start of period
InventoryValueNumberEnd-of-period inventory value (Inventory * Cost)

Calculated KPIs — Profitability

PropertyTypeFormulaDescription
GrossProfitPercentageNumber(RevenueExTax - Cogs) / RevenueExTax * 100Gross margin as a percentage of revenue
MarkupPercentageNumber(RevenueExTax - Cogs) / Cogs * 100Markup over cost
ContributionMarginPerUnitNumber(RevenueExTax - Cogs) / TotalUnitsSoldProfit contribution per unit sold
GmroiNumber(RevenueExTax - Cogs) / (AvgInventory * Cost)Gross Margin Return on Inventory Investment

Calculated KPIs — Sales

PropertyTypeFormulaDescription
NetUnitsSoldNumberTotalUnitsSold - TotalUnitsReturned - TotalUnitsCancelledActual net units sold
AverageSellingPriceNumberRevenueExTax / TotalUnitsSoldAverage selling price excluding tax
AverageSellingPriceIncTaxNumberRevenueIncTax / TotalUnitsSoldAverage selling price including tax

Calculated KPIs — Returns & Fulfillment

PropertyTypeFormulaDescription
ReturnRateNumberTotalUnitsReturned / TotalUnitsSold * 100Return rate as percentage
CancellationRateNumberTotalUnitsCancelled / TotalUnitsSold * 100Cancellation rate as percentage
FulfillmentRateNumberDeliveredQuantity / TotalUnitsSold * 100Fulfillment rate as percentage

Calculated KPIs — Inventory & Logistics

PropertyTypeFormulaDescription
TurnoverRateNumberTotalUnitsSold / AvgInventoryInventory turnover for the period
AnnualizedTurnoverRateNumberTurnoverRate * 365 / DaysInPeriodTurnover rate projected to a full year
AvarageStorageTimeNumberDaysInPeriod / TurnoverRateAverage days in stock before being sold
SellThroughRateNumberTotalUnitsSold / (TotalUnitsSold + Inventory) * 100Percentage of available stock that was sold
DaysOfSupplyNumberInventory / (NetUnitsSold / DaysInPeriod)Days of stock remaining at current sales rate
WeeksOfSupplyNumberInventory / (NetUnitsSold / DaysInPeriod * 7)Weeks of stock remaining at current sales rate

AvgInventory in the formulas above refers to the average of inventory at the start and end of the selected period: (InventoryAtStartOfPeriod + Inventory) / 2. Division-by-zero scenarios (e.g., no sales, no inventory) are handled by returning 0.

Example Configuration

A product sales report for merchandising analysis:

{
    "Id": "e5f6a7b8-c9d0-1234-efab-567890123456",
    "ReportName": "Product Sales Analysis",
    "Description": "Sales performance with profitability and inventory KPIs per SKU",
    "ReportType": "ProductSales",
    "ReportAreas": ["ProductList"],
    "ReportProperties": [
        {
            "Property": "ProductWithSalesDataViewModel.ProductId",
            "Name": "Product ID",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "ProductWithSalesDataViewModel.Name",
            "Name": "Product Name",
            "DataType": "String",
            "Width": 40
        },
        {
            "Property": "ProductWithSalesDataViewModel.SkuId",
            "Name": "SKU",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "ProductWithSalesDataViewModel.Brand",
            "Name": "Brand",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "ProductWithSalesDataViewModel.MainCategoryName",
            "Name": "Category",
            "DataType": "String",
            "Width": 25
        },
        {
            "Property": "ProductWithSalesDataViewModel.TotalUnitsSold",
            "Name": "Units Sold",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.NetUnitsSold",
            "Name": "Net Units Sold",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.RevenueExTax",
            "Name": "Revenue (ex. tax)",
            "DataType": "Number",
            "Width": 18
        },
        {
            "Property": "ProductWithSalesDataViewModel.GrossProfitPercentage",
            "Name": "Gross Margin %",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.ReturnRate",
            "Name": "Return Rate %",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.SellThroughRate",
            "Name": "Sell-Through %",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.Gmroi",
            "Name": "GMROI",
            "DataType": "Number",
            "Width": 12
        },
        {
            "Property": "ProductWithSalesDataViewModel.WeeksOfSupply",
            "Name": "Weeks of Supply",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "ProductWithSalesDataViewModel.Inventory",
            "Name": "Current Stock",
            "DataType": "Number",
            "Width": 15
        }
    ],
    "Roles": ["Admin", "Merchandiser", "PurchaseManager"]
}

Report Areas

The ReportAreas property controls where the custom report appears in the UI. A report can be available in multiple areas.

List Views

AreaDescription
OrderListOrder list view
ReturnListReturn order list view
ProductListProduct list view
CartListCart list view
StoreListStore list view
BusinessCustomerListBusiness customer list view
PrivateCustomerListPrivate customer list view
ProjectListProject list view
PurchaseOrderListPurchase order list view
DeliveryListDelivery list view
GiftCardListGift card list view

Detail Views

AreaDescription
PurchaseOrderPurchase order detail view
DeliveryDelivery detail view

Report Center

AreaDescription
ReportOrdersOrder reports section
ReportProductsProduct reports section
ReportStoresStore reports section
ReportAnalyticsOrderLineAnalytics order line reports
ReportInventoryInventory reports section
ReportInventoryTransactionsInventory transaction reports

Data Types

The DataType property controls how column values are formatted in the export:

Data TypeDescriptionUse Case
StringPlain text (default)Names, descriptions, IDs
NumberNumeric formattingQuantities, prices, counts
DateDate/time formatting with timezone supportOrder dates, timestamps
FormulaExcel formula with row indexingCalculated fields

Date Formatting

When using the Date data type, specify a timezone in the DataFormat property:

{
    "Property": "Order.Created",
    "Name": "Order Date",
    "DataType": "Date",
    "DataFormat": "Europe/Oslo"
}

Formula Support

For Excel exports, you can include formulas that reference the current row using [i] as a placeholder for the row index:

{
    "Property": "",
    "Name": "Line Total",
    "DataType": "Formula",
    "DataFormat": "=E[i]*F[i]"
}

Optional Data

The OptionalData property allows including related entity data in the export. This is useful when the report type doesn't include all the data you need.

Optional DataAvailable ForDescription
ShipmentsOrder reportsInclude shipment data with order exports
ReturnsOrder reportsInclude return data with order exports
ProductsOrder reportsInclude full product data with order line exports

Role-Based Access Control

The Roles property restricts which users can access the report. When configured:

  • Only users with at least one of the specified roles can see and use the report
  • Users with the Admin role always have access regardless of restrictions
  • If Roles is empty or not specified, the report is available to all users

Example:

{
    "Roles": ["OrderManager", "ReportViewer", "FinanceTeam"]
}

UI Configuration

Custom Reports are configured in the Omnium UI under Administration > Tenant Settings > Report Settings.

Creating a New Report

  1. Navigate to Administration > Tenant Settings > Report Settings
  2. Click Add to create a new custom report
  3. Fill in the report details:
    • Type: Select the entity type (Order, Product, etc.)
    • Name: Enter a display name
    • Description: Optionally describe the report's purpose
    • Area: Select one or more UI areas where the report should appear
    • Optional Data: Select additional data to include if needed
    • Roles: Optionally restrict access to specific roles
    • ID: A unique identifier is auto-generated but can be customized

Configuring Report Columns

After creating the report, expand it to configure columns:

  1. Click the expand arrow on the report row

  2. Click Add to add a new column

  3. Configure the column:

    • Name: Column header text
    • Property: Property path (use dot notation for nested properties)
    • Width: Column width for Excel exports
    • Type: Data type (String, Number, Date, Formula)
    • Data Format: Format specification (timezone for dates, formula for calculated fields)
    • Prefix: Optional text prefix
  4. Drag and drop columns to reorder them

  5. Click the delete icon to remove columns

Property Path Syntax

Properties support dot notation to access nested data:

PatternExampleDescription
Direct propertyOrderNumberTop-level entity property
Nested objectOrder.Customer.EmailProperty from related entity
Custom propertiesOrder.Properties.CustomFieldCustom property value
External IDsOrder.ExternalIds.ErpOrderIdExternal ID by key

OrderError Property Paths

The OrderError report type generates one row per error on each order. Properties use the following prefixes:

PrefixDescription
EntityError.*Error properties (Key, Message, Details, Severity, Occured, Status, Comment, ReferenceId)
Order.*Order properties (supports Properties, ExternalIds, CustomProperties)

Example property paths for OrderError reports:

  • EntityError.Key - Error key/code
  • EntityError.Message - Error message
  • EntityError.Severity - Error severity level
  • EntityError.Occured - When the error occurred
  • EntityError.Status - Current error status
  • Order.OrderNumber - Associated order number
  • Order.Properties.CustomField - Custom order property

Example Configuration

Basic Order Report

A simple order report with core order information:

{
    "Id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "ReportName": "Order Summary Report",
    "Description": "Basic order information for customer service",
    "ReportType": "Order",
    "ReportAreas": ["OrderList", "ReportOrders"],
    "ReportProperties": [
        {
            "Property": "OrderNumber",
            "Name": "Order #",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "Created",
            "Name": "Order Date",
            "DataType": "Date",
            "DataFormat": "Europe/Oslo",
            "Width": 25
        },
        {
            "Property": "Customer.Email",
            "Name": "Customer Email",
            "DataType": "String",
            "Width": 40
        },
        {
            "Property": "GrandTotal",
            "Name": "Total",
            "DataType": "Number",
            "Width": 15,
            "Prefix": "NOK "
        },
        {
            "Property": "Status",
            "Name": "Status",
            "DataType": "String",
            "Width": 20
        }
    ],
    "Roles": []
}

Order Lines Report with Products

A detailed order lines report including product information:

{
    "Id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "ReportName": "Detailed Order Lines",
    "Description": "Order lines with full product details for inventory analysis",
    "ReportType": "OrderLine",
    "ReportAreas": ["OrderList", "ReportOrders"],
    "OptionalData": ["Products"],
    "ReportProperties": [
        {
            "Property": "Order.OrderNumber",
            "Name": "Order #",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "ProductId",
            "Name": "SKU",
            "DataType": "String",
            "Width": 25
        },
        {
            "Property": "ProductName",
            "Name": "Product Name",
            "DataType": "String",
            "Width": 50
        },
        {
            "Property": "Quantity",
            "Name": "Qty",
            "DataType": "Number",
            "Width": 10
        },
        {
            "Property": "UnitPrice",
            "Name": "Unit Price",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "LineTotal",
            "Name": "Line Total",
            "DataType": "Number",
            "Width": 15
        }
    ],
    "Roles": ["OrderManager", "FinanceTeam"]
}

Order Errors Report

A report showing all order errors for troubleshooting:

{
    "Id": "d4e5f6a7-b8c9-0123-defg-456789012345",
    "ReportName": "Order Errors Report",
    "Description": "Export order errors for troubleshooting and analysis",
    "ReportType": "OrderError",
    "ReportAreas": ["OrderList", "ReportOrders"],
    "ReportProperties": [
        {
            "Property": "Order.OrderNumber",
            "Name": "Order #",
            "DataType": "String",
            "Width": 20
        },
        {
            "Property": "EntityError.Key",
            "Name": "Error Code",
            "DataType": "String",
            "Width": 25
        },
        {
            "Property": "EntityError.Message",
            "Name": "Error Message",
            "DataType": "String",
            "Width": 60
        },
        {
            "Property": "EntityError.Severity",
            "Name": "Severity",
            "DataType": "String",
            "Width": 15
        },
        {
            "Property": "EntityError.Occured",
            "Name": "Occurred",
            "DataType": "Date",
            "DataFormat": "Europe/Oslo",
            "Width": 25
        },
        {
            "Property": "EntityError.Status",
            "Name": "Status",
            "DataType": "String",
            "Width": 15
        }
    ],
    "Roles": ["Admin", "OrderManager"]
}

Inventory Report with Custom Properties

An inventory report with store-specific custom fields:

{
    "Id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
    "ReportName": "Warehouse Inventory",
    "ReportNameTranslationKey": "Reports_WarehouseInventory",
    "Description": "Current inventory levels with warehouse location data",
    "ReportType": "InventoryItem",
    "ReportAreas": ["ReportInventory"],
    "ReportProperties": [
        {
            "Property": "ProductId",
            "Name": "SKU",
            "DataType": "String",
            "Width": 25
        },
        {
            "Property": "StoreName",
            "Name": "Warehouse",
            "DataType": "String",
            "Width": 30
        },
        {
            "Property": "Available",
            "Name": "Available Qty",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "Reserved",
            "Name": "Reserved Qty",
            "DataType": "Number",
            "Width": 15
        },
        {
            "Property": "Properties.BinLocation",
            "Name": "Bin Location",
            "DataType": "String",
            "Width": 20
        }
    ],
    "Roles": ["WarehouseManager", "InventoryTeam"]
}

How Reports Work

When a user exports a custom report, the following process occurs:

  1. Report Selection: User selects a custom report from the context menu in a supported UI area
  2. Access Validation: System verifies the user has access based on configured roles
  3. Data Query: The appropriate data export service queries data based on the current search/filter criteria
  4. Report Building: The report builder constructs the export based on configured properties:
    • Resolves property paths to actual values
    • Applies data type formatting
    • Handles optional data inclusion
    • Processes formulas and prefixes
  5. Export Generation: The report is generated in the requested format (Excel, CSV, HTML, or PDF)
  6. Download: The exported file is streamed to the user

Best Practices

Report Design

  • Keep reports focused: Create multiple smaller reports rather than one large report with many columns
  • Use meaningful names: Choose clear report names that describe the purpose and content
  • Consider performance: Reports with optional data (Shipments, Returns, Products) require additional queries
  • Set appropriate widths: Configure column widths for readable Excel exports

Property Mapping

  • Use dot notation carefully: Ensure the property path is valid for the selected report type
  • Test custom properties: Verify custom property keys exist before including in reports
  • Handle missing data: Properties that don't exist will export as empty cells

Access Control

  • Apply least privilege: Only grant report access to roles that need the data
  • Use role groups: Create role groups for common report access patterns
  • Document restrictions: Include access information in report descriptions