Feat: dashboard con gráficos, estructura CBS/Portafolios, semáforo de proyectos y cartera de especialistas

This commit is contained in:
Nachou-u
2026-08-20 18:54:58 -04:00
parent 8c0b435555
commit b692614857
25 changed files with 1717 additions and 159 deletions
@@ -0,0 +1,60 @@
# Generated by Django 6.1 on 2026-08-19 22:57
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Vendor',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rut', models.CharField(max_length=15, unique=True, verbose_name='RUT Proveedor')),
('name', models.CharField(max_length=200, verbose_name='Razón Social / Nombre')),
('business_line', models.CharField(blank=True, max_length=200, null=True, verbose_name='Giro Comercial')),
('bank', models.CharField(blank=True, max_length=100, null=True, verbose_name='Banco')),
('account_type', models.CharField(blank=True, max_length=50, null=True, verbose_name='Tipo de Cuenta')),
('account_number', models.CharField(blank=True, max_length=50, null=True, verbose_name='Número de Cuenta')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Correo de Pago/Facturación')),
('payment_terms', models.IntegerField(default=30, verbose_name='Plazo de Pago (Días)')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Proveedor',
'verbose_name_plural': 'Proveedores',
'ordering': ['name'],
},
),
migrations.AddField(
model_name='expense',
name='tax_amount_clp',
field=models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Monto Impuesto (CLP)'),
),
migrations.AddField(
model_name='expense',
name='tax_type',
field=models.CharField(choices=[('EXENTO', 'Exento / No Afecto'), ('IVA_19', 'Afecto a IVA (19%)'), ('HONORARIOS_13_75', 'Boleta de Honorarios (13.75%)')], default='IVA_19', max_length=20, verbose_name='Tipo de Impuesto'),
),
migrations.AddField(
model_name='expense',
name='total_amount_clp',
field=models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Monto Total (CLP)'),
),
migrations.AlterField(
model_name='expense',
name='amount_usd',
field=models.DecimalField(decimal_places=2, max_digits=15, verbose_name='Monto Total (USD)'),
),
migrations.AlterField(
model_name='expense',
name='vendor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses', to='expenses.vendor', verbose_name='Proveedor / Emisor'),
),
]
@@ -0,0 +1,17 @@
# Generated by Django 6.1 on 2026-08-19 23:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('expenses', '0002_vendor_expense_tax_amount_clp_expense_tax_type_and_more'),
]
operations = [
migrations.RemoveField(
model_name='category',
name='parent',
),
]
@@ -0,0 +1,19 @@
# Generated by Django 6.1 on 2026-08-20 15:19
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0003_remove_category_parent'),
]
operations = [
migrations.AddField(
model_name='category',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='expenses.category', verbose_name='Categoría Padre'),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 6.1 on 2026-08-20 22:30
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0004_category_parent'),
]
operations = [
migrations.AddField(
model_name='project',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='expenses.project', verbose_name='Portafolio / Proyecto Padre'),
),
]
@@ -0,0 +1,29 @@
# Generated by Django 6.1 on 2026-08-20 22:44
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0005_project_parent'),
]
operations = [
migrations.AddField(
model_name='project',
name='category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='projects', to='expenses.category', verbose_name='Categoría del Proyecto'),
),
migrations.AddField(
model_name='userprofile',
name='specialties',
field=models.ManyToManyField(blank=True, related_name='specialists', to='expenses.category', verbose_name='Especialidades / Habilidades'),
),
migrations.AlterField(
model_name='project',
name='status',
field=models.CharField(choices=[('ACTIVO', 'Activo'), ('PAUSADA', 'En Pausa'), ('TERMINADO', 'Terminado')], default='ACTIVO', max_length=50, verbose_name='Estado de Proyecto'),
),
]