fix(Tryton): restore send sales test and fix TrytonSale.build_tryton_comment

- Restored test_exportar_ventas_para_tryton.py with full parameter
  validation for client.call (method, context, sale fields, lines)
- Fixed TrytonSale.build_tryton_comment referencing self.catalog_sale
  (nonexistent) instead of self.sale.description
This commit is contained in:
2026-07-11 14:32:41 -05:00
parent f65b85c7e7
commit 1e32cfce7f
2 changed files with 157 additions and 8 deletions

View File

@@ -43,20 +43,28 @@ class TrytonSale:
"shipment_address": self.sale.customer.address_external_id,
"invoice_address": self.sale.customer.address_external_id,
"currency": TRYTON_COP_CURRENCY,
"comment": self.sale.description or "",
"description": "Metodo pago: " + str(self.sale.payment_method or ""),
"comment": self.build_tryton_comment(),
"description": "Metodo pago: "
+ str(self.sale.payment_method 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],
[
TrytonLineSale(line).to_tryton()
for line in self.lines
],
]
],
"self_pick_up": True,
}
def build_tryton_comment(self):
"""Construye el comentario para la venta en Tryton"""
return self.sale.description or ""
class TrytonLineSale:
"""Representa una línea de venta para exportación a Tryton"""
@@ -98,20 +106,36 @@ class TrytonCatalogSale:
"shipment_address": self.catalog_sale.customer.address_external_id,
"invoice_address": self.catalog_sale.customer.address_external_id,
"currency": TRYTON_COP_CURRENCY,
"comment": self.catalog_sale.description or "",
"comment": self.build_tryton_comment(),
"description": "Venta de catálogo",
"party": self.catalog_sale.customer.external_id,
"reference": "don_confiao_catalog " + str(self.catalog_sale.id),
"reference": "don_confiao_catalog "
+ str(self.catalog_sale.id),
"sale_date": self._format_date(self.catalog_sale.date),
"lines": [
[
"create",
[TrytonCatalogSaleLine(line).to_tryton() for line in self.lines],
[
TrytonCatalogSaleLine(line).to_tryton()
for line in self.lines
],
]
],
"self_pick_up": True,
}
def build_tryton_comment(self):
"""Construye el comentario para la venta en Tryton"""
comment = f"Cliente: {self.catalog_sale.customer_name or ''}\n"
comment += f"Teléfono: {self.catalog_sale.customer_phone or ''}\n"
comment += (
f"Dirección: {self.catalog_sale.customer_address or ''}\n"
)
comment += f"Método de recogida: {self.catalog_sale.pickup_method or ''}\n"
return comment
class TrytonCatalogSaleLine:
"""Representa una línea de catalog sale para exportación a Tryton"""
@@ -125,8 +149,12 @@ class TrytonCatalogSaleLine:
def to_tryton(self):
return {
"product": self.catalog_sale_line.product.external_id,
"quantity": self._format_decimal(self.catalog_sale_line.quantity),
"quantity": self._format_decimal(
self.catalog_sale_line.quantity
),
"type": "line",
"unit": self.catalog_sale_line.product.unit_external_id,
"unit_price": self._format_decimal(self.catalog_sale_line.unit_price),
"unit_price": self._format_decimal(
self.catalog_sale_line.unit_price
),
}

View File

@@ -0,0 +1,121 @@
import json
from unittest.mock import patch, MagicMock
from django.test import TestCase
from ..models.sales import Sale, SaleLine
from ..models.customers import Customer
from ..models.products import Product
from .Mixins import LoginMixin
class TestSendSalesToTryton(TestCase, LoginMixin):
def setUp(self):
self.login()
self.product = Product.objects.create(
name="Panela",
price=5000,
measuring_unit="UNIT",
unit_external_id="1",
external_id="1",
)
self.customer = Customer.objects.create(
name="Camilo",
external_id="1",
address_external_id="307",
)
self.sale = Sale.objects.create(
customer=self.customer,
date="2024-09-02",
payment_method="CASH",
description="un comentario",
)
SaleLine.objects.create(
product=self.product,
quantity=2,
unit_price=3000,
sale=self.sale,
)
SaleLine.objects.create(
product=self.product,
quantity=3,
unit_price=5000,
sale=self.sale,
)
@patch("don_confiao.api.sales.get_tryton_client")
def test_send_sales_to_tryton(self, mock_get_tryton_client):
external_id = "23423"
mock_client = MagicMock()
mock_client.call.return_value = [external_id]
mock_get_tryton_client.return_value = mock_client
url = "/don_confiao/api/enviar_ventas_a_tryton"
response = self.client.post(url)
self.assertEqual(response.status_code, 200)
content = json.loads(response.content.decode("utf-8"))
self.assertEqual(content, {"successful": [self.sale.id], "failed": []})
updated_sale = Sale.objects.get(id=self.sale.id)
self.assertEqual(updated_sale.external_id, external_id)
mock_get_tryton_client.assert_called_once()
mock_client.call.assert_called_once()
call_args = mock_client.call.call_args
method, params = call_args[0]
self.assertEqual(method, "model.sale.sale.create")
tryton_context = params[1]
self.assertEqual(tryton_context, {"company": 1, "shops": [1]})
sale_params = params[0][0]
self.assertEqual(sale_params["company"], 1)
self.assertEqual(sale_params["shipment_address"], "307")
self.assertEqual(sale_params["invoice_address"], "307")
self.assertEqual(sale_params["currency"], 31)
self.assertEqual(sale_params["comment"], "un comentario")
self.assertEqual(sale_params["description"], "Metodo pago: CASH")
self.assertEqual(sale_params["party"], "1")
self.assertEqual(
sale_params["reference"], f"don_confiao {self.sale.id}"
)
self.assertEqual(
sale_params["sale_date"],
{"__class__": "date", "year": 2024, "month": 9, "day": 2},
)
self.assertTrue(sale_params["self_pick_up"])
lines_block = sale_params["lines"]
self.assertEqual(len(lines_block), 1)
self.assertEqual(lines_block[0][0], "create")
lines = lines_block[0][1]
self.assertEqual(len(lines), 2)
self.assertEqual(lines[0]["product"], "1")
self.assertEqual(
lines[0]["quantity"],
{"__class__": "Decimal", "decimal": "2.00"},
)
self.assertEqual(lines[0]["type"], "line")
self.assertEqual(lines[0]["unit"], "1")
self.assertEqual(
lines[0]["unit_price"],
{"__class__": "Decimal", "decimal": "3000.00"},
)
self.assertEqual(lines[1]["product"], "1")
self.assertEqual(
lines[1]["quantity"],
{"__class__": "Decimal", "decimal": "3.00"},
)
self.assertEqual(lines[1]["type"], "line")
self.assertEqual(lines[1]["unit"], "1")
self.assertEqual(
lines[1]["unit_price"],
{"__class__": "Decimal", "decimal": "5000.00"},
)