Exportando ventas para tryton desde api #4
@@ -6,9 +6,11 @@ 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
 | 
			
		||||
from .views import sales_to_tryton_csv
 | 
			
		||||
 | 
			
		||||
from decimal import Decimal
 | 
			
		||||
import json
 | 
			
		||||
import io
 | 
			
		||||
import csv
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Pagination(PageNumberPagination):
 | 
			
		||||
@@ -128,12 +130,14 @@ class SalesForReconciliationView(APIView):
 | 
			
		||||
 | 
			
		||||
        return Response(grouped_sales)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SaleSummary(APIView):
 | 
			
		||||
    def get(self, request, id):
 | 
			
		||||
        sale = Sale.objects.get(pk=id)
 | 
			
		||||
        serializer = SaleSummarySerializer(sale)
 | 
			
		||||
        return Response(serializer.data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AdminCodeValidateView(APIView):
 | 
			
		||||
    def get(self, request, code):
 | 
			
		||||
        codes = AdminCode.objects.filter(value=code)
 | 
			
		||||
@@ -144,3 +148,19 @@ class ReconciliateJarModelView(viewsets.ModelViewSet):
 | 
			
		||||
    queryset = ReconciliationJar.objects.all().order_by('-date_time')
 | 
			
		||||
    pagination_class = Pagination
 | 
			
		||||
    serializer_class = ReconciliationJarSerializer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SalesForTrytonView(APIView):
 | 
			
		||||
    def get(self, request):
 | 
			
		||||
        sales = Sale.objects.all()
 | 
			
		||||
        csv = self._generate_sales_CSV(sales)
 | 
			
		||||
        return Response({'csv': csv})
 | 
			
		||||
 | 
			
		||||
    def _generate_sales_CSV(self, sales):
 | 
			
		||||
        output = io.StringIO()
 | 
			
		||||
        writer = csv.writer(output)
 | 
			
		||||
        csv_data = sales_to_tryton_csv(sales)
 | 
			
		||||
 | 
			
		||||
        for row in csv_data:
 | 
			
		||||
            writer.writerow(row)
 | 
			
		||||
        return output.getvalue()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,7 @@
 | 
			
		||||
import json
 | 
			
		||||
import csv
 | 
			
		||||
import io
 | 
			
		||||
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from rest_framework import status
 | 
			
		||||
from rest_framework.test import APITestCase
 | 
			
		||||
@@ -45,6 +48,58 @@ class TestAPI(APITestCase):
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
        self.assertEqual(self.customer.name, json_response[0]['name'])
 | 
			
		||||
 | 
			
		||||
    def test_get_sales_for_tryton(self):
 | 
			
		||||
        url = '/don_confiao/api/sales/for_tryton'
 | 
			
		||||
        self._create_sale()
 | 
			
		||||
        response = self.client.get(url)
 | 
			
		||||
        json_response = json.loads(response.content.decode('utf-8'))
 | 
			
		||||
        self.assertEqual(response.status_code, status.HTTP_200_OK)
 | 
			
		||||
        self.assertIn('csv', json_response)
 | 
			
		||||
        self.assertGreater(len(json_response['csv']), 0)
 | 
			
		||||
 | 
			
		||||
    def test_csv_structure_in_sales_for_tryton(self):
 | 
			
		||||
        url = '/don_confiao/api/sales/for_tryton'
 | 
			
		||||
        self._create_sale()
 | 
			
		||||
        response = self.client.get(url)
 | 
			
		||||
        json_response = json.loads(response.content.decode('utf-8'))
 | 
			
		||||
        self.assertEqual(response.status_code, status.HTTP_200_OK)
 | 
			
		||||
 | 
			
		||||
        csv_reader = csv.reader(io.StringIO(json_response['csv']))
 | 
			
		||||
        expected_header = [
 | 
			
		||||
            "Tercero",
 | 
			
		||||
            "Dirección de facturación",
 | 
			
		||||
            "Dirección de envío",
 | 
			
		||||
            "Descripción",
 | 
			
		||||
            "Referencia",
 | 
			
		||||
            "Fecha venta",
 | 
			
		||||
            "Plazo de pago",
 | 
			
		||||
            "Almacén",
 | 
			
		||||
            "Moneda",
 | 
			
		||||
            "Líneas/Producto",
 | 
			
		||||
            "Líneas/Cantidad",
 | 
			
		||||
            "Líneas/Precio unitario",
 | 
			
		||||
            "Líneas/Unidad",
 | 
			
		||||
            "Empresa",
 | 
			
		||||
            "Tienda",
 | 
			
		||||
            "Terminal de venta",
 | 
			
		||||
            "Autorecogida",
 | 
			
		||||
            "Comentario"
 | 
			
		||||
        ]
 | 
			
		||||
        self.assertEqual(next(csv_reader), expected_header)
 | 
			
		||||
 | 
			
		||||
        expected_rows = [
 | 
			
		||||
            [self.customer.name, self.customer.name, self.customer.name, "",
 | 
			
		||||
             "", "2024-09-02 00:00:00+00:00", "Contado", "Almacén",
 | 
			
		||||
             "Peso colombiano", self.product.name, "2", "3000.00", "Unidad",
 | 
			
		||||
             "TIENDA LA ILUSIÓN", "Tienda La Ilusion", "La Ilusion", "True", ""
 | 
			
		||||
             ],
 | 
			
		||||
            ["", "", "", "", "", "", "", "", "", self.product.name, "3",
 | 
			
		||||
             "5000.00", "Unidad", "", "", "", "", ""
 | 
			
		||||
             ],
 | 
			
		||||
        ]
 | 
			
		||||
        rows = list(csv_reader)
 | 
			
		||||
        self.assertEqual(rows, expected_rows)
 | 
			
		||||
 | 
			
		||||
    def _create_sale(self):
 | 
			
		||||
        url = '/don_confiao/api/sales/'
 | 
			
		||||
        data = {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
import csv
 | 
			
		||||
 | 
			
		||||
from django.test import TestCase, Client
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from ..models import Sale, SaleLine, Product, Customer
 | 
			
		||||
 | 
			
		||||
class TestExportarVentasParaTryton(TestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        self.product = Product.objects.create(
 | 
			
		||||
            name='Panela',
 | 
			
		||||
            price=5000,
 | 
			
		||||
            measuring_unit='UNIT'
 | 
			
		||||
        )
 | 
			
		||||
        self.customer = Customer.objects.create(
 | 
			
		||||
            name='Camilo'
 | 
			
		||||
        )
 | 
			
		||||
        self.sale = Sale.objects.create(
 | 
			
		||||
            customer=self.customer,
 | 
			
		||||
            date='2024-09-02',
 | 
			
		||||
            payment_method='CASH',
 | 
			
		||||
        )
 | 
			
		||||
        self.sale_line1 = SaleLine.objects.create(
 | 
			
		||||
            product=self.product,
 | 
			
		||||
            quantity=2,
 | 
			
		||||
            unit_price=3000,
 | 
			
		||||
            sale=self.sale
 | 
			
		||||
        )
 | 
			
		||||
        self.sale_line2 = SaleLine.objects.create(
 | 
			
		||||
            product=self.product,
 | 
			
		||||
            quantity=3,
 | 
			
		||||
            unit_price=5000,
 | 
			
		||||
            sale=self.sale
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_exportar_ventas_para_tryton(self):
 | 
			
		||||
        client = Client()
 | 
			
		||||
        url = '/don_confiao/exportar_ventas_para_tryton'
 | 
			
		||||
        response = client.get(url)
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
        self.assertEqual(response['Content-Type'], 'text/csv')
 | 
			
		||||
        csv_content = response.content.decode('utf-8')
 | 
			
		||||
 | 
			
		||||
        expected_header = [
 | 
			
		||||
            "Tercero",
 | 
			
		||||
            "Dirección de facturación",
 | 
			
		||||
            "Dirección de envío",
 | 
			
		||||
            "Descripción",
 | 
			
		||||
            "Referencia",
 | 
			
		||||
            "Fecha venta",
 | 
			
		||||
            "Plazo de pago",
 | 
			
		||||
            "Almacén",
 | 
			
		||||
            "Moneda",
 | 
			
		||||
            "Líneas/Producto",
 | 
			
		||||
            "Líneas/Cantidad",
 | 
			
		||||
            "Líneas/Precio unitario",
 | 
			
		||||
            "Líneas/Unidad",
 | 
			
		||||
            "Empresa",
 | 
			
		||||
            "Tienda",
 | 
			
		||||
            "Terminal de venta",
 | 
			
		||||
            "Autorecogida",
 | 
			
		||||
            "Comentario"
 | 
			
		||||
        ]
 | 
			
		||||
        csv_reader = csv.reader(csv_content.splitlines())
 | 
			
		||||
        self.assertEqual(next(csv_reader), expected_header)
 | 
			
		||||
 | 
			
		||||
        expected_rows = [
 | 
			
		||||
            ["Camilo", "Camilo", "Camilo", "", "", "2024-09-02 00:00:00+00:00", "Contado", "Almacén", "Peso colombiano", "Panela", "2", "3000.00", "Unidad", "TIENDA LA ILUSIÓN", "Tienda La Ilusion", "La Ilusion", "True", ""],
 | 
			
		||||
            ["", "", "", "", "", "", "", "", "", "Panela", "3", "5000.00", "Unidad", "", "", "", "", ""],
 | 
			
		||||
        ]
 | 
			
		||||
        csv_rows = list(csv_reader)
 | 
			
		||||
        self.assertEqual(csv_rows[0], expected_rows[0])
 | 
			
		||||
        self.assertEqual(csv_rows[1], expected_rows[1])
 | 
			
		||||
@@ -30,5 +30,6 @@ urlpatterns = [
 | 
			
		||||
    path('purchases/for_reconciliation', api_views.SalesForReconciliationView.as_view(), name='sales_for_reconciliation'),
 | 
			
		||||
    path('reconciliate_jar', api_views.ReconciliateJarView.as_view()),
 | 
			
		||||
    path('api/admin_code/validate/<code>', api_views.AdminCodeValidateView.as_view()),
 | 
			
		||||
    path('api/sales/for_tryton', api_views.SalesForTrytonView.as_view()),
 | 
			
		||||
    path('api/', include(router.urls)),
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -163,8 +163,7 @@ def handle_import_customers_file(csv_file):
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def exportar_ventas_para_tryton(request):
 | 
			
		||||
def sales_to_tryton_csv(sales):
 | 
			
		||||
    tryton_sales_header = [
 | 
			
		||||
        "Tercero",
 | 
			
		||||
        "Dirección de facturación",
 | 
			
		||||
@@ -186,44 +185,50 @@ def exportar_ventas_para_tryton(request):
 | 
			
		||||
        "Comentario"
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    csv_data = [tryton_sales_header]
 | 
			
		||||
    for sale in sales:
 | 
			
		||||
        sale_lines = SaleLine.objects.filter(sale=sale.id)
 | 
			
		||||
        if not sale_lines:
 | 
			
		||||
            continue
 | 
			
		||||
        lines = []
 | 
			
		||||
        first_sale_line = sale_lines[0]
 | 
			
		||||
        customer_info = [sale.customer.name] * 3 + [sale.description] * 2
 | 
			
		||||
        first_line = customer_info + [
 | 
			
		||||
            sale.date,
 | 
			
		||||
            "Contado",
 | 
			
		||||
            "Almacén",
 | 
			
		||||
            "Peso colombiano",
 | 
			
		||||
            first_sale_line.product.name,
 | 
			
		||||
            first_sale_line.quantity,
 | 
			
		||||
            first_sale_line.unit_price,
 | 
			
		||||
            "Unidad",
 | 
			
		||||
            "TIENDA LA ILUSIÓN",
 | 
			
		||||
            "Tienda La Ilusion",
 | 
			
		||||
            "La Ilusion",
 | 
			
		||||
            True,
 | 
			
		||||
            sale.description]
 | 
			
		||||
        lines.append(first_line)
 | 
			
		||||
        for line in sale_lines[1:]:
 | 
			
		||||
            lines.append([""]*9+[
 | 
			
		||||
                line.product.name,
 | 
			
		||||
                line.quantity,
 | 
			
		||||
                line.unit_price,
 | 
			
		||||
                "Unidad"]+[""]*5)
 | 
			
		||||
        for row in lines:
 | 
			
		||||
            csv_data.append(row)
 | 
			
		||||
 | 
			
		||||
    return csv_data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def exportar_ventas_para_tryton(request):
 | 
			
		||||
    if request.method == "GET":
 | 
			
		||||
        response = HttpResponse(content_type='text/csv')
 | 
			
		||||
        response['Content-Disposition'] = "attachment; filename=sales.csv"
 | 
			
		||||
        writer = csv.writer(response)
 | 
			
		||||
        writer.writerow(tryton_sales_header)
 | 
			
		||||
 | 
			
		||||
        sales = Sale.objects.all()
 | 
			
		||||
 | 
			
		||||
        for sale in sales:
 | 
			
		||||
            sale_lines = SaleLine.objects.filter(sale=sale.id)
 | 
			
		||||
            if not sale_lines:
 | 
			
		||||
                continue
 | 
			
		||||
            lines = []
 | 
			
		||||
            first_sale_line = sale_lines[0]
 | 
			
		||||
            customer_info = [sale.customer.name] * 3 + [sale.description] * 2
 | 
			
		||||
            first_line = customer_info + [
 | 
			
		||||
                sale.date,
 | 
			
		||||
                "Contado",
 | 
			
		||||
                "Almacén",
 | 
			
		||||
                "Peso colombiano",
 | 
			
		||||
                first_sale_line.product.name,
 | 
			
		||||
                first_sale_line.quantity,
 | 
			
		||||
                "Unidad",
 | 
			
		||||
                first_sale_line.unit_price,
 | 
			
		||||
                "TIENDA LA ILUSIÓN",
 | 
			
		||||
                "Tienda La Ilusion",
 | 
			
		||||
                "La Ilusion",
 | 
			
		||||
                True,
 | 
			
		||||
                sale.description]
 | 
			
		||||
            lines.append(first_line)
 | 
			
		||||
            for line in sale_lines[1:]:
 | 
			
		||||
                lines.append([""]*9+[
 | 
			
		||||
                    line.product.name,
 | 
			
		||||
                    line.quantity,
 | 
			
		||||
                    line.unit_price,
 | 
			
		||||
                    "Unidad"]+[""]*5)
 | 
			
		||||
            for row in lines:
 | 
			
		||||
                writer.writerow(row)
 | 
			
		||||
        csv_data = sales_to_tryton_csv(sales)
 | 
			
		||||
        writer = csv.writer(response)
 | 
			
		||||
        for row in csv_data:
 | 
			
		||||
            writer.writerow(row)
 | 
			
		||||
 | 
			
		||||
        return response
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user