#9 feat(Tryton): enviar_ventas_a_tryton
This commit is contained in:
		| @@ -9,6 +9,7 @@ from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, | ||||
| from .views import sales_to_tryton_csv | ||||
|  | ||||
| from decimal import Decimal | ||||
| from sabatron_tryton_rpc_client.client import Client | ||||
| import io | ||||
| import csv | ||||
|  | ||||
| @@ -164,3 +165,79 @@ class SalesForTrytonView(APIView): | ||||
|         for row in csv_data: | ||||
|             writer.writerow(row) | ||||
|         return output.getvalue() | ||||
|  | ||||
|  | ||||
| class SalesToTrytonView(APIView): | ||||
|     def post(self, request): | ||||
|         tryton_client = Client( | ||||
|             hostname='localhost', | ||||
|             database='tryton', | ||||
|             username='admin', | ||||
|             password='admin' | ||||
|         ) | ||||
|         tryton_client.connect() | ||||
|         method = 'model.sale.sale.create' | ||||
|         tryton_context = {} | ||||
|  | ||||
|         successful = [] | ||||
|         failed = [] | ||||
|  | ||||
|         sales = Sale.objects.filter(external_id=None) | ||||
|         for sale in sales: | ||||
|             lines = SaleLine.objects.filter(sale=sale.id) | ||||
|             tryton_params = self.__to_tryton_params(sale, lines, tryton_context) | ||||
|             external_ids = tryton_client.call(method, tryton_params) | ||||
|             sale.external_id = external_ids[0] | ||||
|             sale.save() | ||||
|             successful.append(sale.id) | ||||
|  | ||||
|         return Response( | ||||
|             {'successful': successful, 'failed': failed}, | ||||
|             status=200 | ||||
|         ) | ||||
|  | ||||
|     def __to_tryton_params(self, sale, lines, tryton_context): | ||||
|         sale_tryton = TrytonSale(sale, lines) | ||||
|         return [[sale_tryton.to_tryton()], tryton_context] | ||||
|  | ||||
|  | ||||
| class TrytonSale: | ||||
|  | ||||
|     def __init__(self, sale, lines): | ||||
|         self.sale = sale | ||||
|         self.lines = lines | ||||
|  | ||||
|     def _format_date(self, _date): | ||||
|         return {"__class__": "date", "year": _date.year, "month": _date.month, | ||||
|                 "day": _date.day} | ||||
|  | ||||
|     def to_tryton(self): | ||||
|         return { | ||||
|             "company": 1, | ||||
|             "currency": 1, | ||||
|             "description": self.sale.description or '', | ||||
|             "party": self.sale.customer.external_id, | ||||
|             "reference": "don_confiao " + str(self.sale.id), | ||||
|             "sale_date": self._format_date(self.sale.date), | ||||
|             "lines": [[ | ||||
|                 "create", | ||||
|                 [TrytonLineSale(line).to_tryton() for line in self.lines] | ||||
|             ]] | ||||
|         } | ||||
|  | ||||
|  | ||||
| class TrytonLineSale: | ||||
|     def __init__(self, sale_line): | ||||
|         self.sale_line = sale_line | ||||
|  | ||||
|     def _format_decimal(self, number): | ||||
|         return {"__class__": "Decimal", "decimal": str(number)} | ||||
|  | ||||
|     def to_tryton(self): | ||||
|         return { | ||||
|             "product": self.sale_line.product.external_id, | ||||
|             "quantity": self._format_decimal(self.sale_line.quantity), | ||||
|             "type": "line", | ||||
|             "unit": self.sale_line.product.unit_external_id, | ||||
|             "unit_price": self._format_decimal(self.sale_line.unit_price) | ||||
|         } | ||||
|   | ||||
| @@ -1,4 +1,6 @@ | ||||
| import csv | ||||
| import json | ||||
| from unittest.mock import patch | ||||
|  | ||||
| from django.test import TestCase, Client | ||||
| from django.urls import reverse | ||||
| @@ -10,10 +12,13 @@ class TestExportarVentasParaTryton(TestCase): | ||||
|         self.product = Product.objects.create( | ||||
|             name='Panela', | ||||
|             price=5000, | ||||
|             measuring_unit='UNIT' | ||||
|             measuring_unit='UNIT', | ||||
|             unit_external_id=1, | ||||
|             external_id=1 | ||||
|         ) | ||||
|         self.customer = Customer.objects.create( | ||||
|             name='Camilo' | ||||
|             name='Camilo', | ||||
|             external_id=1 | ||||
|         ) | ||||
|         self.sale = Sale.objects.create( | ||||
|             customer=self.customer, | ||||
| @@ -71,3 +76,27 @@ class TestExportarVentasParaTryton(TestCase): | ||||
|         csv_rows = list(csv_reader) | ||||
|         self.assertEqual(csv_rows[0], expected_rows[0]) | ||||
|         self.assertEqual(csv_rows[1], expected_rows[1]) | ||||
|  | ||||
|     @patch('sabatron_tryton_rpc_client.client.Client.call') | ||||
|     @patch('sabatron_tryton_rpc_client.client.Client.connect') | ||||
|     def test_send_sales_to_tryton(self, mock_connect, mock_call): | ||||
|         client = Client() | ||||
|         external_id = '23423' | ||||
|         url = '/don_confiao/api/enviar_ventas_a_tryton' | ||||
|         mock_connect.return_value = None | ||||
|         mock_call.return_value = [external_id] | ||||
|         response = client.post(url) | ||||
|  | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         content = json.loads(response.content.decode('utf-8')) | ||||
|         expected_response = { | ||||
|             'successful': [self.sale.id], | ||||
|             'failed': [], | ||||
|         } | ||||
|         self.assertEqual(content, expected_response) | ||||
|  | ||||
|         updated_sale = Sale.objects.get(id=self.sale.id) | ||||
|         self.assertEqual(updated_sale.external_id, external_id) | ||||
|         mock_connect.assert_called_once() | ||||
|         mock_call.assert_called_once() | ||||
|         mock_call.assert_called_with('model.sale.sale.create', [[{'company': 1, 'currency': 1, 'description': '', 'party': '1', 'reference': 'don_confiao 1', 'sale_date': {'__class__': 'date', 'year': 2024, 'month': 9, 'day': 2}, 'lines': [['create', [{'product': '1', 'quantity': {'__class__': 'Decimal', 'decimal': '2.00'}, 'type': 'line', 'unit': '1', 'unit_price': {'__class__': 'Decimal', 'decimal': '3000.00'}}, {'product': '1', 'quantity': {'__class__': 'Decimal', 'decimal': '3.00'}, 'type': 'line', 'unit': '1', 'unit_price': {'__class__': 'Decimal', 'decimal': '5000.00'}}]]]}], {}]) | ||||
|   | ||||
| @@ -24,6 +24,7 @@ urlpatterns = [ | ||||
|     path("exportar_ventas_para_tryton", | ||||
|          views.exportar_ventas_para_tryton, | ||||
|          name="exportar_ventas_para_tryton"), | ||||
|     path('api/enviar_ventas_a_tryton', api_views.SalesToTrytonView.as_view(), name="send_tryton"), | ||||
|     path("resumen_compra/<int:id>", views.purchase_summary, name="purchase_summary"), | ||||
|     path("resumen_compra_json/<int:id>", api_views.SaleSummary.as_view(), name="purchase_json_summary"), | ||||
|     path("payment_methods/all/select_format", api_views.PaymentMethodView.as_view(), name="payment_methods_to_select"), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user