Merge branch 'main' into 'feat/backups'

arreglado albaranes para que muestren las cajas. tambien se ha actualizado...

See merge request jjimenez/safekat!856
This commit is contained in:
Ignacio Martinez Navajas
2025-06-09 08:08:21 +00:00
260 changed files with 11053 additions and 3987 deletions

View File

@ -411,6 +411,14 @@ class Albaran extends \App\Controllers\BaseResourceController
return '<input type="text" class="form-control form-control-sm input-albaran-linea" value="' . $q->titulo .
'" data-id="' . $q->id . '" data-field="titulo" />';
})
->edit('cajas', function ($q) {
return '<input class="form-control input-albaran-linea
form-control-sm text-center" value="' . $q->cajas . '" data-id="' . $q->id . '" data-field="cajas" />';
})
->edit('unidades_cajas', function ($q) {
return '<input class="form-control input-albaran-linea
form-control-sm text-center" value="' . $q->unidades_cajas . '" data-id="' . $q->id . '" data-field="unidades_cajas" />';
})
->edit('total', function ($q) {
return '<input class="form-control autonumeric-2 input-albaran-linea
form-control-sm text-center" value="' . $q->total . '" data-id="' . $q->id . '" data-field="total" />';
@ -468,10 +476,29 @@ class Albaran extends \App\Controllers\BaseResourceController
$model_linea->update($id, $linea->toArray());
if($fieldName == 'cajas'){
$cajas = $model_linea->where('albaran_id', $linea->albaran_id)
->where('cajas > 0')
->select('SUM(cajas) as total_cajas')
->get();
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
$albaran = $albaranModel->find($linea->albaran_id);
if($albaran != false) {
$albaran->cajas = $cajas->getRow()->total_cajas;
$albaran->user_updated_id = auth()->user()->id;
$albaran->updated_at = date('Y-m-d H:i:s');
$albaranModel->update($linea->albaran_id, $albaran->toArray());
}
}
$data = [
'success' => true,
'message' => lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.',
];
if($fieldName == 'cajas') {
$data['cajas'] = $cajas->getRow()->total_cajas;
};
return $this->respond($data);
} else {

View File

@ -35,7 +35,7 @@ class BaseController extends Controller
*
* @var array
*/
protected $helpers = ['general', 'go_common', 'rbac'];
protected $helpers = ['general', 'go_common', 'rbac', 'assets'];
/**
* Constructor.

View File

@ -85,7 +85,7 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
*
* @var array
*/
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac']; //JJO
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac', 'assets']; //JJO
/**
* Initializer method.

View File

@ -5,6 +5,7 @@ use App\Controllers\BaseResourceController;
use App\Entities\Catalogo\CatalogoLibroEntity;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Models\Clientes\ClienteModel;
use App\Models\Presupuestos\ImportadorModel;
use Hermawan\DataTables\DataTable;
class CatalogoLibros extends BaseResourceController
@ -48,7 +49,6 @@ class CatalogoLibros extends BaseResourceController
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Catalogo.catalogo')]),
'catalogoLibrosEntity' => new CatalogoLibroEntity(),
'usingServerSideDataTable' => true,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
@ -67,7 +67,7 @@ class CatalogoLibros extends BaseResourceController
$sanitizedData = $this->sanitized($postData, true);
$sanitizedData['user_created_id'] = auth()->user()->id;
unset($sanitizedData['isk']);
unset($sanitizedData['iskn']);
$noException = true;
if ($successfulResult = $this->canValidate()):
@ -132,11 +132,11 @@ class CatalogoLibros extends BaseResourceController
$postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, true);
unset($sanitizedData['isk']);
unset($sanitizedData['iskn']);
$sanitizedData['user_update_id'] = auth()->user()->id;
$noException = true;
if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) :
@ -174,7 +174,7 @@ class CatalogoLibros extends BaseResourceController
endif; // $noException && $successfulResult
endif; // ($requestMethod === 'post')
$this->viewData['catalogoLibrosEntity'] = $catalogoLibrosEntity;
$this->viewData['formAction'] = route_to('catalogoLibrosEdit', $id);
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Catalogo.moduleTitle') . ' ' . lang('Basic.global.edit3');
@ -225,7 +225,6 @@ class CatalogoLibros extends BaseResourceController
}
/* IMN */
public function getClientList()
{
@ -235,5 +234,41 @@ class CatalogoLibros extends BaseResourceController
}
/* Historico de pedidos ERP antiguo */
public function datatablePedidosAntiguos()
{
$reqData = $this->request->getGet();
$start = $reqData['start'] ?? 0;
$length = $reqData['length'] ?? 10;
$catalogoId = $reqData['catalogo_id'] ?? null;
// Instanciar el modelo directamente
$importadorModel = new ImportadorModel();
$q = $importadorModel->getHistoricoPedidosCatalogo($catalogoId);
return DataTable::of($q)
->setSearchableColumns([
't1.id',
't1.created_at',
't1.tirada',
'(CASE WHEN t1.tirada > 0 THEN t1.total / t1.tirada ELSE 0 END)',
't1.total',
't1.estado'
])
->edit('total', fn($row) => number_format((float) $row->total, 2, ',', '.') . ' €')
->edit('precio_ud', fn($row) => number_format((float) $row->precio_ud, 2, ',', '.') . ' €')
->edit('created_at', fn($row) => date('d/m/Y', strtotime($row->created_at)))
->add('actionBtns', function ($row) {
return '<div class="btn-group btn-group-sm">
<a href="https://gestion.safekat.es/pedido/detail/' . $row->id . '" class="btn btn-sm btn-info" target="_blank">
<i class="ti ti-eye"></i> Ver
</a>
</div>';
}, 'last')
->toJson(returnAsObject: true);
}
}

View File

@ -363,14 +363,13 @@ class ChatController extends BaseController
$query = $this->userModel->builder()->select(
[
"id",
"CONCAT(first_name,' ',last_name,'(',username,')') as name"
"CONCAT(first_name,' ',last_name) as name"
]
)
->where("deleted_at", null)
->whereNotIn("id", [auth()->user()->id]);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("users.username", $this->request->getGet("q"))
->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
->groupEnd();
}
@ -538,6 +537,23 @@ class ChatController extends BaseController
->toJson(true);
}
public function datatable_direct_messages()
{
$auth_user_id = auth()->user()->id;
$isAdmin = auth()->user()->inGroup('admin');
$query = $this->chatModel->getQueryDatatableDirectMessages($auth_user_id);
return DataTable::of($query)
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
->add("action", fn($q) => ["type" => "direct", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
"view_chat" => lang('Chat.view_chat'),
"view_by_alt_message" => lang('Chat.view_by_alt_message')
]])
->toJson(true);
}
public function get_notifications_not_viewed_from_message(int $chat_message_id)
{
$unviewedNotifications = $this->chatModel->getUsersNotificationNotViewedFromChat($chat_message_id);
@ -605,14 +621,13 @@ class ChatController extends BaseController
$query = $this->userModel->builder()->select(
[
"id",
"CONCAT(first_name,' ',last_name,'(',username,')') as name"
"CONCAT(first_name,' ',last_name) as name"
]
)
->where("deleted_at", null)
->whereNotIn("id", $chat_users_id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("users.username", $this->request->getGet("q"))
->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
->groupEnd();
}

View File

@ -67,6 +67,7 @@ class Imposiciones extends BaseController
['title' => lang("App.menu_imposiciones"), 'route' => route_to("imposicionList"), 'active' => true],
];
$this->viewData["method"] = "add";
return view(static::$viewPath . 'viewImposicionNewForm', $this->viewData);
}
public function add_esquema()
@ -88,6 +89,7 @@ class Imposiciones extends BaseController
];
}
$this->viewData["method"] = "edit";
return view(static::$viewPath . 'viewImposicionForm', $this->viewData);
}
public function edit_imposicion_esquema($imposicion_esquema_id = null)

View File

@ -207,6 +207,9 @@ class Maquinas extends \App\Controllers\BaseResourceController
if ($this->request->getPost('is_inkjet') == null) {
$sanitizedData['is_inkjet'] = false;
}
if ($this->request->getPost('etiqueta_envio') == null) {
$sanitizedData['etiqueta_envio'] = false;
}
// JJO
$sanitizedData['user_updated_id'] = auth()->user()->id;

View File

@ -234,6 +234,13 @@ class Facturas extends \App\Controllers\BaseResourceController
$factura->showDeleteButton = model('App\Models\Facturas\FacturaPagoModel')
->where('factura_id', $factura->id)->countAllResults() == 0;
if($factura->numero != null && $factura->numero != '' && strpos($factura->numero, "REC ") === 0) {
$modelPagos = model('App\Models\Facturas\FacturaPagoModel');
if($modelPagos->where('factura_id', $factura->id)->countAllResults() > 0) {
$factura->facturaRectificativaPagada = 1;
}
}
$this->viewData['facturaEntity'] = $factura;
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3');
@ -831,11 +838,15 @@ class Facturas extends \App\Controllers\BaseResourceController
'user_updated_id' => auth()->user()->id,
];
if ((strpos($numero, "REC ") === 0)) {
$data['estado_pago'] = 'pagada';
}
$this->model->update($factura_id, $data);
if ((strpos($numero, "REC ") === 0)) {
$this->model->where('numero', $factura->factura_rectificada_id)->set([
'factura_rectificativa_id' => $numero,
'user_updated_id' => auth()->user()->id,
])->update();
}
}

View File

@ -92,7 +92,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
Field::inst('id'),
Field::inst('base'),
Field::inst('total_iva'),
Field::inst('total'),
Field::inst('total')->set(Field::SET_BOTH),
Field::inst('cantidad')
->validator(
'Validate::numeric',
@ -126,19 +126,6 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('total')
->validator(
'Validate::numeric',
array(
'message' => lang('Facturas.validation.numerico')
)
)
->validator(
'Validate::notEmpty',
array(
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('pedido_linea_impresion_id')
->setFormatter(function ($val, $data, $opts) {
return $val === '' ? null : $val;
@ -157,7 +144,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -183,7 +170,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -256,14 +243,13 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['base'] = $base;
$values['total_iva'] = $total_iva;
$values['total'] = $total;
}
else{
} else {
// se pasa la base y el iva
$total_iva = round($base_input * $iva / 100, 2);
$total = round($base_input + $total_iva, 2);
$values = [];
$values['base'] = $base_input;
$values['base'] = (float) $base_input;
$values['total_iva'] = $total_iva;
$values['total'] = $total;

View File

@ -136,4 +136,36 @@ class FacturasPagos extends \App\Controllers\BaseResourceController
}
}
public function addPagoRectificativa()
{
if ($this->request->isAJAX()) {
$data['factura_id'] = $this->request->getPost('factura_id');
$data['fecha_vencimiento_at'] = $this->request->getPost('fecha');
$data['total'] = $this->request->getPost('total');
$data['user_updated_id'] = auth()->user()->id;
$data['forma_pago_id'] = 6; // compensada
if($data['fecha_vencimiento_at'] != null && $data['fecha_vencimiento_at'] != '') {
$data['fecha_vencimiento_at'] = date('Y-m-d H:i:s', strtotime($data['fecha_vencimiento_at']));
}
$model = new FacturaPagoModel();
$model->insert($data);
$modelFactura = model('App\Models\Facturas\FacturaModel');
$modelFactura->update($data['factura_id'], [
'estado_pago' => 'pagada',
'updated_at' => date('Y-m-d H:i:s'),
'user_updated_id' => auth()->user()->id,
]);
return $this->response->setJSON([
'status' => true,
'message' => lang('Facturas.facturaConformada'),
]);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
}

View File

@ -139,7 +139,7 @@ abstract class GoBaseController extends Controller
*
* @var array
*/
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac']; //JJO
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac', 'assets']; //JJO
public static $queries = [];

View File

@ -3,6 +3,7 @@ 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
@ -39,6 +40,7 @@ class ImportadorBubok extends BaseResourceController
public function index()
{
checkPermission('importadores.bubok');
$viewData = [
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
@ -50,9 +52,81 @@ class ImportadorBubok extends BaseResourceController
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
@ -83,7 +157,7 @@ class ImportadorBubok extends BaseResourceController
'message' => 'Número de orden o ID del producto no reconocidos.'
]);
}
$refCliente = "$orderNumber - $productId";
$refCliente = "$orderNumber-$productId";
// Titulo
$titulo = $producto->title ?? null;
@ -277,6 +351,15 @@ class ImportadorBubok extends BaseResourceController
]
];
// 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,
@ -295,8 +378,8 @@ class ImportadorBubok extends BaseResourceController
'tipo' => '',
'tipo_presupuesto_id' => $encuadernadoId,
'clienteId' => 40, // BUBOK ID
'isColor' => ($interiorTipo === 'color') ? 1 : 0,
'isHq' => 0,
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $paginas,
'paginasColor' => ($interiorTipo === 'color') ? $paginas : 0,
'paginasCuadernillo' => 32,
@ -317,15 +400,16 @@ class ImportadorBubok extends BaseResourceController
'sobrecubierta' => [],
'faja' => null,
'entrega_taller' => 1,
//'direcciones' => $direcciones, las direcciones que aparecen no se añaden, ya que la recogida la hacen ellos con su empresa de mensajeria
'direcciones' => $direcciones,
'ivaReducido' => 1,
];
/*return $this->respond([
'status' => 400,
'message' => $dataToImport
'message' => $dataToImport,
'interiorTipo' => $interiorTipo,
'isColor' => $isColor
]);*/
// 5. Guardar
@ -358,11 +442,11 @@ class ImportadorBubok extends BaseResourceController
];
}
}
// confirmar y crear pedido y ot
$presupuestoModel->confirmarPresupuesto($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id'], isImported: true);
if (!isset($response['sk_id'])) {
return $this->respond([
@ -372,6 +456,76 @@ class ImportadorBubok extends BaseResourceController
], 400);
}
// Descarga y subida de archivos al SFTP
$presupuestoFicheroModel = model('App\Models\Presupuestos\PresupuestoFicheroModel');
$ftp = new \App\Libraries\SafekatFtpClient();
$archivoUrls = [
'cover' => $producto->cover->file ?? null,
'body' => $producto->body->file ?? null,
];
foreach ($archivoUrls as $tipo => $url) {
if (!$url)
continue;
try {
$contenido = @file_get_contents($url); // silenciar errores de PHP
if ($contenido === false || strlen($contenido) === 0) {
// No se pudo descargar el archivo: generar archivo de error para FTP
$errorMessage = "ERROR: No se pudo descargar el archivo remoto para $tipo desde la URL: $url";
$remoteDir = $ftp->getPresupuestoRemotePath($response['sk_id']); // crea esta función si no existe
$remoteErrorFile = $remoteDir . '/ERROR_' . strtoupper($tipo) . '.txt';
// Crear archivo temporal con el mensaje de error
$tempErrorFile = WRITEPATH . 'uploads/presupuestos/ERROR_' . $tipo . '.txt';
file_put_contents($tempErrorFile, $errorMessage);
if (!$ftp->is_dir($remoteDir)) {
$ftp->mkdir($remoteDir, recursive: true);
}
$ftp->put($remoteErrorFile, $tempErrorFile, $ftp::SOURCE_LOCAL_FILE);
continue; // no procesar este archivo
}
// ✅ Procesar normalmente si la descarga tuvo éxito
$nombreOriginal = basename(parse_url($url, PHP_URL_PATH));
$extension = pathinfo($nombreOriginal, PATHINFO_EXTENSION);
$nombreLimpio = $presupuestoFicheroModel->saveFileInBBDD(
$response['sk_id'],
$nombreOriginal,
$extension,
auth()->id()
);
if (is_null($nombreLimpio))
continue;
$rutaLocal = WRITEPATH . 'uploads/presupuestos/';
if (!is_dir($rutaLocal)) {
mkdir($rutaLocal, 0777, true);
}
file_put_contents($rutaLocal . $nombreLimpio, $contenido);
} catch (\Throwable $e) {
//log_message('error', 'Error inesperado en descarga de archivo remoto: ' . $e->getMessage());
}
}
// Subir al FTP después de guardar localmente
try {
$ftp->uploadFilePresupuesto($response['sk_id']);
} catch (\Throwable $e) {
log_message('error', 'Error subiendo archivos al FTP: ' . $e->getMessage());
}
return $this->respond([
'status' => 200,
'data' => [
@ -380,6 +534,7 @@ class ImportadorBubok extends BaseResourceController
]
]);
} catch (\Throwable $e) {
return $this->respond([
'status' => 500,

View File

@ -3,6 +3,7 @@ namespace App\Controllers\Importadores;
use App\Controllers\BaseResourceController;
use App\Entities\Catalogo\CatalogoLibroEntity;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Controllers\Presupuestos\Presupuestocliente;
use App\Services\PresupuestoService;
@ -42,10 +43,11 @@ class ImportadorCatalogo extends BaseResourceController
public function index()
{
checkPermission('importadores.catalogo');
$viewData = [
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
@ -56,39 +58,55 @@ class ImportadorCatalogo extends BaseResourceController
public function validarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
if (!$json || !isset($json->fila[0])) {
// Validación inicial del JSON y del ISBN
if (!$json || !isset($json->fila[0]) || empty(trim($json->fila[0]))) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Datos inválidos'
'reason' => 'ISBN no proporcionado o datos inválidos'
]);
}
$input = trim($json->fila[0]); // Asumimos que 'input' es el primer campo de la fila
$input = trim($json->fila[0]); // ISBN
$refCliente = isset($json->fila[1]) ? trim($json->fila[1]) : null;
if (empty($input)) {
// Validar formato del refCliente (esperado: idpedido-idlinea)
if (empty($refCliente) || strpos($refCliente, '-') === false) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'ISBN no proporiconado'
'reason' => 'Ref. cliente inválido'
]);
}
// 1. Comprobar duplicado en tabla de presupuestos
$presupuestoModel = new PresupuestoModel(); // Usa el modelo real que corresponda
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
if ($yaExiste) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Referencia ya importada'
]);
}
$catalogoModel = new CatalogoLibroModel();
// 1. Buscar por ISBN exacto
// 2. Buscar por ISBN exacto
$libroPorIsbn = $catalogoModel->where('isbn', $input)->first();
if ($libroPorIsbn) {
return $this->response->setJSON([
'apto' => true
]);
}
// 2. Buscar por EAN sin guiones
// 3. Buscar por EAN sin guiones
$eanLimpio = str_replace('-', '', $input);
$libroPorEan = $catalogoModel->where('REPLACE(ean, "-", "")', $eanLimpio)->first();
$libroPorEan = $catalogoModel
->where('REPLACE(ean, "-", "")', $eanLimpio, false) // false para evitar escapado automático
->first();
if ($libroPorEan) {
return $this->response->setJSON([
@ -96,7 +114,7 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// No encontrado
// 4. No encontrado
return $this->response->setJSON([
'apto' => false,
'reason' => 'No encontrado en catálogo'
@ -104,9 +122,10 @@ class ImportadorCatalogo extends BaseResourceController
}
public function importarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
if (!$json || !isset($json->fila[0])) {
@ -116,12 +135,10 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// Mapear cada columna a una variable
// Mapear cada columna a una variable (debe coincidir con catalogo_tool.js)
$isbn = isset($json->fila[0]) ? trim($json->fila[0]) : null;
$refCliente = isset($json->fila[1]) ? trim($json->fila[1]) : null;
//$descripcion = isset($json->fila[2]) ? trim($json->fila[2]) : null;
$tirada = isset($json->fila[3]) ? (float) $json->fila[3] : null;
$precio_compra = isset($json->fila[4]) ? (float) $json->fila[4] : null;
if (empty($isbn)) {
return $this->response->setJSON([
@ -130,6 +147,17 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// 0. Comprobar duplicado en tabla de presupuestos
$presupuestoModel = new PresupuestoModel(); // Usa el modelo real que corresponda
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
if ($yaExiste) {
return $this->response->setJSON([
'success' => false,
'message' => 'Referencia ya importada'
]);
}
$catalogoModel = new CatalogoLibroModel();
// 1. Buscar por ISBN exacto
@ -191,13 +219,22 @@ class ImportadorCatalogo extends BaseResourceController
// Sobrecubierta
$sobrecubierta = [];
if (!is_null($libro->sobrecubierta_paginas)) {
if (!is_null($libro->sobrecubierta_paginas) && $libro->sobrecubierta_paginas != 0) {
$sobrecubierta['papel'] = $libro->sobrecubierta_papel_id;
$sobrecubierta['gramaje'] = $libro->sobrecubierta_gramaje;
$sobrecubierta['solapas'] = $libro->sobrecubierta_solapas;
$sobrecubierta['acabado'] = $libro->sobrecubierta_acabado_id;
}
// Recalcular calidad (isColor y isHq) en funcion del cliente
[$isColor, $isHq] = PresupuestoService::getCalidad(
'importador-rama',
null,
(in_array(strtolower($libro->tipo_impresion), ['color', 'colorhq']) ? 1 : 0),
(in_array(strtolower($libro->tipo_impresion), ['negrohq', 'colorhq']) ? 1 : 0),
intval($tirada ?? 0)
);
$dataToImport = [
'selectedTirada' => $tirada,
@ -221,8 +258,8 @@ class ImportadorCatalogo extends BaseResourceController
'tipo' => "",
'tipo_presupuesto_id' => $libro->encuadernacion_id,
'clienteId' => 251,
'isColor' => (in_array(strtolower($libro->tipo_impresion), ['color', 'colorhq']) ? 1 : 0),
'isHq' => (in_array(strtolower($libro->tipo_impresion), ['negrohq', 'colorhq']) ? 1 : 0),
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $libro->paginas,
'paginasColor' => $colorPaginas,
'papelInteriorDiferente' => $papelInteriorDiferente,
@ -254,6 +291,32 @@ class ImportadorCatalogo extends BaseResourceController
'data' => $dataToImport
]);*/
$tarifas = $this->obtenerTarifas();
$precioDesdeTarifa = $this->calcularPrecioDesdeTarifa(
$dataToImport['isColor'],
$libro->encuadernacion_id,
$libro->ancho,
$libro->alto,
$libro->paginas,
$tarifas
);
if (is_null($precioDesdeTarifa)) {
return $this->response->setJSON([
'success' => false,
'message' => 'No se pudo calcular el precio desde las tarifas disponibles.',
'detalle' => [
'tinta' => $dataToImport['isColor'] ? 'color' : 'negro',
'encuadernacion_id' => $libro->encuadernacion_id,
'ancho' => $libro->ancho,
'alto' => $libro->alto,
'paginas' => $libro->paginas
]
]);
}
// Usar precio calculado
$precio_compra = $precioDesdeTarifa;
// Procedemos a intentar guardar el presupuesto
// Instancia de presupuesto cliente
@ -287,7 +350,7 @@ class ImportadorCatalogo extends BaseResourceController
$response['data']['sk_id'],
$precio_compra,
$tirada,
null,
null,
true
);
if ($respuesta_ajuste['warning'] == true) {
@ -299,7 +362,7 @@ class ImportadorCatalogo extends BaseResourceController
// confirmar y crear pedido y ot
model('App\Models\Presupuestos\PresupuestoModel')->confirmarPresupuesto($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id'],isImported:true);
return $this->respond($response);
@ -316,6 +379,79 @@ class ImportadorCatalogo extends BaseResourceController
}
private function calcularPrecioDesdeTarifa($isColor, $encuadernacionId, $ancho, $alto, $paginas, $tarifas)
{
// Solo aplicamos tarifa si la encuadernación es Rústica Fresada (id = 2)
if ((int) $encuadernacionId !== 2) {
return null;
}
$tinta = $isColor ? 'color' : 'negro';
foreach ($tarifas as $tarifa) {
if (
strtolower($tarifa['tinta']) === $tinta &&
strtolower($tarifa['manipulado']) === 'rústica fresada' &&
(int) $tarifa['ancho'] === (int) $ancho &&
(int) $tarifa['alto'] === (int) $alto
) {
return round($tarifa['precio_fijo'] + ($tarifa['precio_variable'] * $paginas), 2);
}
}
return null; // No se encontró tarifa válida
}
private function obtenerTarifas()
{
return [
[
'tinta' => 'color',
'manipulado' => 'Rústica Fresada',
'ancho' => 200,
'alto' => 245,
'precio_fijo' => 1.15,
'precio_variable' => 0.076
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 200,
'alto' => 245,
'precio_fijo' => 1.15,
'precio_variable' => 0.009724
],
[
'tinta' => 'color',
'manipulado' => 'Rústica Fresada',
'ancho' => 150,
'alto' => 210,
'precio_fijo' => 1.15,
'precio_variable' => 0.03217
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 150,
'alto' => 210,
'precio_fijo' => 1.15,
'precio_variable' => 0.00572
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 170,
'alto' => 240,
'precio_fijo' => 1.15,
'precio_variable' => 0.008
]
];
}

View File

@ -0,0 +1,467 @@
<?php
namespace App\Controllers\Logistica;
use App\Controllers\BaseController;
use App\Services\ImpresoraEtiquetaService;
use App\Services\EtiquetasTitulosService;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use Hermawan\DataTables\DataTable;
class EtiquetasTitulosController extends BaseController
{
protected ImpresoraEtiquetaService $impresoraEtiquetaService;
protected string $locale;
protected array $viewData;
protected static $controllerSlug = 'etiquetas_titulos';
protected static $viewPath = 'themes/vuexy/form/logistica/';
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->impresoraEtiquetaService = service('impresora_etiqueta');
$this->locale = session()->get('lang');
$this->model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$this->viewData['pageTitle'] = lang('Logistica.logistica');
// Breadcrumbs
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_logistica"), 'route' => route_to("LogisticaPanel"), 'active' => false],
];
parent::initController($request, $response, $logger);
}
public function findOTs()
{
if ($this->request->isAJAX()) {
$query = EtiquetasTitulosService::getOtsWithTitulos();
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("ot.id", $this->request->getGet("q"))
->orLike("pr.titulo)", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("id", "DESC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function findAddresses()
{
if ($this->request->isAJAX()) {
$ot_id = $this->request->getGet("ot_id");
$query = EtiquetasTitulosService::getDireccionesOT($ot_id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("pd.direccion", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("pd.direccion", "ASC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function addEtiqueta()
{
if ($this->request->isAJAX()) {
$data = [];
$data['user_id'] = auth()->user()->id;
$data['ot_id'] = $this->request->getPost('ot_id') ?? null;
$data['direccion'] = $this->request->getPost('direccion') ?? null;
$data['unidades_caja'] = $this->request->getPost('unidades_caja') ?? null;
if (
$this->request->getPost('ot_id') == null ||
$this->request->getPost('direccion') == null ||
$this->request->getPost('unidades_caja') == null
) {
return [
'status' => false,
'message' => lang('Logistica.errorMissingData')
];
}
$result = EtiquetasTitulosService::addEtiqueta($data);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function deleteEtiqueta($id = null)
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
if ($id == null) {
return [
'status' => false,
'message' => lang('Logistica.errorMissingData')
];
}
$modelLineas = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$ids = $modelLineas->where('etiqueta_titulos_id', $id)->findColumn('id');
if ($ids) {
$modelLineas->delete($ids);
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$id = $model->where('id', $id)->findColumn('id');
if ($id) {
$model->delete($id);
}
$result = [
'status' => true,
'message' => lang('Logistica.success.jhn<successDeleteEtiqueta'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function edit($id = null)
{
if (empty($id)) {
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$etiquetaEntity = $model->select('etiquetas_titulos.*, clientes.nombre as cliente')
->join('clientes', 'clientes.id = etiquetas_titulos.cliente_id', 'left')
->where('etiquetas_titulos.id', $id)
->first();
if (empty($etiquetaEntity)) {
return redirect()->to(base_url('logistica/etiquetasLogistica'))->with('error', lang('Logistica.errors.noEnvio'));
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresora->select('id, name, description')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
->findAll();
$etiquetaEntity->impresoras = $impresoras;
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => '<i class="ti ti-ticket ti-xl"></i>' . ' ' . lang('Logistica.EtiquetasTitulos') . ' [' . $etiquetaEntity->id . ']: ' . $etiquetaEntity->direccion,
'usingServerSideDataTable' => true,
'etiquetaEntity' => $etiquetaEntity,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewEtiquetasTitulosEdit', $viewData);
}
public function datatable()
{
$q = $this->model->getEtiquetasTitulos();
if (!empty($otsFilter)) {
$q->groupStart();
$q->like('etl.ot_id', $otsFilter);
$q->groupEnd();
}
$result = DataTable::of($q)
->add("action", callback: function ($q) {
return '
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true);
}
public function findOtsWithAddress()
{
if ($this->request->isAJAX()) {
$id = $this->request->getGet('id') ?? null;
$query = EtiquetasTitulosService::findOTsWithAddress($id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("name", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("id", "DESC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function addLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$etiqueta_id = $this->request->getPost('etiqueta_id') ?? null;
$ot_id = $this->request->getPost('ot_id') ?? null;
$unidades = $this->request->getPost('unidades') ?? null;
$cajas = $this->request->getPost('cajas') ?? null;
$result = EtiquetasTitulosService::addLineasEtiqueta($etiqueta_id, $ot_id, $unidades, $cajas);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function datatableLineasEtiquetas($id = null)
{
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$id = $this->request->getGet('id') ?? null;
$direccion = $this->request->getGet('direccion') ?? null;
$q = $model->getDatatableQuery($id, $direccion);
$result = DataTable::of($q)
->add(
"rowSelected",
callback: function ($q) {
return '<input type="checkbox" class="form-check-input checkbox-linea-envio" name="row_selected[]" value="' . $q->id . '">';
}
)
->edit(
"ot",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ot) . '" target="_blank">' . $row->ot . '</a>';
}
)
->edit(
"unidades",
function ($row, $meta) {
return '<input type="number" class="form-control input-lineas input-unidades text-center"
data-id="' . $row->id . '" data-name="unidades" value="' . $row->unidades . '">';
}
)
->edit(
"numero_caja",
function ($row, $meta) {
return '<input type="number" class="form-control input-lineas input-cajas text-center"
data-id="' . $row->id . '" data-name="numero_caja" value="' . $row->numero_caja . '">';
}
)
->add("unidades_raw", fn($row) => $row->unidades)
->add("pesoUnidad_raw", fn($row) => $row->pesoUnidad)
->add(
"action",
callback: function ($q) {
return '
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete" data-id="' . $q->id . '"></i></a>
</div>
';
}
);
return $result->toJson(returnAsObject: true);
}
public function deleteLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$ids = $this->request->getPost('ids') ?? [];
if ($ids == [] || $ids == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
for ($i = 0; $i < count($ids); $i++) {
$model->delete($ids[$i]);
}
$result = [
'status' => true,
'message' => lang('Logistica.success.successDeleteLines'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
$name = $this->request->getPost('name') ?? null;
$value = $this->request->getPost('value') ?? null;
if ($id == null || $name == null || $value == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$model->update($id, [$name => $value]);
$result = [
'status' => true,
'message' => lang('Logistica.success.successUpdateLine'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateComentarios()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
$comentarios = $this->request->getPost('comentarios') ?? null;
if ($id == null || $comentarios == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$model->update($id, ['comentarios' => $comentarios]);
$result = [
'status' => true,
'message' => lang('Logistica.success.comentariosUpdated'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateOrdenCajas()
{
$rawInput = $this->request->getBody();
$data = json_decode($rawInput, true);
$orden = $data['orden'] ?? [];
if (!is_array($orden)) {
return $this->response->setJSON([
'status' => false,
'message' => 'Datos inválidos'
]);
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
foreach ($orden as $item) {
if (isset($item['id'], $item['numero_caja'])) {
$model->update($item['id'], [
'numero_caja' => $item['numero_caja'],
'updated_at' => date('Y-m-d H:i:s') // opcional
]);
}
}
return $this->response->setJSON([
'status' => true,
'message' => 'Orden de cajas actualizado correctamente'
]);
}
public function renumberCajas()
{
$id = $this->request->getPost('id') ?? null;
if ($id == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$result = EtiquetasTitulosService::reordenarCajas($id);
return $this->response->setJSON($result);
}
public function imprimirEtiquetas()
{
$etiqueta_id = $this->request->getPost('etiqueta_id') ?? null;
$ids = $this->request->getPost('ids') ?? [];
$impresora_id = $this->request->getPost('impresora_id') ?? null;
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $impresora_id)
->orderBy('name', 'asc')
->first();
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
]);
}
if ($etiqueta_id == null || $ids == []) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$result = EtiquetasTitulosService::imprimirEtiquetas($etiqueta_id, $ids, $impresora);
return $this->response->setJSON($result);
}
}

View File

@ -44,6 +44,8 @@ class LogisticaController extends BaseController
public function panel()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.panel'),
@ -58,6 +60,8 @@ class LogisticaController extends BaseController
public function gestionEnvios()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.gestionEnvios'),
@ -73,6 +77,8 @@ class LogisticaController extends BaseController
public function gestionEnviosFerros()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.envioFerros'),
@ -85,7 +91,25 @@ class LogisticaController extends BaseController
return view(static::$viewPath . 'viewLogisticaSelectEnvios', $viewData);
}
public function listAlbaranes(){
public function etiquetasLogistica()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.etiquetasTitulos'),
'usingServerSideDataTable' => true,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewImpresionEtiquetas', $viewData);
}
public function listAlbaranes()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Albaran.albaranes'),
@ -104,7 +128,7 @@ class LogisticaController extends BaseController
$tipo_envio = $this->request->getGet('tipo_envio') ?? 'estandar';
if($tipo_envio == 'ferro_prototipo'){
if ($tipo_envio == 'ferro_prototipo') {
$query = LogisticaService::findForNewEnvioFerro();
} else {
$query = LogisticaService::findForNewEnvio();
@ -119,22 +143,25 @@ class LogisticaController extends BaseController
$result = $query->orderBy("name", "asc")->get()->getResultObject();
$query = model('App\Models\Logistica\EnvioModel')->db->getLastQuery();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function selectDireccionForEnvio(){
public function selectDireccionForEnvio()
{
if ($this->request->isAJAX()) {
$ot = $this->request->getGet('ot_id');
if($ot == null || $ot == 0){
if ($ot == null || $ot == 0) {
return [];
}
$searchVal = $this->request->getGet("q") ?? "";
$result = LogisticaService::findDireccionesNewEnvio($ot, $searchVal);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
@ -172,12 +199,12 @@ class LogisticaController extends BaseController
public function imprimirEtiquetas()
{
if ($this->request->isAJAX()) {
$envio_id = $this->request->getPost('envio_id');
$envio_id = $this->request->getPost('envio_id');
$ids = $this->request->getPost('envio_lineas');
$cajas = $this->request->getPost('cajas');
$printer_id = $this->request->getPost('printer_id');
if($cajas == null || $cajas == 0){
if ($cajas == null || $cajas == 0) {
return $this->response->setJSON([
'status' => false,
'message' => 'Cajas no válidas'
@ -189,7 +216,7 @@ class LogisticaController extends BaseController
->join('clientes', 'clientes.id = envios.cliente_id', 'left')
->where('envios.id', $envio_id)
->first();
if($envio == null){
if ($envio == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Envio no válido'
@ -200,7 +227,7 @@ class LogisticaController extends BaseController
$lineas = $model->select('envios_lineas.*, presupuestos.titulo as titulo, presupuestos.referencia_cliente as referencia_cliente')
->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id', 'left')
->whereIn('envios_lineas.id', $ids)->findAll();
if($lineas == null){
if ($lineas == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Lineas no válidas'
@ -208,12 +235,12 @@ class LogisticaController extends BaseController
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, ip, port, user, pass')
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $printer_id)
->orderBy('name', 'asc')
->first();
if($impresora == null){
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
@ -317,19 +344,19 @@ class LogisticaController extends BaseController
if (empty($envioEntity)) {
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
}
$modelProveedor = model('App\Models\Compras\ProveedorModel');
$proveedor = $modelProveedor->select('id, nombre')
->where('deleted_at', null)
->where('id', $envioEntity->proveedor_id)
->orderBy('nombre', 'asc')
->first();
if(!empty($proveedor)){
if (!empty($proveedor)) {
$envioEntity->proveedor_nombre = $proveedor->nombre;
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresora->select('id, name')
$impresoras = $modelImpresora->select('id, name, description')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
@ -371,7 +398,7 @@ class LogisticaController extends BaseController
$id = $this->request->getPost('id') ?? null;
$finalizar_ots = $this->request->getPost('finalizar_ots') ?? false;
$result = LogisticaService::finalizarEnvio($id, $finalizar_ots);
return $this->response->setJSON($result);
} else {
@ -379,6 +406,17 @@ class LogisticaController extends BaseController
}
}
public function ficharEmbalaje()
{
if ($this->request->isAJAX()) {
$ids = $this->request->getPost('ids') ?? [];
$result = LogisticaService::ficharEmbalaje($ids);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function datatable_enviosEdit($idEnvio)
{
@ -393,6 +431,12 @@ class LogisticaController extends BaseController
return '<input type="checkbox" class="form-check-input checkbox-linea-envio" name="row_selected[]" value="' . $q->id . '">';
}
)
->edit(
"ordenTrabajo",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ordenTrabajo) . '" target="_blank">' . $row->ordenTrabajo . '</a>';
}
)
->edit(
"pedido",
function ($row, $meta) {
@ -407,17 +451,35 @@ class LogisticaController extends BaseController
)->edit(
"unidadesEnvio",
function ($row, $meta) {
if($row->finalizado == 1 || $row->tipo_envio == 'ferro_prototipo'){
if ($row->finalizado == 1 || $row->tipo_envio == 'ferro_prototipo') {
return $row->unidadesEnvio;
}
return '<input type="number" class="form-control input-lineas input-unidades text-center"
data-id="'. $row->id.'" data-name="unidades_envio" value="' . $row->unidadesEnvio . '">';
data-id="' . $row->id . '" data-name="unidades_envio" value="' . $row->unidadesEnvio . '">';
}
);
return $result->toJson(returnAsObject: true);
}
public function datatable_proximosEnvios($envio_id = null)
{
$q = LogisticaService::findNextEnvios($envio_id);
$result = DataTable::of($q)
->edit(
"ot",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ot) . '" target="_blank">' . $row->ot . '</a>';
}
);
$result = $result->toJson(returnAsObject: true);
$query = model('App\Models\Logistica\EnvioModel')->db->getLastQuery();
return $result;
}
public function setCajaLinea()
{
@ -458,7 +520,7 @@ class LogisticaController extends BaseController
$fieldName = $this->request->getPost('name');
$fieldValue = $this->request->getPost('value');
if (!$id || !$fieldName || ($fieldName=='unidades_envio' && !$fieldValue)) {
if (!$id || !$fieldName || ($fieldName == 'unidades_envio' && !$fieldValue)) {
return $this->response->setJSON([
'status' => false,
'message' => 'Datos inválidos'
@ -467,7 +529,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioLineaModel');
$updated = $model->update($id, [
"" . $fieldName => $fieldValue==""? null: $fieldValue,
"" . $fieldName => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([
@ -490,7 +552,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioModel');
$updated = $model->update($id, [
"codigo_seguimiento" => $fieldValue==""? null: $fieldValue,
"codigo_seguimiento" => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([
@ -513,7 +575,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioModel');
$updated = $model->update($id, [
"proveedor_id" => $fieldValue==""? null: $fieldValue,
"proveedor_id" => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([

View File

@ -71,4 +71,55 @@ class PrintAlbaranes extends BaseController
->setHeader('Content-Length', strlen($output))
->setBody($output);
}
public function generarAnonimo($albaran_id)
{
// Cargar modelos
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
$lineasAlbaranModel = model('App\Models\Albaranes\AlbaranLineaModel');
// Informacion del presupuesto
$data['albaran'] = $albaranModel->getResourceForPdf($albaran_id)->get()->getRow();
$data['albaranLineas'] = $lineasAlbaranModel->getResourceForPdf($albaran_id)->get()->getResultObject();
// Obtener contenido HTML de la vista
$html = view(getenv('theme.path') . 'pdfs/albaran-anonimo', $data);
// Cargar CSS desde archivo local
$css = file_get_contents(FCPATH . 'themes/vuexy/css/pdf.albaran.css');
// Combinar CSS y HTML
$html_con_css = "<style>$css</style>" . $html;
// Crear una instancia de Dompdf
$options = new \Dompdf\Options();
$options->set('isHtml5ParserEnabled', true);
$options->set('isPhpEnabled', true);
$options->set('isRemoteEnabled', true);
$dompdf = new \Dompdf\Dompdf($options);
// Contenido HTML del documento
$dompdf->loadHtml($html_con_css);
// Establecer el tamaño del papel
$dompdf->setPaper('A4', 'portrait');
// Renderizar el PDF
$dompdf->render();
// Obtener el contenido generado
$output = $dompdf->output();
// Establecer las cabeceras para visualizar en lugar de descargar
$file_name = "alabaran-$albaran_id.pdf";
return $this->response
->setStatusCode(200)
->setHeader('Content-Type', 'application/pdf')
->setHeader('Content-Disposition', 'inline; filename="' . $file_name . '"')
->setHeader('Cache-Control', 'private, max-age=0, must-revalidate')
->setHeader('Pragma', 'public')
->setHeader('Content-Length', strlen($output))
->setBody($output);
}
}

View File

@ -12,7 +12,7 @@ use Hermawan\DataTables\DataTable;
use CodeIgniter\I18n\Time;
class Pedido extends \App\Controllers\BaseResourceController
{
{
protected $modelName = PedidoModel::class;
protected $format = 'json';
@ -29,9 +29,9 @@ class Pedido extends \App\Controllers\BaseResourceController
{
$this->viewData['pageTitle'] = lang('Pedidos.moduleTitle');
// Se indica que este controlador trabaja con soft_delete
$this->viewData = ['usingServerSideDataTable' => true];
// Breadcrumbs
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_pedidos"), 'route' => "javascript:void(0);", 'active' => false],
@ -169,7 +169,7 @@ class Pedido extends \App\Controllers\BaseResourceController
public function todos()
{
$viewData = [
'currentModule' => static::$controllerSlug,
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Pedidos.pedido')]),
@ -195,21 +195,23 @@ class Pedido extends \App\Controllers\BaseResourceController
}
public function cambiarEstado(){
if($this->request->isAJAX()){
public function cambiarEstado()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id');
$estado = $this->request->getPost('estado');
$this->model->where('id', $id)->set(['estado' => $estado])->update();
return $this->respond(['status' => 'success', 'message' => lang('Basic.global.success')]);
}else{
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function update($id = null){
public function update($id = null)
{
$data = [];
@ -217,7 +219,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$newTokenHash = csrf_hash();
$csrfTokenName = csrf_token();
if ($id == null) :
if ($id == null):
$data = [
'error' => 2,
$csrfTokenName => $newTokenHash
@ -227,7 +229,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$id = filter_var($id, FILTER_SANITIZE_URL);
$pedidoEntity = $this->model->find($id);
if ($pedidoEntity == false) :
if ($pedidoEntity == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.pedido')), $id]);
$data = [
'error' => $message,
@ -236,19 +238,19 @@ class Pedido extends \App\Controllers\BaseResourceController
return $this->respond($data);
endif;
if ($this->request->getPost()) :
if ($this->request->getPost()):
$nullIfEmpty = true; // !(phpversion() >= '8.1');
$postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
foreach(array_keys($sanitizedData) as $key){
if(str_starts_with($key, "fecha_")){
$sanitizedData[$key . "_change_user_id"] =
foreach (array_keys($sanitizedData) as $key) {
if (str_starts_with($key, "fecha_")) {
$sanitizedData[$key . "_change_user_id"] =
auth()->user()->id;
$data[$key . "_change_user"] =
$data[$key . "_change_user"] =
model('App\Models\Usuarios\UserModel')->getFullName(auth()->user()->id);
}
}
@ -256,9 +258,9 @@ class Pedido extends \App\Controllers\BaseResourceController
$sanitizedData['user_updated_id'] = auth()->user()->id;
$noException = true;
if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($this->canValidate()) :
if ($this->canValidate()):
try {
$successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
} catch (\Exception $e) {
@ -274,7 +276,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$pedidoEntity->fill($sanitizedData);
endif;
if ($noException && $successfulResult) :
if ($noException && $successfulResult):
$id = $pedidoEntity->id ?? $id;
$message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.';
@ -291,39 +293,39 @@ class Pedido extends \App\Controllers\BaseResourceController
$csrfTokenName => $newTokenHash
];
return $this->respond($data);
}
else {
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function edit($id=null){
if ($id == null) :
public function edit($id = null)
{
if ($id == null):
return $this->redirect2listView();
endif;
$id = filter_var($id, FILTER_SANITIZE_URL);
$pedidoEntity = $this->model->find($id);
if ($pedidoEntity == false) :
if ($pedidoEntity == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.pedido')), $id]);
return $this->redirect2listView('sweet-error', $message);
endif;
$this->obtenerDatosFormulario($pedidoEntity);
$pedidoEntity->fecha_entrega_real_change_user = $pedidoEntity->fecha_entrega_real_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_real_change_user_id):"";
$pedidoEntity->fecha_impresion_change_user = $pedidoEntity->fecha_impresion_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_impresion_change_user_id):"";
$pedidoEntity->fecha_encuadernado_change_user = $pedidoEntity->fecha_encuadernado_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_encuadernado_change_user_id):"";
$pedidoEntity->fecha_entrega_change_externo_user = $pedidoEntity->fecha_entrega_change_externo_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_change_externo_user_id):"";
$pedidoEntity->fecha_entrega_real_change_user = $pedidoEntity->fecha_entrega_real_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_real_change_user_id) : "";
$pedidoEntity->fecha_impresion_change_user = $pedidoEntity->fecha_impresion_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_impresion_change_user_id) : "";
$pedidoEntity->fecha_encuadernado_change_user = $pedidoEntity->fecha_encuadernado_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_encuadernado_change_user_id) : "";
$pedidoEntity->fecha_entrega_change_externo_user = $pedidoEntity->fecha_entrega_change_externo_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_change_externo_user_id) : "";
$this->viewData['pedidoEntity'] = $pedidoEntity;
if($pedidoEntity->estado == 'validacion'){
if ($pedidoEntity->estado == 'validacion') {
$clienteModel = model('App\Models\Clientes\ClienteModel');
$pendiente = $clienteModel->getPendienteCobro($pedidoEntity->cliente_id);
$pendiente = $pendiente[0] + $pendiente[1];
@ -332,24 +334,25 @@ class Pedido extends \App\Controllers\BaseResourceController
$modelOrden = new \App\Models\OrdenTrabajo\OrdenTrabajoModel();
$orden = $modelOrden->where('pedido_id', $pedidoEntity->id)->first();
if($orden){
if ($orden) {
$this->viewData['orden_id'] = $orden->id;
}
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Pedidos.moduleTitle') . ' ' . lang('Basic.global.edit3');
return $this->displayForm(__METHOD__, $id);
}
public function datatable(){
public function datatable()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns']) ) {
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
$errstr = 'No data available in response to this specific request.';
$response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr);
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
return $response;
}
$start = $reqData['start'] ?? 0;
@ -360,7 +363,8 @@ class Pedido extends \App\Controllers\BaseResourceController
$dir = $reqData['order']['0']['dir'] ?? 'asc';
$estado = $reqData['estado'] ?? 'todos';
$cliente_id = $reqData['cliente_id'] ?? -1;
if($estado == 'todos') $estado = '';
if ($estado == 'todos')
$estado = '';
$showTotal = $reqData['showTotal'] ?? false;
@ -373,7 +377,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$extra_data['total_tirada'] = $totalTirada;
$extra_data['total'] = $total;
$total2 = 0;
if($showTotal){
if ($showTotal) {
$total2 = $model_linea->getTotalOfTotalAceptado($estado);
$tirada2 = $model_linea->getTotalTirada($estado);
$extra_data['total2'] = $total2;
@ -422,11 +426,11 @@ class Pedido extends \App\Controllers\BaseResourceController
$result = DataTable::of($q)
->edit(
'fecha',
fn($q) => $q->fecha?Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y"):""
fn($q) => $q->fecha ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y") : ""
)
->edit(
'fecha_entrega',
fn($q) => $q->fecha_entrega?Time::createFromFormat("Y-m-d H:i:s", $q->fecha_entrega)->format("d/m/Y"):""
fn($q) => $q->fecha_entrega ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_entrega)->format("d/m/Y") : ""
)
->edit(
"estado",
@ -453,13 +457,14 @@ class Pedido extends \App\Controllers\BaseResourceController
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true) ;
return $result->toJson(returnAsObject: true);
}
public function obtenerTotalPedidosCliente($cliente_id){
public function obtenerTotalPedidosCliente($cliente_id)
{
$error = false;
$result = [
@ -472,37 +477,37 @@ class Pedido extends \App\Controllers\BaseResourceController
->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function obtenerPedidosForFacturas(){
public function obtenerPedidosForFacturas()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
$start = $reqData['start'] ?? 0;
}
else {
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function getlineas(){
public function getlineas()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns']) ) {
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
$errstr = 'No data available in response to this specific request.';
$response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr);
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
return $response;
}
$id = $reqData['pedido_id'] ?? 0;
$resourceData = $this->model->obtenerLineasPedido($id);
@ -517,25 +522,26 @@ class Pedido extends \App\Controllers\BaseResourceController
}
public function addFactura(){
public function addFactura()
{
if ($this->request->isAJAX()) {
if($this->request->isAJAX()){
$modelFactura = model('App\Models\Facturas\FacturaModel');
$modelFacturaLinea = model('App\Models\Facturas\FacturaLineaModel');
$pedido_id = $this->request->getPost('pedido_id');
$serie_id = $this->request->getPost('serie_id');
$datosFactura = $this->model->obtenerDatosForFactura($pedido_id);
if(count($datosFactura) == 0){
if (count($datosFactura) == 0) {
return $this->respond(['status' => 'error', 'message' => 'Error obteniendo datos de factura']);
}
$datosFactura = $datosFactura[0];
$modelFactura->insert([
'cliente_id' => $datosFactura->cliente_id,
'serie_id' => $serie_id,
@ -555,13 +561,13 @@ class Pedido extends \App\Controllers\BaseResourceController
$factura_id = $modelFactura->getInsertID();
if($factura_id){
if ($factura_id) {
$model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel');
$lineas = $model_pedido_linea->where('pedido_id', $pedido_id)->first();
$facturas = new Facturas();
$result = $facturas->addLineaPedidoImpresion($factura_id, $lineas->id);
if($result['error'] == 0){
if ($result['error'] == 0) {
// Se actualiza el precio total de la factura obtenido de la linea añadida
$linea_added = $modelFacturaLinea->where('factura_id', $factura_id)->first();
$modelFactura->set([
@ -570,27 +576,28 @@ class Pedido extends \App\Controllers\BaseResourceController
'pendiente' => $linea_added->total,
])->where('id', $factura_id)->update();
return $this->respond(['status' => 'success', 'id' => $factura_id, 'message' => lang('Basic.global.success')]);
}else{
} else {
return $this->respond(['status' => 'error', 'message' => 'Error insertando lineas de factura']);
}
}
return $this->respond(['status' => 'error', 'message' => 'Error insertando factura']);
}else{
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
private function obtenerDatosFormulario(&$pedidoEntity){
private function obtenerDatosFormulario(&$pedidoEntity)
{
$datos = $this->model->obtenerDatosForm($pedidoEntity->id);
$pedidoEntity->estadoText = lang('Pedidos.' . $pedidoEntity->estado);
if(count($datos) > 0){
if (count($datos) > 0) {
$pedidoEntity->cliente = $datos[0]->cliente;
$pedidoEntity->cliente_id = $datos[0]->cliente_id;
$pedidoEntity->comercial = $datos[0]->comercial;
@ -602,8 +609,8 @@ class Pedido extends \App\Controllers\BaseResourceController
$pedidoEntity->fecha_entrega_externo_text = $pedidoEntity->fecha_entrega_externo ? date('d/m/Y', strtotime($pedidoEntity->fecha_entrega_externo)) : '';
$userModel = model('App\Models\Usuarios\UserModel');
$pedidoEntity->created_by = $userModel->getFullName($pedidoEntity->user_created_id);
$pedidoEntity->updated_by = $userModel->getFullName($pedidoEntity->user_updated_id);
$pedidoEntity->created_by = $userModel->getFullName($pedidoEntity->user_created_id);
$pedidoEntity->updated_by = $userModel->getFullName($pedidoEntity->user_updated_id);
$pedidoEntity->created_at_footer = $pedidoEntity->created_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->created_at)) : '';
$pedidoEntity->updated_at_footer = $pedidoEntity->updated_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->updated_at)) : '';
}
@ -613,21 +620,36 @@ class Pedido extends \App\Controllers\BaseResourceController
// $xml_service = new PedidoXMLService($this->model);
return $this->respond($data);
}
public function to_produccion($pedido_id)
{
$serviceProduction = service('production');
$pedido = $this->model->find($pedido_id);
$cliente = $pedido->presupuesto()->cliente_id;
$serviceProduction->setPedido($pedido);
if($pedido->orden_trabajo()){
return $this->response->setJSON(["status"=>false,"data"=>$pedido->orden_trabajo(),"message" => "Ya existe una orden de trabajo para este pedido"]);
if ($pedido->orden_trabajo()) {
return $this->response->setJSON(["status" => false, "data" => $pedido->orden_trabajo(), "message" => "Ya existe una orden de trabajo para este pedido"]);
}else{
} else {
$r = $serviceProduction->createOrdenTrabajo();
$this->model->set(['estado' => 'produccion'])->where('id', $pedido_id)->update();
return $this->response->setJSON(["status"=>true, "data"=>$r,"message" => "Orden trabajo creada correctamente"]);
$clienteModel = model('App\Models\Clientes\ClienteModel');
$cliente = $clienteModel->find($cliente);
if ($cliente) {
if ($cliente->tirada_flexible == 1) {
$ejemplares_tirada_flexible = intval($pedido->total_tirada * 0.05);
$comentario = lang('OrdenTrabajo.tiradaFlexible', [
'unidades' => $ejemplares_tirada_flexible
]) . "\n" . trim($cliente->comentarios_tirada_flexible);
$serviceProduction->init($r->id)->updateOrdenTrabajoData([
'name' => 'comment_logistica',
'comment_logistica' => $comentario
]);
}
}
return $this->response->setJSON(["status" => true, "data" => $r, "message" => "Orden trabajo creada correctamente"]);
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Controllers\Presupuestos;
use App\Models\Presupuestos\ImportadorModel;
use App\Models\Clientes\ClienteModel;
use App\Services\PresupuestoService;
use stdClass;
class Importadorpresupuestos extends \App\Controllers\BaseResourceController
@ -484,6 +485,14 @@ class Importadorpresupuestos extends \App\Controllers\BaseResourceController
$isColor = true;
}
// se recalcula isColor y isHq
[$isColor, $isHq] = PresupuestoService::getCalidad(
'admin',
null,
$isColor,
$isHq,
intval($this->request->getPost('tirada') ?? 0));
$tapaCubierta = model('App\Models\Configuracion\TipoPresupuestoModel')->
select("is_tapa_dura")->where('id', $tipo_presupuesto_id)->first();
$tapaCubierta = $tapaCubierta->is_tapa_dura == 0 ? "tapaBlanda" : "tapaDura";

View File

@ -130,11 +130,10 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$POD = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
$ancho = 0;
$alto = 0;
if(isset($sanitizedData['papel_formato_personalizado']) && $sanitizedData['papel_formato_personalizado'] == '1'){
if (isset($sanitizedData['papel_formato_personalizado']) && $sanitizedData['papel_formato_personalizado'] == '1') {
$ancho = $sanitizedData['papel_formato_ancho'];
$alto = $sanitizedData['papel_formato_alto'];
}
else{
} else {
$papelFormatoModel = new PapelFormatoModel();
$papelFormato = $papelFormatoModel->find($sanitizedData['papel_formato_id']);
$ancho = $papelFormato->ancho;
@ -152,7 +151,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
]);
$model = new PresupuestoEncuadernacionesModel();
foreach($servDefectoEnc as $servicio){
foreach ($servDefectoEnc as $servicio) {
$data = [
'presupuesto_id' => $id,
@ -202,6 +201,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$this->viewData['pais_default_id'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_pais_defecto')->value;
$this->viewData['pais_default'] = model('App\Models\Configuracion\PaisModel')->find($this->viewData['pais_default_id'])->nombre;
$this->viewData['no_envio_base'] = 0;
$this->viewData['formAction'] = route_to('createPresupuestoAdmin', $tipo_impresion_id);
$this->viewData = array_merge($this->viewData, $this->getStringsFromTipoImpresion($tipo_impresion_id));
@ -236,12 +237,14 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$postData = $this->request->getPost();
$postData['updated_at'] = gmdate('Y-m-d H:m:s', time());
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
$sanitizedData['user_updated_id'] = auth()->user()->id;
if(isset($sanitizedData['total_aceptado_revisado']) && $sanitizedData['total_aceptado_revisado'] != 0
&& $sanitizedData['total_aceptado_revisado'] != null && $sanitizedData['total_aceptado_revisado'] != ""){
if (
isset($sanitizedData['total_aceptado_revisado']) && $sanitizedData['total_aceptado_revisado'] != 0
&& $sanitizedData['total_aceptado_revisado'] != null && $sanitizedData['total_aceptado_revisado'] != ""
) {
$sanitizedData['aprobado_at'] = $sanitizedData['updated_at'];
$sanitizedData['aprobado_user_id'] = $sanitizedData['user_updated_id'];
}
@ -367,9 +370,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
// modificar los datos del pedido y de la factura si no está la factura validada
if ($presupuestoEntity->estado_id == 2){
if ($presupuestoEntity->estado_id == 2) {
$facturaModel = model('App\Models\Facturas\FacturaModel');
if(!$facturaModel->presupuestoHasFacturaValidada($id)){
if (!$facturaModel->presupuestoHasFacturaValidada($id)) {
// se actualiza primero el pedido
$pedidoModel = model('App\Models\Pedidos\PedidoLineaModel');
$pedidoLineaId = $pedidoModel->where('presupuesto_id', $id)->first()->id;
@ -434,6 +437,10 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$this->viewData['POD'] = $this->getPOD();
$this->viewData['no_envio_base'] = model('App\Models\Clientes\ClienteModel')->where('id', $presupuestoEntity->cliente_id)->first();
if ($this->viewData['no_envio_base'])
$this->viewData['no_envio_base'] = $this->viewData['no_envio_base']->no_envio_base;
$this->viewData['serviciosAutomaticos'] = [
'solapas_cubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_cubierta')->value,
'solapas_sobrecubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_sobrecubierta')->value,
@ -459,11 +466,11 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$modelPedidoLinea = new \App\Models\Pedidos\PedidoLineaModel();
$linea = $modelPedidoLinea->where('presupuesto_id', $id)->first();
if($linea){
if ($linea) {
$this->viewData['pedido_id'] = $linea->pedido_id;
$modelOrden = new \App\Models\OrdenTrabajo\OrdenTrabajoModel();
$orden = $modelOrden->where('pedido_id', $linea->pedido_id)->first();
if($orden){
if ($orden) {
$this->viewData['orden_id'] = $orden->id;
}
}
@ -633,7 +640,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['comparador']['json_data'] = json_decode($presupuesto->comparador_json_data, true);
if ($data['comparador']['json_data'] != null) {
foreach ($data['comparador']['json_data'] as &$item) {
if(intval($item['papel_id'])>0)
if (intval($item['papel_id']) > 0)
$item['papel_nombre'] = $modelPapelGenerico->getNombre($item['papel_id'])['nombre'];
}
}
@ -657,7 +664,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['comentarios_pdf'] = $presupuesto->comentarios_pdf;
$data['comentarios_presupuesto'] = $presupuesto->comentarios_presupuesto;
$data['comentarios_produccion'] = $presupuesto->comentarios_produccion;
$data['tiradasAlternativas'] = json_decode($presupuesto->tirada_alternativa_json_data);
@ -688,9 +695,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['resumen']['total_factor_ponderado'] = is_numeric($presupuesto->total_factor_ponderado) ? $presupuesto->total_factor_ponderado : 0;
$data['total_aceptado_revisado'] = $presupuesto->total_aceptado_revisado;
$data['aprobado_by_at'] = ($presupuesto->aprobado_user_id != null)?
model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->aprobado_user_id) . ', '
. date('d/m/Y H:i:s', strtotime($presupuesto->aprobado_at)):'';
$data['aprobado_by_at'] = ($presupuesto->aprobado_user_id != null) ?
model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->aprobado_user_id) . ', '
. date('d/m/Y H:i:s', strtotime($presupuesto->aprobado_at)) : '';
$data['resumen']['iva_reducido'] = $presupuesto->iva_reducido;
@ -811,7 +818,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$paginas_color = $sobrecubierta['datosPedido']['paginas'] ?? 0;
$tipo_impresion_id = $sobrecubierta['tipo_impresion_id'];
$faja = intval($sobrecubierta['faja'] ?? 0);
$uso = $faja==1? 'faja' : $sobrecubierta['uso'];
$uso = $faja == 1 ? 'faja' : $sobrecubierta['uso'];
$data = array(
@ -1076,20 +1083,22 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
if($calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) >0 && $resourceData[0]['fields']['num_formas'] > 0) {
if (
$calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) > 0 && $resourceData[0]['fields']['num_formas'] > 0
) {
usort($resourceData, function ($a, $b) {
return $b['fields']['total_impresion'] <=> $a['fields']['total_impresion'];
});
$num_formas = [];
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
array_push($num_formas, $formas_linea);
$POD = $this->getPOD();
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada,$POD, $num_formas);
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
}
@ -1126,20 +1135,22 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);
if($calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) >0 && $resourceData[0]['fields']['num_formas'] > 0) {
if (
$calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) > 0 && $resourceData[0]['fields']['num_formas'] > 0
) {
usort($resourceData, function ($a, $b) {
return $b['fields']['total_impresion'] <=> $a['fields']['total_impresion'];
});
$num_formas = [];
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
array_push($num_formas, $formas_linea);
$POD = $this->getPOD();
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada,$POD, $num_formas);
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);
}
@ -1209,7 +1220,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
return $this->respond($data);
} else if ($tipo == 'duplicar') {
$presupuesto_id = $reqData['presupuesto_id'] ?? -1;
$result = $this->duplicarPresupuesto($presupuesto_id);
$result = PresupuestoService::duplicarPresupuesto($presupuesto_id);
$newTokenHash = csrf_hash();
$csrfTokenName = csrf_token();
if ($result['success']) {
@ -1265,12 +1276,12 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$cubierta = false;
if ($uso == 'cubierta') {
$cubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$sobrecubierta = false;
if ($uso == 'sobrecubierta') {
$sobrecubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$guardas = false;
if ($uso == 'guardas') {
@ -1294,7 +1305,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$isPOD,
$anchoLibro,
$alto,
$tirada);
$tirada
);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("t1.nombre", $this->request->getGet("q"))
@ -1333,12 +1345,12 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$cubierta = false;
if ($uso == 'cubierta') {
$cubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$sobrecubierta = false;
if ($uso == 'sobrecubierta') {
$sobrecubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$guardas = false;
if ($uso == 'guardas') {
@ -1350,7 +1362,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
$model = model('App\Models\Configuracion\PapelGenericoModel');
$query = $model->getGramajeForComparador($tipo,
$query = $model->getGramajeForComparador(
$tipo,
$papel_generico_id,
$cubierta,
$sobrecubierta,
@ -1360,7 +1373,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$isPOD,
$anchoLibro,
$alto,
$tirada);
$tirada
);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("t2.gramaje", $this->request->getGet("q"))
@ -1593,81 +1607,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
/**
* Duplica un presupuesto dado por su ID.
*
* Esta función duplica un presupuesto y todas sus entidades relacionadas como acabados, encuadernaciones, manipulados,
* preimpresiones, direcciones y lineas. El presupuesto duplicado se marca como tal y a su título se le añade
* una cadena 'duplicado'. La función devuelve un array con un estado de éxito y el ID del nuevo presupuesto.
*
* @param int $id El ID del presupuesto a duplicar.
* @return array Un array asociativo que contiene una clave 'success' que indica el estado de éxito de la operación,
* y una clave 'id' que contiene el ID del nuevo presupuesto si la operación fue exitosa.
* Si ocurre una excepción, la clave 'success' será false y una clave 'message' contendrá el mensaje de la excepción.
* @throws \Exception Si ocurre un error durante la operación.
*/
private function duplicarPresupuesto($id)
{
try {
$presupuesto = $this->model->find($id);
$presupuesto->titulo = $presupuesto->titulo . ' - ' . lang('Presupuestos.duplicado');
$presupuesto->is_duplicado = 1;
$presupuesto->estado_id = 1;
$new_id = $this->model->insert($presupuesto);
$presupuestoAcabadosModel = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
foreach ($presupuestoAcabadosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $acabado) {
$acabado->presupuesto_id = $new_id;
$presupuestoAcabadosModel->insert($acabado);
}
$presupuestoEncuadernacionesModel = model('App\Models\Presupuestos\PresupuestoEncuadernacionesModel');
foreach ($presupuestoEncuadernacionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $encuadernacion) {
$encuadernacion->presupuesto_id = $new_id;
$presupuestoEncuadernacionesModel->insert($encuadernacion);
}
$presupuestoManipuladosModel = model('App\Models\Presupuestos\PresupuestoManipuladosModel');
foreach ($presupuestoManipuladosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $manipulado) {
$manipulado->presupuesto_id = $new_id;
$presupuestoManipuladosModel->insert($manipulado);
}
$presupuestoPreimpresionesModel = model('App\Models\Presupuestos\PresupuestoPreimpresionesModel');
foreach ($presupuestoPreimpresionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $preimpresion) {
$preimpresion->presupuesto_id = $new_id;
$presupuestoPreimpresionesModel->insert($preimpresion);
}
$presupuestoServiciosExtraModel = model('App\Models\Presupuestos\PresupuestoServiciosExtraModel');
foreach ($presupuestoServiciosExtraModel->where('presupuesto_id', $presupuesto->id)->findAll() as $servicioExtra) {
$servicioExtra->presupuesto_id = $new_id;
$presupuestoServiciosExtraModel->insert($servicioExtra);
}
$presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
foreach ($presupuestoDireccionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $direccion) {
$direccion->presupuesto_id = $new_id;
$presupuestoDireccionesModel->insert($direccion);
}
$presupuestoLineaModel = model('App\Models\Presupuestos\PresupuestoLineaModel');
$presupuestoLineaModel->duplicateLineasPresupuesto($presupuesto->id, $new_id);
return [
'success' => true,
'id' => $new_id
];
} catch (\Exception $e) {
return [
'success' => false,
'message' => $e->getMessage()
];
}
}
public function allItemsSelect()
{
@ -1806,10 +1745,11 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$result = DataTable::of($q)
->edit(
'fecha',
fn($q) => $q->fecha?Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y"):""
fn($q) => $q->fecha ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y") : ""
)
->edit(
'estado', fn($q) => match ($q->estado) {
'estado',
fn($q) => match ($q->estado) {
"1" => lang('Presupuestos.borrador'),
"2" => lang('Presupuestos.confirmado'),
default => '--'
@ -1820,13 +1760,14 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true) ;
return $result->toJson(returnAsObject: true);
}
public function obtenerTotalPresupuestosCliente($cliente_id){
public function obtenerTotalPresupuestosCliente($cliente_id)
{
$error = false;
$result = [
@ -1837,17 +1778,17 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
->where('presupuestos.cliente_id', $cliente_id)
->select('SUM(presupuestos.total_aceptado) as total')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function obtenerTotalPedidosCliente($cliente_id){
public function obtenerTotalPedidosCliente($cliente_id)
{
$error = false;
$result = [
@ -1860,14 +1801,58 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function hasFiles()
{
if ($this->request->isAJAX()) {
$id = $this->request->getGet('id');
$presupuesto = $this->model->find($id);
if (!$presupuesto) {
return $this->respond([
'status' => 'error',
'message' => lang('Presupuestos.presupuestoNotFound'),
]);
}
$files = $presupuesto->files() ?? [];
if (count($files) == 0) {
return $this->respond([
'status' => 'success',
'hasFiles' => false,
]);
} else {
return $this->respond([
'status' => 'success',
'hasFiles' => true,
]);
}
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function reprintPresupuesto()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id');
$duplicateFiles = $this->request->getPost('duplicateFiles') ?? false;
$response = PresupuestoService::duplicarPresupuesto($id, true, $duplicateFiles);
return $this->respond($response);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
@ -1897,7 +1882,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$modelPapel = new PapelGenericoModel();
foreach ($lineas as $linea) {
$linea->papel_generico = (new PapelGenericoModel())->find($linea->papel_id)->nombre;
if($linea->tipo == 'lp_faja'){
if ($linea->tipo == 'lp_faja') {
$linea->alto_faja = $presupuestoEntity->alto_faja_color;
}
}
@ -1966,4 +1951,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
return $direcciones;
}
}

View File

@ -332,15 +332,15 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$forzarRotativa = false;
if ($tirada[0] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
'uso' => 'interior',
'tipo_impresion_id' => $tipo_impresion_id,
@ -463,7 +463,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
//$reqData = $this->request->getPost();
$modelPapelGenerico = new PapelGenericoModel();
$id = $reqData['id'] ?? 0;
$cliente_id = $reqData['clienteId'] ?? -1;
@ -760,13 +759,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$forzarRotativa = false;
if ($tirada[0] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
@ -1340,7 +1338,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datos_presupuesto['entrega_taller'] = $reqData['entrega_taller'] ?? 0;
$resultado_presupuesto['info']['merma'] = PresupuestoService::calcular_merma($selected_tirada, $POD);
$resultado_presupuesto['info']['merma'] = isset($resultado_presupuesto['info']['num_formas']) ?
PresupuestoService::calcular_merma($selected_tirada, $POD, $resultado_presupuesto['info']['num_formas']) : PresupuestoService::calcular_merma($selected_tirada, $POD);
$datos_presupuesto['faja'] = $faja;
@ -2079,13 +2078,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[$t] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$forzarRotativa = false;
if ($tirada[$t] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
@ -2155,6 +2153,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$input_data['datosPedido']->merma = PresupuestoService::calcular_merma($tirada[$t], $POD, $num_formas);
if ($extra_info) {
$info['merma'] = max($info['merma'], $input_data['datosPedido']->merma);
$info['num_formas'] = $num_formas;
}
$interior = PresupuestoClienteService::obtenerInterior($input_data);
if ($interior == -1) {
@ -2270,7 +2269,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
return $return_data;
}
$cantidad_total = intval($datosPedido->tirada) + intval($datosPedido->merma);
$cantidad_total = intval($datosPedido->tirada);// + intval($datosPedido->merma);
// Acabado Cubierta
if (intval($datos_entrada['cubierta']['acabado']) != 0) {
@ -3584,4 +3583,29 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
return $servicios;
}
public function download_zip()
{
$presupuesto_id = $this->request->getPost('presupuesto_id');
if (!$presupuesto_id) {
return $this->response->setStatusCode(400)->setBody('Presupuesto ID requerido');
}
$ftpClient = new \App\Libraries\SafekatFtpClient();
try {
$zipPath = $ftpClient->downloadZipPresupuesto((int) $presupuesto_id);
if ($zipPath === null || !file_exists($zipPath)) {
return $this->response->setStatusCode(404)->setBody('No se encontraron archivos');
}
return $this->response
->download($zipPath, null) // null = usar nombre original del archivo
->setFileName('archivos_presupuesto_' . $presupuesto_id . '.zip');
} catch (\Throwable $e) {
log_message('error', $e->getMessage());
return $this->response->setStatusCode(500)->setBody('Error interno');
}
}
}

View File

@ -5,11 +5,14 @@ namespace App\Controllers\Produccion;
use App\Controllers\BaseController;
use App\Models\Compras\ProveedorModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Configuracion\MaquinaOtTareaModel;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use App\Models\OrdenTrabajo\OrdenTrabajoUser;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\UserModel;
use App\Services\EtiquetasTitulosService;
use App\Services\ImpresoraEtiquetaService;
use App\Services\ProductionService;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\RequestInterface;
@ -21,6 +24,7 @@ use Exception;
use Hermawan\DataTables\DataTable;
use Psr\Log\LoggerInterface;
class Ordentrabajo extends BaseController
{
protected $format = 'json';
@ -31,6 +35,7 @@ class Ordentrabajo extends BaseController
protected OrdenTrabajoTarea $otTarea;
protected ProveedorModel $proveedorModel;
protected MaquinaModel $maquinaModel;
protected MaquinaOtTareaModel $maquinaOtTareaModel;
protected UserModel $userModel;
protected Validation $validation;
protected static $viewPath = 'themes/vuexy/form/produccion/';
@ -47,6 +52,7 @@ class Ordentrabajo extends BaseController
$this->produccionService = new ProductionService();
$this->otTarea = model(OrdenTrabajoTarea::class);
$this->maquinaModel = model(MaquinaModel::class);
$this->maquinaOtTareaModel = model(MaquinaOtTareaModel::class);
$this->proveedorModel = model(ProveedorModel::class);
$this->validation = service("validation");
helper("time");
@ -110,6 +116,8 @@ class Ordentrabajo extends BaseController
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_tarea");
if ($validated) {
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
$this->produccionService->init($tareaEntity->orden_trabajo_id);
$r = $this->produccionService->updateOrdenTrabajoTarea($bodyData["orden_trabajo_tarea_id"], $bodyData);
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $tareaEntity]);
@ -141,7 +149,8 @@ class Ordentrabajo extends BaseController
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function update_presupuesto_tarea_proveedor(){
public function update_presupuesto_tarea_proveedor()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "proveedor_tarea");
if ($validated) {
@ -151,7 +160,6 @@ class Ordentrabajo extends BaseController
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function reset_orden_trabajo_date()
{
@ -161,6 +169,7 @@ class Ordentrabajo extends BaseController
if ($validated) {
$validatedData = $bodyData;
$r = $this->produccionService->emptyOrdenTrabajoDate($validatedData['orden_trabajo_id'], $validatedData['name']);
$this->produccionService->init($validatedData['orden_trabajo_id']); // Re-init service to update the state of the OT
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "user" => auth()->user(), "data" => $bodyData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
@ -216,8 +225,9 @@ class Ordentrabajo extends BaseController
$this->viewData["user_dates"] = $this->produccionService->userDates();
$this->viewData["pedido_user_dates"] = $this->produccionService->pedidoUserDates();
$this->viewData["colors"] = $this->produccionService->getPdfColors();
$this->viewData["tiempo_estimado"] = $this->produccionService->getTiempoProcesamientoHHMM();
$this->viewData["tiempo_estimado"] = $this->produccionService->getTiempoProcesamientoHHMMSS();
$this->viewData["flags"] = $this->produccionService->getFlags();
$this->viewData["tareaCosido"] = $this->produccionService->getTareaCosido();
return view(static::$viewPath . $this->editRoute, $this->viewData);
@ -236,13 +246,14 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_pendientes()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->whereIn("ordenes_trabajo.estado", ["I", "PM"]);
$q = $this->otModel->getDatatableQuery()->whereIn("ordenes_trabajo.estado", ["I", "PM"])->where('ordenes_trabajo.preimpresion_revisada', true);
// return $this->response->setJSON($q->get()->getResultArray());
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
@ -251,13 +262,14 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_ferro_pendiente()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro',1)->where("ferro_ok_at", null);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at", null);
// return $this->response->setJSON($q->get()->getResultArray());
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
@ -266,13 +278,14 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_ferro_ok()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro',1)->where("ferro_ok_at is NOT NULL", NULL, FALSE);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at is NOT NULL", NULL, FALSE);
// return $this->response->setJSON($q->get()->getResultArray());
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
@ -281,6 +294,67 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_news()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.preimpresion_revisada', false);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_prod()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.preimpresion_revisada', true)->where('pedidos.estado', 'produccion');
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_waiting()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.is_pedido_espera', 1);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_revision_com()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at is NOT NULL", NULL, FALSE);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function papel_gramaje_datatable()
@ -301,9 +375,23 @@ class Ordentrabajo extends BaseController
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_paper'), 'data' => $q])
->toJson(true);
}
public function maquina_plana_datatable()
{
// return $this->response->setStatusCode(400);
$padreId = $this->request->getGet('padre_id');
$q = $this->produccionService->maquinaPlanaDatatableQuery();
if ($padreId) {
$q->where('lg_maquinas.padre_id', $padreId);
}
return DataTable::of($q)
->edit("tiempoReal", fn($q) => $q->tiempoReal)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_machine'), 'data' => $q])
->toJson(true);
}
public function reset_tareas(int $orden_trabajo_id)
{
$r = $this->produccionService->init($orden_trabajo_id)->resetAllTareas();
$this->produccionService->init($orden_trabajo_id); // Re-init service to update the state of the OT
return $this->response->setJSON(["message" => "Tareas reseteadas", "status" => $r]);
}
public function delete_tarea(int $orden_trabajo_tarea_id)
@ -318,8 +406,9 @@ class Ordentrabajo extends BaseController
return DataTable::of($q)
->add("action", fn($q) => $q)
->edit("orden", fn($q) => ["id" => $q->id, "orden" => $q->orden])
->edit("tiempo_estimado", fn($q) => float_seconds_to_hhmm_string($q->tiempo_estimado))
->edit("tiempo_real", fn($q) => float_seconds_to_hhmm_string($q->tiempo_real))
->add("tarea_estado", fn($q) => $this->produccionService->getTitleTareaEstado($q->id))
->edit("tiempo_estimado", fn($q) => float_seconds_to_hhmmss_string($q->tiempo_estimado))
->edit("tiempo_real", fn($q) => float_seconds_to_hhmmss_string($q->tiempo_real))
->add("proveedor", fn($q) => $this->produccionService->getProveedorTarea($q->id))
->edit("maquina_tarea", fn($q) => ["id" => $q->id, "maquina_id" => $q->maquina_tarea, "maquina_name" => $q->maquina_nombre])
->add("imposicion", fn($q) => ["id" => $q->id, "imposicion_id" => $q->imposicion_id, "name" => $q->imposicion_name, "is_presupuesto_linea" => $q->presupuesto_linea_id ? true : false])
@ -415,10 +504,7 @@ class Ordentrabajo extends BaseController
public function planning_plana_datatable()
{
$query = $this->produccionService->planningPlanaQueryDatatable();
$padreId = $this->request->getGet('padre_id');
if ($padreId) {
$query->where('lg_maquinas.padre_id', $padreId);
}
return DataTable::of($query)
->edit("tiempo_real_sum", fn($q) => $q->tiempo_real_sum)
->edit("fecha_entrega_real_at", fn($q) => $q->fecha_entrega_real_at ? Time::createFromFormat("Y-m-d", $q->fecha_entrega_real_at)->format("d/m/Y") : "")
@ -441,7 +527,8 @@ class Ordentrabajo extends BaseController
public function select_maquina_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectMaquinaPlanningPlana($q);
$padreId = $this->request->getGet('padre_id');
$result = $this->produccionService->querySelectMaquinaPlanningPlana($q, $padreId);
return $this->response->setJSON($result);
}
public function select_maquina_padre_planning_plana()
@ -453,7 +540,8 @@ class Ordentrabajo extends BaseController
public function select_papel_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectPapelPlanningPlana($q);
$maquinaId = $this->request->getGet('maquina_id');
$result = $this->produccionService->querySelectPapelPlanningPlana($q,$maquinaId);
return $this->response->setJSON($result);
}
public function tarea_toggle_corte($orden_trabajo_id)
@ -544,23 +632,60 @@ class Ordentrabajo extends BaseController
['title' => $maquina->nombre, 'route' => route_to("viewProduccionMaquinistaMaquina", $maquina_id), 'active' => true],
];
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
$tareasRunning = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina->id)->countAllResults();
if ($tareasRunning) {
return view(static::$viewPath . '/maquinista/viewProduccionMaquinistaOtTareasView', $this->viewData);
} else {
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
}
}
public function maquinista_maquina_tareas_fichaje_automatico(int $maquina_id)
{
$maquina = $this->maquinaModel->find($maquina_id);
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaFichajeAutomatico', $this->viewData);
}
public function maquinista_maquina_tareas_scan(int $maquina_id)
{
$maquina = $this->maquinaModel->find($maquina_id);
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaTareaScan', $this->viewData);
}
public function maquinista_maquina_tarea_view(int $orden_trabajo_tarea_id)
{
$modelImpresoras = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresoras->select('id, name')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
->findAll();
$impresoras = array_map(fn($impresora) => $impresora->toArray(), $impresoras);
$otTareaEntity = $this->otTarea->find($orden_trabajo_tarea_id);
$this->viewData['ot_tarea'] = $otTareaEntity;
$this->viewData['ot'] = $otTareaEntity->orden_trabajo();
$this->viewData['presupuesto'] = $this->viewData['ot']->presupuesto();
$this->viewData['impresoras'] = $impresoras;
$this->viewData['breadcrumb'] = [
['title' => lang("Produccion.maquinista.maquinas"), 'route' => route_to("viewProduccionMaquinistaMaquinas"), 'active' => false],
['title' => $otTareaEntity->maquina_actual()->nombre, 'route' => route_to("viewProduccionMaquinaTareasList", $otTareaEntity?->maquina_actual()?->id), 'active' => true],
['title' => $otTareaEntity->nombre, 'route' => route_to("viewProduccionMaquinistaTareaView", $otTareaEntity->id), 'active' => true]
];
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTarea', $this->viewData);
}
public function maquinista_maquina_ot_tareas_view(int $maquina_id)
{
$maquinaEntity = $this->maquinaModel->find($maquina_id);
$this->viewData['maquinaEntity'] = $maquinaEntity;
$tareasRunning = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina_id)->countAllResults();
if ($tareasRunning) {
return view(static::$viewPath . '/maquinista/viewProduccionMaquinistaOtTareasView', $this->viewData);
} else {
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
}
}
public function maquinista_colas_view()
{
return view(static::$viewPath . '/maquinista/viewMaquinistaPlanningList', $this->viewData);
@ -573,6 +698,16 @@ class Ordentrabajo extends BaseController
}
return DataTable::of($pm)
->edit('fecha_impresion', fn($q) => $q->fecha_impresion ? Time::createFromFormat('Y-m-d H:i:s', $q->fecha_impresion)->format('d/m/Y') : '')
->add("tareaEstado", fn($q) => $this->produccionService->getTitleTareaEstado($q->ot_tarea_id))
->add('action', fn($q) => $this->produccionService->buttonActionDatatableTareaList($q->ot_tarea_id))
->toJson(true);
}
public function maquinista_maquina_tareas_aplazada_datatable(int $maquina_id)
{
$pm = $this->produccionService->getMaquinaImpresionTareasList($maquina_id)->where("tarea_progress.estado", 'D');
return DataTable::of($pm)
->edit('fecha_impresion', fn($q) => $q->fecha_impresion ? Time::createFromFormat('Y-m-d H:i:s', $q->fecha_impresion)->format('d/m/Y') : '')
->add("tareaEstado", fn($q) => $this->produccionService->getTitleTareaEstado($q->ot_tarea_id))
->add('action', fn($q) => $this->produccionService->buttonActionDatatableTareaList($q->ot_tarea_id))
->toJson(true);
}
@ -583,10 +718,16 @@ class Ordentrabajo extends BaseController
try {
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_tarea_progress_date");
// return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "data" => $this->validation->getValidated(),"errors" => $this->validation->getErrors()]);
if ($validated) {
$r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($this->validation->getValidated());
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $bodyData]);
$validatedData = $this->validation->getValidated();
$r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($validatedData);
$otTareaEntity = $this->otTarea->find($validatedData['ot_tarea_id']);
$data = [
"tiempo_trabajado" => float_seconds_to_hhmmss_string($otTareaEntity->tiempo_real),
"tarea" => $otTareaEntity,
"estado" => $validatedData['estado'],
];
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $data]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
@ -603,27 +744,248 @@ class Ordentrabajo extends BaseController
{
$otTareaEntity = $this->otTarea->find($orden_trabajo_tarea_id);
$data = [
"tiempo_trabajado" => float_seconds_to_hhmm_string($otTareaEntity->tiempo_trabajado()),
"tiempo_trabajado" => float_seconds_to_hhmmss_string($otTareaEntity->tiempo_trabajado()),
"progress_dates" => $otTareaEntity->progress_dates(),
];
return $this->response->setJSON($data);
}
public function update_pod_pedido_dates($orden_trabajo_id)
{
$this->produccionService->init($orden_trabajo_id);
if($this->produccionService->isPOD){
if ($this->produccionService->isPOD) {
$status = $this->produccionService->updatePodDates();
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $status, "data" => $this->produccionService->getPedido()]);
}else{
} else {
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => false, "data" => $this->produccionService->getPedido()]);
}
}
public function get_orden_trabajo_tareas_dates($orden_trabajo_id)
{
$data = $this->produccionService->init($orden_trabajo_id)->getOrdenTrabajoTareaDates();
return $this->response->setJSON(["data" => $data ]);
return $this->response->setJSON(["data" => $data]);
}
public function get_tareas_ot_maquina(int $orden_trabajo_id, int $maquina_id)
{
$tareasWithMaquina = $this->produccionService->init($orden_trabajo_id)->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
if ($tareasWithMaquina) {
$data = [
'tareas' => $tareasWithMaquina,
'ot' => $this->produccionService->getOrdenTrabajo(),
'presupuesto' => $this->produccionService->getPresupuesto()
];
return $this->response->setJSON(["message" => lang("App.global_alert_fetch_success"), "data" => $data]);
} else {
$tareasWithMaquina = $this->produccionService->init($orden_trabajo_id)->getTareasWithMaquina($maquina_id, ['F']);
if ($tareasWithMaquina) {
return $this->response->setJSON(["message" => lang("Produccion.errors.tareas_finalizadas"), "data" => $tareasWithMaquina])->setStatusCode(400);
} else {
return $this->response->setJSON(["message" => lang("Produccion.errors.maquina_not_in_ot"), "data" => null])->setStatusCode(400);
}
}
}
public function update_orden_trabajo_fa_tareas()
{
$responseData = [
"tiempo_total_estimado" => 0,
"tiempo_total_real" => 0,
"clicks_total" => 0,
"tirada_total" => 0,
"estado" => "P",
];
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_fichaje_auto");
if ($validated) {
$validatedData = $this->validation->getValidated();
$this->produccionService->init($validatedData['orden_trabajo_id']);
foreach ($validatedData['tareas'] as $key => $tareaId) {
$this->produccionService->storeOrdenTrabajoTareaProgressDate(
[
'estado' => $validatedData['estado'],
'ot_tarea_id' => $tareaId
]
);
$tareaEntity = $this->otTarea->find($tareaId);
$tiempo_trabajado = $tareaEntity->tiempo_trabajado();
$responseData['tiempo_total_estimado'] += $tareaEntity->tiempo_estimado;
$responseData['tiempo_total_real'] += $tiempo_trabajado;
$responseData["estado"] = $validatedData["estado"];
$tareaEntity->tiempo_real = $tiempo_trabajado / count($validatedData['tareas']);
$tareaEntity->click_init = $validatedData['click_init'] / count($validatedData['tareas']);
$tareaEntity->click_end = $validatedData['click_end'] / count($validatedData['tareas']);
$this->otTarea->save($tareaEntity);
}
$responseData['tiempo_total_estimado'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_estimado']);
$responseData['tiempo_total_real'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_real']);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $responseData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function delete_orden_trabajo_fa_tareas()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_fichaje_auto");
if ($validated) {
$validatedData = $this->validation->getValidated();
$this->produccionService->init($validatedData['orden_trabajo_id']);
foreach ($validatedData['tareas'] as $key => $tareaId) {
$this->produccionService->deleteOrdenTrabajoTareaProgressDates($tareaId);
}
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $validatedData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function store_maquina_ordenes_trabajo()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "maquina_ordenes_trabajo");
if ($validated) {
$validatedData = $this->validation->getValidated();
foreach ($validatedData['ordenes_trabajo'] as $key => $orden_trabajo_id) {
$maquinaOtTarea = $this->maquinaOtTareaModel->where('orden_trabajo_id', $orden_trabajo_id)->where('maquina_id', $validatedData['maquina_id'])->where('deleted_at', null)->countAllResults();
if ($maquinaOtTarea) {
continue;
}
$this->maquinaOtTareaModel->insert(['maquina_id' => $validatedData['maquina_id'], 'orden_trabajo_id' => $orden_trabajo_id]);
}
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $validatedData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function update_maquina_ordenes_trabajo_estado()
{
$bodyData = $this->request->getPost();
$maquina_id = $bodyData['maquina_id'];
$estado = $bodyData['estado'];
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
$totalTareas = [];
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$this->produccionService->storeOrdenTrabajoTareaProgressDate(
[
'estado' => $estado,
'ot_tarea_id' => $tarea->id
]
);
$tarea->click_init = $bodyData['click_init'];
$tarea->click_end = $bodyData['click_end'];
$totalTareas[] = $tarea;
}
}
foreach ($totalTareas as $key => $tarea) {
$tiempo_trabajado = $tarea->tiempo_trabajado();
$tarea->tiempo_real = $tiempo_trabajado / count($totalTareas);
$tarea->click_init = $tarea->click_init / count($totalTareas);
$tarea->click_end = $tarea->click_end / count($totalTareas);
$this->otTarea->save($tarea);
}
if ($estado == "F") {
$this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
}
return $this->response->setJSON(["message" => lang("Produccion.responses.update_maquina_ordenes_trabajo_estado")]);
}
public function delete_maquina_orden_trabajo_tarea($maquina_orden_trabajo_tarea_id)
{
$status = $this->maquinaOtTareaModel->delete($maquina_orden_trabajo_tarea_id);
return $this->response->setJSON(["message" => lang("App.user_alert_delete"), "status" => $status]);
}
public function delete_maquina_orden_trabajo_all($maquina_id)
{
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$this->produccionService->deleteOrdenTrabajoTareaProgressDates($tarea->id);
}
}
$status = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
return $this->response->setJSON(["message" => lang("App.user_alert_delete"), "status" => $status]);
}
public function datatable_maquina_ordenes_trabajo($maquina_id)
{
$query = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina_id);
return DataTable::of($query)
->add('action', fn($q) => $q->otId)
->add('titulo', fn($q) => $this->otModel->find($q->otId)->presupuesto()->titulo)
->add('barcode', fn($q) => $this->otModel->find($q->otId)->getBarCode())
->toJson(true);
}
public function get_maquina_ots($maquina_id)
{
$responseData = [
"tiempo_total_estimado" => 0,
"tiempo_total_real" => 0,
"clicks_total" => 0,
"tirada_total" => 0,
"estado" => "P",
];
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$responseData['tiempo_total_estimado'] += $tarea->tiempo_estimado;
$responseData['tiempo_total_real'] += $tarea->tiempo_real;
$responseData["estado"] = $tarea->lastState()->estado;
if ($tarea->presupuesto_linea_id) {
$responseData["clicks_total"] += $tarea->presupuesto_linea()->rotativa_clicks_total;
$responseData["tirada_total"] += $tarea->orden_trabajo()->presupuesto()->tirada;
}
}
}
$responseData['tiempo_total_estimado'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_estimado']);
$responseData['tiempo_total_real'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_real']);
return $this->response->setJSON($responseData);
}
public function printPackagingLabels()
{
$ot_id = $this->request->getPost('ot_id') ?? null;
$unidades_caja = $this->request->getPost('unidades_caja') ?? null;
$impresora_id = $this->request->getPost('impresora_id') ?? null;
if ($ot_id == null || $impresora_id == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $impresora_id)
->orderBy('name', 'asc')
->first();
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
]);
}
$printerService = new ImpresoraEtiquetaService();
$result = $printerService->generateEtiquetasEmbalaje($ot_id, $unidades_caja, $impresora);
return $this->response->setJSON($result);
}
public function get_ot_pdf_content($orden_trabajo_id)
{
return $this->produccionService->init($orden_trabajo_id)->getPdfContent();
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Controllers\Scripts;
use App\Controllers\BaseController;
use App\Models\Usuarios\UserModel;
use App\Entities\Usuarios\UserEntity;
use CodeIgniter\Shield\Authentication\Passwords\IdentityModel;
class UsersIntegrity extends BaseController
{
public function completarIdentidades()
{
$userModel = new UserModel();
// Buscar usuarios safekat.com no eliminados
$usuarios = $userModel
->where('deleted_at', null)
//->like('username', '@safekat.com')
->findAll();
$resultados = [];
foreach ($usuarios as $usuario) {
$email = $usuario->username . "@safekat.com";
// 1. Verificar si el usuario ya tiene identidad tipo email_password
$tieneIdentidad = array_filter(
$usuario->getIdentities(),
fn($identity) => $identity->type === 'email_password'
);
if (!empty($tieneIdentidad)) {
$resultados[] = "✅ Ya tiene identidad: {$email}";
continue;
}
// 2. Verificar si ya existe una identidad globalmente con ese email
$db = db_connect();
$builder = $db->table('auth_identities');
$existeGlobal = $builder
->where('type', 'email_password')
->where('secret', $email)
->get()
->getFirstRow();
if ($existeGlobal) {
$resultados[] = "⚠️ Email ya registrado en otra identidad: {$email}";
continue;
}
// 3. Crear y guardar identidad
try {
$identity = $usuario->createEmailIdentity([
'email' => $email,
'password' => 'Temporal123!', // reemplazar por valor real si lo tenés
]);
//$userModel->saveEmailIdentity($identity);
$resultados[] = " Identidad creada: {$email}";
} catch (\Throwable $e) {
$resultados[] = "❌ Error con {$email}: " . $e->getMessage();
}
}
return $this->response->setJSON([
'status' => 'completado',
'procesados' => count($usuarios),
'resultados' => $resultados,
]);
}
}

View File

@ -153,7 +153,10 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController
return $this->redirect2listView();
endif;
$id = filter_var($requestedId, FILTER_SANITIZE_URL);
$ticket = $this->model->find($id);
$ticket = $this->model->select("tickets.*, CONCAT(users.first_name, ' ',users.last_name) as usuario_ticket")
->join('users', 'users.id = tickets.usuario_id', 'left')
->where('tickets.id', $id)->first();
if ($ticket == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Tickets.ticket')), $id]);
@ -275,7 +278,7 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController
$searchValues = get_filter_datatables_columns($reqData);
if (auth()->user()->can('tickets.edit')) {
if (auth()->user()->can('tickets.edit') && auth()->user()->inGroup('admin')) {
$user_id = null;
} else {
$user_id = auth()->user()->id;

View File

@ -12,7 +12,6 @@ use App\Models\Presupuestos\ImportadorModel;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\GroupModel;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Models\Catalogo\IdentificadorIskModel;
use App\Services\PresupuestoService;
use CodeIgniter\Shield\Entities\User;
@ -32,28 +31,7 @@ class Test extends BaseController
public function index()
{
$this->emailService = service('emailService');
$a= $this->emailService->send('prueba', 'Esto es una prueba', ['imnavajas@coit.es','imnavajas@gmail.com']);
echo var_dump($a);
/*$modelCL = new CatalogoLibroModel();
$modelISK = new IdentificadorIskModel();
// Obtener todos los registros sin isk
$registros = $modelCL->where('isk', null)->findAll();
$i = 0;
foreach ($registros as $registro) {
$isk = $modelISK->newIsk();
$modelCL->update($registro->id, ['isk' => $isk]);
echo "[" . $i++ . "]Asignado ISK {$isk} a ID {$registro->id}<br>";
}*/
}