From 305eea00e60c3de66682740774137928f6b19660 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Mon, 5 May 2025 00:47:00 +0200 Subject: [PATCH] fichaje automatico y escaneo --- ci4/app/Config/Routes.php | 9 + ci4/app/Config/Validation.php | 11 + .../Controllers/Produccion/Ordentrabajo.php | 148 +++++++++++- ...2025-05-04-172900_MaquinaOtTareasTable.php | 58 +++++ .../OrdenTrabajoTareaProgressDateEntity.php | 2 +- .../Tarifas/Maquinas/MaquinaOtTareaEntity.php | 45 ++++ ci4/app/Helpers/time_helper.php | 12 +- ci4/app/Language/es/Produccion.php | 7 +- ci4/app/Models/Configuracion/MaquinaModel.php | 12 +- .../Configuracion/MaquinaOtTareaModel.php | 66 ++++++ ci4/app/Services/ProductionService.php | 5 + .../cards/tarea_multiple_card_actions.php | 55 +++++ .../maquinista/viewMaquinistaMaquinaList.php | 6 +- .../maquinista/viewMaquinistaTareaScan.php | 24 +- .../viewProduccionMaquinistaOtTareasView.php | 81 +++++++ .../maquinista/maquinistaMultipleTarea.js | 223 ++++++++++++++++++ .../maquinista/maquinistaScan.js | 69 +++++- .../maquinista/viewTareaMultipleView.js | 7 + httpdocs/themes/vuexy/css/maquinista.css | 6 + 19 files changed, 821 insertions(+), 25 deletions(-) create mode 100755 ci4/app/Database/Migrations/2025-05-04-172900_MaquinaOtTareasTable.php create mode 100755 ci4/app/Entities/Tarifas/Maquinas/MaquinaOtTareaEntity.php create mode 100755 ci4/app/Models/Configuracion/MaquinaOtTareaModel.php create mode 100644 ci4/app/Views/themes/vuexy/components/cards/tarea_multiple_card_actions.php create mode 100644 ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewProduccionMaquinistaOtTareasView.php create mode 100644 httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaMultipleTarea.js create mode 100644 httpdocs/assets/js/safekat/pages/configuracion/maquinista/viewTareaMultipleView.js diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index b733f254..cc21364d 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -762,6 +762,8 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func $routes->get('datatable_waiting', 'Ordentrabajo::datatable_waiting'); $routes->get('datatable_revision_com', 'Ordentrabajo::datatable_revision_com'); $routes->get('tareas/datatable/(:num)', 'Ordentrabajo::tareas_datatable/$1', ['as' => 'datatableTareasOrdenTrabajo']); + $routes->get('maquinas/ots/datatable/(:num)','Ordentrabajo::datatable_maquina_ordenes_trabajo/$1'); + $routes->get('maquinas/ots/(:num)','Ordentrabajo::get_maquina_ots/$1'); /**====================== * UPDATES *========================**/ @@ -780,12 +782,17 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func $routes->post("update/tarea/pliegos", "Ordentrabajo::update_orden_trabajo_pliegos"); $routes->post("update/tarea/proveedor", "Ordentrabajo::update_presupuesto_tarea_proveedor"); $routes->post("fa/tareas/finish", 'Ordentrabajo::update_orden_trabajo_fa_tareas'); + $routes->post('maquinas/ots','Ordentrabajo::store_maquina_ordenes_trabajo'); + $routes->post('maquinas/ots/estado','Ordentrabajo::update_maquina_ordenes_trabajo_estado'); + /**DELETES */ $routes->delete("portada/(:num)", 'Ordentrabajo::delete_orden_trabajo_portada/$1'); $routes->delete("tarea/progress/(:num)", "Ordentrabajo::delete_orden_trabajo_progress_date/$1"); $routes->delete('reset/tareas/(:num)', 'Ordentrabajo::reset_tareas/$1'); $routes->delete('tareas/(:num)', 'Ordentrabajo::delete_tarea/$1'); + $routes->delete('maquinas/ots/(:num)', 'Ordentrabajo::delete_maquina_orden_trabajo_tarea/$1'); + $routes->delete('maquinas/ots/all/(:num)', 'Ordentrabajo::delete_maquina_orden_trabajo_all/$1'); /**====================== * FILES *========================**/ @@ -823,6 +830,8 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func $routes->get('maquinas/view/auto/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_fichaje_automatico/$1', ['as' => 'viewMaquinistaFichajeAutomatico']); $routes->get('maquinas/view/scan/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_scan/$1', ['as' => 'viewMaquinistaTareaScan']); $routes->get('maquinas/view/tarea/(:num)', 'Ordentrabajo::maquinista_maquina_tarea_view/$1', ['as' => 'viewProduccionMaquinistaTareaView']); + $routes->get('maquinas/view/maquina/ot/tareas/(:num)', 'Ordentrabajo::maquinista_maquina_ot_tareas_view/$1', ['as' => 'viewProduccionMaquinistaOtTareasView']); + $routes->get('colas/view', 'Ordentrabajo::maquinista_colas_view', ['as' => 'viewProduccionMaquinistaColas']); /** DATATABLE */ diff --git a/ci4/app/Config/Validation.php b/ci4/app/Config/Validation.php index a1acbd7a..02265475 100755 --- a/ci4/app/Config/Validation.php +++ b/ci4/app/Config/Validation.php @@ -195,6 +195,17 @@ class Validation extends BaseConfig "label" => "Click end" ], + ]; + public array $maquina_ordenes_trabajo = [ + "ordenes_trabajo" => [ + "rules" => "required", + "label" => "Orden trabajo" + ], + "maquina_id" => [ + "rules" => "required|integer", + "label" => "Máquina" + ], + ]; public array $chat_department = [ diff --git a/ci4/app/Controllers/Produccion/Ordentrabajo.php b/ci4/app/Controllers/Produccion/Ordentrabajo.php index 0beac9d9..0cf73fce 100755 --- a/ci4/app/Controllers/Produccion/Ordentrabajo.php +++ b/ci4/app/Controllers/Produccion/Ordentrabajo.php @@ -5,6 +5,7 @@ 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; @@ -31,6 +32,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 +49,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"); @@ -375,8 +378,8 @@ class Ordentrabajo extends BaseController ->add("action", fn($q) => $q) ->edit("orden", fn($q) => ["id" => $q->id, "orden" => $q->orden]) ->add("tarea_estado", fn($q) => $this->produccionService->getTitleTareaEstado($q->id)) - ->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)) + ->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]) @@ -601,7 +604,12 @@ 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) { @@ -628,9 +636,19 @@ class Ordentrabajo extends BaseController ['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); @@ -722,14 +740,14 @@ class Ordentrabajo extends BaseController 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){ + if ($tareasWithMaquina) { return $this->response->setJSON(["message" => lang("Produccion.errors.tareas_finalizadas"), "data" => $tareasWithMaquina])->setStatusCode(400); - }else{ + } else { return $this->response->setJSON(["message" => lang("Produccion.errors.maquina_not_in_ot"), "data" => null])->setStatusCode(400); } } } - + public function update_orden_trabajo_fa_tareas() { $bodyData = $this->request->getPost(); @@ -757,4 +775,120 @@ class Ordentrabajo extends BaseController 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); + + } } diff --git a/ci4/app/Database/Migrations/2025-05-04-172900_MaquinaOtTareasTable.php b/ci4/app/Database/Migrations/2025-05-04-172900_MaquinaOtTareasTable.php new file mode 100755 index 00000000..47a6fc4f --- /dev/null +++ b/ci4/app/Database/Migrations/2025-05-04-172900_MaquinaOtTareasTable.php @@ -0,0 +1,58 @@ + [ + 'type' => 'INT', + 'unsigned' => true, + 'auto_increment' => true, + ], + 'maquina_id' => [ + 'type' => 'INT', + 'unsigned' => true, + 'constraint' => 11 + ], + 'orden_trabajo_id' => [ + 'type' => 'INT', + 'unsigned' => true, + ], + + ]; + + public function up() + { + $this->forge->addField($this->COLUMNS); + $currenttime = new RawSql('CURRENT_TIMESTAMP'); + $this->forge->addField([ + 'created_at' => [ + 'type' => 'TIMESTAMP', + 'default' => $currenttime, + ], + 'updated_at' => [ + 'type' => 'TIMESTAMP', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'TIMESTAMP', + 'null' => true, + + ], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->addForeignKey('maquina_id','lg_maquinas','id','CASCADE','CASCADE','maquina_ot_tareas_maquina_id_fk'); + $this->forge->addForeignKey('orden_trabajo_id','ordenes_trabajo','id','CASCADE','CASCADE','maquina_ot_tareas_ot_id_fk'); + $this->forge->createTable("maquina_ot_tareas"); + } + + public function down() + { + $this->forge->dropTable("maquina_ot_tareas"); + } +} diff --git a/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php b/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php index 60276d7e..f0a60843 100755 --- a/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php +++ b/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php @@ -21,7 +21,7 @@ class OrdenTrabajoTareaProgressDateEntity extends Entity /** * Orden de trabajo de la tarea * - * @return OrdenTrabajoEntity + * @return OrdenTrabajoTareaEntity */ public function orden_trabajo_tarea() : OrdenTrabajoTareaEntity { diff --git a/ci4/app/Entities/Tarifas/Maquinas/MaquinaOtTareaEntity.php b/ci4/app/Entities/Tarifas/Maquinas/MaquinaOtTareaEntity.php new file mode 100755 index 00000000..86cdc5ed --- /dev/null +++ b/ci4/app/Entities/Tarifas/Maquinas/MaquinaOtTareaEntity.php @@ -0,0 +1,45 @@ + null, + "maquina_id" => null, + "orden_trabajo_id" => null, + ]; + protected $casts = [ + "id" => "integer", + "maquina_id" => "integer", + "orden_trabajo_id" => "integer", + ]; + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + /** + * Orden de trabajo + * + * @return OrdenTrabajoEntity + */ + public function orden_trabajo_tarea(): OrdenTrabajoEntity + { + $m = model(OrdenTrabajoModel::class); + return $m->find($this->attributes["orden_trabajo_id"]); + } + /** + * Maquina + * + * @return Maquina + */ + public function maquina(): Maquina + { + $m = model(MaquinaModel::class); + return $m->find($this->attributes["maquina_id"]); + } +} diff --git a/ci4/app/Helpers/time_helper.php b/ci4/app/Helpers/time_helper.php index 6e1381ce..fb4bcffe 100755 --- a/ci4/app/Helpers/time_helper.php +++ b/ci4/app/Helpers/time_helper.php @@ -10,7 +10,17 @@ function float_seconds_to_hhmm_string(?float $time):?string } return $time_str; } - +function float_seconds_to_hhmmss_string(?float $time): ?string +{ + $time_str = null; + if ($time !== null) { + $hours = floor($time / 3600); + $minutes = floor(($time % 3600) / 60); + $seconds = floor($time % 60); + $time_str = sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds); + } + return $time_str; +} function week_day_humanize(int $week_day,bool $upper = false) : string { $week_days = ["Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"]; diff --git a/ci4/app/Language/es/Produccion.php b/ci4/app/Language/es/Produccion.php index 266deb21..c9c7ddce 100755 --- a/ci4/app/Language/es/Produccion.php +++ b/ci4/app/Language/es/Produccion.php @@ -164,7 +164,8 @@ return [ "placeholder_ot_id" => "Introduce el ID de la OT", "fa_ot_input_form_text" => "Introduce una OT para terminar la actual e iniciar la siguiente.", "scan_ot_input_form_text" => "Introduce una OT para añadirla al proceso", - "next_scan_ot" => "Comenzar" + "next_scan_ot" => "Comenzar", + "reset" => "Resetear" ], @@ -188,7 +189,11 @@ return [ "comentariosEncuadernacion" => "Comentarios encuadernación", "comentariosLogistica" => "Comentarios logística", "info_solapa_guillotina" => "Datos solapa y preparación guillotina", + "responses" => [ + "finish_maquina_ordenes_trabajo" => "Tareas finalizadas correctamente", + "update_maquina_ordenes_trabajo_estado" => "Tareas actualizadas correctamente", + ], "errors" => [ "maquina_not_in_ot" => "Esta OT no tiene ninguna tarea con esta máquina", "tareas_finalizadas" => "Las tareas de esta OT y máquina están marcadas como finalizadas", diff --git a/ci4/app/Models/Configuracion/MaquinaModel.php b/ci4/app/Models/Configuracion/MaquinaModel.php index d462cc08..cbe249f8 100755 --- a/ci4/app/Models/Configuracion/MaquinaModel.php +++ b/ci4/app/Models/Configuracion/MaquinaModel.php @@ -404,7 +404,9 @@ class MaquinaModel extends \App\Models\BaseModel ->select([ 'lg_maquinas.id as maquinaId', 'lg_maquinas.nombre', - 'COUNT(tarea_progress.ot_tarea_id) as countTareas' + 'COUNT(tarea_progress.ot_tarea_id) as countTareas', + 'COUNT(maquina_ot_tareas.orden_trabajo_id) as countMaquinaTareas' + ]) ->join('orden_trabajo_tareas', 'orden_trabajo_tareas.maquina_id = lg_maquinas.id', 'left') ->join( @@ -420,6 +422,14 @@ class MaquinaModel extends \App\Models\BaseModel 'tarea_progress.ot_tarea_id = orden_trabajo_tareas.id', 'left' ) + ->join( + "(SELECT orden_trabajo_id,deleted_at,maquina_id + FROM maquina_ot_tareas + WHERE deleted_at is NULL + ) as maquina_ot_tareas", + 'maquina_ot_tareas.maquina_id = lg_maquinas.id', + 'left' + ) ->join('ordenes_trabajo', 'ordenes_trabajo.id = orden_trabajo_tareas.orden_trabajo_id', 'left') ->join('pedidos', 'pedidos.id = ordenes_trabajo.pedido_id', 'left') ->where('lg_maquinas.tipo', $maquina_tipo) diff --git a/ci4/app/Models/Configuracion/MaquinaOtTareaModel.php b/ci4/app/Models/Configuracion/MaquinaOtTareaModel.php new file mode 100755 index 00000000..dce7d17e --- /dev/null +++ b/ci4/app/Models/Configuracion/MaquinaOtTareaModel.php @@ -0,0 +1,66 @@ +builder() + ->select([ + 'maquina_ot_tareas.id as maquinaOtTareaId', + 'ordenes_trabajo.id as otId' + ]) + ->join('ordenes_trabajo','ordenes_trabajo.id = maquina_ot_tareas.orden_trabajo_id','left') + ->where('maquina_ot_tareas.maquina_id',$maquina_id) + ->where('maquina_ot_tareas.deleted_at',null); + + } + + +} diff --git a/ci4/app/Services/ProductionService.php b/ci4/app/Services/ProductionService.php index 8f984094..1a5349d1 100755 --- a/ci4/app/Services/ProductionService.php +++ b/ci4/app/Services/ProductionService.php @@ -1051,6 +1051,10 @@ class ProductionService extends BaseService $this->init($tareaEntity->orden_trabajo_id); $dateName = $this->getOrdenTrabajoTareaDate($tareaEntity); $this->emptyOrdenTrabajoDate($this->ot->id, $dateName); + $tareaEntity->tiempo_real = 0; + $tareaEntity->click_init = 0; + $tareaEntity->click_end = 0; + $this->otTarea->save($tareaEntity); } if ($status) { $response = $this->storeOrdenTrabajoTareaProgressDate($data); @@ -1482,6 +1486,7 @@ class ProductionService extends BaseService } return $uvi; } + //TODO ACTUALIZAR public function updateProgress(): bool { $userDates = $this->ordenTrabajoConfig->DATE_USER_MAPPING; diff --git a/ci4/app/Views/themes/vuexy/components/cards/tarea_multiple_card_actions.php b/ci4/app/Views/themes/vuexy/components/cards/tarea_multiple_card_actions.php new file mode 100644 index 00000000..58e362c9 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/cards/tarea_multiple_card_actions.php @@ -0,0 +1,55 @@ +
+
+
+
+
+ +
+ +
+

Tirada

+
+
+
" > +

Clicks

+
+
+
+ +
+
+

Tiempo estimado

+
+
+
+

Tiempo real

+
+
+
+
tipo != "impresion" ? "disabled" : "" ?>> +
+ + +
+
+ + +
+
+
+ +
+
+
+ + + + + + +
+
+
+ +
+
\ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaMaquinaList.php b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaMaquinaList.php index aadb2a0a..2fa945e9 100644 --- a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaMaquinaList.php +++ b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaMaquinaList.php @@ -18,7 +18,7 @@
$maquina): ?>
- " type="button" class="maquina-btn btn btn-outline-primary w-100"> + " type="button" class="maquina-btn btn btn-outline- 0 ? "danger" : "primary" ?> w-100"> 0): ?> @@ -39,7 +39,7 @@
$maquina): ?>
- " type="button" class="maquina-btn btn btn-outline-primary w-100"> + " type="button" class="maquina-btn btn btn-outline- 0 ? "danger" : "primary" ?> w-100"> 0): ?> @@ -60,7 +60,7 @@
$maquina): ?>
- " type="button" class="maquina-btn btn btn-outline-primary w-100"> + " type="button" class="maquina-btn btn btn-outline- 0 ? "danger" : "primary" ?> w-100"> 0): ?> diff --git a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaTareaScan.php b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaTareaScan.php index 7d37ba72..526426d7 100644 --- a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaTareaScan.php +++ b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaTareaScan.php @@ -10,12 +10,21 @@ -
+

ESCANEAR: nombre ?>

-
- + +
+
+ +
+
+
+
@@ -38,16 +47,23 @@
-
+ + endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewProduccionMaquinistaOtTareasView.php b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewProduccionMaquinistaOtTareasView.php new file mode 100644 index 00000000..7ef0af1c --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewProduccionMaquinistaOtTareasView.php @@ -0,0 +1,81 @@ +include('themes/_commonPartialsBs/select2bs5') ?> +include('themes/_commonPartialsBs/datatables') ?> +include('themes/_commonPartialsBs/sweetalert') ?> +include('themes/_commonPartialsBs/_confirm2delete') ?> +extend('themes/vuexy/main/defaultlayout') ?> +section('content'); ?> + +
+
+ + + + + + + + + + + +
+
+
+
+ +
+
+
+
+ +
+
+
+ +endSection() ?> + +section('css') ?> + + + + + + + +endSection() ?> + +section("additionalExternalJs") ?> + + + + + + + +endSection() ?> \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaMultipleTarea.js b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaMultipleTarea.js new file mode 100644 index 00000000..9211b8f7 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaMultipleTarea.js @@ -0,0 +1,223 @@ + + +import Ajax from '../../../components/ajax.js' +import { alertConfirmAction, alertError, alertSuccess } from '../../../components/alerts/sweetAlert.js' +class MaquinistaMultipleTarea { + constructor(domItem) { + this.item = domItem + this.maquinaId = this.item.data("id"); + this.btnPlay = this.item.find("#btn-start-tarea") + this.btnPause = this.item.find("#btn-pause-tarea") + this.btnDelay = this.item.find("#btn-stop-tarea") + this.btnFinish = this.item.find("#btn-finish-tarea") + this.btnDeleteProgress = this.item.find("#btn-delete-tarea") + this.actionButtons = this.item.find('.action-btn') + this.tareaCardClass = '.tarea-card-action-block' + this.inputClick = $('.ot-tarea-click') + this.datatableItem = this.item.find('#table-scanned-ots') + this.datatableColumns = [ + { data: 'otId', searchable: false, sortable: false }, + { data: 'titulo', searchable: false, sortable: false }, + { + data: 'barcode', searchable: false, sortable: false, render: (d, t) => { + return `barcode` + } + }, + { + data: 'action', searchable: false, sortable: false, render: (d, t) => { + return `` + } + }, + ] + } + init() { + this.actionButtons.on('click', this.eventActionButton.bind(this)) + this.btnDelay.on('click', this.delayEventActionButton.bind(this)) + this.btnDeleteProgress.on('click', this.deleteAll.bind(this)) + this.actionLoader(true) + this.datatableItem.DataTable({ + processing: true, + dom: "", + serverSide: true, + ordering: false, + pageLength: 25, + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + columns: this.datatableColumns, + ajax: '/produccion/ordentrabajo/maquinas/ots/datatable/' + this.maquinaId, + + }); + this.initData() + } + async initData() { + try { + let responseData = await this.getMaquinaMultipleTarea(); + this.fillCardData(responseData) + } catch (error) { + console.error(error) + } finally { + this.actionLoader(false) + } + } + fillCardData(responseData) { + this.item.find('#tirada-info').text(responseData?.tirada_total ?? 0) + this.item.find('#clicks-info').text(responseData?.clicks_total ?? 0) + this.item.find('#tiempo-estimado-info').text(responseData.tiempo_total_estimado ?? "00:00:00") + this.item.find('#tiempo-real-info').text(responseData.tiempo_total_real ?? "00:00:00") + this.showBasedOnStatus(responseData.estado) + } + async deleteAll() { + try { + let result = await alertConfirmAction('Se resetearán las tareas y se borrará el progreso') + if(result.isConfirmed){ + let response = await this.deleteMaquinaOrdenesTrabajo() + popSuccessAlert(response.message); + window.location.reload(); + } + } catch (error) { + console.error(error) + } + + } + async eventActionButton(event) { + try { + this.actionLoader(true) + let statusClick = $(event.currentTarget).data('estado'); + this.showBasedOnStatus(statusClick); + console.info(`Estado ${statusClick}`) + this.showBasedOnStatus(statusClick); + if (statusClick == "F") { + let result = await alertConfirmAction('Se marcarán como finalizadas todas las tareas') + if (result.isConfirmed == false) { + this.enableButtons() + throw new Error('Cancelado') + } + } + let response = await this.updateEstadoOts(statusClick) + popSuccessAlert(response.message) + let responseData = await this.getMaquinaMultipleTarea() + this.fillCardData(responseData) + if(statusClick == "F"){ + window.location.reload(); + } + } catch (error) { + console.error(error) + } finally { + this.actionLoader(false) + } + } + + async delayEventActionButton(event) { + try { + this.actionLoader(true) + let statusClick = $(event.currentTarget).data('estado'); + this.showBasedOnStatus(statusClick); + let response = await this.updateEstadoOts(statusClick) + popSuccessAlert(response.message) + let responseData = await this.getMaquinaMultipleTarea() + this.fillCardData(responseData) + } catch (error) { + console.error(error) + } finally { + this.actionLoader(false) + } + } + actionLoader(status = true) { + if (status) { + Notiflix.Block.circle(this.tareaCardClass); + } else { + Notiflix.Block.remove(this.tareaCardClass); + } + } + showPlay() { + this.btnPause.addClass('d-none') + this.btnPlay.removeClass('d-none') + this.btnFinish.removeClass('d-none') + this.btnDelay.removeClass('d-none') + + } + showPause() { + this.btnPlay.addClass('d-none') + this.btnFinish.addClass('d-none') + this.btnPause.removeClass('d-none') + + } + disableButtons() { + this.actionButtons.attr('disabled', 'disabled') + this.btnDelay.attr('disabled', 'disabled') + this.btnDeleteProgress.attr('disabled', 'disabled') + } + enableButtons() { + this.actionButtons.removeAttr('disabled') + this.btnDelay.removeAttr('disabled', 'disabled') + this.btnDeleteProgress.removeAttr('disabled', 'disabled') + } + + showBasedOnStatus(status) { + if (['P', 'S'].includes(status)) { + this.enableButtons() + this.showPlay() + } + if (['F', 'E'].includes(status)) { + this.disableButtons() + this.showPlay() + } + if (status == 'I') { + this.enableButtons() + this.showPause() + } + if (status == "D") { + this.showPlay() + } + + } + getClicks() { + return { + click_init: this.item.find('#input-click-init').val() ?? 0, + click_end: this.item.find('#input-click-end').val() ?? 0, + } + } + /** maquinas/ots/estado */ + updateEstadoOts(estado) { + return new Promise((resolve, reject) => { + new Ajax('/produccion/ordentrabajo/maquinas/ots/estado', + { + maquina_id: this.maquinaId, + estado: estado, + ...this.getClicks() + }, + null, + resolve, + reject + ).post() + }) + } + getMaquinaMultipleTarea() { + return new Promise((resolve, reject) => { + new Ajax('/produccion/ordentrabajo/maquinas/ots/' + this.maquinaId, + null, + null, + resolve, + reject + ).get() + }) + } + + deleteMaquinaOrdenesTrabajo() { + return new Promise((resolve, reject) => { + new Ajax('/produccion/ordentrabajo/maquinas/ots/all/' + this.maquinaId, + null, + null, + resolve, + reject + ).delete() + }) + } + + + + +} + +export default MaquinistaMultipleTarea; \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaScan.js b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaScan.js index 4aa88cdd..863ebf97 100644 --- a/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaScan.js +++ b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/maquinistaScan.js @@ -7,20 +7,26 @@ class MaquinistaScan { this.item = domItem /** ELEMENT DOM VARIABLES */ this.otInputId = this.item.find('#ot-id') - this.wrapperCard = this.item.find('#ot-fa-card') this.otId = null this.maquinaId = this.item.data("id") this.ots = [] this.datatableItem = this.item.find('#table-scanned-ots') + this.btnSave = this.item.find('#btn-save-maquina-ots'); + this.btnReset = this.item.find('#btn-reset-ots') this.datatableColumns = [ { data: 'id', searchable: false, sortable: false }, { data: 'title', searchable: false, sortable: false }, ] this.datatableData = []; + this.linkAfterSave = this.item.find('#ot-maquina-tareas-link') + this.scanWrapper = this.item.find('.ot-scan-wrapper') + } init() { this.otInputId.trigger('focus') this.otInputId.on('change', this.addOt.bind(this)) + this.btnReset.on('click',this.reset.bind(this)) + this.btnSave.on('click',this.saveMultipleOTs.bind(this)) this.datatable = this.datatableItem.DataTable({ processing: true, serverSide: false, @@ -32,13 +38,20 @@ class MaquinistaScan { columns: this.datatableColumns, data: this.datatableData }); - } - hideCard() { - this.wrapperCard.addClass('d-none') } - showCard() { - this.wrapperCard.removeClass('d-none') + reset(){ + this.ots = [] + this.datatable.clear() + this.datatable.draw() + this.reloadFocus(); + this.btnSave.attr('disabled','disabled'); + } + hideWrapper() { + this.scanWrapper.addClass('d-none') + } + showWrapper() { + this.scanWrapper.removeClass('d-none') } actionLoader(status = true) { if (status) { @@ -47,10 +60,31 @@ class MaquinistaScan { Notiflix.Block.remove('.section-block'); } } - reloadFocus(){ + reloadFocus() { this.otInputId.val("") this.otInputId.trigger('focus') } + async saveMultipleOTs() { + try { + let result = await alertConfirmAction() + if(result.isConfirmed){ + this.actionLoader(true) + let response = await this.postMaquinaOrdenesTrabajo() + this.actionLoader(false) + popSuccessAlert(response.message) + this.hideWrapper() + this.linkAfterSave.removeClass('d-none') + } + + } catch (error) { + this.actionLoader(false) + if (error?.responseJSON) { + popErrorAlert(error.responseJSON.message) + } else { + popErrorAlert(error) + } + } + } async addOt() { try { if (this.ots.includes(this.otInputId.val())) { @@ -67,6 +101,7 @@ class MaquinistaScan { }]) this.datatable.draw() this.reloadFocus() + this.btnSave.removeAttr('disabled') } } catch (error) { @@ -97,6 +132,26 @@ class MaquinistaScan { } + postMaquinaOrdenesTrabajo() { + return new Promise((resolve, reject) => { + let ajax = new Ajax( + `/produccion/ordentrabajo/maquinas/ots`, + { + maquina_id: this.maquinaId, + ordenes_trabajo: this.ots + }, + null, + (response) => { + resolve(response) + }, + (error) => { + reject(error) + } + ) + ajax.post(); + }) + } + diff --git a/httpdocs/assets/js/safekat/pages/configuracion/maquinista/viewTareaMultipleView.js b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/viewTareaMultipleView.js new file mode 100644 index 00000000..2080234e --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/configuracion/maquinista/viewTareaMultipleView.js @@ -0,0 +1,7 @@ +import MaquinistaMultipleTarea from "./maquinistaMultipleTarea.js" + +$(() => { + console.info("MAQUINISTA MAQUINA OT TAREAS") + let tareaMultiple = new MaquinistaMultipleTarea($("#viewProduccionMaquinistaOtTareasView")) + tareaMultiple.init() +}) \ No newline at end of file diff --git a/httpdocs/themes/vuexy/css/maquinista.css b/httpdocs/themes/vuexy/css/maquinista.css index 61ac1780..d37c8901 100644 --- a/httpdocs/themes/vuexy/css/maquinista.css +++ b/httpdocs/themes/vuexy/css/maquinista.css @@ -4,6 +4,12 @@ width : 100%; font-size : 20px; } +.maquina-btn-v +{ + height : 5rem; + width : 1rem; + font-size : 20px; +} .table-maquinista td{ height : 7rem; } \ No newline at end of file