MVP 0.5 modificaciones finales
This commit is contained in:
+25
-4
@@ -131,8 +131,18 @@ def expense_create(request):
|
|||||||
receipts = request.FILES.getlist('receipt')
|
receipts = request.FILES.getlist('receipt')
|
||||||
if receipts:
|
if receipts:
|
||||||
from .models import Document
|
from .models import Document
|
||||||
for f in receipts:
|
import os
|
||||||
Document.objects.create(expense=expense, file=f, title=f.name, uploaded_by=request.user)
|
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
|
||||||
|
)
|
||||||
|
|
||||||
AuditLog.objects.create(
|
AuditLog.objects.create(
|
||||||
user=request.user,
|
user=request.user,
|
||||||
@@ -183,8 +193,19 @@ def expense_edit(request, pk):
|
|||||||
receipts = request.FILES.getlist('receipt')
|
receipts = request.FILES.getlist('receipt')
|
||||||
if receipts:
|
if receipts:
|
||||||
from .models import Document
|
from .models import Document
|
||||||
for f in receipts:
|
import os
|
||||||
Document.objects.create(expense=exp, file=f, title=f.name, uploaded_by=request.user)
|
cat_name = exp.category.name if exp.category else 'Evidencia'
|
||||||
|
proj_code = exp.project.code if exp.project else 'PROY'
|
||||||
|
existing_count = exp.documents.count()
|
||||||
|
for idx, f in enumerate(receipts, start=existing_count + 1):
|
||||||
|
ext = os.path.splitext(f.name)[1].lower()
|
||||||
|
semantic_title = f"{proj_code} · {cat_name} · Doc {idx:02d}{ext}"
|
||||||
|
Document.objects.create(
|
||||||
|
expense=exp,
|
||||||
|
file=f,
|
||||||
|
title=semantic_title,
|
||||||
|
uploaded_by=request.user
|
||||||
|
)
|
||||||
|
|
||||||
AuditLog.objects.create(
|
AuditLog.objects.create(
|
||||||
user=request.user,
|
user=request.user,
|
||||||
|
|||||||
@@ -99,15 +99,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="new-vendor-fields" style="display: none; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1.5rem; background: #f0fdf4; padding: 1.25rem; border-radius: 6px; border: 1px solid #bbf7d0; box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);">
|
<div id="new-vendor-fields" style="display: none; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1.5rem; background: #f0fdf4; padding: 1.25rem; border-radius: 6px; border: 1px solid #bbf7d0; box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05); align-items: end;">
|
||||||
<div class="form-group">
|
<div class="form-group" style="display:flex; flex-direction:column;">
|
||||||
<label for="id_new_vendor_rut" style="font-weight: 600; font-size: 0.85rem; color: #166534;">RUT del Nuevo Proveedor</label>
|
<label for="id_new_vendor_rut" style="font-weight: 600; font-size: 0.85rem; color: #166534; margin-bottom: 0.35rem;">RUT del Nuevo Proveedor</label>
|
||||||
{{ form.new_vendor_rut }}
|
{{ form.new_vendor_rut }}
|
||||||
|
<small style="color: #166534; opacity: 0.7; font-size: 0.7rem; margin-top: 0.25rem;">Ej: 12.345.678-9</small>
|
||||||
{% if form.new_vendor_rut.errors %}<div style="color: var(--efintel-danger); font-size: 0.75rem; margin-top: 4px;">{{ form.new_vendor_rut.errors }}</div>{% endif %}
|
{% if form.new_vendor_rut.errors %}<div style="color: var(--efintel-danger); font-size: 0.75rem; margin-top: 4px;">{{ form.new_vendor_rut.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group" style="display:flex; flex-direction:column;">
|
||||||
<label for="id_new_vendor_name" style="font-weight: 600; font-size: 0.85rem; color: #166534;">Nombre / Razón Social del Nuevo Proveedor</label>
|
<label for="id_new_vendor_name" style="font-weight: 600; font-size: 0.85rem; color: #166534; margin-bottom: 0.35rem;">Nombre / Razón Social</label>
|
||||||
{{ form.new_vendor_name }}
|
{{ form.new_vendor_name }}
|
||||||
|
<small style="color: #166534; opacity: 0.7; font-size: 0.7rem; margin-top: 0.25rem;">Nombre legal del proveedor</small>
|
||||||
{% if form.new_vendor_name.errors %}<div style="color: var(--efintel-danger); font-size: 0.75rem; margin-top: 4px;">{{ form.new_vendor_name.errors }}</div>{% endif %}
|
{% if form.new_vendor_name.errors %}<div style="color: var(--efintel-danger); font-size: 0.75rem; margin-top: 4px;">{{ form.new_vendor_name.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -682,6 +684,46 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RUT Auto-formatter (XX.XXX.XXX-X)
|
||||||
|
const rutInput = document.getElementById('id_new_vendor_rut');
|
||||||
|
if (rutInput) {
|
||||||
|
rutInput.addEventListener('input', () => {
|
||||||
|
let val = rutInput.value.replace(/[^0-9kK]/g, '').toUpperCase();
|
||||||
|
if (val.length === 0) { rutInput.value = ''; return; }
|
||||||
|
|
||||||
|
// Separate body and verifier digit
|
||||||
|
const dv = val.slice(-1);
|
||||||
|
let body = val.slice(0, -1);
|
||||||
|
|
||||||
|
// Add thousands separator to body
|
||||||
|
body = body.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||||
|
|
||||||
|
rutInput.value = body ? `${body}-${dv}` : dv;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Validate on blur: simple dv check using modulo 11
|
||||||
|
rutInput.addEventListener('blur', () => {
|
||||||
|
const raw = rutInput.value.replace(/\./g, '').replace(/-/g, '');
|
||||||
|
if (raw.length < 2) return;
|
||||||
|
const body = raw.slice(0, -1);
|
||||||
|
const dv = raw.slice(-1).toUpperCase();
|
||||||
|
let sum = 0, factor = 2;
|
||||||
|
for (let i = body.length - 1; i >= 0; i--) {
|
||||||
|
sum += parseInt(body[i]) * factor;
|
||||||
|
factor = factor === 7 ? 2 : factor + 1;
|
||||||
|
}
|
||||||
|
const remainder = 11 - (sum % 11);
|
||||||
|
const expectedDv = remainder === 11 ? '0' : remainder === 10 ? 'K' : String(remainder);
|
||||||
|
if (dv !== expectedDv) {
|
||||||
|
rutInput.style.border = '2px solid var(--efintel-danger)';
|
||||||
|
rutInput.title = `RUT inválido (dígito verificador esperado: ${expectedDv})`;
|
||||||
|
} else {
|
||||||
|
rutInput.style.border = '';
|
||||||
|
rutInput.title = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user