diff --git a/ci4/app/Config/OrdenTrabajo.php b/ci4/app/Config/OrdenTrabajo.php index 0e63dd5a..787f5c9d 100755 --- a/ci4/app/Config/OrdenTrabajo.php +++ b/ci4/app/Config/OrdenTrabajo.php @@ -122,7 +122,7 @@ class OrdenTrabajo extends BaseConfig ]; public array $OT_TAREA_STATUS_COLOR = [ - "P" => '#FFD63A', + "P" => '#FFB22C', "F" => '#67AE6E', "S" => '#EB5B00', "I" => '#3A59D1', @@ -130,6 +130,7 @@ class OrdenTrabajo extends BaseConfig "D" => '#FFA725', ]; + public function __construct() { parent::__construct(); diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index fc2e1373..b733f254 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -40,8 +40,8 @@ foreach (glob(APPPATH . 'Config/Routes/*Routes.php') as $routeFile) { $routes->group('users', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) { $routes->get('', 'Users::index', ['as' => 'userList']); - $routes->get('maquinista/change/user','Users::index_maquinista_change_user',['as' => 'maquinistaUserChangeList']); - $routes->get('maquinista/change/session/(:num)','Users::change_user_session/$1',['as' => 'maquinistaChangeUserSession']); + $routes->get('maquinista/change/user', 'Users::index_maquinista_change_user', ['as' => 'maquinistaUserChangeList']); + $routes->get('maquinista/change/session/(:num)', 'Users::change_user_session/$1', ['as' => 'maquinistaChangeUserSession']); $routes->get('list', 'Users::index', ['as' => 'userList2']); $routes->get('add', 'Users::add', ['as' => 'newUser']); $routes->post('add', 'Users::add', ['as' => 'createUser']); @@ -742,11 +742,17 @@ $routes->group('soporte', ['namespace' => 'App\Controllers\Soporte'], function ( $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { $routes->group('ordentrabajo', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { + /** VIEWS */ $routes->get('', 'Ordentrabajo::index', ['as' => 'viewOrdenTrabajoIndex']); $routes->get('edit/(:num)', 'Ordentrabajo::edit/$1', ['as' => 'viewOrdenTrabajoEdit']); - $routes->delete('reset/tareas/(:num)', 'Ordentrabajo::reset_tareas/$1'); - $routes->delete('tareas/(:num)', 'Ordentrabajo::delete_tarea/$1'); + + /** GET */ $routes->get('summary/(:num)', 'Ordentrabajo::get_orden_trabajo_summary/$1', ['as' => 'getOrdenTrabajoSumary']); + $routes->get("tarea/progress/(:num)", "Ordentrabajo::get_orden_trabajo_progress_date/$1"); + $routes->get('tarea/(:num)', 'Ordentrabajo::find_tarea/$1'); + $routes->get('tarea/dates/(:num)', 'Ordentrabajo::get_orden_trabajo_tareas_dates/$1'); + $routes->get('tareas/maquina/(:num)/(:num)','Ordentrabajo::get_tareas_ot_maquina/$1/$2'); + /** DATATABLES */ $routes->get('datatable', 'Ordentrabajo::datatable'); $routes->get('datatable_pendientes', 'Ordentrabajo::datatable_pendientes'); $routes->get('datatable_ferro_pendiente', 'Ordentrabajo::datatable_ferro_pendiente'); @@ -756,9 +762,6 @@ $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("tarea/progress/(:num)", "Ordentrabajo::get_orden_trabajo_progress_date/$1"); - $routes->get('tarea/(:num)', 'Ordentrabajo::find_tarea/$1'); - $routes->get('tarea/dates/(:num)','Ordentrabajo::get_orden_trabajo_tareas_dates/$1'); /**====================== * UPDATES *========================**/ @@ -767,18 +770,22 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func $routes->post("reset/date", 'Ordentrabajo::reset_orden_trabajo_date'); $routes->post("update/pedido/date", 'Ordentrabajo::update_orden_trabajo_pedido_date'); $routes->post("reset/pedido/date", 'Ordentrabajo::reset_orden_trabajo_pedido_date'); - $routes->post("update/pod/pedido/date/(:num)",'Ordentrabajo::update_pod_pedido_dates/$1'); + $routes->post("update/pod/pedido/date/(:num)", 'Ordentrabajo::update_pod_pedido_dates/$1'); $routes->post("update/pedido", 'Ordentrabajo::update_orden_trabajo_pedido'); $routes->post("update/user", 'Ordentrabajo::update_orden_trabajo_user'); $routes->post("update", 'Ordentrabajo::update_orden_trabajo'); $routes->post("upload/portada", 'Ordentrabajo::upload_orden_trabajo_portada'); - $routes->delete("portada/(:num)", 'Ordentrabajo::delete_orden_trabajo_portada/$1'); $routes->get("color/(:num)", 'Ordentrabajo::get_orden_trabajo_color_status/$1'); $routes->post("update/tarea/progress", "Ordentrabajo::store_orden_trabajo_progress_date"); $routes->post("update/tarea/pliegos", "Ordentrabajo::update_orden_trabajo_pliegos"); $routes->post("update/tarea/proveedor", "Ordentrabajo::update_presupuesto_tarea_proveedor"); - $routes->delete("tarea/progress/(:num)", "Ordentrabajo::delete_orden_trabajo_progress_date/$1"); + $routes->post("fa/tareas/finish", 'Ordentrabajo::update_orden_trabajo_fa_tareas'); + /**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'); /**====================== * FILES *========================**/ @@ -792,6 +799,7 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func $routes->get('pdf/ferro/(:num)', 'Ordentrabajo::get_ferro_pdf/$1'); $routes->get('pdf/prototipo/(:num)', 'Ordentrabajo::get_prototipo_pdf/$1'); $routes->get('portada/(:num)', 'Ordentrabajo::get_portada_img/$1'); + /** PLANNING */ $routes->group('planning', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { $routes->get('select/maquina/rotativa', 'Ordentrabajo::select_maquina_planning_rot'); $routes->get('select/papel/rotativa', 'Ordentrabajo::select_papel_planning_rot'); @@ -807,12 +815,19 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func }); $routes->group('maquinista', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { + /** + * VIEWS + */ $routes->get('maquinas/view', 'Ordentrabajo::maquinista_maquinas_view', ['as' => 'viewProduccionMaquinistaMaquinas']); $routes->get('maquinas/view/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_list/$1', ['as' => 'viewProduccionMaquinaTareasList']); - $routes->get('maquinas/tareas/datatable/(:alpha)/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_datatable/$1/$2', ['as' => 'viewMaquinistaMaquinaTareaDatatable']); - + $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('colas/view', 'Ordentrabajo::maquinista_colas_view', ['as' => 'viewProduccionMaquinistaColas']); + + /** DATATABLE */ + $routes->get('maquinas/tareas/datatable/(:alpha)/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_datatable/$1/$2', ['as' => 'viewMaquinistaMaquinaTareaDatatable']); + $routes->get('maquinas/tareas/aplazadas/datatable/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_aplazada_datatable/$1', ['as' => 'viewMaquinistaMaquinaTareaAplazadaDatatable']); }); }); }); @@ -842,7 +857,6 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->post('imprimirEtiquetas', 'LogisticaController::imprimirEtiquetas'); $routes->get('listAlbaranes', 'LogisticaController::listAlbaranes', ['as' => 'albaranesList']); - }); /* diff --git a/ci4/app/Config/Validation.php b/ci4/app/Config/Validation.php index f8c5881c..a1acbd7a 100755 --- a/ci4/app/Config/Validation.php +++ b/ci4/app/Config/Validation.php @@ -172,6 +172,29 @@ class Validation extends BaseConfig "label" => "Orden trabajo" ], + ]; + public array $orden_trabajo_fichaje_auto = [ + "orden_trabajo_id" => [ + "rules" => "required|integer", + "label" => "Orden trabajo" + ], + "maquina_id" => [ + "rules" => "required|integer", + "label" => "Máquina" + ], + "tareas" => [ + "rules" => "required", + "label" => "Tareas" + ], + "click_init" => [ + "rules" => "required|integer", + "label" => "Click init" + ], + "click_end" => [ + "rules" => "required|integer", + "label" => "Click end" + ], + ]; public array $chat_department = [ diff --git a/ci4/app/Controllers/Produccion/Ordentrabajo.php b/ci4/app/Controllers/Produccion/Ordentrabajo.php index 32a1a647..0beac9d9 100755 --- a/ci4/app/Controllers/Produccion/Ordentrabajo.php +++ b/ci4/app/Controllers/Produccion/Ordentrabajo.php @@ -141,7 +141,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 +152,6 @@ class Ordentrabajo extends BaseController } else { return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400); } - } public function reset_orden_trabajo_date() { @@ -242,7 +242,7 @@ class Ordentrabajo extends BaseController { $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()]) @@ -257,7 +257,7 @@ class Ordentrabajo extends BaseController { $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()]) @@ -272,7 +272,7 @@ class Ordentrabajo extends BaseController { $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()]) @@ -287,7 +287,7 @@ class Ordentrabajo extends BaseController { $logo = config(LogoImpresion::class); - $q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.preimpresion_revisada',false); + $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( @@ -301,7 +301,7 @@ class Ordentrabajo extends BaseController { $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('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( @@ -315,7 +315,7 @@ class Ordentrabajo extends BaseController { $logo = config(LogoImpresion::class); - $q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.is_pedido_espera',1); + $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( @@ -329,7 +329,7 @@ class Ordentrabajo extends BaseController { $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 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( @@ -374,6 +374,7 @@ class Ordentrabajo extends BaseController return DataTable::of($q) ->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)) ->add("proveedor", fn($q) => $this->produccionService->getProveedorTarea($q->id)) @@ -602,6 +603,19 @@ class Ordentrabajo extends BaseController $this->viewData["maquinaEntity"] = $maquina; 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) { $otTareaEntity = $this->otTarea->find($orden_trabajo_tarea_id); @@ -629,6 +643,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); } @@ -639,13 +663,12 @@ 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) { $validatedData = $this->validation->getValidated(); $r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($validatedData); $otTareaEntity = $this->otTarea->find($validatedData['ot_tarea_id']); $data = [ - "tiempo_trabajado" => float_seconds_to_hhmm_string($otTareaEntity->tiempo_trabajado()), + "tiempo_trabajado" => float_seconds_to_hhmm_string($otTareaEntity->tiempo_real), "tarea" => $otTareaEntity, "estado" => $validatedData['estado'], ]; @@ -673,20 +696,65 @@ class Ordentrabajo extends BaseController } 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() + { + $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' => 'F', + 'ot_tarea_id' => $tareaId + ] + ); + $tareaEntity = $this->otTarea->find($tareaId); + $tiempo_trabajado = $tareaEntity->tiempo_trabajado(); + $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); + } + 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); + } } } diff --git a/ci4/app/Entities/Produccion/OrdenTrabajoTareaEntity.php b/ci4/app/Entities/Produccion/OrdenTrabajoTareaEntity.php index 3dcf518e..c90de2b9 100755 --- a/ci4/app/Entities/Produccion/OrdenTrabajoTareaEntity.php +++ b/ci4/app/Entities/Produccion/OrdenTrabajoTareaEntity.php @@ -178,7 +178,7 @@ class OrdenTrabajoTareaEntity extends Entity $m = model(OrdenTrabajoTareaProgressDate::class); return $m->where('ot_tarea_id', $this->attributes["id"])->findAll() ?? []; } - public function lastState() : ?OrdenTrabajoTareaProgressDateEntity + public function lastState(): ?OrdenTrabajoTareaProgressDateEntity { $m = model(OrdenTrabajoTareaProgressDate::class); $progressDates = $m->where('ot_tarea_id', $this->attributes["id"])->orderBy('action_at', 'DESC')->first(); @@ -193,12 +193,12 @@ class OrdenTrabajoTareaEntity extends Entity foreach ($dates as $key => $date) { if ($date->estado == "I") { if ($date->action_at) { - $init = Time::createFromFormat('Y-m-d H:i:s', $date->action_at); + $init = $date->action_at; } } if ($date->estado == "S" || $date->estado == "F") { if ($date->action_at && $init) { - $end = Time::createFromFormat('Y-m-d H:i:s', $date->action_at); + $end = $date->action_at; $intervals[] = $init->difference($end)->getSeconds(); } } @@ -218,23 +218,23 @@ class OrdenTrabajoTareaEntity extends Entity } return $isTareaCosido; } - public function isImpresion() : bool + public function isImpresion(): bool { return $this->attributes['presupuesto_linea_id'] != null; } - public function isAcabado() : bool + public function isAcabado(): bool { return $this->attributes['presupuesto_acabado_id'] != null; } - public function isManipulado() : bool + public function isManipulado(): bool { return $this->attributes['presupuesto_manipulado_id'] != null; } - public function isEncuadernado() : bool + public function isEncuadernado(): bool { return $this->attributes['presupuesto_encuadernado_id'] != null; } - public function isCorte() : bool + public function isCorte(): bool { return $this->attributes['is_corte']; } diff --git a/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php b/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php index 9523c8c3..60276d7e 100755 --- a/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php +++ b/ci4/app/Entities/Produccion/OrdenTrabajoTareaProgressDateEntity.php @@ -2,6 +2,7 @@ namespace App\Entities\Produccion; +use App\Entities\Usuarios\UserEntity; use App\Models\OrdenTrabajo\OrdenTrabajoTarea; use CodeIgniter\Entity\Entity; @@ -27,5 +28,14 @@ class OrdenTrabajoTareaProgressDateEntity extends Entity $m = model(OrdenTrabajoTarea::class); return $m->find($this->attributes["ot_tarea_id"]); } + public function user() : ?UserEntity + { + $user = null; + if($this->attributes['action_user_id']) + { + $user = auth()->getProvider()->findById($this->attributes['action_user_id']); + } + return $user; + } } diff --git a/ci4/app/Language/es/Produccion.php b/ci4/app/Language/es/Produccion.php index 6a1e4d10..266deb21 100755 --- a/ci4/app/Language/es/Produccion.php +++ b/ci4/app/Language/es/Produccion.php @@ -12,6 +12,8 @@ return [ 'prod' => 'Producción' ], "datatable" => [ + "ot_id" => "OT ID", + "barcode" => "Código", "pedido_id" => "Pedido ID", "fecha_encuadernacion" => "Fecha encuadernación", "fecha_impresion" => "Fecha impresión", @@ -154,6 +156,16 @@ return [ "play_stop" => "Aplazar", "play_end" => "Finalizar", "cancel" => "Cancelar", + "fichaje_auto" => "F.auto", + "scan" => "Escanear", + "tarea_list" => "Lista de tareas", + "fichaje_auto_alert_text" => "Cada vez que introduza un nº de pedido se iniciará la tarea y se finalizará la tarea actual (del pedido anterior)", + "next_ot" => "SIGUIENTE OT", + "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" + ], 'tarea_estados' => [ @@ -176,4 +188,11 @@ return [ "comentariosEncuadernacion" => "Comentarios encuadernación", "comentariosLogistica" => "Comentarios logística", "info_solapa_guillotina" => "Datos solapa y preparación guillotina", + + "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", + "ot_not_found" => "La orden de trabajo número {ot_id} no existe" + + ] ]; diff --git a/ci4/app/Models/OrdenTrabajo/OrdenTrabajoModel.php b/ci4/app/Models/OrdenTrabajo/OrdenTrabajoModel.php index 96652556..e28a7e1b 100755 --- a/ci4/app/Models/OrdenTrabajo/OrdenTrabajoModel.php +++ b/ci4/app/Models/OrdenTrabajo/OrdenTrabajoModel.php @@ -5,6 +5,7 @@ namespace App\Models\OrdenTrabajo; use App\Entities\Produccion\OrdenTrabajoEntity; use CodeIgniter\Database\BaseBuilder; use CodeIgniter\Model; + class OrdenTrabajoModel extends Model { protected $table = 'ordenes_trabajo'; @@ -75,41 +76,71 @@ class OrdenTrabajoModel extends Model protected $beforeDelete = []; protected $afterDelete = []; - public function getDatatableQuery() : BaseBuilder + public function getDatatableQuery(): BaseBuilder { $q = $this->builder() - ->select([ - "ordenes_trabajo.id", - "ordenes_trabajo.pedido_id", - "pedidos.fecha_encuadernado as fecha_encuadernado_at", - "clientes.nombre as cliente_nombre", - "presupuestos.titulo as presupuesto_titulo", - "ordenes_trabajo.estado", - "ubicaciones.nombre as ubicacion_nombre", - "pedidos.total_tirada", - "tipos_presupuestos.codigo as tipo_presupuesto_impresion", - "ordenes_trabajo.progreso", - "presupuesto_linea.tipo as presupuesto_linea_tipo", - "orden_trabajo_dates.ferro_ok_at", - "CONCAT(lg_imposiciones.ancho,'x',lg_imposiciones.alto,'_',COALESCE(lg_imposiciones.unidades,'NULL'),'_',COALESCE(lg_imposiciones.orientacion,'NULL')) as imposicion_name" + ->select([ + "ordenes_trabajo.id", + "ordenes_trabajo.pedido_id", + "pedidos.fecha_encuadernado as fecha_encuadernado_at", + "clientes.nombre as cliente_nombre", + "presupuestos.titulo as presupuesto_titulo", + "ordenes_trabajo.estado", + "ubicaciones.nombre as ubicacion_nombre", + "pedidos.total_tirada", + "tipos_presupuestos.codigo as tipo_presupuesto_impresion", + "ordenes_trabajo.progreso", + "presupuesto_linea.tipo as presupuesto_linea_tipo", + "orden_trabajo_dates.ferro_ok_at", + "CONCAT(lg_imposiciones.ancho,'x',lg_imposiciones.alto,'_',COALESCE(lg_imposiciones.unidades,'NULL'),'_',COALESCE(lg_imposiciones.orientacion,'NULL')) as imposicion_name" - ]) - ->join("orden_trabajo_dates","orden_trabajo_dates.orden_trabajo_id = ordenes_trabajo.id","left") - ->join("pedidos","pedidos.id = ordenes_trabajo.pedido_id","left") - ->join("pedidos_linea","pedidos.id = pedidos_linea.pedido_id","left") - ->join("presupuestos","presupuestos.id = pedidos_linea.presupuesto_id","left") - ->join("presupuesto_linea","presupuestos.id = presupuesto_linea.presupuesto_id","left") - ->join("clientes","clientes.id = presupuestos.cliente_id","left") - ->join("tipos_presupuestos","presupuestos.tipo_impresion_id = tipos_presupuestos.id","left") - ->join("ubicaciones","ubicaciones.id = pedidos_linea.ubicacion_id","left") - ->join("orden_trabajo_tareas","orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id","left") - ->join("lg_imposiciones","lg_imposiciones.id = orden_trabajo_tareas.imposicion_id","left") + ]) + ->join("orden_trabajo_dates", "orden_trabajo_dates.orden_trabajo_id = ordenes_trabajo.id", "left") + ->join("pedidos", "pedidos.id = ordenes_trabajo.pedido_id", "left") + ->join("pedidos_linea", "pedidos.id = pedidos_linea.pedido_id", "left") + ->join("presupuestos", "presupuestos.id = pedidos_linea.presupuesto_id", "left") + ->join("presupuesto_linea", "presupuestos.id = presupuesto_linea.presupuesto_id", "left") + ->join("clientes", "clientes.id = presupuestos.cliente_id", "left") + ->join("tipos_presupuestos", "presupuestos.tipo_impresion_id = tipos_presupuestos.id", "left") + ->join("ubicaciones", "ubicaciones.id = pedidos_linea.ubicacion_id", "left") + ->join("orden_trabajo_tareas", "orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id", "left") + ->join("lg_imposiciones", "lg_imposiciones.id = orden_trabajo_tareas.imposicion_id", "left") - ->whereIn("presupuesto_linea.tipo",["lp_bn","lp_bnhq","lp_rot_bn","lp_color","lp_colorhq","lp_rot_color"]) - ->where("ordenes_trabajo.deleted_at",null) - ->groupBy("ordenes_trabajo.id"); + ->whereIn("presupuesto_linea.tipo", ["lp_bn", "lp_bnhq", "lp_rot_bn", "lp_color", "lp_colorhq", "lp_rot_color"]) + ->where("ordenes_trabajo.deleted_at", null) + ->groupBy("ordenes_trabajo.id"); return $q; } - - + public function queryMaquinaTareas(int $maquina_id, ?array $tareaEstados = null) + { + $query = $this->builder()->select([ + 'orden_trabajo_tareas.*', + 'tarea_progress.estado' + ]) + ->join('orden_trabajo_tareas', 'orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id', 'left') + ->join('lg_maquinas', 'orden_trabajo_tareas.maquina_id = lg_maquinas.id', 'left'); + //* Obtener el ultimo estado de la tarea + if ($tareaEstados) { + $query->join( + '(SELECT ot_tarea_id, estado + FROM orden_trabajo_tarea_progress_dates + WHERE (ot_tarea_id, created_at) IN ( + SELECT ot_tarea_id, MAX(created_at) + FROM orden_trabajo_tarea_progress_dates + GROUP BY ot_tarea_id + ) + ) as tarea_progress', + 'tarea_progress.ot_tarea_id = orden_trabajo_tareas.id', + 'left' + ) + ->groupStart() + ->whereIn('tarea_progress.estado', $tareaEstados) + ->orWhere('tarea_progress.estado',null) + ->groupEnd(); + } + $query->where('orden_trabajo_tareas.deleted_at', null) + ->where('lg_maquinas.id', $maquina_id) + ->groupBy('orden_trabajo_tareas.id'); + return $query; + } } diff --git a/ci4/app/Models/OrdenTrabajo/OrdenTrabajoTareaProgressDate.php b/ci4/app/Models/OrdenTrabajo/OrdenTrabajoTareaProgressDate.php index 00b09b7a..79904d05 100644 --- a/ci4/app/Models/OrdenTrabajo/OrdenTrabajoTareaProgressDate.php +++ b/ci4/app/Models/OrdenTrabajo/OrdenTrabajoTareaProgressDate.php @@ -3,6 +3,7 @@ namespace App\Models\OrdenTrabajo; use App\Entities\Produccion\OrdenTrabajoTareaEntity; +use App\Entities\Produccion\OrdenTrabajoTareaProgressDateEntity; use CodeIgniter\Database\MySQLi\Builder; use CodeIgniter\Model; @@ -11,7 +12,7 @@ class OrdenTrabajoTareaProgressDate extends Model protected $table = 'orden_trabajo_tarea_progress_dates'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = OrdenTrabajoTareaEntity::class; + protected $returnType = OrdenTrabajoTareaProgressDateEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ diff --git a/ci4/app/Services/PresupuestoService.php b/ci4/app/Services/PresupuestoService.php index 6feb5b4f..56d7dfdc 100755 --- a/ci4/app/Services/PresupuestoService.php +++ b/ci4/app/Services/PresupuestoService.php @@ -253,8 +253,7 @@ class PresupuestoService extends BaseService $linea['fields']['precio_libro'] = $linea['fields']['pliegos_libro'] * $linea['fields']['precios_pliegos']; // Precio papel pedido $linea['fields']['precio_pedido'] = $linea['fields']['precio_libro'] * ($datosPedido->tirada + $datosPedido->merma); - $linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro'] * $margen_pliego_impresion * ($datosPedido->tirada + $datosPedido->merma); - ; + $linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro'] * $margen_pliego_impresion * ($datosPedido->tirada + $datosPedido->merma);; $linea['fields']['a_favor_fibra'] = $parametrosRotativa->a_favor_fibra; $linea['fields']['maquina'] = $maquina->maquina; @@ -615,9 +614,9 @@ class PresupuestoService extends BaseService // precio tinta $data['precio_tinta'] = round( round(($data['peso_gotas_negro_pedido'] / 1000.0) * $maquina->precio_tinta_negro, 2) + - round(($data['peso_gotas_cyan_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) + - round(($data['peso_gotas_magenta_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) + - round(($data['peso_gotas_amarillo_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2), + round(($data['peso_gotas_cyan_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) + + round(($data['peso_gotas_magenta_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) + + round(($data['peso_gotas_amarillo_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2), 2 ); @@ -1907,8 +1906,8 @@ class PresupuestoService extends BaseService $pedido = $modelPedido->find($pedido_id); $serviceProduction->setPedido($pedido); if (!$pedido->orden_trabajo()) { - - $r = $serviceProduction->createOrdenTrabajo(); + + $r = $serviceProduction->createOrdenTrabajo(true); $modelPedido->set(['estado' => 'produccion'])->where('id', $pedido_id)->update(); } } @@ -1984,17 +1983,17 @@ class PresupuestoService extends BaseService return $peso; } - public static function ajustarPresupuesto($id, $precio_unidad = null, $unidades = null, $precio_total = null, $forzar_descuento = false){ + public static function ajustarPresupuesto($id, $precio_unidad = null, $unidades = null, $precio_total = null, $forzar_descuento = false) + { $precio_total_asignado = 0; $precio_unidad_asignado = $precio_unidad; $warning = false; - $model = model('App\Models\Presupuestos\PresupuestoModel'); - if($precio_unidad != null && $unidades != null){ + $model = model('App\Models\Presupuestos\PresupuestoModel'); + if ($precio_unidad != null && $unidades != null) { $precio_total_asignado = round(floatval($precio_unidad) * intval($unidades), 2); - } - else{ + } else { $precio_total_asignado = floatval($precio_total); } $presupuesto = $model->find($id); @@ -2003,13 +2002,12 @@ class PresupuestoService extends BaseService $total_descuento = 0; $total_descuentoPercent = 0; - if($costes + $envio_base > $precio_total_asignado){ + if ($costes + $envio_base > $precio_total_asignado) { - if($forzar_descuento){ + if ($forzar_descuento) { $total_descuento = $costes + $envio_base - $precio_total_asignado; $total_descuentoPercent = round($total_descuento / ($costes + $envio_base) * 100, 2); - } - else{ + } else { $precio_total_asignado = round($costes + $envio_base, 2); $precio_unidad_asignado = round($precio_total_asignado / intval($unidades), 4); } @@ -2021,22 +2019,22 @@ class PresupuestoService extends BaseService $sumForFactor = floatval($presupuesto->total_coste_papel) + floatval($presupuesto->total_coste_impresion); $sumForFactorPonderado = $sumForFactor + floatval($presupuesto->total_coste_servicios); - - $factor = ($precio_total_asignado - floatval($presupuesto->envio_base) + + $factor = ($precio_total_asignado - floatval($presupuesto->envio_base) - floatval($presupuesto->total_coste_envios) - floatval($presupuesto->total_margen_envios)) / $sumForFactor; - - $factorPonderado = ($precio_total_asignado - floatval($presupuesto->envio_base) + + $factorPonderado = ($precio_total_asignado - floatval($presupuesto->envio_base) - floatval($presupuesto->total_coste_envios) - floatval($presupuesto->total_margen_envios)) / $sumForFactorPonderado; - + if ($presupuesto) { - $presupuesto->total_margenes = $total_margenes; + $presupuesto->total_margenes = $total_margenes; $presupuesto->total_aceptado = $precio_total_asignado; $presupuesto->total_aceptado_revisado = $precio_total_asignado; $presupuesto->total_presupuesto = $precio_total_asignado; $presupuesto->total_antes_descuento = $precio_total_asignado - $costes - $envio_base < 0 ? - $costes + $envio_base : - $precio_total_asignado; + $costes + $envio_base : + $precio_total_asignado; $presupuesto->total_precio_unidad = $precio_unidad_asignado; $presupuesto->total_descuento = $total_descuento; $presupuesto->total_descuentoPercent = $total_descuentoPercent; diff --git a/ci4/app/Services/ProductionService.php b/ci4/app/Services/ProductionService.php index 14742531..8f984094 100755 --- a/ci4/app/Services/ProductionService.php +++ b/ci4/app/Services/ProductionService.php @@ -52,6 +52,7 @@ class ProductionService extends BaseService */ public array $TIPOS_ROTATIVA = ['lp_rot_bn', 'lp_rot_color']; + public array $OT_TAREA_STATUS_TITLE; protected OrdenTrabajoModel $otModel; protected OrdenTrabajoTarea $otTarea; @@ -211,6 +212,14 @@ class ProductionService extends BaseService $this->statusColor = $this->ordenTrabajoConfig->OT_COLORS["sin_imprimir"]; $this->configVariableModel = model(ConfigVariableModel::class); $this->podValue = $this->configVariableModel->getVariable('POD')->value; + $this->OT_TAREA_STATUS_TITLE = [ + "P" => lang('Produccion.tarea_estados.P'), + "F" => lang('Produccion.tarea_estados.F'), + "S" => lang('Produccion.tarea_estados.S'), + "I" => lang('Produccion.tarea_estados.I'), + "E" => lang('Produccion.tarea_estados.E'), + "D" => lang('Produccion.tarea_estados.D'), + ]; } public function init(int $orden_trabajo_id): self @@ -218,7 +227,11 @@ class ProductionService extends BaseService try { $this->maquinaModel = model(MaquinaModel::class); $this->otModel = model(OrdenTrabajoModel::class); - $this->ot = $this->otModel->find($orden_trabajo_id); + $ot = $this->otModel->find($orden_trabajo_id); + if($ot == null){ + throw new Exception(lang('Produccion.errors.ot_not_found',['ot_id' => $orden_trabajo_id])); + } + $this->ot = $ot; $pedido = $this->ot->pedido(); $this->setPedido($pedido); $this->defaultMaquinaCorte = $this->maquinaModel->where('nombre', $this->defaultMaquinaCorteName)->first(); @@ -597,6 +610,12 @@ class ProductionService extends BaseService } return ["tareas" => $tareas]; } + public function getTareasWithMaquina(int $maquina_id,?array $tareaEstados = null) : ?array + { + return $this->otModel->queryMaquinaTareas($maquina_id, $tareaEstados) + ->where('ordenes_trabajo.id', $this->ot->id) + ->get()->getResult(OrdenTrabajoTareaEntity::class); + } public function getPdf() { @@ -994,9 +1013,9 @@ class ProductionService extends BaseService $data["action_user_id"] = auth()->user()->id; $lastDate = $this->otTareaProgressDate->where('ot_tarea_id', $data['ot_tarea_id'])->orderBy('action_at', 'DESC')->first(); if ($lastDate) { - if ($lastDate->estado == $data['estado']) { - throw new Exception(lang('Produccion.duplicate_estado_tarea_progress')); - } + // if ($lastDate->estado == $data['estado']) { + // throw new Exception(lang('Produccion.duplicate_estado_tarea_progress')); + // } if ($lastDate->estado == 'F') { throw new Exception(lang('Produccion.task_already_finished')); } @@ -1907,7 +1926,9 @@ class ProductionService extends BaseService "pedidos.fecha_impresion", "orden_trabajo_tareas.nombre as tareaName", "orden_trabajo_tareas.maquina_id", - "tarea_progress.estado as tareaEstado" + "tarea_progress.estado as tareaEstado", + "tarea_progress.estado", + ]) ->join("orden_trabajo_tareas", "orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id", "left") //* Obtener el ultimo estado de la tarea @@ -1929,7 +1950,6 @@ class ProductionService extends BaseService // ->where('pedidos.fecha_impresion IS NOT NULL', null, false) //! Dejar comentado por ahora ->where('ordenes_trabajo.preimpresion_revisada', true) ->where("orden_trabajo_tareas.deleted_at", null) - ->where("tarea_progress.estado", 'P') ->orderBy("pedidos.fecha_impresion", "ASC") ->groupBy('orden_trabajo_tareas.id'); @@ -2110,7 +2130,7 @@ class ProductionService extends BaseService $data[$tareasAcabado->id] = 'plastificado_at'; } if ($tarifaAcabado->rectractilado) { - $data[$tareasAcabado->id] = 'rectractilado_at'; + $data[$tareasAcabado->id] = 'retractilado_at'; } if ($tarifaAcabado->estampado) { $data[$tareasAcabado->id] = 'estampado_at'; @@ -2132,7 +2152,7 @@ class ProductionService extends BaseService $dateName = 'plastificado_at'; } if ($tarifaAcabado->rectractilado) { - $dateName = 'rectractilado_at'; + $dateName = 'retractilado_at'; } if ($tarifaAcabado->plakene) { $dateName = 'plakene_at'; @@ -2190,4 +2210,23 @@ class ProductionService extends BaseService } return $dateName; } + public function getTitleTareaEstado($tarea_id): array + { + $estadoTitle = $this->OT_TAREA_STATUS_TITLE["P"]; + $estadoColor = $this->ordenTrabajoConfig->OT_TAREA_STATUS_COLOR['P']; + $userName = null; + $progressDateEntity = $this->otTarea->find($tarea_id)->lastState(); + if ($progressDateEntity) { + if (isset($this->OT_TAREA_STATUS_TITLE[$progressDateEntity->estado])) { + $estadoTitle = $this->OT_TAREA_STATUS_TITLE[$progressDateEntity->estado]; + $estadoColor = $this->ordenTrabajoConfig->OT_TAREA_STATUS_COLOR[$progressDateEntity->estado]; + $userName = $progressDateEntity->user()->fullName(); + } + } + return [ + "title" => $estadoTitle, + "color" => $estadoColor, + "userName" => $userName ?? "", + ]; + } } diff --git a/ci4/app/Views/themes/vuexy/components/cards/tarea_card_auto.php b/ci4/app/Views/themes/vuexy/components/cards/tarea_card_auto.php new file mode 100644 index 00000000..51b682d6 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/cards/tarea_card_auto.php @@ -0,0 +1,45 @@ +
Tiempo estimado
+Tiempo real
+| = lang('ID') ?> | += lang('OT ID') ?> | = lang('Produccion.task.task') ?> | = lang('Produccion.task.estado') ?> | = lang('Produccion.datatable.fecha_impresion') ?> | diff --git a/ci4/app/Views/themes/vuexy/components/tables/ot_task_table.php b/ci4/app/Views/themes/vuexy/components/tables/ot_task_table.php index 77a28ddf..e6ff1789 100755 --- a/ci4/app/Views/themes/vuexy/components/tables/ot_task_table.php +++ b/ci4/app/Views/themes/vuexy/components/tables/ot_task_table.php @@ -5,6 +5,7 @@|||
|---|---|---|---|---|---|---|---|
| = lang('Produccion.task.order') ?> | = lang('Produccion.task.task') ?> | += lang('Produccion.task.estado') ?> | = lang('Produccion.task.maquina_presupuesto') ?> | = lang('Produccion.task.maquina_actual') ?> | = lang('Produccion.task.imposicion') ?> | diff --git a/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaFichajeAutomatico.php b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaFichajeAutomatico.php new file mode 100644 index 00000000..06fe1bbc --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/produccion/maquinista/viewMaquinistaFichajeAutomatico.php @@ -0,0 +1,63 @@ += $this->include('themes/_commonPartialsBs/select2bs5') ?> += $this->include('themes/_commonPartialsBs/datatables') ?> += $this->include('themes/_commonPartialsBs/sweetalert') ?> += $this->include('themes/_commonPartialsBs/_confirm2delete') ?> += $this->extend('themes/vuexy/main/defaultlayout') ?> += $this->section('content'); ?> + +
| = lang('Produccion.datatable.ot_id') ?> | += lang('Produccion.datatable.titulo') ?> | +
|---|