From ee38c29ce3050ad73fb1a6981d21d4d7ca35ccb1 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 11:43:16 -0500
Subject: [PATCH 01/16] feat: implement reconciliation jar summary.

---
 .../don_confiao/migrations/0012_payment.py    | 23 ++++++++
 .../0013_rename_mount_payment_amount.py       | 18 +++++++
 ...ciliationjar_payment_reconciliation_jar.py | 27 ++++++++++
 .../0015_alter_payment_reconciliation_jar.py  | 19 +++++++
 tienda_ilusion/don_confiao/models.py          | 52 +++++++++++++++++++
 tienda_ilusion/don_confiao/test_billing.py    | 38 ++++++++++++++
 6 files changed, 177 insertions(+)
 create mode 100644 tienda_ilusion/don_confiao/migrations/0012_payment.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0013_rename_mount_payment_amount.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0014_reconciliationjar_payment_reconciliation_jar.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0015_alter_payment_reconciliation_jar.py
 create mode 100644 tienda_ilusion/don_confiao/test_billing.py

diff --git a/tienda_ilusion/don_confiao/migrations/0012_payment.py b/tienda_ilusion/don_confiao/migrations/0012_payment.py
new file mode 100644
index 0000000..474ef16
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0012_payment.py
@@ -0,0 +1,23 @@
+# Generated by Django 5.0.6 on 2024-07-13 14:50
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0011_alter_product_name'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Payment',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date_time', models.DateTimeField()),
+                ('type_payment', models.CharField(choices=[('CASH', 'Cash'), ('CONFIAR', 'Confiar'), ('BANCOLOMBIA', 'Bancolombia')], default='CASH', max_length=30)),
+                ('mount', models.DecimalField(decimal_places=2, max_digits=9)),
+                ('description', models.CharField(blank=True, max_length=255, null=True)),
+            ],
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0013_rename_mount_payment_amount.py b/tienda_ilusion/don_confiao/migrations/0013_rename_mount_payment_amount.py
new file mode 100644
index 0000000..c55facb
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0013_rename_mount_payment_amount.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-13 15:56
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0012_payment'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='payment',
+            old_name='mount',
+            new_name='amount',
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0014_reconciliationjar_payment_reconciliation_jar.py b/tienda_ilusion/don_confiao/migrations/0014_reconciliationjar_payment_reconciliation_jar.py
new file mode 100644
index 0000000..9ea211f
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0014_reconciliationjar_payment_reconciliation_jar.py
@@ -0,0 +1,27 @@
+# Generated by Django 5.0.6 on 2024-07-13 16:35
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0013_rename_mount_payment_amount'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ReconciliationJar',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date_time', models.DateTimeField()),
+                ('description', models.CharField(blank=True, max_length=255, null=True)),
+            ],
+        ),
+        migrations.AddField(
+            model_name='payment',
+            name='reconciliation_jar',
+            field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.RESTRICT, to='don_confiao.reconciliationjar'),
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0015_alter_payment_reconciliation_jar.py b/tienda_ilusion/don_confiao/migrations/0015_alter_payment_reconciliation_jar.py
new file mode 100644
index 0000000..55d21cb
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0015_alter_payment_reconciliation_jar.py
@@ -0,0 +1,19 @@
+# Generated by Django 5.0.6 on 2024-07-13 16:36
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0014_reconciliationjar_payment_reconciliation_jar'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='payment',
+            name='reconciliation_jar',
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.RESTRICT, to='don_confiao.reconciliationjar'),
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 7d7ee0a..357e3e0 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -44,3 +44,55 @@ class Product(models.Model):
 
     def __str__(self):
         return self.name
+
+class PyamentMethods(models.TextChoices):
+    CASH = 'CASH', _('Cash')
+    CONFIAR = 'CONFIAR', _('Confiar')
+    BANCOLOMBIA = 'BANCOLOMBIA', _('Bancolombia')
+
+class ReconciliationJarSummary():
+    def __init__(self, payments):
+        self._validate_payments(payments)
+        self._payments = payments
+
+    def _validate_payments(self, payments):
+        pass
+
+    @property
+    def total(self):
+        return sum([p.amount for p in self.payments])
+
+    @property
+    def payments(self):
+        return self._payments
+
+
+class ReconciliationJar(models.Model):
+    date_time = models.DateTimeField()
+    description = models.CharField(max_length=255, null=True, blank=True)
+
+
+class Payment(models.Model):
+    date_time = models.DateTimeField()
+    type_payment = models.CharField(
+        max_length=30,
+        choices=PyamentMethods.choices,
+        default=PyamentMethods.CASH
+    )
+    amount = models.DecimalField(max_digits=9, decimal_places=2)
+    reconciliation_jar = models.ForeignKey(
+        ReconciliationJar,
+        null=True,
+        default=None,
+        on_delete=models.RESTRICT
+    )
+    description = models.CharField(max_length=255, null=True, blank=True)
+
+    @classmethod
+    def get_reconciliation_jar_summary(cls):
+        return ReconciliationJarSummary(
+            cls.objects.filter(
+                type_payment=PyamentMethods.CASH,
+                reconciliation_jar=None
+            )
+        )
diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
new file mode 100644
index 0000000..4e6f212
--- /dev/null
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -0,0 +1,38 @@
+from django.test import Client, TestCase
+from .models import Payment
+
+
+class TestBilling(TestCase):
+
+    def test_reconciliation_jar_summary(self):
+        cash_payment1 = Payment()
+        cash_payment1.date_time = '2024-07-07 12:00:00'
+        cash_payment1.type_payment = 'CASH'
+        cash_payment1.amount = 132000
+        cash_payment1.description = 'Saldo en compra'
+        cash_payment1.save()
+
+        cash_payment2 = Payment()
+        cash_payment2.date_time = '2024-07-07 13:05:00'
+        cash_payment2.type_payment = 'CASH'
+        cash_payment2.amount = 32000
+        cash_payment2.save()
+
+        confiar_payment = Payment()
+        confiar_payment.date_time = '2024-07-07 16:00:00'
+        confiar_payment.type_payment = 'CONFIAR'
+        confiar_payment.amount = 85000
+        confiar_payment.save()
+
+        bancolombia_payment = Payment()
+        bancolombia_payment.date_time = '2024-07-07 12:30:00'
+        bancolombia_payment.type_payment = 'BANCOLOMBIA'
+        bancolombia_payment.amount = 12000
+        bancolombia_payment.save()
+
+        jar_summary = Payment.get_reconciliation_jar_summary()
+        self.assertEqual(164000, jar_summary.total)
+        self.assertSetEqual(
+            {cash_payment1, cash_payment2},
+            set(jar_summary.payments)
+        )
-- 
2.45.2


From a8f8820a55a35dc9648e074afa00552f18be537f Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 17:13:17 -0500
Subject: [PATCH 02/16] feat: implementing form to reconciliation jar.

---
 tienda_ilusion/don_confiao/forms.py           | 18 ++++-
 ...nciliationjar_cash_discrepancy_and_more.py | 37 +++++++++
 .../0017_reconciliationjar_draft.py           | 18 +++++
 ...18_rename_draft_reconciliationjar_valid.py | 18 +++++
 ...rename_valid_reconciliationjar_is_valid.py | 18 +++++
 ...020_remove_reconciliationjar_cash_float.py | 17 ++++
 tienda_ilusion/don_confiao/models.py          | 22 ++++++
 .../don_confiao/reconciliate_jar.html         |  2 +
 tienda_ilusion/don_confiao/test_billing.py    | 77 ++++++++++++++++---
 .../test_reconciliation_jar_client.py         | 34 ++++++++
 tienda_ilusion/don_confiao/urls.py            |  3 +-
 tienda_ilusion/don_confiao/views.py           | 19 ++++-
 12 files changed, 266 insertions(+), 17 deletions(-)
 create mode 100644 tienda_ilusion/don_confiao/migrations/0016_reconciliationjar_cash_discrepancy_and_more.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0017_reconciliationjar_draft.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0018_rename_draft_reconciliationjar_valid.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0019_rename_valid_reconciliationjar_is_valid.py
 create mode 100644 tienda_ilusion/don_confiao/migrations/0020_remove_reconciliationjar_cash_float.py
 create mode 100644 tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
 create mode 100644 tienda_ilusion/don_confiao/test_reconciliation_jar_client.py

diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py
index 4db321a..5836c83 100644
--- a/tienda_ilusion/don_confiao/forms.py
+++ b/tienda_ilusion/don_confiao/forms.py
@@ -1,7 +1,7 @@
 from django import forms
-from django.forms.widgets import DateInput
+from django.forms.widgets import DateInput, DateTimeInput
 
-from .models import Sale, SaleLine
+from .models import Sale, SaleLine, ReconciliationJar
 
 
 class ImportProductsForm(forms.Form):
@@ -37,3 +37,17 @@ LineaFormSet = forms.models.inlineformset_factory(
     extra=2,
     fields='__all__'
 )
+
+class ReconciliationJarForm(forms.ModelForm):
+    class Meta:
+        model = ReconciliationJar
+        fields = [
+            'date_time',
+            'description',
+            'reconciler',
+            'cash_taken',
+            'cash_discrepancy',
+        ]
+        # widgets = {
+        #     'date_time': DateTimeInput(attrs={'type': 'datetime-local'})
+        # }
diff --git a/tienda_ilusion/don_confiao/migrations/0016_reconciliationjar_cash_discrepancy_and_more.py b/tienda_ilusion/don_confiao/migrations/0016_reconciliationjar_cash_discrepancy_and_more.py
new file mode 100644
index 0000000..8bb7bd2
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0016_reconciliationjar_cash_discrepancy_and_more.py
@@ -0,0 +1,37 @@
+# Generated by Django 5.0.6 on 2024-07-13 18:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0015_alter_payment_reconciliation_jar'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='reconciliationjar',
+            name='cash_discrepancy',
+            field=models.DecimalField(decimal_places=2, default=0, max_digits=9),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='reconciliationjar',
+            name='cash_float',
+            field=models.DecimalField(decimal_places=2, default=0, max_digits=9),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='reconciliationjar',
+            name='cash_taken',
+            field=models.DecimalField(decimal_places=2, default=0, max_digits=9),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='reconciliationjar',
+            name='reconciler',
+            field=models.CharField(default='Jorge', max_length=255),
+            preserve_default=False,
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0017_reconciliationjar_draft.py b/tienda_ilusion/don_confiao/migrations/0017_reconciliationjar_draft.py
new file mode 100644
index 0000000..13dc149
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0017_reconciliationjar_draft.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-13 18:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0016_reconciliationjar_cash_discrepancy_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='reconciliationjar',
+            name='draft',
+            field=models.BooleanField(default=False),
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0018_rename_draft_reconciliationjar_valid.py b/tienda_ilusion/don_confiao/migrations/0018_rename_draft_reconciliationjar_valid.py
new file mode 100644
index 0000000..7228161
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0018_rename_draft_reconciliationjar_valid.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-13 18:19
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0017_reconciliationjar_draft'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='reconciliationjar',
+            old_name='draft',
+            new_name='valid',
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0019_rename_valid_reconciliationjar_is_valid.py b/tienda_ilusion/don_confiao/migrations/0019_rename_valid_reconciliationjar_is_valid.py
new file mode 100644
index 0000000..a0d7a02
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0019_rename_valid_reconciliationjar_is_valid.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-13 19:56
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0018_rename_draft_reconciliationjar_valid'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='reconciliationjar',
+            old_name='valid',
+            new_name='is_valid',
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/migrations/0020_remove_reconciliationjar_cash_float.py b/tienda_ilusion/don_confiao/migrations/0020_remove_reconciliationjar_cash_float.py
new file mode 100644
index 0000000..dea5619
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0020_remove_reconciliationjar_cash_float.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.0.6 on 2024-07-13 20:13
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0019_rename_valid_reconciliationjar_is_valid'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='reconciliationjar',
+            name='cash_float',
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 357e3e0..579189f 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -1,5 +1,7 @@
 from django.db import models
 from django.utils.translation import gettext_lazy as _
+from django.core.exceptions import ValidationError
+
 
 class Sale(models.Model):
 
@@ -23,15 +25,18 @@ class SaleLine(models.Model):
     def __str__(self):
         return f"{self.sale} - {self.product}"
 
+
 class MeasuringUnits(models.TextChoices):
     UNIT = 'UNIT', _('Unit')
 
+
 class ProductCategory(models.Model):
     name = models.CharField(max_length=100, unique=True)
 
     def __str__(self):
         return self.name
 
+
 class Product(models.Model):
     name = models.CharField(max_length=100, unique=True)
     price = models.DecimalField(max_digits=9, decimal_places=2)
@@ -45,11 +50,13 @@ class Product(models.Model):
     def __str__(self):
         return self.name
 
+
 class PyamentMethods(models.TextChoices):
     CASH = 'CASH', _('Cash')
     CONFIAR = 'CONFIAR', _('Confiar')
     BANCOLOMBIA = 'BANCOLOMBIA', _('Bancolombia')
 
+
 class ReconciliationJarSummary():
     def __init__(self, payments):
         self._validate_payments(payments)
@@ -68,9 +75,24 @@ class ReconciliationJarSummary():
 
 
 class ReconciliationJar(models.Model):
+    is_valid = models.BooleanField(default=False)
     date_time = models.DateTimeField()
     description = models.CharField(max_length=255, null=True, blank=True)
+    reconciler = models.CharField(max_length=255, null=False, blank=False)
+    cash_taken = models.DecimalField(max_digits=9, decimal_places=2)
+    cash_discrepancy = models.DecimalField(max_digits=9, decimal_places=2)
 
+    def clean(self):
+        payments_amount = sum([p.amount for p in self.payment_set.all()])
+        reconciliation_ammount = sum([
+            self.cash_taken,
+            self.cash_discrepancy,
+        ])
+        if reconciliation_ammount != payments_amount:
+            raise ValidationError(
+                {"cash_take": _("The taken ammount has discrepancy.")}
+            )
+        self.is_valid = True
 
 class Payment(models.Model):
     date_time = models.DateTimeField()
diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
new file mode 100644
index 0000000..2da1ac5
--- /dev/null
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
@@ -0,0 +1,2 @@
+<!doctype html>
+{{ summary.total }}
diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index 4e6f212..49f8e97 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -1,22 +1,21 @@
 from django.test import Client, TestCase
-from .models import Payment
+from django.core.exceptions import ValidationError
+from .models import Payment, ReconciliationJar
 
 
 class TestBilling(TestCase):
 
     def test_reconciliation_jar_summary(self):
-        cash_payment1 = Payment()
-        cash_payment1.date_time = '2024-07-07 12:00:00'
-        cash_payment1.type_payment = 'CASH'
-        cash_payment1.amount = 132000
-        cash_payment1.description = 'Saldo en compra'
-        cash_payment1.save()
+        cash_payment1, cash_payment2 = self._create_two_cash_payments()
+        jar_summary = Payment.get_reconciliation_jar_summary()
+        self.assertEqual(164000, jar_summary.total)
+        self.assertSetEqual(
+            {cash_payment1, cash_payment2},
+            set(jar_summary.payments)
+        )
 
-        cash_payment2 = Payment()
-        cash_payment2.date_time = '2024-07-07 13:05:00'
-        cash_payment2.type_payment = 'CASH'
-        cash_payment2.amount = 32000
-        cash_payment2.save()
+    def test_reconciliation_jar_summary_use_only_cash(self):
+        cash_payment1, cash_payment2 = self._create_two_cash_payments()
 
         confiar_payment = Payment()
         confiar_payment.date_time = '2024-07-07 16:00:00'
@@ -36,3 +35,57 @@ class TestBilling(TestCase):
             {cash_payment1, cash_payment2},
             set(jar_summary.payments)
         )
+
+    def test_fail_validate_reconciliation_jar_with_discrepancy_values(self):
+        cash_payment1, cash_payment2 = self._create_two_cash_payments()
+
+        jar_summary = Payment.get_reconciliation_jar_summary()
+
+        reconciliation_jar = ReconciliationJar()
+        reconciliation_jar.date_time = '2024-07-13 13:02:00'
+        reconciliation_jar.description = "test reconcialiation jar"
+        reconciliation_jar.reconcilier = 'Jorge'
+        reconciliation_jar.cash_float = 0
+        reconciliation_jar.cash_taken = 0
+        reconciliation_jar.cash_discrepancy = 0
+        reconciliation_jar.save()
+
+        for payment in jar_summary.payments:
+            reconciliation_jar.payment_set.add(payment)
+        with self.assertRaises(ValidationError):
+            reconciliation_jar.clean()
+
+    def test_validate_reconciliation_jar_with_cash_float(self):
+        cash_payment1, cash_payment2 = self._create_two_cash_payments()
+        jar_summary = Payment.get_reconciliation_jar_summary()
+
+        reconciliation_jar = ReconciliationJar()
+        reconciliation_jar.date_time = '2024-07-13 13:02:00'
+        reconciliation_jar.description = "test reconcialiation jar"
+        reconciliation_jar.reconcilier = 'Jorge'
+        reconciliation_jar.cash_float = 10000
+        reconciliation_jar.cash_taken = jar_summary.total
+        reconciliation_jar.cash_discrepancy = 0
+        reconciliation_jar.save()
+
+        for payment in jar_summary.payments:
+            reconciliation_jar.payment_set.add(payment)
+        reconciliation_jar.clean()
+        reconciliation_jar.save()
+        self.assertTrue(reconciliation_jar.is_valid)
+
+    def _create_two_cash_payments(self):
+        cash_payment1 = Payment()
+        cash_payment1.date_time = '2024-07-07 12:00:00'
+        cash_payment1.type_payment = 'CASH'
+        cash_payment1.amount = 132000
+        cash_payment1.description = 'Saldo en compra'
+        cash_payment1.save()
+
+        cash_payment2 = Payment()
+        cash_payment2.date_time = '2024-07-07 13:05:00'
+        cash_payment2.type_payment = 'CASH'
+        cash_payment2.amount = 32000
+        cash_payment2.save()
+
+        return [cash_payment1, cash_payment2]
diff --git a/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
new file mode 100644
index 0000000..04ce878
--- /dev/null
+++ b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
@@ -0,0 +1,34 @@
+from django.test import Client, TestCase
+from django.contrib.auth.models import AnonymousUser, User
+#from django.conf import settings
+
+#from .views import import_products, products
+from .models import Payment
+
+
+class TestReconciliationJarClient(TestCase):
+    def setUp(self):
+        self.client = Client()
+
+    def test_get_summary_info_on_view(self):
+        self._generate_two_cash_payments()
+        response = self.client.get("/don_confiao/cuadrar_tarro")
+        self.assertEqual(response.status_code, 200)
+        # raise Exception(response.content.decode('utf-8'))
+        self.assertEqual(response.context["summary"].total, 160000)
+        self.assertIn('160000', response.content.decode('utf-8'))
+
+    def _generate_two_cash_payments(self):
+        cash_payment1 = Payment()
+        cash_payment1.date_time = '2024-07-07 12:00:00'
+        cash_payment1.type_payment = 'CASH'
+        cash_payment1.amount = 130000
+        cash_payment1.description = 'Saldo en compra'
+        cash_payment1.save()
+        # raise Exception (cash_payment1.id)
+
+        cash_payment2 = Payment()
+        cash_payment2.date_time = '2024-07-07 13:05:00'
+        cash_payment2.type_payment = 'CASH'
+        cash_payment2.amount = 30000
+        cash_payment2.save()
diff --git a/tienda_ilusion/don_confiao/urls.py b/tienda_ilusion/don_confiao/urls.py
index a9b716f..10f9518 100644
--- a/tienda_ilusion/don_confiao/urls.py
+++ b/tienda_ilusion/don_confiao/urls.py
@@ -8,5 +8,6 @@ urlpatterns = [
     path("comprar", views.buy, name="buy"),
     path("compras", views.purchases, name="purchases"),
     path("productos", views.products, name="products"),
-    path("importar_productos", views.import_products, name="import_products")
+    path("importar_productos", views.import_products, name="import_products"),
+    path("cuadrar_tarro", views.reconciliate_jar, name="reconciliate_jar"),
 ]
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 1904ab6..5d7e9e2 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -2,8 +2,8 @@ from django.shortcuts import render
 from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
 from django.template import loader
 
-from .models import Sale, Product, ProductCategory
-from .forms import ImportProductsForm, PurchaseForm, LineaFormSet
+from .models import Sale, Product, ProductCategory, Payment
+from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm
 
 import csv
 import io
@@ -69,6 +69,21 @@ def import_products(request):
         {'form': form}
     )
 
+
+def reconciliate_jar(request):
+    if request.method == 'POST':
+        return HttpResponseRedirect("cuadres")
+
+    form = ReconciliationJarForm()
+    summary = Payment.get_reconciliation_jar_summary()
+    # raise Exception(Payment.get_reconciliation_jar_summary().payments)
+    return render(
+        request,
+        "don_confiao/reconciliate_jar.html",
+        {'summary': summary, 'form': form}
+    )
+
+
 def _categories_from_csv_string(categories_string, separator="&"):
     categories = categories_string.split(separator)
     clean_categories = [c.strip() for c in categories]
-- 
2.45.2


From 3570af7b60daaa8e7c5c1f55f49ac0d398b66888 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 17:17:45 -0500
Subject: [PATCH 03/16] refactor: rename column.

---
 tienda_ilusion/don_confiao/forms.py            |  2 +-
 ...reconciler_reconciliationjar_reconcilier.py | 18 ++++++++++++++++++
 tienda_ilusion/don_confiao/models.py           |  2 +-
 3 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 tienda_ilusion/don_confiao/migrations/0021_rename_reconciler_reconciliationjar_reconcilier.py

diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py
index 5836c83..8fc05c9 100644
--- a/tienda_ilusion/don_confiao/forms.py
+++ b/tienda_ilusion/don_confiao/forms.py
@@ -44,7 +44,7 @@ class ReconciliationJarForm(forms.ModelForm):
         fields = [
             'date_time',
             'description',
-            'reconciler',
+            'reconcilier',
             'cash_taken',
             'cash_discrepancy',
         ]
diff --git a/tienda_ilusion/don_confiao/migrations/0021_rename_reconciler_reconciliationjar_reconcilier.py b/tienda_ilusion/don_confiao/migrations/0021_rename_reconciler_reconciliationjar_reconcilier.py
new file mode 100644
index 0000000..20e8f6e
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0021_rename_reconciler_reconciliationjar_reconcilier.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-13 22:16
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0020_remove_reconciliationjar_cash_float'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='reconciliationjar',
+            old_name='reconciler',
+            new_name='reconcilier',
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 579189f..78c4746 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -78,7 +78,7 @@ class ReconciliationJar(models.Model):
     is_valid = models.BooleanField(default=False)
     date_time = models.DateTimeField()
     description = models.CharField(max_length=255, null=True, blank=True)
-    reconciler = models.CharField(max_length=255, null=False, blank=False)
+    reconcilier = models.CharField(max_length=255, null=False, blank=False)
     cash_taken = models.DecimalField(max_digits=9, decimal_places=2)
     cash_discrepancy = models.DecimalField(max_digits=9, decimal_places=2)
 
-- 
2.45.2


From f9ee2ad9c29bdb696d169365c4bd59a3a1c3ff76 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 17:38:12 -0500
Subject: [PATCH 04/16] view: improve reconciliate_jar template.

---
 .../don_confiao/reconciliate_jar.html         | 28 ++++++++++++++++++-
 tienda_ilusion/don_confiao/views.py           |  1 -
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
index 2da1ac5..ff0d778 100644
--- a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
@@ -1,2 +1,28 @@
 <!doctype html>
-{{ summary.total }}
+{% if summary.total %}
+<div class="reconciliate_jar summary">
+    <h2>Pagos No reconciliados</h2>
+    <table>
+        <thead>
+            <th><td>Fecha</td>Monto</th>
+            {% for payment in summary.payments %}
+            <tr><td>payment.date_time</td><td>payment.amount</td></tr>
+            {% endfor %}
+        </thead>
+    {{ summary.total }}
+</div>
+<form method="POST">
+    <table style="border: solid 1px blue; margin: 10px">
+        {% csrf_token %}
+        {{ form.as_table }}
+    </table>
+    <br/><button name="form" type="submit" >Comprar</button>
+</form>
+{% else %}
+<div class="reconciliate_jar information noform">
+    <h2>No hay pagos registrados.</h2>
+</div>
+{% endif %}
+    
+
+
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 5d7e9e2..8d2b34e 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -76,7 +76,6 @@ def reconciliate_jar(request):
 
     form = ReconciliationJarForm()
     summary = Payment.get_reconciliation_jar_summary()
-    # raise Exception(Payment.get_reconciliation_jar_summary().payments)
     return render(
         request,
         "don_confiao/reconciliate_jar.html",
-- 
2.45.2


From 74d2e0d2345ea0d4d8e0052ab2b6dfad15fa4184 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 17:38:33 -0500
Subject: [PATCH 05/16] admin: set Payment and reconciliatoJar in admin

---
 tienda_ilusion/don_confiao/admin.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tienda_ilusion/don_confiao/admin.py b/tienda_ilusion/don_confiao/admin.py
index 0756544..fe34059 100644
--- a/tienda_ilusion/don_confiao/admin.py
+++ b/tienda_ilusion/don_confiao/admin.py
@@ -1,7 +1,9 @@
 from django.contrib import admin
-from .models import Sale, SaleLine, Product, ProductCategory
+from .models import Sale, SaleLine, Product, ProductCategory, Payment, ReconciliationJar
 
 admin.site.register(Sale)
 admin.site.register(SaleLine)
 admin.site.register(Product)
 admin.site.register(ProductCategory)
+admin.site.register(Payment)
+admin.site.register(ReconciliationJar)
-- 
2.45.2


From 08deb9d4ec346841da0bb3cbeadf3925d5e04fad Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 13 Jul 2024 17:48:57 -0500
Subject: [PATCH 06/16] view: improve reconciliate_jar.

---
 tienda_ilusion/don_confiao/forms.py           |  6 +++---
 .../0022_alter_payment_reconciliation_jar.py  | 19 +++++++++++++++++
 tienda_ilusion/don_confiao/models.py          |  1 +
 .../don_confiao/reconciliate_jar.html         | 21 ++++++++++++-------
 4 files changed, 36 insertions(+), 11 deletions(-)
 create mode 100644 tienda_ilusion/don_confiao/migrations/0022_alter_payment_reconciliation_jar.py

diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py
index 8fc05c9..758b119 100644
--- a/tienda_ilusion/don_confiao/forms.py
+++ b/tienda_ilusion/don_confiao/forms.py
@@ -48,6 +48,6 @@ class ReconciliationJarForm(forms.ModelForm):
             'cash_taken',
             'cash_discrepancy',
         ]
-        # widgets = {
-        #     'date_time': DateTimeInput(attrs={'type': 'datetime-local'})
-        # }
+        widgets = {
+            'date_time': DateTimeInput(attrs={'type': 'datetime-local'})
+        }
diff --git a/tienda_ilusion/don_confiao/migrations/0022_alter_payment_reconciliation_jar.py b/tienda_ilusion/don_confiao/migrations/0022_alter_payment_reconciliation_jar.py
new file mode 100644
index 0000000..5956a97
--- /dev/null
+++ b/tienda_ilusion/don_confiao/migrations/0022_alter_payment_reconciliation_jar.py
@@ -0,0 +1,19 @@
+# Generated by Django 5.0.6 on 2024-07-13 22:39
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('don_confiao', '0021_rename_reconciler_reconciliationjar_reconcilier'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='payment',
+            name='reconciliation_jar',
+            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.RESTRICT, to='don_confiao.reconciliationjar'),
+        ),
+    ]
diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 78c4746..2874dac 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -106,6 +106,7 @@ class Payment(models.Model):
         ReconciliationJar,
         null=True,
         default=None,
+        blank=True,
         on_delete=models.RESTRICT
     )
     description = models.CharField(max_length=255, null=True, blank=True)
diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
index ff0d778..16fa5dc 100644
--- a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
@@ -1,22 +1,27 @@
 <!doctype html>
 {% if summary.total %}
-<div class="reconciliate_jar summary">
+<div class="reconciliate_jar summary" style="border: solid 1px brown; margin: 10px">
     <h2>Pagos No reconciliados</h2>
-    <table>
+    <table style="border: solid 1px blue; margin: 10px">
         <thead>
-            <th><td>Fecha</td>Monto</th>
-            {% for payment in summary.payments %}
-            <tr><td>payment.date_time</td><td>payment.amount</td></tr>
-            {% endfor %}
+            <tr><th>Fecha</th><th>Monto</th></tr>
         </thead>
-    {{ summary.total }}
+        <tbody>
+            {% for payment in summary.payments %}
+            <tr><td>{{ payment.date_time }}</td><td>{{ payment.amount }}</td></tr>
+            {% endfor %}
+        </tbody>
+        <tfoot>
+            <tr><th>Total</th><td>{{ summary.total }}</td></tr>
+        </tfoot>
+    </table>
 </div>
 <form method="POST">
     <table style="border: solid 1px blue; margin: 10px">
         {% csrf_token %}
         {{ form.as_table }}
     </table>
-    <br/><button name="form" type="submit" >Comprar</button>
+    <br/><button name="form" type="submit" >Recoger dinero</button>
 </form>
 {% else %}
 <div class="reconciliate_jar information noform">
-- 
2.45.2


From a3c8189d8cdbd8d643f7c292681027cb5d56e13e Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 20 Jul 2024 11:44:49 -0500
Subject: [PATCH 07/16] feat: create a correct reconciliation jar.

---
 tienda_ilusion/don_confiao/models.py          |  2 +-
 tienda_ilusion/don_confiao/test_billing.py    |  3 ++-
 .../test_reconciliation_jar_client.py         | 16 +++++++++++--
 tienda_ilusion/don_confiao/urls.py            |  1 +
 tienda_ilusion/don_confiao/views.py           | 23 +++++++++++++++----
 5 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 2874dac..fb429ec 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -82,7 +82,7 @@ class ReconciliationJar(models.Model):
     cash_taken = models.DecimalField(max_digits=9, decimal_places=2)
     cash_discrepancy = models.DecimalField(max_digits=9, decimal_places=2)
 
-    def clean(self):
+    def manual_clean(self):
         payments_amount = sum([p.amount for p in self.payment_set.all()])
         reconciliation_ammount = sum([
             self.cash_taken,
diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index 49f8e97..ae9f6b0 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -53,7 +53,7 @@ class TestBilling(TestCase):
         for payment in jar_summary.payments:
             reconciliation_jar.payment_set.add(payment)
         with self.assertRaises(ValidationError):
-            reconciliation_jar.clean()
+            reconciliation_jar.manual_clean()
 
     def test_validate_reconciliation_jar_with_cash_float(self):
         cash_payment1, cash_payment2 = self._create_two_cash_payments()
@@ -72,6 +72,7 @@ class TestBilling(TestCase):
             reconciliation_jar.payment_set.add(payment)
         reconciliation_jar.clean()
         reconciliation_jar.save()
+        reconciliation_jar.manual_clean()
         self.assertTrue(reconciliation_jar.is_valid)
 
     def _create_two_cash_payments(self):
diff --git a/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
index 04ce878..fa008d8 100644
--- a/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
+++ b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
@@ -14,10 +14,23 @@ class TestReconciliationJarClient(TestCase):
         self._generate_two_cash_payments()
         response = self.client.get("/don_confiao/cuadrar_tarro")
         self.assertEqual(response.status_code, 200)
-        # raise Exception(response.content.decode('utf-8'))
         self.assertEqual(response.context["summary"].total, 160000)
         self.assertIn('160000', response.content.decode('utf-8'))
 
+    def test_create_reconciliation_jar(self):
+        self._generate_two_cash_payments()
+        response = self.client.post(
+            "/don_confiao/cuadrar_tarro",
+            {
+                "date_time": "2024-07-20T00:00",
+                "description": "Cuadre de prueba",
+                "reconcilier": "Jorge",
+                "cash_taken": "100000",
+                "cash_discrepancy": "60000",
+            }
+        )
+        self.assertRedirects(response, '/don_confiao/cuadres')
+
     def _generate_two_cash_payments(self):
         cash_payment1 = Payment()
         cash_payment1.date_time = '2024-07-07 12:00:00'
@@ -25,7 +38,6 @@ class TestReconciliationJarClient(TestCase):
         cash_payment1.amount = 130000
         cash_payment1.description = 'Saldo en compra'
         cash_payment1.save()
-        # raise Exception (cash_payment1.id)
 
         cash_payment2 = Payment()
         cash_payment2.date_time = '2024-07-07 13:05:00'
diff --git a/tienda_ilusion/don_confiao/urls.py b/tienda_ilusion/don_confiao/urls.py
index 10f9518..bdea574 100644
--- a/tienda_ilusion/don_confiao/urls.py
+++ b/tienda_ilusion/don_confiao/urls.py
@@ -10,4 +10,5 @@ urlpatterns = [
     path("productos", views.products, name="products"),
     path("importar_productos", views.import_products, name="import_products"),
     path("cuadrar_tarro", views.reconciliate_jar, name="reconciliate_jar"),
+    path("cuadres", views.reconciliate_jar, name="reconciliations"),
 ]
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 8d2b34e..f981775 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -1,6 +1,7 @@
 from django.shortcuts import render
 from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
 from django.template import loader
+from django.core.exceptions import ValidationError
 
 from .models import Sale, Product, ProductCategory, Payment
 from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm
@@ -71,17 +72,31 @@ def import_products(request):
 
 
 def reconciliate_jar(request):
-    if request.method == 'POST':
-        return HttpResponseRedirect("cuadres")
-
-    form = ReconciliationJarForm()
     summary = Payment.get_reconciliation_jar_summary()
+    if request.method == 'POST':
+        form = ReconciliationJarForm(request.POST)
+        reconciliation = form.save()
+        try:
+            if form.is_valid():
+                reconciliation.payment_set.set(summary.payments)
+                reconciliation.manual_clean()
+                form.save()
+                return HttpResponseRedirect('cuadres')
+        except Exception as e:
+            reconciliation.payment_set.set({})
+            reconciliation.delete()
+            raise e
+    else:
+        form = ReconciliationJarForm()
     return render(
         request,
         "don_confiao/reconciliate_jar.html",
         {'summary': summary, 'form': form}
     )
 
+def reconciliations(request):
+    return HttpResponse('<h1>Reconciliaciones</h1>')
+
 
 def _categories_from_csv_string(categories_string, separator="&"):
     categories = categories_string.split(separator)
-- 
2.45.2


From 58792961325dc2343d0774de7f8dd6701f559d21 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 27 Jul 2024 12:37:31 -0500
Subject: [PATCH 08/16] fix: ReconciliationJar.

---
 tienda_ilusion/don_confiao/models.py       | 24 ++++++++++++++++------
 tienda_ilusion/don_confiao/test_billing.py | 13 +++++-------
 tienda_ilusion/don_confiao/views.py        | 17 ++++++---------
 3 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index fb429ec..91d1199 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -2,6 +2,7 @@ from django.db import models
 from django.utils.translation import gettext_lazy as _
 from django.core.exceptions import ValidationError
 
+from decimal import Decimal
 
 class Sale(models.Model):
 
@@ -82,16 +83,27 @@ class ReconciliationJar(models.Model):
     cash_taken = models.DecimalField(max_digits=9, decimal_places=2)
     cash_discrepancy = models.DecimalField(max_digits=9, decimal_places=2)
 
-    def manual_clean(self):
-        payments_amount = sum([p.amount for p in self.payment_set.all()])
-        reconciliation_ammount = sum([
+    def clean(self):
+        if not self.is_valid:
+            payments = Payment.get_reconciliation_jar_summary().payments
+        else:
+            payments = self.payment_set.all()
+
+        payments_amount = Decimal(sum([p.amount for p in payments]))
+        reconciliation_ammount = Decimal(sum([
             self.cash_taken,
             self.cash_discrepancy,
-        ])
-        if reconciliation_ammount != payments_amount:
+        ]))
+
+        equal_ammounts = reconciliation_ammount.compare(payments_amount) == Decimal('0')
+        if not equal_ammounts:
             raise ValidationError(
-                {"cash_take": _("The taken ammount has discrepancy.")}
+                {"cash_taken": _("The taken ammount has discrepancy.")}
             )
+
+    def add_payments(self, payments):
+        for payment in payments:
+            self.payment_set.add(payment)
         self.is_valid = True
 
 class Payment(models.Model):
diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index ae9f6b0..9b6372b 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -1,4 +1,4 @@
-from django.test import Client, TestCase
+from django.test import TestCase
 from django.core.exceptions import ValidationError
 from .models import Payment, ReconciliationJar
 
@@ -50,10 +50,10 @@ class TestBilling(TestCase):
         reconciliation_jar.cash_discrepancy = 0
         reconciliation_jar.save()
 
-        for payment in jar_summary.payments:
-            reconciliation_jar.payment_set.add(payment)
+        reconciliation_jar.add_payments(jar_summary.payments)
+
         with self.assertRaises(ValidationError):
-            reconciliation_jar.manual_clean()
+            reconciliation_jar.clean()
 
     def test_validate_reconciliation_jar_with_cash_float(self):
         cash_payment1, cash_payment2 = self._create_two_cash_payments()
@@ -63,16 +63,13 @@ class TestBilling(TestCase):
         reconciliation_jar.date_time = '2024-07-13 13:02:00'
         reconciliation_jar.description = "test reconcialiation jar"
         reconciliation_jar.reconcilier = 'Jorge'
-        reconciliation_jar.cash_float = 10000
         reconciliation_jar.cash_taken = jar_summary.total
         reconciliation_jar.cash_discrepancy = 0
         reconciliation_jar.save()
 
-        for payment in jar_summary.payments:
-            reconciliation_jar.payment_set.add(payment)
+        reconciliation_jar.add_payments(jar_summary.payments)
         reconciliation_jar.clean()
         reconciliation_jar.save()
-        reconciliation_jar.manual_clean()
         self.assertTrue(reconciliation_jar.is_valid)
 
     def _create_two_cash_payments(self):
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index f981775..8d7222c 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -75,17 +75,12 @@ def reconciliate_jar(request):
     summary = Payment.get_reconciliation_jar_summary()
     if request.method == 'POST':
         form = ReconciliationJarForm(request.POST)
-        reconciliation = form.save()
-        try:
-            if form.is_valid():
-                reconciliation.payment_set.set(summary.payments)
-                reconciliation.manual_clean()
-                form.save()
-                return HttpResponseRedirect('cuadres')
-        except Exception as e:
-            reconciliation.payment_set.set({})
-            reconciliation.delete()
-            raise e
+        if form.is_valid():
+            reconciliation = form.save()
+            reconciliation.add_payments(summary.payments)
+            reconciliation.clean()
+            reconciliation.save()
+            return HttpResponseRedirect('cuadres')
     else:
         form = ReconciliationJarForm()
     return render(
-- 
2.45.2


From 02fba454ba1054b5eb9630e9c735a65bce3cf672 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 27 Jul 2024 13:19:37 -0500
Subject: [PATCH 09/16] Fix: Clean Home, Crear lineas de Venta

---
 tienda_ilusion/don_confiao/forms.py           |  2 ++
 tienda_ilusion/don_confiao/models.py          |  1 +
 tienda_ilusion/don_confiao/tests/__init__.py  |  1 +
 .../don_confiao/{ => tests}/test_products.py  | 10 ++++-----
 .../don_confiao/{ => tests}/tests.py          |  2 +-
 tienda_ilusion/don_confiao/views.py           | 21 +++++++++++++------
 6 files changed, 24 insertions(+), 13 deletions(-)
 create mode 100644 tienda_ilusion/don_confiao/tests/__init__.py
 rename tienda_ilusion/don_confiao/{ => tests}/test_products.py (93%)
 rename tienda_ilusion/don_confiao/{ => tests}/tests.py (98%)

diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py
index 758b119..85aeec0 100644
--- a/tienda_ilusion/don_confiao/forms.py
+++ b/tienda_ilusion/don_confiao/forms.py
@@ -7,6 +7,7 @@ from .models import Sale, SaleLine, ReconciliationJar
 class ImportProductsForm(forms.Form):
     csv_file = forms.FileField()
 
+
 class PurchaseForm(forms.ModelForm):
     class Meta:
         model = Sale
@@ -20,6 +21,7 @@ class PurchaseForm(forms.ModelForm):
             'date': DateInput(attrs={'type': 'date'})
         }
 
+
 class PurchaseLineForm(forms.ModelForm):
     class Meta:
         model = SaleLine
diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py
index 91d1199..36b48e9 100644
--- a/tienda_ilusion/don_confiao/models.py
+++ b/tienda_ilusion/don_confiao/models.py
@@ -4,6 +4,7 @@ from django.core.exceptions import ValidationError
 
 from decimal import Decimal
 
+
 class Sale(models.Model):
 
     customer = models.CharField(max_length=100)
diff --git a/tienda_ilusion/don_confiao/tests/__init__.py b/tienda_ilusion/don_confiao/tests/__init__.py
new file mode 100644
index 0000000..e5a0d9b
--- /dev/null
+++ b/tienda_ilusion/don_confiao/tests/__init__.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3
diff --git a/tienda_ilusion/don_confiao/test_products.py b/tienda_ilusion/don_confiao/tests/test_products.py
similarity index 93%
rename from tienda_ilusion/don_confiao/test_products.py
rename to tienda_ilusion/don_confiao/tests/test_products.py
index 0b4e0dc..0c12f74 100644
--- a/tienda_ilusion/don_confiao/test_products.py
+++ b/tienda_ilusion/don_confiao/tests/test_products.py
@@ -1,13 +1,11 @@
 from django.test import Client, TestCase
-from django.contrib.auth.models import AnonymousUser, User
 from django.conf import settings
-
-from .views import import_products, products
-from .models import ProductCategory, Product
+from ..models import ProductCategory, Product
 
 import os
 import json
 
+
 class TestProducts(TestCase):
     def setUp(self):
         self.client = Client()
@@ -54,7 +52,8 @@ class TestProducts(TestCase):
         first_categories = {p["name"]: p["categories"] for p in first_products}
         self._import_csv('example_products2.csv')
         updated_products = self._get_products()
-        updated_categories = {p["name"]: p["categories"] for p in updated_products}
+        updated_categories = {
+            p["name"]: p["categories"] for p in updated_products}
 
         self.assertIn('Cafes', first_categories['Arroz'])
         self.assertNotIn('Granos', first_categories['Arroz'])
@@ -62,7 +61,6 @@ class TestProducts(TestCase):
         self.assertIn('Granos', updated_categories['Arroz'])
         self.assertNotIn('Cafes', updated_categories['Arroz'])
 
-
     def test_update_price(self):
         self._import_csv()
         first_products = self._get_products()
diff --git a/tienda_ilusion/don_confiao/tests.py b/tienda_ilusion/don_confiao/tests/tests.py
similarity index 98%
rename from tienda_ilusion/don_confiao/tests.py
rename to tienda_ilusion/don_confiao/tests/tests.py
index 27b5d3e..771ec89 100644
--- a/tienda_ilusion/don_confiao/tests.py
+++ b/tienda_ilusion/don_confiao/tests/tests.py
@@ -1,5 +1,5 @@
 from django.test import TestCase
-from .models import Sale, SaleLine
+from ..models import Sale, SaleLine
 
 
 class ConfiaoTest(TestCase):
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 8d7222c..25a67da 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -1,6 +1,7 @@
 from django.shortcuts import render
+
 from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
-from django.template import loader
+#from django.template import loader
 from django.core.exceptions import ValidationError
 
 from .models import Sale, Product, ProductCategory, Payment
@@ -9,18 +10,22 @@ from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, Reconciliatio
 import csv
 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)
-        if sale_form.is_valid():
-            sale_form.save()
-        if sale_linea_form.is_valid():
-            sale_linea_form.save()
-        return HttpResponseRedirect("productos")
+        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()
+            return HttpResponseRedirect("compras")
     else:
         sale_form = PurchaseForm()
         sale_linea_form = LineaFormSet()
@@ -33,6 +38,7 @@ def buy(request):
         }
     )
 
+
 def purchases(request):
     purchases = Sale.objects.all()
     context = {
@@ -89,6 +95,7 @@ def reconciliate_jar(request):
         {'summary': summary, 'form': form}
     )
 
+
 def reconciliations(request):
     return HttpResponse('<h1>Reconciliaciones</h1>')
 
@@ -98,9 +105,11 @@ def _categories_from_csv_string(categories_string, separator="&"):
     clean_categories = [c.strip() for c in categories]
     return [_category_from_name(category) for category in clean_categories]
 
+
 def _category_from_name(name):
     return ProductCategory.objects.get_or_create(name=name)[0]
 
+
 def handle_import_products_file(csv_file):
     data = io.StringIO(csv_file.read().decode('utf-8'))
     reader = csv.DictReader(data, quotechar='"')
-- 
2.45.2


From b94c5a007043a1e05650cce07fc8aa26652d2478 Mon Sep 17 00:00:00 2001
From: sinergia <alejandro.ayala@onecluster.org>
Date: Fri, 12 Jul 2024 22:38:07 -0500
Subject: [PATCH 10/16] feat: Se agrega testform

---
 tienda_ilusion/don_confiao/forms.py           |  2 +-
 .../don_confiao/tests/tests_purchase_form.py  | 33 +++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 tienda_ilusion/don_confiao/tests/tests_purchase_form.py

diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py
index 85aeec0..1c739f1 100644
--- a/tienda_ilusion/don_confiao/forms.py
+++ b/tienda_ilusion/don_confiao/forms.py
@@ -36,7 +36,7 @@ class PurchaseLineForm(forms.ModelForm):
 LineaFormSet = forms.models.inlineformset_factory(
     Sale,
     SaleLine,
-    extra=2,
+    extra=1,
     fields='__all__'
 )
 
diff --git a/tienda_ilusion/don_confiao/tests/tests_purchase_form.py b/tienda_ilusion/don_confiao/tests/tests_purchase_form.py
new file mode 100644
index 0000000..e50849b
--- /dev/null
+++ b/tienda_ilusion/don_confiao/tests/tests_purchase_form.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+from django.test import TestCase
+from ..forms import PurchaseForm
+# from ..models import Sale, SaleLine
+
+_csrf_token = \
+    "bVjBevJRavxRPFOlVgAWiyh9ceuiwPlyEcmbPZprNuCGHjFZRKZrBeunJvKTRgOx"
+
+
+class PurchaseFormTest(TestCase):
+
+    def test_add_purchase(self):
+        form_data = {
+            "csrfmiddlewaretoken": _csrf_token,
+            "customer": "San Judas de Asis",
+            "date": "2024-07-12",
+            "phone": "3010101000",
+            "description": "Esta es una Venta",
+            "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": "1",
+            "saleline_set-0-unit_price": "22030",
+            "saleline_set-0-description": "Linea de Venta",
+            "saleline_set-0-sale": "",
+            "saleline_set-0-id": "",
+            "form": ""
+        }
+
+        purchase_form = PurchaseForm(data=form_data)
+        self.assertTrue(purchase_form.is_valid())
-- 
2.45.2


From cb84371f4bf460943f60fc38c4f4d28586db03a8 Mon Sep 17 00:00:00 2001
From: Rodia <alejandro.ayala@onecluster.org>
Date: Fri, 12 Jul 2024 23:40:43 -0500
Subject: [PATCH 11/16] =?UTF-8?q?Feat(ButtonAddLine):=20A=C3=B1adir=20line?=
 =?UTF-8?q?a=20de=20venta=20en=20formulario=20WIP?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../don_confiao/static/js/add_line.js         | 18 ++++++++++++++++
 .../templates/don_confiao/purchase.html       | 21 ++++++++++++-------
 2 files changed, 32 insertions(+), 7 deletions(-)
 create mode 100644 tienda_ilusion/don_confiao/static/js/add_line.js

diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js
new file mode 100644
index 0000000..aed4bec
--- /dev/null
+++ b/tienda_ilusion/don_confiao/static/js/add_line.js
@@ -0,0 +1,18 @@
+document.addEventListener('DOMContentLoaded', function(){
+  var button = document.getElementById('add_line');
+  var formContainer = document.getElementById('formset-container');
+  var totalForms = document.getElementById('id_form-TOTAL_FORMS');
+  button.addEventListener('click', function(){
+    // Clonar un formulario vacío
+    var newForm = formContainer.querySelector('.form-container').cloneNode(true);
+    // Obtener el número actual de formularios
+    var formCount = parseInt(totalForms.value);
+    // Actualizar los atributos de los nuevos campos del formulario
+    var regex = new RegExp('__prefix__', 'g');
+    newForm.innerHTML = newForm.innerHTML.replace(regex, formCount);
+    // Añadir el nuevo formulario al contenedor
+    formContainer.appendChild(newForm);
+    // Incrementar el total de formularios
+    totalForms.value = formCount + 1;
+  });
+});
diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
index 0d2c2f4..7f6c8d9 100644
--- a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
@@ -1,12 +1,19 @@
 <!doctype html>
+{% load static %}
 <form method="POST">
-    {% csrf_token %}
-        {{ sale_form}}
+  {% csrf_token %}
+  {{ sale_form}}
   {{ linea_formset.management_form }}
-  {% for form in linea_formset %}
-    <table style="border: solid 1px blue; margin: 10px">
-        {{ form.as_table }}
-    </table>
+  <div id="formset-container">
+    {% for form in linea_formset %}
+      <div class="form-container">
+        <table style="border: solid 1px blue; margin: 10px">
+          {{ form.as_table }}
+        </table>
+      </div>
     {% endfor %}
-    <br/><button name="form" type="submit" >Comprar</button>
+  </div>
+  <button id="add_line">Añadir Linea</button>
+  <br/><button name="form" type="submit" >Comprar</button>
+  <script src="{% static 'js/add_line.js' %}"></script>
 </form>
-- 
2.45.2


From b70a0b73c32dd06469ae8a9f8a4658d11f4e7d4e Mon Sep 17 00:00:00 2001
From: Rodia <alejandro.ayala@onecluster.org>
Date: Sat, 13 Jul 2024 11:01:11 -0500
Subject: [PATCH 12/16] Feat(AddSaleLineButton): Sale Line Button

---
 tienda_ilusion/don_confiao/static/js/add_line.js               | 2 +-
 tienda_ilusion/don_confiao/templates/don_confiao/purchase.html | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js
index aed4bec..bfb38ed 100644
--- a/tienda_ilusion/don_confiao/static/js/add_line.js
+++ b/tienda_ilusion/don_confiao/static/js/add_line.js
@@ -1,7 +1,7 @@
 document.addEventListener('DOMContentLoaded', function(){
   var button = document.getElementById('add_line');
   var formContainer = document.getElementById('formset-container');
-  var totalForms = document.getElementById('id_form-TOTAL_FORMS');
+  var totalForms = document.getElementById('id_saleline_set-TOTAL_FORMS');
   button.addEventListener('click', function(){
     // Clonar un formulario vacío
     var newForm = formContainer.querySelector('.form-container').cloneNode(true);
diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
index 7f6c8d9..d174357 100644
--- a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html
@@ -13,7 +13,7 @@
       </div>
     {% endfor %}
   </div>
-  <button id="add_line">Añadir Linea</button>
+  <button id="add_line" type="button" onclick="add_line">Añadir Linea</button>
   <br/><button name="form" type="submit" >Comprar</button>
   <script src="{% static 'js/add_line.js' %}"></script>
 </form>
-- 
2.45.2


From 9edbd1caef4547af7cdc3af0ebeacc9908675429 Mon Sep 17 00:00:00 2001
From: Rodia <alejandro.ayala@onecluster.org>
Date: Sat, 13 Jul 2024 11:25:12 -0500
Subject: [PATCH 13/16] Feat(ReplaceNameIdSaleLine)

---
 .../don_confiao/static/js/add_line.js         | 21 ++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js
index bfb38ed..4f6bc25 100644
--- a/tienda_ilusion/don_confiao/static/js/add_line.js
+++ b/tienda_ilusion/don_confiao/static/js/add_line.js
@@ -3,16 +3,27 @@ document.addEventListener('DOMContentLoaded', function(){
   var formContainer = document.getElementById('formset-container');
   var totalForms = document.getElementById('id_saleline_set-TOTAL_FORMS');
   button.addEventListener('click', function(){
-    // Clonar un formulario vacío
     var newForm = formContainer.querySelector('.form-container').cloneNode(true);
-    // Obtener el número actual de formularios
     var formCount = parseInt(totalForms.value);
-    // Actualizar los atributos de los nuevos campos del formulario
     var regex = new RegExp('__prefix__', 'g');
     newForm.innerHTML = newForm.innerHTML.replace(regex, formCount);
-    // Añadir el nuevo formulario al contenedor
+
+    var fields = newForm.querySelectorAll('[id^="id_saleline_set-"], [name^="saleline_set-"]');
+    fields.forEach(function(field) {
+      var oldId = field.id;
+      var oldName = field.name;
+
+      if (oldId) {
+        var newId = oldId.replace(/-\d+-/, '-' + formCount + '-');
+        field.id = newId;
+      }
+      if (oldName) {
+        var newName = oldName.replace(/-\d+-/, '-' + formCount + '-');
+        field.name = newName;
+      }
+    });
+
     formContainer.appendChild(newForm);
-    // Incrementar el total de formularios
     totalForms.value = formCount + 1;
   });
 });
-- 
2.45.2


From 675b4f059f0b0130279af81c7f2ce3fad10f2969 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 27 Jul 2024 13:30:14 -0500
Subject: [PATCH 14/16] feat: implementing form to reconciliation jar.

---
 .../don_confiao/templates/don_confiao/reconciliate_jar.html    | 3 ---
 tienda_ilusion/don_confiao/test_billing.py                     | 1 -
 tienda_ilusion/don_confiao/test_reconciliation_jar_client.py   | 1 +
 tienda_ilusion/don_confiao/views.py                            | 2 --
 4 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
index 16fa5dc..6771044 100644
--- a/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
+++ b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html
@@ -28,6 +28,3 @@
     <h2>No hay pagos registrados.</h2>
 </div>
 {% endif %}
-    
-
-
diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index 9b6372b..89a5a43 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -51,7 +51,6 @@ class TestBilling(TestCase):
         reconciliation_jar.save()
 
         reconciliation_jar.add_payments(jar_summary.payments)
-
         with self.assertRaises(ValidationError):
             reconciliation_jar.clean()
 
diff --git a/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
index fa008d8..ad58d0e 100644
--- a/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
+++ b/tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
@@ -31,6 +31,7 @@ class TestReconciliationJarClient(TestCase):
         )
         self.assertRedirects(response, '/don_confiao/cuadres')
 
+
     def _generate_two_cash_payments(self):
         cash_payment1 = Payment()
         cash_payment1.date_time = '2024-07-07 12:00:00'
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 25a67da..6e67f01 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -95,11 +95,9 @@ def reconciliate_jar(request):
         {'summary': summary, 'form': form}
     )
 
-
 def reconciliations(request):
     return HttpResponse('<h1>Reconciliaciones</h1>')
 
-
 def _categories_from_csv_string(categories_string, separator="&"):
     categories = categories_string.split(separator)
     clean_categories = [c.strip() for c in categories]
-- 
2.45.2


From 09f734f5cbea404ddd1084bd9f4fc43519f78cf4 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 27 Jul 2024 13:32:31 -0500
Subject: [PATCH 15/16] feat: create a correct reconciliation jar.

---
 tienda_ilusion/don_confiao/test_billing.py | 3 ++-
 tienda_ilusion/don_confiao/views.py        | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index 89a5a43..79254e9 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -52,7 +52,7 @@ class TestBilling(TestCase):
 
         reconciliation_jar.add_payments(jar_summary.payments)
         with self.assertRaises(ValidationError):
-            reconciliation_jar.clean()
+            reconciliation_jar.manual_clean()
 
     def test_validate_reconciliation_jar_with_cash_float(self):
         cash_payment1, cash_payment2 = self._create_two_cash_payments()
@@ -69,6 +69,7 @@ class TestBilling(TestCase):
         reconciliation_jar.add_payments(jar_summary.payments)
         reconciliation_jar.clean()
         reconciliation_jar.save()
+        reconciliation_jar.manual_clean()
         self.assertTrue(reconciliation_jar.is_valid)
 
     def _create_two_cash_payments(self):
diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py
index 6e67f01..2041831 100644
--- a/tienda_ilusion/don_confiao/views.py
+++ b/tienda_ilusion/don_confiao/views.py
@@ -1,7 +1,7 @@
 from django.shortcuts import render
 
 from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
-#from django.template import loader
+from django.template import loader
 from django.core.exceptions import ValidationError
 
 from .models import Sale, Product, ProductCategory, Payment
@@ -95,9 +95,11 @@ def reconciliate_jar(request):
         {'summary': summary, 'form': form}
     )
 
+
 def reconciliations(request):
     return HttpResponse('<h1>Reconciliaciones</h1>')
 
+
 def _categories_from_csv_string(categories_string, separator="&"):
     categories = categories_string.split(separator)
     clean_categories = [c.strip() for c in categories]
-- 
2.45.2


From 72bf284dfd9c6c036ef1363c7c412f8bbbde77c7 Mon Sep 17 00:00:00 2001
From: Mono Mono <monomono@disroot.org>
Date: Sat, 27 Jul 2024 13:41:01 -0500
Subject: [PATCH 16/16] fix merge error.

---
 tienda_ilusion/don_confiao/test_billing.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tienda_ilusion/don_confiao/test_billing.py b/tienda_ilusion/don_confiao/test_billing.py
index 79254e9..89a5a43 100644
--- a/tienda_ilusion/don_confiao/test_billing.py
+++ b/tienda_ilusion/don_confiao/test_billing.py
@@ -52,7 +52,7 @@ class TestBilling(TestCase):
 
         reconciliation_jar.add_payments(jar_summary.payments)
         with self.assertRaises(ValidationError):
-            reconciliation_jar.manual_clean()
+            reconciliation_jar.clean()
 
     def test_validate_reconciliation_jar_with_cash_float(self):
         cash_payment1, cash_payment2 = self._create_two_cash_payments()
@@ -69,7 +69,6 @@ class TestBilling(TestCase):
         reconciliation_jar.add_payments(jar_summary.payments)
         reconciliation_jar.clean()
         reconciliation_jar.save()
-        reconciliation_jar.manual_clean()
         self.assertTrue(reconciliation_jar.is_valid)
 
     def _create_two_cash_payments(self):
-- 
2.45.2