Merge pull request 'Registrar pagos completos con compras en efectivo #13' (#20) from make_payment_with_efective_purchase_#13 into main
Reviewed-on: OneTeam/don_confiao#20
This commit is contained in:
		@@ -50,12 +50,11 @@ class PurchaseSummaryForm(forms.Form):
 | 
				
			|||||||
        widget=readonly_number_widget
 | 
					        widget=readonly_number_widget
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    payment_method = forms.ChoiceField(
 | 
					    payment_method = forms.ChoiceField(
 | 
				
			||||||
        choices=PaymentMethods.choices,
 | 
					        choices=[(PaymentMethods.CASH, PaymentMethods.CASH)],
 | 
				
			||||||
        widget=forms.Select(attrs={'disabled': 'disabled'})
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LineaFormSet = inlineformset_factory(
 | 
					SaleLineFormSet = inlineformset_factory(
 | 
				
			||||||
    Sale,
 | 
					    Sale,
 | 
				
			||||||
    SaleLine,
 | 
					    SaleLine,
 | 
				
			||||||
    extra=1,
 | 
					    extra=1,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										22
									
								
								tienda_ilusion/don_confiao/migrations/0030_paymentsale.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tienda_ilusion/don_confiao/migrations/0030_paymentsale.py
									
									
									
									
									
										Normal file
									
								
							@@ -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')),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _
 | 
				
			|||||||
from django.core.exceptions import ValidationError
 | 
					from django.core.exceptions import ValidationError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from decimal import Decimal
 | 
					from decimal import Decimal
 | 
				
			||||||
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Customer(models.Model):
 | 
					class Customer(models.Model):
 | 
				
			||||||
@@ -12,7 +13,6 @@ class Customer(models.Model):
 | 
				
			|||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.name
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class MeasuringUnits(models.TextChoices):
 | 
					class MeasuringUnits(models.TextChoices):
 | 
				
			||||||
    UNIT = 'UNIT', _('Unit')
 | 
					    UNIT = 'UNIT', _('Unit')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,3 +145,23 @@ class Payment(models.Model):
 | 
				
			|||||||
                reconciliation_jar=None
 | 
					                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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,37 +1,51 @@
 | 
				
			|||||||
from django.test import Client, TestCase
 | 
					from django.test import Client, TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..models import Payment, Sale
 | 
					from ..models import Payment, Sale, Product, Customer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestPurchaseWithPayment(TestCase):
 | 
					class TestPurchaseWithPayment(TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.client = Client()
 | 
					        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):
 | 
					    def test_generate_payment_when_it_has_payment(self):
 | 
				
			||||||
    #     quantity = 2
 | 
					        quantity = 2
 | 
				
			||||||
    #     unit_price = 2500
 | 
					        unit_price = 2500
 | 
				
			||||||
    #     total = 5000
 | 
					        total = 5000
 | 
				
			||||||
    #     response = self.client.post(
 | 
					        self.client.post(
 | 
				
			||||||
    #         '/don_confiao/comprar',
 | 
					            '/don_confiao/comprar',
 | 
				
			||||||
    #         {
 | 
					            {
 | 
				
			||||||
    #             "customer": "Noelba Lopez",
 | 
					                "customer": str(self.customer.id),
 | 
				
			||||||
    #             "date": "2024-07-27",
 | 
					                "date": "2024-07-27",
 | 
				
			||||||
    #             "phone": "3010101000",
 | 
					                "phone": "3010101000",
 | 
				
			||||||
    #             "description": "Venta de contado",
 | 
					                "description": "Venta de contado",
 | 
				
			||||||
    #             "saleline_set-TOTAL_FORMS": "1",
 | 
					                "saleline_set-TOTAL_FORMS": "1",
 | 
				
			||||||
    #             "saleline_set-INITIAL_FORMS": "0",
 | 
					                "saleline_set-INITIAL_FORMS": "0",
 | 
				
			||||||
    #             "saleline_set-MIN_NUM_FORMS": "0",
 | 
					                "saleline_set-MIN_NUM_FORMS": "0",
 | 
				
			||||||
    #             "saleline_set-MAX_NUM_FORMS": "1000",
 | 
					                "saleline_set-MAX_NUM_FORMS": "1000",
 | 
				
			||||||
    #             "saleline_set-0-product": "Papayita",
 | 
					                "saleline_set-0-product": str(self.product.id),
 | 
				
			||||||
    #             "saleline_set-0-quantity": str(quantity),
 | 
					                "saleline_set-0-quantity": str(quantity),
 | 
				
			||||||
    #             "saleline_set-0-unit_price": str(unit_price),
 | 
					                "saleline_set-0-unit_price": str(unit_price),
 | 
				
			||||||
    #             "saleline_set-0-description": "Linea de Venta",
 | 
					                "saleline_set-0-description": "Linea de Venta",
 | 
				
			||||||
    #             "saleline_set-0-sale": "",
 | 
					                "saleline_set-0-sale": "",
 | 
				
			||||||
    #             "saleline_set-0-id": "",
 | 
					                "saleline_set-0-id": "",
 | 
				
			||||||
    #         }
 | 
					                "quantity_lines": "1",
 | 
				
			||||||
    #     )
 | 
					                "quantity_products": str(quantity),
 | 
				
			||||||
    #     purchases = Sale.objects.all()
 | 
					                "ammount": str(quantity * unit_price),
 | 
				
			||||||
    #     self.assertEqual(1, len(purchases))
 | 
					                "payment_method": "CASH",
 | 
				
			||||||
    #     payments = Payment.objects.all()
 | 
					            }
 | 
				
			||||||
    #     self.assertEqual(1, len(payments))
 | 
					        )
 | 
				
			||||||
    #     self.assertEqual(total, payments[0].ammount)
 | 
					
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,10 @@
 | 
				
			|||||||
from django.shortcuts import render
 | 
					from django.shortcuts import render
 | 
				
			||||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
 | 
					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.views.generic import ListView
 | 
				
			||||||
 | 
					from django.db import transaction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Sale, Product, ProductCategory, Payment
 | 
					from .models import Sale, Product, ProductCategory, Payment, PaymentMethods
 | 
				
			||||||
from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm, PurchaseSummaryForm
 | 
					from .forms import ImportProductsForm, PurchaseForm, SaleLineFormSet, ReconciliationJarForm, PurchaseSummaryForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import csv
 | 
					import csv
 | 
				
			||||||
import io
 | 
					import io
 | 
				
			||||||
@@ -14,29 +13,39 @@ import io
 | 
				
			|||||||
def index(request):
 | 
					def index(request):
 | 
				
			||||||
    return render(request, 'don_confiao/index.html')
 | 
					    return render(request, 'don_confiao/index.html')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
def buy(request):
 | 
					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)
 | 
					        line_formset = SaleLineFormSet(request.POST)
 | 
				
			||||||
        sale_summary_form = PurchaseSummaryForm(request.POST)
 | 
					        sale_summary_form = PurchaseSummaryForm(request.POST)
 | 
				
			||||||
        if sale_form.is_valid() and sale_linea_form.is_valid():
 | 
					        forms_are_valid = all([
 | 
				
			||||||
            sale = sale_form.save()
 | 
					            sale_form.is_valid(),
 | 
				
			||||||
            lines = sale_linea_form.save(commit=False)
 | 
					            line_formset.is_valid(),
 | 
				
			||||||
            for line in lines:
 | 
					            sale_summary_form.is_valid()
 | 
				
			||||||
                line.sale = sale
 | 
					        ])
 | 
				
			||||||
                line.save()
 | 
					        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")
 | 
					            return HttpResponseRedirect("compras")
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        sale_form = PurchaseForm()
 | 
					        sale_form = PurchaseForm()
 | 
				
			||||||
        sale_linea_form = LineaFormSet()
 | 
					        line_formset = SaleLineFormSet()
 | 
				
			||||||
        sale_summary_form = PurchaseSummaryForm()
 | 
					        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': line_formset,
 | 
				
			||||||
            'summary_form': sale_summary_form,
 | 
					            'summary_form': sale_summary_form,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user