Modelar cuadre de caja #10 #12
@ -1,7 +1,9 @@
|
|||||||
from django.contrib import admin
|
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(Sale)
|
||||||
admin.site.register(SaleLine)
|
admin.site.register(SaleLine)
|
||||||
admin.site.register(Product)
|
admin.site.register(Product)
|
||||||
admin.site.register(ProductCategory)
|
admin.site.register(ProductCategory)
|
||||||
|
admin.site.register(Payment)
|
||||||
|
admin.site.register(ReconciliationJar)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from django import forms
|
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):
|
class ImportProductsForm(forms.Form):
|
||||||
@ -39,3 +39,17 @@ LineaFormSet = forms.models.inlineformset_factory(
|
|||||||
extra=1,
|
extra=1,
|
||||||
fields='__all__'
|
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'})
|
||||||
|
}
|
||||||
|
23
tienda_ilusion/don_confiao/migrations/0012_payment.py
Normal file
23
tienda_ilusion/don_confiao/migrations/0012_payment.py
Normal file
@ -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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
),
|
||||||
|
]
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
@ -1,5 +1,9 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Sale(models.Model):
|
class Sale(models.Model):
|
||||||
@ -48,3 +52,84 @@ class Product(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<!doctype html>
|
||||||
|
{% if summary.total %}
|
||||||
|
<div class="reconciliate_jar summary" style="border: solid 1px brown; margin: 10px">
|
||||||
|
<h2>Pagos No reconciliados</h2>
|
||||||
|
<table style="border: solid 1px blue; margin: 10px">
|
||||||
|
<thead>
|
||||||
|
<tr><th>Fecha</th><th>Monto</th></tr>
|
||||||
|
</thead>
|
||||||
|
<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" >Recoger dinero</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<div class="reconciliate_jar information noform">
|
||||||
|
<h2>No hay pagos registrados.</h2>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
88
tienda_ilusion/don_confiao/test_billing.py
Normal file
88
tienda_ilusion/don_confiao/test_billing.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from .models import Payment, ReconciliationJar
|
||||||
|
|
||||||
|
|
||||||
|
class TestBilling(TestCase):
|
||||||
|
|
||||||
|
def test_reconciliation_jar_summary(self):
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
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'
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
reconciliation_jar.add_payments(jar_summary.payments)
|
||||||
|
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_taken = jar_summary.total
|
||||||
|
reconciliation_jar.cash_discrepancy = 0
|
||||||
|
reconciliation_jar.save()
|
||||||
|
|
||||||
|
reconciliation_jar.add_payments(jar_summary.payments)
|
||||||
|
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]
|
47
tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
Normal file
47
tienda_ilusion/don_confiao/test_reconciliation_jar_client.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
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)
|
||||||
|
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'
|
||||||
|
cash_payment1.type_payment = 'CASH'
|
||||||
|
cash_payment1.amount = 130000
|
||||||
|
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 = 30000
|
||||||
|
cash_payment2.save()
|
@ -8,5 +8,7 @@ urlpatterns = [
|
|||||||
path("comprar", views.buy, name="buy"),
|
path("comprar", views.buy, name="buy"),
|
||||||
path("compras", views.purchases, name="purchases"),
|
path("compras", views.purchases, name="purchases"),
|
||||||
path("productos", views.products, name="products"),
|
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"),
|
||||||
|
path("cuadres", views.reconciliate_jar, name="reconciliations"),
|
||||||
]
|
]
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpResponseRedirect, JsonResponse
|
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
|
from .models import Sale, Product, ProductCategory, Payment
|
||||||
from .forms import ImportProductsForm, PurchaseForm, LineaFormSet
|
from .forms import ImportProductsForm, PurchaseForm, LineaFormSet, ReconciliationJarForm
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
@ -75,6 +76,29 @@ def import_products(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def reconciliate_jar(request):
|
||||||
|
summary = Payment.get_reconciliation_jar_summary()
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = ReconciliationJarForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
reconciliation = form.save()
|
||||||
|
reconciliation.add_payments(summary.payments)
|
||||||
|
reconciliation.clean()
|
||||||
|
reconciliation.save()
|
||||||
|
return HttpResponseRedirect('cuadres')
|
||||||
|
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="&"):
|
def _categories_from_csv_string(categories_string, separator="&"):
|
||||||
categories = categories_string.split(separator)
|
categories = categories_string.split(separator)
|
||||||
clean_categories = [c.strip() for c in categories]
|
clean_categories = [c.strip() for c in categories]
|
||||||
|
Loading…
Reference in New Issue
Block a user