100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
/**
|
|
* Filament model matching the Extrudex backend FilamentResponse DTO.
|
|
* Used for displaying spool inventory in the filament table UI.
|
|
*/
|
|
export interface Filament {
|
|
/** Unique identifier for the filament spool. */
|
|
id: string;
|
|
|
|
/** Foreign key to the base material. */
|
|
materialBaseId: string;
|
|
|
|
/** Name of the base material (e.g., "PLA", "PETG"). */
|
|
materialBaseName: string;
|
|
|
|
/** Foreign key to the material finish. */
|
|
materialFinishId: string;
|
|
|
|
/** Name of the material finish (e.g., "Basic", "Matte"). */
|
|
materialFinishName: string;
|
|
|
|
/** Foreign key to the optional material modifier. */
|
|
materialModifierId: string | null;
|
|
|
|
/** Name of the material modifier (e.g., "Carbon Fiber"). Null if none. */
|
|
materialModifierName: string | null;
|
|
|
|
/** Brand name (e.g., "Bambu Lab", "Polymaker"). */
|
|
brand: string;
|
|
|
|
/** Human-readable color name (e.g., "Fire Engine Red"). */
|
|
colorName: string;
|
|
|
|
/** Hex color code (e.g., "#FF0000"). */
|
|
colorHex: string;
|
|
|
|
/** Total spool weight in grams when full. */
|
|
weightTotalGrams: number;
|
|
|
|
/** Current remaining weight in grams. */
|
|
weightRemainingGrams: number;
|
|
|
|
/** Filament diameter in millimeters. Typically 1.75mm. */
|
|
filamentDiameterMm: number;
|
|
|
|
/** Manufacturer-assigned serial number. */
|
|
spoolSerial: string;
|
|
|
|
/** Purchase price per spool. Null if not tracked. */
|
|
purchasePrice: number | null;
|
|
|
|
/** Date the spool was purchased or received. */
|
|
purchaseDate: string | null;
|
|
|
|
/** Whether the spool is currently active and available. */
|
|
isActive: boolean;
|
|
|
|
/** Timestamp when this record was created (UTC). */
|
|
createdAt: string;
|
|
|
|
/** Timestamp when this record was last updated (UTC). */
|
|
updatedAt: string;
|
|
|
|
/** URL to the QR code image for this spool. */
|
|
qrCodeUrl: string;
|
|
}
|
|
|
|
/**
|
|
* Stock level classification for low stock indicators.
|
|
* - critical: ≤ 10% remaining
|
|
* - low: ≤ 25% remaining
|
|
* - moderate: ≤ 50% remaining
|
|
* - healthy: > 50% remaining
|
|
*/
|
|
export type StockLevel = 'critical' | 'low' | 'moderate' | 'healthy';
|
|
|
|
/**
|
|
* Compute the remaining weight percentage for a filament spool.
|
|
* Returns a value from 0 to 100.
|
|
*/
|
|
export function getRemainingPercent(filament: Filament): number {
|
|
if (filament.weightTotalGrams <= 0) return 0;
|
|
const pct = (filament.weightRemainingGrams / filament.weightTotalGrams) * 100;
|
|
return Math.min(Math.max(pct, 0), 100);
|
|
}
|
|
|
|
/**
|
|
* Classify the stock level based on remaining percentage.
|
|
* Thresholds:
|
|
* critical — ≤ 10% (nearly empty, red alert)
|
|
* low — ≤ 25% (getting low, amber warning)
|
|
* moderate — ≤ 50% (half or less, yellow info)
|
|
* healthy — > 50% (plenty left, green OK)
|
|
*/
|
|
export function classifyStockLevel(filament: Filament): StockLevel {
|
|
const pct = getRemainingPercent(filament);
|
|
if (pct <= 10) return 'critical';
|
|
if (pct <= 25) return 'low';
|
|
if (pct <= 50) return 'moderate';
|
|
return 'healthy';
|
|
} |