mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
497 lines
18 KiB
PHP
497 lines
18 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Importadores;
|
|
|
|
use App\Controllers\BaseResourceController;
|
|
use App\Controllers\Presupuestos\Presupuestocliente;
|
|
use App\Models\Presupuestos\PresupuestoModel;
|
|
use App\Services\PresupuestoService;
|
|
|
|
class ImportadorBubok extends BaseResourceController
|
|
{
|
|
|
|
protected $format = 'json';
|
|
|
|
protected static $singularObjectName = 'Importador';
|
|
protected static $singularObjectNameCc = 'ImportadorBubok';
|
|
protected static $pluralObjectName = 'Importadores';
|
|
protected static $pluralObjectNameCc = 'importadores';
|
|
|
|
protected static $controllerSlug = 'importador';
|
|
|
|
protected static $viewPath = 'themes/vuexy/form/importador/bubok/';
|
|
|
|
protected $indexRoute = 'ImportadorBubokTool';
|
|
|
|
|
|
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
|
{
|
|
$this->viewData['pageTitle'] = lang('Importador.listingPage');
|
|
$this->viewData['usingSweetAlert'] = true;
|
|
|
|
// Breadcrumbs (IMN)
|
|
$this->viewData['breadcrumb'] = [
|
|
['title' => lang("App.menu_importadores"), 'route' => "javascript:void(0);", 'active' => false],
|
|
['title' => lang("App.menu_importadores_bubok"), 'route' => route_to('importadorBubokTool'), 'active' => true]
|
|
];
|
|
|
|
parent::initController($request, $response, $logger);
|
|
}
|
|
|
|
|
|
public function index()
|
|
{
|
|
checkPermission('importadores.bubok');
|
|
|
|
$viewData = [
|
|
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
|
|
|
|
];
|
|
|
|
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
|
|
|
|
return view(static::$viewPath . 'viewImportadorBubokTool', $viewData);
|
|
}
|
|
|
|
public function validarFila()
|
|
{
|
|
checkPermission('importadores.bubok');
|
|
|
|
$json = $this->request->getJSON();
|
|
|
|
if (!$json || empty($json->producto) || empty($json->pedido)) {
|
|
return $this->response->setJSON([
|
|
'apto' => false,
|
|
'reason' => 'Datos incompletos'
|
|
]);
|
|
}
|
|
|
|
$producto = $json->producto;
|
|
$pedido = $json->pedido;
|
|
|
|
// Validar existencia de ID de producto
|
|
if (empty($producto->id)) {
|
|
return $this->response->setJSON([
|
|
'apto' => false,
|
|
'reason' => 'ID de producto no proporcionado'
|
|
]);
|
|
}
|
|
|
|
$refCliente = $pedido->orderNumber . '-' . $producto->id;
|
|
|
|
// Validar formato Ref. Cliente
|
|
if (strpos($refCliente, '-') === false || strlen($refCliente) < 5) {
|
|
return $this->response->setJSON([
|
|
'apto' => false,
|
|
'reason' => 'Ref. cliente inválido'
|
|
]);
|
|
}
|
|
|
|
// 1. Verificar si ya fue importado
|
|
$presupuestoModel = new PresupuestoModel();
|
|
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
|
|
|
|
if ($yaExiste) {
|
|
return $this->response->setJSON([
|
|
'apto' => false,
|
|
'reason' => 'Referencia ya importada'
|
|
]);
|
|
}
|
|
|
|
// 2. Validación básica del producto (puedes expandir con más reglas si lo necesitas)
|
|
$errores = [];
|
|
|
|
if (empty($producto->title))
|
|
$errores[] = 'Falta título';
|
|
if (empty($producto->body->pages))
|
|
$errores[] = 'Faltan páginas';
|
|
if (empty($producto->amount))
|
|
$errores[] = 'Falta tirada';
|
|
|
|
if (!empty($errores)) {
|
|
return $this->response->setJSON([
|
|
'apto' => false,
|
|
'reason' => implode(', ', $errores)
|
|
]);
|
|
}
|
|
|
|
// 3. Producto considerado apto
|
|
return $this->response->setJSON([
|
|
'apto' => true
|
|
]);
|
|
}
|
|
|
|
|
|
|
|
public function importarFila()
|
|
{
|
|
|
|
checkPermission('importadores.bubok');
|
|
|
|
$json = $this->request->getJSON();
|
|
|
|
// Validación mínima de datos comunes
|
|
$pedido = $json->pedido ?? null;
|
|
if (!$pedido || !isset($pedido->orderNumber)) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Datos comunes del pedido ausentes o inválidos.'
|
|
]);
|
|
}
|
|
|
|
// Validación mínima de existencia del producto en la linea
|
|
if (!$json || !isset($json->producto)) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Producto no proporcionado o inválido.'
|
|
]);
|
|
}
|
|
$producto = $json->producto;
|
|
|
|
// 1. Datos básicos:
|
|
// Referencia del cliente
|
|
$orderNumber = $pedido->orderNumber ?? null;
|
|
$productId = $producto->id ?? null;
|
|
if (is_null($orderNumber) || is_null($productId)) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Número de orden o ID del producto no reconocidos.'
|
|
]);
|
|
}
|
|
$refCliente = "$orderNumber-$productId";
|
|
|
|
// Titulo
|
|
$titulo = $producto->title ?? null;
|
|
if (is_null($titulo)) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Título del libro no reconocido.'
|
|
]);
|
|
}
|
|
|
|
// Validación de páginas y tirada
|
|
$paginas = isset($producto->body->pages) ? (int) $producto->body->pages : 0;
|
|
$tirada = isset($producto->amount) ? (int) $producto->amount : 0;
|
|
if ($paginas <= 0 || $tirada <= 0) {
|
|
$errores = [];
|
|
if ($paginas <= 0) {
|
|
$errores[] = 'Número de páginas inválido.';
|
|
}
|
|
if ($tirada <= 0) {
|
|
$errores[] = 'Tirada inválida.';
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => implode(' ', $errores)
|
|
]);
|
|
}
|
|
|
|
// Ancho y alto
|
|
$ancho = null;
|
|
$alto = null;
|
|
foreach ($producto->size as $key => $val) {
|
|
if ($val == 1) {
|
|
// ejemplo: size170x235
|
|
$size = str_replace('size', '', $key);
|
|
[$ancho, $alto] = explode('x', $size);
|
|
$ancho = (int) $ancho;
|
|
$alto = (int) $alto;
|
|
break;
|
|
}
|
|
}
|
|
if (!$ancho || !$alto) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Tamaño del libro no reconocido.'
|
|
]);
|
|
}
|
|
|
|
/*$numGuardaPages = 4;
|
|
$hasGuarda = !empty($producto->cover->guarda);
|
|
if ($hasGuarda)
|
|
$paginas += $numGuardaPages;*/
|
|
|
|
// 2. Interior: color o negro
|
|
// Determinar tipo de impresión interior
|
|
$interiorTipo = null;
|
|
if (isset($producto->body->color->CMYK) && $producto->body->color->CMYK == '1') {
|
|
$interiorTipo = 'color';
|
|
} elseif (isset($producto->body->color->Monochrome) && $producto->body->color->Monochrome == '1') {
|
|
$interiorTipo = 'negro';
|
|
} elseif (isset($producto->body->color->Semicolor) && $producto->body->color->Semicolor == '1') {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Tipo de impresión "Semicolor" no soportado.'
|
|
]);
|
|
}
|
|
|
|
if (is_null($interiorTipo)) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'No se pudo determinar si el interior es en color o blanco y negro.'
|
|
]);
|
|
}
|
|
|
|
// Determinar tipo de papel interior
|
|
$papelInteriorId = null;
|
|
if (isset($producto->body->paperColor->white) && $producto->body->paperColor->white == '1') {
|
|
$papelInteriorId = 3; // Offset blanco 'OFF1'
|
|
} elseif (isset($producto->body->paperColor->cream) && $producto->body->paperColor->cream == '1') {
|
|
$papelInteriorId = 4; // Offset ahuesado 'OFF2'
|
|
} else {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Tipo de papel interior no definido.'
|
|
]);
|
|
}
|
|
|
|
// Determinar el gramaje del papel
|
|
$gramajePapelInterior = null;
|
|
foreach ($producto->body->paperWeight as $key => $val) {
|
|
if ($val == 1) {
|
|
$gramajePapelInterior = (int) str_replace(['weight', 'gr'], '', $key);
|
|
break;
|
|
}
|
|
}
|
|
if (!$gramajePapelInterior) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Gramaje del papel no válido.'
|
|
]);
|
|
}
|
|
|
|
// 3. Encuadernación
|
|
// Tapa dura
|
|
$tapaDura = isset($producto->cover->type->tapadura) && $producto->cover->type->tapadura == '1';
|
|
|
|
// Solapas
|
|
$solapas = isset($producto->cover->type->consolapas) && $producto->cover->type->consolapas == '1';
|
|
|
|
// Doble cara (a veces se activa con tapa dura) una cara => 2; dos caras => 4
|
|
$doscara = false;
|
|
|
|
// Tipo de encuadernado
|
|
$encuadernadoId = null;
|
|
|
|
if (isset($producto->cover->coverType->SoftCover) && $producto->cover->coverType->SoftCover == '1') {
|
|
if ($tapaDura) {
|
|
$encuadernadoId = 1; // Libro fresado tapa dura
|
|
$doscara = true;
|
|
} else {
|
|
$encuadernadoId = 2; // Libro fresado tapa blanda
|
|
}
|
|
} elseif (isset($producto->cover->coverType->SaddleStitch) && $producto->cover->coverType->SaddleStitch == '1') {
|
|
if ($tapaDura) {
|
|
$encuadernadoId = 3; // Libro cosido tapa dura
|
|
$doscara = true;
|
|
} else {
|
|
$encuadernadoId = $solapas ? 20 : 4; // Libro cosido tapa blanda (solapas) : (sin solapas)
|
|
}
|
|
} elseif (isset($producto->cover->coverType->CoilBinding) && $producto->cover->coverType->CoilBinding == '1') {
|
|
if ($tapaDura) {
|
|
$encuadernadoId = 5; // Libro espiral tapa dura
|
|
$doscara = true;
|
|
} else {
|
|
$encuadernadoId = 6; // Libro espiral tapa blanda
|
|
}
|
|
}
|
|
if (!$encuadernadoId) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Tipo de encuadernación no identificado.'
|
|
]);
|
|
}
|
|
|
|
// Determinar el acabado de la cubierta
|
|
$acabadoId = null;
|
|
if (isset($producto->cover->acabado->brillo) && $producto->cover->acabado->brillo == '1') {
|
|
$acabadoId = 1; // Plastificado brillo 1/c
|
|
} elseif (isset($producto->cover->acabado->mate) && $producto->cover->acabado->mate == '1') {
|
|
$acabadoId = 2; // Plastificado mate 1/c
|
|
} else {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'Tipo de acabado de cubierta no definido.'
|
|
]);
|
|
}
|
|
|
|
// 4. ENVÍO: recuperamos la primera dirección del cliente BUBOK (ID 40)
|
|
$clienteDireccionModel = model('App\Models\Clientes\ClienteDireccionesModel');
|
|
$direccionCliente = $clienteDireccionModel
|
|
->where('cliente_id', 40)
|
|
->orderBy('id', 'asc')
|
|
->first();
|
|
|
|
if (!$direccionCliente) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'message' => 'El cliente Bubok no tiene direcciones asociadas.'
|
|
]);
|
|
}
|
|
|
|
$direcciones = [
|
|
[
|
|
'direccion' => [
|
|
'id' => (int) $direccionCliente->id,
|
|
'cliente_id' => (int) $direccionCliente->cliente_id,
|
|
'cliente_nombre' => $direccionCliente->clienteNombre,
|
|
'att' => $direccionCliente->persona_contacto ?? '',
|
|
'alias' => $direccionCliente->alias ?? '',
|
|
'email' => $direccionCliente->email ?? '',
|
|
'direccion' => $direccionCliente->direccion,
|
|
'pais_id' => (int) $direccionCliente->pais_id,
|
|
'pais' => $direccionCliente->paisNombre,
|
|
'municipio' => $direccionCliente->municipio,
|
|
'provincia' => $direccionCliente->provincia,
|
|
'cp' => $direccionCliente->cp,
|
|
'telefono' => $direccionCliente->telefono,
|
|
],
|
|
'unidades' => $tirada,
|
|
'entregaPalets' => false
|
|
]
|
|
];
|
|
|
|
// Recalcular calidad (isColor y isHq) en funcion del cliente
|
|
[$isColor, $isHq] = PresupuestoService::getCalidad(
|
|
'importador-bubok',
|
|
null,
|
|
((trim(strtolower($interiorTipo)) === 'color') ? 1 : 0),
|
|
0,
|
|
intval($tirada ?? 0)
|
|
);
|
|
|
|
// Generamos el objeto a importar
|
|
$dataToImport = [
|
|
'selectedTirada' => $tirada,
|
|
'datosCabecera' => [
|
|
'titulo' => $titulo,
|
|
'autor' => null,
|
|
'isbn' => null,
|
|
'coleccion' => null,
|
|
'referenciaCliente' => $refCliente
|
|
],
|
|
'tirada' => [$tirada],
|
|
'tamanio' => [
|
|
'ancho' => $ancho,
|
|
'alto' => $alto
|
|
],
|
|
'tipo' => '',
|
|
'tipo_presupuesto_id' => $encuadernadoId,
|
|
'clienteId' => 40, // BUBOK ID
|
|
'isColor' => $isColor,
|
|
'isHq' => $isHq,
|
|
'paginas' => $paginas,
|
|
'paginasColor' => ($interiorTipo === 'color') ? $paginas : 0,
|
|
'paginasCuadernillo' => 32,
|
|
'interior' => [
|
|
'papelInterior' => $papelInteriorId,
|
|
'gramajeInterior' => $gramajePapelInterior
|
|
],
|
|
'cubierta' => [
|
|
'papelCubierta' => 2, // 'EST2'
|
|
'carasCubierta' => $doscara ? 2 : 4,
|
|
'gramajeCubierta' => in_array($encuadernadoId, [1, 3]) ? 150 : 300, // 150 gramos para "fresado tapa dura" y "cosido tapa dura"
|
|
'solapas' => !empty($producto->cover->type->consolapas) ? 80 : 0,
|
|
'acabado' => $acabadoId,
|
|
'cabezada' => 'WHI',
|
|
'lomoRedondo' => 0
|
|
],
|
|
'guardas' => [],
|
|
'sobrecubierta' => [],
|
|
'faja' => null,
|
|
|
|
'direcciones' => $direcciones,
|
|
|
|
'ivaReducido' => 1,
|
|
];
|
|
|
|
/*return $this->respond([
|
|
'status' => 400,
|
|
'message' => $dataToImport,
|
|
'interiorTipo' => $interiorTipo,
|
|
'isColor' => $isColor
|
|
]);*/
|
|
|
|
// 5. Guardar
|
|
try {
|
|
$presupuestocliente = new Presupuestocliente();
|
|
$response = $presupuestocliente->guardar($dataToImport);
|
|
|
|
// Guardar la URL de la portada y el cuerpo en los comentarios del presupuesto
|
|
$presupuestoModel = model('App\Models\Presupuestos\PresupuestoModel');
|
|
$presupuestoModel->update($response['sk_id'], [
|
|
'comentarios_safekat' => 'URL COVER: ' . $producto->cover->file . "\nURL BODY: " . $producto->body->file,
|
|
]);
|
|
|
|
|
|
// Ajuste del precio
|
|
$precio_compra = $json->producto->prices->unitPrice ?? null;
|
|
if ($precio_compra != null && $precio_compra > 0) {
|
|
|
|
$respuesta_ajuste = PresupuestoService::ajustarPresupuesto(
|
|
$response['sk_id'],
|
|
$precio_compra,
|
|
$tirada,
|
|
null,
|
|
true
|
|
);
|
|
if ($respuesta_ajuste['warning'] == true) {
|
|
$response['price_warning'] = [
|
|
'new_precio_unidad' => $respuesta_ajuste['new_precio_unidad'],
|
|
'new_total' => $respuesta_ajuste['new_total'],
|
|
];
|
|
}
|
|
}
|
|
|
|
// confirmar y crear pedido y ot
|
|
$presupuestoModel->confirmarPresupuesto($response['sk_id']);
|
|
PresupuestoService::crearPedido($response['sk_id'], isImported: true);
|
|
|
|
|
|
if (!isset($response['sk_id'])) {
|
|
return $this->respond([
|
|
'status' => 400,
|
|
'error' => 'Missing sk_id',
|
|
'message' => 'No se pudo crear el presupuesto.'
|
|
], 400);
|
|
}
|
|
|
|
// ✅ Importar archivos desde URLs y subir al SFTP
|
|
$uploaderService = new \App\Services\PresupuestoUploaderService(
|
|
new \App\Libraries\SftpClientWrapper(config('PresupuestoSFTP')),
|
|
model(\App\Models\Presupuestos\PresupuestoFicheroModel::class),
|
|
config('PresupuestoSFTP')
|
|
);
|
|
|
|
$archivoUrls = [
|
|
'cover' => $producto->cover->file ?? null,
|
|
'body' => $producto->body->file ?? null,
|
|
];
|
|
|
|
$resultadoArchivos = $uploaderService->importarArchivosDesdeUrlsBubok($response['sk_id'], $archivoUrls);
|
|
|
|
if (!$resultadoArchivos['success']) {
|
|
log_message('warning', 'Errores al importar archivos desde Bubok: ' . print_r($resultadoArchivos['errores'], true));
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 200,
|
|
'data' => [
|
|
'sk_id' => $response['sk_id'],
|
|
'sk_url' => $response['sk_url'] ?? null,
|
|
'archivos_subidos' => $resultadoArchivos['archivos_subidos'],
|
|
'errores_archivos' => $resultadoArchivos['errores']
|
|
]
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
return $this->respond([
|
|
'status' => 500,
|
|
'error' => 'Server error',
|
|
'message' => 'Error inesperado',
|
|
'debug' => $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
}
|