Files
erp-efintel-2026-portainer/expenses/forms.py
T
2026-08-20 19:43:56 -04:00

195 lines
6.7 KiB
Python

from django import forms
from django.contrib.auth.models import User, Group
from .models import Expense, Project, Category, SystemSetting, UserProfile, Document, CurrencyEnum, ExpenseTypeEnum, Vendor, VehicleOwnershipEnum
from .chile_regions import REGION_CHOICES, COMMUNE_CHOICES
class MultipleFileInput(forms.FileInput):
allow_multiple_selected = True
class ExpenseForm(forms.ModelForm):
date = forms.DateField(
widget=forms.DateInput(attrs={'type': 'date'}),
label='Fecha del Gasto'
)
amount_clp = forms.DecimalField(
label='Monto Neto (CLP)',
required=True,
widget=forms.NumberInput(attrs={'placeholder': 'Ej: 1450000'})
)
receipt = forms.FileField(
label='Adjuntar Evidencia(s) (Boleta / Factura)',
required=False,
widget=MultipleFileInput(attrs={'multiple': True, 'accept': 'image/*,.pdf'})
)
region = forms.ChoiceField(
choices=[('', '--- Seleccione Región ---')] + REGION_CHOICES,
label='Región Operativa',
required=False
)
comuna = forms.ChoiceField(
choices=[('', '--- Seleccione Comuna ---')] + COMMUNE_CHOICES,
label='Comuna',
required=False
)
vehicle_ownership = forms.ChoiceField(
choices=[('', '--- Seleccione Modalidad ---')] + VehicleOwnershipEnum.choices,
label='Modalidad / Vehículo',
required=False
)
tax_amount_clp = forms.DecimalField(
label='Monto Impuesto (CLP)',
required=False,
widget=forms.NumberInput(attrs={'readonly': 'readonly'})
)
total_amount_clp = forms.DecimalField(
label='Monto Total (CLP)',
required=False,
widget=forms.NumberInput(attrs={'readonly': 'readonly'})
)
class Meta:
model = Expense
fields = [
'project', 'category', 'amount_clp', 'tax_type', 'tax_amount_clp', 'total_amount_clp', 'currency', 'responsible_person', 'date',
'description', 'vendor', 'region', 'comuna', 'vehicle_ownership'
]
widgets = {
'description': forms.Textarea(attrs={'rows': 3, 'placeholder': 'Ej: Carga combustible Copec / Pasajes bus terreno'}),
}
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['code', 'name', 'parent', 'category', 'status', 'type', 'description', 'manager', 'assigned_budget_clp']
widgets = {
'description': forms.Textarea(attrs={'rows': 3}),
}
class CategoryForm(forms.ModelForm):
class Meta:
model = Category
fields = ['code', 'name', 'parent', 'description']
widgets = {
'description': forms.Textarea(attrs={'rows': 3}),
}
class VendorForm(forms.ModelForm):
class Meta:
model = Vendor
fields = ['rut', 'name', 'business_line', 'bank', 'account_type', 'account_number', 'email', 'payment_terms']
class SystemSettingForm(forms.ModelForm):
class Meta:
model = SystemSetting
fields = ['global_budget', 'usd_exchange_rate']
class ResponsableForm(forms.Form):
username = forms.CharField(max_length=150, label="Nombre de Usuario")
password = forms.CharField(widget=forms.PasswordInput(), label="Contraseña", required=False)
email = forms.EmailField(label="Correo Electrónico", required=False)
role = forms.ModelChoiceField(queryset=Group.objects.all(), label="Rol / Grupo")
# Perfil Fields
rut = forms.CharField(max_length=20, label="RUT", required=False)
job_title = forms.CharField(max_length=150, label="Cargo", required=False)
description = forms.CharField(widget=forms.Textarea(attrs={'rows': 3}), label="Descripción / Bio", required=False)
specialties = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
label="Especialidades Técnicas (Categorías)"
)
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop('instance', None)
super().__init__(*args, **kwargs)
if self.instance:
self.fields['username'].initial = self.instance.username
self.fields['email'].initial = self.instance.email
# Set role
groups = self.instance.groups.all()
if groups.exists():
self.fields['role'].initial = groups.first()
# Set profile info
try:
self.fields['description'].initial = self.instance.profile.description
self.fields['rut'].initial = self.instance.profile.rut
self.fields['job_title'].initial = self.instance.profile.job_title
self.fields['specialties'].initial = self.instance.profile.specialties.all()
except Exception:
pass
# Password is optional for edit
self.fields['password'].required = False
self.fields['password'].help_text = "Dejar en blanco si no desea cambiarla."
def clean_username(self):
username = self.cleaned_data.get('username')
qs = User.objects.filter(username=username)
if self.instance:
qs = qs.exclude(pk=self.instance.pk)
if qs.exists():
raise forms.ValidationError("Este nombre de usuario ya está registrado.")
return username
def save(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
email = self.cleaned_data.get('email')
role = self.cleaned_data.get('role')
description = self.cleaned_data.get('description')
rut = self.cleaned_data.get('rut')
job_title = self.cleaned_data.get('job_title')
if self.instance:
user = self.instance
user.username = username
user.email = email
if password:
user.set_password(password)
else:
user = User.objects.create_user(username=username, email=email, password=password)
if role.name == 'Administrador' or role.name == 'Administrador Finanzas':
user.is_staff = True
user.is_superuser = True
else:
user.is_staff = False
user.is_superuser = False
user.save()
user.groups.clear()
user.groups.add(role)
profile, _ = UserProfile.objects.get_or_create(user=user)
profile.description = description
profile.rut = rut
profile.job_title = job_title
profile.save()
# Save specialties
specialties = self.cleaned_data.get('specialties')
if specialties is not None:
profile.specialties.set(specialties)
return user
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['file', 'title']