| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- from odoo import api, fields, models
- from odoo.exceptions import ValidationError
- import pandas as pd
- import os
- import base64
- class ImportLayput(models.TransientModel):
- _name = 'import.layout'
- _description = 'Importación de layout'
- _rec_name = "rule_id"
- rule_id = fields.Many2one(comodel_name="import.layout.rule", string="Plantilla")
- file_data = fields.Binary(string="Archivo")
- file_name = fields.Char(string="Nombre del archivo")
- company_id = fields.Many2one(comodel_name="res.company", string="Empresa", default=lambda self: self.env.company)
- def read_excel(self):
- # Validar la extensión
- self.extension_validator(self.file_name)
- # Validar que se cargue el modelo correspondiente al menú
- self.validate_model_id()
- # Lectura del excel
- data_decode = base64.b64decode(self.file_data)
- df = pd.read_excel(data_decode)
- group_line_id = self.rule_id.main_columns_ids.filtered(lambda line: line.group_by)
- df_group_by = df.groupby(group_line_id.name)
- move_ids = self.get_data(df_group_by)
- if move_ids:
- return {
- 'type': 'ir.actions.client',
- 'tag': 'display_notification',
- 'params': {
- 'type': 'success',
- 'message': (f'Se crearon los siguientes movimientos {move_ids}.'),
- 'next': {'type': 'ir.actions.act_window_close'},
- }
- }
- def validate_model_id(self):
- if self.env.context.get("sale_import") and self.sudo().rule_id.main_model_id.model not in ("sale.order", "purchase.order", "account.move"):
- raise ValidationError("Es necesario asignar una regla relacionada al modelo seleccionado")
- def extension_validator(self, file_name):
- name, extension = os.path.splitext(file_name)
- valid = True if str(extension).upper() == '.XLSX' or str(extension).upper() == '.XLS' else False
- if not valid:
- raise ValidationError(
- "La extensión del archivo no es valida con el formato de excel, esta debe ser .xlsx o xls")
- def get_data(self, df):
- try:
- main_name = []
- for ciudad, grupo in df:
- main_data = dict()
- data_list = []
- # Obtencion de los datos del cabecero
- for column in self.rule_id.main_columns_ids:
- value = self.get_field_info(column.field_id, grupo.loc[grupo.index[0], column.name])
- main_data[f"{column.field_id.name}"] = value
- # Creación del cabecero
- if main_data:
- main_id = self.env[self.rule_id.main_model_id.model].sudo().create(main_data)
- main_name.append(main_id.name)
- # Obtenciónd de los datos de las lineas de la orden
- for line_index in range(grupo.shape[0]):
- data = {}
- for column in self.rule_id.column_ids:
- value = self.get_field_info(column.field_id,
- grupo.loc[grupo.index[line_index], column.name])
- data[f"{column.field_id.name}"] = value
- main_field = self.env[self.rule_id.model_id.model].fields_get()
- related_field = next((campo for campo, datos in main_field.items() if
- datos.get('relation') == f'{self.rule_id.main_model_id.model}'), None)
- # Relación de las lineas con su llave primaria
- data[f"{related_field}"] = main_id.id
- if data:
- data_list.append(data)
- # Creación de las lineas de las ordenes
- if data_list:
- line_ids = self.env[self.rule_id.model_id.model].sudo().create(data_list)
- return main_name if main_name else False
- except Exception as e:
- raise ValidationError(
- f"Hay algun problema con la configuración de la regla, posiblemente el nombre de las columnas no coincidan con el archivo, como por ejemplo: {e}")
- # Obtener los valores de los campos dependiendo del tipo de campo
- def get_field_info(self, field_id, value):
- if field_id.ttype in ["many2one", "many2one_reference"]:
- if str(value).isnumeric():
- if len(str(value)) <= 9:
- field_value = self.env[field_id.relation].sudo().search([("id", "=", int(value))], limit=1)
- else:
- field_value = False
- if not field_value and field_id.relation in ['product.product', 'product.template']:
- field_value = self.env[field_id.relation].sudo().search(["|",("default_code", "=", value),("barcode","=",value)], limit=1)
- if not field_value:
- raise ValidationError(
- f"No se encontro un registro en el modelo de {field_id.relation} con el id {value}")
- elif not field_value:
- raise ValidationError(
- f"No se encontro un registro en el modelo de {field_id.relation} con el código {value}")
- value = field_value.id
- elif field_id.relation in ['product.product', 'product.template']:
- field_value = self.env[field_id.relation].sudo().search(["|",("default_code", "=", value),("barcode","=",value)], limit=1)
- if not field_value:
- field_value = self.env[field_id.relation].sudo().search([("name", "=", value)], limit=1)
- if not field_value:
- raise ValidationError(
- f"No se encontro un registro en el modelo de {field_id.relation} con el código {value}")
- value = field_value.id
- else:
- field_value = self.env[field_id.relation].sudo().search([("name", "=", value)], limit=1)
- if not field_value:
- raise ValidationError(
- f"No se encontro un registro en el modelo de {field_id.relation} con el nombre {value}")
- value = field_value.id
- return value
|