Files
dashboard/utils/feedSackMapping.ts

137 lines
4.4 KiB
TypeScript

import { FeedSackColumnConfig } from '../types/counting.ts';
export function getFeedSackColumnType(cameraName: string): 'inbound' | 'usage' | 'outbound' {
if (cameraName.includes('karung_masuk')) return 'inbound';
if (cameraName.includes('karung_keluar')) return 'outbound';
return 'usage';
}
export function inferKandangIdFromCameraName(cameraName: string): number | null {
const match = cameraName.toLowerCase().match(/^kandang_(\d+)_/);
if (!match) {
return null;
}
const parsed = Number(match[1]);
return Number.isFinite(parsed) ? parsed : null;
}
export function normalizeFeedSackColumnConfig(column: FeedSackColumnConfig): FeedSackColumnConfig {
const rawKandangId: unknown = (column as { kandangId?: unknown }).kandangId;
let kandangId: number | null = null;
if (typeof rawKandangId === 'number' && Number.isFinite(rawKandangId)) {
kandangId = rawKandangId;
} else if (typeof rawKandangId === 'string' && rawKandangId.trim().length > 0) {
const parsed = Number(rawKandangId);
kandangId = Number.isFinite(parsed) ? parsed : null;
} else if (rawKandangId === undefined) {
kandangId = inferKandangIdFromCameraName(column.cameraName);
}
return {
...column,
type: column.type || getFeedSackColumnType(column.cameraName),
kandangId,
};
}
export function normalizeFeedSackColumnConfigs(
columns: FeedSackColumnConfig[]
): FeedSackColumnConfig[] {
return columns.map(normalizeFeedSackColumnConfig);
}
type FeedSackColumnType = 'inbound' | 'usage' | 'outbound';
function columnsOfType(
columns: FeedSackColumnConfig[],
type: FeedSackColumnType
): FeedSackColumnConfig[] {
return columns.filter(
(column) => (column.type || getFeedSackColumnType(column.cameraName)) === type
);
}
/**
* Cameras of one type mapped to a kandang. Returns [] when mapping fails —
* never all cameras (report must not silently become all-kandang).
*/
export function getCameraNamesForKandang(
columns: FeedSackColumnConfig[],
type: FeedSackColumnType,
kandangId?: number | null,
kandangName?: string | null
): string[] {
const typed = columnsOfType(columns, type);
if (kandangId !== null && kandangId !== undefined) {
const mappedCameras = typed
.filter((column) => column.kandangId === kandangId)
.map((column) => column.cameraName);
if (mappedCameras.length > 0) return mappedCameras;
const inferredCameras = typed
.filter((column) => inferKandangIdFromCameraName(column.cameraName) === kandangId)
.map((column) => column.cameraName);
if (inferredCameras.length > 0) return inferredCameras;
}
if (kandangName) {
const kandangNameLower = kandangName.toLowerCase();
const kandangPrefix = kandangNameLower.replace(/\s+/g, '_');
if (kandangNameLower.includes('atas')) {
const atasCameras = typed
.filter(
(column) =>
column.cameraName.toLowerCase().includes('atas') ||
column.cameraName.toLowerCase().includes('kiri')
)
.map((column) => column.cameraName);
if (atasCameras.length > 0) return atasCameras;
}
if (kandangNameLower.includes('bawah')) {
const bawahCameras = typed
.filter(
(column) =>
column.cameraName.toLowerCase().includes('bawah') ||
column.cameraName.toLowerCase().includes('kanan')
)
.map((column) => column.cameraName);
if (bawahCameras.length > 0) return bawahCameras;
}
const prefixedCameras = typed
.filter((column) => column.cameraName.toLowerCase().startsWith(kandangPrefix))
.map((column) => column.cameraName);
if (prefixedCameras.length > 0) return prefixedCameras;
}
return [];
}
export function getInboundCameraNamesForKandang(
columns: FeedSackColumnConfig[],
kandangId?: number | null,
kandangName?: string | null
): string[] {
return getCameraNamesForKandang(columns, 'inbound', kandangId, kandangName);
}
export function getUsageCameraNamesForKandang(
columns: FeedSackColumnConfig[],
kandangId?: number | null,
kandangName?: string | null
): string[] {
const mapped = getCameraNamesForKandang(columns, 'usage', kandangId, kandangName);
if (mapped.length > 0) return mapped;
return getCombinedUsageCameraNames(columns);
}
/** All usage cameras (left + right / atas + bawah). Production feed use is combined. */
export function getCombinedUsageCameraNames(columns: FeedSackColumnConfig[]): string[] {
return columnsOfType(columns, 'usage').map((column) => column.cameraName);
}