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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user