erp-core-backend-v2/src/modules/branches/entities/branch.entity.ts
rckrdmrd ca07b4268d feat: Add complete module structure for ERP backend
- Add modules: ai, audit, billing-usage, biometrics, branches, dashboard,
  feature-flags, invoices, mcp, mobile, notifications, partners,
  payment-terminals, products, profiles, purchases, reports, sales,
  storage, warehouses, webhooks, whatsapp
- Add controllers, DTOs, entities, and services for each module
- Add shared services and utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 00:40:54 -06:00

159 lines
4.3 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Index,
ManyToOne,
OneToMany,
JoinColumn,
Unique,
} from 'typeorm';
import { UserBranchAssignment } from './user-branch-assignment.entity';
import { BranchSchedule } from './branch-schedule.entity';
import { BranchPaymentTerminal } from './branch-payment-terminal.entity';
export type BranchType = 'headquarters' | 'regional' | 'store' | 'warehouse' | 'office' | 'factory';
@Entity({ name: 'branches', schema: 'core' })
@Unique(['tenantId', 'code'])
export class Branch {
@PrimaryGeneratedColumn('uuid')
id: string;
@Index()
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
@Index()
@Column({ name: 'parent_id', type: 'uuid', nullable: true })
parentId: string;
// Identificacion
@Index()
@Column({ type: 'varchar', length: 20 })
code: string;
@Column({ type: 'varchar', length: 100 })
name: string;
@Column({ name: 'short_name', type: 'varchar', length: 50, nullable: true })
shortName: string;
// Tipo
@Index()
@Column({ name: 'branch_type', type: 'varchar', length: 30, default: 'store' })
branchType: BranchType;
// Contacto
@Column({ type: 'varchar', length: 20, nullable: true })
phone: string;
@Column({ type: 'varchar', length: 255, nullable: true })
email: string;
@Column({ name: 'manager_id', type: 'uuid', nullable: true })
managerId: string;
// 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;
// Geolocalizacion
@Column({ type: 'decimal', precision: 10, scale: 8, nullable: true })
latitude: number;
@Column({ type: 'decimal', precision: 11, scale: 8, nullable: true })
longitude: number;
@Column({ name: 'geofence_radius', type: 'integer', default: 100 })
geofenceRadius: number; // Radio en metros
@Column({ name: 'geofence_enabled', type: 'boolean', default: true })
geofenceEnabled: boolean;
// Configuracion
@Column({ type: 'varchar', length: 50, default: 'America/Mexico_City' })
timezone: string;
@Column({ type: 'varchar', length: 3, default: 'MXN' })
currency: string;
@Index()
@Column({ name: 'is_active', type: 'boolean', default: true })
isActive: boolean;
@Column({ name: 'is_main', type: 'boolean', default: false })
isMain: boolean; // Sucursal principal/matriz
// Horarios de operacion
@Column({ name: 'operating_hours', type: 'jsonb', default: {} })
operatingHours: Record<string, { open: string; close: string }>;
// Configuraciones especificas
@Column({ type: 'jsonb', default: {} })
settings: {
allowPos?: boolean;
allowWarehouse?: boolean;
allowCheckIn?: boolean;
[key: string]: any;
};
// Jerarquia (path materializado)
@Index()
@Column({ name: 'hierarchy_path', type: 'text', nullable: true })
hierarchyPath: string;
@Column({ name: 'hierarchy_level', type: 'integer', default: 0 })
hierarchyLevel: number;
@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;
// Relaciones
@ManyToOne(() => Branch, { nullable: true })
@JoinColumn({ name: 'parent_id' })
parent: Branch;
@OneToMany(() => Branch, (branch) => branch.parent)
children: Branch[];
@OneToMany(() => UserBranchAssignment, (assignment) => assignment.branch)
userAssignments: UserBranchAssignment[];
@OneToMany(() => BranchSchedule, (schedule) => schedule.branch)
schedules: BranchSchedule[];
@OneToMany(() => BranchPaymentTerminal, (terminal) => terminal.branch)
paymentTerminals: BranchPaymentTerminal[];
}