All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m47s
729 lines
15 KiB
TypeScript
729 lines
15 KiB
TypeScript
import type { ProductTypeKey } from './productClassification';
|
|
|
|
export interface OrderData {
|
|
Nome_Cliente: string;
|
|
Data_Pedido: string;
|
|
Valor_Pedido: number;
|
|
ID_Produto: string;
|
|
Descricao_Produto: string;
|
|
Quantidade: number;
|
|
Valor_Unitario: number;
|
|
Recebido_Em?: string;
|
|
ID_Pedido?: string;
|
|
Fone_Cliente?: string;
|
|
cliente_nome_fantasia?: string;
|
|
id_vendedor?: string;
|
|
nome_vendedor?: string;
|
|
marketplace?: string;
|
|
canal_venda?: string;
|
|
numero_ecommerce?: string;
|
|
}
|
|
|
|
export interface StockData {
|
|
produto_id: string;
|
|
nome: string;
|
|
saldo: number;
|
|
delta_estoque: number;
|
|
updated_at?: string;
|
|
}
|
|
|
|
export type ProductionOrderStatus = 'open' | 'in_progress' | 'finished' | 'canceled' | string;
|
|
|
|
export interface ProductionOrderMarker {
|
|
label: string;
|
|
color?: string | null;
|
|
}
|
|
|
|
export interface ProductionOrderComponent {
|
|
id: number;
|
|
componentTinyId: string;
|
|
componentSku: string;
|
|
componentName: string;
|
|
quantityPerUnit: number;
|
|
totalQuantity: number;
|
|
unit: string;
|
|
}
|
|
|
|
export interface ProductionOrderStep {
|
|
id: number;
|
|
stepNumber: number | null;
|
|
name: string;
|
|
startDate: string | null;
|
|
endDate: string | null;
|
|
status: string;
|
|
color: string;
|
|
}
|
|
|
|
export interface ProductionOrderItem {
|
|
id: number;
|
|
tinyId: string;
|
|
number: string;
|
|
status: ProductionOrderStatus;
|
|
statusLabel: string;
|
|
orderReference: string;
|
|
issueDate: string | null;
|
|
expectedDate: string | null;
|
|
productSku: string;
|
|
productDescription: string;
|
|
quantity: number;
|
|
unit: string;
|
|
integrationStatus: string;
|
|
notes: string;
|
|
supplier: string;
|
|
lotCode: string;
|
|
rollQuantity: number | null;
|
|
fabricKg: number | null;
|
|
ribKg: number | null;
|
|
yieldPiecesPerKg: number | null;
|
|
markers: ProductionOrderMarker[];
|
|
components: ProductionOrderComponent[];
|
|
steps: ProductionOrderStep[];
|
|
createdAt: string | null;
|
|
updatedAt: string | null;
|
|
}
|
|
|
|
export interface ProductionOrderCounts {
|
|
all: number;
|
|
open: number;
|
|
in_progress: number;
|
|
finished: number;
|
|
canceled: number;
|
|
[key: string]: number;
|
|
}
|
|
|
|
export interface ProductionOrderSummary {
|
|
orders: ProductionOrderItem[];
|
|
counts: ProductionOrderCounts;
|
|
}
|
|
|
|
export type ProductionOrderMarkerPayload = {
|
|
label: string;
|
|
color?: string | null;
|
|
};
|
|
|
|
export type ProductionOrderPayload = {
|
|
number?: string;
|
|
status?: ProductionOrderStatus;
|
|
orderReference?: string;
|
|
issueDate?: string | null;
|
|
expectedDate?: string | null;
|
|
productSku?: string;
|
|
productDescription: string;
|
|
quantity: number;
|
|
unit?: string;
|
|
integrationStatus?: string;
|
|
markers?: ProductionOrderMarkerPayload[];
|
|
metadata?: Record<string, unknown>;
|
|
};
|
|
|
|
export interface CreateProductionOrdersResult {
|
|
created: ProductionOrderItem[];
|
|
skipped: Array<{
|
|
productSku?: string;
|
|
productDescription?: string;
|
|
reason: string;
|
|
}>;
|
|
}
|
|
|
|
export type CutFamilyKey = 'BLCS' | 'BLOS' | 'BLMC' | 'BLPM' | 'OUTROS';
|
|
|
|
export interface CutProductOverride {
|
|
familyKey?: CutFamilyKey | '';
|
|
color?: string;
|
|
size?: string;
|
|
productType?: ProductTypeKey | '';
|
|
planningNotes?: string;
|
|
}
|
|
|
|
export interface CuttingSettings {
|
|
familyYields: Partial<Record<CutFamilyKey, number>>;
|
|
productOverrides: Record<string, CutProductOverride>;
|
|
}
|
|
|
|
export type CatalogProductType = 'finished_product' | 'raw_material';
|
|
|
|
export interface CatalogCategory {
|
|
id: number;
|
|
name: string;
|
|
description: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface CatalogProduct {
|
|
id: number;
|
|
type: CatalogProductType;
|
|
sku: string;
|
|
name: string;
|
|
categoryId: number | null;
|
|
categoryName: string;
|
|
composition: string;
|
|
notes: string;
|
|
gramature: number | null;
|
|
materialYield: number | null;
|
|
widthCm: number | null;
|
|
color: string;
|
|
subcategory: string;
|
|
sizes: string[];
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface ConsumptionReference {
|
|
id: number;
|
|
productId: number;
|
|
productSku: string;
|
|
productName: string;
|
|
materialProductId: number | null;
|
|
materialSku: string;
|
|
materialName: string;
|
|
color: string;
|
|
generalYield: number | null;
|
|
sizeYields: Record<string, number>;
|
|
sizeAreas: Record<string, number>;
|
|
gramature: number | null;
|
|
efficiencyPercent: number | null;
|
|
ribGPerPiece: number | null;
|
|
materialCostPerKg: number | null;
|
|
consumptionQuantity: number | null;
|
|
consumptionUnit: string;
|
|
source: string;
|
|
lastProductionOrderId: number | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface CatalogSummary {
|
|
categories: CatalogCategory[];
|
|
products: CatalogProduct[];
|
|
consumptionReferences: ConsumptionReference[];
|
|
}
|
|
|
|
export type CatalogCategoryPayload = {
|
|
name: string;
|
|
description?: string;
|
|
};
|
|
|
|
export type CatalogProductPayload = {
|
|
type: CatalogProductType;
|
|
sku: string;
|
|
name: string;
|
|
categoryId?: number | null;
|
|
composition?: string;
|
|
notes?: string;
|
|
gramature?: number | string | null;
|
|
materialYield?: number | string | null;
|
|
widthCm?: number | string | null;
|
|
color?: string;
|
|
subcategory?: string;
|
|
sizes?: string[];
|
|
};
|
|
|
|
export type ConsumptionReferencePayload = {
|
|
productId: number | string;
|
|
materialProductId?: number | string | null;
|
|
color?: string;
|
|
generalYield?: number | string | null;
|
|
sizeYields?: Record<string, number | string>;
|
|
sizeAreas?: Record<string, number | string>;
|
|
gramature?: number | string | null;
|
|
efficiencyPercent?: number | string | null;
|
|
ribGPerPiece?: number | string | null;
|
|
materialCostPerKg?: number | string | null;
|
|
consumptionQuantity?: number | string | null;
|
|
consumptionUnit?: string | null;
|
|
};
|
|
|
|
export type SupplyReceiptStatus = 'pending' | 'approved';
|
|
|
|
export interface SupplyReceipt {
|
|
id: number;
|
|
category: string;
|
|
product: string;
|
|
quantity: number;
|
|
unit: string;
|
|
supplier: string;
|
|
invoice: string;
|
|
notes: string;
|
|
status: SupplyReceiptStatus;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
approvedAt: string | null;
|
|
}
|
|
|
|
export interface SupplyLot {
|
|
id: number;
|
|
receiptId: number | null;
|
|
category: string;
|
|
product: string;
|
|
quantity: number;
|
|
unit: string;
|
|
supplier: string;
|
|
invoice: string;
|
|
status: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface SupplyMovement {
|
|
id: number;
|
|
receiptId: number | null;
|
|
lotId: number | null;
|
|
type: string;
|
|
category: string;
|
|
product: string;
|
|
quantity: number;
|
|
unit: string;
|
|
reason: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface SupplyFabricPlan {
|
|
id: number;
|
|
material: string;
|
|
color: string;
|
|
quantityKg: number;
|
|
supplier: string;
|
|
priority: string;
|
|
status: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface SupplyPurchaseNeed {
|
|
material: string;
|
|
plannedKg: number;
|
|
stockKg: number;
|
|
pendingKg: number;
|
|
purchaseKg: number;
|
|
priority: string;
|
|
status: 'critical' | 'attention' | 'ok';
|
|
suppliers: string[];
|
|
colors: string[];
|
|
unit?: string;
|
|
source?: string;
|
|
missingReference?: boolean;
|
|
products?: Array<{
|
|
productId: string;
|
|
name: string;
|
|
suggestedQuantity: number;
|
|
quantitySold: number;
|
|
stockQuantity: number;
|
|
yieldPerKg?: number;
|
|
consumptionQuantity?: number;
|
|
consumptionUnit?: string;
|
|
}>;
|
|
}
|
|
|
|
export interface SupplyStats {
|
|
totalQuantityKg: number;
|
|
activeLots: number;
|
|
rolls: number;
|
|
alerts: number;
|
|
pendingReceipts: number;
|
|
approvedReceipts: number;
|
|
}
|
|
|
|
export interface SupplySummary {
|
|
receipts: SupplyReceipt[];
|
|
lots: SupplyLot[];
|
|
movements: SupplyMovement[];
|
|
fabricPlans: SupplyFabricPlan[];
|
|
purchaseNeeds: SupplyPurchaseNeed[];
|
|
stats: SupplyStats;
|
|
}
|
|
|
|
export type SupplyReceiptPayload = {
|
|
category: string;
|
|
product: string;
|
|
quantity: number | string;
|
|
unit: string;
|
|
supplier?: string;
|
|
invoice?: string;
|
|
notes?: string;
|
|
};
|
|
|
|
export type SupplyFabricPlanPayload = {
|
|
material: string;
|
|
color?: string;
|
|
quantityKg: number | string;
|
|
supplier?: string;
|
|
priority?: string;
|
|
};
|
|
|
|
export type SupplyInventoryAdjustmentPayload = {
|
|
countedQuantity: number | string;
|
|
reason: string;
|
|
};
|
|
|
|
export type SupplyProductionExitPayload = {
|
|
quantity: number | string;
|
|
productionOrderNumber?: string;
|
|
reason?: string;
|
|
};
|
|
|
|
export interface DateRange {
|
|
start: Date;
|
|
end: Date;
|
|
}
|
|
|
|
export type AuthRole = 'super_admin' | 'user';
|
|
|
|
export interface AuthUser {
|
|
id: number | null;
|
|
name: string;
|
|
email: string;
|
|
role: AuthRole;
|
|
}
|
|
|
|
export interface ManagedUser {
|
|
id: number;
|
|
name: string;
|
|
email: string;
|
|
isActive: boolean;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface CreateUserResult {
|
|
user: ManagedUser;
|
|
temporaryPassword?: string;
|
|
}
|
|
|
|
export interface DashboardAnalytics {
|
|
totalRevenue: number;
|
|
totalOrders: number;
|
|
orderLineCount?: number;
|
|
averageOrderValue: number;
|
|
salesByProduct: Array<{
|
|
name: string;
|
|
id: string;
|
|
value: number;
|
|
}>;
|
|
revenueByProduct: Array<{
|
|
name: string;
|
|
id: string;
|
|
value: number;
|
|
}>;
|
|
revenueBySeller?: Array<{
|
|
name: string;
|
|
id: string;
|
|
value: number;
|
|
}>;
|
|
ordersBySeller?: Array<{
|
|
name: string;
|
|
id: string;
|
|
value: number;
|
|
}>;
|
|
sellerRevenueByDate?: Array<{
|
|
name: string;
|
|
id: string;
|
|
date: string;
|
|
value: number;
|
|
orders?: number;
|
|
}>;
|
|
sellerRevenueByHour?: Array<{
|
|
name: string;
|
|
id: string;
|
|
hour: number;
|
|
value: number;
|
|
orders?: number;
|
|
}>;
|
|
}
|
|
|
|
export interface ProductAnalyticsItem {
|
|
id: string;
|
|
name: string;
|
|
quantitySold: number;
|
|
revenue: number;
|
|
orderLineCount: number;
|
|
lastPrice: number;
|
|
stock: number;
|
|
firstSaleDate: string | null;
|
|
lastSaleDate: string | null;
|
|
}
|
|
|
|
export interface ProductDetailsAnalytics {
|
|
range: {
|
|
start: string | null;
|
|
end: string | null;
|
|
};
|
|
productInfo: {
|
|
id: string;
|
|
name: string;
|
|
price: number;
|
|
stock: number;
|
|
};
|
|
chartData: Array<{
|
|
date: string;
|
|
value: number;
|
|
quantitySold?: number;
|
|
revenue?: number;
|
|
orderCount?: number;
|
|
averageTicket?: number;
|
|
}>;
|
|
totalSold: number;
|
|
totalRevenue: number;
|
|
totalOrders?: number;
|
|
averageTicket?: number;
|
|
variantBreakdown?: Array<{
|
|
id: string;
|
|
name: string;
|
|
quantitySold: number;
|
|
revenue: number;
|
|
orderCount: number;
|
|
}>;
|
|
}
|
|
|
|
export interface ProductCompositionComponent {
|
|
id: number;
|
|
componentTinyId: string;
|
|
componentSku: string;
|
|
componentName: string;
|
|
quantityPerUnit: number;
|
|
unit: string;
|
|
productId: string | null;
|
|
}
|
|
|
|
export interface ProductComposition {
|
|
id: number;
|
|
source: string;
|
|
externalSourceId: string;
|
|
finishedProductSku: string;
|
|
finishedProductDescription: string;
|
|
finishedProductUnit: string;
|
|
finishedTinyProductId: string;
|
|
sourceMetadata: Record<string, unknown>;
|
|
lastSyncedAt: string | null;
|
|
components: ProductCompositionComponent[];
|
|
}
|
|
|
|
export interface ProductCompositionImportSummary {
|
|
imported: number;
|
|
failed: number;
|
|
componentCount: number;
|
|
referenceCount: number;
|
|
skippedReferenceCount: number;
|
|
issues: Array<{
|
|
type: string;
|
|
productSku?: string;
|
|
product?: string;
|
|
component?: string;
|
|
componentSku?: string;
|
|
tinyProductId?: string;
|
|
unit?: string;
|
|
count?: number;
|
|
message?: string;
|
|
}>;
|
|
}
|
|
|
|
export interface ClientAnalyticsItem {
|
|
customerKey: string;
|
|
clientToken: string;
|
|
name: string;
|
|
phone: string;
|
|
quantityPurchased: number;
|
|
totalSpent: number;
|
|
orderCount: number;
|
|
lastPurchaseDate: string;
|
|
}
|
|
|
|
export interface SellerAnalyticsItem {
|
|
id: string;
|
|
name: string;
|
|
revenue: number;
|
|
quantitySold: number;
|
|
orderCount: number;
|
|
customerCount: number;
|
|
lastOrderDate: string | null;
|
|
averageTicket: number;
|
|
}
|
|
|
|
export interface SellerDetailsAnalytics {
|
|
seller: SellerAnalyticsItem;
|
|
chartData: Array<{ date: string; revenue: number; quantitySold: number; orderCount: number }>;
|
|
topProducts: ProductAnalyticsItem[];
|
|
topClients: ClientAnalyticsItem[];
|
|
marketplaces: Array<{ name: string; revenue: number; orderCount: number }>;
|
|
}
|
|
|
|
export interface ClientMetadataFilters {
|
|
marketplace: string;
|
|
canal_venda: string;
|
|
seller: string;
|
|
}
|
|
|
|
export interface ClientSellerFilterOption {
|
|
value: string;
|
|
id: string;
|
|
name: string;
|
|
}
|
|
|
|
export interface ClientFilterOptions {
|
|
marketplaces: string[];
|
|
salesChannels: string[];
|
|
sellers: ClientSellerFilterOption[];
|
|
}
|
|
|
|
export interface ClientPurchasePatternAnalytics {
|
|
weekdayRangeLabel?: string;
|
|
hourRangeLabel?: string;
|
|
purchaseWeekdays: Array<{
|
|
label: string;
|
|
value: number;
|
|
}>;
|
|
purchaseHours: Array<{
|
|
label: string;
|
|
value: number;
|
|
}>;
|
|
}
|
|
|
|
export interface RfmClient {
|
|
customerKey: string;
|
|
clientToken: string;
|
|
name: string;
|
|
phone: string;
|
|
monetary: number;
|
|
frequency: number;
|
|
quantityPurchased: number;
|
|
lastPurchaseDate: string;
|
|
recencyDays: number;
|
|
recencyScore: 1 | 2 | 3;
|
|
frequencyScore: 1 | 2 | 3;
|
|
monetaryScore: 1 | 2 | 3;
|
|
valueScore: 1 | 2 | 3;
|
|
rfmScore: string;
|
|
segmentKey: string;
|
|
segmentLabel: string;
|
|
}
|
|
|
|
export interface RfmSegment {
|
|
key: string;
|
|
label: string;
|
|
count: number;
|
|
totalRevenue: number;
|
|
averageRevenue: number;
|
|
}
|
|
|
|
export interface RfmAnalytics {
|
|
range: {
|
|
start: string | null;
|
|
end: string | null;
|
|
};
|
|
clients: RfmClient[];
|
|
segments: RfmSegment[];
|
|
matrix: {
|
|
recencyScores: number[];
|
|
valueScores: number[];
|
|
};
|
|
}
|
|
|
|
export interface GroupedClientOrder {
|
|
date: string;
|
|
orderId: string;
|
|
orderTotal: number;
|
|
items: OrderData[];
|
|
}
|
|
|
|
export interface ClientDetailsAnalytics {
|
|
range: {
|
|
start: string | null;
|
|
end: string | null;
|
|
};
|
|
clientToken: string;
|
|
chartData: Array<{
|
|
date: string;
|
|
value: number;
|
|
}>;
|
|
purchaseWeekdays?: Array<{
|
|
label: string;
|
|
value: number;
|
|
}>;
|
|
purchaseHours?: Array<{
|
|
label: string;
|
|
value: number;
|
|
}>;
|
|
purchaseWeekdayRangeLabel?: string;
|
|
purchaseHourRangeLabel?: string;
|
|
groupedOrders: GroupedClientOrder[];
|
|
allTimeOrderCount: number;
|
|
clientName: string;
|
|
clientPhone: string;
|
|
hasClient: boolean;
|
|
periodAverageTicket: number;
|
|
periodOrderCount: number;
|
|
periodSpent: number;
|
|
periodItems: number;
|
|
}
|
|
|
|
export type CampaignStatus = 'pending' | 'processing' | 'sent' | 'failed' | 'skipped';
|
|
|
|
export interface CampaignQueueItem {
|
|
id: number;
|
|
base_product_name: string;
|
|
produto_id: string;
|
|
nome: string;
|
|
saldo: number;
|
|
delta_estoque: number;
|
|
status: CampaignStatus;
|
|
attempts: number;
|
|
last_error?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
sent_at?: string | null;
|
|
}
|
|
|
|
export interface CampaignGroup {
|
|
key: string;
|
|
baseProductName: string;
|
|
status: CampaignStatus;
|
|
totalDelta: number;
|
|
rowCount: number;
|
|
attempts: number;
|
|
lastError?: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
sentAt?: string | null;
|
|
items: CampaignQueueItem[];
|
|
}
|
|
|
|
export interface CampaignQueueSummary {
|
|
threshold: number;
|
|
maxAttempts: number;
|
|
groups: CampaignGroup[];
|
|
rows: CampaignQueueItem[];
|
|
}
|
|
|
|
export interface CampaignProductPreview {
|
|
baseProduct: string;
|
|
total_delta: number;
|
|
sizes: Array<{
|
|
id: string;
|
|
nome: string;
|
|
delta: number;
|
|
saldo: number;
|
|
}>;
|
|
}
|
|
|
|
export interface CampaignPreview {
|
|
threshold: number;
|
|
readyProducts: CampaignProductPreview[];
|
|
belowThresholdProducts: CampaignProductPreview[];
|
|
productsText: string;
|
|
customerCount: number;
|
|
customersPreview: Array<{
|
|
nome: string;
|
|
fone: string;
|
|
total_gasto?: string;
|
|
total_comprado?: string;
|
|
}>;
|
|
}
|
|
|
|
export interface CampaignProcessSummary {
|
|
claimed: number;
|
|
sentGroups: number;
|
|
skippedGroups: number;
|
|
failedGroups: number;
|
|
pendingBelowThresholdGroups: number;
|
|
}
|