erp-core-backend-v2/src/modules/warehouses/entities/warehouse.entity.ts
rckrdmrd 6054102774 [BACKEND] feat: EPIC-001 & EPIC-002 - Core module completion and entity consolidation
EPIC-001: Complete Core Module
- Add PaymentTerm entity with multi-line support (30/60/90 days, early payment discounts)
- Add PaymentTerms service with calculateDueDate() functionality
- Add DiscountRule entity with volume/time-based conditions
- Add DiscountRules service with applyDiscounts() and rule combination logic
- Add REST endpoints for payment-terms and discount-rules in core module
- Register new entities in TypeORM configuration

EPIC-002: Entity Consolidation
- Add inventoryProductId FK to products.products for linking to inventory module
- Consolidate Warehouse entity in warehouses module as canonical source
- Add companyId and Location relation to canonical Warehouse
- Update inventory module to re-export Warehouse from warehouses module
- Remove deprecated warehouse.entity.ts from inventory module
- Update inventory/warehouses.service.ts to use canonical Warehouse

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 05:13:34 -06:00

146 lines
4.1 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Index,
ManyToOne,
OneToMany,
JoinColumn,
} from 'typeorm';
import { Company } from '../../auth/entities/company.entity.js';
/**
* Warehouse Entity (schema: inventory.warehouses)
*
* This is the CANONICAL warehouse entity for the ERP system.
* All warehouse-related imports should use this entity.
*
* Note: The deprecated entity at inventory/entities/warehouse.entity.ts
* has been superseded by this one and should not be used for new code.
*/
@Entity({ name: 'warehouses', schema: 'inventory' })
@Index('idx_warehouses_tenant_id', ['tenantId'])
@Index('idx_warehouses_company_id', ['companyId'])
@Index('idx_warehouses_code_company', ['companyId', 'code'], { unique: true })
export class Warehouse {
@PrimaryGeneratedColumn('uuid')
id: string;
@Index()
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
@Index()
@Column({ name: 'company_id', type: 'uuid', nullable: true })
companyId: string | null;
@ManyToOne(() => Company)
@JoinColumn({ name: 'company_id' })
company: Company;
@Index()
@Column({ name: 'branch_id', type: 'uuid', nullable: true })
branchId: string;
// Identificacion
@Index()
@Column({ type: 'varchar', length: 20 })
code: string;
@Column({ type: 'varchar', length: 100 })
name: string;
@Column({ type: 'text', nullable: true })
description: string;
// Tipo
@Index()
@Column({ name: 'warehouse_type', type: 'varchar', length: 20, default: 'standard' })
warehouseType: 'standard' | 'transit' | 'returns' | 'quarantine' | 'virtual';
// Direccion
@Column({ name: 'address_line1', type: 'varchar', length: 200, nullable: true })
addressLine1: string;
@Column({ name: 'address_line2', type: 'varchar', length: 200, nullable: true })
addressLine2: string;
@Column({ type: 'varchar', length: 100, nullable: true })
city: string;
@Column({ type: 'varchar', length: 100, nullable: true })
state: string;
@Column({ name: 'postal_code', type: 'varchar', length: 20, nullable: true })
postalCode: string;
@Column({ type: 'varchar', length: 3, default: 'MEX' })
country: string;
// Contacto
@Column({ name: 'manager_name', type: 'varchar', length: 100, nullable: true })
managerName: string;
@Column({ type: 'varchar', length: 30, nullable: true })
phone: string;
@Column({ type: 'varchar', length: 255, nullable: true })
email: string;
// Geolocalizacion
@Column({ type: 'decimal', precision: 10, scale: 8, nullable: true })
latitude: number;
@Column({ type: 'decimal', precision: 11, scale: 8, nullable: true })
longitude: number;
// Capacidad
@Column({ name: 'capacity_units', type: 'int', nullable: true })
capacityUnits: number;
@Column({ name: 'capacity_volume', type: 'decimal', precision: 10, scale: 4, nullable: true })
capacityVolume: number;
@Column({ name: 'capacity_weight', type: 'decimal', precision: 10, scale: 4, nullable: true })
capacityWeight: number;
// Configuracion
@Column({ type: 'jsonb', default: {} })
settings: {
allowNegative?: boolean;
autoReorder?: boolean;
};
// Relations (lazy-loaded to avoid circular dependency with inventory module)
// Note: Location entity in inventory module references this entity via warehouse_id FK
// Use: await warehouse.locations to load related locations
@OneToMany('Location', 'warehouse')
locations: Promise<any[]>;
// Estado
@Column({ name: 'is_active', type: 'boolean', default: true })
isActive: boolean;
@Column({ name: 'is_default', type: 'boolean', default: false })
isDefault: boolean;
// Metadata
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@Column({ name: 'created_by', type: 'uuid', nullable: true })
createdBy: string;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
updatedBy: string;
@DeleteDateColumn({ name: 'deleted_at', type: 'timestamptz', nullable: true })
deletedAt: Date;
}