import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, ManyToOne, JoinColumn, Index, } from 'typeorm'; import { StockTransfer } from './stock-transfer.entity'; export enum TransferLineStatus { PENDING = 'pending', PARTIALLY_SHIPPED = 'partially_shipped', SHIPPED = 'shipped', PARTIALLY_RECEIVED = 'partially_received', RECEIVED = 'received', CANCELLED = 'cancelled', } @Entity('stock_transfer_lines', { schema: 'retail' }) @Index(['tenantId', 'transferId']) @Index(['tenantId', 'productId']) export class StockTransferLine { @PrimaryGeneratedColumn('uuid') id: string; @Column({ name: 'tenant_id', type: 'uuid' }) @Index() tenantId: string; @Column({ name: 'transfer_id', type: 'uuid' }) transferId: string; @Column({ name: 'line_number', type: 'int' }) lineNumber: number; // Product (from erp-core) @Column({ name: 'product_id', type: 'uuid' }) productId: string; @Column({ name: 'product_code', length: 50 }) productCode: string; @Column({ name: 'product_name', length: 200 }) productName: string; @Column({ name: 'product_barcode', length: 50, nullable: true }) productBarcode: string; // Variant @Column({ name: 'variant_id', type: 'uuid', nullable: true }) variantId: string; @Column({ name: 'variant_name', length: 200, nullable: true }) variantName: string; // Unit of measure @Column({ name: 'uom_id', type: 'uuid', nullable: true }) uomId: string; @Column({ name: 'uom_name', length: 20, default: 'PZA' }) uomName: string; // Quantities @Column({ name: 'quantity_requested', type: 'decimal', precision: 15, scale: 4 }) quantityRequested: number; @Column({ name: 'quantity_approved', type: 'decimal', precision: 15, scale: 4, nullable: true }) quantityApproved: number; @Column({ name: 'quantity_shipped', type: 'decimal', precision: 15, scale: 4, default: 0 }) quantityShipped: number; @Column({ name: 'quantity_received', type: 'decimal', precision: 15, scale: 4, default: 0 }) quantityReceived: number; @Column({ name: 'quantity_difference', type: 'decimal', precision: 15, scale: 4, default: 0 }) quantityDifference: number; // Costs @Column({ name: 'unit_cost', type: 'decimal', precision: 15, scale: 4, default: 0 }) unitCost: number; @Column({ name: 'total_cost', type: 'decimal', precision: 15, scale: 2, default: 0 }) totalCost: number; // Stock info at time of request @Column({ name: 'source_stock_before', type: 'decimal', precision: 15, scale: 4, nullable: true }) sourceStockBefore: number; @Column({ name: 'dest_stock_before', type: 'decimal', precision: 15, scale: 4, nullable: true }) destStockBefore: number; // Lot/Serial tracking @Column({ name: 'lot_number', length: 50, nullable: true }) lotNumber: string; @Column({ name: 'serial_numbers', type: 'jsonb', nullable: true }) serialNumbers: string[]; @Column({ name: 'expiry_date', type: 'date', nullable: true }) expiryDate: Date; // Status @Column({ type: 'enum', enum: TransferLineStatus, default: TransferLineStatus.PENDING, }) status: TransferLineStatus; // Receiving details @Column({ name: 'received_date', type: 'timestamp with time zone', nullable: true }) receivedDate: Date; @Column({ name: 'received_by', type: 'uuid', nullable: true }) receivedBy: string; @Column({ name: 'receiving_notes', length: 255, nullable: true }) receivingNotes: string; @Column({ name: 'damage_quantity', type: 'decimal', precision: 15, scale: 4, default: 0 }) damageQuantity: number; @Column({ name: 'damage_reason', length: 255, nullable: true }) damageReason: string; // Notes @Column({ type: 'text', nullable: true }) notes: string; // Metadata @Column({ type: 'jsonb', nullable: true }) metadata: Record; @CreateDateColumn({ name: 'created_at' }) createdAt: Date; // Relations @ManyToOne(() => StockTransfer, (transfer) => transfer.lines) @JoinColumn({ name: 'transfer_id' }) transfer: StockTransfer; }