mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Compare commits
168 Commits
mod/histor
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f44da0c2b7 | |||
| 2a3cab872b | |||
| e642f0520a | |||
| 200e45c898 | |||
| 266241b260 | |||
| 94222790df | |||
| e43a7b7304 | |||
| 5e954ae350 | |||
| afe9f6e0e3 | |||
| e65e942e58 | |||
| 065903be2f | |||
| 9ed397e9ad | |||
| a1aaa095d4 | |||
| 41ac08fcd8 | |||
| 709a802db4 | |||
| 5e8a36a345 | |||
| 54816180df | |||
| 0a8ecdb939 | |||
| e3c4cf48ed | |||
| 1d7f2e044f | |||
| 702e6bf77c | |||
| 599fce7f2f | |||
| e01b824045 | |||
| cc757b5db3 | |||
| df21b5ba05 | |||
| 2639fe705e | |||
| 3f65c9e92a | |||
| e804aa3768 | |||
| f73472c729 | |||
| 4ffd280302 | |||
| d1cbb8eb24 | |||
| 3f6037de76 | |||
| 619fd9beba | |||
| e69503c273 | |||
| 6a3a825b26 | |||
| 1ef6d476fe | |||
| 2f6e27d4ca | |||
| 38f6656842 | |||
| d31830cf1a | |||
| f40e88ed6e | |||
| 7e7b39fc38 | |||
| 6c94858d8c | |||
| c79ae6245c | |||
| 107e66a2be | |||
| be3e9a47c2 | |||
| 45ec831f8f | |||
| 9aa7d2e0cb | |||
| 40391405eb | |||
| 7bfe9c002a | |||
| d5c51f2063 | |||
| 61d8dca583 | |||
| e257a3516e | |||
| 26249c893c | |||
| b9360ef7e5 | |||
| 911124287f | |||
| 18b96f020b | |||
| 055274d6df | |||
| f900ace902 | |||
| 401c2c8f5a | |||
| 594da68b3a | |||
| 8a32e13eb4 | |||
| 34701e5960 | |||
| 364b9f8ccd | |||
| 813e5b1980 | |||
| b3336273d0 | |||
| bbd2a389af | |||
| 8007e33760 | |||
| 266e872f8f | |||
| b11b1807d8 | |||
| f5a58dc32d | |||
| ee9e3eb143 | |||
| 5c34316bc2 | |||
| 91f22fd3fb | |||
| 102ba8267b | |||
| 508758331d | |||
| 416b4db915 | |||
| bdb1d1aaec | |||
| bdc0252c72 | |||
| 47eafa75ec | |||
| 4e2003b8b8 | |||
| 5590076d7d | |||
| ddf3255a8a | |||
| 4694d62cd4 | |||
| 0c85af66da | |||
| f6ffa20d5f | |||
| 53ec5945e8 | |||
| 9fcda514f0 | |||
| 410d21dc5f | |||
| 4a60bcdd61 | |||
| 33a196667e | |||
| 03b43de185 | |||
| 2d267386a6 | |||
| 7e82142b38 | |||
| b240107565 | |||
| 647c0bd72d | |||
| 847b476341 | |||
| 6081a34c05 | |||
| c3bce03921 | |||
| 0b598e14d7 | |||
| 83753d1784 | |||
| c35e683089 | |||
| c9b822c9c2 | |||
| ff9ce9eda2 | |||
| 41fde19f43 | |||
| 3b0da8d560 | |||
| fc68676c29 | |||
| 365a487791 | |||
| 9c505584b1 | |||
| 94b72073e4 | |||
| 0b3574ca63 | |||
| cf8ddb3156 | |||
| fd81a188d4 | |||
| 4bfc679c3e | |||
| 819f297e90 | |||
| da0ca27c8c | |||
| 75ac2e0218 | |||
| d89d140dac | |||
| 4da6ee19c6 | |||
| 4fde46a222 | |||
| 55b10a7266 | |||
| 219bdfeaa3 | |||
| 1f5a625513 | |||
| beefc2f416 | |||
| 73fe7e5097 | |||
| 7d1eef9b28 | |||
| 018119a3c3 | |||
| b2652fc277 | |||
| 6c020375be | |||
| 45bd973507 | |||
| 75020a075c | |||
| 900e0b373e | |||
| 00073b3f7e | |||
| 154dfd14f6 | |||
| 8288219872 | |||
| db91776747 | |||
| 70087a24b6 | |||
| 505cc6fb31 | |||
| b0bceb20bc | |||
| b31d9b94eb | |||
| ae60955b3f | |||
| ee4de11cca | |||
| 7aa577f316 | |||
| 882cc913de | |||
| 4fe8930217 | |||
| 0bcd9899ef | |||
| 6967a61d93 | |||
| e53626bbfe | |||
| 808bcd3847 | |||
| e0974068a0 | |||
| d3bcd295cb | |||
| 6a3a10c7e8 | |||
| e2ff0f6667 | |||
| 3a0f355ffe | |||
| 87661d855d | |||
| 95ffb22c84 | |||
| 0e802f791b | |||
| 5a9326ae82 | |||
| 06ba0c0500 | |||
| 760144b5fc | |||
| 49140cea40 | |||
| 6a9331747e | |||
| fb292520a2 | |||
| 909228512c | |||
| 602fb591f9 | |||
| 764d5c8f29 | |||
| b1cd63f665 | |||
| 5058ae488b | |||
| d7a85ca04f |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -14,4 +14,5 @@
|
||||
"username": "sk_imn"
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
@ -9,7 +9,7 @@ use App\Models\Catalogo\IdentificadorIsknModel;
|
||||
|
||||
class CatalogoLibroAsignarIskn extends BaseCommand
|
||||
{
|
||||
protected $group = 'custom';
|
||||
protected $group = 'Safekat';
|
||||
protected $name = 'catalogo:libro-asignar-iskn';
|
||||
protected $description = 'Asigna ISKN directamente en la base de datos a los libros que no lo tienen.';
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ use CodeIgniter\CLI\CLI;
|
||||
|
||||
class CatalogoLibroImportar extends BaseCommand
|
||||
{
|
||||
protected $group = 'custom';
|
||||
protected $group = 'Safekat';
|
||||
protected $name = 'catalogo:libro-importar';
|
||||
protected $description = 'Importa los registros de catalogo_libro a catalogo_libros para un customer_id dado';
|
||||
|
||||
|
||||
274
ci4/app/Commands/ClienteImportar.php
Normal file
274
ci4/app/Commands/ClienteImportar.php
Normal file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
namespace App\Commands;
|
||||
|
||||
use CodeIgniter\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
|
||||
class ClienteImportar extends BaseCommand
|
||||
{
|
||||
protected $group = 'Safekat';
|
||||
protected $name = 'cliente:importar';
|
||||
protected $description = 'Importa registros desde customers a clientes solo si no existen por ID';
|
||||
|
||||
public function run(array $params)
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
$accion = $params[0] ?? 'todo';
|
||||
|
||||
// Mapeo de provincias
|
||||
$provincias = $db->table('lg_provincias')
|
||||
->select('id, nombre')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$provinciaMap = [];
|
||||
foreach ($provincias as $provincia) {
|
||||
$clave = trim(mb_strtolower($provincia['nombre']));
|
||||
$provinciaMap[$clave] = $provincia['id'];
|
||||
}
|
||||
|
||||
if (in_array($accion, ['clientes', 'todo'])) {
|
||||
// ⬅️ aquí va tu bloque actual de importación de clientes
|
||||
$insertados = 0;
|
||||
$omitidos = 0;
|
||||
|
||||
CLI::write("Iniciando importación de clientes por ID...", 'yellow');
|
||||
|
||||
$clientes = $db->table('customers')
|
||||
->where('deleted_at', null)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if (empty($clientes)) {
|
||||
CLI::write('No se encontraron registros en "customers".', 'red');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($clientes as $cliente) {
|
||||
$id = (int) $cliente['id'];
|
||||
|
||||
// Verifica si ya existe en la tabla destino
|
||||
$yaExiste = $db->table('clientes')->where('id', $id)->countAllResults();
|
||||
|
||||
if ($yaExiste) {
|
||||
$omitidos++;
|
||||
CLI::write("Cliente ID $id ya existe. Omitido.", 'blue');
|
||||
continue;
|
||||
}
|
||||
|
||||
$datos = [
|
||||
'id' => $id,
|
||||
'nombre' => $cliente['name'],
|
||||
'alias' => $cliente['alias'],
|
||||
'cif' => $cliente['cif'],
|
||||
'direccion' => $cliente['direccion'],
|
||||
'ciudad' => $cliente['ciudad'],
|
||||
'comunidad_autonoma_id' => $cliente['comunidad_autonoma_id'],
|
||||
'provincia_id' => $this->getProvinciaId($cliente['provincia'], $provinciaMap),
|
||||
'cp' => $cliente['cp'],
|
||||
'pais_id' => $cliente['pais_id'],
|
||||
'telefono' => $cliente['telefono'],
|
||||
'email' => $cliente['email'],
|
||||
'comercial_id' => 122,
|
||||
'soporte_id' => 122,
|
||||
'forma_pago_id' => ($cliente['forma_pago_id'] > 6) ? 1 : $cliente['forma_pago_id'], // Si no se reconoce fijar a transferencias
|
||||
'vencimiento' => $cliente['vencimiento'],
|
||||
'fecha_vencimiento' => $cliente['fechaVencimiento'],
|
||||
'margen' => $cliente['margen'],
|
||||
'descuento' => $cliente['descuento'],
|
||||
'limite_credito' => $cliente['limite_credito'],
|
||||
'limite_credito_user_id' => $cliente['limite_credito_user_id'],
|
||||
'limite_credito_change_at' => $cliente['limite_credito_change_at'],
|
||||
'credito_asegurado' => $cliente['creditoAsegurado'],
|
||||
'ccc' => $cliente['ccc'],
|
||||
'ccc_cliente' => $cliente['ccc_customer'],
|
||||
'num_cuenta' => $cliente['num_cuenta'],
|
||||
'message_tracking' => $cliente['message_tracking'],
|
||||
'message_production_start' => $cliente['message_production_start'],
|
||||
'tirada_flexible' => $cliente['tirada_flexible'],
|
||||
'descuento_tirada_flexible' => $cliente['descuento_tirada_flexible'],
|
||||
'comentarios_tirada_flexible' => $cliente['comentarios_tirada_flexible'],
|
||||
'margen_plantilla_id' => $cliente['margen_plantilla_id'],
|
||||
'comentarios' => $cliente['comentarios'],
|
||||
'deleted_at' => null,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'user_created_id' => 10,
|
||||
'user_update_id' => 10,
|
||||
'no_envio_base' => 0,
|
||||
'forzar_rotativa_pod' => 0,
|
||||
];
|
||||
|
||||
try {
|
||||
$db->table('clientes')->insert($datos);
|
||||
$insertados++;
|
||||
CLI::write("Cliente ID $id insertado correctamente.", 'green');
|
||||
} catch (\Throwable $e) {
|
||||
CLI::error("❌ Error al insertar cliente ID $id: " . $e->getMessage());
|
||||
CLI::error("📦 Datos del cliente: " . json_encode($datos, JSON_PRETTY_PRINT));
|
||||
$omitidos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CLI::write("Importación completada.", 'green');
|
||||
CLI::write("Clientes insertados: $insertados", 'green');
|
||||
CLI::write("Clientes ya existentes: $omitidos", 'blue');
|
||||
|
||||
}
|
||||
|
||||
if (in_array($accion, ['direcciones', 'todo'])) {
|
||||
// ⬅️ aquí va tu bloque actual de importación de direcciones
|
||||
CLI::write("Iniciando importación de direcciones...", 'yellow');
|
||||
|
||||
$direcciones = $db->table('customers_address')
|
||||
->where('deleted_at', null)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$direccionesInsertadas = 0;
|
||||
$direccionesOmitidas = 0;
|
||||
|
||||
foreach ($direcciones as $dir) {
|
||||
$clienteId = (int) $dir['customer_id'];
|
||||
|
||||
$clienteExiste = $db->table('clientes')
|
||||
->where('id', $clienteId)
|
||||
->countAllResults();
|
||||
|
||||
if (!$clienteExiste) {
|
||||
CLI::write("⚠️ Dirección ID {$dir['id']} omitida: cliente_id $clienteId no existe.", 'blue');
|
||||
$direccionesOmitidas++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$direccionExiste = $db->table('cliente_direcciones')
|
||||
->where([
|
||||
'cliente_id' => $clienteId,
|
||||
'direccion' => $dir['direccion'] ?? '',
|
||||
'cp' => $dir['cp'] ?? '0',
|
||||
'municipio' => $dir['ciudad'] ?? '',
|
||||
'provincia' => $dir['provincia'],
|
||||
])
|
||||
->countAllResults();
|
||||
|
||||
if ($direccionExiste) {
|
||||
CLI::write("⚠️ Dirección ID {$dir['id']} ya existe para cliente $clienteId. Omitida.", 'blue');
|
||||
$direccionesOmitidas++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$nuevaDir = [
|
||||
'cliente_id' => $clienteId,
|
||||
'alias' => $dir['nombre'] ?? '',
|
||||
'att' => $dir['persona_contacto'] ?? '',
|
||||
'email' => $dir['email'],
|
||||
'direccion' => $dir['direccion'] ?? '',
|
||||
'pais_id' => is_numeric($dir['pais_id']) ? (int) $dir['pais_id'] : null,
|
||||
'provincia' => $dir['provincia'],
|
||||
'municipio' => $dir['ciudad'] ?? '',
|
||||
'cp' => $dir['cp'] ?? '0',
|
||||
'telefono' => $dir['telefono'],
|
||||
];
|
||||
|
||||
try {
|
||||
$db->table('cliente_direcciones')->insert($nuevaDir);
|
||||
$direccionesInsertadas++;
|
||||
CLI::write("✅ Dirección ID {$dir['id']} insertada para cliente $clienteId", 'green');
|
||||
} catch (\Throwable $e) {
|
||||
CLI::error("❌ Error al insertar dirección ID {$dir['id']} (cliente_id $clienteId): " . $e->getMessage());
|
||||
$direccionesOmitidas++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CLI::write("Importación de direcciones finalizada.", 'green');
|
||||
CLI::write("Direcciones insertadas: $direccionesInsertadas", 'green');
|
||||
CLI::write("Direcciones omitidas: $direccionesOmitidas", 'blue');
|
||||
}
|
||||
|
||||
if (in_array($accion, ['contactos', 'todo'])) {
|
||||
CLI::write("Iniciando importación de contactos...", 'yellow');
|
||||
|
||||
$contactos = $db->table('customers_contact')
|
||||
->where('deleted_at', null)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$contactosInsertados = 0;
|
||||
$contactosOmitidos = 0;
|
||||
|
||||
foreach ($contactos as $contacto) {
|
||||
$clienteId = (int) $contacto['customer_id'];
|
||||
|
||||
// Verificar si cliente existe
|
||||
$clienteExiste = $db->table('clientes')
|
||||
->where('id', $clienteId)
|
||||
->countAllResults();
|
||||
|
||||
if (!$clienteExiste) {
|
||||
CLI::write("⚠️ Contacto ID {$contacto['id']} omitido: cliente_id $clienteId no existe.", 'blue');
|
||||
$contactosOmitidos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validación para evitar duplicados básicos
|
||||
$yaExiste = $db->table('cliente_contactos')
|
||||
->where([
|
||||
'cliente_id' => $clienteId,
|
||||
'email' => $contacto['email'],
|
||||
'nombre' => $contacto['nombre']
|
||||
])
|
||||
->countAllResults();
|
||||
|
||||
if ($yaExiste) {
|
||||
CLI::write("⚠️ Contacto ID {$contacto['id']} ya existe para cliente $clienteId. Omitido.", 'blue');
|
||||
$contactosOmitidos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$nuevoContacto = [
|
||||
'cliente_id' => $clienteId,
|
||||
'cargo' => $contacto['cargo'],
|
||||
'nombre' => $contacto['nombre'],
|
||||
'apellidos' => $contacto['apellidos'],
|
||||
'telefono' => $contacto['telefono'],
|
||||
'email' => $contacto['email'],
|
||||
'deleted_at' => null,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
try {
|
||||
$db->table('cliente_contactos')->insert($nuevoContacto);
|
||||
$contactosInsertados++;
|
||||
CLI::write("✅ Contacto ID {$contacto['id']} insertado para cliente $clienteId", 'green');
|
||||
} catch (\Throwable $e) {
|
||||
CLI::error("❌ Error al insertar contacto ID {$contacto['id']}: " . $e->getMessage());
|
||||
$contactosOmitidos++;
|
||||
}
|
||||
}
|
||||
|
||||
CLI::write("Importación de contactos finalizada.", 'green');
|
||||
CLI::write("Contactos insertados: $contactosInsertados", 'green');
|
||||
CLI::write("Contactos omitidos: $contactosOmitidos", 'blue');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function getProvinciaId(?string $nombre, array $map): ?int
|
||||
{
|
||||
if ($nombre === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$clave = trim(mb_strtolower($nombre));
|
||||
return $map[$clave] ?? null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
93
ci4/app/Commands/RestoreBackup.php
Normal file
93
ci4/app/Commands/RestoreBackup.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Commands;
|
||||
|
||||
use CodeIgniter\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use ZipArchive;
|
||||
|
||||
class RestoreBackup extends BaseCommand
|
||||
{
|
||||
protected $group = 'Safekat';
|
||||
protected $name = 'restore:backup';
|
||||
protected $description = 'Restaura un backup desde un archivo .zip en writable/backups/.';
|
||||
protected $usage = 'restore:backup [--dry-run]';
|
||||
protected $options = [
|
||||
'--dry-run' => 'Simula el proceso de restauración sin ejecutarlo realmente.',
|
||||
];
|
||||
|
||||
public function run(array $params)
|
||||
{
|
||||
$isDryRun = CLI::getOption('dry-run');
|
||||
|
||||
$backupDir = WRITEPATH . 'backups/';
|
||||
$backups = glob($backupDir . '*.zip');
|
||||
|
||||
if (empty($backups)) {
|
||||
CLI::error("No se encontraron backups .zip en: $backupDir");
|
||||
return;
|
||||
}
|
||||
|
||||
CLI::write("Backups disponibles:", 'blue');
|
||||
foreach ($backups as $i => $file) {
|
||||
CLI::write("[" . ($i + 1) . "] " . basename($file));
|
||||
}
|
||||
|
||||
$index = CLI::prompt("Selecciona el número del backup a restaurar", null, 'required');
|
||||
|
||||
if (!is_numeric($index) || $index < 1 || $index > count($backups)) {
|
||||
CLI::error("Selección no válida.");
|
||||
return;
|
||||
}
|
||||
|
||||
$selectedFile = $backups[$index - 1];
|
||||
CLI::write("🎯 Seleccionado: " . basename($selectedFile), 'cyan');
|
||||
|
||||
if ($isDryRun) {
|
||||
CLI::write("🔍 Modo simulación activado (--dry-run)", 'yellow');
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($selectedFile) !== TRUE) {
|
||||
CLI::error("No se pudo abrir el archivo ZIP.");
|
||||
return;
|
||||
}
|
||||
|
||||
$extractPath = WRITEPATH . 'backups/tmp_restore/';
|
||||
if (!is_dir($extractPath)) {
|
||||
mkdir($extractPath, 0775, true);
|
||||
}
|
||||
|
||||
$zip->extractTo($extractPath);
|
||||
$zip->close();
|
||||
|
||||
$sqlFiles = glob($extractPath . '*.sql');
|
||||
if (count($sqlFiles) === 0) {
|
||||
CLI::error("No se encontró ningún .sql dentro del backup.");
|
||||
return;
|
||||
}
|
||||
|
||||
$sqlFile = escapeshellarg($sqlFiles[0]);
|
||||
$db = config('Database')->default;
|
||||
|
||||
$cmd = "mysql -h {$db['hostname']} -u {$db['username']} -p'{$db['password']}' {$db['database']} < {$sqlFile}";
|
||||
|
||||
if ($isDryRun) {
|
||||
CLI::write("📋 Comando que se ejecutaría:", 'yellow');
|
||||
CLI::write($cmd, 'light_gray');
|
||||
CLI::write("✅ Simulación completa. No se hizo ninguna modificación.", 'green');
|
||||
} else {
|
||||
CLI::write("⏳ Restaurando...", 'yellow');
|
||||
system($cmd, $retval);
|
||||
|
||||
if ($retval !== 0) {
|
||||
CLI::error("❌ Error al restaurar la base de datos (código $retval).");
|
||||
} else {
|
||||
CLI::write("✅ Backup restaurado correctamente.", 'green');
|
||||
}
|
||||
}
|
||||
|
||||
array_map('unlink', glob($extractPath . '*'));
|
||||
rmdir($extractPath);
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ class Auth extends ShieldAuth
|
||||
* --------------------------------------------------------------------
|
||||
* Determines whether users can register for the site.
|
||||
*/
|
||||
public bool $allowRegistration = true;
|
||||
public bool $allowRegistration = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------
|
||||
|
||||
@ -42,7 +42,7 @@ class Kint extends BaseConfig
|
||||
*/
|
||||
public string $richTheme = 'aante-light.css';
|
||||
public bool $richFolder = false;
|
||||
public int $richSort = AbstractRenderer::SORT_FULL;
|
||||
public int $richSort = 0; //AbstractRenderer::SORT_FULL;
|
||||
|
||||
/**
|
||||
* @var array<string, class-string<ValuePluginInterface>>|null
|
||||
|
||||
@ -72,4 +72,21 @@ class Paths
|
||||
* is used when no value is provided to `Services::renderer()`.
|
||||
*/
|
||||
public string $viewDirectory = __DIR__ . '/../Views';
|
||||
|
||||
/**
|
||||
* Ruta base relativa dentro de WRITEPATH donde se almacenan
|
||||
* los archivos asociados a presupuestos.
|
||||
*
|
||||
* Esta ruta se utiliza como base para componer las rutas
|
||||
* completas tanto locales como remotas (SFTP) de ficheros
|
||||
* relacionados con cada presupuesto.
|
||||
*
|
||||
* Ejemplo:
|
||||
* Si el ID del presupuesto es 123 y el nombre del archivo es "documento.pdf",
|
||||
* la ruta final será: storage/presupuestos/123/documento.pdf
|
||||
*
|
||||
* Se recomienda mantener esta ruta fuera de `public/` por razones de seguridad
|
||||
* y utilizar controladores para servir los archivos si se desea acceso web.
|
||||
*/
|
||||
public string $presupuestosPath = 'storage/presupuestos';
|
||||
}
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class PedidoXML extends BaseConfig
|
||||
{
|
||||
|
||||
public string $host;
|
||||
public int $port;
|
||||
public string $username;
|
||||
public string $password;
|
||||
public string $base_dir; # FTP server directory
|
||||
public bool $xml_enabled;
|
||||
public int $id_offset;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->host = env("HIDRIVE_HOST","10.5.0.6");
|
||||
$this->port = env("HIDRIVE_PORT",21);
|
||||
$this->username = env("HIDRIVE_USER","admin");
|
||||
$this->password = env("HIDRIVE_PASS","A77h3b0X4OA2rOYAf4w2");
|
||||
$this->base_dir = env("HIDRIVE_PATH_ROOT","/home/admin/safekat"); # FTP server directory
|
||||
$this->xml_enabled = env("FTP_XML_ENABLED",false);
|
||||
$this->id_offset = env("XML_OFFSET_CUSTOMER_ID",1000000);
|
||||
|
||||
}
|
||||
}
|
||||
38
ci4/app/Config/PresupuestoSFTP.php
Normal file
38
ci4/app/Config/PresupuestoSFTP.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class PresupuestoSFTP extends BaseConfig
|
||||
{
|
||||
public string $host;
|
||||
public int $port;
|
||||
public string $username;
|
||||
public string $password;
|
||||
public string $base_dir;
|
||||
public string $remote_base_dir = 'ficheros'; // subcarpeta específica para presupuestos
|
||||
public int $id_offset;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->host = env("HIDRIVE_FILES_HOST", "sftp.hidrive.ionos.com");
|
||||
$this->port = (int) env("HIDRIVE_FILES_PORT", 22);
|
||||
$this->username = env("HIDRIVE_FILES_USER");
|
||||
$this->password = env("HIDRIVE_FILES_PASS");
|
||||
$this->id_offset = (int) env("BUDGET_FILES_OFFSET_ID", 1000000);
|
||||
|
||||
// Directorio base remoto: /users/usuario/dominio
|
||||
$domain = parse_url(env("app.baseURL"), PHP_URL_HOST);
|
||||
$this->base_dir = "/users/{$this->username}/{$domain}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve la ruta completa del directorio remoto para un presupuesto
|
||||
*/
|
||||
public function getRemoteDirForPresupuesto(int $presupuestoId): string
|
||||
{
|
||||
return "{$this->base_dir}/{$this->remote_base_dir}/" . ($presupuestoId + $this->id_offset);
|
||||
}
|
||||
}
|
||||
@ -20,12 +20,6 @@ $routes->get('viewmode/(:alpha)', 'Viewmode::index/$1');
|
||||
$routes->get('test', 'Test::index');
|
||||
|
||||
|
||||
$routes->group('activity', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
|
||||
$routes->get('', 'Actividad::index', ['as' => 'activityList']);
|
||||
$routes->post('datatable', 'Actividad::datatable', ['as' => 'activityDT']);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
* Route Definitions
|
||||
@ -325,6 +319,7 @@ $routes->group('clienteusuarios', ['namespace' => 'App\Controllers\Clientes'], f
|
||||
$routes->group('misdirecciones', ['namespace' => 'App\Controllers\Clientes'], function ($routes) {
|
||||
$routes->get('', 'Clientedirecciones::index', ['as' => 'clientedireccionesIndex']);
|
||||
$routes->get('get/(:num)', 'Clientedirecciones::get/$1', ['as' => 'get']);
|
||||
$routes->get('getId', 'Clientedirecciones::getDireccionIdFromData');
|
||||
$routes->get('getDireccionPresupuesto/(:num)', 'Clientedirecciones::getDireccionPresupuesto/$1', ['as' => 'getDireccionPresupuesto']);
|
||||
$routes->post('add', 'Clientedirecciones::add', ['as' => 'newClientedirecciones']);
|
||||
$routes->get('getSelect2', 'Clientedirecciones::getSelect2', ['as' => 'listaClientedirecciones']);
|
||||
@ -505,7 +500,6 @@ $routes->group('pedidos', ['namespace' => 'App\Controllers\Pedidos'], function (
|
||||
$routes->post('cambiarestado', 'Pedido::cambiarEstado', ['as' => 'cambiarEstadoPedido']);
|
||||
$routes->post('update/(:any)', 'Pedido::update/$1', ['as' => 'actualizarPedido']);
|
||||
$routes->post('insertfactura', 'Pedido::addFactura');
|
||||
$routes->get('xml/(:num)', 'Pedido::get_xml_pedido/$1', ['as' => 'getXMLPedido']);
|
||||
$routes->post('produccion/(:num)', 'Pedido::to_produccion/$1', ['as' => 'toProduccion']);
|
||||
$routes->get('pedidosCliente', 'Pedido::tablaClienteForm');
|
||||
$routes->get('getSumCliente/(:num)', 'Pedido::obtenerTotalPedidosCliente/$1');
|
||||
@ -575,6 +569,7 @@ $routes->group(
|
||||
function ($routes) {
|
||||
$routes->get('index/(:num)', 'PrintAlbaranes::index/$1', ['as' => 'viewAlbaranPDF']);
|
||||
$routes->get('generar/(:num)', 'PrintAlbaranes::generar/$1', ['as' => 'albaranToPdf']);
|
||||
$routes->get('generar-anonimo/(:num)', 'PrintAlbaranes::generarAnonimo/$1', ['as' => 'albaranAnonimoToPdf']);
|
||||
}
|
||||
);
|
||||
|
||||
@ -907,6 +902,8 @@ $routes->group('etiquetasTitulos', ['namespace' => 'App\Controllers\Logistica'],
|
||||
*/
|
||||
$routes->group('translate', ['namespace' => 'App\Controllers'], function ($routes) {
|
||||
$routes->post('getTranslation', 'Language::getTranslation', ['as' => 'getKeys']);
|
||||
$routes->get('lang/(:segment)', 'Language::file/$1');
|
||||
|
||||
});
|
||||
$routes->resource('translate', ['namespace' => 'App\Controllers', 'controller' => 'Language', 'except' => '']);
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ $routes->group('presupuestoadmin', ['namespace' => 'App\Controllers\Presupuestos
|
||||
$routes->post('allmenuitems', 'Presupuestoadmin::allItemsSelect', ['as' => 'select2ItemsOfPresupuestoAdmin']);
|
||||
$routes->post('menuitems', 'Presupuestoadmin::menuItems', ['as' => 'menuItemsOfPresupuestoAdmin']);
|
||||
|
||||
$routes->get('checklomointerior', 'Presupuestoadmin::checkLomo');
|
||||
|
||||
$routes->get('cargar/(:any)', 'Presupuestoadmin::cargar/$1');
|
||||
$routes->post('comparadorinterior', 'Presupuestoadmin::obtenerComparadorInterior');
|
||||
$routes->post('comparadorexteriores', 'Presupuestoadmin::obtenerComparadorExteriores');
|
||||
@ -67,4 +69,10 @@ $routes->group('importador', ['namespace' => 'App\Controllers\Presupuestos'], fu
|
||||
$routes->get('getencuadernacion', 'Importadorpresupuestos::getEncuadernacionList');
|
||||
$routes->get('getpresupuestodata', 'Importadorpresupuestos::getPresupuesto', ['as' => 'getPresupuesto']);
|
||||
$routes->post('importar', 'Importadorpresupuestos::importarPresupuesto');
|
||||
});
|
||||
|
||||
$routes->group('files', ['namespace' => 'App\Controllers\Presupuestos'], function($routes) {
|
||||
$routes->post('get_files', 'PresupuestoFicheroController::get_files', ['as' => 'getFiles']);
|
||||
$routes->post('upload_files', 'PresupuestoFicheroController::upload_files', ['as' => 'uploadFiles']);
|
||||
$routes->post('download_zip', 'PresupuestoFicheroController::download_zip', ['as' => 'downloadFilesZipped']);
|
||||
});
|
||||
35
ci4/app/Config/Routes/SistemaRoutes.php
Normal file
35
ci4/app/Config/Routes/SistemaRoutes.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use CodeIgniter\Router\RouteCollection;
|
||||
|
||||
/** @var RouteCollection $routes */
|
||||
|
||||
/* Rutas para tarifas */
|
||||
$routes->group('sistema', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
|
||||
/* Actividad */
|
||||
$routes->group('actividad', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
|
||||
/**======================
|
||||
* CRUD
|
||||
*========================**/
|
||||
$routes->get('', 'Actividad::index', ['as' => 'activityList']);
|
||||
$routes->post('datatable', 'Actividad::datatable', ['as' => 'activityDT']);
|
||||
|
||||
});
|
||||
|
||||
/* Backups */
|
||||
$routes->group('backups', function ($routes) {
|
||||
/**======================
|
||||
* Tool
|
||||
*========================**/
|
||||
$routes->get('', 'Backups::index', ['as' => 'backupsList']);
|
||||
$routes->get('create', 'Backups::create', ['as' => 'backupsCreate']);
|
||||
$routes->get('create-dev', 'Backups::createDevelopment', ['as' => 'backupsCreateDev']);
|
||||
$routes->get('backups/download/(:segment)', 'Backups::download/$1', ['as' => 'backupsDownload']);
|
||||
$routes->get('delete-local/(:num)', 'Backups::deleteLocal/$1', ['as' => 'backupsDeleteLocal']);
|
||||
$routes->get('delete-local-dev/(:segment)', 'Backups::deleteLocalDevelopment/$1', ['as' => 'backupsDeleteLocalDev']);
|
||||
$routes->get('restore/(:segment)/local', 'Backups::restoreLocal/$1', ['as' => 'backupsRestoreLocal']);
|
||||
$routes->get('restore/(:segment)/remote', 'Backups::restoreRemote/$1', ['as' => 'backupsRestoreRemote']);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@ -11,6 +11,7 @@ use App\Services\PapelImpresionService;
|
||||
use CodeIgniter\Config\BaseService;
|
||||
use App\Services\ProductionService;
|
||||
use App\Services\TarifaMaquinaService;
|
||||
use App\Services\PapelService;
|
||||
use CodeIgniter\Email\Email;
|
||||
|
||||
/**
|
||||
@ -39,6 +40,9 @@ class Services extends BaseService
|
||||
* }
|
||||
*/
|
||||
|
||||
public static function papel(){
|
||||
return new PapelService();
|
||||
}
|
||||
public static function production(){
|
||||
return new ProductionService();
|
||||
}
|
||||
|
||||
@ -476,10 +476,29 @@ class Albaran extends \App\Controllers\BaseResourceController
|
||||
|
||||
$model_linea->update($id, $linea->toArray());
|
||||
|
||||
if($fieldName == 'cajas'){
|
||||
$cajas = $model_linea->where('albaran_id', $linea->albaran_id)
|
||||
->where('cajas > 0')
|
||||
->select('SUM(cajas) as total_cajas')
|
||||
->get();
|
||||
|
||||
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
|
||||
$albaran = $albaranModel->find($linea->albaran_id);
|
||||
if($albaran != false) {
|
||||
$albaran->cajas = $cajas->getRow()->total_cajas;
|
||||
$albaran->user_updated_id = auth()->user()->id;
|
||||
$albaran->updated_at = date('Y-m-d H:i:s');
|
||||
$albaranModel->update($linea->albaran_id, $albaran->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'success' => true,
|
||||
'message' => lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.',
|
||||
];
|
||||
if($fieldName == 'cajas') {
|
||||
$data['cajas'] = $cajas->getRow()->total_cajas;
|
||||
};
|
||||
return $this->respond($data);
|
||||
|
||||
} else {
|
||||
|
||||
@ -35,7 +35,7 @@ class BaseController extends Controller
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $helpers = ['general', 'go_common', 'rbac'];
|
||||
protected $helpers = ['general', 'go_common', 'rbac', 'assets'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
||||
@ -77,6 +77,14 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
*/
|
||||
public $alertStyle = 'alerts';
|
||||
|
||||
/**
|
||||
* Permiso requerido para borrar. Si es false/null, no se valida.
|
||||
* Si es un string (nombre del permiso), se valida.
|
||||
*
|
||||
* @var string|false|null
|
||||
*/
|
||||
protected $deletePermission = false;
|
||||
|
||||
|
||||
/**
|
||||
* An array of helpers to be loaded automatically upon
|
||||
@ -85,7 +93,7 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac']; //JJO
|
||||
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac', 'assets']; //JJO
|
||||
|
||||
/**
|
||||
* Initializer method.
|
||||
@ -222,6 +230,13 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
*/
|
||||
public function delete($id = null)
|
||||
{
|
||||
|
||||
// 🔒 Verificar permiso solo si está definido como string
|
||||
if (is_string($this->deletePermission) && !auth()->user()->can($this->deletePermission)) {
|
||||
$message = lang('Basic.global.permissionDenied'); // O el mensaje que uses
|
||||
return $this->failWithNewToken($message, 403); // Estilo coherente con tu clase
|
||||
}
|
||||
|
||||
if (!empty(static::$pluralObjectNameCc) && !empty(static::$singularObjectNameCc)) {
|
||||
$objName = mb_strtolower(lang(ucfirst(static::$pluralObjectNameCc) . '.' . static::$singularObjectNameCc));
|
||||
} else {
|
||||
@ -236,8 +251,10 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
} else {
|
||||
$datetime = (new \CodeIgniter\I18n\Time("now"));
|
||||
$rawResult = $this->model->where('id', $id)
|
||||
->set(['deleted_at' => $datetime->format('Y-m-d H:i:s'),
|
||||
'is_deleted' => $this->delete_flag])
|
||||
->set([
|
||||
'deleted_at' => $datetime->format('Y-m-d H:i:s'),
|
||||
'is_deleted' => $this->delete_flag
|
||||
])
|
||||
->update();
|
||||
if (!$rawResult) {
|
||||
return $this->failNotFound(lang('Basic.global.deleteError', [$objName]));
|
||||
@ -270,7 +287,8 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
}
|
||||
|
||||
if ($customValidationMessages == null) {
|
||||
$validationErrorMessages = $this->model->validationMessages ?? $this->formValidationErrorMessagess ?? null;;
|
||||
$validationErrorMessages = $this->model->validationMessages ?? $this->formValidationErrorMessagess ?? null;
|
||||
;
|
||||
} else {
|
||||
$validationErrorMessages = $customValidationMessages;
|
||||
}
|
||||
@ -366,12 +384,12 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
|
||||
$queryStr = !is_null($query) ? $query->getQuery() : '';
|
||||
$dbError = $this->model->db->error();
|
||||
$userFriendlyErrMsg = lang('Basic.global.persistErr1', [static::$singularObjectNameCc]);
|
||||
if (isset($dbError['code']) && $dbError['code'] == 1062) :
|
||||
if (isset($dbError['code']) && $dbError['code'] == 1062):
|
||||
$userFriendlyErrMsg .= PHP_EOL . lang('Basic.global.persistDuplErr', [static::$singularObjectNameCc]);
|
||||
endif;
|
||||
// $userFriendlyErrMsg = str_replace("'", "\'", $userFriendlyErrMsg); // Uncomment if experiencing unescaped single quote errors
|
||||
log_message('error', $userFriendlyErrMsg . PHP_EOL . $e->getMessage() . PHP_EOL . $queryStr);
|
||||
if (isset($dbError['message']) && !empty($dbError['message'])) :
|
||||
if (isset($dbError['message']) && !empty($dbError['message'])):
|
||||
log_message('error', $dbError['code'] . ' : ' . $dbError['message']);
|
||||
endif;
|
||||
$this->viewData['errorMessage'] = $userFriendlyErrMsg;
|
||||
|
||||
@ -252,11 +252,12 @@ class CatalogoLibros extends BaseResourceController
|
||||
't1.id',
|
||||
't1.created_at',
|
||||
't1.tirada',
|
||||
'(CASE WHEN t1.tirada > 0 THEN t1.total / t1.tirada ELSE 0 END)',
|
||||
't1.total',
|
||||
't1.estado'
|
||||
])
|
||||
->edit('total', fn($row) => number_format((float) $row->total, 2, ',', '.') . ' €')
|
||||
->edit('precio_ud', fn($row) => number_format((float) $row->total, 2, ',', '.') . ' €')
|
||||
->edit('precio_ud', fn($row) => number_format((float) $row->precio_ud, 2, ',', '.') . ' €')
|
||||
->edit('created_at', fn($row) => date('d/m/Y', strtotime($row->created_at)))
|
||||
->add('actionBtns', function ($row) {
|
||||
return '<div class="btn-group btn-group-sm">
|
||||
|
||||
@ -61,11 +61,13 @@ class ChatController extends BaseController
|
||||
$this->chatService = service("chat");
|
||||
|
||||
}
|
||||
public function index() {}
|
||||
public function get_chat_departments(string $model,int $modelId)
|
||||
public function index()
|
||||
{
|
||||
}
|
||||
public function get_chat_departments(string $model, int $modelId)
|
||||
{
|
||||
|
||||
$data = $this->chatService->getChatDepartments($model,$modelId);
|
||||
$data = $this->chatService->getChatDepartments($model, $modelId);
|
||||
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
@ -250,7 +252,7 @@ class ChatController extends BaseController
|
||||
public function store_message($model)
|
||||
{
|
||||
$data = $this->request->getPost();
|
||||
$chatMessageEntity = $this->chatService->storeChatMessage($data["chat_department_id"],$model,$data["model_id"],$data);
|
||||
$chatMessageEntity = $this->chatService->storeChatMessage($data["chat_department_id"], $model, $data["model_id"], $data);
|
||||
return $this->response->setJSON($chatMessageEntity);
|
||||
|
||||
}
|
||||
@ -341,22 +343,26 @@ class ChatController extends BaseController
|
||||
}
|
||||
public function get_chat_users_internal()
|
||||
{
|
||||
$query = $this->userModel->builder()->select(
|
||||
[
|
||||
"id",
|
||||
"CONCAT(first_name,' ',last_name,'(',username,')') as name"
|
||||
]
|
||||
)->where("cliente_id", null)
|
||||
->where("deleted_at", null)
|
||||
->whereNotIn("id", [auth()->user()->id]);
|
||||
if ($this->request->getGet("q")) {
|
||||
$query->groupStart()
|
||||
->orLike("users.username", $this->request->getGet("q"))
|
||||
->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
|
||||
$builder = $this->userModel->builder();
|
||||
|
||||
$builder->select([
|
||||
'users.id',
|
||||
"CONCAT(first_name, ' ', last_name, ' (', auth_identities.secret, ')') AS name"
|
||||
])
|
||||
->join('auth_identities', 'auth_identities.user_id = users.id AND auth_identities.type = "email_password"')
|
||||
->where('cliente_id', null)
|
||||
->where('deleted_at', null)
|
||||
->whereNotIn('users.id', [auth()->user()->id]);
|
||||
|
||||
if ($this->request->getGet('q')) {
|
||||
$q = $this->request->getGet('q');
|
||||
$builder->groupStart()
|
||||
->orLike('auth_identities.secret', $q)
|
||||
->orLike("CONCAT(first_name, ' ', last_name)", $q)
|
||||
->groupEnd();
|
||||
}
|
||||
|
||||
return $this->response->setJSON($query->get()->getResultObject());
|
||||
return $this->response->setJSON($builder->get()->getResultObject());
|
||||
}
|
||||
public function get_chat_users_all()
|
||||
{
|
||||
@ -381,7 +387,7 @@ class ChatController extends BaseController
|
||||
$pm = model(PresupuestoModel::class);
|
||||
$p = $pm->find($presupuesto_id);
|
||||
$cm = model(ClienteModel::class);
|
||||
$clienteContactos = $cm->querySelectClienteContacto($p->cliente_id,$this->request->getGet('q'));
|
||||
$clienteContactos = $cm->querySelectClienteContacto($p->cliente_id, $this->request->getGet('q'));
|
||||
return $this->response->setJSON($clienteContactos);
|
||||
}
|
||||
public function get_pedido_client_users(int $pedido_id)
|
||||
@ -389,7 +395,7 @@ class ChatController extends BaseController
|
||||
$pm = model(PedidoModel::class);
|
||||
$p = $pm->find($pedido_id);
|
||||
$cm = model(ClienteModel::class);
|
||||
$clienteContactos = $cm->querySelectClienteContacto($p->cliente()->id,$this->request->getGet('q'));
|
||||
$clienteContactos = $cm->querySelectClienteContacto($p->cliente()->id, $this->request->getGet('q'));
|
||||
return $this->response->setJSON($clienteContactos);
|
||||
}
|
||||
public function get_factura_client_users(int $factura_id)
|
||||
@ -397,7 +403,7 @@ class ChatController extends BaseController
|
||||
$fm = model(FacturaModel::class);
|
||||
$f = $fm->find($factura_id);
|
||||
$cm = model(ClienteModel::class);
|
||||
$clienteContactos = $cm->querySelectClienteContacto($f->cliente_id,$this->request->getGet('q'));
|
||||
$clienteContactos = $cm->querySelectClienteContacto($f->cliente_id, $this->request->getGet('q'));
|
||||
return $this->response->setJSON($clienteContactos);
|
||||
}
|
||||
public function get_orden_trabajo_client_users(int $orden_trabajo_id)
|
||||
@ -406,21 +412,21 @@ class ChatController extends BaseController
|
||||
$ot = $otm->find($orden_trabajo_id);
|
||||
$cm = model(ClienteModel::class);
|
||||
$cliente = $ot->pedido()->cliente();
|
||||
$clienteContactos = $cm->querySelectClienteContacto($cliente->id,$this->request->getGet('q'));
|
||||
$clienteContactos = $cm->querySelectClienteContacto($cliente->id, $this->request->getGet('q'));
|
||||
return $this->response->setJSON($clienteContactos);
|
||||
}
|
||||
public function store_hebra(string $model)
|
||||
{
|
||||
$auth_user = auth()->user();
|
||||
$bodyData = $this->request->getPost();
|
||||
$status = $this->chatService->storeHebra($model,$bodyData['modelId'],$bodyData);
|
||||
$status = $this->chatService->storeHebra($model, $bodyData['modelId'], $bodyData);
|
||||
return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => $status]);
|
||||
}
|
||||
|
||||
public function update_hebra($chat_id)
|
||||
{
|
||||
$bodyData = $this->request->getPost();
|
||||
$chatMessageId = $this->chatMessageModel->insert([
|
||||
$chatMessageId = $this->chatMessageModel->insert([
|
||||
"chat_id" => $chat_id,
|
||||
"message" => $bodyData["message"],
|
||||
"sender_id" => auth()->user()->id
|
||||
@ -441,9 +447,9 @@ class ChatController extends BaseController
|
||||
}
|
||||
return $this->response->setJSON(["message" => "Hebra actualizada correctamente", "status" => true]);
|
||||
}
|
||||
public function get_hebra(string $model,int $modelId)
|
||||
public function get_hebra(string $model, int $modelId)
|
||||
{
|
||||
$data = $this->chatService->getHebras($model,$modelId);
|
||||
$data = $this->chatService->getHebras($model, $modelId);
|
||||
return $this->response->setJSON($data);
|
||||
}
|
||||
|
||||
@ -456,8 +462,8 @@ class ChatController extends BaseController
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i"))
|
||||
->edit('updated_at', fn($q) => Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i"))
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
|
||||
->add("action", fn($q) => [
|
||||
"type" => "direct",
|
||||
"modelId" => $q->id,
|
||||
@ -478,12 +484,18 @@ class ChatController extends BaseController
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
|
||||
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("action", fn($q) => ["type" => "presupuesto", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]])
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("action", fn($q) => [
|
||||
"type" => "presupuesto",
|
||||
"modelId" => $q->id,
|
||||
"isAdmin" => $isAdmin,
|
||||
"chatMessageId" => $q->chatMessageId,
|
||||
"lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]
|
||||
])
|
||||
->toJson(true);
|
||||
}
|
||||
public function datatable_pedido_messages()
|
||||
@ -494,12 +506,18 @@ class ChatController extends BaseController
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
|
||||
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => ["type" => "pedido", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]])
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => [
|
||||
"type" => "pedido",
|
||||
"modelId" => $q->id,
|
||||
"isAdmin" => $isAdmin,
|
||||
"chatMessageId" => $q->chatMessageId,
|
||||
"lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]
|
||||
])
|
||||
|
||||
->toJson(true);
|
||||
}
|
||||
@ -511,12 +529,18 @@ class ChatController extends BaseController
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
|
||||
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => ["type" => "factura", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]])
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => [
|
||||
"type" => "factura",
|
||||
"modelId" => $q->id,
|
||||
"isAdmin" => $isAdmin,
|
||||
"chatMessageId" => $q->chatMessageId,
|
||||
"lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]
|
||||
])
|
||||
|
||||
->toJson(true);
|
||||
}
|
||||
@ -528,29 +552,41 @@ class ChatController extends BaseController
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
|
||||
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => ["type" => "ot", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]])
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => [
|
||||
"type" => "ot",
|
||||
"modelId" => $q->id,
|
||||
"isAdmin" => $isAdmin,
|
||||
"chatMessageId" => $q->chatMessageId,
|
||||
"lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]
|
||||
])
|
||||
|
||||
->toJson(true);
|
||||
}
|
||||
public function datatable_direct_messages()
|
||||
{
|
||||
$auth_user_id = auth()->user()->id;
|
||||
$auth_user_id = auth()->user()->id;
|
||||
$isAdmin = auth()->user()->inGroup('admin');
|
||||
$query = $this->chatModel->getQueryDatatableDirectMessages($auth_user_id);
|
||||
return DataTable::of($query)
|
||||
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
|
||||
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
|
||||
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => ["type" => "direct", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]])
|
||||
->edit("creator", fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">' . lang("App.me") . '</span>' : $q->creator)
|
||||
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
|
||||
->add("action", fn($q) => [
|
||||
"type" => "direct",
|
||||
"modelId" => $q->id,
|
||||
"isAdmin" => $isAdmin,
|
||||
"chatMessageId" => $q->chatMessageId,
|
||||
"lang" => [
|
||||
"view_chat" => lang('Chat.view_chat'),
|
||||
"view_by_alt_message" => lang('Chat.view_by_alt_message')
|
||||
]
|
||||
])
|
||||
|
||||
->toJson(true);
|
||||
}
|
||||
@ -651,14 +687,15 @@ class ChatController extends BaseController
|
||||
{
|
||||
$bodyData = $this->request->getPost();
|
||||
$auth_user = auth()->user();
|
||||
$bodyData["sender_id"] = $auth_user->id;
|
||||
$bodyData["sender_id"] = $auth_user->id;
|
||||
$chat_message_id = $this->chatMessageModel->insert($bodyData);
|
||||
$users_id = $this->chatUserModel->getChatUserArrayId($chat_id);
|
||||
foreach ($users_id as $user_id) {
|
||||
if ($user_id != $auth_user->id) {
|
||||
$this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user_id]);
|
||||
}
|
||||
};
|
||||
}
|
||||
;
|
||||
$message = $this->chatMessageModel->get_chat_message($chat_message_id);
|
||||
return $this->response->setJSON($message);
|
||||
}
|
||||
@ -747,7 +784,7 @@ class ChatController extends BaseController
|
||||
}
|
||||
public function chat_department_edit($chat_department_id)
|
||||
{
|
||||
$chatDepartment = $this->chatDeparmentModel->find($chat_department_id);
|
||||
$chatDepartment = $this->chatDeparmentModel->find($chat_department_id);
|
||||
$this->viewData['breadcrumb'] = [
|
||||
['title' => lang("App.menu_configuration"), 'route' => 'javascript:void(0);', 'active' => false],
|
||||
['title' => lang("App.menu_config_messages"), 'route' => route_to("configMessagesIndex"), 'active' => false],
|
||||
|
||||
@ -215,13 +215,13 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
|
||||
{
|
||||
try {
|
||||
$resourceData = $this->model->getDireccion($id);
|
||||
$response = (object)[
|
||||
$response = (object) [
|
||||
'error' => false,
|
||||
'data' => $resourceData
|
||||
];
|
||||
return $this->respond($response);
|
||||
} catch (\Exception $e) {
|
||||
$response = (object)[
|
||||
$response = (object) [
|
||||
'error' => true,
|
||||
'message' => $e->getMessage()
|
||||
];
|
||||
@ -229,22 +229,61 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
|
||||
}
|
||||
}
|
||||
|
||||
public function getDireccionIdFromData()
|
||||
{
|
||||
$data = $this->request->getGet('data') ?? [];
|
||||
$cliente_id = $this->request->getGet('cliente_id') ?? -1;
|
||||
$att = $data['att'] ?? "";
|
||||
$direccion = $data['direccion'] ?? "";
|
||||
$cp = $data['cp'] ?? "";
|
||||
$municipio = $data['municipio'] ?? "";
|
||||
$provincia = $data['provincia'] ?? "";
|
||||
$pais_id = $data['pais_id'] ?? -1;
|
||||
$email = $data['email'] ?? "";
|
||||
$telefono = $data['telefono'] ?? "";
|
||||
try {
|
||||
$model = model('App\Models\Clientes\ClienteDireccionesModel');
|
||||
$id = $model->select('id')
|
||||
->where('att', $att)
|
||||
->where('direccion', $direccion)
|
||||
->where('cp', $cp)
|
||||
->where('municipio', $municipio)
|
||||
->where('provincia', $provincia)
|
||||
->where('pais_id', $pais_id)
|
||||
->where('email', $email)
|
||||
->where('telefono', $telefono)
|
||||
->where('cliente_id', $cliente_id)
|
||||
->get()
|
||||
->getResultObject();
|
||||
|
||||
if (count($id) > 0) {
|
||||
$id = $id[0]->id;
|
||||
} else {
|
||||
$id = null;
|
||||
}
|
||||
return $id;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getDireccionPresupuesto($id)
|
||||
{
|
||||
try {
|
||||
$model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
|
||||
$resourceData = $model->getDireccion($id);
|
||||
if(count($resourceData) > 0){
|
||||
if (count($resourceData) > 0) {
|
||||
$resourceData[0]->direccionId = $id;
|
||||
}
|
||||
|
||||
$response = (object)[
|
||||
|
||||
$response = (object) [
|
||||
'error' => false,
|
||||
'data' => $resourceData
|
||||
];
|
||||
return $this->respond($response);
|
||||
} catch (\Exception $e) {
|
||||
$response = (object)[
|
||||
$response = (object) [
|
||||
'error' => true,
|
||||
'message' => $e->getMessage()
|
||||
];
|
||||
@ -400,11 +439,11 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
|
||||
protected function getComunidadAutonomaListItems($selId = null)
|
||||
{
|
||||
$data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('ComunidadesAutonomas.comunidadAutonoma'))])];
|
||||
if (!is_null($selId)) :
|
||||
if (!is_null($selId)):
|
||||
$comunidadAutonomaModel = model('App\Models\Configuracion\ComunidadAutonomaModel');
|
||||
|
||||
$selOption = $comunidadAutonomaModel->where('id', $selId)->findColumn('nombre');
|
||||
if (!empty($selOption)) :
|
||||
if (!empty($selOption)):
|
||||
$data[$selId] = $selOption[0];
|
||||
endif;
|
||||
endif;
|
||||
@ -414,11 +453,11 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
|
||||
protected function getProvinciaListItems($selId = null)
|
||||
{
|
||||
$data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Provincias.provincia'))])];
|
||||
if (!empty($selId)) :
|
||||
if (!empty($selId)):
|
||||
$provinciaModel = model('App\Models\Configuracion\ProvinciaModel');
|
||||
|
||||
$selOption = $provinciaModel->where('id', $selId)->findColumn('nombre');
|
||||
if (!empty($selOption)) :
|
||||
if (!empty($selOption)):
|
||||
$data[$selId] = $selOption[0];
|
||||
endif;
|
||||
endif;
|
||||
|
||||
@ -25,6 +25,7 @@ class Proveedores extends \App\Controllers\BaseResourceController {
|
||||
|
||||
protected $indexRoute = 'proveedorList';
|
||||
|
||||
protected $deletePermission = 'proveedores.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) {
|
||||
|
||||
@ -26,6 +26,8 @@ class FormasPago extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'formaDePagoList';
|
||||
|
||||
protected $deletePermission = 'formas-pago.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -44,6 +46,7 @@ class FormasPago extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('formas-pago.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -61,6 +64,7 @@ class FormasPago extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
checkPermission('formas-pago.create');
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
|
||||
@ -115,6 +119,7 @@ class FormasPago extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('formas-pago.edit');
|
||||
|
||||
if ($requestedId == null) :
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -21,6 +21,8 @@ class Group extends \App\Controllers\GoBaseController
|
||||
|
||||
protected $indexRoute = 'userGroupList';
|
||||
|
||||
protected $deletePermission = 'roles-permisos.delete';
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
self::$viewPath = getenv('theme.path') . 'form/group/';
|
||||
@ -37,6 +39,8 @@ class Group extends \App\Controllers\GoBaseController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('roles-permisos.menu');
|
||||
|
||||
$this->viewData['usingClientSideDataTable'] = true;
|
||||
$this->viewData['pageSubTitle'] = lang('Basic.global.ManageAllRecords', [lang('Groups.group')]);
|
||||
// IMN
|
||||
@ -48,11 +52,12 @@ class Group extends \App\Controllers\GoBaseController
|
||||
public function add()
|
||||
{
|
||||
|
||||
checkPermission('roles-permisos.create');
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
|
||||
$temp_data['id'] = $groupEntity->id;
|
||||
$temp_data['title'] = $postData['title'];
|
||||
$temp_data['description'] = $postData['description'];
|
||||
|
||||
@ -124,6 +129,7 @@ class Group extends \App\Controllers\GoBaseController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('roles-permisos.edit');
|
||||
|
||||
helper('general');
|
||||
|
||||
@ -243,30 +249,4 @@ class Group extends \App\Controllers\GoBaseController
|
||||
}
|
||||
}
|
||||
|
||||
public function menuItems()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$searchStr = goSanitize($this->request->getPost('searchTerm'))[0];
|
||||
$reqId = goSanitize($this->request->getPost('id'))[0];
|
||||
$reqText = goSanitize($this->request->getPost('text'))[0];
|
||||
$onlyActiveOnes = false;
|
||||
$columns2select = [$reqId ?? 'id', $reqText ?? 'nombre'];
|
||||
$onlyActiveOnes = false;
|
||||
$menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr);
|
||||
$nonItem = new \stdClass;
|
||||
$nonItem->id = '';
|
||||
$nonItem->text = '- ' . lang('Basic.global.None') . ' -';
|
||||
array_unshift($menu, $nonItem);
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
$data = [
|
||||
'menu' => $menu,
|
||||
$csrfTokenName => $newTokenHash
|
||||
];
|
||||
return $this->respond($data);
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ class Maquinas extends \App\Controllers\BaseResourceController
|
||||
protected static $viewPath = 'themes/vuexy/form/configuracion/maquinas/';
|
||||
|
||||
protected $indexRoute = 'maquinaList';
|
||||
|
||||
protected MaquinaService $maquinaService;
|
||||
protected Validation $validation;
|
||||
|
||||
@ -55,6 +56,7 @@ class Maquinas extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('maquinas.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -112,6 +114,8 @@ class Maquinas extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
checkPermission('maquinas.create');
|
||||
|
||||
if ($this->request->getPost()):
|
||||
|
||||
$nullIfEmpty = true; // !(phpversion() >= '8.1');
|
||||
@ -176,7 +180,7 @@ class Maquinas extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
|
||||
checkPermission('maquinas.edit');
|
||||
|
||||
if ($requestedId == null):
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -28,6 +28,8 @@ class Maquinasdefecto extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'maquinaPorDefectoList';
|
||||
|
||||
protected $deletePermission = 'maquinas-defecto.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -45,6 +47,7 @@ class Maquinasdefecto extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('maquinas-defecto.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -63,7 +66,7 @@ class Maquinasdefecto extends \App\Controllers\BaseResourceController
|
||||
public function add()
|
||||
{
|
||||
|
||||
|
||||
checkPermission('maquinas-defecto.create');
|
||||
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
@ -138,6 +141,7 @@ class Maquinasdefecto extends \App\Controllers\BaseResourceController
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
|
||||
checkPermission('maquinas-defecto.edit');
|
||||
|
||||
if ($requestedId == null) :
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -100,6 +100,7 @@ class Maquinaspapelesimpresion extends \App\Controllers\BaseResourceController {
|
||||
$resourceData = $this->model->getResource($search, $isRotativa, $tarifas, $maquina_id)
|
||||
->orderBy($order, $dir)->orderBy($order2, $dir2)->orderBy($order3, $dir3)->orderBy($order4, $dir4)->limit($length, $start)->get()->getResultObject();
|
||||
|
||||
$query =$this->model->getLastQuery();
|
||||
return $this->respond(Collection::datatable(
|
||||
$resourceData,
|
||||
$this->model->getResource("", $isRotativa, $tarifas, $maquina_id)->countAllResults(),
|
||||
|
||||
@ -29,6 +29,7 @@ class Paises extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'paisList';
|
||||
|
||||
protected $deletePermission = 'paises.delete';
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -47,6 +48,7 @@ class Paises extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('paises.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -65,6 +67,8 @@ class Paises extends \App\Controllers\BaseResourceController
|
||||
public function add()
|
||||
{
|
||||
|
||||
checkPermission('paises.create');
|
||||
|
||||
if ($this->request->getPost()):
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
@ -119,6 +123,7 @@ class Paises extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('paises.edit');
|
||||
|
||||
if ($requestedId == null):
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -28,6 +28,7 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'papelGenericoList';
|
||||
|
||||
protected $deletePermission = 'papel-generico.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
@ -40,6 +41,8 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
// Se indica el flag para los ficheros borrados
|
||||
$this->delete_flag = 1;
|
||||
|
||||
$this->papelService = service('papel');
|
||||
|
||||
// Breadcrumbs (IMN)
|
||||
$this->viewData['breadcrumb'] = [
|
||||
['title' => lang("App.menu_configuration"), 'route' => "javascript:void(0);", 'active' => false],
|
||||
@ -52,6 +55,7 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('papel-generico.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -69,10 +73,7 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
checkPermission('papel-generico.create');
|
||||
|
||||
if ($this->request->getPost()):
|
||||
|
||||
@ -120,9 +121,11 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
endif; // $noException && $successfulResult
|
||||
|
||||
endif; // ($requestMethod === 'post')
|
||||
|
||||
|
||||
$this->viewData['papelGenerico'] = isset($sanitizedData) ? new PapelGenerico($sanitizedData) : new PapelGenerico();
|
||||
|
||||
$this->viewData['tipoPapelGenericoList'] = $this->papelService->getTipoPapelGenerico();
|
||||
|
||||
$this->viewData['formAction'] = route_to('createPapelGenerico');
|
||||
|
||||
$this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('PapelGenerico.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
|
||||
@ -132,6 +135,7 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('papel-generico.edit');
|
||||
|
||||
if ($requestedId == null):
|
||||
return $this->redirect2listView();
|
||||
@ -145,7 +149,6 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
endif;
|
||||
|
||||
|
||||
|
||||
if ($this->request->getPost()):
|
||||
|
||||
$nullIfEmpty = true; // !(phpversion() >= '8.1');
|
||||
@ -211,6 +214,8 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController
|
||||
|
||||
$this->viewData['papelGenerico'] = $papelGenerico;
|
||||
|
||||
$this->viewData['tipoPapelGenericoList'] = $this->papelService->getTipoPapelGenerico();
|
||||
|
||||
$this->viewData['formAction'] = route_to('updatePapelGenerico', $id);
|
||||
|
||||
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('PapelGenerico.moduleTitle') . ' ' . lang('Basic.global.edit3');
|
||||
|
||||
@ -52,6 +52,9 @@ class Papelesimpresion extends \App\Controllers\BaseResourceController
|
||||
protected static $viewPath = 'themes/vuexy/form/configuracion/papel/';
|
||||
|
||||
protected $indexRoute = 'papelImpresionList';
|
||||
|
||||
protected $deletePermission = 'papel-impresion.delete';
|
||||
|
||||
protected Validation $validation;
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
@ -81,6 +84,7 @@ class Papelesimpresion extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('papel-impresion.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -98,7 +102,7 @@ class Papelesimpresion extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
|
||||
checkPermission('papel-impresion.create');
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
|
||||
@ -161,6 +165,7 @@ class Papelesimpresion extends \App\Controllers\BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('papel-impresion.edit');
|
||||
|
||||
if ($requestedId == null) :
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -22,6 +22,8 @@ class SeriesFacturas extends BaseResourceController
|
||||
|
||||
protected $indexRoute = 'seriesFacturasList';
|
||||
|
||||
protected $deletePermission = 'series-facturas.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -40,6 +42,7 @@ class SeriesFacturas extends BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('series-facturas.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -57,6 +60,8 @@ class SeriesFacturas extends BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
checkPermission('series-facturas.create');
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
@ -110,6 +115,8 @@ class SeriesFacturas extends BaseResourceController
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
|
||||
checkPermission('series-facturas.edit');
|
||||
|
||||
if ($requestedId == null) :
|
||||
return $this->redirect2listView();
|
||||
endif;
|
||||
|
||||
@ -22,6 +22,8 @@ class Ubicaciones extends BaseResourceController
|
||||
|
||||
protected $indexRoute = 'ubicacionesList';
|
||||
|
||||
protected $deletePermission = 'ubicaciones.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -40,6 +42,7 @@ class Ubicaciones extends BaseResourceController
|
||||
|
||||
public function index()
|
||||
{
|
||||
checkPermission('ubicaciones.menu');
|
||||
|
||||
$viewData = [
|
||||
'currentModule' => static::$controllerSlug,
|
||||
@ -57,6 +60,8 @@ class Ubicaciones extends BaseResourceController
|
||||
|
||||
public function add()
|
||||
{
|
||||
checkPermission('ubicaciones.create');
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
@ -111,6 +116,7 @@ class Ubicaciones extends BaseResourceController
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
checkPermission('ubicaciones.edit');
|
||||
|
||||
if ($requestedId == null) :
|
||||
return $this->redirect2listView();
|
||||
|
||||
@ -69,7 +69,7 @@ class Users extends \App\Controllers\GoBaseController
|
||||
public function add()
|
||||
{
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
if ($this->request->getPost()):
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
|
||||
@ -94,8 +94,8 @@ class Users extends \App\Controllers\GoBaseController
|
||||
// Obtener proveedor de usuarios
|
||||
$users = auth()->getProvider();
|
||||
|
||||
if ($successfulResult = $this->canValidate()) :
|
||||
if ($this->canValidate()) :
|
||||
if ($successfulResult = $this->canValidate()):
|
||||
if ($this->canValidate()):
|
||||
try {
|
||||
|
||||
// The Email is unique
|
||||
@ -134,17 +134,12 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$thenRedirect = true; // Change this to false if you want your user to stay on the form after submission
|
||||
endif;
|
||||
|
||||
if ($noException && $successfulResult) :
|
||||
if ($noException && $successfulResult):
|
||||
|
||||
$id = $users->getInsertID();
|
||||
$this->group_user_model->where('user_id', $id)->delete();
|
||||
foreach ($currentGroups as $group) {
|
||||
$group_user_data = [
|
||||
'user_id' => $id,
|
||||
'group' => $group
|
||||
];
|
||||
$this->group_user_model->insert($group_user_data);
|
||||
}
|
||||
// Asignar los grupos de usuarios a los que pertenece el usuario editado
|
||||
$this->saveUserGroupsSafely($id, $currentGroups);
|
||||
|
||||
$this->chat_department_user_model->where("user_id", $id)->delete();
|
||||
foreach ($chatDepartments as $chatDepartment) {
|
||||
$this->chat_department_user_model->insert([
|
||||
@ -156,8 +151,8 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$message = lang('Basic.global.saveSuccess', [mb_strtolower(lang('Users.user'))]) . '.';
|
||||
$message = ucfirst(str_replace("'", "\'", $message));
|
||||
|
||||
if ($thenRedirect) :
|
||||
if (!empty($this->indexRoute)) :
|
||||
if ($thenRedirect):
|
||||
if (!empty($this->indexRoute)):
|
||||
return redirect()->to(route_to($this->indexRoute))->with('successMessage', $message);
|
||||
else:
|
||||
return $this->redirect2listView('successMessage', $message);
|
||||
@ -173,7 +168,7 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$this->viewData['user'] = isset($sanitizedData) ? new UserEntity($sanitizedData) : new UserEntity();
|
||||
$this->viewData['clienteList'] = $this->getClienteListItems();
|
||||
$this->viewData['formAction'] = route_to('createUser');
|
||||
$this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll();
|
||||
$this->viewData['groups'] = $this->group_model->select('keyword, title')->where('id >', 0)->findAll();
|
||||
$this->viewData['chatDepartments'] = $this->chat_department_model->findAll();
|
||||
$this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.addNewSuffix');
|
||||
|
||||
@ -191,12 +186,12 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$users = auth()->getProvider();
|
||||
$user = $users->findById($id);
|
||||
|
||||
if ($user == false) :
|
||||
if ($user == false):
|
||||
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Users.user')), $id]);
|
||||
return $this->redirect2listView('errorMessage', $message);
|
||||
endif;
|
||||
|
||||
if ($this->request->getPost()) :
|
||||
if ($this->request->getPost()):
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
|
||||
@ -218,9 +213,9 @@ class Users extends \App\Controllers\GoBaseController
|
||||
}
|
||||
|
||||
$noException = true;
|
||||
if ($successfulResult = $this->canValidate()) :
|
||||
if ($successfulResult = $this->canValidate()):
|
||||
|
||||
if ($this->canValidate()) :
|
||||
if ($this->canValidate()):
|
||||
try {
|
||||
|
||||
if (in_array('cliente-editor', $currentGroups) || in_array('cliente-administrador', $currentGroups)) {
|
||||
@ -249,16 +244,11 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$thenRedirect = false;
|
||||
|
||||
endif;
|
||||
if ($noException && $successfulResult) :
|
||||
if ($noException && $successfulResult):
|
||||
|
||||
// Asignar los grupos de usuarios a los que pertenece el usuario editado
|
||||
$this->saveUserGroupsSafely($user->id, $currentGroups);
|
||||
|
||||
$this->group_user_model->where('user_id', $user->id)->delete();
|
||||
foreach ($currentGroups as $group) {
|
||||
$group_user_data = [
|
||||
'user_id' => $user->id,
|
||||
'group' => $group
|
||||
];
|
||||
$this->group_user_model->insert($group_user_data);
|
||||
}
|
||||
$this->chat_department_user_model->where("user_id", $id)->delete();
|
||||
foreach ($chatDepartments as $chatDepartment) {
|
||||
$this->chat_department_user_model->insert([
|
||||
@ -270,8 +260,8 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Users.user'))]) . '.';
|
||||
$message = ucfirst(str_replace("'", "\'", $message));
|
||||
|
||||
if ($thenRedirect) :
|
||||
if (!empty($this->indexRoute)) :
|
||||
if ($thenRedirect):
|
||||
if (!empty($this->indexRoute)):
|
||||
return redirect()->to(route_to($this->indexRoute))->with('successMessage', $message);
|
||||
else:
|
||||
return $this->redirect2listView('successMessage', $message);
|
||||
@ -287,7 +277,7 @@ class Users extends \App\Controllers\GoBaseController
|
||||
$this->viewData['clienteList'] = $this->getClienteListItems($user->cliente_id);
|
||||
$this->viewData['formAction'] = route_to('updateUser', $id);
|
||||
$this->viewData['selectedGroups'] = $this->group_model->getUsersRoles($requestedId);
|
||||
$this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll();
|
||||
$this->viewData['groups'] = $this->group_model->select('keyword, title')->where('id >', 0)->findAll();
|
||||
$this->viewData['chatDepartments'] = $this->chat_department_model->select(["display", "name", "id as chatDepartmentId"])->findAll();
|
||||
$this->viewData['chatDepartmentUser'] = $this->chat_department_user_model->getChatDepartmentUser($user->id);
|
||||
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.edit3');
|
||||
@ -299,18 +289,22 @@ class Users extends \App\Controllers\GoBaseController
|
||||
public function delete($requestedId = null, bool $deletePermanently = true)
|
||||
{
|
||||
|
||||
if ($requestedId == null) :
|
||||
if ($requestedId == null):
|
||||
return $this->redirect2listView();
|
||||
endif;
|
||||
|
||||
$id = filter_var($requestedId, FILTER_SANITIZE_URL);
|
||||
$user = $this->model->find($id);
|
||||
|
||||
if ($user == false) :
|
||||
if ($user == false):
|
||||
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Users.user')), $id]);
|
||||
return $this->redirect2listView('errorMessage', $message);
|
||||
endif;
|
||||
|
||||
// Elimina todos los grupos actuales
|
||||
$this->group_user_model->where('user_id', $id)->delete();
|
||||
|
||||
// Elimina todos los grupos de chat actuales
|
||||
$this->chat_department_user_model->where("user_id", $id)->delete();
|
||||
|
||||
$users = auth()->getProvider();
|
||||
@ -433,11 +427,11 @@ class Users extends \App\Controllers\GoBaseController
|
||||
protected function getClienteListItems($selId = null)
|
||||
{
|
||||
$data = ['' => ""];
|
||||
if (!empty($selId)) :
|
||||
if (!empty($selId)):
|
||||
$clienteModel = model('App\Models\Clientes\ClienteModel');
|
||||
|
||||
$selOption = $clienteModel->where('id', $selId)->findColumn('nombre');
|
||||
if (!empty($selOption)) :
|
||||
if (!empty($selOption)):
|
||||
$data[$selId] = $selOption[0];
|
||||
endif;
|
||||
endif;
|
||||
@ -450,7 +444,7 @@ class Users extends \App\Controllers\GoBaseController
|
||||
['title' => lang("App.menu_change_session"), 'route' => route_to('maquinistaUserChangeList'), 'active' => true]
|
||||
];
|
||||
$maquinistas = [];
|
||||
$users = auth()->getProvider()->whereNotIn('id',[auth()->user()->id])->findAll();
|
||||
$users = auth()->getProvider()->whereNotIn('id', [auth()->user()->id])->findAll();
|
||||
foreach ($users as $key => $user) {
|
||||
if ($user->inGroup('maquina') && !$user->inGroup('admin', 'comercial', 'cliente-editor', 'cliente-admin')) {
|
||||
$maquinistas[] = $user;
|
||||
@ -467,4 +461,50 @@ class Users extends \App\Controllers\GoBaseController
|
||||
auth()->login($user);
|
||||
return redirect("home");
|
||||
}
|
||||
|
||||
/**
|
||||
* Asigna grupos a un usuario, asegurando que no se pueda inyectar el grupo 'root',
|
||||
* pero manteniéndolo si ya lo tenía previamente.
|
||||
*
|
||||
* @param int $userId ID del usuario al que se le asignarán los grupos
|
||||
* @param array $requestedGroups Grupos solicitados desde el formulario
|
||||
* @return void
|
||||
*/
|
||||
private function saveUserGroupsSafely(int $userId, array $requestedGroups): void
|
||||
{
|
||||
// Verifica si el usuario ya tenía el grupo 'root'
|
||||
$existingGroups = $this->group_user_model
|
||||
->where('user_id', $userId)
|
||||
->findColumn('group') ?? [];
|
||||
|
||||
$hasRoot = in_array('root', $existingGroups);
|
||||
|
||||
// Elimina todos los grupos actuales
|
||||
$this->group_user_model->where('user_id', $userId)->delete();
|
||||
|
||||
// Inserta solo los grupos válidos (sin 'root')
|
||||
foreach ($requestedGroups as $group) {
|
||||
if (!empty($group) && $group !== 'root') {
|
||||
$this->group_user_model->insert([
|
||||
'user_id' => $userId,
|
||||
'group' => $group,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
} elseif ($group === 'root') {
|
||||
log_message('alert', "Intento de asignar grupo 'root' al usuario ID $userId");
|
||||
}
|
||||
}
|
||||
|
||||
// Reasigna 'root' solo si el usuario ya lo tenía
|
||||
if ($hasRoot) {
|
||||
$this->group_user_model->insert([
|
||||
'user_id' => $userId,
|
||||
'group' => 'root',
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ abstract class GoBaseController extends Controller
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac']; //JJO
|
||||
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac', 'assets']; //JJO
|
||||
|
||||
public static $queries = [];
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Importadores;
|
||||
|
||||
use App\Controllers\BaseResourceController;
|
||||
@ -393,7 +394,7 @@ class ImportadorBubok extends BaseResourceController
|
||||
'gramajeCubierta' => in_array($encuadernadoId, [1, 3]) ? 150 : 300, // 150 gramos para "fresado tapa dura" y "cosido tapa dura"
|
||||
'solapas' => !empty($producto->cover->type->consolapas) ? 80 : 0,
|
||||
'acabado' => $acabadoId,
|
||||
'cabezada' => 'WHI',
|
||||
'cabezada' => model('\App\Models\Configuracion\ConfigVariableModel')->getCabezadaDefault(),
|
||||
'lomoRedondo' => 0
|
||||
],
|
||||
'guardas' => [],
|
||||
@ -456,85 +457,33 @@ class ImportadorBubok extends BaseResourceController
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
// Descarga y subida de archivos al SFTP
|
||||
$presupuestoFicheroModel = model('App\Models\Presupuestos\PresupuestoFicheroModel');
|
||||
$ftp = new \App\Libraries\SafekatFtpClient();
|
||||
// ✅ Importar archivos desde URLs y subir al SFTP
|
||||
$uploaderService = new \App\Services\PresupuestoUploaderService(
|
||||
new \App\Libraries\SftpClientWrapper(config('PresupuestoSFTP')),
|
||||
model(\App\Models\Presupuestos\PresupuestoFicheroModel::class),
|
||||
config('PresupuestoSFTP')
|
||||
);
|
||||
|
||||
$archivoUrls = [
|
||||
'cover' => $producto->cover->file ?? null,
|
||||
'body' => $producto->body->file ?? null,
|
||||
];
|
||||
|
||||
foreach ($archivoUrls as $tipo => $url) {
|
||||
if (!$url)
|
||||
continue;
|
||||
$resultadoArchivos = $uploaderService->importarArchivosDesdeUrlsBubok($response['sk_id'], $archivoUrls);
|
||||
|
||||
try {
|
||||
$contenido = @file_get_contents($url); // silenciar errores de PHP
|
||||
|
||||
if ($contenido === false || strlen($contenido) === 0) {
|
||||
// No se pudo descargar el archivo: generar archivo de error para FTP
|
||||
$errorMessage = "ERROR: No se pudo descargar el archivo remoto para $tipo desde la URL: $url";
|
||||
|
||||
$remoteDir = $ftp->getPresupuestoRemotePath($response['sk_id']); // crea esta función si no existe
|
||||
$remoteErrorFile = $remoteDir . '/ERROR_' . strtoupper($tipo) . '.txt';
|
||||
|
||||
// Crear archivo temporal con el mensaje de error
|
||||
$tempErrorFile = WRITEPATH . 'uploads/presupuestos/ERROR_' . $tipo . '.txt';
|
||||
file_put_contents($tempErrorFile, $errorMessage);
|
||||
|
||||
if (!$ftp->is_dir($remoteDir)) {
|
||||
$ftp->mkdir($remoteDir, recursive: true);
|
||||
}
|
||||
|
||||
$ftp->put($remoteErrorFile, $tempErrorFile, $ftp::SOURCE_LOCAL_FILE);
|
||||
|
||||
continue; // no procesar este archivo
|
||||
}
|
||||
|
||||
// ✅ Procesar normalmente si la descarga tuvo éxito
|
||||
$nombreOriginal = basename(parse_url($url, PHP_URL_PATH));
|
||||
$extension = pathinfo($nombreOriginal, PATHINFO_EXTENSION);
|
||||
|
||||
$nombreLimpio = $presupuestoFicheroModel->saveFileInBBDD(
|
||||
$response['sk_id'],
|
||||
$nombreOriginal,
|
||||
$extension,
|
||||
auth()->id()
|
||||
);
|
||||
|
||||
if (is_null($nombreLimpio))
|
||||
continue;
|
||||
|
||||
$rutaLocal = WRITEPATH . 'uploads/presupuestos/';
|
||||
if (!is_dir($rutaLocal)) {
|
||||
mkdir($rutaLocal, 0777, true);
|
||||
}
|
||||
|
||||
file_put_contents($rutaLocal . $nombreLimpio, $contenido);
|
||||
} catch (\Throwable $e) {
|
||||
//log_message('error', 'Error inesperado en descarga de archivo remoto: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Subir al FTP después de guardar localmente
|
||||
try {
|
||||
$ftp->uploadFilePresupuesto($response['sk_id']);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Error subiendo archivos al FTP: ' . $e->getMessage());
|
||||
if (!$resultadoArchivos['success']) {
|
||||
log_message('warning', 'Errores al importar archivos desde Bubok: ' . print_r($resultadoArchivos['errores'], true));
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'data' => [
|
||||
'sk_id' => $response['sk_id'],
|
||||
'sk_url' => $response['sk_url'] ?? null
|
||||
'sk_url' => $response['sk_url'] ?? null,
|
||||
'archivos_subidos' => $resultadoArchivos['archivos_subidos'],
|
||||
'errores_archivos' => $resultadoArchivos['errores']
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return $this->respond([
|
||||
'status' => 500,
|
||||
@ -544,8 +493,4 @@ class ImportadorBubok extends BaseResourceController
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ class ImportadorCatalogo extends BaseResourceController
|
||||
'gramajeCubierta' => $libro->cubierta_gramaje,
|
||||
'solapas' => $libro->cubierta_ancho_solapas,
|
||||
'acabado' => $libro->cubierta_acabado_id,
|
||||
'cabezada' => 'WHI',
|
||||
'cabezada' => model('\App\Models\Configuracion\ConfigVariableModel')->getCabezadaDefault(),
|
||||
'lomoRedondo' => 0
|
||||
],
|
||||
|
||||
@ -344,6 +344,10 @@ class ImportadorCatalogo extends BaseResourceController
|
||||
]
|
||||
];
|
||||
|
||||
// Vincular el presupuesto con el catálogo
|
||||
model('\App\Models\Presupuestos\PresupuestoModel')
|
||||
->vincularCatalogo($response['data']['sk_id'], $libro->id);
|
||||
|
||||
|
||||
// Ajuste del precio a RAMA
|
||||
$respuesta_ajuste = PresupuestoService::ajustarPresupuesto(
|
||||
@ -362,7 +366,7 @@ class ImportadorCatalogo extends BaseResourceController
|
||||
|
||||
// confirmar y crear pedido y ot
|
||||
model('App\Models\Presupuestos\PresupuestoModel')->confirmarPresupuesto($response['data']['sk_id']);
|
||||
PresupuestoService::crearPedido($response['data']['sk_id'],isImported:true);
|
||||
PresupuestoService::crearPedido($response['data']['sk_id'], isImported: true);
|
||||
|
||||
return $this->respond($response);
|
||||
|
||||
@ -379,7 +383,7 @@ class ImportadorCatalogo extends BaseResourceController
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function calcularPrecioDesdeTarifa($isColor, $encuadernacionId, $ancho, $alto, $paginas, $tarifas)
|
||||
{
|
||||
// Solo aplicamos tarifa si la encuadernación es Rústica Fresada (id = 2)
|
||||
|
||||
@ -39,4 +39,19 @@ class Language extends BaseController
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function file(string $file)
|
||||
{
|
||||
$locale = $this->request->getLocale(); // es, en, fr…
|
||||
$path = APPPATH."Language/{$locale}/{$file}.php";
|
||||
|
||||
if (! is_file($path)) {
|
||||
return $this->response->setStatusCode(404);
|
||||
}
|
||||
|
||||
/** @var array $lines */
|
||||
$lines = require $path; // el array que devuelve tu lang-file
|
||||
|
||||
return $this->response->setJSON($lines); // Content-Type: application/json
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,4 +71,55 @@ class PrintAlbaranes extends BaseController
|
||||
->setHeader('Content-Length', strlen($output))
|
||||
->setBody($output);
|
||||
}
|
||||
|
||||
public function generarAnonimo($albaran_id)
|
||||
{
|
||||
|
||||
// Cargar modelos
|
||||
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
|
||||
$lineasAlbaranModel = model('App\Models\Albaranes\AlbaranLineaModel');
|
||||
|
||||
// Informacion del presupuesto
|
||||
$data['albaran'] = $albaranModel->getResourceForPdf($albaran_id)->get()->getRow();
|
||||
$data['albaranLineas'] = $lineasAlbaranModel->getResourceForPdf($albaran_id)->get()->getResultObject();
|
||||
|
||||
|
||||
// Obtener contenido HTML de la vista
|
||||
$html = view(getenv('theme.path') . 'pdfs/albaran-anonimo', $data);
|
||||
|
||||
// Cargar CSS desde archivo local
|
||||
$css = file_get_contents(FCPATH . 'themes/vuexy/css/pdf.albaran.css');
|
||||
// Combinar CSS y HTML
|
||||
$html_con_css = "<style>$css</style>" . $html;
|
||||
|
||||
// Crear una instancia de Dompdf
|
||||
$options = new \Dompdf\Options();
|
||||
$options->set('isHtml5ParserEnabled', true);
|
||||
$options->set('isPhpEnabled', true);
|
||||
$options->set('isRemoteEnabled', true);
|
||||
$dompdf = new \Dompdf\Dompdf($options);
|
||||
|
||||
// Contenido HTML del documento
|
||||
$dompdf->loadHtml($html_con_css);
|
||||
|
||||
// Establecer el tamaño del papel
|
||||
$dompdf->setPaper('A4', 'portrait');
|
||||
|
||||
// Renderizar el PDF
|
||||
$dompdf->render();
|
||||
|
||||
// Obtener el contenido generado
|
||||
$output = $dompdf->output();
|
||||
|
||||
// Establecer las cabeceras para visualizar en lugar de descargar
|
||||
$file_name = "alabaran-$albaran_id.pdf";
|
||||
return $this->response
|
||||
->setStatusCode(200)
|
||||
->setHeader('Content-Type', 'application/pdf')
|
||||
->setHeader('Content-Disposition', 'inline; filename="' . $file_name . '"')
|
||||
->setHeader('Cache-Control', 'private, max-age=0, must-revalidate')
|
||||
->setHeader('Pragma', 'public')
|
||||
->setHeader('Content-Length', strlen($output))
|
||||
->setBody($output);
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ use App\Controllers\Facturacion\Facturas;
|
||||
use App\Entities\Pedidos\PedidoEntity;
|
||||
use App\Models\Collection;
|
||||
use App\Models\Pedidos\PedidoModel;
|
||||
use App\Services\PedidoXMLService;
|
||||
use App\Services\ProductionService;
|
||||
use Hermawan\DataTables\DataTable;
|
||||
use CodeIgniter\I18n\Time;
|
||||
@ -614,12 +613,7 @@ class Pedido extends \App\Controllers\BaseResourceController
|
||||
$pedidoEntity->created_at_footer = $pedidoEntity->created_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->created_at)) : '';
|
||||
$pedidoEntity->updated_at_footer = $pedidoEntity->updated_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->updated_at)) : '';
|
||||
}
|
||||
public function get_xml_pedido($pedido_id)
|
||||
{
|
||||
$data = PedidoXMLService::generate_xml($pedido_id);
|
||||
// $xml_service = new PedidoXMLService($this->model);
|
||||
return $this->respond($data);
|
||||
}
|
||||
|
||||
|
||||
public function to_produccion($pedido_id)
|
||||
{
|
||||
|
||||
@ -36,6 +36,8 @@ class Buscador extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'buscadorPresupuestosList';
|
||||
|
||||
protected $deletePermission = 'presupuesto.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Presupuestos;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Services\PresupuestoUploaderService;
|
||||
use App\Libraries\SftpClientWrapper;
|
||||
use App\Models\Presupuestos\PresupuestoFicheroModel;
|
||||
use Config\PresupuestoSFTP;
|
||||
|
||||
class PresupuestoFicheroController extends BaseController
|
||||
{
|
||||
|
||||
|
||||
public function get_files()
|
||||
{
|
||||
// Aceptar solo POST (puedes cambiar a GET si lo necesitas)
|
||||
if ($this->request->getMethod(true) !== 'POST') {
|
||||
return $this->response->setStatusCode(405)->setJSON(['message' => 'Método no permitido']);
|
||||
}
|
||||
|
||||
$presupuesto_id = $this->request->getPost('presupuesto_id') ?? 0;
|
||||
|
||||
$model = model('App\Models\Presupuestos\PresupuestoFicheroModel');
|
||||
$files = $model->getFiles($presupuesto_id);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$relativePath = $file->file_path;
|
||||
$fullPath = WRITEPATH . ltrim($relativePath, '/');
|
||||
|
||||
$relativePath = $file->file_path;
|
||||
$basename = basename($relativePath); // solo el nombre del archivo
|
||||
|
||||
$result[] = (object) [
|
||||
'name' => $file->nombre,
|
||||
'size' => file_exists(WRITEPATH . $relativePath) ? filesize(WRITEPATH . $relativePath) : 0,
|
||||
'hash' => $basename
|
||||
];
|
||||
}
|
||||
|
||||
return $this->response->setJSON($result);
|
||||
}
|
||||
|
||||
|
||||
public function upload_files()
|
||||
{
|
||||
$request = service('request');
|
||||
$model = model('App\Models\Presupuestos\PresupuestoFicheroModel');
|
||||
$files = $request->getFiles()['file'] ?? [];
|
||||
$presupuesto_id = $request->getPost('presupuesto_id');
|
||||
$old_files = json_decode($request->getPost('oldFiles') ?? '[]');
|
||||
|
||||
if (!is_array($files)) {
|
||||
$files = [$files];
|
||||
}
|
||||
|
||||
// Servicio de subida (con SFTP)
|
||||
$service = new \App\Services\PresupuestoUploaderService(
|
||||
new \App\Libraries\SftpClientWrapper(config('PresupuestoSFTP')),
|
||||
$model,
|
||||
config('PresupuestoSFTP')
|
||||
);
|
||||
|
||||
// Borrar ficheros eliminados por el usuario (BD y remoto)
|
||||
$service->removeFromRemote($presupuesto_id);
|
||||
$numDeleted = $model->deleteMissingFiles($presupuesto_id, $old_files);
|
||||
|
||||
$results = [];
|
||||
foreach ($files as $file) {
|
||||
if (!$file->isValid()) {
|
||||
$results[] = [
|
||||
'name' => $file->getName(),
|
||||
'status' => 'invalid',
|
||||
'message' => $file->getErrorString()
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
$newName = $model->saveFileInBBDD(
|
||||
$presupuesto_id,
|
||||
$file->getClientName(),
|
||||
$file->getClientExtension(),
|
||||
auth()->id()
|
||||
);
|
||||
|
||||
// Crear directorio si no existe
|
||||
$uploadDir = dirname($model->getAbsolutePath($presupuesto_id, $newName));
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
$file->move($uploadDir, $newName);
|
||||
|
||||
$results[] = [
|
||||
'name' => $file->getClientName(),
|
||||
'status' => 'uploaded'
|
||||
];
|
||||
}
|
||||
|
||||
// Subida al SFTP
|
||||
$sftpResult = $service->uploadToRemote($presupuesto_id);
|
||||
|
||||
// ✅ Contar totales para mostrar en el frontend
|
||||
$numUploaded = count(array_filter($results, fn($f) => $f['status'] === 'uploaded'));
|
||||
$numErrores = count(array_filter($results, fn($f) => $f['status'] !== 'uploaded'));
|
||||
|
||||
if (!$sftpResult['success']) {
|
||||
return $this->response->setJSON([
|
||||
'message' => 'Error en la subida de algunos archivos.',
|
||||
'summary' => [
|
||||
'subidos_ok' => $numUploaded,
|
||||
'errores_locales' => $numErrores,
|
||||
'errores_remotos' => count(array_filter($sftpResult['files'], fn($f) => !$f['success'])),
|
||||
'borrados' => $numDeleted,
|
||||
],
|
||||
'details' => [
|
||||
'local' => $results,
|
||||
'sftp' => $sftpResult['files']
|
||||
]
|
||||
])->setStatusCode(500);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'message' => 'Archivos subidos correctamente.',
|
||||
'summary' => [
|
||||
'subidos_ok' => $numUploaded,
|
||||
'errores_locales' => $numErrores,
|
||||
'errores_remotos' => 0,
|
||||
'borrados' => $numDeleted
|
||||
],
|
||||
'details' => [
|
||||
'local' => $results,
|
||||
'sftp' => $sftpResult['files']
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function download_zip()
|
||||
{
|
||||
$presupuesto_id = $this->request->getPost('presupuesto_id');
|
||||
$ot_id = $this->request->getPost('ot_id');
|
||||
|
||||
if (!$presupuesto_id) {
|
||||
return $this->response->setStatusCode(400)->setBody('Presupuesto ID requerido');
|
||||
}
|
||||
|
||||
$prefijo = (!empty($ot_id) && is_numeric($ot_id)) ? "OT_{$ot_id}" : null;
|
||||
|
||||
$service = new \App\Services\PresupuestoUploaderService(
|
||||
new \App\Libraries\SftpClientWrapper(config('PresupuestoSFTP')),
|
||||
model('App\Models\Presupuestos\PresupuestoFicheroModel'),
|
||||
config('PresupuestoSFTP')
|
||||
);
|
||||
|
||||
$result = $service->downloadZip((int) $presupuesto_id, $prefijo);
|
||||
|
||||
if (!$result['success'] || empty($result['zipPath'])) {
|
||||
return $this->response
|
||||
->setStatusCode(500)
|
||||
->setJSON(['error' => $result['message']]);
|
||||
}
|
||||
|
||||
$zipPath = $result['zipPath'];
|
||||
|
||||
// Definir nombre final del ZIP para el cliente
|
||||
$nombreArchivo = $prefijo
|
||||
? "{$prefijo}_PRESUPUESTO_{$presupuesto_id}.zip"
|
||||
: "archivos_presupuesto_{$presupuesto_id}.zip";
|
||||
|
||||
// Eliminar archivo ZIP tras terminar la descarga (una vez enviada la respuesta)
|
||||
register_shutdown_function(function () use ($zipPath) {
|
||||
if (file_exists($zipPath)) {
|
||||
unlink($zipPath);
|
||||
}
|
||||
});
|
||||
|
||||
// Descargar el archivo al cliente
|
||||
return $this->response
|
||||
->download($zipPath, null)
|
||||
->setFileName($nombreArchivo);
|
||||
}
|
||||
}
|
||||
@ -448,7 +448,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
'retractilado' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_retractilado')->value,
|
||||
'retractilado5' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_retractilado5')->value,
|
||||
'ferro' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_ferro')->value,
|
||||
'ferro_2' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_ferro_2')->value,
|
||||
'prototipo' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_prototipo')->value,
|
||||
'prototipo_2' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_prototipo_2')->value,
|
||||
'solapas_grandes_cubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_cubierta')->value,
|
||||
'solapas_grandes_sobrecubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_sobrecubierta')->value,
|
||||
'solapas_grandes_faja' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_faja')->value,
|
||||
@ -458,6 +460,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
|
||||
$this->viewData['tipo_impresion_id'] = $presupuestoEntity->tipo_impresion_id; // Cosido tapa blanda JJO
|
||||
|
||||
$this->viewData['cabezadas'] = model('\App\Models\Configuracion\ConfigVariableModel')->getCabezadasDisponibles();
|
||||
|
||||
$this->viewData = array_merge($this->viewData, $this->getStringsFromTipoImpresion($presupuestoEntity->tipo_impresion_id));
|
||||
|
||||
$this->viewData['formAction'] = route_to('updatePresupuestoAdmin', $id);
|
||||
@ -565,7 +569,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
$modelCliente = new ClienteModel();
|
||||
$modelPapelGenerico = new PapelGenericoModel();
|
||||
|
||||
|
||||
$presupuesto = $this->model->find($id);
|
||||
$data = [];
|
||||
if ($presupuesto) {
|
||||
@ -586,6 +589,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
$data['datosGenerales']['coleccion'] = $presupuesto->coleccion;
|
||||
$data['datosGenerales']['numero_edicion'] = $presupuesto->numero_edicion;
|
||||
$data['datosGenerales']['isbn'] = $presupuesto->isbn;
|
||||
$data['datosGenerales']['iskn'] = $presupuesto->iskn;
|
||||
$data['datosGenerales']['pais'] = $presupuesto->pais_id;
|
||||
$data['datosGenerales']['pais_nombre'] = model('App\Models\Configuracion\PaisModel')->find($presupuesto->pais_id)->nombre;
|
||||
$data['datosGenerales']['cliente']['id'] = $presupuesto->cliente_id;
|
||||
@ -630,7 +634,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
$data['datosLibro']['acabadoFaja']['text'] = $modelAcabado->find($presupuesto->acabado_faja_id)->nombre;
|
||||
}
|
||||
$data['datosLibro']['prototipo'] = $presupuesto->prototipo;
|
||||
$data['datosLibro']['prototipo2'] = $this->hasPrototipo2($id);
|
||||
$data['datosLibro']['ferro'] = $presupuesto->ferro;
|
||||
$data['datosLibro']['ferro2'] = $this->hasFerro2($id);
|
||||
$data['datosLibro']['ferroDigital'] = $presupuesto->ferro_digital;
|
||||
$data['datosLibro']['marcapaginas'] = $presupuesto->marcapaginas;
|
||||
$data['datosLibro']['retractilado'] = $presupuesto->retractilado;
|
||||
@ -659,6 +665,21 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
$data['direcciones'] = $this->obtenerDireccionesEnvio($id, $presupuesto->cliente_id);
|
||||
}
|
||||
|
||||
$data['direccionesFP'] = [];
|
||||
$direccionFP1 = $this->obtenerDireccionesEnvio($id, $presupuesto->cliente_id, true, 1);
|
||||
if(count($direccionFP1) > 0){
|
||||
$data['direccionesFP']['fp1'] = $direccionFP1;
|
||||
} else {
|
||||
$data['direccionesFP']['fp1'] = [];
|
||||
}
|
||||
$direccionFP2 = $this->obtenerDireccionesEnvio($id, $presupuesto->cliente_id, true, 2);
|
||||
if(count($direccionFP2) > 0){
|
||||
$data['direccionesFP']['fp2'] = $direccionFP2;
|
||||
} else {
|
||||
$data['direccionesFP']['fp2'] = [];
|
||||
}
|
||||
$data['direccionesFP']['checkboxes'] = json_decode($presupuesto->getDireccionFPChecks());
|
||||
|
||||
$data['comentarios_cliente'] = $presupuesto->comentarios_cliente;
|
||||
$data['comentarios_safekat'] = $presupuesto->comentarios_safekat;
|
||||
$data['comentarios_pdf'] = $presupuesto->comentarios_pdf;
|
||||
@ -1841,6 +1862,18 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
}
|
||||
}
|
||||
|
||||
public function checkLomo()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$tipo_impresion_id = $this->request->getGet('tipo_impresion_id');
|
||||
$lomo = $this->request->getGet('lomo') ?? 0;
|
||||
$response = PresupuestoService::check_lomo_interior($tipo_impresion_id, $lomo);
|
||||
return $this->respond($response);
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function reprintPresupuesto()
|
||||
{
|
||||
|
||||
@ -1939,7 +1972,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
return PresupuestoService::checkLineasEnvios($direccionesEnvio);
|
||||
}
|
||||
|
||||
protected function obtenerDireccionesEnvio($id, $cliente_id)
|
||||
protected function obtenerDireccionesEnvio($id, $cliente_id, $is_fp = false, $num_fp = 0)
|
||||
{
|
||||
$model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
|
||||
$model_direcciones = model('App\Models\Clientes\ClienteDireccionesModel');
|
||||
@ -1947,10 +1980,38 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
|
||||
->join('lg_proveedores', 'presupuesto_direcciones.proveedor_id = lg_proveedores.id')
|
||||
->join('lg_paises', 'presupuesto_direcciones.pais_id = lg_paises.id')
|
||||
->select('presupuesto_direcciones.*, lg_proveedores.nombre AS proveedor, lg_paises.nombre AS pais')
|
||||
->where('presupuesto_id', $id)->findAll();
|
||||
->where('presupuesto_id', $id)
|
||||
->where('is_ferro_prototipo', $is_fp);
|
||||
if ($is_fp) {
|
||||
$direcciones = $direcciones
|
||||
->where('num_ferro_prototipo', $num_fp);
|
||||
}
|
||||
|
||||
return $direcciones;
|
||||
|
||||
return $direcciones->findAll();
|
||||
}
|
||||
|
||||
protected function hasPrototipo2($presupuestoId){
|
||||
|
||||
$servicios = (new PresupuestoServiciosExtraModel())->getResource($presupuestoId)->get()->getResultObject();
|
||||
$id_servicio = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_prototipo_2')->value;
|
||||
foreach ($servicios as $servicio) {
|
||||
if ($servicio->tarifa_extra_id == $id_servicio) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function hasFerro2($presupuestoId)
|
||||
{
|
||||
$servicios = (new PresupuestoServiciosExtraModel())->getResource($presupuestoId)->get()->getResultObject();
|
||||
$id_servicio = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_ferro_2')->value;
|
||||
foreach ($servicios as $servicio) {
|
||||
if ($servicio->tarifa_extra_id == $id_servicio) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -55,6 +55,7 @@ class Presupuestodirecciones extends \App\Controllers\BaseResourceController
|
||||
$proveedor_id = $reqData['proveedor_id'] ?? "";
|
||||
$entregaPieCalle = $reqData['entregaPieCalle'] ?? 0;
|
||||
$is_ferro_prototipo = $reqData['is_ferro_prototipo'] ?? 0;
|
||||
$num_ferro_prototipo = $reqData['num_ferro_prototipo'] ?? 0;
|
||||
|
||||
$data = [
|
||||
"presupuesto_id" => $presupuesto_id,
|
||||
@ -74,7 +75,8 @@ class Presupuestodirecciones extends \App\Controllers\BaseResourceController
|
||||
"proveedor" => $proveedor,
|
||||
"proveedor_id" => $proveedor_id,
|
||||
"entregaPieCalle" => $entregaPieCalle,
|
||||
"is_ferro_prototipo" => $is_ferro_prototipo
|
||||
"is_ferro_prototipo" => $is_ferro_prototipo,
|
||||
"num_ferro_prototipo" => $num_ferro_prototipo
|
||||
];
|
||||
$response = $this->model->insert($data);
|
||||
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Produccion;
|
||||
use App\Controllers\BaseController;
|
||||
|
||||
|
||||
class Ordenmaquina extends BaseController
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo 'Orden maquina';
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -116,6 +116,8 @@ class Ordentrabajo extends BaseController
|
||||
$bodyData = $this->request->getPost();
|
||||
$validated = $this->validation->run($bodyData, "orden_trabajo_tarea");
|
||||
if ($validated) {
|
||||
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
|
||||
$this->produccionService->init($tareaEntity->orden_trabajo_id);
|
||||
$r = $this->produccionService->updateOrdenTrabajoTarea($bodyData["orden_trabajo_tarea_id"], $bodyData);
|
||||
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
|
||||
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $tareaEntity]);
|
||||
@ -167,6 +169,7 @@ class Ordentrabajo extends BaseController
|
||||
if ($validated) {
|
||||
$validatedData = $bodyData;
|
||||
$r = $this->produccionService->emptyOrdenTrabajoDate($validatedData['orden_trabajo_id'], $validatedData['name']);
|
||||
$this->produccionService->init($validatedData['orden_trabajo_id']); // Re-init service to update the state of the OT
|
||||
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "user" => auth()->user(), "data" => $bodyData]);
|
||||
} else {
|
||||
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
|
||||
@ -230,6 +233,10 @@ class Ordentrabajo extends BaseController
|
||||
return view(static::$viewPath . $this->editRoute, $this->viewData);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTable for Ordenes de Trabajo Finalizadas
|
||||
* @return \CodeIgniter\HTTP\ResponseInterface
|
||||
*/
|
||||
public function datatable()
|
||||
{
|
||||
$logo = config(LogoImpresion::class);
|
||||
@ -250,8 +257,11 @@ class Ordentrabajo extends BaseController
|
||||
{
|
||||
$logo = config(LogoImpresion::class);
|
||||
|
||||
$q = $this->otModel->getDatatableQuery()->whereIn("ordenes_trabajo.estado", ["I", "PM"])->where('ordenes_trabajo.preimpresion_revisada', true);
|
||||
// return $this->response->setJSON($q->get()->getResultArray());
|
||||
$q = $this->otModel->getDatatableQuery()
|
||||
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
|
||||
->where('ordenes_trabajo.preimpresion_revisada', true)
|
||||
->where('ordenes_trabajo.is_pedido_espera', false)
|
||||
->where('ordenes_trabajo.progreso <=', 0);
|
||||
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(
|
||||
@ -298,7 +308,10 @@ class Ordentrabajo extends BaseController
|
||||
{
|
||||
$logo = config(LogoImpresion::class);
|
||||
|
||||
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.preimpresion_revisada', false);
|
||||
$q = $this->otModel->getDatatableQuery()
|
||||
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
|
||||
->where('ordenes_trabajo.preimpresion_revisada', false)
|
||||
->where('ordenes_trabajo.is_pedido_espera', 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(
|
||||
@ -313,7 +326,12 @@ class Ordentrabajo extends BaseController
|
||||
{
|
||||
$logo = config(LogoImpresion::class);
|
||||
|
||||
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.preimpresion_revisada', true)->where('pedidos.estado', 'produccion');
|
||||
$q = $this->otModel->getDatatableQuery()
|
||||
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
|
||||
->where('ordenes_trabajo.preimpresion_revisada', true)
|
||||
->where('ordenes_trabajo.is_pedido_espera', false)
|
||||
->where('ordenes_trabajo.progreso >', 0)
|
||||
->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(
|
||||
@ -328,7 +346,9 @@ class Ordentrabajo extends BaseController
|
||||
{
|
||||
$logo = config(LogoImpresion::class);
|
||||
|
||||
$q = $this->otModel->getDatatableQuery()->where('ordenes_trabajo.is_pedido_espera', 1);
|
||||
$q = $this->otModel->getDatatableQuery()
|
||||
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
|
||||
->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(
|
||||
@ -388,6 +408,7 @@ class Ordentrabajo extends BaseController
|
||||
public function reset_tareas(int $orden_trabajo_id)
|
||||
{
|
||||
$r = $this->produccionService->init($orden_trabajo_id)->resetAllTareas();
|
||||
$this->produccionService->init($orden_trabajo_id); // Re-init service to update the state of the OT
|
||||
return $this->response->setJSON(["message" => "Tareas reseteadas", "status" => $r]);
|
||||
}
|
||||
public function delete_tarea(int $orden_trabajo_tarea_id)
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Produccion;
|
||||
use App\Controllers\BaseController;
|
||||
|
||||
|
||||
class Ordentrabajomaquetacion extends BaseController
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo 'Orden maquetación';
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\Produccion;
|
||||
use App\Controllers\BaseController;
|
||||
|
||||
|
||||
class Pedidoproduccion extends BaseController
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo 'Pedido produccion';
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
534
ci4/app/Controllers/Sistema/Backups.php
Normal file
534
ci4/app/Controllers/Sistema/Backups.php
Normal file
@ -0,0 +1,534 @@
|
||||
<?php
|
||||
namespace App\Controllers\Sistema;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\Sistema\BackupModel;
|
||||
use phpseclib3\Net\SFTP;
|
||||
use ZipArchive;
|
||||
|
||||
class Backups extends BaseController
|
||||
{
|
||||
protected $backupModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->backupModel = new BackupModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
helper('filesystem');
|
||||
|
||||
$entorno = getenv('SK_ENVIRONMENT');
|
||||
$backups = [];
|
||||
|
||||
if ($entorno === 'development') {
|
||||
// Leer archivos directamente del disco en entorno de desarrollo
|
||||
$backups = [];
|
||||
|
||||
// === 1. Backups locales ===
|
||||
$localDir = WRITEPATH . 'backups/';
|
||||
$localFiles = get_filenames($localDir);
|
||||
|
||||
foreach ($localFiles as $file) {
|
||||
if (!str_ends_with($file, '.zip') || !str_starts_with($file, 'backup_dev_')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$localPath = $localDir . $file;
|
||||
|
||||
$fecha = date('Y-m-d H:i', filemtime($localPath));
|
||||
$tamano = filesize($localPath);
|
||||
$tamanoFmt = $tamano > 1048576
|
||||
? number_format($tamano / 1048576, 2) . ' MB'
|
||||
: number_format($tamano / 1024, 2) . ' KB';
|
||||
|
||||
$backups[$file] = [
|
||||
'id' => null,
|
||||
'filename' => $file,
|
||||
'fecha' => $fecha,
|
||||
'tamano' => $tamanoFmt,
|
||||
'local' => true,
|
||||
'remoto' => false,
|
||||
];
|
||||
}
|
||||
|
||||
// === 2. Backups remotos en SFTP ===
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
$remoteDir = getenv('HIDRIVE_BK_PATH_ROOT');
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
if ($sftp->login($sftpUser, $sftpPass)) {
|
||||
$remoteFiles = $sftp->nlist($remoteDir);
|
||||
|
||||
foreach ($remoteFiles as $file) {
|
||||
if (!str_ends_with($file, '.zip') || !str_starts_with($file, 'backup_')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Verificar si ya se cargó como local
|
||||
$alreadyLocal = isset($backups[$file]);
|
||||
|
||||
// Obtener info de archivo remoto
|
||||
$stat = $sftp->stat($remoteDir . $file);
|
||||
$fecha = isset($stat['mtime']) ? date('Y-m-d H:i', $stat['mtime']) : '-';
|
||||
$tamano = $stat['size'] ?? null;
|
||||
$tamanoFmt = $tamano > 1048576
|
||||
? number_format($tamano / 1048576, 2) . ' MB'
|
||||
: number_format($tamano / 1024, 2) . ' KB';
|
||||
|
||||
$backups[$file] = [
|
||||
'id' => null,
|
||||
'filename' => $file,
|
||||
'fecha' => $fecha,
|
||||
'tamano' => $tamanoFmt,
|
||||
'local' => $alreadyLocal,
|
||||
'remoto' => true,
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// Opcional: mostrar un error o dejarlo pasar silenciosamente
|
||||
session()->setFlashdata('warning', 'No se pudo conectar al servidor SFTP para obtener backups remotos.');
|
||||
}
|
||||
|
||||
// Convertir a lista (por si se usó índice por filename)
|
||||
$backups = array_values($backups);
|
||||
|
||||
} else {
|
||||
// En producción: seguir usando la base de datos
|
||||
$entries = $this->backupModel->orderBy('created_at', 'DESC')->findAll();
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$file = $entry['filename'];
|
||||
|
||||
if (!str_ends_with($file, '.zip')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$localPath = $entry['path_local'];
|
||||
$remotePath = $entry['path_remote'];
|
||||
|
||||
$isLocal = $localPath && file_exists($localPath);
|
||||
$isRemote = !empty($remotePath);
|
||||
|
||||
if ($isLocal) {
|
||||
$fecha = date('Y-m-d H:i', filemtime($localPath));
|
||||
$tamano = filesize($localPath);
|
||||
$tamanoFmt = $tamano > 1048576
|
||||
? number_format($tamano / 1048576, 2) . ' MB'
|
||||
: number_format($tamano / 1024, 2) . ' KB';
|
||||
|
||||
if ($entry['size'] != $tamano) {
|
||||
$this->backupModel->update($entry['id'], [
|
||||
'size' => $tamano,
|
||||
]);
|
||||
}
|
||||
|
||||
} else {
|
||||
$fecha = $entry['created_at'] ?? '-';
|
||||
$tamano = $entry['size'] ?? null;
|
||||
$tamanoFmt = $tamano > 1048576
|
||||
? number_format($tamano / 1048576, 2) . ' MB'
|
||||
: number_format($tamano / 1024, 2) . ' KB';
|
||||
}
|
||||
|
||||
$backups[] = [
|
||||
'id' => $entry['id'],
|
||||
'filename' => $file,
|
||||
'fecha' => $fecha,
|
||||
'tamano' => $tamanoFmt,
|
||||
'local' => $isLocal,
|
||||
'remoto' => $isRemote,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return view('themes/vuexy/form/backups/backupList', ['backups' => $backups]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
if (getenv('SK_ENVIRONMENT') !== 'production') {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No permitido en entorno de desarrollo.');
|
||||
}
|
||||
|
||||
helper('filesystem');
|
||||
|
||||
$timestamp = date('Ymd_His');
|
||||
$sqlFilename = "backup_{$timestamp}.sql";
|
||||
$zipFilename = "backup_{$timestamp}.zip";
|
||||
$sqlPath = WRITEPATH . 'backups/' . $sqlFilename;
|
||||
$zipPath = WRITEPATH . 'backups/' . $zipFilename;
|
||||
|
||||
$dbConfig = config('Database')->default;
|
||||
$host = $dbConfig['hostname'];
|
||||
$username = $dbConfig['username'];
|
||||
$password = $dbConfig['password'];
|
||||
$database = $dbConfig['database'];
|
||||
|
||||
$command = "mysqldump -h {$host} -u" . escapeshellarg($username) . " -p'" . addslashes($password) . "' {$database} > {$sqlPath}";
|
||||
|
||||
system($command, $retval);
|
||||
|
||||
if ($retval !== 0) {
|
||||
throw new \RuntimeException("Error al crear el backup.");
|
||||
}
|
||||
|
||||
// Crear el zip
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
|
||||
$zip->addFile($sqlPath, $sqlFilename);
|
||||
$zip->close();
|
||||
unlink($sqlPath); // eliminar el .sql original
|
||||
} else {
|
||||
throw new \RuntimeException("Error al comprimir el backup.");
|
||||
}
|
||||
|
||||
// Insertar en BD
|
||||
$backupId = $this->backupModel->insert([
|
||||
'filename' => $zipFilename,
|
||||
'type' => 'manual',
|
||||
'path_local' => $zipPath,
|
||||
'path_remote' => null,
|
||||
'size' => filesize($zipPath),
|
||||
'status' => 'pendiente',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
], true);
|
||||
|
||||
// Enviar a SFTP
|
||||
$this->sendToSFTP($zipPath, $zipFilename);
|
||||
|
||||
// Actualizar BD
|
||||
$remotePath = "/users/erp2019/backups_erp/" . $zipFilename;
|
||||
$this->backupModel->update($backupId, [
|
||||
'path_remote' => $remotePath,
|
||||
'status' => 'subido'
|
||||
]);
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('message', 'Backup del entorno de produccion creado, comprimido y enviado al remoto.');
|
||||
}
|
||||
|
||||
public function createDevelopment()
|
||||
{
|
||||
if (getenv('SK_ENVIRONMENT') !== 'development') {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Esta acción solo está permitida en desarrollo.');
|
||||
}
|
||||
|
||||
helper('filesystem');
|
||||
|
||||
$timestamp = date('Ymd_His');
|
||||
$sqlFilename = "backup_dev_{$timestamp}.sql";
|
||||
$zipFilename = "backup_dev_{$timestamp}.zip";
|
||||
$sqlPath = WRITEPATH . 'backups/' . $sqlFilename;
|
||||
$zipPath = WRITEPATH . 'backups/' . $zipFilename;
|
||||
|
||||
$dbConfig = config('Database')->default;
|
||||
$host = $dbConfig['hostname'];
|
||||
$username = $dbConfig['username'];
|
||||
$password = $dbConfig['password'];
|
||||
$database = $dbConfig['database'];
|
||||
|
||||
$command = "mysqldump -h {$host} -u{$username} -p'{$password}' {$database} > {$sqlPath}";
|
||||
system($command, $retval);
|
||||
|
||||
if ($retval !== 0) {
|
||||
throw new \RuntimeException("Error al crear el backup local.");
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($zipPath, \ZipArchive::CREATE) === TRUE) {
|
||||
$zip->addFile($sqlPath, $sqlFilename);
|
||||
$zip->close();
|
||||
unlink($sqlPath);
|
||||
} else {
|
||||
throw new \RuntimeException("Error al comprimir el backup local.");
|
||||
}
|
||||
|
||||
// Ya no insertamos en la base de datos; el archivo queda en disco y se listará dinámicamente
|
||||
return redirect()->to(route_to('backupsList'))->with('message', 'Backup local del entorno de desarrollo creado.');
|
||||
}
|
||||
|
||||
|
||||
public function download($filename)
|
||||
{
|
||||
helper('filesystem');
|
||||
|
||||
$entorno = getenv('SK_ENVIRONMENT');
|
||||
|
||||
$backup = $this->backupModel->where('filename', $filename)->first();
|
||||
|
||||
// 1. Si hay entrada en la base de datos
|
||||
if ($backup) {
|
||||
$localPath = $backup['path_local'];
|
||||
$remotePath = $backup['path_remote'];
|
||||
|
||||
if ($localPath && file_exists($localPath)) {
|
||||
return $this->response->download($localPath, null)->setFileName($filename);
|
||||
}
|
||||
|
||||
if (!empty($remotePath)) {
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
|
||||
if (!$sftp->login($sftpUser, $sftpPass)) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo conectar al servidor SFTP.');
|
||||
}
|
||||
|
||||
$fileContents = $sftp->get($remotePath);
|
||||
if ($fileContents === false) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Error al descargar desde SFTP.');
|
||||
}
|
||||
|
||||
$newLocalPath = WRITEPATH . 'backups/' . $filename;
|
||||
write_file($newLocalPath, $fileContents);
|
||||
|
||||
// Omitimos update() si estamos en desarrollo sin base de datos
|
||||
if ($entorno === 'production') {
|
||||
$this->backupModel->update($backup['id'], ['path_local' => $newLocalPath]);
|
||||
}
|
||||
|
||||
return $this->response->download($newLocalPath, null)->setFileName($filename);
|
||||
}
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo encontrar el archivo ni local ni remoto.');
|
||||
}
|
||||
|
||||
// 2. Si NO hay entrada en la BD y estamos en desarrollo
|
||||
if ($entorno === 'development') {
|
||||
$localPath = WRITEPATH . 'backups/' . $filename;
|
||||
|
||||
if (file_exists($localPath)) {
|
||||
return $this->response->download($localPath, null)->setFileName($filename);
|
||||
}
|
||||
|
||||
// También se puede intentar buscar en el SFTP si quieres
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
$remotePath = getenv('HIDRIVE_BK_PATH_ROOT') . $filename;
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
if ($sftp->login($sftpUser, $sftpPass)) {
|
||||
$fileContents = $sftp->get($remotePath);
|
||||
if ($fileContents !== false) {
|
||||
$newLocalPath = WRITEPATH . 'backups/' . $filename;
|
||||
write_file($newLocalPath, $fileContents);
|
||||
return $this->response->download($newLocalPath, null)->setFileName($filename);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Archivo no encontrado local ni remoto (sin base de datos).');
|
||||
}
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Backup no encontrado.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function deleteLocal($id)
|
||||
{
|
||||
$entorno = getenv('SK_ENVIRONMENT');
|
||||
$backup = $this->backupModel->find($id);
|
||||
|
||||
if (!$backup) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Backup no encontrado en la base de datos.');
|
||||
}
|
||||
|
||||
$localPath = $backup['path_local'];
|
||||
|
||||
// Si existe el archivo, intentamos borrarlo
|
||||
if ($localPath && file_exists($localPath)) {
|
||||
unlink($localPath);
|
||||
}
|
||||
|
||||
if ($entorno === 'production') {
|
||||
// Solo desvincular el archivo local
|
||||
$this->backupModel->update($id, ['path_local' => null]);
|
||||
return redirect()->to(route_to('backupsList'))->with('message', 'Archivo local eliminado (registro conservado).');
|
||||
} else {
|
||||
// Eliminar completamente en desarrollo
|
||||
$this->backupModel->delete($id);
|
||||
return redirect()->to(route_to('backupsList'))->with('message', 'Backup de desarrollo eliminado completamente.');
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteLocalDevelopment($filename)
|
||||
{
|
||||
$entorno = getenv('SK_ENVIRONMENT');
|
||||
if ($entorno !== 'development') {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Solo permitido en desarrollo.');
|
||||
}
|
||||
|
||||
$path = WRITEPATH . 'backups/' . $filename;
|
||||
|
||||
if (file_exists($path)) {
|
||||
unlink($path);
|
||||
return redirect()->to(route_to('backupsList'))->with('message', "Archivo '$filename' eliminado del sistema de archivos.");
|
||||
}
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('error', "Archivo '$filename' no encontrado en el sistema.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function restoreLocal($file)
|
||||
{
|
||||
$path = WRITEPATH . 'backups/' . $file;
|
||||
|
||||
if (!file_exists($path)) {
|
||||
throw new \CodeIgniter\Exceptions\PageNotFoundException("Backup no encontrado.");
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($path) === TRUE) {
|
||||
$extractPath = WRITEPATH . 'backups/tmp_restore/';
|
||||
if (!is_dir($extractPath)) {
|
||||
mkdir($extractPath, 0775, true);
|
||||
}
|
||||
$zip->extractTo($extractPath);
|
||||
$zip->close();
|
||||
|
||||
$sqlFiles = glob($extractPath . '*.sql');
|
||||
if (count($sqlFiles) === 0) {
|
||||
throw new \RuntimeException("No se encontró ningún archivo .sql en el ZIP");
|
||||
}
|
||||
|
||||
$sqlFile = $sqlFiles[0];
|
||||
|
||||
// === Verificar que el archivo SQL existe y tiene contenido
|
||||
if (!file_exists($sqlFile)) {
|
||||
throw new \RuntimeException("Archivo SQL no encontrado.");
|
||||
}
|
||||
|
||||
if (filesize($sqlFile) === 0) {
|
||||
throw new \RuntimeException("El archivo SQL está vacío.");
|
||||
}
|
||||
|
||||
// === Configuración de base de datos
|
||||
$dbConfig = config('Database')->default;
|
||||
$host = escapeshellarg($dbConfig['hostname']);
|
||||
$username = escapeshellarg($dbConfig['username']);
|
||||
$password = escapeshellarg($dbConfig['password']);
|
||||
$database = escapeshellarg($dbConfig['database']);
|
||||
|
||||
// === Construcción del comando con stderr redirigido
|
||||
$cmd = "mysql -h $host -u $username -p$password $database -e \"source $sqlFile\" 2>&1";
|
||||
|
||||
// === Ejecutar y capturar la salida
|
||||
exec($cmd, $output, $retval);
|
||||
|
||||
// === Verificar resultado
|
||||
if ($retval !== 0) {
|
||||
throw new \RuntimeException("Error al restaurar la base de datos:\n" . implode("\n", $output));
|
||||
}
|
||||
|
||||
// === Limpieza
|
||||
helper('filesystem');
|
||||
delete_files($extractPath, true); // elimina contenido
|
||||
rmdir($extractPath); // elimina el directorio
|
||||
|
||||
return redirect()->to(route_to('backupsList'))->with('message', 'Backup restaurado correctamente (vía sistema).');
|
||||
} else {
|
||||
throw new \RuntimeException("No se pudo abrir el archivo ZIP");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function restoreRemote($filename)
|
||||
{
|
||||
helper('filesystem');
|
||||
|
||||
$entorno = getenv('SK_ENVIRONMENT');
|
||||
|
||||
if ($entorno === 'development') {
|
||||
// Construir ruta remota directamente
|
||||
$remotePath = '/users/erp2019/backups_erp/' . $filename;
|
||||
$localPath = WRITEPATH . 'backups/' . $filename;
|
||||
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
if (!$sftp->login($sftpUser, $sftpPass)) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.');
|
||||
}
|
||||
|
||||
$fileContents = $sftp->get($remotePath);
|
||||
if ($fileContents === false) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.');
|
||||
}
|
||||
|
||||
if (write_file($localPath, $fileContents) === false) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.');
|
||||
}
|
||||
|
||||
// Restaurar directamente
|
||||
return $this->restoreLocal($filename);
|
||||
}
|
||||
|
||||
// Producción: flujo normal con base de datos
|
||||
$backup = $this->backupModel->where('filename', $filename)->first();
|
||||
|
||||
if (!$backup || empty($backup['path_remote'])) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'Backup remoto no encontrado en la base de datos.');
|
||||
}
|
||||
|
||||
$remotePath = $backup['path_remote'];
|
||||
$localPath = WRITEPATH . 'backups/' . $filename;
|
||||
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
if (!$sftp->login($sftpUser, $sftpPass)) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.');
|
||||
}
|
||||
|
||||
$fileContents = $sftp->get($remotePath);
|
||||
if ($fileContents === false) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.');
|
||||
}
|
||||
|
||||
if (write_file($localPath, $fileContents) === false) {
|
||||
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.');
|
||||
}
|
||||
|
||||
$this->backupModel->update($backup['id'], ['path_local' => $localPath]);
|
||||
|
||||
return $this->restoreLocal($filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private function sendToSFTP($localPath, $remoteFilename)
|
||||
{
|
||||
$sftpHost = getenv('HIDRIVE_BK_HOST');
|
||||
$sftpUser = getenv('HIDRIVE_BK_USER');
|
||||
$sftpPass = getenv('HIDRIVE_BK_PASS');
|
||||
$remotePath = getenv('HIDRIVE_BK_PATH_ROOT') . $remoteFilename;
|
||||
|
||||
$sftp = new SFTP($sftpHost);
|
||||
|
||||
if (!$sftp->login($sftpUser, $sftpPass)) {
|
||||
throw new \RuntimeException('Error de autenticación SFTP');
|
||||
}
|
||||
|
||||
$fileContents = file_get_contents($localPath);
|
||||
|
||||
if (!$sftp->put($remotePath, $fileContents)) {
|
||||
throw new \RuntimeException("No se pudo subir el backup al servidor SFTP.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Controllers\Sistema;
|
||||
|
||||
use CodeIgniter\Controller;
|
||||
use App\Models\Presupuestos\PresupuestoFicheroModel;
|
||||
|
||||
class Intranet extends Controller
|
||||
{
|
||||
@ -11,25 +12,24 @@ class Intranet extends Controller
|
||||
{
|
||||
helper('file');
|
||||
|
||||
$resource_path = WRITEPATH . 'uploads/presupuestos/' . $resource_name;
|
||||
$model = new PresupuestoFicheroModel();
|
||||
$file = $model->where('file_path LIKE', "%{$resource_name}")->first();
|
||||
|
||||
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();
|
||||
if (!$file) {
|
||||
return service('response')->setStatusCode(404)->setBody("Archivo no encontrado");
|
||||
}
|
||||
|
||||
$resource_path = WRITEPATH . $file->file_path;
|
||||
|
||||
if (file_exists($resource_path)) {
|
||||
$mime_type = mime_content_type($resource_path);
|
||||
$response = service('response');
|
||||
$response->setContentType($mime_type);
|
||||
$response->setBody(file_get_contents($resource_path));
|
||||
$response->send();
|
||||
} else {
|
||||
return service('response')->setStatusCode(404)->setBody("Archivo no encontrado");
|
||||
}
|
||||
}
|
||||
|
||||
function tickets($resource_name)
|
||||
@ -54,7 +54,6 @@ class Intranet extends Controller
|
||||
// Send the response to the browser
|
||||
$response->send();
|
||||
}
|
||||
|
||||
}
|
||||
function orden_trabajo($ot_id, $resource_name)
|
||||
{
|
||||
@ -76,7 +75,6 @@ class Intranet extends Controller
|
||||
// Send the response to the browser
|
||||
$response->send();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function catalogo($catalogo_id, $resource_name)
|
||||
@ -99,7 +97,5 @@ class Intranet extends Controller
|
||||
// Send the response to the browser
|
||||
$response->send();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ class ServiciosAcabado extends BaseResourceController
|
||||
|
||||
protected $indexRoute = 'serviciosAcabadoList';
|
||||
|
||||
protected $deletePermission = 'tarifa-acabado.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
@ -80,7 +82,7 @@ class ServiciosAcabado extends BaseResourceController
|
||||
$sanitizedData['user_updated_id'] = auth()->user()->id;
|
||||
|
||||
if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) {
|
||||
$sanitizedData['mostrar_en_presupuesto'] = false;
|
||||
$sanitizedData['mostrar_en_presupuesto_cliente'] = false;
|
||||
}
|
||||
|
||||
if ($this->request->getPost('acabado_cubierta') == null) {
|
||||
@ -174,7 +176,7 @@ class ServiciosAcabado extends BaseResourceController
|
||||
$sanitizedData['user_updated_id'] = auth()->user()->id;
|
||||
|
||||
if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) {
|
||||
$sanitizedData['mostrar_en_presupuesto'] = false;
|
||||
$sanitizedData['mostrar_en_presupuesto_cliente'] = false;
|
||||
}
|
||||
|
||||
if ($this->request->getPost('acabado_cubierta') == null) {
|
||||
|
||||
@ -28,6 +28,8 @@ class TarifaAcabados extends BaseResourceController
|
||||
|
||||
protected $indexRoute = 'tarifaAcabadoList';
|
||||
|
||||
protected $deletePermission = 'tarifa-acabado.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -19,6 +19,8 @@ class Tarifaextra extends \App\Controllers\GoBaseController
|
||||
|
||||
protected $indexRoute = 'tarifaextraList';
|
||||
|
||||
protected $deletePermission = 'tarifa-extra.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -19,6 +19,8 @@ class Tarifapreimpresion extends \App\Controllers\GoBaseController
|
||||
|
||||
protected $indexRoute = 'tarifapreimpresionList';
|
||||
|
||||
protected $deletePermission = 'tarifa-preimpresion.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -32,6 +32,8 @@ class Tarifasencuadernacion extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'tarifaEncuadernacionList';
|
||||
|
||||
protected $deletePermission = 'tarifa-encuadernacion.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -28,6 +28,8 @@ class Tarifasmanipulado extends \App\Controllers\BaseResourceController
|
||||
|
||||
protected $indexRoute = 'tarifaManipuladoList';
|
||||
|
||||
protected $deletePermission = 'tarifa-manipulado.delete';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
|
||||
@ -15,25 +15,24 @@ use App\Models\Catalogo\CatalogoLibroModel;
|
||||
use App\Services\PresupuestoService;
|
||||
use CodeIgniter\Shield\Entities\User;
|
||||
|
||||
use App\Libraries\SftpClientWrapper;
|
||||
use Config\PresupuestoSFTP;
|
||||
|
||||
|
||||
class Test extends BaseController
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
}
|
||||
function __construct() {}
|
||||
|
||||
public function echo()
|
||||
{
|
||||
|
||||
echo "echo";
|
||||
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -75,10 +74,8 @@ class Test extends BaseController
|
||||
|
||||
// Insert it
|
||||
$tel_model->insert($tarifasLinea);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -224,7 +221,6 @@ class Test extends BaseController
|
||||
} else {
|
||||
$values = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateBackupsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true
|
||||
],
|
||||
'filename' => ['type' => 'VARCHAR', 'constraint' => 255],
|
||||
'type' => ['type' => 'ENUM', 'constraint' => ['manual', 'cron']],
|
||||
'path_local' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
|
||||
'path_remote' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
|
||||
'size' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
|
||||
'status' => ['type' => 'ENUM', 'constraint' => ['pendiente', 'subido', 'error'], 'default' => 'pendiente'],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => false],
|
||||
'updated_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->createTable('backups');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable('backups');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateRestoresTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
|
||||
'backup_id' => ['type' => 'INT', 'unsigned' => true],
|
||||
'restored_by' => ['type' => 'VARCHAR', 'constraint' => 100],
|
||||
'source' => ['type' => 'ENUM', 'constraint' => ['local', 'remote']],
|
||||
'restored_at' => ['type' => 'DATETIME'],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addForeignKey('backup_id', 'backups', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->forge->createTable('backup_restores');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable('backup_restores');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class LomoMaximoLibros extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Renombrar campo
|
||||
$this->db->table('config_variables_app')
|
||||
->where('name', 'lomo_maximo')
|
||||
->set('name', 'lomo_maximo_fresado_cosido')
|
||||
->update();
|
||||
|
||||
// Insertar nuevo campo: lomo_maximo_espiral
|
||||
$this->db->table('config_variables_app')->insert([
|
||||
'name' => 'lomo_maximo_espiral',
|
||||
'value' => '45',
|
||||
'description' => 'Tamaño máximo (mm) para el lomo de los libros espiral',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
// Insertar nuevo campo: lomo_maximo_wireo
|
||||
$this->db->table('config_variables_app')->insert([
|
||||
'name' => 'lomo_maximo_wireo',
|
||||
'value' => '26',
|
||||
'description' => 'Tamaño máximo (mm) para el lomo de los libros wire-O',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Revertir nombre
|
||||
$this->db->table('config_variables_app')
|
||||
->where('name', 'lomo_maximo_fresado_cosido')
|
||||
->set('name', 'lomo_maximo')
|
||||
->update();
|
||||
|
||||
// Borrar los nuevos campos
|
||||
$this->db->table('config_variables_app')->whereIn('name', [
|
||||
'lomo_maximo_espiral',
|
||||
'lomo_maximo_wireo'
|
||||
])->delete();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class DireccionesFerroPrototipo extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Insertar nuevo campo: lomo_maximo_espiral
|
||||
$this->forge->addColumn('presupuesto_direcciones', [
|
||||
'num_ferro_prototipo' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 3,
|
||||
'null' => false,
|
||||
'default' => '0',
|
||||
'description' => 'numero de ferro/prototipo',
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->db->table('presupuesto_direcciones')->whereIn('name', [
|
||||
'num_ferro_prototipo',
|
||||
'lomo_maximo_wireo'
|
||||
])->delete();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class ConfigDireccionesFerroPrototipo extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addColumn('presupuestos', [
|
||||
'direcciones_fp_checks' => [
|
||||
'type' => 'JSON',
|
||||
'null' => false,
|
||||
'default' => '{"addFP1isAddMain": "0", "addFP2isAddMain": "0", "addFP2isaddFP1": "0"}',
|
||||
'comment' => 'valores de los checks de las direcciones ferro/prototipo',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropColumn('presupuestos', 'direcciones_fp_checks');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddCatalogoIdToPresupuestos extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Añadir columna
|
||||
$this->forge->addColumn('presupuestos', [
|
||||
'catalogo_id' => [
|
||||
'type' => 'INT',
|
||||
'constraint' => 10,
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'tipologia_id'
|
||||
],
|
||||
]);
|
||||
|
||||
// Agregar clave foránea
|
||||
$this->db->query('
|
||||
ALTER TABLE presupuestos
|
||||
ADD CONSTRAINT FK_presupuestos_catalogo_libros
|
||||
FOREIGN KEY (catalogo_id) REFERENCES catalogo_libros(id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Eliminar la clave foránea primero
|
||||
$this->db->query('
|
||||
ALTER TABLE presupuestos
|
||||
DROP FOREIGN KEY FK_presupuestos_catalogo_libros
|
||||
');
|
||||
|
||||
// Eliminar columna
|
||||
$this->forge->dropColumn('presupuestos', 'catalogo_id');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AumentoLomoFijo extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->db->table('config_variables_app')->insert([
|
||||
'name' => 'aumento_fijo_lomo_interior',
|
||||
'value' => '1.3',
|
||||
'description' => 'Aumento fijo del lomo interior por cola (se añade en el interior)',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Borrar los nuevos campos
|
||||
$this->db->table('config_variables_app')->whereIn('name', [
|
||||
'aumento_fijo_lomo_interior'
|
||||
])->delete();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class FerroPrototipo2 extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->db->table('config_variables_app')->insert([
|
||||
'name' => 'id_servicio_ferro_2',
|
||||
'value' => '31',
|
||||
'description' => 'D del servicio extra "ferro (2 unidades)" que aparece en los presupuestos',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
$this->db->table('config_variables_app')->insert([
|
||||
'name' => 'id_servicio_prototipo_2',
|
||||
'value' => '28',
|
||||
'description' => 'D del servicio extra "Prototipo (2 unidades)" que aparece en los presupuestos',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Borrar los nuevos campos
|
||||
$this->db->table('config_variables_app')->whereIn('name', [
|
||||
'id_servicio_ferro_2',
|
||||
'id_servicio_prototipo_2'
|
||||
])->delete();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateTiposPapelGenerico extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Crear tabla tipos_papel_generico
|
||||
$this->forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'clave' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => '50',
|
||||
'unique' => true,
|
||||
],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->createTable('tipos_papel_generico');
|
||||
|
||||
// Insertar claves
|
||||
$data = [
|
||||
['clave' => 'offset_blanco'],
|
||||
['clave' => 'offset_ahuesado'],
|
||||
['clave' => 'estucados'],
|
||||
['clave' => 'volumen'],
|
||||
['clave' => 'especiales'],
|
||||
['clave' => 'reciclados'],
|
||||
['clave' => 'cartulinas'],
|
||||
['clave' => 'verjurados'],
|
||||
];
|
||||
$this->db->table('tipos_papel_generico')->insertBatch($data);
|
||||
|
||||
// Añadir columna tipo_papel_generico_id a lg_papel_generico
|
||||
$this->forge->addColumn('lg_papel_generico', [
|
||||
'tipo_papel_generico_id' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'id', // Ajusta si deseas colocarla en otro lugar
|
||||
]
|
||||
]);
|
||||
|
||||
// Agregar constraint foreign key
|
||||
$this->db->query(
|
||||
'ALTER TABLE lg_papel_generico
|
||||
ADD CONSTRAINT fk_tipo_papel_generico
|
||||
FOREIGN KEY (tipo_papel_generico_id)
|
||||
REFERENCES tipos_papel_generico(id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE'
|
||||
);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Eliminar foreign key primero
|
||||
$this->db->query('ALTER TABLE lg_papel_generico DROP FOREIGN KEY fk_tipo_papel_generico');
|
||||
$this->forge->dropColumn('lg_papel_generico', 'tipo_papel_generico_id');
|
||||
$this->forge->dropTable('tipos_papel_generico');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddIsknToPresupuestos extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->forge->addColumn('presupuestos', [
|
||||
'iskn' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 64,
|
||||
'null' => true,
|
||||
'default' => null,
|
||||
'after' => 'coleccion', // o cualquier campo existente tras el cual quieras insertarlo
|
||||
'collation' => 'utf8_unicode_ci',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropColumn('presupuestos', 'iskn');
|
||||
}
|
||||
}
|
||||
@ -16,11 +16,13 @@ class PapelGenerico extends \CodeIgniter\Entity\Entity
|
||||
"activo" => false,
|
||||
"created_at" => null,
|
||||
"updated_at" => null,
|
||||
"tipo_papel_generico_id" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"show_in_client" => "boolean",
|
||||
"activo" => "boolean",
|
||||
"show_in_client_special" => "boolean",
|
||||
"is_deleted" => "int",
|
||||
"tipo_papel_generico_id" => "int",
|
||||
];
|
||||
}
|
||||
|
||||
11
ci4/app/Entities/Configuracion/TipoPapelGenerico.php
Executable file
11
ci4/app/Entities/Configuracion/TipoPapelGenerico.php
Executable file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace App\Entities\Configuracion;
|
||||
|
||||
use CodeIgniter\Entity;
|
||||
|
||||
class TipoPapelGenerico extends \CodeIgniter\Entity\Entity
|
||||
{
|
||||
protected $attributes = [
|
||||
"clave" => null,
|
||||
];
|
||||
}
|
||||
@ -26,6 +26,7 @@ class PresupuestoDireccionesEntity extends \CodeIgniter\Entity\Entity
|
||||
"margen" => null,
|
||||
"entregaPieCalle" => null,
|
||||
"is_ferro_prototipo" => null,
|
||||
"num_ferro_prototipo" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"presupuesto_id" => "int",
|
||||
@ -40,6 +41,7 @@ class PresupuestoDireccionesEntity extends \CodeIgniter\Entity\Entity
|
||||
"proveedor_id" => "int",
|
||||
"entregaPieCalle" => "int",
|
||||
"is_ferro_prototipo" => "int",
|
||||
"num_ferro_prototipo" => "int",
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
"user_update_id" => null,
|
||||
"tipo_impresion_id" => null,
|
||||
"tipologia_id" => null,
|
||||
"catalogo_id" => null,
|
||||
"pais_id" => 1,
|
||||
"estado_id" => 1,
|
||||
"inc_rei" => null,
|
||||
@ -46,6 +47,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
"titulo" => "",
|
||||
"autor" => null,
|
||||
"coleccion" => null,
|
||||
"iskn" => null,
|
||||
"numero_edicion" => null,
|
||||
"isbn" => null,
|
||||
"referencia_cliente" => null,
|
||||
@ -116,6 +118,12 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
'lomo_redondo' => null,
|
||||
'cabezada' => null,
|
||||
'envio_base' => null,
|
||||
'direcciones_fp_checks' => [
|
||||
'addFP1isAddMain' => "false",
|
||||
'addFP2isAddMain' => "false",
|
||||
'addFP2isaddFP1' => "false"
|
||||
],
|
||||
|
||||
];
|
||||
protected $casts = [
|
||||
"cliente_id" => "int",
|
||||
@ -123,6 +131,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
"user_update_id" => "?int",
|
||||
"tipo_impresion_id" => "?int",
|
||||
"tipologia_id" => "?int",
|
||||
"catalogo_id" => "?int",
|
||||
"pais_id" => "int",
|
||||
"estado_id" => "int",
|
||||
"retractilado" => "boolean",
|
||||
@ -188,6 +197,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
'papel_interior_diferente' => "boolean",
|
||||
'paginasCuadernillo' => "int",
|
||||
'lomo_redondo' => "boolean",
|
||||
'direcciones_fp_checks' => 'json',
|
||||
];
|
||||
/**
|
||||
* Devuelve la entity con un campo `presupuesto_lineas` con las lineas de presupuesto asociadas
|
||||
@ -324,4 +334,15 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
|
||||
}
|
||||
return $tipo_presupuesto;
|
||||
}
|
||||
|
||||
public function getDireccionFPChecks()
|
||||
{
|
||||
return $this->attributes['direcciones_fp_checks'] ?? [];
|
||||
}
|
||||
|
||||
public function setDireccionFPChecks($value)
|
||||
{
|
||||
$this->attributes['direcciones_fp_checks'] = is_array($value) ? json_encode($value) : $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,6 +200,7 @@ class OrdenTrabajoTareaEntity extends Entity
|
||||
if ($date->action_at && $init) {
|
||||
$end = $date->action_at;
|
||||
$intervals[] = $init->difference($end)->getSeconds();
|
||||
$init = null; // Reset init after calculating the interval
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
ci4/app/Helpers/assets_helper.php
Normal file
10
ci4/app/Helpers/assets_helper.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('versioned_asset')) {
|
||||
function versioned_asset(string $path): string
|
||||
{
|
||||
$fullPath = FCPATH . $path;
|
||||
$version = file_exists($fullPath) ? filemtime($fullPath) : time();
|
||||
return site_url($path) . '?v=' . $version;
|
||||
}
|
||||
}
|
||||
@ -101,6 +101,20 @@ function getGravatarURL(int $size = 30)
|
||||
{
|
||||
return "https://gravatar.com/avatar/".md5(auth()->user()->getEmail())."?s=".$size;
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('gravatar_url')) {
|
||||
function gravatar_url(?string $email, int $size = 40): string
|
||||
{
|
||||
if (!$email) {
|
||||
return "https://www.gravatar.com/avatar/?s={$size}&d=mp";
|
||||
}
|
||||
|
||||
return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?s={$size}&d=identicon";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getAllClassFolder($folder = null){
|
||||
try {
|
||||
helper('filesystem');
|
||||
|
||||
@ -123,7 +123,7 @@ if (!function_exists('checkPermission')) {
|
||||
$response = \Config\Services::response();
|
||||
|
||||
if (!auth()->user()->can($sectionPermission)) {
|
||||
$session->setFlashdata('errorMessage', "No tiene permisos de acceso");
|
||||
$session->setFlashdata('errorMessage', lang('Basic.global.permissionDenied'));
|
||||
|
||||
$route = $redirectRoute ?? 'home';
|
||||
return $response->redirect(route_to($route));
|
||||
|
||||
@ -90,6 +90,7 @@ return [
|
||||
'wait' => 'Wait',
|
||||
'yes' => 'Yes',
|
||||
'back' => 'Back',
|
||||
'permissionDenied' => 'You do not have permission for this action'
|
||||
],
|
||||
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ return [
|
||||
'coleccion' => 'Collection',
|
||||
'numeroEdicion' => 'Edition number',
|
||||
'isbn' => 'ISBN',
|
||||
'iskn' => 'Identificador ISKN',
|
||||
'referenciaCliente' => 'Customer reference',
|
||||
'formatoLibro' => "Book format",
|
||||
'papelFormatoId' => "Size",
|
||||
@ -42,8 +43,8 @@ return [
|
||||
'papelFormatoAncho' => 'Width',
|
||||
'papelFormatoAlto' => 'Height',
|
||||
'cosido' => 'Sewn',
|
||||
'ferro' => 'Ferro',
|
||||
'ferroDigital' => 'Digital Ferro',
|
||||
'ferro' => 'Blueline proof',
|
||||
'ferroDigital' => 'Digital Blueline proof',
|
||||
'prototipo' => 'Prototype',
|
||||
'imagenesBnInterior' => 'B/W pictures inside',
|
||||
'recogerEnTaller' => 'Pick up in workshop',
|
||||
|
||||
@ -28,6 +28,7 @@ return [
|
||||
'addIva' => 'Añadir IVA',
|
||||
'nuevaLinea' => 'Nueva línea',
|
||||
'imprimirAlbaran' => 'Imprimir albarán',
|
||||
'imprimirAlbaranAnonimo' => 'Imprimir albarán anónimo',
|
||||
'borrarAlbaran' => 'Borrar albarán',
|
||||
'borrarAlbaranConfirm' => '¿Está seguro de que desea borrar el albarán?',
|
||||
'borrar' => 'Borrar',
|
||||
|
||||
@ -34,7 +34,7 @@ return [
|
||||
"global_prev" => "Anterior",
|
||||
"global_next" => "Siguiente",
|
||||
"global_save_file" => "Guardar ficheros",
|
||||
"global_upload_files" => "Subir ficheros",
|
||||
"global_select_files" => "Seleccionar ficheros",
|
||||
"global_download_files" => "Descargar ficheros",
|
||||
"global_all" => "Todos",
|
||||
// LOGIN - Index
|
||||
@ -316,59 +316,7 @@ return [
|
||||
"group_rules_title_r" => "¡El campo del nombre del grupo es obligatorio!",
|
||||
"group_rules_dashboard_r" => "¡El campo del panel es obligatorio!",
|
||||
|
||||
// GROUP - Rules Name
|
||||
/* JJO
|
||||
"group_rules_label_group" => "Permiso de grupo",
|
||||
"group_rules_label_user" => "Usuario",
|
||||
"group_rules_label_settings" => "Configuración",
|
||||
"group_rules_label_index" => "Lista",
|
||||
"group_rules_label_add" => "Agregar",
|
||||
"group_rules_label_edit" => "Editar",
|
||||
"group_rules_label_delete" => "Eliminar",
|
||||
"group_rules_label_store" => "Guardar",
|
||||
"group_rules_label_oauth" => "Autenticaciones",
|
||||
"group_rules_label_template" => "Plantillas",
|
||||
"group_rules_label_all" => "Ver todo",
|
||||
"group_rules_label_my" => "Mis notificaciones",
|
||||
"group_rules_label_view" => "Ver notificación",
|
||||
"group_rules_label_oauth_store" => "Guardar oAuth",
|
||||
"group_rules_label_template_store" => "Guardar plantillas",
|
||||
*/
|
||||
|
||||
// AUTH - index
|
||||
"oauth_title" => "Autenticación oAuth",
|
||||
"oauth_subtitle" => "Configuración de autenticación de redes sociales",
|
||||
"oauth_label_id" => "ID de la Cuenta",
|
||||
"oauth_label_id_ph" => "Escriba su id de la cuenta",
|
||||
"oauth_label_key" => "Key de la Cuenta",
|
||||
"oauth_label_key_ph" => "Escriba su key de la cuenta",
|
||||
"oauth_label_secret" => "Llave Secreta",
|
||||
"oauth_label_secret_ph" => "Escriba su llave secreta",
|
||||
"oauth_label_view" => "Mostrar texto",
|
||||
"oauth_label_active" => "Activar red social",
|
||||
"oauth_alert_add" => "¡Guardado exitosamente!",
|
||||
"oauth_alert_error" => "¡Error al guardar!",
|
||||
|
||||
// TEMPLATE - index
|
||||
"template_title" => "Plantillas",
|
||||
"template_subtitle" => "Configuración de Plantilla",
|
||||
"template_subtitle_email" => "Plantillas de Correo Electrónico",
|
||||
"template_label_title" => "Título",
|
||||
"template_label_title_ph" => "Escriba su título",
|
||||
"template_label_message" => "Mensaje",
|
||||
"template_label_forgot_pass" => "Olvido la contraseña",
|
||||
"template_label_welcome" => "Bienvenida",
|
||||
"template_label_tfa" => "Autenticación de dos factores (2FA)",
|
||||
"template_label_tag" => "Ver palabras clave",
|
||||
"template_alert_add" => "¡Guardado exitosamente!",
|
||||
"template_alert_error" => "¡Error al guardar!",
|
||||
"template_modal_title" => "Palabras Clave",
|
||||
"template_modal_subtitle" => "A continuación, se muestran algunas palabras clave que se pueden incorporar al texto:",
|
||||
"template_modal_btn_1" => "Cerrar",
|
||||
"template_modal_copy" => "Copiado!",
|
||||
"template_modal_copy_msg" => "¡Copiado con éxito!",
|
||||
"template_label_confirmation_email" => "Confirmación por correo electrónico",
|
||||
"template_label_notification" => "Notificación de cuentas nuevas",
|
||||
|
||||
|
||||
// SETTINGS - index
|
||||
"settings_title" => "Configuración",
|
||||
@ -634,7 +582,6 @@ return [
|
||||
"permisos_tarifaenvio" => "Envío",
|
||||
"permisos_tarifaimpresion" => "Impresión",
|
||||
|
||||
"permisos_configuracion" => "Configuración",
|
||||
"permisos_tareasservicio" => "Tareas servicio",
|
||||
"permisos_formaspago" => "Formas de pago",
|
||||
"permisos_papelgenerico" => "Papel genérico",
|
||||
@ -810,7 +757,7 @@ return [
|
||||
"menu_tarifaextra" => "Serv. Extra",
|
||||
"menu_tarifamanipulado" => "Manipulado",
|
||||
"menu_tarifaencuadernacion" => "Encuadernación",
|
||||
"menu_tarifapapelcompra" => "Papel compra",
|
||||
"menu_tarifapapelcompra" => "Papel impresión",
|
||||
"menu_servicioAcabado" => "Servicios acabado",
|
||||
"menu_tarifaacabado" => "Acabado",
|
||||
"menu_tarifapapeldefecto" => "Papel defecto",
|
||||
@ -827,11 +774,10 @@ return [
|
||||
"menu_logout" => "Salir",
|
||||
"menu_profile" => "Mi Perfil",
|
||||
"menu_activity" => "Actividad",
|
||||
"menu_backups" => "Backups",
|
||||
"menu_notification" => "Notificaciones",
|
||||
"menu_list" => "Lista",
|
||||
"menu_add" => "Agregar",
|
||||
"menu_oauth" => "Autenticaciones",
|
||||
"menu_template" => "Plantillas",
|
||||
|
||||
"menu_soporte" => "Soporte",
|
||||
"menu_soporte_new_ticket" => "Crear ticket",
|
||||
|
||||
@ -94,6 +94,7 @@ return [
|
||||
'yes' => 'Si',
|
||||
'no' => 'No',
|
||||
'back' => 'Volver',
|
||||
'permissionDenied' => 'No tiene permisos de acceso'
|
||||
|
||||
],
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ return [
|
||||
'code' => 'Código',
|
||||
'codeOt' => 'Código Ot',
|
||||
'createdAt' => 'Creado el',
|
||||
'tipo_papel_generico_id' => 'Tipo Papel Genérico',
|
||||
'deletedAt' => 'Deleted At',
|
||||
'id' => 'ID',
|
||||
'activo' => 'Activo',
|
||||
@ -21,6 +22,16 @@ return [
|
||||
'updatedAt' => 'Actualizado el',
|
||||
'form_acordion_title' => 'Propiedades Papel Genérico',
|
||||
|
||||
// Tipos de papel genérico
|
||||
'offset_blanco' => 'Offset Blanco',
|
||||
'offset_ahuesado' => 'Offset Ahuesado',
|
||||
'estucados' => 'Estucados',
|
||||
'volumen' => 'Volumen',
|
||||
'especiales' => 'Especiales',
|
||||
'reciclados' => 'Reciclados',
|
||||
'cartulinas' => 'Cartulinas',
|
||||
'verjurados' => 'Verjurados',
|
||||
|
||||
'validation' => [
|
||||
'code' => [
|
||||
'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.',
|
||||
|
||||
@ -31,6 +31,12 @@ return [
|
||||
'libroWireoTapaBlanda' => "Wire-o Tapa Blanda",
|
||||
'libroGrapado' => "Grapado",
|
||||
|
||||
'cosido' => 'Cosido',
|
||||
'fresado' => 'Fresado',
|
||||
'espiral' => 'Espiral',
|
||||
'wireo' => 'Wire-o',
|
||||
'grapado' => 'Grapado',
|
||||
|
||||
'datosPresupuesto' => 'Datos generales del presupuesto',
|
||||
'datosLibro' => 'Datos del libro',
|
||||
'datosServicios' => 'Otros Servicios',
|
||||
@ -74,8 +80,10 @@ return [
|
||||
'acabadoFaja' => 'Acabado Faja',
|
||||
'cosido' => 'Cosido',
|
||||
'ferro' => 'Ferro',
|
||||
'ferro_2' => 'Ferro (2 uds.)',
|
||||
'ferroDigital' => 'Ferro Digital',
|
||||
'prototipo' => 'Prototipo',
|
||||
'prototipo_2' => 'Prototipo (2 uds.)',
|
||||
'imagenesBnInterior' => 'Imágenes B/N interior',
|
||||
'recogerEnTaller' => 'Recoger en taller',
|
||||
'marcapaginas' => 'Marcapáginas',
|
||||
@ -155,15 +163,18 @@ return [
|
||||
'lomo' => 'Lomo',
|
||||
'lomoRedondo' => 'Lomo redondo',
|
||||
'peso' => 'Peso',
|
||||
'click' => 'Click',
|
||||
'click' => 'Click (C+M)',
|
||||
'totalClicks' => 'Total clicks',
|
||||
'costeClicks' => 'Coste clicks',
|
||||
'totalClicksMargen' => 'Marge clicks',
|
||||
'horas' => 'Horas máquina',
|
||||
'precioHora' => 'Precio hora',
|
||||
'precioImpresion' => 'Total horas',
|
||||
'precioHora' => 'Precio hora (C+M)',
|
||||
'precioImpresion' => 'Coste horas',
|
||||
'precioImpresionMargen' => 'Margen horas',
|
||||
'precioPagNegro' => 'Precio pág. negro',
|
||||
'precioPagColor' => 'Precio pág. color',
|
||||
'totalTinta' => 'Total tinta',
|
||||
'totalCorte' => 'Total corte',
|
||||
'totalTinta' => 'Total tinta (C+M)',
|
||||
'totalCorte' => 'Total corte (C+M)',
|
||||
'total' => 'Total',
|
||||
'totalLinea' => 'Total Precio Línea',
|
||||
'aFavorFibra' => 'A favor de fibra',
|
||||
@ -230,8 +241,6 @@ return [
|
||||
'gTintaCG' => 'G. tinta CG',
|
||||
'clicksPedido' => 'Clicks Pedido',
|
||||
'totalClicks' => 'Total Clicks',
|
||||
'totalTinta' => 'Total Tinta',
|
||||
'totalCorte' => 'Total Corte',
|
||||
'totalImpresion' => 'Total máquina',
|
||||
'velocidadCorte' => 'Velocidad corte',
|
||||
'precioHoraCorte' => 'Precio hora corte',
|
||||
@ -298,7 +307,7 @@ return [
|
||||
'previewSobrecubierta' => 'Configuración del papel: Sobrecubierta',
|
||||
'previewFaja' => 'Configuración del papel: Faja',
|
||||
'previewPapelGenerico' => 'Papel Genérico',
|
||||
'previewPapelCompra' => 'Papel de Compra',
|
||||
'previewPapelCompra' => 'Papel Impresión',
|
||||
'previewAreaImpresion' => 'Área de Impresión',
|
||||
'previewPosicionFormas' => 'Posición de Formas',
|
||||
'previewDetalles' => 'Detalles del trabajo',
|
||||
@ -380,6 +389,17 @@ return [
|
||||
],
|
||||
|
||||
'validation' => [
|
||||
'fix_errors' => 'Corrija los siguientes errores antes de continuar:',
|
||||
'titulo_requerido' => 'El campo "Título" es obligatorio.',
|
||||
'tirada_integer_greatherThan_0' => 'Los valores de las tiradas deben ser enteros mayores que 0.',
|
||||
'tirada_pod_nopod' => 'No se pueden mezclar tiradas POD (menor o igual que 30 unidades) con tiradas no POD (mayor que 30 unidades).',
|
||||
'papelFormatoAncho' => 'Seleccione un ancho de libro válido.',
|
||||
'papelFormatoAlto' => 'Seleccione un alto de libro válido.',
|
||||
'papelFormato' => 'Seleccione un formato de libro válido.',
|
||||
'paginasColor' => 'El número de páginas a color debe ser un número entero mayor o igual que 0.',
|
||||
'paginasNegro' => 'El número de páginas en negro debe ser un número entero mayor o igual que 0.',
|
||||
'paginas' => 'El total de páginas tiene que ser mayor que 0.',
|
||||
'tipo_libro' => 'Seleccione el tipo de encuadernación que desea para el presupuesto.',
|
||||
'decimal' => 'El campo {field} debe contener un número decimal.',
|
||||
'integer' => 'El campo {field} debe contener un número entero.',
|
||||
'requerido' => 'El campo {field} es obligatorio.',
|
||||
@ -388,21 +408,39 @@ return [
|
||||
'no_lp_for_merma' => 'Inserte líneas de presupuesto para calcular la merma',
|
||||
'ejemplares_envio' => 'El número de ejemplares enviados no coincide con la tirada',
|
||||
'cliente' => 'Debe seleccionar un cliente',
|
||||
'papelFormato' => 'Seleccione un formato',
|
||||
'tipo_libro' => 'Seleccione un tipo de libro',
|
||||
'disenio_interior' => 'Seleccione el diseño del interior',
|
||||
'papel_interior' => 'Seleccione el tipo de papel',
|
||||
'gramaje_interior' => 'Seleccione el gramaje',
|
||||
|
||||
'disenio_interior' => 'Seleccione el tipo de impresión del interior',
|
||||
'papel_interior' => 'Seleccione el tipo de papel para el interior',
|
||||
'papel_interior_especial' => 'Seleccione el papel especial en el desplegable para el interior',
|
||||
'gramaje_interior' => 'Seleccione el gramaje para el interior',
|
||||
|
||||
'tipo_cubierta' => 'Seleccione el tipo de cubierta',
|
||||
'papel_guardas' => 'Seleccione el tipo de papel para las guardas',
|
||||
'gramaje_guardas' => 'Seleccione el gramaje para las guardas',
|
||||
'papel_cubierta' => 'Seleccione el tipo de papel para la cubierta',
|
||||
'papel_cubierta_especial' => 'Seleccione el papel especial en el desplegable para la cubierta',
|
||||
'gramaje_cubierta' => 'Seleccione el gramaje para la cubierta',
|
||||
|
||||
'papel_sobrecubierta' => 'Seleccione el tipo de papel para la sobrecubierta',
|
||||
'gramaje_sobrecubierta' => 'Seleccione el gramaje para la sobrecubierta',
|
||||
'papel_faja' => 'Seleccione el tipo de papel para la faja',
|
||||
'gramaje_faja' => 'Seleccione el gramaje para la faja',
|
||||
|
||||
'unidades_envio_mayor_tirada' => 'El número de unidades enviadas debe ser igual a {field} unidades.',
|
||||
|
||||
'pais' => 'Debe seleccionar un país',
|
||||
'integer_greatherThan_0' => 'Número entero > 0 requerido',
|
||||
'greater_than_0' => 'El campo {field} debe ser mayor que 0',
|
||||
'tirada_no_valida' => "Tirada no valida",
|
||||
'sin_gramaje' => "Seleccione gramaje",
|
||||
'tipo_cubierta' => 'Seleccione tipo de cubierta',
|
||||
|
||||
'opcion_solapas' => 'Seleccione la opción para las solapas',
|
||||
'paginas_multiplo_4' => 'El número de páginas para <b>cosido</b> o <b>grapado</b> debe ser múltiplo de 4',
|
||||
'paginas_multiplo_4' => 'El número total de páginas para <b>cosido</b> y <b>grapado</b> debe ser múltiplo de 4',
|
||||
'paginas_pares' => 'El número de páginas debe ser par',
|
||||
'extras_cubierta' => 'Rellene todos los campos',
|
||||
|
||||
'error_sameAddPrincipal_FP' => 'Debe añadir al menos una dirección en el envío para usarla',
|
||||
'error_sameAddFP1' => 'Debe añadir al menos una dirección en el envío del primer ferro para usarla.'
|
||||
],
|
||||
|
||||
'errores' => [
|
||||
@ -425,7 +463,12 @@ return [
|
||||
'noCubiertaSobrecubierta' => 'No se hay resultados para cubierta/sobrecubierta',
|
||||
'errorPresupuesto' => 'Se ha producido un error al calcular el presupuesto. Póngase en contacto con el administrador',
|
||||
'error_sobrecubierta_sin_solapas' => 'Debe seleccionar "sobrecubierta" en los datos del libro para introducir el ancho de solapa',
|
||||
'error_faja_sin_solapas' => 'Debe seleccionar "faja" en los datos del libro para introducir el ancho de solapa'
|
||||
'error_faja_sin_solapas' => 'Debe seleccionar "faja" en los datos del libro para introducir el ancho de solapa',
|
||||
'error_lomo_maximo' => "No se pueden encuadernar libros {0} con un lomo interior superior a {1} mm. El lomo actual es de {2} mm. <br>
|
||||
Por favor, disminuya el número de páginas o el gramaje del papel para que sea encuadernable.",
|
||||
'error_lomo_minimo' => "No se pueden encuadernar libros {0} con un lomo interior inferior a {1} mm. El lomo actual es de {2} mm. <br>
|
||||
Por favor, aumente el número de páginas o el gramaje del papel para que sea encuadernable.",
|
||||
'error_direccion_principal_no_encontrada' => 'No se ha encontrado la dirección en las direcciones del cliente. Por favor, añádala antes de marcar esta opción.',
|
||||
],
|
||||
'resize_preview' => 'Refrescar vista esquema'
|
||||
|
||||
|
||||
@ -21,6 +21,8 @@ return [
|
||||
'costePrecio' => 'Coste/Precio',
|
||||
'saveDirection' => 'Guardar en direcciones de cliente',
|
||||
'entregaPieCalle' => 'Entrega a pie de calle (enviado en palets)',
|
||||
'sameAddPrincipal' => 'Usar la dirección principal del presupuesto',
|
||||
'sameAddFP1' => 'Usar la dirección del ferro/prototipo 1',
|
||||
'validation' => [
|
||||
'ejemplares_envio' => 'El número de ejemplares enviados no coincide con la tirada',
|
||||
'max_length' => 'Max. valor caracteres alcanzado',
|
||||
|
||||
@ -157,6 +157,7 @@ return [
|
||||
"tareas_hoy" => "Tareas para HOY",
|
||||
"tareas_all" => "Todas",
|
||||
"tareas_delay" => "Aplazadas",
|
||||
'init_tarea' => 'Iniciar',
|
||||
"play_tarea" => "Continuar",
|
||||
"play_pause" => "Pausar",
|
||||
"play_stop" => "Aplazar",
|
||||
|
||||
@ -62,6 +62,7 @@ return [
|
||||
'seriesFacturasSection' => 'Series facturas',
|
||||
'ajustesSection' => 'Ajustes',
|
||||
'actividadSection' => 'Accesos',
|
||||
'backupSection' => 'Backups',
|
||||
'facturasSection' => 'Facturas',
|
||||
'logisticaSection' => 'Logística',
|
||||
'albaranesPermission' => 'Albaranes',
|
||||
|
||||
@ -15,52 +15,23 @@ class SafekatFtpClient
|
||||
protected string $username;
|
||||
protected string $password;
|
||||
protected string $base_dir;
|
||||
protected bool $xml_enabled;
|
||||
protected object $pedido_xml_config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->pedido_xml_config = config("PedidoXML");
|
||||
$this->pedido_xml_config = config("PresupuestoSFTP");
|
||||
$this->host = $this->pedido_xml_config->host;
|
||||
$this->username = $this->pedido_xml_config->username;
|
||||
$this->password = $this->pedido_xml_config->password;
|
||||
$this->port = $this->pedido_xml_config->port;
|
||||
$this->base_dir = $this->pedido_xml_config->base_dir;
|
||||
$this->xml_enabled = $this->pedido_xml_config->xml_enabled;
|
||||
$this->ftp = new SFTP($this->host);
|
||||
|
||||
}
|
||||
/**
|
||||
* Upload the content of $filename to the base directory declared in App\Config\FTP.php
|
||||
*
|
||||
* @param string $content
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
public function uploadXML(string $content, string $filename): bool
|
||||
{
|
||||
try {
|
||||
if ($this->xml_enabled == false)
|
||||
return false;
|
||||
$remotePath = implode("/", [$this->base_dir, 'pedidos', 'xml_nuevos']);
|
||||
$this->ftp->login(username: $this->username, password: $this->password);
|
||||
if (!$this->ftp->is_dir($remotePath)) {
|
||||
$this->ftp->mkdir($remotePath, recursive: true);
|
||||
}
|
||||
$this->ftp->put($remotePath . '/' . $filename, $content);
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
log_message('error', $th->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function uploadFilePresupuesto(int $presupuesto_id)
|
||||
{
|
||||
try {
|
||||
if ($this->xml_enabled == false)
|
||||
return false;
|
||||
$model = model(PresupuestoFicheroModel::class);
|
||||
$modelPedidoLinea = model(PedidoLineaModel::class);
|
||||
$pedidoLinea = $modelPedidoLinea->findByPresupuesto($presupuesto_id);
|
||||
@ -86,7 +57,6 @@ class SafekatFtpClient
|
||||
public function removeFiles(int $presupuesto_id)
|
||||
{
|
||||
try {
|
||||
// if ($this->xml_enabled == false) return false;
|
||||
$model = model(PresupuestoFicheroModel::class);
|
||||
$modelPedidoLinea = model(PedidoLineaModel::class);
|
||||
$pedidoLinea = $modelPedidoLinea->findByPresupuesto($presupuesto_id);
|
||||
@ -115,7 +85,7 @@ class SafekatFtpClient
|
||||
return implode('/', [$this->base_dir, 'pedidos_files', $rootIdExtern]);
|
||||
}
|
||||
|
||||
public function downloadZipPresupuesto(int $presupuesto_id): ?string
|
||||
public function downloadZipPresupuesto(int $presupuesto_id, ?string $prefijo = null): ?string
|
||||
{
|
||||
$modelPedidoLinea = model(PedidoLineaModel::class);
|
||||
$model = model(PresupuestoFicheroModel::class);
|
||||
@ -143,8 +113,11 @@ class SafekatFtpClient
|
||||
|
||||
foreach ($files as $file) {
|
||||
$originalName = $file->nombre ?? basename($file->file_path);
|
||||
$localFile = $localTempDir . '/' . $originalName;
|
||||
$prefixedName = $prefijo ? $prefijo . '_' . $originalName : $originalName;
|
||||
|
||||
$localFile = $localTempDir . '/' . $prefixedName;
|
||||
$remoteFile = $remotePath . '/' . basename($file->file_path);
|
||||
|
||||
$this->ftp->get($remoteFile, $localFile);
|
||||
}
|
||||
|
||||
@ -167,4 +140,5 @@ class SafekatFtpClient
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
47
ci4/app/Libraries/SftpClientWrapper.php
Normal file
47
ci4/app/Libraries/SftpClientWrapper.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Libraries;
|
||||
|
||||
use phpseclib3\Net\SFTP;
|
||||
use Config\PresupuestoSFTP;
|
||||
|
||||
class SftpClientWrapper
|
||||
{
|
||||
protected SFTP $client;
|
||||
|
||||
public function __construct(PresupuestoSFTP $config)
|
||||
{
|
||||
$this->client = new SFTP($config->host, $config->port);
|
||||
$this->client->login($config->username, $config->password);
|
||||
}
|
||||
|
||||
public function upload(string $local, string $remote): bool
|
||||
{
|
||||
return $this->client->put($remote, $local, SFTP::SOURCE_LOCAL_FILE);
|
||||
}
|
||||
|
||||
public function delete(string $remote): bool
|
||||
{
|
||||
return $this->client->delete($remote);
|
||||
}
|
||||
|
||||
public function exists(string $remote): bool
|
||||
{
|
||||
return $this->client->file_exists($remote);
|
||||
}
|
||||
|
||||
public function mkdir(string $remote): bool
|
||||
{
|
||||
return $this->client->mkdir($remote, true);
|
||||
}
|
||||
|
||||
public function chmod(string $path, int $permissions): bool
|
||||
{
|
||||
return $this->client->chmod($permissions, $path);
|
||||
}
|
||||
|
||||
public function get(string $remotePath, string $localPath): bool
|
||||
{
|
||||
return $this->client->get($remotePath, $localPath);
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,7 @@ class AlbaranLineaModel extends \App\Models\BaseModel
|
||||
->select(
|
||||
"t1.id, t1.titulo as titulo, t1.isbn as isbn, t1.ref_cliente as ref_cliente,
|
||||
t1.cantidad as unidades, t1.precio_unidad as precio_unidad, t1.iva_reducido as iva_reducido,
|
||||
t1.total as total, pedidos.id AS pedido"
|
||||
t1.total as total, pedidos.id AS pedido, t1.cajas, t1.unidades_cajas"
|
||||
)
|
||||
->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left")
|
||||
->join("pedidos", "pedidos_linea.pedido_id = pedidos.id", "left");
|
||||
|
||||
@ -56,4 +56,40 @@ class ConfigVariableModel extends Model
|
||||
|
||||
return $builder->get()->getFirstRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve solo el valor de la variable por nombre
|
||||
*/
|
||||
public function getValue(string $name): ?string
|
||||
{
|
||||
$row = $this->getVariable($name);
|
||||
return $row ? $row->value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve el valor decodificado (JSON) si aplica
|
||||
*/
|
||||
public function getDecodedValue(string $name): ?array
|
||||
{
|
||||
$value = $this->getValue($name);
|
||||
$decoded = json_decode($value, true);
|
||||
|
||||
return (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve las opciones disponibles de cabezadas (como array clave => langKey)
|
||||
*/
|
||||
public function getCabezadasDisponibles(): array
|
||||
{
|
||||
return $this->getDecodedValue('cabezadas_disponibles') ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve la cabezada por defecto, o 'WHI' si no está definida
|
||||
*/
|
||||
public function getCabezadaDefault(): string
|
||||
{
|
||||
return $this->getValue('cabezada_default') ?? 'WHI';
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +131,7 @@ class MaquinasPapelesImpresionModel extends \App\Models\BaseModel
|
||||
$builder->where("t1.papel_impresion_id", $papel_id);
|
||||
$builder->where("t2.is_deleted", 0);
|
||||
$builder->where("t2.is_rotativa", $isRotativa);
|
||||
$builder->where("t2.tipo", 'impresion');
|
||||
$builder->where("t3.is_deleted", 0);
|
||||
$builder->where("t3.isActivo", 1);
|
||||
|
||||
|
||||
@ -22,7 +22,18 @@ class PapelGenericoModel extends \App\Models\BaseModel
|
||||
4 => "t1.show_in_client_special",
|
||||
];
|
||||
|
||||
protected $allowedFields = ["nombre", "code", "code_ot", "show_in_client", "show_in_client_special", "deleted_at", "is_deleted", "activo"];
|
||||
protected $allowedFields =
|
||||
[
|
||||
"nombre",
|
||||
"code",
|
||||
"code_ot",
|
||||
"show_in_client",
|
||||
"show_in_client_special",
|
||||
"deleted_at",
|
||||
"is_deleted",
|
||||
"activo",
|
||||
"tipo_papel_generico_id",
|
||||
];
|
||||
protected $returnType = "App\Entities\Configuracion\PapelGenerico";
|
||||
|
||||
protected $useTimestamps = true;
|
||||
@ -132,16 +143,16 @@ class PapelGenericoModel extends \App\Models\BaseModel
|
||||
return empty($search)
|
||||
? $builder
|
||||
: $builder
|
||||
->groupStart()
|
||||
->like("t1.id", $search)
|
||||
->orLike("t1.nombre", $search)
|
||||
->orLike("t1.code", $search)
|
||||
->orLike("t1.code_ot", $search)
|
||||
->orLike("t1.id", $search)
|
||||
->orLike("t1.nombre", $search)
|
||||
->orLike("t1.code", $search)
|
||||
->orLike("t1.code_ot", $search)
|
||||
->groupEnd();
|
||||
->groupStart()
|
||||
->like("t1.id", $search)
|
||||
->orLike("t1.nombre", $search)
|
||||
->orLike("t1.code", $search)
|
||||
->orLike("t1.code_ot", $search)
|
||||
->orLike("t1.id", $search)
|
||||
->orLike("t1.nombre", $search)
|
||||
->orLike("t1.code", $search)
|
||||
->orLike("t1.code_ot", $search)
|
||||
->groupEnd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
22
ci4/app/Models/Configuracion/TipoPapelGenericoModel.php
Executable file
22
ci4/app/Models/Configuracion/TipoPapelGenericoModel.php
Executable file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Configuracion;
|
||||
|
||||
class TipoPapelGenericoModel extends \App\Models\BaseModel
|
||||
{
|
||||
protected $table = "tipos_papel_generico";
|
||||
|
||||
/**
|
||||
* Whether primary key uses auto increment.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $useAutoIncrement = true;
|
||||
|
||||
protected $allowedFields = [
|
||||
"clave",
|
||||
];
|
||||
protected $returnType = "App\Entities\Configuracion\TipoPapelGenerico";
|
||||
|
||||
|
||||
}
|
||||
@ -241,6 +241,8 @@ class PedidoLineaModel extends \App\Models\BaseModel
|
||||
// Ejecutar la consulta y devolver resultados
|
||||
$query = $builder->get();
|
||||
$data = $query->getResult();
|
||||
|
||||
$query_text = $this->db->getLastQuery();
|
||||
|
||||
foreach($data as $register) {
|
||||
$item = (object)[
|
||||
|
||||
@ -56,10 +56,11 @@ class ErrorPresupuesto extends Model
|
||||
protected $beforeDelete = [];
|
||||
protected $afterDelete = [];
|
||||
|
||||
public function insertError(int $presupuesto_id, int $presupuesto_user_id, string $error, mixed $datos)
|
||||
public function insertError($presupuesto_id, int $presupuesto_user_id, string $error, mixed $datos)
|
||||
{
|
||||
$presupuesto = is_null($presupuesto_id) ? 0 : $presupuesto_id;
|
||||
$this->insert([
|
||||
"presupuesto_id" => $presupuesto_id,
|
||||
"presupuesto_id" => $presupuesto,
|
||||
"presupuesto_user_id" => $presupuesto_user_id,
|
||||
"error" => $error,
|
||||
"datos_presupuesto" => json_encode($datos)
|
||||
|
||||
@ -141,12 +141,16 @@ class ImportadorModel extends \App\Models\BaseModel
|
||||
ELSE 0
|
||||
END) AS precio_ud,
|
||||
t1.total,
|
||||
t1.estado');
|
||||
t1.estado'
|
||||
);
|
||||
|
||||
if ($catalogoId !== null) {
|
||||
$builder->where('t1.catalogo_id', $catalogoId);
|
||||
}
|
||||
|
||||
// Agregar filtro por estados
|
||||
$builder->whereIn('t1.estado', ['aceptado', 'validado', 'finalizado']);
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,8 @@ class PresupuestoDireccionesModel extends \App\Models\BaseModel
|
||||
"proveedor_id",
|
||||
"proveedor",
|
||||
"entregaPieCalle",
|
||||
"is_ferro_prototipo"
|
||||
"is_ferro_prototipo",
|
||||
"num_ferro_prototipo"
|
||||
];
|
||||
|
||||
protected $returnType = "App\Entities\Presupuestos\PresupuestoDireccionesEntity";
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models\Presupuestos;
|
||||
|
||||
use Config\Paths;
|
||||
|
||||
class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
{
|
||||
protected $table = "presupuesto_ficheros";
|
||||
@ -23,16 +25,42 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
|
||||
public static $labelField = "nombre";
|
||||
|
||||
/**
|
||||
* Devuelve la ruta relativa del archivo dentro de WRITEPATH.
|
||||
*
|
||||
* @param int $presupuesto_id
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public function getRelativePath(int $presupuesto_id, string $filename): string
|
||||
{
|
||||
return config(Paths::class)->presupuestosPath . '/' . $presupuesto_id . '/' . $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve la ruta absoluta en el sistema de archivos del servidor.
|
||||
*
|
||||
* @param int $presupuesto_id
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public function getAbsolutePath(int $presupuesto_id, string $filename): string
|
||||
{
|
||||
return WRITEPATH . $this->getRelativePath($presupuesto_id, $filename);
|
||||
}
|
||||
|
||||
|
||||
public function saveFileInBBDD($presupuesto_id, $filename, $extension, $user_id)
|
||||
{
|
||||
try {
|
||||
|
||||
$new_filename = $this->generateFileHash($filename) . '.' . $extension;
|
||||
$relativePath = $this->getRelativePath($presupuesto_id, $new_filename);
|
||||
|
||||
$this->db->table($this->table . " t1")
|
||||
->set('presupuesto_id', $presupuesto_id)
|
||||
->set('nombre', $filename)
|
||||
->set('file_path', WRITEPATH . 'uploads/presupuestos/' . $new_filename)
|
||||
->set('file_path', $relativePath)
|
||||
->set('upload_by', $user_id)
|
||||
->set('upload_at', date('Y-m-d H:i:s'))
|
||||
->insert();
|
||||
@ -54,8 +82,9 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
|
||||
// se comprueba que el $file->nombre no sea igual a ninguno de los elementos del array $old_files
|
||||
if (!in_array($file->nombre, $old_files)) {
|
||||
if (file_exists($file->file_path)) {
|
||||
unlink($file->file_path);
|
||||
$fullPath = WRITEPATH . $file->file_path;
|
||||
if (file_exists($fullPath)) {
|
||||
unlink($fullPath);
|
||||
}
|
||||
|
||||
$this->db
|
||||
@ -76,20 +105,23 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
->table($this->table . " t1")
|
||||
->where('presupuesto_id', $presupuesto_id_origen)->get()->getResult();
|
||||
if ($files) {
|
||||
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
$hash = $this->generateFileHash($file->nombre);
|
||||
|
||||
// se copia el fichero a la nueva ubicación
|
||||
if (!file_exists(WRITEPATH . $file->file_path)) {
|
||||
copy($file->file_path, WRITEPATH . 'uploads/presupuestos/' . $hash);
|
||||
$originalPath = WRITEPATH . $file->file_path;
|
||||
$newPath = 'uploads/presupuestos/' . $hash;
|
||||
|
||||
if (file_exists($originalPath)) {
|
||||
copy($originalPath, WRITEPATH . $newPath);
|
||||
}
|
||||
|
||||
$this->db->table($this->table . " t1")
|
||||
->set('presupuesto_id', $presupuesto_id_destino)
|
||||
->set('nombre', $file->nombre)
|
||||
->set('file_path', WRITEPATH . 'uploads/presupuestos/' . $hash)
|
||||
->set('file_path', $newPath)
|
||||
->set('upload_by', auth()->user()->id)
|
||||
->set('upload_at', date('Y-m-d H:i:s'))
|
||||
->insert();
|
||||
@ -105,6 +137,30 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
->where('presupuesto_id', $presupuesto_id)->get()->getResult();
|
||||
}
|
||||
|
||||
public function deleteMissingFiles(int $presupuesto_id, array $keepNames = [])
|
||||
{
|
||||
$files = $this->getFiles($presupuesto_id);
|
||||
$deletedCount = 0;
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!in_array($file->nombre, $keepNames)) {
|
||||
$fullPath = WRITEPATH . $file->file_path;
|
||||
if (file_exists($fullPath)) {
|
||||
unlink($fullPath);
|
||||
}
|
||||
$this->db->table($this->table)
|
||||
->where('presupuesto_id', $presupuesto_id)
|
||||
->where('nombre', $file->nombre)
|
||||
->delete();
|
||||
|
||||
$deletedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return $deletedCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Función para convertir el nombre y extensión de un fichero en un hash único
|
||||
@ -117,6 +173,4 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
|
||||
{
|
||||
return hash('sha256', $filename);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
"user_update_id",
|
||||
"tipo_impresion_id",
|
||||
"tipologia_id",
|
||||
"catalogo_id",
|
||||
"pais_id",
|
||||
"estado_id",
|
||||
"inc_rei",
|
||||
@ -66,6 +67,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
"titulo",
|
||||
"autor",
|
||||
"coleccion",
|
||||
"iskn",
|
||||
"numero_edicion",
|
||||
"isbn",
|
||||
"referencia_cliente",
|
||||
@ -138,6 +140,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
'lomo_redondo',
|
||||
'cabezada',
|
||||
'envio_base',
|
||||
'direcciones_fp_checks',
|
||||
];
|
||||
protected $returnType = "App\Entities\Presupuestos\PresupuestoEntity";
|
||||
|
||||
@ -399,15 +402,27 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
function confirmarPresupuesto($presupuesto_id)
|
||||
/**
|
||||
* Confirma un presupuesto (cambia su estado a 'confirmado') y,
|
||||
* si no tiene asignado un ISKN, lo genera y lo asigna automáticamente.
|
||||
*
|
||||
* @param int $presupuesto_id ID del presupuesto a confirmar.
|
||||
* @return void
|
||||
*/
|
||||
public function confirmarPresupuesto($presupuesto_id)
|
||||
{
|
||||
// Cambiar el estado del presupuesto a '2' (confirmado)
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->where('t1.id', $presupuesto_id)
|
||||
->set('t1.estado_id', 2)
|
||||
->update();
|
||||
|
||||
// Si existe y aún no tiene ISKN asignado, lo generamos y asignamos
|
||||
$this->asignarIskn($presupuesto_id);
|
||||
}
|
||||
|
||||
|
||||
function insertarPresupuestoCliente($id, $tirada, $data, $data_cabecera, $extra_info, $resumen_totales, $iva_reducido, $excluir_rotativa, $tiradas_alternativas)
|
||||
{
|
||||
|
||||
@ -467,13 +482,13 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
|
||||
'comparador_json_data' => $this->generateJson($data),
|
||||
|
||||
'faja_color' => is_array($data['faja']) && count($data['faja'])>0 ? 1 : 0,
|
||||
'faja_color' => is_array($data['faja']) && count($data['faja']) > 0 ? 1 : 0,
|
||||
'solapas_ancho_faja_color' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['solapas'] : 60,
|
||||
'alto_faja_color' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['alto'] : 50,
|
||||
'alto_faja_color' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['alto'] : 50,
|
||||
|
||||
'acabado_cubierta_id' => $data['cubierta']['acabado'],
|
||||
'acabado_sobrecubierta_id' => !$data['sobrecubierta'] ? 0 : $data['sobrecubierta']['acabado'],
|
||||
'acabado_faja_id' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['acabado'] : 0,
|
||||
'acabado_faja_id' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['acabado'] : 0,
|
||||
|
||||
'comp_tipo_impresion' => $data['isHq'] ? ($data['isColor'] ? 'colorhq' : 'negrohq') : ($data['isColor'] ? 'color' : 'negro'),
|
||||
|
||||
@ -498,41 +513,55 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
'total_margenes' => round($totalMargenes, 2),
|
||||
|
||||
'total_antes_descuento' => round(
|
||||
$totalCostes + $totalMargenes +
|
||||
$resumen_totales['coste_envio']+$resumen_totales['margen_envio'] +
|
||||
$data['envio_base'], 2),
|
||||
$totalCostes + $totalMargenes +
|
||||
$resumen_totales['coste_envio'] + $resumen_totales['margen_envio'] +
|
||||
$data['envio_base'],
|
||||
2
|
||||
),
|
||||
'total_descuento' => 0,
|
||||
'total_descuentoPercent' => 0,
|
||||
|
||||
'total_precio_unidad' => $resumen_totales['precio_unidad'],
|
||||
'total_presupuesto' => round(
|
||||
$totalCostes + $totalMargenes +
|
||||
$resumen_totales['coste_envio']+$resumen_totales['margen_envio'] +
|
||||
$data['envio_base'], 2),
|
||||
'total_aceptado' => round($totalCostes + $totalMargenes + $resumen_totales['coste_envio']+$resumen_totales['margen_envio'], 2),
|
||||
$totalCostes + $totalMargenes +
|
||||
$resumen_totales['coste_envio'] + $resumen_totales['margen_envio'] +
|
||||
$data['envio_base'],
|
||||
2
|
||||
),
|
||||
'total_aceptado' => round(
|
||||
$totalCostes + $totalMargenes +
|
||||
$resumen_totales['coste_envio'] + $resumen_totales['margen_envio'] +
|
||||
$data['envio_base'],
|
||||
2
|
||||
),
|
||||
|
||||
'total_factor' => round(
|
||||
($totalCostes + $totalMargenes ) /
|
||||
$resumen_totales['sumForFactor'], 2),
|
||||
($totalCostes + $totalMargenes) /
|
||||
$resumen_totales['sumForFactor'],
|
||||
2
|
||||
),
|
||||
'total_factor_ponderado' => round(
|
||||
($totalCostes + $totalMargenes ) /
|
||||
$resumen_totales['sumForFactorPonderado'], 2),
|
||||
($totalCostes + $totalMargenes) /
|
||||
$resumen_totales['sumForFactorPonderado'],
|
||||
2
|
||||
),
|
||||
|
||||
'iva_reducido' => $iva_reducido,
|
||||
'excluir_rotativa' => $excluir_rotativa,
|
||||
|
||||
'direcciones_fp_checks' => $data['direcciones_fp_checks'] ? json_encode($data['direcciones_fp_checks']) : null,
|
||||
|
||||
];
|
||||
/* Actualizacion */
|
||||
if ($id != 0) {
|
||||
$fields['id'] = $id;
|
||||
$fields['updated_at'] = date('Y-m-d H:i:s', now());
|
||||
$fields['user_update_id'] = auth()->id();
|
||||
$fields['user_update_id'] = auth()->id();
|
||||
$this->db->table($this->table)->where('id', $id)->update($fields);
|
||||
return $id;
|
||||
}
|
||||
/* Inserccion */
|
||||
else {
|
||||
$fields['user_created_id'] = auth()->id();
|
||||
}
|
||||
/* Inserccion */ else {
|
||||
$fields['user_created_id'] = auth()->id();
|
||||
$fields['user_update_id'] = auth()->id();
|
||||
$this->db->table($this->table)->insert($fields);
|
||||
return $this->db->insertID();
|
||||
@ -619,7 +648,6 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
'gramaje' => intval($data['faja']['gramaje']),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
$json = json_encode($values);
|
||||
return $json;
|
||||
@ -630,7 +658,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id AS numero, t1.tipo_impresion_id as tipo, t1.tirada AS unidades, t1.total_aceptado as total, t1.paginas AS paginas,
|
||||
"t1.id AS numero, t1.tipo_impresion_id as tipo, t1.tirada AS unidades, t1.total_aceptado as total, t1.paginas AS paginas,
|
||||
t1.titulo AS titulo, t1.autor AS autor, t1.isbn AS isbn,
|
||||
t1.papel_formato_id AS papel_formato_id, t1.papel_formato_personalizado AS papel_formato_personalizado,
|
||||
t1.papel_formato_ancho AS papel_formato_ancho, t1.papel_formato_alto AS papel_formato_alto,
|
||||
@ -638,7 +666,7 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
t3.codigo AS codigo_encuadernacion,
|
||||
t1.solapas AS solapas_cubierta, CAST(t1.solapas_ancho AS INT) AS solapas_ancho_cubierta,
|
||||
t1.solapas_sobrecubierta AS solapas_sobrecubierta, CAST(t1.solapas_ancho_sobrecubierta AS INT) AS solapas_ancho_sobrecubierta,"
|
||||
);
|
||||
);
|
||||
$builder->join("lg_papel_formato t2", "t1.papel_formato_id = t2.id", "left");
|
||||
$builder->join("tipos_presupuestos t3", "t1.tipo_impresion_id = t3.id", "left");
|
||||
$builder->where("t1.is_deleted", 0);
|
||||
@ -742,12 +770,13 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
return $servicios;
|
||||
}
|
||||
|
||||
public function getPresupuestosClienteForm($cliente_id = -1){
|
||||
public function getPresupuestosClienteForm($cliente_id = -1)
|
||||
{
|
||||
$builder = $this->db
|
||||
->table($this->table . " pr")
|
||||
->table($this->table . " pr")
|
||||
->select('pr.id, pr.created_at as fecha, CONCAT(u.first_name, " ", u.last_name) AS comercial, pr.titulo,
|
||||
pr.paginas as paginas, pr.tirada, pr.total_aceptado as total, pr.estado_id as estado')
|
||||
->join ("clientes c", "pr.cliente_id = c.id", "left")
|
||||
->join("clientes c", "pr.cliente_id = c.id", "left")
|
||||
->join("users u", "c.comercial_id= u.id", "left")
|
||||
->where('pr.cliente_id', $cliente_id)
|
||||
->groupBy('pr.id');
|
||||
@ -889,6 +918,28 @@ class PresupuestoModel extends \App\Models\BaseModel
|
||||
return $description_interior . $description_cubierta . $description_sobrecubierta . $acabado;
|
||||
}
|
||||
|
||||
public function vincularCatalogo(int $presupuesto_id, int $catalogo_id): bool
|
||||
{
|
||||
return $this->update($presupuesto_id, [
|
||||
'catalogo_id' => $catalogo_id,
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'user_update_id' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function asignarIskn(int $presupuesto_id): bool
|
||||
{
|
||||
$presupuesto = $this->find($presupuesto_id);
|
||||
|
||||
// Si no existe o ya tiene ISKN, no lo modificamos
|
||||
if (!$presupuesto || !empty($presupuesto->iskn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->update($presupuesto_id, [
|
||||
'iskn' => model('App\Models\Catalogo\IdentificadorIsknModel')->newIskn(),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'user_update_id' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
15
ci4/app/Models/Sistema/BackupModel.php
Normal file
15
ci4/app/Models/Sistema/BackupModel.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Sistema;
|
||||
|
||||
use App\Models\BaseModel;
|
||||
|
||||
class BackupModel extends BaseModel
|
||||
{
|
||||
protected $table = 'backups';
|
||||
protected $primaryKey = 'id';
|
||||
protected $allowedFields = [
|
||||
'filename', 'type', 'path_local', 'path_remote', 'size', 'status', 'created_at', 'updated_at'
|
||||
];
|
||||
protected $useTimestamps = true;
|
||||
}
|
||||
@ -100,6 +100,18 @@ class GroupModel extends \App\Models\BaseModel
|
||||
->countAllResults();
|
||||
}
|
||||
|
||||
public function getUsersByRol(string $groupKeyWord)
|
||||
{
|
||||
return $this->db
|
||||
->table('auth_groups_users agu')
|
||||
->select('u.id, ai.secret as email, u.first_name, u.last_name')
|
||||
->join('users u', 'u.id = agu.user_id')
|
||||
->join('auth_identities ai', 'ai.user_id = u.id AND ai.type = "email_password"', 'left')
|
||||
->where('agu.group', $groupKeyWord)
|
||||
->get()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
|
||||
public function getUsersRoles($userId)
|
||||
{
|
||||
|
||||
27
ci4/app/Services/PapelService.php
Normal file
27
ci4/app/Services/PapelService.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use CodeIgniter\Config\BaseService;
|
||||
use App\Models\Configuracion\TipoPapelGenericoModel;
|
||||
|
||||
class PapelService extends BaseService
|
||||
{
|
||||
protected TipoPapelGenericoModel $tipoPapelGenericoModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->tipoPapelGenericoModel = model(TipoPapelGenericoModel::class);
|
||||
}
|
||||
|
||||
public function getTipoPapelGenerico()
|
||||
{
|
||||
$values = $this->tipoPapelGenericoModel->findAll();
|
||||
$tipoPapelGenericoList = [];
|
||||
foreach ($values as $value) {
|
||||
$tipoPapelGenericoList[$value->id] = lang('PapelGenerico.' . $value->clave);
|
||||
}
|
||||
|
||||
return $tipoPapelGenericoList;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user