Files
erp-efintel-2026-portainer/payroll/migrations/0001_initial.py
T
2026-09-07 18:44:32 -03:00

134 lines
13 KiB
Python

# Generated by Django 6.1 on 2026-09-07 02:36
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='EmployeeProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rut', models.CharField(max_length=20, unique=True, verbose_name='RUT Trabajador')),
('first_name', models.CharField(max_length=100, verbose_name='Nombres')),
('last_name', models.CharField(max_length=100, verbose_name='Apellidos')),
('email', models.EmailField(max_length=254, verbose_name='Correo Electrónico')),
('phone', models.CharField(blank=True, max_length=30, verbose_name='Teléfono Móvil')),
('address', models.CharField(blank=True, max_length=255, verbose_name='Dirección Particular')),
('position', models.CharField(default='Ingeniero de Desarrollo', max_length=150, verbose_name='Cargo / Especialidad I+D+i')),
('department', models.CharField(default='I+D+i y Operaciones', max_length=100, verbose_name='Departamento / Área')),
('contract_type', models.CharField(choices=[('INDEFINIDO', 'Contrato Indefinido'), ('PLAZO_FIJO', 'Contrato a Plazo Fijo'), ('HONORARIOS', 'Prestación de Servicios (Honorarios)'), ('PRACTICA', 'Práctica Profesional')], default='INDEFINIDO', max_length=50, verbose_name='Tipo de Contrato')),
('work_schedule', models.CharField(choices=[('40H_LEY_21561', '40 Horas Semanales (Ley 21.561)'), ('44H', '44 Horas Semanales'), ('45H', '45 Horas Semanales (Antiguo)'), ('30H_PART_TIME', 'Part-time 30 Horas'), ('20H_PART_TIME', 'Part-time 20 Horas'), ('ART_22_INC_2', 'Sin Fiscalización Superior (Art. 22 Inc. 2)')], default='40H_LEY_21561', max_length=50, verbose_name='Jornada Laboral')),
('hire_date', models.DateField(verbose_name='Fecha de Contratación')),
('afp', models.CharField(choices=[('HABITAT', 'AFP Habitat (11.27%)'), ('CUPRUM', 'AFP Cuprum (11.44%)'), ('MODELO', 'AFP Modelo (10.58%)'), ('PLANVITAL', 'AFP PlanVital (11.16%)'), ('PROVIDA', 'AFP ProVida (11.45%)'), ('CAPITAL', 'AFP Capital (11.44%)'), ('UNO', 'AFP Uno (10.49%)')], default='MODELO', max_length=50, verbose_name='AFP Previsional')),
('afp_rate', models.DecimalField(decimal_places=2, default=10.58, max_digits=5, verbose_name='Tasa Cotización AFP (%)')),
('health_system', models.CharField(choices=[('FONASA', 'FONASA (7.00%)'), ('ISAPRE', 'ISAPRE (Pactado UF / %)')], default='FONASA', max_length=50, verbose_name='Sistema de Salud')),
('health_institution', models.CharField(blank=True, default='FONASA', max_length=100, verbose_name='Institución Salud (FONASA / Isapre)')),
('health_plan_uf', models.DecimalField(decimal_places=4, default=0, max_digits=6, verbose_name='Plan Salud Pactado (UF - solo Isapre)')),
('health_rate', models.DecimalField(decimal_places=2, default=7.0, max_digits=5, verbose_name='Tasa Legal Salud (%)')),
('has_afc', models.BooleanField(default=True, verbose_name='Afecto a Seguro de Cesantía (AFC)')),
('base_salary_clp', models.DecimalField(decimal_places=2, default=1500000, max_digits=12, verbose_name='Sueldo Base Mensual (CLP)')),
('colacion_clp', models.DecimalField(decimal_places=2, default=65000, max_digits=10, verbose_name='Asignación Colación (No Imponible)')),
('movilizacion_clp', models.DecimalField(decimal_places=2, default=65000, max_digits=10, verbose_name='Asignación Movilización (No Imponible)')),
('bank_name', models.CharField(default='Banco Santander-Chile', max_length=100, verbose_name='Banco Receptor')),
('account_type', models.CharField(choices=[('CORRIENTE', 'Cuenta Corriente'), ('VISTA_RUT', 'Cuenta Vista / Cuenta RUT'), ('AHORRO', 'Cuenta de Ahorro')], default='CORRIENTE', max_length=50, verbose_name='Tipo de Cuenta')),
('account_number', models.CharField(default='00000000', max_length=50, verbose_name='Número de Cuenta Bancaria')),
('is_active', models.BooleanField(default=True, verbose_name='Trabajador Activo')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_profile', to=settings.AUTH_USER_MODEL, verbose_name='Usuario del Sistema')),
],
options={
'verbose_name': 'Perfil de Colaborador',
'verbose_name_plural': 'Nómina de Colaboradores',
'ordering': ['last_name', 'first_name'],
},
),
migrations.CreateModel(
name='PayrollCentralizationEntry',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('month', models.IntegerField(verbose_name='Mes')),
('year', models.IntegerField(verbose_name='Año')),
('entry_date', models.DateField(verbose_name='Fecha del Asiento')),
('glosa', models.CharField(default='Centralización de Remuneraciones y Leyes Sociales', max_length=255, verbose_name='Glosa Contable')),
('account_code', models.CharField(default='5101', max_length=50, verbose_name='Cuenta Contable Débito (5101)')),
('account_name', models.CharField(default='Gastos en Personal y Cargas Sociales I+D+i', max_length=150, verbose_name='Nombre Cuenta Débito')),
('total_taxable', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Total Haberes Imponibles')),
('total_non_taxable', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Total Haberes No Imponibles')),
('total_employer_charges', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Total Cargas Sociales Empleador (SIS/ACHS/AFC)')),
('total_net_payable', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Sueldos Líquidos por Pagar (Banco)')),
('total_previred_payable', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Cotizaciones por Pagar (Previred)')),
('total_sii_payable', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Retención Impuesto Único SII')),
('total_debit', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Total Debe (CLP)')),
('total_credit', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Total Haber (CLP)')),
('is_balanced', models.BooleanField(default=True, verbose_name='Asiento Cuadrado (Debe == Haber)')),
('status', models.CharField(default='CONTABILIZADO', max_length=30, verbose_name='Estado Asiento')),
('created_at', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name': 'Asiento de Centralización de Remuneraciones',
'verbose_name_plural': 'Asientos de Centralización (Cuenta 5101)',
'ordering': ['-year', '-month'],
'unique_together': {('month', 'year')},
},
),
migrations.CreateModel(
name='SalarySlip',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('slip_uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('month', models.IntegerField(verbose_name='Mes (1-12)')),
('year', models.IntegerField(verbose_name='Año (ej. 2026)')),
('issue_date', models.DateField(verbose_name='Fecha de Emisión')),
('days_worked', models.IntegerField(default=30, verbose_name='Días Trabajados')),
('base_salary', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Sueldo Base')),
('overtime_hours_50', models.DecimalField(decimal_places=2, default=0, max_digits=5, verbose_name='Horas Extras (50%)')),
('overtime_amount_50', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Monto Horas Extras 50%')),
('legal_gratification', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Gratificación Legal (Art. 50)')),
('rd_bonus', models.DecimalField(decimal_places=2, default=0, max_digits=12, verbose_name='Bonos de Rendimiento I+D+i')),
('other_taxable', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Otros Haberes Imponibles')),
('total_taxable_income', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Total Haberes Imponibles')),
('allowance_lunch', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Asignación Colación')),
('allowance_commute', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Asignación Movilización')),
('expense_reimbursements', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Reembolsos de Gastos en Terreno')),
('total_non_taxable_income', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Total Haberes No Imponibles')),
('total_gross_income', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Total Haberes (Bruto)')),
('afp_deduction', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Cotización Previsional AFP')),
('health_deduction', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Cotización Legal Salud (7% o Isapre)')),
('afc_deduction', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Seguro de Cesantía Trabajador (AFC 0.6%)')),
('second_category_tax', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Impuesto Único 2da Categoría SII')),
('other_deductions', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Otros Descuentos / Anticipos')),
('total_deductions', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Total Descuentos')),
('net_salary', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Sueldo Líquido a Pagar')),
('employer_sis', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Seguro Invalidez y Sobrevivencia SIS (1.49%)')),
('employer_mutual', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Aporte Mutualidad / ACHS (0.93%)')),
('employer_afc', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Seguro Cesantía Empleador AFC (2.4%)')),
('total_company_cost', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Costo Total Empresa')),
('status', models.CharField(choices=[('BORRADOR', 'Borrador'), ('EMITIDA', 'Emitida (Pendiente de Firma)'), ('FIRMADA', 'Firmada Digitalmente'), ('PAGADA', 'Pagada / Transferida'), ('ANULADA', 'Anulada')], default='BORRADOR', max_length=30, verbose_name='Estado de Liquidación')),
('digital_signature_hash', models.CharField(blank=True, max_length=128, verbose_name='Hash de Firma Digital (SHA-256)')),
('signed_at', models.DateTimeField(blank=True, null=True, verbose_name='Fecha y Hora de Firma')),
('notes', models.TextField(blank=True, verbose_name='Observaciones')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='salary_slips', to='payroll.employeeprofile', verbose_name='Colaborador')),
],
options={
'verbose_name': 'Liquidación de Sueldo',
'verbose_name_plural': 'Liquidaciones de Sueldo (Buk)',
'ordering': ['-year', '-month', 'employee__last_name'],
'unique_together': {('employee', 'month', 'year')},
},
),
]