Add manual SKU planning overrides
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m18s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m18s
This commit is contained in:
@@ -9,12 +9,12 @@ import ProductTypeBadge from '../components/ProductTypeBadge';
|
||||
import RefreshStatus from '../components/RefreshStatus';
|
||||
import { buildSkuEditPath } from '../catalogLinks';
|
||||
import { buildOpenProductionByProductId } from '../analytics/cutting';
|
||||
import { fetchProductAnalytics, fetchProductionOrders } from '../dataService';
|
||||
import { fetchCuttingSettings, fetchProductAnalytics, fetchProductionOrders } from '../dataService';
|
||||
import { decodeProductGroupKey, normalizeProductText, parseProductName } from '../productParsing';
|
||||
import { formatColorLabel } from '../displayFormatters';
|
||||
import { getProductColor } from '../productColors';
|
||||
import { classifyProductType, getDominantProductType, getProductTypeConfig, type ProductTypeKey } from '../productClassification';
|
||||
import type { DateRange, ProductAnalyticsItem, ProductionOrderItem } from '../types';
|
||||
import { getDominantProductType, getProductTypeConfig, resolveProductType, type ProductTypeKey } from '../productClassification';
|
||||
import type { CuttingSettings, DateRange, ProductAnalyticsItem, ProductionOrderItem } from '../types';
|
||||
|
||||
type VariantRow = ProductAnalyticsItem & {
|
||||
color: string;
|
||||
@@ -194,6 +194,7 @@ const ProductGroupDetails = () => {
|
||||
const [products, setProducts] = useState<ProductAnalyticsItem[]>([]);
|
||||
const [productionOrders, setProductionOrders] = useState<ProductionOrderItem[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [planningSettings, setPlanningSettings] = useState<CuttingSettings>({ familyYields: {}, productOverrides: {} });
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(20);
|
||||
|
||||
@@ -207,6 +208,21 @@ const ProductGroupDetails = () => {
|
||||
}
|
||||
}, [groupKey]);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
const loadPlanningSettings = async () => {
|
||||
const settings = await fetchCuttingSettings();
|
||||
if (isMounted) setPlanningSettings(settings);
|
||||
};
|
||||
|
||||
void loadPlanningSettings();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
@@ -243,7 +259,7 @@ const ProductGroupDetails = () => {
|
||||
return products
|
||||
.map(product => {
|
||||
const metadata = parseProductName(product.name);
|
||||
const productType = classifyProductType(product.name);
|
||||
const productType = resolveProductType(product.name, planningSettings.productOverrides[product.id]);
|
||||
const dailySales = product.quantitySold / rangeDays;
|
||||
const projectedDemand = dailySales * REPLENISHMENT_TARGET_DAYS;
|
||||
const openProductionQuantity = openProductionByProductId[product.id] || 0;
|
||||
@@ -266,7 +282,7 @@ const ProductGroupDetails = () => {
|
||||
})
|
||||
.filter(product => normalizeProductText(product.baseName).toLowerCase() === normalizedGroupName)
|
||||
.sort((a, b) => b.quantitySold - a.quantitySold);
|
||||
}, [dateRange, groupName, openProductionByProductId, products]);
|
||||
}, [dateRange, groupName, openProductionByProductId, planningSettings.productOverrides, products]);
|
||||
|
||||
const totals = useMemo(() => {
|
||||
const totalSold = groupRows.reduce((total, row) => total + row.quantitySold, 0);
|
||||
|
||||
Reference in New Issue
Block a user