erp-core-backend-v2/src/modules/billing-usage/entities/tenant-subscription.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

118 lines
3.4 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
Index,
ManyToOne,
JoinColumn,
Unique,
} from 'typeorm';
import { SubscriptionPlan } from './subscription-plan.entity';
export type BillingCycle = 'monthly' | 'annual';
export type SubscriptionStatus = 'trial' | 'active' | 'past_due' | 'cancelled' | 'suspended';
@Entity({ name: 'tenant_subscriptions', schema: 'billing' })
@Unique(['tenantId'])
export class TenantSubscription {
@PrimaryGeneratedColumn('uuid')
id: string;
@Index()
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
@Index()
@Column({ name: 'plan_id', type: 'uuid' })
planId: string;
// Periodo
@Column({ name: 'billing_cycle', type: 'varchar', length: 20, default: 'monthly' })
billingCycle: BillingCycle;
@Column({ name: 'current_period_start', type: 'timestamptz' })
currentPeriodStart: Date;
@Column({ name: 'current_period_end', type: 'timestamptz' })
currentPeriodEnd: Date;
// Estado
@Index()
@Column({ type: 'varchar', length: 20, default: 'active' })
status: SubscriptionStatus;
// Trial
@Column({ name: 'trial_start', type: 'timestamptz', nullable: true })
trialStart: Date;
@Column({ name: 'trial_end', type: 'timestamptz', nullable: true })
trialEnd: Date;
// Configuracion de facturacion
@Column({ name: 'billing_email', type: 'varchar', length: 255, nullable: true })
billingEmail: string;
@Column({ name: 'billing_name', type: 'varchar', length: 200, nullable: true })
billingName: string;
@Column({ name: 'billing_address', type: 'jsonb', default: {} })
billingAddress: Record<string, any>;
@Column({ name: 'tax_id', type: 'varchar', length: 20, nullable: true })
taxId: string; // RFC para Mexico
// Metodo de pago
@Column({ name: 'payment_method_id', type: 'uuid', nullable: true })
paymentMethodId: string;
@Column({ name: 'payment_provider', type: 'varchar', length: 30, nullable: true })
paymentProvider: string; // stripe, mercadopago, bank_transfer
// Precios actuales
@Column({ name: 'current_price', type: 'decimal', precision: 12, scale: 2 })
currentPrice: number;
@Column({ name: 'discount_percent', type: 'decimal', precision: 5, scale: 2, default: 0 })
discountPercent: number;
@Column({ name: 'discount_reason', type: 'varchar', length: 100, nullable: true })
discountReason: string;
// Uso contratado
@Column({ name: 'contracted_users', type: 'integer', nullable: true })
contractedUsers: number;
@Column({ name: 'contracted_branches', type: 'integer', nullable: true })
contractedBranches: number;
// Facturacion automatica
@Column({ name: 'auto_renew', type: 'boolean', default: true })
autoRenew: boolean;
@Column({ name: 'next_invoice_date', type: 'date', nullable: true })
nextInvoiceDate: Date;
// Cancelacion
@Column({ name: 'cancel_at_period_end', type: 'boolean', default: false })
cancelAtPeriodEnd: boolean;
@Column({ name: 'cancelled_at', type: 'timestamptz', nullable: true })
cancelledAt: Date;
@Column({ name: 'cancellation_reason', type: 'text', nullable: true })
cancellationReason: string;
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
// Relaciones
@ManyToOne(() => SubscriptionPlan)
@JoinColumn({ name: 'plan_id' })
plan: SubscriptionPlan;
}