diff --git a/tienda_ilusion/don_confiao/api_views.py b/tienda_ilusion/don_confiao/api_views.py index 31be80a..fc462cc 100644 --- a/tienda_ilusion/don_confiao/api_views.py +++ b/tienda_ilusion/don_confiao/api_views.py @@ -2,6 +2,7 @@ from rest_framework import viewsets from rest_framework.response import Response from rest_framework.status import HTTP_400_BAD_REQUEST from rest_framework.views import APIView +from rest_framework.pagination import PageNumberPagination from .models import Sale, SaleLine, Customer, Product, ReconciliationJar, PaymentMethods, AdminCode from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, ReconciliationJarSerializer, PaymentMethodSerializer, SaleForRenconciliationSerializer, SaleSummarySerializer @@ -9,6 +10,12 @@ from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, from decimal import Decimal import json + +class Pagination(PageNumberPagination): + page_size = 10 + page_size_query_param = 'page_size' + + class SaleView(viewsets.ModelViewSet): queryset = Sale.objects.all() serializer_class = SaleSerializer @@ -131,3 +138,9 @@ class AdminCodeValidateView(APIView): def get(self, request, code): codes = AdminCode.objects.filter(value=code) return Response({'validCode': bool(codes)}) + + +class ReconciliateJarModelView(viewsets.ModelViewSet): + queryset = ReconciliationJar.objects.all().order_by('-date_time') + pagination_class = Pagination + serializer_class = ReconciliationJarSerializer diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/NavBar.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/NavBar.vue index 3c25a2a..66c44c1 100644 --- a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/NavBar.vue +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/NavBar.vue @@ -29,7 +29,8 @@ menuItems: [ { title: 'Inicio', route: '/'}, { title: 'Comprar', route:'/comprar'}, - { title: 'Cuadrar tarro', route: '/cuadrar_tarro'} + { title: 'Cuadrar tarro', route: '/cuadrar_tarro'}, + { title: 'Cuadres de tarro', route: '/cuadres_de_tarro'}, ], }), watch: { diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarIndex.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarIndex.vue new file mode 100644 index 0000000..e88e376 --- /dev/null +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarIndex.vue @@ -0,0 +1,64 @@ + + diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarView.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarView.vue new file mode 100644 index 0000000..b1ae8cc --- /dev/null +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/ReconciliationJarView.vue @@ -0,0 +1,140 @@ + + diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryPurchase.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryPurchase.vue index 07a37c2..9549d79 100644 --- a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryPurchase.vue +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryPurchase.vue @@ -53,7 +53,7 @@ name: 'SummaryPurchase', props: { msg: String, - id: String + id: Number }, data () { return { diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliation.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliation.vue new file mode 100644 index 0000000..0079d0f --- /dev/null +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliation.vue @@ -0,0 +1,30 @@ + + + diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliationModal.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliationModal.vue new file mode 100644 index 0000000..004d904 --- /dev/null +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/components/SummaryReconciliationModal.vue @@ -0,0 +1,31 @@ + + + diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/pages/cuadres_de_tarro.vue b/tienda_ilusion/don_confiao/frontend/don-confiao/src/pages/cuadres_de_tarro.vue new file mode 100644 index 0000000..739a1e9 --- /dev/null +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/pages/cuadres_de_tarro.vue @@ -0,0 +1,20 @@ + + + diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/api.js b/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/api.js index 92186b5..2e6ef11 100644 --- a/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/api.js +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/api.js @@ -23,6 +23,14 @@ class Api { return this.apiImplementation.getPurchasesForReconciliation(); } + getListReconcliations(page=1, itemsPerPage=10) { + return this.apiImplementation.getListReconcliations(page, itemsPerPage); + } + + getReconciliation(reconciliationId) { + return this.apiImplementation.getReconciliation(reconciliationId); + } + isValidAdminCode(code) { return this.apiImplementation.isValidAdminCode(code); } diff --git a/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/django-api.js b/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/django-api.js index 5faae05..abe9f4d 100644 --- a/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/django-api.js +++ b/tienda_ilusion/don_confiao/frontend/don-confiao/src/services/django-api.js @@ -24,6 +24,16 @@ class DjangoApi { return this.getRequest(url); } + getListReconcliations(page, itemsPerPage) { + const url = `/don_confiao/api/reconciliate_jar/?page=${page}&page_size=${itemsPerPage}`; + return this.getRequest(url); + } + + getReconciliation(reconciliationId) { + const url = `/don_confiao/api/reconciliate_jar/${reconciliationId}/`; + return this.getRequest(url); + } + isValidAdminCode(code) { const url = `/don_confiao/api/admin_code/validate/${code}` return this.getRequest(url) diff --git a/tienda_ilusion/don_confiao/serializers.py b/tienda_ilusion/don_confiao/serializers.py index d567275..8c68dd4 100644 --- a/tienda_ilusion/don_confiao/serializers.py +++ b/tienda_ilusion/don_confiao/serializers.py @@ -10,9 +10,12 @@ class SaleLineSerializer(serializers.ModelSerializer): class SaleSerializer(serializers.ModelSerializer): + total = serializers.ReadOnlyField(source='get_total') + class Meta: model = Sale - fields = ['id', 'customer', 'date', 'saleline_set'] + fields = ['id', 'customer', 'date', 'saleline_set', + 'total', 'payment_method'] class ProductSerializer(serializers.ModelSerializer): @@ -28,6 +31,8 @@ class CustomerSerializer(serializers.ModelSerializer): class ReconciliationJarSerializer(serializers.ModelSerializer): + Sales = SaleSerializer(many=True, read_only=True) + class Meta: model = ReconciliationJar fields = [ @@ -37,8 +42,10 @@ class ReconciliationJarSerializer(serializers.ModelSerializer): 'cash_taken', 'cash_discrepancy', 'total_cash_purchases', + 'Sales', ] + class PaymentMethodSerializer(serializers.Serializer): text = serializers.CharField() value = serializers.CharField() @@ -49,6 +56,7 @@ class PaymentMethodSerializer(serializers.Serializer): 'value': instance[0], } + class SaleForRenconciliationSerializer(serializers.Serializer): id = serializers.IntegerField() date = serializers.DateTimeField() diff --git a/tienda_ilusion/don_confiao/tests/test_jar_reconciliation.py b/tienda_ilusion/don_confiao/tests/test_jar_reconciliation.py index de8503c..9efb15d 100644 --- a/tienda_ilusion/don_confiao/tests/test_jar_reconciliation.py +++ b/tienda_ilusion/don_confiao/tests/test_jar_reconciliation.py @@ -139,22 +139,7 @@ class TestJarReconcliation(TestCase): self.assertIn('total_cash_purchases', content['error']) def test_create_reconciliation_with_purchases(self): - url = '/don_confiao/reconciliate_jar' - total_purchases = (11 * 72500) + (27 * 72500) - data = { - 'date_time': '2024-12-02T21:07', - 'reconcilier': 'carlos', - 'total_cash_purchases': total_purchases, - 'cash_taken': total_purchases, - 'cash_discrepancy': 0, - 'cash_purchases': [ - self.purchase.id, - self.purchase2.id, - self.purchase.id, - ], - } - response = self.client.post(url, data=json.dumps(data).encode('utf-8'), - content_type='application/json') + response = self._create_reconciliation_with_purchase() rawContent = response.content.decode('utf-8') content = json.loads(rawContent) @@ -197,6 +182,59 @@ class TestJarReconcliation(TestCase): purchases = Sale.objects.filter(reconciliation_id=content['id']) self.assertEqual(len(purchases), 3) + def test_list_reconciliations(self): + self._create_simple_reconciliation() + self._create_simple_reconciliation() + + url = '/don_confiao/api/reconciliate_jar/' + + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + content = json.loads(response.content.decode('utf-8')) + self.assertEqual(2, content['count']) + self.assertEqual(2, len(content['results'])) + self.assertEqual('2024-07-30T00:00:00Z', + content['results'][0]['date_time']) + + def test_list_reconciliations_pagination(self): + self._create_simple_reconciliation() + self._create_simple_reconciliation() + + url = '/don_confiao/api/reconciliate_jar/?page=2&page_size=1' + + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + content = json.loads(response.content.decode('utf-8')) + self.assertEqual(1, len(content['results'])) + self.assertEqual('2024-07-30T00:00:00Z', + content['results'][0]['date_time']) + + def test_get_single_reconciliation(self): + createResponse = self._create_reconciliation_with_purchase() + reconciliationId = json.loads( + createResponse.content.decode('utf-8') + )['id'] + self.assertGreater(reconciliationId, 0) + + url = f'/don_confiao/api/reconciliate_jar/{reconciliationId}/' + response = self.client.get(url, content_type='application/json') + content = json.loads( + response.content.decode('utf-8') + ) + self.assertEqual(reconciliationId, content['id']) + self.assertGreater(len(content['Sales']), 0) + self.assertIn( + self.purchase.id, + [sale['id'] for sale in content['Sales']] + ) + + self.assertIn( + 'CASH', + [sale['payment_method'] for sale in content['Sales']] + ) + def _create_simple_reconciliation(self): reconciliation = ReconciliationJar() reconciliation.date_time = "2024-07-30" @@ -206,3 +244,21 @@ class TestJarReconcliation(TestCase): reconciliation.clean() reconciliation.save() return reconciliation + + def _create_reconciliation_with_purchase(self): + url = '/don_confiao/reconciliate_jar' + total_purchases = (11 * 72500) + (27 * 72500) + data = { + 'date_time': '2024-12-02T21:07', + 'reconcilier': 'carlos', + 'total_cash_purchases': total_purchases, + 'cash_taken': total_purchases, + 'cash_discrepancy': 0, + 'cash_purchases': [ + self.purchase.id, + self.purchase2.id, + self.purchase.id, + ], + } + return self.client.post(url, data=json.dumps(data).encode('utf-8'), + content_type='application/json') diff --git a/tienda_ilusion/don_confiao/urls.py b/tienda_ilusion/don_confiao/urls.py index 5f8f654..3b4dd69 100644 --- a/tienda_ilusion/don_confiao/urls.py +++ b/tienda_ilusion/don_confiao/urls.py @@ -10,7 +10,8 @@ router = DefaultRouter() router.register(r'sales', api_views.SaleView, basename='sale') router.register(r'customers', api_views.CustomerView, basename='customer') router.register(r'products', api_views.ProductView, basename='product') - +router.register(r'reconciliate_jar', api_views.ReconciliateJarModelView, + basename='reconciliate_jar') urlpatterns = [ path("", views.index, name="wellcome"),