[SPRINT-2-COHERENCIA] feat: Add missing DDL tables and fix numbering

- Add inventory.lots table (coherence with lot.entity.ts)
- Add inventory.pickings table with ENUMs (coherence with picking.entity.ts)
- Add partners.partner_tax_info table (coherence with partner-tax-info.entity.ts)
- Add partners.partner_segments table (coherence with partner-segment.entity.ts)
- Rename 21-fiscal-catalogs.sql to 26-fiscal-catalogs.sql (fix duplicate with 21-inventory.sql)
- Remove duplicate 25-fiscal-catalogs.sql

Gaps resolved:
- GAP-P1-001: lots DDL added
- GAP-P1-002: pickings DDL added
- GAP-P1-006: partner_tax_info DDL added
- GAP-P1-007: partner_segments DDL added
- GAP-P1-008: DDL numbering fixed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Adrian Flores Cortes 2026-01-24 08:54:32 -06:00
parent 67cb99d4b4
commit ac54edc855
4 changed files with 229 additions and 298 deletions

View File

@ -213,3 +213,103 @@ COMMENT ON TABLE partners.partner_contacts IS 'Personas de contacto individuales
COMMENT ON COLUMN partners.partner_contacts.contact_type IS 'Rol: general, billing, purchasing, sales, technical'; COMMENT ON COLUMN partners.partner_contacts.contact_type IS 'Rol: general, billing, purchasing, sales, technical';
COMMENT ON TABLE partners.partner_bank_accounts IS 'Cuentas bancarias de partners para pagos/cobros'; COMMENT ON TABLE partners.partner_bank_accounts IS 'Cuentas bancarias de partners para pagos/cobros';
-- =====================
-- TABLA: partner_tax_info
-- Informacion fiscal extendida para facturacion y cumplimiento
-- Coherencia: partner-tax-info.entity.ts
-- =====================
CREATE TABLE IF NOT EXISTS partners.partner_tax_info (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
partner_id UUID NOT NULL REFERENCES partners.partners(id) ON DELETE CASCADE,
-- Identificacion fiscal
tax_id_type VARCHAR(20), -- RFC, CURP, EIN, VAT
tax_id_country VARCHAR(3) DEFAULT 'MEX',
-- SAT (Mexico) especifico
sat_regime VARCHAR(10), -- 601, 603, 612, etc.
sat_regime_name VARCHAR(200),
cfdi_use VARCHAR(10), -- G01, G02, G03, etc.
cfdi_use_name VARCHAR(200),
fiscal_zip_code VARCHAR(10),
-- Retenciones
withholding_isr DECIMAL(5, 2) DEFAULT 0,
withholding_iva DECIMAL(5, 2) DEFAULT 0,
-- Validacion
is_verified BOOLEAN DEFAULT FALSE,
verified_at TIMESTAMPTZ,
verification_source VARCHAR(50), -- SAT, MANUAL, API
-- Metadata
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
-- Indices para partner_tax_info
CREATE INDEX IF NOT EXISTS idx_partner_tax_info_partner ON partners.partner_tax_info(partner_id);
CREATE INDEX IF NOT EXISTS idx_partner_tax_info_regime ON partners.partner_tax_info(sat_regime);
CREATE INDEX IF NOT EXISTS idx_partner_tax_info_verified ON partners.partner_tax_info(is_verified) WHERE is_verified = TRUE;
-- =====================
-- TABLA: partner_segments
-- Segmentos de clientes/proveedores para agrupacion y analytics
-- Coherencia: partner-segment.entity.ts
-- =====================
CREATE TABLE IF NOT EXISTS partners.partner_segments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
-- Identificacion
code VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo de segmento
segment_type VARCHAR(20) DEFAULT 'customer', -- customer, supplier, both
-- Estilo visual
color VARCHAR(20),
icon VARCHAR(50),
-- Reglas de auto-asignacion (JSON)
rules JSONB,
-- Beneficios/condiciones
default_discount DECIMAL(5, 2) DEFAULT 0,
default_payment_terms INTEGER DEFAULT 0,
priority INTEGER DEFAULT 0,
-- Estado
is_active BOOLEAN DEFAULT TRUE,
sort_order INTEGER DEFAULT 0,
-- Metadata
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_by UUID REFERENCES auth.users(id),
UNIQUE(tenant_id, code)
);
-- Indices para partner_segments
CREATE INDEX IF NOT EXISTS idx_partner_segments_tenant ON partners.partner_segments(tenant_id);
CREATE INDEX IF NOT EXISTS idx_partner_segments_code ON partners.partner_segments(code);
CREATE INDEX IF NOT EXISTS idx_partner_segments_type ON partners.partner_segments(segment_type);
CREATE INDEX IF NOT EXISTS idx_partner_segments_active ON partners.partner_segments(is_active) WHERE is_active = TRUE;
-- =====================
-- COMENTARIOS ADICIONALES
-- =====================
COMMENT ON TABLE partners.partner_tax_info IS 'Informacion fiscal extendida para cumplimiento de facturacion electronica (CFDI en Mexico)';
COMMENT ON COLUMN partners.partner_tax_info.sat_regime IS 'Regimen fiscal SAT (ej: 601-General de Ley, 612-Persona Fisica)';
COMMENT ON COLUMN partners.partner_tax_info.cfdi_use IS 'Uso del CFDI (ej: G01-Adquisicion de mercancias, G03-Gastos en general)';
COMMENT ON COLUMN partners.partner_tax_info.withholding_isr IS 'Porcentaje de retencion de ISR';
COMMENT ON COLUMN partners.partner_tax_info.withholding_iva IS 'Porcentaje de retencion de IVA';
COMMENT ON TABLE partners.partner_segments IS 'Segmentos para clasificar y agrupar partners (VIP, Mayorista, Local, etc.)';
COMMENT ON COLUMN partners.partner_segments.rules IS 'Reglas JSON para auto-asignacion de partners al segmento';
COMMENT ON COLUMN partners.partner_segments.default_discount IS 'Descuento por defecto para partners en este segmento';

View File

@ -301,3 +301,128 @@ COMMENT ON COLUMN inventory.inventory_counts.count_type IS 'Tipo: full (completo
COMMENT ON TABLE inventory.transfer_orders IS 'Ordenes de transferencia entre almacenes'; COMMENT ON TABLE inventory.transfer_orders IS 'Ordenes de transferencia entre almacenes';
COMMENT ON COLUMN inventory.transfer_orders.status IS 'Estado: draft, confirmed, shipped, in_transit, received, cancelled'; COMMENT ON COLUMN inventory.transfer_orders.status IS 'Estado: draft, confirmed, shipped, in_transit, received, cancelled';
-- =====================
-- TABLA: lots
-- Lotes de productos para trazabilidad y control de caducidad
-- Coherencia: lot.entity.ts
-- =====================
CREATE TABLE IF NOT EXISTS inventory.lots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES products.products(id) ON DELETE CASCADE,
-- Identificacion
name VARCHAR(100) NOT NULL,
ref VARCHAR(100),
-- Fechas de control
manufacture_date DATE,
expiration_date DATE,
removal_date DATE,
alert_date DATE,
-- Notas
notes TEXT,
-- Metadata
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES auth.users(id),
UNIQUE(product_id, name)
);
-- Indices para lots
CREATE INDEX IF NOT EXISTS idx_lots_tenant ON inventory.lots(tenant_id);
CREATE INDEX IF NOT EXISTS idx_lots_product ON inventory.lots(product_id);
CREATE INDEX IF NOT EXISTS idx_lots_name_product ON inventory.lots(product_id, name);
CREATE INDEX IF NOT EXISTS idx_lots_expiration ON inventory.lots(expiration_date) WHERE expiration_date IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_lots_alert ON inventory.lots(alert_date) WHERE alert_date IS NOT NULL;
-- =====================
-- TIPO ENUM: picking_type
-- =====================
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'picking_type_enum') THEN
CREATE TYPE inventory.picking_type_enum AS ENUM ('incoming', 'outgoing', 'internal');
END IF;
END$$;
-- =====================
-- TIPO ENUM: move_status
-- =====================
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'move_status_enum') THEN
CREATE TYPE inventory.move_status_enum AS ENUM ('draft', 'waiting', 'confirmed', 'assigned', 'done', 'cancelled');
END IF;
END$$;
-- =====================
-- TABLA: pickings
-- Operaciones de recepcion, envio y movimientos internos
-- Coherencia: picking.entity.ts
-- =====================
CREATE TABLE IF NOT EXISTS inventory.pickings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
-- Identificacion
name VARCHAR(100) NOT NULL,
-- Tipo de operacion
picking_type inventory.picking_type_enum NOT NULL,
-- Ubicaciones
location_id UUID NOT NULL REFERENCES inventory.warehouse_locations(id),
location_dest_id UUID NOT NULL REFERENCES inventory.warehouse_locations(id),
-- Partner (proveedor/cliente)
partner_id UUID REFERENCES partners.partners(id),
-- Fechas
scheduled_date TIMESTAMPTZ,
date_done TIMESTAMPTZ,
-- Origen (referencia documento)
origin VARCHAR(255),
-- Estado
status inventory.move_status_enum NOT NULL DEFAULT 'draft',
-- Notas
notes TEXT,
-- Validacion
validated_at TIMESTAMPTZ,
validated_by UUID REFERENCES auth.users(id),
-- Metadata
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES auth.users(id),
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_by UUID REFERENCES auth.users(id)
);
-- Indices para pickings
CREATE INDEX IF NOT EXISTS idx_pickings_tenant ON inventory.pickings(tenant_id);
CREATE INDEX IF NOT EXISTS idx_pickings_company ON inventory.pickings(company_id);
CREATE INDEX IF NOT EXISTS idx_pickings_status ON inventory.pickings(status);
CREATE INDEX IF NOT EXISTS idx_pickings_partner ON inventory.pickings(partner_id) WHERE partner_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_pickings_scheduled ON inventory.pickings(scheduled_date);
CREATE INDEX IF NOT EXISTS idx_pickings_type ON inventory.pickings(picking_type);
-- =====================
-- COMENTARIOS ADICIONALES
-- =====================
COMMENT ON TABLE inventory.lots IS 'Lotes de productos para trazabilidad, control de caducidad y FIFO/FEFO';
COMMENT ON COLUMN inventory.lots.name IS 'Numero o nombre del lote (debe ser unico por producto)';
COMMENT ON COLUMN inventory.lots.expiration_date IS 'Fecha de caducidad del lote';
COMMENT ON COLUMN inventory.lots.alert_date IS 'Fecha para alerta previa a caducidad';
COMMENT ON TABLE inventory.pickings IS 'Operaciones de recepcion (incoming), envio (outgoing) y movimientos internos';
COMMENT ON COLUMN inventory.pickings.picking_type IS 'Tipo: incoming (recepcion), outgoing (envio), internal (transferencia interna)';
COMMENT ON COLUMN inventory.pickings.status IS 'Estado: draft, waiting, confirmed, assigned, done, cancelled';
COMMENT ON COLUMN inventory.pickings.origin IS 'Documento origen (ej: PO-2026-001, SO-2026-001)';

View File

@ -1,295 +0,0 @@
-- =============================================================
-- ARCHIVO: 21-fiscal-catalogs.sql
-- DESCRIPCION: Catalogos fiscales - SAT Mexico, regimenes, CFDI
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-18
-- =============================================================
-- =====================
-- SCHEMA: fiscal
-- =====================
CREATE SCHEMA IF NOT EXISTS fiscal;
-- =====================
-- TABLA: tax_categories
-- Categorias de impuestos (IVA, ISR, IEPS, etc.)
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.tax_categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(20) NOT NULL UNIQUE, -- IVA, ISR, IEPS, etc.
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo de impuesto
tax_nature VARCHAR(20) NOT NULL DEFAULT 'tax', -- tax, withholding, both
-- Configuracion SAT Mexico
sat_code VARCHAR(10), -- Codigo SAT (002=IVA, 001=ISR, etc.)
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_tax_categories_code ON fiscal.tax_categories(code);
CREATE INDEX IF NOT EXISTS idx_tax_categories_sat ON fiscal.tax_categories(sat_code);
CREATE INDEX IF NOT EXISTS idx_tax_categories_active ON fiscal.tax_categories(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.tax_categories IS 'Categorias de impuestos (IVA, ISR, IEPS, etc.)';
-- =====================
-- TABLA: fiscal_regimes
-- Regimenes fiscales SAT Mexico (Catalogo c_RegimenFiscal)
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.fiscal_regimes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(10) NOT NULL UNIQUE, -- Codigo SAT (601, 603, 612, etc.)
name VARCHAR(255) NOT NULL,
description TEXT,
-- Aplica a persona fisica o moral
applies_to VARCHAR(20) NOT NULL DEFAULT 'both', -- natural (fisica), legal (moral), both
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_fiscal_regimes_code ON fiscal.fiscal_regimes(code);
CREATE INDEX IF NOT EXISTS idx_fiscal_regimes_applies ON fiscal.fiscal_regimes(applies_to);
CREATE INDEX IF NOT EXISTS idx_fiscal_regimes_active ON fiscal.fiscal_regimes(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.fiscal_regimes IS 'Catalogo de regimenes fiscales SAT (c_RegimenFiscal)';
-- =====================
-- TABLA: cfdi_uses
-- Uso del CFDI SAT Mexico (Catalogo c_UsoCFDI)
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.cfdi_uses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(10) NOT NULL UNIQUE, -- Codigo SAT (G01, G02, G03, etc.)
name VARCHAR(255) NOT NULL,
description TEXT,
-- Aplica a persona fisica o moral
applies_to VARCHAR(20) NOT NULL DEFAULT 'both', -- natural, legal, both
-- Regimenes fiscales permitidos (NULL = todos)
allowed_regimes VARCHAR[] DEFAULT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_cfdi_uses_code ON fiscal.cfdi_uses(code);
CREATE INDEX IF NOT EXISTS idx_cfdi_uses_applies ON fiscal.cfdi_uses(applies_to);
CREATE INDEX IF NOT EXISTS idx_cfdi_uses_active ON fiscal.cfdi_uses(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.cfdi_uses IS 'Catalogo de uso del CFDI SAT (c_UsoCFDI)';
-- =====================
-- TABLA: payment_methods
-- Formas de pago SAT Mexico (Catalogo c_FormaPago)
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.payment_methods (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(10) NOT NULL UNIQUE, -- Codigo SAT (01, 02, 03, etc.)
name VARCHAR(100) NOT NULL,
description TEXT,
-- Configuracion
requires_bank_info BOOLEAN DEFAULT FALSE, -- Requiere info bancaria
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_payment_methods_code ON fiscal.payment_methods(code);
CREATE INDEX IF NOT EXISTS idx_payment_methods_active ON fiscal.payment_methods(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.payment_methods IS 'Catalogo de formas de pago SAT (c_FormaPago)';
-- =====================
-- TABLA: payment_types
-- Metodos de pago SAT Mexico (Catalogo c_MetodoPago)
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.payment_types (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(10) NOT NULL UNIQUE, -- PUE, PPD
name VARCHAR(100) NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_payment_types_code ON fiscal.payment_types(code);
CREATE INDEX IF NOT EXISTS idx_payment_types_active ON fiscal.payment_types(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.payment_types IS 'Catalogo de metodos de pago SAT (c_MetodoPago)';
-- =====================
-- TABLA: withholding_types
-- Tipos de retencion
-- =====================
CREATE TABLE IF NOT EXISTS fiscal.withholding_types (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(20) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tasa de retencion por defecto
default_rate DECIMAL(5, 2) NOT NULL DEFAULT 0,
-- Categoria de impuesto asociada
tax_category_id UUID REFERENCES fiscal.tax_categories(id),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_withholding_types_code ON fiscal.withholding_types(code);
CREATE INDEX IF NOT EXISTS idx_withholding_types_category ON fiscal.withholding_types(tax_category_id);
CREATE INDEX IF NOT EXISTS idx_withholding_types_active ON fiscal.withholding_types(is_active) WHERE is_active = TRUE;
COMMENT ON TABLE fiscal.withholding_types IS 'Tipos de retencion fiscal';
-- =====================
-- DATOS INICIALES: tax_categories
-- =====================
INSERT INTO fiscal.tax_categories (code, name, description, tax_nature, sat_code) VALUES
('IVA', 'Impuesto al Valor Agregado', 'Impuesto al consumo aplicado a bienes y servicios', 'tax', '002'),
('ISR', 'Impuesto Sobre la Renta', 'Impuesto a los ingresos', 'withholding', '001'),
('IEPS', 'Impuesto Especial sobre Produccion y Servicios', 'Impuesto a productos especiales', 'tax', '003'),
('IVA_RET', 'IVA Retenido', 'Retencion de IVA', 'withholding', '002'),
('ISR_RET', 'ISR Retenido', 'Retencion de ISR', 'withholding', '001'),
('CEDULAR', 'Impuesto Cedular', 'Impuesto local sobre ingresos', 'tax', NULL),
('ISH', 'Impuesto Sobre Hospedaje', 'Impuesto estatal al hospedaje', 'tax', NULL)
ON CONFLICT (code) DO NOTHING;
-- =====================
-- DATOS INICIALES: fiscal_regimes (SAT Mexico c_RegimenFiscal)
-- =====================
INSERT INTO fiscal.fiscal_regimes (code, name, applies_to) VALUES
('601', 'General de Ley Personas Morales', 'legal'),
('603', 'Personas Morales con Fines no Lucrativos', 'legal'),
('605', 'Sueldos y Salarios e Ingresos Asimilados a Salarios', 'natural'),
('606', 'Arrendamiento', 'natural'),
('607', 'Régimen de Enajenación o Adquisición de Bienes', 'natural'),
('608', 'Demás ingresos', 'natural'),
('609', 'Consolidación', 'legal'),
('610', 'Residentes en el Extranjero sin Establecimiento Permanente en México', 'both'),
('611', 'Ingresos por Dividendos (socios y accionistas)', 'natural'),
('612', 'Personas Físicas con Actividades Empresariales y Profesionales', 'natural'),
('614', 'Ingresos por intereses', 'natural'),
('615', 'Régimen de los ingresos por obtención de premios', 'natural'),
('616', 'Sin obligaciones fiscales', 'both'),
('620', 'Sociedades Cooperativas de Producción que optan por diferir sus ingresos', 'legal'),
('621', 'Incorporación Fiscal', 'natural'),
('622', 'Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras', 'both'),
('623', 'Opcional para Grupos de Sociedades', 'legal'),
('624', 'Coordinados', 'legal'),
('625', 'Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas', 'natural'),
('626', 'Régimen Simplificado de Confianza', 'both')
ON CONFLICT (code) DO NOTHING;
-- =====================
-- DATOS INICIALES: cfdi_uses (SAT Mexico c_UsoCFDI)
-- =====================
INSERT INTO fiscal.cfdi_uses (code, name, applies_to) VALUES
('G01', 'Adquisición de mercancías', 'both'),
('G02', 'Devoluciones, descuentos o bonificaciones', 'both'),
('G03', 'Gastos en general', 'both'),
('I01', 'Construcciones', 'both'),
('I02', 'Mobiliario y equipo de oficina por inversiones', 'both'),
('I03', 'Equipo de transporte', 'both'),
('I04', 'Equipo de cómputo y accesorios', 'both'),
('I05', 'Dados, troqueles, moldes, matrices y herramental', 'both'),
('I06', 'Comunicaciones telefónicas', 'both'),
('I07', 'Comunicaciones satelitales', 'both'),
('I08', 'Otra maquinaria y equipo', 'both'),
('D01', 'Honorarios médicos, dentales y gastos hospitalarios', 'natural'),
('D02', 'Gastos médicos por incapacidad o discapacidad', 'natural'),
('D03', 'Gastos funerales', 'natural'),
('D04', 'Donativos', 'natural'),
('D05', 'Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación)', 'natural'),
('D06', 'Aportaciones voluntarias al SAR', 'natural'),
('D07', 'Primas por seguros de gastos médicos', 'natural'),
('D08', 'Gastos de transportación escolar obligatoria', 'natural'),
('D09', 'Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones', 'natural'),
('D10', 'Pagos por servicios educativos (colegiaturas)', 'natural'),
('S01', 'Sin efectos fiscales', 'both'),
('CP01', 'Pagos', 'both'),
('CN01', 'Nómina', 'natural')
ON CONFLICT (code) DO NOTHING;
-- =====================
-- DATOS INICIALES: payment_methods (SAT Mexico c_FormaPago)
-- =====================
INSERT INTO fiscal.payment_methods (code, name, requires_bank_info) VALUES
('01', 'Efectivo', false),
('02', 'Cheque nominativo', true),
('03', 'Transferencia electrónica de fondos', true),
('04', 'Tarjeta de crédito', true),
('05', 'Monedero electrónico', false),
('06', 'Dinero electrónico', false),
('08', 'Vales de despensa', false),
('12', 'Dación en pago', false),
('13', 'Pago por subrogación', false),
('14', 'Pago por consignación', false),
('15', 'Condonación', false),
('17', 'Compensación', false),
('23', 'Novación', false),
('24', 'Confusión', false),
('25', 'Remisión de deuda', false),
('26', 'Prescripción o caducidad', false),
('27', 'A satisfacción del acreedor', false),
('28', 'Tarjeta de débito', true),
('29', 'Tarjeta de servicios', true),
('30', 'Aplicación de anticipos', false),
('31', 'Intermediario pagos', false),
('99', 'Por definir', false)
ON CONFLICT (code) DO NOTHING;
-- =====================
-- DATOS INICIALES: payment_types (SAT Mexico c_MetodoPago)
-- =====================
INSERT INTO fiscal.payment_types (code, name, description) VALUES
('PUE', 'Pago en una sola exhibición', 'El pago se realiza en una sola exhibición al momento de emitir el CFDI'),
('PPD', 'Pago en parcialidades o diferido', 'El pago se realiza en parcialidades o de forma diferida')
ON CONFLICT (code) DO NOTHING;
-- =====================
-- DATOS INICIALES: withholding_types
-- =====================
INSERT INTO fiscal.withholding_types (code, name, description, default_rate, tax_category_id) VALUES
('ISR_10', 'Retención ISR 10%', 'Retención de ISR al 10% para servicios profesionales', 10.00,
(SELECT id FROM fiscal.tax_categories WHERE code = 'ISR')),
('ISR_10.67', 'Retención ISR 10.67%', 'Retención de ISR al 10.67% para arrendamiento', 10.67,
(SELECT id FROM fiscal.tax_categories WHERE code = 'ISR')),
('IVA_RET_10.67', 'Retención IVA 10.67%', 'Retención de IVA para servicios profesionales persona moral', 10.67,
(SELECT id FROM fiscal.tax_categories WHERE code = 'IVA_RET')),
('IVA_RET_4', 'Retención IVA 4%', 'Retención de IVA al 4% para autotransporte', 4.00,
(SELECT id FROM fiscal.tax_categories WHERE code = 'IVA_RET'))
ON CONFLICT (code) DO NOTHING;
-- =====================
-- FIN DEL ARCHIVO
-- =====================

View File

@ -1,9 +1,10 @@
-- ============================================================= -- =============================================================
-- ARCHIVO: 21-fiscal-catalogs.sql -- ARCHIVO: 26-fiscal-catalogs.sql
-- DESCRIPCION: Catalogos fiscales - SAT Mexico, regimenes, CFDI -- DESCRIPCION: Catalogos fiscales - SAT Mexico, regimenes, CFDI
-- VERSION: 1.0.0 -- VERSION: 1.0.1
-- PROYECTO: ERP-Core V2 -- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-18 -- FECHA: 2026-01-24
-- NOTA: Renumerado de 21 a 26 para resolver conflicto con 21-inventory.sql
-- ============================================================= -- =============================================================
-- ===================== -- =====================