Enhance Dashboard Components with Additional Statistics and History Displays
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Expanded FinanceOverview, InventoryOverview, and SalesOverview components to include new statistics and history displays for various object types, improving data visibility. - Added support for tax record statistics, payment history, and invoice history in FinanceOverview. - Introduced stock transfer, shipment, and part stock history statistics in InventoryOverview. - Enhanced SalesOverview with order item statistics and shipment history, providing a more comprehensive view of sales data. - Updated ModelHistoryDisplay to support dynamic history groups, improving flexibility in data representation. - Refactored various model definitions to include new statistical measures, enhancing the overall data model structure.
This commit is contained in:
parent
b347ec3637
commit
eb61700248
@ -1,9 +1,22 @@
|
|||||||
import DashboardOverviewPage from '../common/DashboardOverviewPage'
|
import DashboardOverviewPage from '../common/DashboardOverviewPage'
|
||||||
import StatsDisplay from '../common/StatsDisplay'
|
import StatsDisplay from '../common/StatsDisplay'
|
||||||
|
import ModelHistoryDisplay from '../common/ModelHistoryDisplay'
|
||||||
|
import ObjectTable from '../common/ObjectTable'
|
||||||
|
|
||||||
const collapseDefaults = {
|
const collapseDefaults = {
|
||||||
invoiceStats: true,
|
invoiceStats: true,
|
||||||
paymentStats: true
|
paymentStats: true,
|
||||||
|
taxRecordStats: true,
|
||||||
|
invoiceCountHistory: true,
|
||||||
|
invoiceAmountHistory: true,
|
||||||
|
paymentCountHistory: true,
|
||||||
|
paymentAmountHistory: true,
|
||||||
|
taxRecordCountHistory: true,
|
||||||
|
taxRecordAmountHistory: true,
|
||||||
|
overdueInvoices: true,
|
||||||
|
partiallyPaidInvoices: true,
|
||||||
|
dueInvoices: true,
|
||||||
|
authorisedPayments: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const sections = [
|
const sections = [
|
||||||
@ -18,6 +31,135 @@ const sections = [
|
|||||||
title: 'Payment Statistics',
|
title: 'Payment Statistics',
|
||||||
className: 'no-t-padding-collapse',
|
className: 'no-t-padding-collapse',
|
||||||
content: <StatsDisplay objectType='payment' />
|
content: <StatsDisplay objectType='payment' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'taxRecordStats',
|
||||||
|
title: 'Tax Record Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='taxRecord' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'invoiceHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'invoiceCountHistory',
|
||||||
|
title: 'Invoice Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='invoice' historyGroup='count' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'invoiceAmountHistory',
|
||||||
|
title: 'Invoice Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='invoice' historyGroup='amount' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'paymentHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'paymentCountHistory',
|
||||||
|
title: 'Payment Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='payment' historyGroup='count' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'paymentAmountHistory',
|
||||||
|
title: 'Payment Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='payment' historyGroup='amount' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'taxRecordHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'taxRecordCountHistory',
|
||||||
|
title: 'Tax Record Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='taxRecord' historyGroup='count' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'taxRecordAmountHistory',
|
||||||
|
title: 'Tax Record Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='taxRecord' historyGroup='amount' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'overdueAndPartiallyPaidInvoicesRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'overdueInvoices',
|
||||||
|
title: 'Overdue Invoices',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='invoice' masterFilter={{ state: 'overdue' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'partiallyPaidInvoices',
|
||||||
|
title: 'Partially Paid Invoices',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='invoice'
|
||||||
|
masterFilter={{ state: 'partiallyPaid' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'dueInvoicesAndAuthorisedPaymentsRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'dueInvoices',
|
||||||
|
title: 'Due Invoices',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='invoice' masterFilter={{ state: 'sent' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'authorisedPayments',
|
||||||
|
title: 'Authorised Payments',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='payment' masterFilter={{ state: 'authorised' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -9,15 +9,28 @@ const collapseDefaults = {
|
|||||||
productStockStats: true,
|
productStockStats: true,
|
||||||
purchaseOrderStats: true,
|
purchaseOrderStats: true,
|
||||||
stockEventStats: true,
|
stockEventStats: true,
|
||||||
partStockHistory: true,
|
stockTransferStats: true,
|
||||||
|
stockLocationStats: true,
|
||||||
|
shipmentStats: true,
|
||||||
|
partStockCountHistory: true,
|
||||||
|
partStockValueHistory: true,
|
||||||
newPartStocks: true,
|
newPartStocks: true,
|
||||||
filamentStockHistory: true,
|
filamentStockCountHistory: true,
|
||||||
|
filamentStockValueHistory: true,
|
||||||
unconsumedFilamentStocks: true,
|
unconsumedFilamentStocks: true,
|
||||||
productStockHistory: true,
|
productStockCountHistory: true,
|
||||||
|
productStockValueHistory: true,
|
||||||
draftProductStocks: true,
|
draftProductStocks: true,
|
||||||
purchaseOrderHistory: true,
|
purchaseOrderCountHistory: true,
|
||||||
|
purchaseOrderAmountHistory: true,
|
||||||
draftPurchaseOrders: true,
|
draftPurchaseOrders: true,
|
||||||
stockEventHistory: true
|
stockEventHistory: true,
|
||||||
|
stockTransferHistory: true,
|
||||||
|
draftStockTransfers: true,
|
||||||
|
sentPurchaseOrders: true,
|
||||||
|
usedPartStocks: true,
|
||||||
|
plannedShipments: true,
|
||||||
|
shippedInboundShipments: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const sections = [
|
const sections = [
|
||||||
@ -52,24 +65,82 @@ const sections = [
|
|||||||
content: <StatsDisplay objectType='stockEvent' />
|
content: <StatsDisplay objectType='stockEvent' />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'partAndFilamentHistoryRow',
|
key: 'stockTransferStats',
|
||||||
|
title: 'Stock Transfer Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='stockTransfer' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'stockLocationStats',
|
||||||
|
title: 'Stock Location Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='stockLocation' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'shipmentStats',
|
||||||
|
title: 'Shipment Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='shipment' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'partStockHistoryRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'partStockHistory',
|
key: 'partStockCountHistory',
|
||||||
title: 'Part Stock History',
|
title: 'Part Stock Count History',
|
||||||
content: (
|
content: (
|
||||||
<ModelHistoryDisplay objectType='partStock' chartType='line' />
|
<ModelHistoryDisplay
|
||||||
|
objectType='partStock'
|
||||||
|
historyGroup='count'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'filamentStockHistory',
|
key: 'partStockValueHistory',
|
||||||
title: 'Filament Stock History',
|
title: 'Part Stock Quantity History',
|
||||||
content: (
|
content: (
|
||||||
<ModelHistoryDisplay objectType='filamentStock' chartType='line' />
|
<ModelHistoryDisplay
|
||||||
|
objectType='partStock'
|
||||||
|
historyGroup='value'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'filamentStockHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'filamentStockCountHistory',
|
||||||
|
title: 'Filament Stock Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='filamentStock'
|
||||||
|
historyGroup='count'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'filamentStockValueHistory',
|
||||||
|
title: 'Filament Stock Weight History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='filamentStock'
|
||||||
|
historyGroup='value'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -103,23 +174,63 @@ const sections = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'productAndPurchaseOrderHistoryRow',
|
key: 'productStockHistoryRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'productStockHistory',
|
key: 'productStockCountHistory',
|
||||||
title: 'Product Stock History',
|
title: 'Product Stock Count History',
|
||||||
content: (
|
content: (
|
||||||
<ModelHistoryDisplay objectType='productStock' chartType='line' />
|
<ModelHistoryDisplay
|
||||||
|
objectType='productStock'
|
||||||
|
historyGroup='count'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'purchaseOrderHistory',
|
key: 'productStockValueHistory',
|
||||||
title: 'Purchase Order History',
|
title: 'Product Stock Quantity History',
|
||||||
content: <ModelHistoryDisplay objectType='purchaseOrder' />
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='productStock'
|
||||||
|
historyGroup='value'
|
||||||
|
chartType='line'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'purchaseOrderHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'purchaseOrderCountHistory',
|
||||||
|
title: 'Purchase Order Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='purchaseOrder'
|
||||||
|
historyGroup='count'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'purchaseOrderAmountHistory',
|
||||||
|
title: 'Purchase Order Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='purchaseOrder'
|
||||||
|
historyGroup='amount'
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -155,7 +266,7 @@ const sections = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'stockEventHistoryRow',
|
key: 'stockEventAndTransferHistoryRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
@ -166,6 +277,85 @@ const sections = [
|
|||||||
<ModelHistoryDisplay objectType='stockEvent' chartType='line' />
|
<ModelHistoryDisplay objectType='stockEvent' chartType='line' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'stockTransferHistory',
|
||||||
|
title: 'Stock Transfer History',
|
||||||
|
content: <ModelHistoryDisplay objectType='stockTransfer' />
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'draftTransfersAndSentPurchaseOrdersRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'draftStockTransfers',
|
||||||
|
title: 'Draft Stock Transfers',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='stockTransfer'
|
||||||
|
masterFilter={{ state: 'draft' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'sentPurchaseOrders',
|
||||||
|
title: 'Sent Purchase Orders',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='purchaseOrder'
|
||||||
|
masterFilter={{ state: 'sent' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'usedPartsAndPlannedShipmentsRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'usedPartStocks',
|
||||||
|
title: 'Used Part Stocks',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='partStock' masterFilter={{ state: 'used' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'plannedShipments',
|
||||||
|
title: 'Planned Shipments',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='shipment' masterFilter={{ state: 'planned' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'shippedInboundShipmentsRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'shippedInboundShipments',
|
||||||
|
title: 'Inbound Shipments In Transit',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='shipment'
|
||||||
|
masterFilter={{ orderType: 'purchaseOrder', state: 'shipped' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,17 +5,28 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
|
|
||||||
const collapseDefaults = {
|
const collapseDefaults = {
|
||||||
salesOrderStats: true,
|
salesOrderStats: true,
|
||||||
|
orderItemStats: true,
|
||||||
listingStats: true,
|
listingStats: true,
|
||||||
marketplaceStats: true,
|
marketplaceStats: true,
|
||||||
clientStats: true,
|
clientStats: true,
|
||||||
salesOrderHistory: true,
|
shipmentStats: true,
|
||||||
confirmedSalesOrders: true,
|
salesOrderCountHistory: true,
|
||||||
|
salesOrderAmountHistory: true,
|
||||||
listingHistory: true,
|
listingHistory: true,
|
||||||
|
orderItemCountHistory: true,
|
||||||
|
orderItemAmountHistory: true,
|
||||||
|
shipmentCountHistory: true,
|
||||||
|
shipmentAmountHistory: true,
|
||||||
|
confirmedSalesOrders: true,
|
||||||
draftListings: true,
|
draftListings: true,
|
||||||
marketplaceHistory: true,
|
marketplaceHistory: true,
|
||||||
readyMarketplaces: true,
|
|
||||||
clientHistory: true,
|
clientHistory: true,
|
||||||
activeClients: true
|
readyMarketplaces: true,
|
||||||
|
activeClients: true,
|
||||||
|
sentSalesOrders: true,
|
||||||
|
activeListings: true,
|
||||||
|
ordersToShip: true,
|
||||||
|
plannedOutboundShipments: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const sections = [
|
const sections = [
|
||||||
@ -25,6 +36,12 @@ const sections = [
|
|||||||
className: 'no-t-padding-collapse',
|
className: 'no-t-padding-collapse',
|
||||||
content: <StatsDisplay objectType='salesOrder' />
|
content: <StatsDisplay objectType='salesOrder' />
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'orderItemStats',
|
||||||
|
title: 'Order Item Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='orderItem' />
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'listingStats',
|
key: 'listingStats',
|
||||||
title: 'Listing Statistics',
|
title: 'Listing Statistics',
|
||||||
@ -44,16 +61,42 @@ const sections = [
|
|||||||
content: <StatsDisplay objectType='client' />
|
content: <StatsDisplay objectType='client' />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'salesOrderAndListingHistoryRow',
|
key: 'shipmentStats',
|
||||||
|
title: 'Shipment Statistics',
|
||||||
|
className: 'no-t-padding-collapse',
|
||||||
|
content: <StatsDisplay objectType='shipment' />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'salesOrderHistoryRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'salesOrderHistory',
|
key: 'salesOrderCountHistory',
|
||||||
title: 'Sales Order History',
|
title: 'Sales Order Count History',
|
||||||
content: <ModelHistoryDisplay objectType='salesOrder' />
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='salesOrder' historyGroup='count' />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'salesOrderAmountHistory',
|
||||||
|
title: 'Sales Order Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay
|
||||||
|
objectType='salesOrder'
|
||||||
|
historyGroup='amount'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'listingHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'listingHistory',
|
key: 'listingHistory',
|
||||||
@ -63,6 +106,54 @@ const sections = [
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'orderItemHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'orderItemCountHistory',
|
||||||
|
title: 'Order Item Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='orderItem' historyGroup='count' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'orderItemAmountHistory',
|
||||||
|
title: 'Order Item Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='orderItem' historyGroup='amount' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'shipmentHistoryRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'shipmentCountHistory',
|
||||||
|
title: 'Shipment Count History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='shipment' historyGroup='count' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'shipmentAmountHistory',
|
||||||
|
title: 'Shipment Amount History',
|
||||||
|
content: (
|
||||||
|
<ModelHistoryDisplay objectType='shipment' historyGroup='amount' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'confirmedSalesOrdersAndDraftListingsRow',
|
key: 'confirmedSalesOrdersAndDraftListingsRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
@ -90,6 +181,30 @@ const sections = [
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'sentSalesOrdersAndActiveListingsRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'sentSalesOrders',
|
||||||
|
title: 'Sent Sales Orders',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='salesOrder' masterFilter={{ state: 'sent' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'activeListings',
|
||||||
|
title: 'Active Listings',
|
||||||
|
content: (
|
||||||
|
<ObjectTable type='listing' masterFilter={{ state: 'active' }} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'marketplaceAndClientHistoryRow',
|
key: 'marketplaceAndClientHistoryRow',
|
||||||
type: 'row',
|
type: 'row',
|
||||||
@ -131,6 +246,36 @@ const sections = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ordersToShipAndPlannedShipmentsRow',
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'ordersToShip',
|
||||||
|
title: 'Orders To Ship',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='salesOrder'
|
||||||
|
masterFilter={{ state: 'partiallyShipped' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'plannedOutboundShipments',
|
||||||
|
title: 'Planned Outbound Shipments',
|
||||||
|
content: (
|
||||||
|
<ObjectTable
|
||||||
|
type='shipment'
|
||||||
|
masterFilter={{ orderType: 'salesOrder', state: 'planned' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -35,14 +35,52 @@ const legendMeasureStyle = {
|
|||||||
const toCssHeight = (value) =>
|
const toCssHeight = (value) =>
|
||||||
typeof value === 'number' ? `${value}px` : value
|
typeof value === 'number' ? `${value}px` : value
|
||||||
|
|
||||||
|
const isAmountStat = (statDef) => {
|
||||||
|
if (statDef.prefix === '£') return true
|
||||||
|
const name = statDef.name || ''
|
||||||
|
if (name.includes('Amount') || name.includes('Value')) return true
|
||||||
|
const combineList = statDef.combine || statDef.sum
|
||||||
|
if (
|
||||||
|
combineList?.some(
|
||||||
|
(statName) => statName.includes('Amount') || statName.endsWith('.sum')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const isValueStat = (statDef) => {
|
||||||
|
if (isAmountStat(statDef)) return false
|
||||||
|
if (statDef.name?.endsWith('.sum')) return true
|
||||||
|
if (statDef.suffix) return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const resolveStatHistoryGroup = (statDef) => {
|
||||||
|
if (statDef.history === false) return null
|
||||||
|
if (statDef.historyGroup) return statDef.historyGroup
|
||||||
|
if (isAmountStat(statDef)) return 'amount'
|
||||||
|
if (isValueStat(statDef)) return 'value'
|
||||||
|
return 'count'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getModelHistoryStats = (model, historyGroup = 'count') => {
|
||||||
|
return (model?.stats || []).filter(
|
||||||
|
(statDef) => resolveStatHistoryGroup(statDef) === historyGroup
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const ModelHistoryDisplay = ({
|
const ModelHistoryDisplay = ({
|
||||||
objectType,
|
objectType,
|
||||||
|
historyGroup = 'count',
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
styles,
|
styles,
|
||||||
height = 400,
|
height = 400,
|
||||||
chartType = 'bar'
|
chartType: chartTypeProp
|
||||||
}) => {
|
}) => {
|
||||||
|
const chartType = chartTypeProp ?? (historyGroup === 'amount' ? 'line' : 'bar')
|
||||||
const { getModelHistory, connected } = useContext(ApiServerContext)
|
const { getModelHistory, connected } = useContext(ApiServerContext)
|
||||||
const { token } = useContext(AuthContext)
|
const { token } = useContext(AuthContext)
|
||||||
const [historyData, setHistoryData] = useState([])
|
const [historyData, setHistoryData] = useState([])
|
||||||
@ -132,8 +170,8 @@ const ModelHistoryDisplay = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const modelStats = useMemo(
|
const modelStats = useMemo(
|
||||||
() => (model?.stats || []).filter((statDef) => statDef.history !== false),
|
() => getModelHistoryStats(model, historyGroup),
|
||||||
[model]
|
[model, historyGroup]
|
||||||
)
|
)
|
||||||
|
|
||||||
const themeColors = getColors()
|
const themeColors = getColors()
|
||||||
@ -516,6 +554,7 @@ const ModelHistoryDisplay = ({
|
|||||||
|
|
||||||
ModelHistoryDisplay.propTypes = {
|
ModelHistoryDisplay.propTypes = {
|
||||||
objectType: PropTypes.string.isRequired,
|
objectType: PropTypes.string.isRequired,
|
||||||
|
historyGroup: PropTypes.oneOf(['count', 'amount', 'value']),
|
||||||
startDate: PropTypes.oneOfType([
|
startDate: PropTypes.oneOfType([
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
PropTypes.instanceOf(Date)
|
PropTypes.instanceOf(Date)
|
||||||
|
|||||||
@ -192,22 +192,19 @@ export const FilamentStock = {
|
|||||||
name: 'unconsumed.count',
|
name: 'unconsumed.count',
|
||||||
label: 'Unconsumed',
|
label: 'Unconsumed',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'success',
|
color: 'success'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'used.count',
|
name: 'used.count',
|
||||||
label: 'Used',
|
label: 'Used',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'warning',
|
color: 'warning'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'consumed.count',
|
name: 'consumed.count',
|
||||||
label: 'Consumed',
|
label: 'Consumed',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'default',
|
color: 'default'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'totalCurrentWeight.sum',
|
name: 'totalCurrentWeight.sum',
|
||||||
@ -215,7 +212,8 @@ export const FilamentStock = {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
roundNumber: 2,
|
roundNumber: 2,
|
||||||
suffix: 'g',
|
suffix: 'g',
|
||||||
cardWidth: 200
|
cardWidth: 200,
|
||||||
|
historyGroup: 'value'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -741,6 +741,36 @@ export const Invoice = {
|
|||||||
prefix: '£',
|
prefix: '£',
|
||||||
roundNumber: 2,
|
roundNumber: 2,
|
||||||
color: 'error'
|
color: 'error'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'partiallyPaid.partiallyPaidGrandTotalAmount.sum',
|
||||||
|
label: 'Partially Paid Amount',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'processing',
|
||||||
|
cardWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'paid.paidCount.count',
|
||||||
|
label: 'Paid',
|
||||||
|
type: 'number',
|
||||||
|
color: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'paid.paidGrandTotalAmount.sum',
|
||||||
|
label: 'Paid Amount',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'success',
|
||||||
|
cardWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cancelled.cancelledCount.count',
|
||||||
|
label: 'Cancelled',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -503,5 +503,49 @@ export const OrderItem = {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 225
|
columnWidth: 225
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
stats: [
|
||||||
|
{
|
||||||
|
name: 'draft.count',
|
||||||
|
label: 'Draft',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ordered.count',
|
||||||
|
label: 'Ordered',
|
||||||
|
type: 'number',
|
||||||
|
color: 'cyan'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'shipped.count',
|
||||||
|
label: 'Shipped',
|
||||||
|
type: 'number',
|
||||||
|
color: 'processing'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'received.count',
|
||||||
|
label: 'Received',
|
||||||
|
type: 'number',
|
||||||
|
color: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'shippedValue.totalAmountWithTax.sum',
|
||||||
|
label: 'Shipped Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'processing',
|
||||||
|
cardWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'receivedValue.totalAmountWithTax.sum',
|
||||||
|
label: 'Received Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'success',
|
||||||
|
cardWidth: 175
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -257,36 +257,33 @@ export const PartStock = {
|
|||||||
name: 'draft.count',
|
name: 'draft.count',
|
||||||
label: 'Draft',
|
label: 'Draft',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'default',
|
color: 'default'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'new.count',
|
name: 'new.count',
|
||||||
label: 'New',
|
label: 'New',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'success',
|
color: 'success'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'used.count',
|
name: 'used.count',
|
||||||
label: 'Used',
|
label: 'Used',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'warning',
|
color: 'warning'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'consumed.count',
|
name: 'consumed.count',
|
||||||
label: 'Consumed',
|
label: 'Consumed',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'default',
|
color: 'default'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'totalCurrentQuantity.sum',
|
name: 'totalCurrentQuantity.sum',
|
||||||
label: 'Total Current Quantity',
|
label: 'Total Current Quantity',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
roundNumber: 2,
|
roundNumber: 2,
|
||||||
cardWidth: 200
|
cardWidth: 200,
|
||||||
|
historyGroup: 'value'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -379,6 +379,21 @@ export const Payment = {
|
|||||||
prefix: '£',
|
prefix: '£',
|
||||||
roundNumber: 2,
|
roundNumber: 2,
|
||||||
color: 'red'
|
color: 'red'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cancelled.cancelledCount.count',
|
||||||
|
label: 'Cancelled',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cancelled.cancelledAmount.sum',
|
||||||
|
label: 'Cancelled Amount',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'default',
|
||||||
|
cardWidth: 200
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -420,36 +420,33 @@ export const ProductStock = {
|
|||||||
name: 'draft.count',
|
name: 'draft.count',
|
||||||
label: 'Draft',
|
label: 'Draft',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'default',
|
color: 'default'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'new.count',
|
name: 'new.count',
|
||||||
label: 'New',
|
label: 'New',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'success',
|
color: 'success'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'used.count',
|
name: 'used.count',
|
||||||
label: 'Used',
|
label: 'Used',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'warning',
|
color: 'warning'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'consumed.count',
|
name: 'consumed.count',
|
||||||
label: 'Consumed',
|
label: 'Consumed',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'default',
|
color: 'default'
|
||||||
history: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'totalCurrentQuantity.sum',
|
name: 'totalCurrentQuantity.sum',
|
||||||
label: 'Total Current Quantity',
|
label: 'Total Current Quantity',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
roundNumber: 2,
|
roundNumber: 2,
|
||||||
cardWidth: 200
|
cardWidth: 200,
|
||||||
|
historyGroup: 'value'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -449,6 +449,24 @@ export const PurchaseOrder = {
|
|||||||
label: 'Completed',
|
label: 'Completed',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'success'
|
color: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'awaitingReceiptValue.grandTotalAmount.sum',
|
||||||
|
label: 'Awaiting Receipt Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'warning',
|
||||||
|
cardWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'receivedValue.grandTotalAmount.sum',
|
||||||
|
label: 'Received Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'success',
|
||||||
|
cardWidth: 200
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -448,6 +448,24 @@ export const SalesOrder = {
|
|||||||
label: 'Cancelled',
|
label: 'Cancelled',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'error'
|
color: 'error'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pipelineValue.grandTotalAmount.sum',
|
||||||
|
label: 'Pipeline Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'purple',
|
||||||
|
cardWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'completedValue.grandTotalAmount.sum',
|
||||||
|
label: 'Completed Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'success',
|
||||||
|
cardWidth: 200
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -428,5 +428,46 @@ export const Shipment = {
|
|||||||
step: 0.01,
|
step: 0.01,
|
||||||
columnWidth: 275
|
columnWidth: 275
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
stats: [
|
||||||
|
{
|
||||||
|
name: 'draft.count',
|
||||||
|
label: 'Draft',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'planned.count',
|
||||||
|
label: 'Planned',
|
||||||
|
type: 'number',
|
||||||
|
color: 'warning'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'shipped.count',
|
||||||
|
label: 'Shipped',
|
||||||
|
type: 'number',
|
||||||
|
color: 'processing'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'delivered.count',
|
||||||
|
label: 'Delivered',
|
||||||
|
type: 'number',
|
||||||
|
color: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cancelled.count',
|
||||||
|
label: 'Cancelled',
|
||||||
|
type: 'number',
|
||||||
|
color: 'error'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'inTransitValue.amountWithTax.sum',
|
||||||
|
label: 'In Transit Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'processing',
|
||||||
|
cardWidth: 200
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,6 +115,14 @@ export const StockEvent = {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
cardWidth: 220
|
cardWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'totalEvents',
|
||||||
|
label: 'Total Events',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default',
|
||||||
|
cardWidth: 175,
|
||||||
|
sum: ['partStock.count', 'filamentStock.count', 'productStock.count']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -224,5 +224,49 @@ export const TaxRecord = {
|
|||||||
type: 'dateTime',
|
type: 'dateTime',
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
stats: [
|
||||||
|
{
|
||||||
|
name: 'total.count.count',
|
||||||
|
label: 'Total Records',
|
||||||
|
type: 'number',
|
||||||
|
color: 'default'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'total.taxAmount.sum',
|
||||||
|
label: 'Total Tax',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'warning',
|
||||||
|
cardWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'total.amount.sum',
|
||||||
|
label: 'Total Transaction Value',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'default',
|
||||||
|
cardWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'salesOrder.taxAmount.sum',
|
||||||
|
label: 'Sales Tax',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'success',
|
||||||
|
cardWidth: 175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'purchaseOrder.taxAmount.sum',
|
||||||
|
label: 'Purchase Tax',
|
||||||
|
type: 'number',
|
||||||
|
prefix: '£',
|
||||||
|
roundNumber: 2,
|
||||||
|
color: 'processing',
|
||||||
|
cardWidth: 175
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user