Merge pull request 'Adicionar resumen de compra en el formulario de compra' (#14) from pagar_una_compra_en_efectivo_#13 into main

Reviewed-on: #14
This commit is contained in:
mono 2024-08-03 09:45:26 -05:00
commit 6f4ac50a58
8 changed files with 110 additions and 14 deletions

View File

@ -1,8 +1,11 @@
from django import forms from django import forms
from django.forms.models import inlineformset_factory
from django.forms.widgets import DateInput, DateTimeInput from django.forms.widgets import DateInput, DateTimeInput
from .models import Sale, SaleLine, ReconciliationJar from .models import Sale, SaleLine, ReconciliationJar, PaymentMethods
readonly_number_widget = forms.NumberInput(attrs={'readonly': 'readonly'})
class ImportProductsForm(forms.Form): class ImportProductsForm(forms.Form):
csv_file = forms.FileField() csv_file = forms.FileField()
@ -33,7 +36,24 @@ class PurchaseLineForm(forms.ModelForm):
] ]
LineaFormSet = forms.models.inlineformset_factory( class PurchaseSummaryForm(forms.Form):
quantity_lines = forms.IntegerField(
widget=readonly_number_widget
)
quantity_products = forms.IntegerField(
widget=readonly_number_widget
)
ammount = forms.DecimalField(
max_digits=10,
decimal_places=2,
widget=readonly_number_widget
)
payment_method = forms.ChoiceField(
choices=PaymentMethods.choices,
widget=forms.Select(attrs={'disabled': 'disabled'})
)
LineaFormSet = inlineformset_factory(
Sale, Sale,
SaleLine, SaleLine,
extra=1, extra=1,

View File

@ -54,7 +54,7 @@ class Product(models.Model):
return self.name return self.name
class PyamentMethods(models.TextChoices): class PaymentMethods(models.TextChoices):
CASH = 'CASH', _('Cash') CASH = 'CASH', _('Cash')
CONFIAR = 'CONFIAR', _('Confiar') CONFIAR = 'CONFIAR', _('Confiar')
BANCOLOMBIA = 'BANCOLOMBIA', _('Bancolombia') BANCOLOMBIA = 'BANCOLOMBIA', _('Bancolombia')
@ -112,8 +112,8 @@ class Payment(models.Model):
date_time = models.DateTimeField() date_time = models.DateTimeField()
type_payment = models.CharField( type_payment = models.CharField(
max_length=30, max_length=30,
choices=PyamentMethods.choices, choices=PaymentMethods.choices,
default=PyamentMethods.CASH default=PaymentMethods.CASH
) )
amount = models.DecimalField(max_digits=9, decimal_places=2) amount = models.DecimalField(max_digits=9, decimal_places=2)
reconciliation_jar = models.ForeignKey( reconciliation_jar = models.ForeignKey(
@ -129,7 +129,7 @@ class Payment(models.Model):
def get_reconciliation_jar_summary(cls): def get_reconciliation_jar_summary(cls):
return ReconciliationJarSummary( return ReconciliationJarSummary(
cls.objects.filter( cls.objects.filter(
type_payment=PyamentMethods.CASH, type_payment=PaymentMethods.CASH,
reconciliation_jar=None reconciliation_jar=None
) )
) )

View File

@ -0,0 +1,37 @@
const complete_form = document.getElementById('complete_form_purchase')
const quantityLines = document.getElementById('id_quantity_lines');
const quantityProducts = document.getElementById('id_quantity_products');
const ammountInput = document.getElementById('id_ammount');
const idPrefix = 'id_saleline_set-';
const quantitySuffix = '-quantity';
const priceSuffix = '-unit_price';
const quantityRegexSelector = `[id^="${idPrefix}"][id$="${quantitySuffix}"]`;
const priceRegexSelector = `[id^="${idPrefix}"][id$="${priceSuffix}"]`;
complete_form.addEventListener('change', function(event){
if (event.target.matches(quantityRegexSelector)) {
calculateSummary();
}
if (event.target.matches(priceRegexSelector)) {
calculateSummary();
}
});
function calculateSummary() {
let quantity = 0;
let ammount = 0;
const quantityInputs = document.querySelectorAll(quantityRegexSelector);
const ids = Array.prototype.map.call(quantityInputs, function(input) {
return input.id.match(/\d+/)[0];
});
ids.forEach(function(id) {
let lineQuantity = document.getElementById(`${idPrefix}${id}${quantitySuffix}`)
let linePrice = document.getElementById(`${idPrefix}${id}${priceSuffix}`)
quantity += parseFloat(lineQuantity.value);
ammount += parseFloat(linePrice.value) * parseFloat(lineQuantity.value);
});
quantityProducts.value = quantity;
quantityLines.value = quantityInputs.length;
ammountInput.value = ammount;
}

View File

@ -1,8 +1,8 @@
<!doctype html> <!doctype html>
{% load static %} {% load static %}
<form method="POST"> <form id="complete_form_purchase" method="POST">
{% csrf_token %} {% csrf_token %}
{{ sale_form}} {{ sale_form }}
{{ linea_formset.management_form }} {{ linea_formset.management_form }}
<div id="formset-container"> <div id="formset-container">
{% for form in linea_formset %} {% for form in linea_formset %}
@ -14,6 +14,8 @@
{% endfor %} {% endfor %}
</div> </div>
<button id="add_line" type="button" onclick="add_line">Añadir Linea</button> <button id="add_line" type="button" onclick="add_line">Añadir Linea</button>
{{ summary_form }}
<br/><button name="form" type="submit" >Comprar</button> <br/><button name="form" type="submit" >Comprar</button>
<script src="{% static 'js/add_line.js' %}"></script> <script src="{% static 'js/add_line.js' %}"></script>
<script src="{% static 'js/sale_summary.js' %}"></script>
</form> </form>

View File

@ -1,6 +1,6 @@
from django.test import TestCase from django.test import TestCase
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from .models import Payment, ReconciliationJar from ..models import Payment, ReconciliationJar
class TestBilling(TestCase): class TestBilling(TestCase):

View File

@ -0,0 +1,36 @@
from django.test import Client, TestCase
from ..models import Payment, Sale
class TestPurchaseWithPayment(TestCase):
def setUp(self):
self.client = Client()
# def test_generate_payment_when_it_has_payment(self):
# quantity = 2
# unit_price = 2500
# total = 5000
# response = self.client.post(
# '/don_confiao/comprar',
# {
# "customer": "Noelba Lopez",
# "date": "2024-07-27",
# "phone": "3010101000",
# "description": "Venta de contado",
# "saleline_set-TOTAL_FORMS": "1",
# "saleline_set-INITIAL_FORMS": "0",
# "saleline_set-MIN_NUM_FORMS": "0",
# "saleline_set-MAX_NUM_FORMS": "1000",
# "saleline_set-0-product": "Papayita",
# "saleline_set-0-quantity": str(quantity),
# "saleline_set-0-unit_price": str(unit_price),
# "saleline_set-0-description": "Linea de Venta",
# "saleline_set-0-sale": "",
# "saleline_set-0-id": "",
# }
# )
# purchases = Sale.objects.all()
# self.assertEqual(1, len(purchases))
# payments = Payment.objects.all()
# self.assertEqual(1, len(payments))
# self.assertEqual(total, payments[0].ammount)

View File

@ -1,9 +1,7 @@
from django.test import Client, TestCase from django.test import Client, TestCase
from django.contrib.auth.models import AnonymousUser, User from django.contrib.auth.models import AnonymousUser, User
#from django.conf import settings
#from .views import import_products, products from ..models import Payment
from .models import Payment
class TestReconciliationJarClient(TestCase): class TestReconciliationJarClient(TestCase):

View File

@ -5,7 +5,7 @@ from django.core.exceptions import ValidationError
from django.views.generic import ListView from django.views.generic import ListView
from .models import Sale, Product, ProductCategory, Payment from .models import Sale, Product, ProductCategory, Payment
from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm, PurchaseSummaryForm
import csv import csv
import io import io
@ -19,6 +19,7 @@ def buy(request):
if request.method == "POST": if request.method == "POST":
sale_form = PurchaseForm(request.POST) sale_form = PurchaseForm(request.POST)
sale_linea_form = LineaFormSet(request.POST) sale_linea_form = LineaFormSet(request.POST)
sale_summary_form = PurchaseSummaryForm(request.POST)
if sale_form.is_valid() and sale_linea_form.is_valid(): if sale_form.is_valid() and sale_linea_form.is_valid():
sale = sale_form.save() sale = sale_form.save()
lines = sale_linea_form.save(commit=False) lines = sale_linea_form.save(commit=False)
@ -29,12 +30,14 @@ def buy(request):
else: else:
sale_form = PurchaseForm() sale_form = PurchaseForm()
sale_linea_form = LineaFormSet() sale_linea_form = LineaFormSet()
sale_summary_form = PurchaseSummaryForm()
return render( return render(
request, request,
'don_confiao/purchase.html', 'don_confiao/purchase.html',
{ {
'sale_form': sale_form, 'sale_form': sale_form,
'linea_formset': sale_linea_form 'linea_formset': sale_linea_form,
'summary_form': sale_summary_form,
} }
) )