Feat: dashboard con gráficos, estructura CBS/Portafolios, semáforo de proyectos y cartera de especialistas
This commit is contained in:
+42
-3
@@ -1,6 +1,6 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User, Group
|
||||
from .models import Expense, Project, Category, SystemSetting, UserProfile, Document, CurrencyEnum, ExpenseTypeEnum
|
||||
from .models import Expense, Project, Category, SystemSetting, UserProfile, Document, CurrencyEnum, ExpenseTypeEnum, Vendor
|
||||
|
||||
|
||||
class ExpenseForm(forms.ModelForm):
|
||||
@@ -21,10 +21,22 @@ class ExpenseForm(forms.ModelForm):
|
||||
widget=forms.FileInput(attrs={'accept': 'image/*,.pdf'})
|
||||
)
|
||||
|
||||
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', 'currency', 'date',
|
||||
'project', 'category', 'amount_clp', 'tax_type', 'tax_amount_clp', 'total_amount_clp', 'currency', 'date',
|
||||
'description', 'vendor', 'region', 'comuna', 'vehicle_ownership'
|
||||
]
|
||||
widgets = {
|
||||
@@ -35,12 +47,27 @@ class ExpenseForm(forms.ModelForm):
|
||||
class ProjectForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = ['code', 'name', 'type', 'description', 'manager', 'assigned_budget_clp']
|
||||
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
|
||||
@@ -57,6 +84,12 @@ class ResponsableForm(forms.Form):
|
||||
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)
|
||||
@@ -73,6 +106,7 @@ class ResponsableForm(forms.Form):
|
||||
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
|
||||
@@ -124,6 +158,11 @@ class ResponsableForm(forms.Form):
|
||||
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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user