erp-retail-backend-v2/src/modules/inventory/entities/stock-transfer-line.entity.ts
rckrdmrd a6186c4022 Migración desde erp-retail/backend - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:11:34 -06:00

145 lines
3.9 KiB
TypeScript

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<string, any>;
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
// Relations
@ManyToOne(() => StockTransfer, (transfer) => transfer.lines)
@JoinColumn({ name: 'transfer_id' })
transfer: StockTransfer;
}