#9 feat(Tryton): create products from tryton.
This commit is contained in:
		| @@ -249,3 +249,77 @@ class TrytonLineSale: | ||||
|             "unit": self.sale_line.product.unit_external_id, | ||||
|             "unit_price": self._format_decimal(self.sale_line.unit_price) | ||||
|         } | ||||
|  | ||||
|  | ||||
| class ProductsFromTrytonView(APIView): | ||||
|     def post(self, request): | ||||
|         tryton_client = Client( | ||||
|             hostname=TRYTON_HOST, | ||||
|             database=TRYTON_DATABASE, | ||||
|             username=TRYTON_USERNAME, | ||||
|             password=TRYTON_PASSWORD | ||||
|         ) | ||||
|         tryton_client.connect() | ||||
|         method = 'model.product.product.search' | ||||
|         context = {'company': 1} | ||||
|         params = [[], 0, 1000, [["rec_name", "ASC"], ["id", None]], context] | ||||
|         product_ids = tryton_client.call(method, params) | ||||
|         tryton_products = self.__get_product_datails_from_tryton( | ||||
|             product_ids, tryton_client, context | ||||
|         ) | ||||
|         checked_tryton_products = product_ids | ||||
|         failed_products = [] | ||||
|         updated_products = [] | ||||
|         created_products = [] | ||||
|         untouched_products = [] | ||||
|  | ||||
|         for tryton_product in tryton_products: | ||||
|             try: | ||||
|                 product = Product.objects.get( | ||||
|                     external_id=tryton_product.get('id') | ||||
|                 ) | ||||
|             except Product.DoesNotExist: | ||||
|                 product = self.__create_product(tryton_product) | ||||
|                 created_products.append(product.id) | ||||
|                 continue | ||||
|             if self.__need_update(product, tryton_product): | ||||
|                 self.update_product(product, tryton_product) | ||||
|                 updated_products.append(product.id) | ||||
|             else: | ||||
|                 untouched_products.append(product.id) | ||||
|  | ||||
|         return Response( | ||||
|             { | ||||
|                 'checked_tryton_products': checked_tryton_products, | ||||
|                 'failed_products': failed_products, | ||||
|                 'updated_products': updated_products, | ||||
|                 'created_products': created_products, | ||||
|                 'untouched_products': untouched_products, | ||||
|             }, | ||||
|             status=200 | ||||
|         ) | ||||
|  | ||||
|     def __get_product_datails_from_tryton(self, product_ids, tryton_client, context): | ||||
|         tryton_fields = ['id', 'name', 'default_uom.id', | ||||
|                          'default_uom.rec_name', 'list_price'] | ||||
|         method = 'model.product.product.read' | ||||
|         params = (product_ids, tryton_fields, context) | ||||
|         response = tryton_client.call(method, params) | ||||
|         return response | ||||
|  | ||||
|     def __need_update(self, product, tryton_product): | ||||
|         if not product.name == tryton_product.get('name'): | ||||
|             return True | ||||
|         if not product.price == tryton_product.get('price'): | ||||
|             return True | ||||
|  | ||||
|     def __create_product(self, tryton_product): | ||||
|         product = Product() | ||||
|         product.name = tryton_product.get('name') | ||||
|         product.price = tryton_product.get('list_price') | ||||
|         product.external_id = tryton_product.get('id') | ||||
|         unit = tryton_product.get('default_uom.') | ||||
|         product.measuring_unit = unit.get('rec_name') | ||||
|         product.unit_external_id = unit.get('id') | ||||
|         product.save() | ||||
|         return product | ||||
|   | ||||
| @@ -0,0 +1,57 @@ | ||||
| import json | ||||
| from decimal import Decimal | ||||
| from unittest.mock import patch | ||||
|  | ||||
| from django.test import Client, TestCase | ||||
| from ..models import ProductCategory, Product | ||||
|  | ||||
|  | ||||
| class TestProductsFromTryton(TestCase): | ||||
|     def setUp(self): | ||||
|         self.client = Client() | ||||
|  | ||||
|     @patch('sabatron_tryton_rpc_client.client.Client.call') | ||||
|     @patch('sabatron_tryton_rpc_client.client.Client.connect') | ||||
|     def test_import_products(self, mock_connect, mock_call): | ||||
|         mock_connect.return_value = None | ||||
|  | ||||
|         def fake_call(*args, **kwargs): | ||||
|             product_search = 'model.product.product.search' | ||||
|             search_args = [[], 0, 1000, [['rec_name', 'ASC'], ['id', None]], {'company': 1}] | ||||
|             if (args == (product_search, search_args)): | ||||
|                 return [190] | ||||
|  | ||||
|             product_read = 'model.product.product.read' | ||||
|             product_args = ([190], | ||||
|                             ['id', 'name', 'default_uom.id', | ||||
|                              'default_uom.rec_name', 'list_price'], | ||||
|                             {'company': 1} | ||||
|                             ) | ||||
|             if (args == (product_read, product_args)): | ||||
|                 return [{'id': 190, 'list_price': Decimal('25000'), | ||||
|                          'name': 'Producto 1', | ||||
|                          'default_uom.': {'id': 1, 'rec_name': 'Unit'}}] | ||||
|  | ||||
|             raise Exception(f"Sorry, args non expected on  this test: {args}") | ||||
|  | ||||
|         mock_call.side_effect = fake_call | ||||
|  | ||||
|         url = '/don_confiao/api/importar_productos_de_tryton' | ||||
|         response = self.client.post(url) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|         content = json.loads(response.content.decode('utf-8')) | ||||
|         expected_response = { | ||||
|             'checked_tryton_products': [190], | ||||
|             'created_products': [1], | ||||
|             'untouched_products': [], | ||||
|             'failed_products': [], | ||||
|             'updated_products': [] | ||||
|         } | ||||
|         self.assertEqual(content, expected_response) | ||||
|  | ||||
|         created_product = Product.objects.get(id=1) | ||||
|         self.assertEqual(created_product.external_id, str(190)) | ||||
|         self.assertEqual(created_product.name, 'Producto 1') | ||||
|         self.assertEqual(created_product.price, Decimal('25000')) | ||||
|         self.assertEqual(created_product.measuring_unit, 'Unit') | ||||
| @@ -20,6 +20,9 @@ urlpatterns = [ | ||||
|     path("productos", views.products, name="products"), | ||||
|     path("lista_productos", views.ProductListView.as_view(), name='product_list'), | ||||
|     path("importar_productos", views.import_products, name="import_products"), | ||||
|     path('api/importar_productos_de_tryton', | ||||
|          api_views.ProductsFromTrytonView.as_view(), | ||||
|          name="products_from_tryton"), | ||||
|     path("importar_terceros", views.import_customers, name="import_customers"), | ||||
|     path("exportar_ventas_para_tryton", | ||||
|          views.exportar_ventas_para_tryton, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user