diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py index 0e877ea..241dac3 100644 --- a/tienda_ilusion/don_confiao/forms.py +++ b/tienda_ilusion/don_confiao/forms.py @@ -50,12 +50,11 @@ class PurchaseSummaryForm(forms.Form): widget=readonly_number_widget ) payment_method = forms.ChoiceField( - choices=PaymentMethods.choices, - widget=forms.Select(attrs={'disabled': 'disabled'}) + choices=[(PaymentMethods.CASH, PaymentMethods.CASH)], ) -LineaFormSet = inlineformset_factory( +SaleLineFormSet = inlineformset_factory( Sale, SaleLine, extra=1, diff --git a/tienda_ilusion/don_confiao/migrations/0029_alter_customer_name.py b/tienda_ilusion/don_confiao/migrations/0029_alter_customer_name.py new file mode 100644 index 0000000..dcbceb0 --- /dev/null +++ b/tienda_ilusion/don_confiao/migrations/0029_alter_customer_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.6 on 2024-08-17 19:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('don_confiao', '0028_alter_customer_address'), + ] + + operations = [ + migrations.AlterField( + model_name='customer', + name='name', + field=models.CharField(default=None, max_length=100), + ), + ] diff --git a/tienda_ilusion/don_confiao/migrations/0030_paymentsale.py b/tienda_ilusion/don_confiao/migrations/0030_paymentsale.py new file mode 100644 index 0000000..77d4522 --- /dev/null +++ b/tienda_ilusion/don_confiao/migrations/0030_paymentsale.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.6 on 2024-08-17 21:00 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('don_confiao', '0029_alter_customer_name'), + ] + + operations = [ + migrations.CreateModel( + name='PaymentSale', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('payment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='don_confiao.payment')), + ('sale', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='don_confiao.sale')), + ], + ), + ] diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py index 62d6fd6..71772d1 100644 --- a/tienda_ilusion/don_confiao/models.py +++ b/tienda_ilusion/don_confiao/models.py @@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError from decimal import Decimal +from datetime import datetime class Customer(models.Model): @@ -12,7 +13,6 @@ class Customer(models.Model): def __str__(self): return self.name - class MeasuringUnits(models.TextChoices): UNIT = 'UNIT', _('Unit') @@ -119,7 +119,7 @@ class ReconciliationJar(models.Model): self.payment_set.add(payment) self.is_valid = True - + class Payment(models.Model): date_time = models.DateTimeField() type_payment = models.CharField( @@ -145,3 +145,23 @@ class Payment(models.Model): reconciliation_jar=None ) ) + + @classmethod + def total_payment_from_sale(cls, payment_method, sale): + payment = cls() + payment.date_time = datetime.today() + payment.type_payment = payment_method + payment.amount = sale.get_total() + payment.clean() + payment.save() + + payment_sale = PaymentSale() + payment_sale.payment = payment + payment_sale.sale = sale + payment_sale.clean() + payment_sale.save() + + +class PaymentSale(models.Model): + payment = models.ForeignKey(Payment, on_delete=models.CASCADE) + sale = models.ForeignKey(Sale, on_delete=models.CASCADE) diff --git a/tienda_ilusion/don_confiao/tests/test_purchase_with_payment.py b/tienda_ilusion/don_confiao/tests/test_purchase_with_payment.py index a27904c..962aaa2 100644 --- a/tienda_ilusion/don_confiao/tests/test_purchase_with_payment.py +++ b/tienda_ilusion/don_confiao/tests/test_purchase_with_payment.py @@ -1,37 +1,51 @@ from django.test import Client, TestCase -from ..models import Payment, Sale +from ..models import Payment, Sale, Product, Customer class TestPurchaseWithPayment(TestCase): def setUp(self): self.client = Client() + self.product = Product() + self.product.name = "Arroz" + self.product.price = 5000 + self.product.save() + customer = Customer() + customer.name = "Noelba Lopez" + customer.save() + self.customer = customer - # 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) + def test_generate_payment_when_it_has_payment(self): + quantity = 2 + unit_price = 2500 + total = 5000 + self.client.post( + '/don_confiao/comprar', + { + "customer": str(self.customer.id), + "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": str(self.product.id), + "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": "", + "quantity_lines": "1", + "quantity_products": str(quantity), + "ammount": str(quantity * unit_price), + "payment_method": "CASH", + } + ) + + purchases = Sale.objects.all() + self.assertEqual(1, len(purchases)) + payments = Payment.objects.all() + self.assertEqual(1, len(payments)) + self.assertEqual(total, payments[0].amount) + self.assertEqual('CASH', payments[0].type_payment) diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py index 563a6a6..63169c4 100644 --- a/tienda_ilusion/don_confiao/views.py +++ b/tienda_ilusion/don_confiao/views.py @@ -1,11 +1,10 @@ from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect, JsonResponse -from django.template import loader -from django.core.exceptions import ValidationError from django.views.generic import ListView +from django.db import transaction -from .models import Sale, Product, ProductCategory, Payment -from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm, PurchaseSummaryForm +from .models import Sale, Product, ProductCategory, Payment, PaymentMethods +from .forms import ImportProductsForm, PurchaseForm, SaleLineFormSet, ReconciliationJarForm, PurchaseSummaryForm import csv import io @@ -14,29 +13,39 @@ import io def index(request): return render(request, 'don_confiao/index.html') - def buy(request): if request.method == "POST": sale_form = PurchaseForm(request.POST) - sale_linea_form = LineaFormSet(request.POST) + line_formset = SaleLineFormSet(request.POST) sale_summary_form = PurchaseSummaryForm(request.POST) - if sale_form.is_valid() and sale_linea_form.is_valid(): - sale = sale_form.save() - lines = sale_linea_form.save(commit=False) - for line in lines: - line.sale = sale - line.save() + forms_are_valid = all([ + sale_form.is_valid(), + line_formset.is_valid(), + sale_summary_form.is_valid() + ]) + payment_method = request.POST.get('payment_method') + valid_payment_methods = [PaymentMethods.CASH] + valid_payment_method = payment_method in valid_payment_methods + if forms_are_valid: + with transaction.atomic(): + sale = sale_form.save() + line_formset.instance = sale + line_formset.save() + Payment.total_payment_from_sale( + payment_method, + sale + ) return HttpResponseRedirect("compras") else: sale_form = PurchaseForm() - sale_linea_form = LineaFormSet() + line_formset = SaleLineFormSet() sale_summary_form = PurchaseSummaryForm() return render( request, 'don_confiao/purchase.html', { 'sale_form': sale_form, - 'linea_formset': sale_linea_form, + 'linea_formset': line_formset, 'summary_form': sale_summary_form, } )