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) diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py index 72b4b9c..1c739f1 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): @@ -39,3 +39,17 @@ LineaFormSet = forms.models.inlineformset_factory( extra=1, fields='__all__' ) + +class ReconciliationJarForm(forms.ModelForm): + class Meta: + model = ReconciliationJar + fields = [ + 'date_time', + 'description', + 'reconcilier', + 'cash_taken', + 'cash_discrepancy', + ] + widgets = { + 'date_time': DateTimeInput(attrs={'type': 'datetime-local'}) + } 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/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/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/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 a3c2432..9de8188 100644 --- a/tienda_ilusion/don_confiao/models.py +++ b/tienda_ilusion/don_confiao/models.py @@ -1,5 +1,9 @@ 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): @@ -48,3 +52,84 @@ 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): + is_valid = models.BooleanField(default=False) + date_time = models.DateTimeField() + description = models.CharField(max_length=255, null=True, blank=True) + 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) + + 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, + ])) + + equal_ammounts = reconciliation_ammount.compare(payments_amount) == Decimal('0') + if not equal_ammounts: + raise ValidationError( + {"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): + 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, + blank=True, + 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/templates/don_confiao/reconciliate_jar.html b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html new file mode 100644 index 0000000..6771044 --- /dev/null +++ b/tienda_ilusion/don_confiao/templates/don_confiao/reconciliate_jar.html @@ -0,0 +1,30 @@ + +{% if summary.total %} +
Fecha | Monto |
---|---|
{{ payment.date_time }} | {{ payment.amount }} |
Total | {{ summary.total }} |