refactor: migrar a supabase, aplicar cia y poo a gastos
This commit is contained in:
+76
-69
@@ -1,6 +1,11 @@
|
||||
import csv
|
||||
import io
|
||||
from decimal import Decimal
|
||||
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.urls import reverse_lazy
|
||||
from .mixins import RoleRequiredMixin
|
||||
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.cache import cache_page
|
||||
@@ -96,81 +101,83 @@ def dashboard(request):
|
||||
return render(request, 'expenses/dashboard.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def expense_list(request):
|
||||
expenses = Expense.objects.select_related('project', 'category', 'user').order_by('-date')
|
||||
class ExpenseListView(LoginRequiredMixin, ListView):
|
||||
model = Expense
|
||||
template_name = 'expenses/expense_list.html'
|
||||
context_object_name = 'expenses'
|
||||
|
||||
# Filtros
|
||||
project_id = request.GET.get('project')
|
||||
category_id = request.GET.get('category')
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset().select_related('project', 'category', 'user').order_by('-date')
|
||||
project_id = self.request.GET.get('project')
|
||||
category_id = self.request.GET.get('category')
|
||||
|
||||
if project_id:
|
||||
queryset = queryset.filter(project_id=project_id)
|
||||
if category_id:
|
||||
queryset = queryset.filter(category_id=category_id)
|
||||
return queryset
|
||||
|
||||
if project_id:
|
||||
expenses = expenses.filter(project_id=project_id)
|
||||
if category_id:
|
||||
expenses = expenses.filter(category_id=category_id)
|
||||
|
||||
context = {
|
||||
'expenses': expenses,
|
||||
'projects': Project.objects.all(),
|
||||
'categories': Category.objects.all(),
|
||||
'selected_project': project_id,
|
||||
'selected_category': category_id,
|
||||
}
|
||||
return render(request, 'expenses/expense_list.html', context)
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['projects'] = Project.objects.all()
|
||||
context['categories'] = Category.objects.all()
|
||||
context['selected_project'] = self.request.GET.get('project')
|
||||
context['selected_category'] = self.request.GET.get('category')
|
||||
return context
|
||||
|
||||
|
||||
@login_required
|
||||
@transaction.atomic # Integridad de datos
|
||||
def expense_create(request):
|
||||
# Only allow creation if user is admin or allowed to
|
||||
if request.method == 'POST':
|
||||
form = ExpenseForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
expense = form.save(commit=False)
|
||||
expense.user = request.user
|
||||
# Auto convert to USD if CLP
|
||||
setting, _ = SystemSetting.objects.get_or_create(id=1)
|
||||
if expense.currency == CurrencyEnum.CLP:
|
||||
expense.amount_usd = expense.amount_clp / setting.usd_exchange_rate
|
||||
else:
|
||||
expense.amount_usd = expense.amount_clp
|
||||
expense.amount_clp = expense.amount_usd * setting.usd_exchange_rate
|
||||
from django.utils.decorators import method_decorator
|
||||
|
||||
@method_decorator(transaction.atomic, name='dispatch')
|
||||
class ExpenseCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Expense
|
||||
form_class = ExpenseForm
|
||||
template_name = 'expenses/expense_form.html'
|
||||
success_url = reverse_lazy('expense_list')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['regions_communes_json'] = json.dumps(REGIONS_COMMUNES)
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
expense = form.save(commit=False)
|
||||
expense.user = self.request.user
|
||||
|
||||
setting, _ = SystemSetting.objects.get_or_create(id=1)
|
||||
if expense.currency == CurrencyEnum.CLP:
|
||||
expense.amount_usd = expense.amount_clp / setting.usd_exchange_rate
|
||||
else:
|
||||
expense.amount_usd = expense.amount_clp
|
||||
expense.amount_clp = expense.amount_usd * setting.usd_exchange_rate
|
||||
|
||||
expense.save()
|
||||
|
||||
receipts = request.FILES.getlist('receipt')
|
||||
if receipts:
|
||||
from .models import Document
|
||||
import os
|
||||
cat_name = expense.category.name if expense.category else 'Evidencia'
|
||||
proj_code = expense.project.code if expense.project else 'PROY'
|
||||
for idx, f in enumerate(receipts, start=1):
|
||||
ext = os.path.splitext(f.name)[1].lower()
|
||||
semantic_title = f"{proj_code} · {cat_name} · Doc {idx:02d}{ext}"
|
||||
Document.objects.create(
|
||||
expense=expense,
|
||||
file=f,
|
||||
title=semantic_title,
|
||||
uploaded_by=request.user
|
||||
)
|
||||
expense.save()
|
||||
|
||||
receipts = self.request.FILES.getlist('receipt')
|
||||
if receipts:
|
||||
from .models import Document
|
||||
import os
|
||||
cat_name = expense.category.name if expense.category else 'Evidencia'
|
||||
proj_code = expense.project.code if expense.project else 'PROY'
|
||||
for idx, f in enumerate(receipts, start=1):
|
||||
ext = os.path.splitext(f.name)[1].lower()
|
||||
semantic_title = f"{proj_code} · {cat_name} · Doc {idx:02d}{ext}"
|
||||
Document.objects.create(
|
||||
expense=expense,
|
||||
file=f,
|
||||
title=semantic_title,
|
||||
uploaded_by=self.request.user
|
||||
)
|
||||
|
||||
AuditLog.objects.create(
|
||||
user=request.user,
|
||||
action="Gasto Creado",
|
||||
entity_name="Expense",
|
||||
entity_id=expense.expense_code,
|
||||
description=f"Se creó el gasto por {expense.amount_clp} CLP"
|
||||
)
|
||||
messages.success(request, 'Gasto registrado exitosamente.')
|
||||
return redirect('expense_list')
|
||||
else:
|
||||
form = ExpenseForm()
|
||||
|
||||
context = {
|
||||
'form': form,
|
||||
'regions_communes_json': json.dumps(REGIONS_COMMUNES)
|
||||
}
|
||||
return render(request, 'expenses/expense_form.html', context)
|
||||
AuditLog.objects.create(
|
||||
user=self.request.user,
|
||||
action="Gasto Creado",
|
||||
entity_name="Expense",
|
||||
entity_id=expense.expense_code,
|
||||
description=f"Se creó el gasto por {expense.amount_clp} CLP"
|
||||
)
|
||||
messages.success(self.request, 'Gasto registrado exitosamente.')
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
Reference in New Issue
Block a user