Merge branch 'feat/sk-32' into 'main'

Feat/sk 32

See merge request jjimenez/safekat!662
This commit is contained in:
Alvaro
2025-04-06 07:42:31 +00:00
31 changed files with 614 additions and 129 deletions

View File

@ -1001,6 +1001,11 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
$routes->post("upload/portada", 'Ordentrabajo::upload_orden_trabajo_portada');
$routes->delete("portada/(:num)", 'Ordentrabajo::delete_orden_trabajo_portada/$1');
/**======================
* FILES
*========================**/
$routes->post('get_files', 'Ordentrabajo::get_files');
$routes->post('upload_files', 'Ordentrabajo::upload_files');
/**======================
* PDF
*========================**/

View File

@ -68,8 +68,13 @@ class Ordentrabajo extends BaseController
public function get_orden_trabajo_summary($orden_trabajo_id)
{
$summary = $this->produccionService->init($orden_trabajo_id)->getSummary();
return $this->response->setJSON($summary);
try {
//code...
$summary = $this->produccionService->init($orden_trabajo_id)->getSummary();
return $this->response->setJSON($summary);
} catch (\Throwable $th) {
return $this->response->setStatusCode(500)->setJSON(["message" => $th->getMessage(), "error" => $th]);
}
}
public function add() {}
@ -168,7 +173,7 @@ class Ordentrabajo extends BaseController
->add("logo", fn($q) => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)))
->edit(
"fecha_encuadernado_at",
fn($q) =>$q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->toJson(true);
@ -193,8 +198,8 @@ class Ordentrabajo extends BaseController
$q = $this->produccionService->papelGramajeDatatableQuery();
return DataTable::of($q)
->edit("tiempoReal", fn($q) => $q->tiempoReal * 3600)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_task'), 'data' => $q])
->edit("tiempoReal", fn($q) => $q->tiempoReal)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_paper'), 'data' => $q])
->toJson(true);
}
public function papel_pliego_datatable()
@ -202,8 +207,8 @@ class Ordentrabajo extends BaseController
$q = $this->produccionService->papelPliegoDatatableQuery();
return DataTable::of($q)
->edit("tiempoReal", fn($q) => $q->tiempoReal * 3600)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_task'), 'data' => $q])
->edit("tiempoReal", fn($q) => $q->tiempoReal)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_paper'), 'data' => $q])
->toJson(true);
}
public function reset_tareas(int $orden_trabajo_id)
@ -260,7 +265,7 @@ class Ordentrabajo extends BaseController
$otEntity = $this->otModel->find($orden_trabajo_id);
$pathActualFile = $otEntity->portada_path;
$fullPath = WRITEPATH . 'uploads/' . $pathActualFile;
if(file_exists($fullPath)){
if (file_exists($fullPath)) {
delete_files($fullPath);
}
$r = $this->otModel->update($otEntity->id, ["portada_path" => null]);
@ -289,7 +294,7 @@ class Ordentrabajo extends BaseController
return DataTable::of($q)
->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") : "")
->add("metros_check", fn($q) => $q->otId)
->add("corte", fn($q) => ["otId" => $q->otId,"tipo_corte" => $this->produccionService->ordenTrabajoTareaCorte($q->otId)])
->add("corte", fn($q) => ["otId" => $q->otId, "tipo_corte" => $this->produccionService->ordenTrabajoTareaCorte($q->otId)])
->add("action", fn($q) => $q)
->toJson(true);
}
@ -297,27 +302,32 @@ class Ordentrabajo extends BaseController
{
$q = $this->produccionService->planningPlanaQueryDatatable();
return DataTable::of($q)
->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") : "")
->add("pliegos_check", fn($q) => $q->otId)
->add("action", fn($q) => $q)
->toJson(true);
}
public function select_maquina_planning_rot(){
public function select_maquina_planning_rot()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectMaquinaPlanningRotativa($q);
return $this->response->setJSON($result);
}
public function select_papel_planning_rot(){
public function select_papel_planning_rot()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectPapelPlanningRot($q);
return $this->response->setJSON($result);
}
public function select_maquina_planning_plana(){
public function select_maquina_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectMaquinaPlanningPlana($q);
return $this->response->setJSON($result);
}
public function select_papel_planning_plana(){
public function select_papel_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectPapelPlanningPlana($q);
return $this->response->setJSON($result);
@ -325,7 +335,52 @@ class Ordentrabajo extends BaseController
public function tarea_toggle_corte($orden_trabajo_id)
{
$status = $this->produccionService->tareaUpdateMaquinaCorte($orden_trabajo_id);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $status ]);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $status]);
}
public function get_files()
{
$bodyData = $this->request->getPost();
$files = $this->produccionService->init($bodyData["orden_trabajo_id"])->getOtFiles();
$response = [];
foreach ($files as $key => $file) {
$file_ci4 = new File($file->file_path);
$response[] = [
"name" => $file->name,
"size" => $file_ci4->getSize(),
"hash" => $file->hash()
];
}
return json_encode($response);
}
public function upload_files()
{
try {
//code...
$otFiles = [];
$bodyData = $this->request->getPost();
$files = $this->request->getFileMultiple('file');
$ps = $this->produccionService->init($bodyData["orden_trabajo_id"]);
$existingFiles = json_decode($bodyData["oldFiles"]);
$ps->deleteOtFiles($existingFiles);
if($files){
$response = $ps->storeOtFiles($files);
}else{
$response = null;
}
return $this->response->setJSON([
"message" => lang("App.global_alert_save_success"),
"data" => $response,
"status" => true
]);
} catch (\Throwable $th) {
return $this->response->setJSON(
[
"message" => lang("App.global_alert_save_error"),
"data" => $th,
"error" => $th->getMessage(),
"status" => false
]
);
}
}
}

View File

@ -56,5 +56,27 @@ class Intranet extends Controller
}
}
function orden_trabajo($ot_id,$resource_name)
{
helper('file');
$resource_path = WRITEPATH . 'uploads/orden_trabajo/'.$ot_id. '/' . $resource_name;
if (file_exists($resource_path)) {
// Get the mime type of the file
$mime_type = mime_content_type($resource_path);
// Get an instance of the Response class
$response = service('response');
// Set the content type
$response->setContentType($mime_type);
// Set the output
$response->setBody(file_get_contents($resource_path));
// Send the response to the browser
$response->send();
}
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class OrdenTrabajoTableFilesTable extends Migration
{
protected array $COLUMNS = [
"id" => [
"type" => "INT",
"unsigned" => true,
"auto_increment" => true
],
"orden_trabajo_id" => [
"type" => "INT",
"unsigned" => true,
],
"name" => [
"type" => "TEXT",
],
"upload_by" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
],
"file_path" => [
"type" => "TEXT",
]
];
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("upload_by", "users", "id","CASCADE","CASCADE");
$this->forge->addForeignKey("orden_trabajo_id", "ordenes_trabajo", "id","CASCADE","CASCADE");
$this->forge->createTable("orden_trabajo_files", true);
}
public function down()
{
$this->forge->dropTable("orden_trabajo_files");
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddColumnIsPedidoEsperaOrdenTrabajoTable extends Migration
{
public function up()
{
$field = [
'is_pedido_espera' => [
'type' => 'BOOLEAN',
'default' => false,
'comment' => 'Marca que el pedido está en espera.'
],
'pedido_espera_by' => [
'type' => 'int',
'unsigned' => true,
'constraint' => 11,
'null' => true,
'comment' => 'Foreign a usuario que ha marcado is_pedido_espera'
]
];
$this->forge->addColumn('ordenes_trabajo',$field);
}
public function down()
{
$this->forge->dropColumn('ordenes_trabajo',['is_pedido_espera','pedido_espera_by']);
}
}

View File

@ -8,6 +8,7 @@ use App\Models\Clientes\ClienteModel;
use App\Models\Configuracion\PapelFormatoModel;
use App\Models\Presupuestos\PresupuestoAcabadosModel;
use App\Models\Presupuestos\PresupuestoEncuadernacionesModel;
use App\Models\Presupuestos\PresupuestoFicheroModel;
use App\Models\Presupuestos\PresupuestoLineaModel;
use App\Models\Presupuestos\PresupuestoManipuladosModel;
use App\Models\Presupuestos\PresupuestoModel;
@ -293,4 +294,10 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
$m = model(PapelFormatoModel::class);
return $m->find($this->attributes["papel_formato_id"]);
}
public function files(): array
{
$m = model(PresupuestoFicheroModel::class);
$files = $m->where('presupuesto_id',$this->attributes['id'])->findAll();
return $files ?? [];
}
}

View File

@ -5,10 +5,14 @@ namespace App\Entities\Produccion;
use App\Controllers\Produccion\Ordentrabajo;
use App\Database\Migrations\OrdenTrabajoDatesTable;
use App\Entities\Pedidos\PedidoEntity;
use App\Entities\Usuarios\UserEntity;
use App\Entities\Usuarios\UsersEntity;
use App\Models\OrdenTrabajo\OrdenTrabajoDate;
use App\Models\OrdenTrabajo\OrdenTrabajoFileModel;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use App\Models\OrdenTrabajo\OrdenTrabajoUser;
use App\Models\Pedidos\PedidoModel;
use App\Models\UserModel;
use CodeIgniter\Entity\Entity;
use Picqer\Barcode\Renderers\PngRenderer;
use Picqer\Barcode\Types\TypeCode128;
@ -34,6 +38,9 @@ class OrdenTrabajoEntity extends Entity
"revisar_codigo_barras" => false,
"realizar_imposicion" => false,
"enviar_impresion" => false,
"portada_path" => null,
"is_pedido_espera" => null,
"pedido_espera_by" => null,
];
protected $casts = [
"pedido_id" => "integer",
@ -54,6 +61,8 @@ class OrdenTrabajoEntity extends Entity
"revisar_codigo_barras" => "bool",
"realizar_imposicion" => "bool",
"enviar_impresion" => "bool",
"portada_path" => "string",
"is_pedido_espera" => "bool",
];
@ -109,4 +118,22 @@ class OrdenTrabajoEntity extends Entity
$barcodeData = $barcode->getBarcode($this->pedido()->presupuesto()->id);
return base64_encode($renderer->render($barcodeData,200, 50));
}
public function files() : array
{
$m = model(OrdenTrabajoFileModel::class);
return $m->where('orden_trabajo_id',$this->attributes['id'])->findAll() ?? [];
}
public function pedidoEsperaBy() : ?UsersEntity
{
$m = model(UserModel::class);
if($this->attributes['pedido_espera_by']){
return $m->findById($this->attributes['pedido_espera_by']);
}else{
return null;
}
}
public function getPedidoEsperaBy(): ?UsersEntity
{
return $this->pedidoEsperaBy();
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Entities\Produccion;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;
use CodeIgniter\Entity\Entity;
class OrdenTrabajoFileEntity extends Entity
{
protected $attributes = [
"orden_trabajo_id" => null,
"name" => null,
"upload_by" => null,
"file_path" => null
];
protected $casts = [
"orden_trabajo_id" => "integer",
"name" => "string",
"upload_by" => "integer",
"file_path" => "string"
];
public function orden_trabajo(): ?OrdenTrabajoEntity
{
$m = model(OrdenTrabajoModel::class);
return $m->find($this->attributes["orden_trabajo_id"]);
}
public function hash(): string
{
return array_reverse(explode('/', $this->attributes["file_path"]))[0];
}
}

View File

@ -24,6 +24,7 @@ return [
"progreso" => "Progreso",
"logo" => "Logo impresion",
"filter_by_task" => "Filtrar por tarea",
"filter_by_paper" => "Filtrar por papel",
"metros" => "Metros",
"corte" => "Corte",
"pliegos" => "Pliegos",
@ -76,6 +77,8 @@ return [
"planning_rotativa" => "Planificación rotativa",
"planning_plana" => "Planificación plana",
"solapa" => "Solapa",
"papel_gramajes" => "Papel y gramajes"
"papel_gramajes" => "Papel y gramajes",
"estado" => "Estado",
"pedido_espera" => "Pedido en espera"
];

View File

@ -0,0 +1,56 @@
<?php
namespace App\Models\OrdenTrabajo;
use App\Entities\Produccion\OrdenTrabajoFileEntity;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Model;
class OrdenTrabajoFileModel extends Model
{
protected $table = 'orden_trabajo_files';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = OrdenTrabajoFileEntity::class;
protected $useSoftDeletes = true;
protected $protectFields = true;
protected $allowedFields = [
"orden_trabajo_id",
"name",
"upload_by",
"file_path"
];
protected bool $allowEmptyInserts = false;
protected bool $updateOnlyChanged = true;
protected array $casts = [
];
protected array $castHandlers = [];
// Dates
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
// Validation
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
protected $cleanValidationRules = true;
// Callbacks
protected $allowCallbacks = true;
protected $beforeInsert = [];
protected $afterInsert = [];
protected $beforeUpdate = [];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
}

View File

@ -33,29 +33,14 @@ class OrdenTrabajoModel extends Model
"realizar_imposicion",
"enviar_impresion",
"portada_path",
"is_pedido_espera",
"pedido_espera_by"
];
protected bool $allowEmptyInserts = false;
protected bool $updateOnlyChanged = true;
protected array $casts = [
"pedido_id" => "integer",
"user_created_id" => "?integer",
"user_updated_id" => "?integer",
"fecha_entrega_warning" => "bool",
"fecha_entrega_warning_revised" => "bool",
"total_tirada" => "?integer",
"total_precio" => "?integer",
"tipo_entrada" => "?integer",
"progreso" => "float",
"revisar_formato" => "bool",
"revisar_lomo" => "bool",
"revisar_solapa" => "bool",
"revisar_isbn" => "bool",
"revisar_codigo_barras" => "bool",
"realizar_imposicion" => "bool",
"enviar_impresion" => "bool"
];
protected array $casts = [];
protected array $castHandlers = [];
// Dates

View File

@ -15,15 +15,18 @@ use App\Models\OrdenTrabajo\OrdenTrabajoUser;
use App\Models\Usuarios\UserModel;
use CodeIgniter\Config\BaseService;
use App\Entities\Configuracion\Maquina as MaquinaEntity;
use App\Entities\Produccion\OrdenTrabajoFileEntity;
use App\Entities\Produccion\OrdenTrabajoTareaEntity;
use App\Models\Configuracion\ConfigVariableModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\OrdenTrabajo\OrdenTrabajoFileModel;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\BaseResult;
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Files\UploadedFile;
use CodeIgniter\I18n\Time;
use CodeIgniter\Model;
use Dompdf\Dompdf;
use Exception;
/**
* Clase con las funcionalidades necesarias trabajar con las ordenes de trabajo.
@ -39,6 +42,7 @@ class ProductionService extends BaseService
protected OrdenTrabajoDate $otDate;
protected OrdenTrabajoUser $otUser;
protected OrdenTrabajoEntity $ot;
protected OrdenTrabajoFileModel $otFileModel;
protected UserModel $userModel;
protected string $defaultMaquinaCorteName = 'HT-1000';
protected MaquinaEntity $defaultMaquinaCorte;
@ -80,6 +84,7 @@ class ProductionService extends BaseService
$this->otTarea = model(OrdenTrabajoTarea::class);
$this->otUser = model(OrdenTrabajoUser::class);
$this->userModel = model(UserModel::class);
$this->otFileModel = model(OrdenTrabajoFileModel::class);
}
public function init(int $orden_trabajo_id): self
{
@ -138,6 +143,7 @@ class ProductionService extends BaseService
];
$id = $this->otModel->insert($data);
$this->init($id);
$this->updatePedidoEspera();
$this->storeOrdenTrabajoUsers();
$this->storeOrdenTrabajoDates();
$this->storeAllTareas();
@ -329,6 +335,8 @@ class ProductionService extends BaseService
$ot_tareas["nombre"] = $p_linea->tarifa()->nombre;
$ot_tareas["orden"] = $linea_maquina->orden_planning ?? 110;
$ot_tareas["maquina_id"] = $linea_maquina->id;
$ot_tareas["tiempo_estimado"] = $p_linea->tiempo;
$ot_tareas["tiempo_real"] = $p_linea->tiempo;
$ot_tareas["imposicion_id"] = null;
$this->otTarea->insert($ot_tareas);
$ot_tareas = [];
@ -336,6 +344,8 @@ class ProductionService extends BaseService
$ot_tareas["orden_trabajo_id"] = $this->ot->id;
$ot_tareas["presupuesto_encuadernado_id"] = $p_linea->id;
$ot_tareas["nombre"] = $p_linea->tarifa()->nombre ?? "";
$ot_tareas["tiempo_estimado"] = $p_linea->tiempo;
$ot_tareas["tiempo_real"] = $p_linea->tiempo;
$ot_tareas["orden"] = 110;
$this->otTarea->insert($ot_tareas);
}
@ -443,13 +453,8 @@ class ProductionService extends BaseService
"lg_papel_formato.ancho as papel_ancho",
"lg_papel_formato.alto as papel_alto",
"presupuesto_linea.rotativa_metros_total as metros",
// "JSON_EXTRACT(presupuesto_linea.formas,'$.maquina_ancho') as maquina_ancho",
// "JSON_EXTRACT(presupuesto_linea.formas,'$.maquina_alto') as maquina_alto",
"lg_papel_impresion.nombre as papel_impresion",
"presupuesto_linea.gramaje as papel_gramaje",
])
->join("orden_trabajo_tareas", "orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id", "left")
->join("orden_trabajo_dates", "orden_trabajo_dates.orden_trabajo_id = ordenes_trabajo.id", "left")
@ -460,11 +465,12 @@ class ProductionService extends BaseService
->join("lg_papel_impresion", "lg_papel_impresion.id = presupuesto_linea.papel_impresion_id", "left")
->join("lg_maquinas as lgmp", "lgmp.id = presupuesto_linea.maquina_id", "left")
->join("lg_imposiciones", "lg_imposiciones.id = orden_trabajo_tareas.imposicion_id", "left")
// ->where("orden_trabajo_tareas.orden_trabajo_id", $this->ot->id)
->whereIn("presupuesto_linea.tipo", $this->TIPOS_ROTATIVA)
->where('lg_maquinas.is_rotativa', true)
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC");
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('ordenes_trabajo.id');
return $q;
}
/**
@ -488,9 +494,7 @@ class ProductionService extends BaseService
// "JSON_EXTRACT(presupuesto_linea.formas,'$.maquina_alto') as maquina_alto",
"lg_papel_impresion.nombre as papel_impresion",
"presupuesto_linea.gramaje as papel_gramaje",
"SUM(orden_trabajo_tareas.tiempo_real) as tiempo_real_sum"
])
->join("orden_trabajo_tareas", "orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id", "left")
->join("orden_trabajo_dates", "orden_trabajo_dates.orden_trabajo_id = ordenes_trabajo.id", "left")
@ -505,7 +509,9 @@ class ProductionService extends BaseService
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->where('lg_maquinas.is_rotativa', false)
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC");
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('ordenes_trabajo.id');
return $q;
}
/**
@ -749,6 +755,9 @@ class ProductionService extends BaseService
public function updateOrdenTrabajo($data): bool
{
if(isset($data["is_pedido_espera"])){
$data["pedido_espera_by"] = auth()->user()->id;
}
return $this->otModel->update($this->ot->id, $data);
}
/**========================================================================
@ -894,7 +903,8 @@ class ProductionService extends BaseService
->join("lg_papel_impresion", "presupuesto_linea.papel_impresion_id = lg_papel_impresion.id", "left")
->join("lg_papel_formato", "lg_papel_formato.id = presupuestos.papel_formato_id", "left")
->where("orden_trabajo_tareas.deleted_at", null)
->where("orden_trabajo_tareas.presupuesto_linea_id IS NOT NULL", NULL, FALSE)
->where("orden_trabajo_tareas.presupuesto_linea_
id IS NOT NULL", NULL, FALSE)
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->groupBy('lg_papel_impresion.id');
if ($q) {
@ -926,4 +936,66 @@ class ProductionService extends BaseService
{
return $this->otTarea->where('orden_trabajo_id', $ot_id)->where('is_corte', true)?->first()->tipo_corte ?? null;
}
public function getOtFiles(): array
{
$otFiles = $this->ot->files();
return $otFiles;
}
public function storeOtFiles(array $uploadFiles): array
{
$otFileEntities = [];
foreach ($uploadFiles as $uploadFile) {
$otFileEntities[] = $this->storeOtFile($uploadFile);
}
return $otFileEntities;
}
protected function storeOtFile(UploadedFile $file): ?OrdenTrabajoFileEntity
{
$result = null;
if ($this->ot) {
if ($file->isValid() && !$file->hasMoved()) {
$fullpath = $file->store('orden_trabajo/' . $this->ot->id);
$ot_file_id = $this->otFileModel->insert([
"orden_trabajo_id" => $this->ot->id,
"name" => $file->getClientName(),
"file_path" => WRITEPATH . 'uploads/' . $fullpath,
"upload_by" => auth()->user()->id
]);
$result = $this->otFileModel->find($ot_file_id);
}
return $result;
} else {
throw new Exception('No se ha especificado una orden de trabajo. Usa $this->producctionService->init($orden_trabajo_id)');
}
}
public function deleteOtFiles(?array $existingFiles): bool
{
helper('filesystem');
if ($this->ot) {
$otFiles = $this->ot->files();
foreach ($otFiles as $key => $file) {
$file_path = $file->file_path;
if ($existingFiles) {
if (!in_array($file->name, $existingFiles)) {
$this->otFileModel->delete($file->id);
unlink($file_path);
}
}
}
return true;
} else {
throw new Exception('No se ha especificado una orden de trabajo. Usa $this->producctionService->init($orden_trabajo_id)');
}
}
protected function updatePedidoEspera(): bool
{
$status = false;
$presupuestoFiles = $this->presupuesto->files();
if (count($presupuestoFiles) == 0) {
$status = $this->otModel->update($this->ot->id, ['pedido_espera' => true]);
}
return $status;
}
}

View File

@ -4,7 +4,8 @@
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse"
data-bs-target="#accordionPresupuestoFilesTip" aria-expanded="false"
aria-controls="accordionPresupuestoFilesTip">
<h3><?= lang("Presupuestos.files") ?></h3>
<span><i class="ti-files ti-md ti"></i></span>
<h4><?= lang("Presupuestos.files") ?></h4>
</button>
</h2>
<div id="accordionPresupuestoFilesTip" class="accordion-collapse collapse"
@ -22,11 +23,11 @@
</div>
</div>
<div class="col-md-12 gap-2">
<button id="<?= $id ?>_btnUploadFiles" class="btn mt-3 btn-primary btn-submit waves-effect waves-light ml-2 ">
<button id="<?= $id ?>_btnUploadFiles" class="btn mt-3 btn-sm btn-primary waves-effect waves-light ml-2 ">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('App.global_upload_files') ?></span>
<i class="ti ti-upload ti-xs"></i>
</button>
<button id="<?= $id ?>_btnSubmitFiles" class="btn mt-3 btn-success btn-submit waves-effect waves-light ml-2">
<button id="<?= $id ?>_btnSubmitFiles" class="btn mt-3 btn-success btn-sm waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('App.global_save_file') ?></span>
<i class="ti ti-device-floppy ti-xs"></i>
</button>

View File

@ -14,6 +14,7 @@
<th><?= lang('Produccion.datatable.gramaje') ?></th>
<th></th>
<th><?= lang('Produccion.datatable.pliegos') ?></th>
<th><?= lang('Produccion.datatable.tiempo') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
<tr>
@ -25,13 +26,14 @@
<th></th>
<th></th>
<th><select class="select2 form-select-sm planning-papel-select" name="papel_impresion"></select></th>
<th><input type="text" class="form-control planning-filter" name="gramaje"></th>
<th><input type="text" class="form-control planning-filter" name="papel_gramaje"></th>
<th>
<div class="form-check mt-4">
<input class="form-check-input" id="pliegos-check-all" type="checkbox" value="" />
</div>
</th>
<th><span id="pliegos-sel-total"></span></th>
<th><span id="horas-sel-total"></span></th>
<th></th>
</tr>
</thead>

View File

@ -15,6 +15,7 @@
<th><?= lang('Produccion.datatable.corte') ?></th>
<th></th>
<th><?= lang('Produccion.datatable.metros') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
<tr>
@ -26,7 +27,7 @@
<th></th>
<th></th>
<th><select class="select2 form-select-sm planning-papel-select" name="papel_impresion"></select></th>
<th><input type="text" class="form-control planning-filter" name="gramaje"></th>
<th><input type="text" class="form-control planning-filter" name="papel_gramaje"></th>
<th>
<select class="select2 form-select-sm w-100" name="corte">
<option value="0" default></option>

View File

@ -3,7 +3,7 @@
<h2 class="accordion-header">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionOtDatesTip" aria-expanded="false" aria-controls="accordionOtDatesTip">
<div class="d-flex flex-row justify-content-start align-items-stretch gap-2">
<div class="d-flex flex-row justify-content-start align-items-stretch gap-2">
<span><i class="ti-calendar ti-md ti"></i></span>
<h4> Fechas </h4>
</div>
@ -40,32 +40,38 @@
<!-- Date 5-->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
<div class="row d-flex flex-column">
<label for="ot-fecha-entrega" class="form-label"><?= @lang("Produccion.fecha_entrega_real") ?></label>
<input type="date" class="form-control ot-date" placeholder="DD/MM/YYYY" name="fecha_entrega_real_at" id="ot-fecha-entrega-real" data-input />
<label class="switch switch-danger switch-md mt-1">
<input type="checkbox" class="switch-input ot-preview" name="fecha_entrega_warning" />
<span class="switch-toggle-slider">
<span class="switch-on">
<i class="ti ti-alert-triangle"></i>
<div>
<label for="ot-fecha-entrega" class="form-label"><?= @lang("Produccion.fecha_entrega_real") ?></label>
<input type="date" class="form-control ot-date" placeholder="DD/MM/YYYY" name="fecha_entrega_real_at" id="ot-fecha-entrega-real" data-input />
</div>
<div class="d-flex flex-column">
<label class="switch switch-danger switch-lg mt-1">
<input type="checkbox" class="switch-input ot-preview" name="fecha_entrega_warning" />
<span class="switch-toggle-slider">
<span class="switch-on">
<i class="ti ti-alert-triangle"></i>
</span>
<span class="switch-off">
<i class="ti ti-x"></i>
</span>
</span>
<span class="switch-off">
<i class="ti ti-x"></i>
<span class="switch-label fw-large">Inaplazable</span>
</label>
<label class="switch switch-lg mt-1">
<input type="checkbox" class="switch-input ot-preview" name="fecha_entrega_warning_revised" />
<span class="switch-toggle-slider">
<span class="switch-on">
<i class="ti ti-check"></i>
</span>
<span class="switch-off">
<i class="ti ti-x"></i>
</span>
</span>
</span>
<span class="switch-label">Inaplazable</span>
</label>
<label class="switch switch-md mt-1">
<input type="checkbox" class="switch-input ot-preview" name="fecha_entrega_warning_revised" />
<span class="switch-toggle-slider">
<span class="switch-on">
<i class="ti ti-check"></i>
</span>
<span class="switch-off">
<i class="ti ti-x"></i>
</span>
</span>
<span class="switch-label">Revisada</span>
</label>
<span class="switch-label fw-large">Revisada</span>
</label>
</div>
</div>
</div>

View File

@ -0,0 +1,5 @@
<div class="row">
<div class="col-md-12">
<?= view("themes/vuexy/components/dropzone",data: ['id' => 'dropzone-ot-files','modelId' => $modelId]) ?>
</div><!--//.col -->
</div><!--//.row -->

View File

@ -9,7 +9,7 @@
</button>
</h2>
<div id="accordionOtPortadaTip" class="accordion-collapse collapse show" data-bs-parent="#accordionOtPortada">
<div id="accordionOtPortadaTip" class="accordion-collapse collapse" data-bs-parent="#accordionOtPortada">
<div class="accordion-body">
<div class="mb-3">
<label for="formFile" class="form-label">Portada</label>
@ -17,8 +17,8 @@
</div>
<div class="mb-3">
<div class="d-flex flex-row align-items-center justify-content-start gap-2">
<button type="button" class="btn btn-primary" id="btn-upload-portada"><i class="ti ti-md ti-upload"></i>Subir portada </button>
<button type="button" class="btn btn-danger" id="btn-delete-portada"><i class="ti ti-md ti-trash"></i>Eliminar </button>
<button type="button" class="btn btn-primary btn-sm" id="btn-upload-portada"><i class="ti ti-sm ti-upload"></i>Subir portada </button>
<button type="button" class="btn btn-danger btn-sm" id="btn-delete-portada"><i class="ti ti-sm ti-trash"></i>Eliminar </button>
</div>
</div>

View File

@ -3,7 +3,7 @@
<h2 class="accordion-header">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionOtProgressTip" aria-expanded="false" aria-controls="accordionOtProgressTip">
<div class="d-flex flex-row justify-content-start align-items-stretch gap-2">
<div class="d-flex flex-row justify-content-start align-items-stretch gap-2">
<span><i class="ti-list-details ti-md ti"></i></span>
<h4> Progreso </h4>
</div>
@ -14,9 +14,9 @@
<div class="accordion-body">
<div class="row">
<div class="col-md-12 mb-3">
<label class="form-label" for="ot-progress-bar-parent"><?=@lang("App.progress") ?></label>
<label class="form-label" for="ot-progress-bar-parent"><?= @lang("App.progress") ?></label>
<div class="progress" id="ot-progress-bar-parent">
<div id="ot-progress-bar" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<div id="ot-progress-bar" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
@ -34,7 +34,7 @@
<!-- Progress -->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
<label for="ot-ferro-ok" class="form-label"><?= @lang("Produccion.ferro_ok") ?></label>
<input type="text" class="form-control ot-date" name="ferro_ok_at" placeholder="DD/MM/YYYY" id="ot-ferro-ok">
<input type="text" class="form-control ot-date" name="ferro_ok_at" placeholder="DD/MM/YYYY" id="ot-ferro-ok">
</div>
<!-- Progress -->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
@ -44,12 +44,12 @@
<!-- Progress -->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
<label for="ot-impresion-color" class="form-label"><?= @lang("Produccion.impresion_color") ?></label>
<input type="text" class="form-control ot-date" placeholder="DD/MM/YYYY" name="interior_color_at" id="ot-impresion-color">
<input type="text" class="form-control ot-date" placeholder="DD/MM/YYYY" name="interior_color_at" id="ot-impresion-color">
</div>
<!-- Progress -->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
<label for="ot-portada" class="form-label"><?= @lang("Produccion.portada") ?></label>
<input type="text" class="form-control ot-date" placeholder="DD/MM/YYYY" name="cubierta_at" id="ot-portada">
<input type="text" class="form-control ot-date" placeholder="DD/MM/YYYY" name="cubierta_at" id="ot-portada">
</div>
<!-- Progress -->
<div class="col-xs-12 col-md-4 col-lg-4 mb-2">
@ -76,6 +76,15 @@
<label for="ot-envio" class="form-label"><?= @lang("Produccion.envio") ?></label>
<input type="text" class="form-control ot-date" placeholder="DD/MM/YYYY" name="envio_at" id="ot-envio">
</div>
<!-- <div class="col-xs-12 col-md-4 col-lg-4 mb-2">
<label for="ot-estado" class="form-label"><?= @lang("Produccion.estado") ?></label>
<select class="form-control ot-preview" name="estado" id="ot-estado">
<option value="I">INICIADA</option>
<option value="E">ERROR</option>
<option value="P">PENDIENTE</option>
</select>
</div> -->
</div>
<div class="row">
<div class="row">
@ -87,8 +96,21 @@
</div>
<div class="row">
<div class="col-md-12">
<div class="d-grip">
<button type="button" id="btn-finalizar-orden-pedido" class="btn btn-primary btn-block w-100" <?=$ot->estado == "F" ? "disabled" : "" ?>><?=@lang("Produccion.finalizar_orden")?></button>
<div class="d-flex flex-row justify-content-between align-items-center">
<label class="switch switch-danger switch-lg mt-1">
<input type="checkbox" class="switch-input ot-preview" id="ot-pedido-espera" name="is_pedido_espera" />
<span class="switch-toggle-slider">
<span class="switch-on">
<i class="ti ti-alert-triangle"></i>
</span>
<span class="switch-off">
<i class="ti ti-x"></i>
</span>
</span>
<span class="switch-label fw-lg"><?= @lang("Produccion.pedido_espera") ?></span>
<span class="badge text-bg-warning fw-lg" id="pedido_espera_by"></span>
</label>
<button type="button" id="btn-finalizar-orden-pedido" class="btn btn-primary btn-block" <?= $ot->estado == "F" ? "disabled" : "" ?>><?= @lang("Produccion.finalizar_orden") ?></button>
</div>
</div>
</div>

View File

@ -9,41 +9,45 @@
<?= view("themes/vuexy/form/produccion/ot/otHeader") ?>
<div class="row">
<form id="ot-edit-form">
<div class="col-md-12">
<idv id="ot-edit-form">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otPortada") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otDates") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otDetails") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otProgress") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otTask") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otFiles") ?>
</div>
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otCosts") ?>
</div>
<div class="col-md-12">
<div class="col-md-12 section-block">
<?= view("themes/vuexy/form/produccion/ot/otComments") ?>
</div>
</form>
<div class="col-md-12 mt-3">
<div class="d-grip gap-2">
<a type="button" class="btn btn-outline-danger btn-block mb-1" target="__blank" href="<?= "/produccion/ordentrabajo/pdf/" . $modelId ?>">
</div>
<div class="col-md-12 mt-3">
<div class="d-grip gap-2">
<a type="button" class="btn btn-outline-danger btn-block mb-1" target="__blank" href="<?= "/produccion/ordentrabajo/pdf/" . $modelId ?>">
<span class="ti-sm ti ti-eye me-1"></span>
<?= @lang("Produccion.preview_pdf") ?></a>
<button type="button" class="btn btn-primary btn-block mb-1"><?= @lang("Produccion.imprimir_ferro") ?></button>
<button type="button" class="btn btn-secondary btn-block mb-1"><?= @lang("Produccion.imprimir_codigo_safekat") ?></button>
<button type="button" class="btn btn-primary btn-block mb-1"><?= @lang("Produccion.imprimir_ferro") ?></button>
<button type="button" class="btn btn-secondary btn-block mb-1"><?= @lang("Produccion.imprimir_codigo_safekat") ?></button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="modalCommentTarea" tabindex="-1" aria-hidden="true">
<div class="modal-dialog" role="document">
@ -67,6 +71,8 @@
<?= $this->section('css') ?>
<link rel="stylesheet" href="<?= site_url("themes/vuexy/vendor/libs/dropzone/dropzone.css") ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/spinkit/spinkit.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/notiflix/notiflix.css') ?>" />
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/sweetalert2/sweetalert2.css') ?>" />
@ -74,6 +80,7 @@
<?= $this->endSection() ?>
<?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("themes/vuexy/vendor/libs/dropzone/dropzone.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/notiflix/notiflix.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/bs-stepper/bs-stepper.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/formvalidation/dist/js/FormValidation.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/formvalidation/dist/js/plugins/Bootstrap5.min.js") ?>"></script>