Propagated modules: - payment-terminals: MercadoPago + Clip TPV - ai: Role-based AI access (ADMIN, JEFE_TALLER, MECANICO, CLIENTE) - mcp: 18 ERP tools for AI assistants Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
183 lines
4.9 KiB
TypeScript
183 lines
4.9 KiB
TypeScript
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
Index,
|
|
ManyToOne,
|
|
JoinColumn,
|
|
} from 'typeorm';
|
|
import { TenantTerminalConfig, TerminalProvider } from './tenant-terminal-config.entity';
|
|
|
|
export type TerminalPaymentStatus =
|
|
| 'pending'
|
|
| 'processing'
|
|
| 'approved'
|
|
| 'authorized'
|
|
| 'in_process'
|
|
| 'rejected'
|
|
| 'refunded'
|
|
| 'partially_refunded'
|
|
| 'cancelled'
|
|
| 'charged_back';
|
|
|
|
export type PaymentMethodType = 'card' | 'qr' | 'link' | 'cash' | 'bank_transfer';
|
|
|
|
@Entity({ name: 'terminal_payments', schema: 'payment_terminals' })
|
|
export class TerminalPayment {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
tenantId: string;
|
|
|
|
@Column({ name: 'config_id', type: 'uuid', nullable: true })
|
|
configId: string | null;
|
|
|
|
@Column({ name: 'branch_terminal_id', type: 'uuid', nullable: true })
|
|
branchTerminalId: string | null;
|
|
|
|
@Index()
|
|
@Column({
|
|
type: 'enum',
|
|
enum: ['mercadopago', 'clip', 'stripe_terminal'],
|
|
enumName: 'terminal_provider',
|
|
})
|
|
provider: TerminalProvider;
|
|
|
|
@Index()
|
|
@Column({ name: 'external_id', type: 'varchar', length: 255, nullable: true })
|
|
externalId: string | null;
|
|
|
|
@Column({ name: 'external_status', type: 'varchar', length: 50, nullable: true })
|
|
externalStatus: string | null;
|
|
|
|
// Monto
|
|
@Column({ type: 'decimal', precision: 12, scale: 2 })
|
|
amount: number;
|
|
|
|
@Column({ type: 'varchar', length: 3, default: 'MXN' })
|
|
currency: string;
|
|
|
|
// Estado
|
|
@Index()
|
|
@Column({
|
|
type: 'enum',
|
|
enum: [
|
|
'pending',
|
|
'processing',
|
|
'approved',
|
|
'authorized',
|
|
'in_process',
|
|
'rejected',
|
|
'refunded',
|
|
'partially_refunded',
|
|
'cancelled',
|
|
'charged_back',
|
|
],
|
|
enumName: 'terminal_payment_status',
|
|
default: 'pending',
|
|
})
|
|
status: TerminalPaymentStatus;
|
|
|
|
// Método de pago
|
|
@Column({
|
|
name: 'payment_method',
|
|
type: 'enum',
|
|
enum: ['card', 'qr', 'link', 'cash', 'bank_transfer'],
|
|
enumName: 'payment_method_type',
|
|
default: 'card',
|
|
})
|
|
paymentMethod: PaymentMethodType;
|
|
|
|
// Datos de tarjeta
|
|
@Column({ name: 'card_last_four', type: 'varchar', length: 4, nullable: true })
|
|
cardLastFour: string | null;
|
|
|
|
@Column({ name: 'card_brand', type: 'varchar', length: 20, nullable: true })
|
|
cardBrand: string | null;
|
|
|
|
@Column({ name: 'card_type', type: 'varchar', length: 20, nullable: true })
|
|
cardType: string | null;
|
|
|
|
// Cliente
|
|
@Column({ name: 'customer_email', type: 'varchar', length: 255, nullable: true })
|
|
customerEmail: string | null;
|
|
|
|
@Column({ name: 'customer_phone', type: 'varchar', length: 20, nullable: true })
|
|
customerPhone: string | null;
|
|
|
|
@Column({ name: 'customer_name', type: 'varchar', length: 200, nullable: true })
|
|
customerName: string | null;
|
|
|
|
// Descripción
|
|
@Column({ type: 'text', nullable: true })
|
|
description: string | null;
|
|
|
|
@Column({ name: 'statement_descriptor', type: 'varchar', length: 50, nullable: true })
|
|
statementDescriptor: string | null;
|
|
|
|
// Referencia interna
|
|
@Index()
|
|
@Column({ name: 'reference_type', type: 'varchar', length: 50, nullable: true })
|
|
referenceType: string | null;
|
|
|
|
@Column({ name: 'reference_id', type: 'uuid', nullable: true })
|
|
referenceId: string | null;
|
|
|
|
// Comisiones
|
|
@Column({ name: 'fee_amount', type: 'decimal', precision: 10, scale: 4, nullable: true })
|
|
feeAmount: number | null;
|
|
|
|
@Column({ name: 'fee_details', type: 'jsonb', nullable: true })
|
|
feeDetails: Record<string, any> | null;
|
|
|
|
@Column({ name: 'net_amount', type: 'decimal', precision: 12, scale: 2, nullable: true })
|
|
netAmount: number | null;
|
|
|
|
// Reembolso
|
|
@Column({ name: 'refunded_amount', type: 'decimal', precision: 12, scale: 2, default: 0 })
|
|
refundedAmount: number;
|
|
|
|
@Column({ name: 'refund_reason', type: 'text', nullable: true })
|
|
refundReason: string | null;
|
|
|
|
// Respuesta del proveedor
|
|
@Column({ name: 'provider_response', type: 'jsonb', nullable: true })
|
|
providerResponse: Record<string, any> | null;
|
|
|
|
// Error
|
|
@Column({ name: 'error_code', type: 'varchar', length: 50, nullable: true })
|
|
errorCode: string | null;
|
|
|
|
@Column({ name: 'error_message', type: 'text', nullable: true })
|
|
errorMessage: string | null;
|
|
|
|
// Timestamps
|
|
@Column({ name: 'processed_at', type: 'timestamptz', nullable: true })
|
|
processedAt: Date | null;
|
|
|
|
@Column({ name: 'refunded_at', type: 'timestamptz', nullable: true })
|
|
refundedAt: Date | null;
|
|
|
|
@Column({ type: 'jsonb', default: {} })
|
|
metadata: Record<string, any>;
|
|
|
|
@Index()
|
|
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
|
createdAt: Date;
|
|
|
|
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
|
|
updatedAt: Date;
|
|
|
|
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
|
createdBy: string | null;
|
|
|
|
// Relaciones
|
|
@ManyToOne(() => TenantTerminalConfig, { nullable: true })
|
|
@JoinColumn({ name: 'config_id' })
|
|
config?: TenantTerminalConfig;
|
|
}
|