import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, OneToMany, Index, } from 'typeorm'; import { StockAdjustmentLine } from './stock-adjustment-line.entity'; export enum AdjustmentStatus { DRAFT = 'draft', PENDING_APPROVAL = 'pending_approval', APPROVED = 'approved', POSTED = 'posted', REJECTED = 'rejected', CANCELLED = 'cancelled', } export enum AdjustmentType { INVENTORY_COUNT = 'inventory_count', DAMAGE = 'damage', THEFT = 'theft', EXPIRY = 'expiry', CORRECTION = 'correction', INITIAL_STOCK = 'initial_stock', PRODUCTION = 'production', OTHER = 'other', } @Entity('stock_adjustments', { schema: 'retail' }) @Index(['tenantId', 'branchId', 'status']) @Index(['tenantId', 'adjustmentDate']) @Index(['tenantId', 'number'], { unique: true }) export class StockAdjustment { @PrimaryGeneratedColumn('uuid') id: string; @Column({ name: 'tenant_id', type: 'uuid' }) @Index() tenantId: string; @Column({ name: 'branch_id', type: 'uuid' }) branchId: string; @Column({ name: 'warehouse_id', type: 'uuid' }) warehouseId: string; @Column({ name: 'location_id', type: 'uuid', nullable: true }) locationId: string; @Column({ length: 30, unique: true }) number: string; @Column({ type: 'enum', enum: AdjustmentType, default: AdjustmentType.INVENTORY_COUNT, }) type: AdjustmentType; @Column({ type: 'enum', enum: AdjustmentStatus, default: AdjustmentStatus.DRAFT, }) status: AdjustmentStatus; @Column({ name: 'adjustment_date', type: 'date' }) adjustmentDate: Date; // Count info (for inventory counts) @Column({ name: 'is_full_count', type: 'boolean', default: false }) isFullCount: boolean; @Column({ name: 'count_category_id', type: 'uuid', nullable: true }) countCategoryId: string; // Summary @Column({ name: 'lines_count', type: 'int', default: 0 }) linesCount: number; @Column({ name: 'total_increase_qty', type: 'decimal', precision: 15, scale: 4, default: 0 }) totalIncreaseQty: number; @Column({ name: 'total_decrease_qty', type: 'decimal', precision: 15, scale: 4, default: 0 }) totalDecreaseQty: number; @Column({ name: 'total_increase_value', type: 'decimal', precision: 15, scale: 2, default: 0 }) totalIncreaseValue: number; @Column({ name: 'total_decrease_value', type: 'decimal', precision: 15, scale: 2, default: 0 }) totalDecreaseValue: number; @Column({ name: 'net_adjustment_value', type: 'decimal', precision: 15, scale: 2, default: 0 }) netAdjustmentValue: number; // Financial account (for accounting integration) @Column({ name: 'account_id', type: 'uuid', nullable: true }) accountId: string; @Column({ name: 'counterpart_account_id', type: 'uuid', nullable: true }) counterpartAccountId: string; // Approval workflow @Column({ name: 'requires_approval', type: 'boolean', default: true }) requiresApproval: boolean; @Column({ name: 'approval_threshold', type: 'decimal', precision: 15, scale: 2, nullable: true }) approvalThreshold: number; // Users @Column({ name: 'created_by', type: 'uuid' }) createdBy: string; @Column({ name: 'approved_by', type: 'uuid', nullable: true }) approvedBy: string; @Column({ name: 'approved_at', type: 'timestamp with time zone', nullable: true }) approvedAt: Date; @Column({ name: 'posted_by', type: 'uuid', nullable: true }) postedBy: string; @Column({ name: 'posted_at', type: 'timestamp with time zone', nullable: true }) postedAt: Date; @Column({ name: 'rejected_by', type: 'uuid', nullable: true }) rejectedBy: string; @Column({ name: 'rejected_at', type: 'timestamp with time zone', nullable: true }) rejectedAt: Date; @Column({ name: 'rejection_reason', length: 255, nullable: true }) rejectionReason: string; // Reason/Description @Column({ type: 'text' }) reason: string; // Reference @Column({ name: 'reference_type', length: 50, nullable: true }) referenceType: string; @Column({ name: 'reference_id', type: 'uuid', nullable: true }) referenceId: string; @Column({ name: 'reference_number', length: 50, nullable: true }) referenceNumber: string; // Notes @Column({ type: 'text', nullable: true }) notes: string; // Metadata @Column({ type: 'jsonb', nullable: true }) metadata: Record; @CreateDateColumn({ name: 'created_at' }) createdAt: Date; @UpdateDateColumn({ name: 'updated_at' }) updatedAt: Date; // Relations @OneToMany(() => StockAdjustmentLine, (line) => line.adjustment) lines: StockAdjustmentLine[]; }