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; @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; }