Autosave: 20260505-022427
BIN
assets/uploads/vouchers/69f628e5003ef-Screenshot_279.png
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
assets/uploads/vouchers/69f62c490eda7-Screenshot_280.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
BIN
assets/uploads/vouchers/69f8af82967ba-Screenshot_281.png
Normal file
|
After Width: | Height: | Size: 279 KiB |
BIN
assets/uploads/vouchers/69f8afbe93f18-817.png
Normal file
|
After Width: | Height: | Size: 320 KiB |
BIN
assets/uploads/vouchers/69f8afed2d55f-Screenshot_282.png
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
assets/uploads/vouchers/69f8b0359ef5a-573.png
Normal file
|
After Width: | Height: | Size: 410 KiB |
BIN
assets/uploads/vouchers/69f8b32a16007-Screenshot_281.png
Normal file
|
After Width: | Height: | Size: 279 KiB |
BIN
assets/uploads/vouchers/69f8b72bb3d23-Screenshot_284.png
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
assets/uploads/vouchers/69f8b8eb5f055-3945.png
Normal file
|
After Width: | Height: | Size: 594 KiB |
BIN
assets/uploads/vouchers/69f8c40730a5a-383.png
Normal file
|
After Width: | Height: | Size: 660 KiB |
BIN
assets/uploads/vouchers/69f8c47e3da97-440.png
Normal file
|
After Width: | Height: | Size: 464 KiB |
BIN
assets/uploads/vouchers/69f8c50043bb9-786.png
Normal file
|
After Width: | Height: | Size: 473 KiB |
BIN
assets/uploads/vouchers/69f8c55a30c84-91.png
Normal file
|
After Width: | Height: | Size: 429 KiB |
BIN
assets/uploads/vouchers/69f8ec16f11ec-Screenshot_285.png
Normal file
|
After Width: | Height: | Size: 252 KiB |
BIN
assets/uploads/vouchers/69f8efbfce35f-Screenshot_286.png
Normal file
|
After Width: | Height: | Size: 296 KiB |
BIN
assets/uploads/vouchers/69f8f847ecbe7-Screenshot_287.png
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
assets/uploads/vouchers/69f91193e8602-Screenshot_289.png
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
assets/uploads/vouchers/69f912182d9e0-Screenshot_290.png
Normal file
|
After Width: | Height: | Size: 343 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 48 KiB |
BIN
assets/uploads/vouchers/69f928e46f4fa-Screenshot_291.png
Normal file
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 43 KiB |
2
db/migrations/070_add_descargo_to_pedidos.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- Migration: Add descargo column to pedidos table
|
||||
ALTER TABLE pedidos ADD COLUMN descargo TEXT NULL;
|
||||
@ -10,11 +10,12 @@ try {
|
||||
$pdo = db();
|
||||
$type = $_GET['type'] ?? 'all';
|
||||
|
||||
// Filtramos solo los pedidos que están en estado 'ROTULADO 📦'
|
||||
// Filtramos solo los pedidos que están en estado 'ROTULADO 📦' y son de la agencia 'SHALOM'
|
||||
$query = "
|
||||
SELECT p.dni_cliente, p.celular, p.sede_envio, p.agencia
|
||||
FROM pedidos p
|
||||
WHERE p.estado = 'ROTULADO 📦'
|
||||
AND p.agencia LIKE '%SHALOM%'
|
||||
";
|
||||
|
||||
if ($type === 'terrestre') {
|
||||
@ -61,10 +62,22 @@ try {
|
||||
foreach ($pedidos as $pedido) {
|
||||
// Limpiar el DNI: solo números
|
||||
$dni = preg_replace('/[^0-9]/', '', $pedido['dni_cliente'] ?? '');
|
||||
$celular = htmlspecialchars($pedido['celular'] ?? '');
|
||||
|
||||
// Limpiar el celular: solo números
|
||||
$celular = preg_replace('/[^0-9]/', '', $pedido['celular'] ?? '');
|
||||
|
||||
// Eliminar prefijo '51' si existe al inicio y el número es largo (ej. 51987654321)
|
||||
if (str_starts_with($celular, '51') && strlen($celular) > 9) {
|
||||
$celular = substr($celular, 2);
|
||||
}
|
||||
|
||||
$celular = htmlspecialchars($celular);
|
||||
|
||||
$destino_raw = str_ireplace('shalom:', '', $pedido['sede_envio'] ?? '');
|
||||
$parts = explode('/', $destino_raw);
|
||||
$destino = trim(end($parts));
|
||||
// Convertir a mayúsculas
|
||||
$destino = mb_strtoupper($destino, 'UTF-8');
|
||||
$destino = htmlspecialchars($destino);
|
||||
|
||||
$output .= '<tr>';
|
||||
|
||||
@ -164,6 +164,7 @@ include 'layout_header.php';
|
||||
<th>Nº De Orden</th>
|
||||
<th>Codigo De Orden</th>
|
||||
<th>CLAVE</th>
|
||||
<th>DESCARGO</th>
|
||||
<th>PENDIENTES</th>
|
||||
<th>Estado</th>
|
||||
<?php if ($user_role !== 'Asesor'): ?><th>Asesor</th><?php endif; ?>
|
||||
@ -193,6 +194,9 @@ include 'layout_header.php';
|
||||
<td class="<?php echo $isEditableClave; ?>" data-id="<?php echo $pedido['id']; ?>" data-field="clave">
|
||||
<?php echo $canSeeClave ? htmlspecialchars($pedido['clave'] ?? 'N/A') : '<i class="fas fa-eye-slash text-muted" title="Suba el número de operación y seleccione el banco para ver la clave"></i> <span class="text-muted" style="font-size: 0.8rem;">Oculto</span>'; ?>
|
||||
</td>
|
||||
<td class="editable" data-id="<?php echo $pedido['id']; ?>" data-field="descargo">
|
||||
<?php echo htmlspecialchars($pedido['descargo'] ?? 'N/A'); ?>
|
||||
</td>
|
||||
<td class="editable-pendientes" data-id="<?php echo $pedido['id']; ?>" data-value="<?php echo htmlspecialchars($pedido['pendientes'] ?? ''); ?>" style="cursor: pointer;">
|
||||
<span class="badge" style="<?php echo getPendientesStyle($pedido['pendientes'] ?? ''); ?>">
|
||||
<?php echo htmlspecialchars(!empty($pedido['pendientes']) ? $pedido['pendientes'] : 'Seleccionar'); ?>
|
||||
@ -325,13 +329,22 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
if (e.target && e.target.classList.contains('editable')) {
|
||||
const cell = e.target;
|
||||
if (cell.querySelector('input')) {
|
||||
if (cell.querySelector('input') || cell.querySelector('textarea')) {
|
||||
return; // Already in edit mode
|
||||
}
|
||||
|
||||
const originalContent = cell.textContent.trim();
|
||||
const input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
const field = cell.dataset.field;
|
||||
let input;
|
||||
|
||||
if (field === 'descargo') {
|
||||
input = document.createElement('textarea');
|
||||
input.rows = 2;
|
||||
} else {
|
||||
input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
}
|
||||
|
||||
input.className = 'form-control form-control-sm';
|
||||
input.value = originalContent === 'N/A' ? '' : originalContent;
|
||||
|
||||
@ -347,6 +360,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
let endpoint = 'update_tracking.php'; // Default endpoint
|
||||
if (field === 'clave') {
|
||||
endpoint = 'update_clave.php';
|
||||
} else if (field === 'descargo') {
|
||||
endpoint = 'update_pedido_field.php';
|
||||
}
|
||||
|
||||
// Restore original content visually
|
||||
|
||||
@ -226,6 +226,25 @@ $navItems = [
|
||||
'text' => 'Gestionar Usuarios',
|
||||
'roles' => ['Administrador', 'admin']
|
||||
],
|
||||
'marketing_group' => [
|
||||
'icon' => 'fa-bullhorn',
|
||||
'text' => 'Marketing',
|
||||
'roles' => ['Administrador', 'admin'],
|
||||
'submenu' => [
|
||||
'marketing_produccion' => [
|
||||
'url' => 'marketing_produccion.php',
|
||||
'icon' => 'fa-video',
|
||||
'text' => 'Producción de Video',
|
||||
'roles' => ['Administrador', 'admin']
|
||||
],
|
||||
'marketing_assets' => [
|
||||
'url' => 'marketing_assets.php',
|
||||
'icon' => 'fa-folder-open',
|
||||
'text' => 'Biblioteca de Assets',
|
||||
'roles' => ['Administrador', 'admin']
|
||||
],
|
||||
]
|
||||
],
|
||||
'configuracion' => [
|
||||
'url' => 'configuracion.php',
|
||||
'icon' => 'fa-cog',
|
||||
|
||||
14
marketing_assets.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
$pageTitle = "Biblioteca de Assets";
|
||||
include 'layout_header.php';
|
||||
?>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Biblioteca de Recursos de Marketing</h5>
|
||||
<p>Aquí podrás subir y organizar logos, intros de video, música y otros materiales que la editora deba utilizar de forma recurrente.</p>
|
||||
<div class="alert alert-info">
|
||||
<i class="bi bi-info-circle me-1"></i> Esta sección está en desarrollo. Pronto podrás gestionar tus archivos aquí.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include 'layout_footer.php'; ?>
|
||||
131
marketing_produccion.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
$pageTitle = "Producción de Video";
|
||||
include 'db/config.php';
|
||||
include 'layout_header.php';
|
||||
|
||||
$db = db();
|
||||
|
||||
// Obtener productos para el select
|
||||
$stmt_products = $db->query("SELECT id, nombre FROM products ORDER BY nombre ASC");
|
||||
$productos = $stmt_products->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Obtener videos existentes
|
||||
$stmt_videos = $db->query("SELECT mv.*, p.nombre as nombre_producto
|
||||
FROM marketing_videos mv
|
||||
LEFT JOIN products p ON mv.producto_id = p.id
|
||||
ORDER BY mv.fecha_creacion DESC");
|
||||
$videos = $stmt_videos->fetchAll(PDO::FETCH_ASSOC);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>Gestión de Producción</h2>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#nuevoVideoModal">
|
||||
<i class="fas fa-plus"></i> Nuevo Pedido de Video
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_GET['success'])): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
¡Pedido creado con éxito!
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<?php if (empty($videos)): ?>
|
||||
<div class="col-12 text-center py-5">
|
||||
<i class="fas fa-video fa-4x text-muted mb-3"></i>
|
||||
<p class="text-muted">No hay pedidos de video registrados aún.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($videos as $v): ?>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100 shadow-sm">
|
||||
<div class="position-relative">
|
||||
<?php if ($v['foto_producto']): ?>
|
||||
<img src="<?php echo $v['foto_producto']; ?>" class="card-img-top" alt="Producto" style="height: 200px; object-fit: cover;">
|
||||
<?php else: ?>
|
||||
<div class="bg-light d-flex align-items-center justify-content-center" style="height: 200px;">
|
||||
<i class="fas fa-image fa-3x text-muted"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<span class="position-absolute top-0 end-0 m-2 badge <?php
|
||||
echo $v['estado'] == 'Pendiente' ? 'bg-warning' :
|
||||
($v['estado'] == 'En Proceso' ? 'bg-info' :
|
||||
($v['estado'] == 'Terminado' ? 'bg-primary' : 'bg-success'));
|
||||
?>">
|
||||
<?php echo $v['estado']; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?php echo htmlspecialchars($v['nombre_producto'] ?: 'Producto General'); ?></h5>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo nl2br(htmlspecialchars(substr($v['instrucciones'], 0, 100))); ?>...
|
||||
</p>
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<small class="text-muted"><i class="far fa-calendar-alt"></i> <?php echo date('d/m/Y', strtotime($v['fecha_creacion'])); ?></small>
|
||||
<?php if ($v['link_video']): ?>
|
||||
<a href="<?php echo $v['link_video']; ?>" target="_blank" class="btn btn-sm btn-success">
|
||||
<i class="fas fa-play"></i> Ver Video
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer bg-white border-top-0">
|
||||
<button class="btn btn-outline-primary btn-sm w-100" onclick="verDetalles(<?php echo $v['id']; ?>)">
|
||||
<i class="fas fa-edit"></i> Gestionar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Modal Nuevo Video -->
|
||||
<div class="modal fade" id="nuevoVideoModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form action="save_marketing_video.php" method="POST" enctype="multipart/form-data">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Nuevo Pedido de Video</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Producto Relacionado</label>
|
||||
<select name="producto_id" class="form-select">
|
||||
<option value="">Seleccionar producto...</option>
|
||||
<?php foreach ($productos as $p): ?>
|
||||
<option value="<?php echo $p['id']; ?>"><?php echo htmlspecialchars($p['nombre']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Foto de Referencia / Ángulo</label>
|
||||
<input type="file" name="foto_producto" class="form-control" accept="image/*">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Instrucciones Detalladas</label>
|
||||
<textarea name="instrucciones" class="form-control" rows="4" placeholder="Describe el ángulo, la música, el estilo del video, etc."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
||||
<button type="submit" class="btn btn-primary">Crear Pedido</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function verDetalles(id) {
|
||||
// Por ahora solo mostramos un mensaje, luego implementaremos la edición
|
||||
alert("Funcionalidad de edición para el ID " + id + " en desarrollo.");
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include 'layout_footer.php'; ?>
|
||||
@ -317,6 +317,11 @@ include 'layout_header.php';
|
||||
<textarea class="form-control" id="observacion" name="observacion" rows="2"><?php echo htmlspecialchars($pedido['observacion'] ?? ''); ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="descargo" class="form-label">Descargo (Observación del Cliente)</label>
|
||||
<textarea class="form-control" id="descargo" name="descargo" rows="2"><?php echo htmlspecialchars($pedido['descargo'] ?? ''); ?></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Guardar Pedido</button>
|
||||
<a href="<?php echo htmlspecialchars($_SERVER['HTTP_REFERER'] ?? 'pedidos.php'); ?>" class="btn btn-secondary">Cancelar</a>
|
||||
</form>
|
||||
|
||||
@ -98,7 +98,7 @@ include 'layout_header.php';
|
||||
|
||||
<!-- Modal for tracking status -->
|
||||
<div class="modal fade" id="trackingModal" tabindex="-1" aria-labelledby="trackingModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl" style="max-width: 950px;">
|
||||
<div class="modal-dialog modal-xl" style="max-width: 1100px;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="trackingModalLabel">Estado del Envío - Shalom</h5>
|
||||
@ -416,23 +416,23 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const isCurrent = stepNum === activeStep;
|
||||
|
||||
stepsHtml += `
|
||||
<div class="text-center" style="width: 100px; position: relative; z-index: 2;">
|
||||
<div style="width: 32px; height: 32px; background-color: ${isActive ? '#e30613' : 'white'}; border: 2px solid ${isActive ? '#e30613' : '#fce4e4'}; border-radius: 50%; margin: 0 auto 10px; display: flex; align-items: center; justify-content: center;">
|
||||
${isActive ? '<i class="fas fa-check" style="color: white; font-size: 16px;"></i>' : ''}
|
||||
<div class="text-center" style="width: 120px; position: relative; z-index: 2;">
|
||||
<div style="width: 36px; height: 36px; background-color: ${isActive ? '#e30613' : 'white'}; border: 2px solid ${isActive ? '#e30613' : '#fce4e4'}; border-radius: 50%; margin: 0 auto 10px; display: flex; align-items: center; justify-content: center;">
|
||||
${isActive ? '<i class="fas fa-check" style="color: white; font-size: 18px;"></i>' : ''}
|
||||
</div>
|
||||
<span style="font-size: 1rem; font-weight: ${isCurrent ? 'bold' : 'normal'}; color: ${isActive ? '#1a1a6e' : '#999'}; display: block; white-space: nowrap;">${step}</span>
|
||||
<span style="font-size: 1.1rem; font-weight: ${isCurrent ? 'bold' : 'normal'}; color: ${isActive ? '#1a1a6e' : '#999'}; display: block; white-space: nowrap;">${step}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
let html = `
|
||||
<div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #333; background: white; padding: 40px 50px; border-radius: 15px; border: 1px solid #eee; box-shadow: 0 4px 12px rgba(0,0,0,0.05);">
|
||||
<div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #333; background: white; padding: 50px 60px; border-radius: 15px; border: 1px solid #eee; box-shadow: 0 4px 12px rgba(0,0,0,0.05);">
|
||||
<!-- Header Section -->
|
||||
<div class="d-flex justify-content-between align-items-start mb-3 flex-wrap">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="me-4">
|
||||
<!-- Illustration -->
|
||||
<svg width="160" height="160" viewBox="0 0 200 200">
|
||||
<svg width="180" height="180" viewBox="0 0 200 200">
|
||||
<!-- Dashed path -->
|
||||
<path d="M40 80C60 80 70 130 100 130C130 130 140 80 160 80" stroke="#94a3b8" stroke-width="3" stroke-dasharray="6 6" fill="none" />
|
||||
|
||||
@ -469,41 +469,41 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex align-items-center mb-1">
|
||||
<h1 style="color: #e30613 !important; font-weight: 900; margin: 0; margin-right: 15px; text-transform: uppercase; font-size: 2.8rem;">${statusMessage.toUpperCase()}</h1>
|
||||
<span style="border: 3px solid #e30613; color: #e30613; border-radius: 25px; padding: 4px 15px; font-size: 1.1rem; font-weight: bold;">
|
||||
<h1 style="color: #e30613 !important; font-weight: 900; margin: 0; margin-right: 15px; text-transform: uppercase; font-size: 3.2rem;">${statusMessage.toUpperCase()}</h1>
|
||||
<span style="border: 3px solid #e30613; color: #e30613; border-radius: 25px; padding: 6px 20px; font-size: 1.2rem; font-weight: bold;">
|
||||
<i class="fas fa-download"></i> GRT
|
||||
</span>
|
||||
</div>
|
||||
<p class="mb-1" style="color: #666; font-size: 1.1rem;">${descriptionText}</p>
|
||||
<p style="color: #e30613; font-weight: bold; font-size: 1rem; margin: 0;">
|
||||
<p class="mb-1" style="color: #666; font-size: 1.3rem;">${descriptionText}</p>
|
||||
<p style="color: #e30613; font-weight: bold; font-size: 1.1rem; margin: 0;">
|
||||
<i class="fas fa-chevron-right"></i> Tiempo referencial de llegada 1 día.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm-end">
|
||||
<p class="mb-1" style="font-weight: bold; font-size: 1.1rem; color: #1a1a6e;">N° DE ORDEN: ${orderNumber}</p>
|
||||
<p class="text-muted" style="font-size: 1rem;">Desde el ${formattedDate}</p>
|
||||
<p class="mb-1" style="font-weight: bold; font-size: 1.2rem; color: #1a1a6e;">N° DE ORDEN: ${orderNumber}</p>
|
||||
<p class="text-muted" style="font-size: 1.1rem;">Desde el ${formattedDate}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div class="position-relative mb-4 mt-4" style="padding: 0 40px;">
|
||||
<div class="progress" style="height: 10px; background-color: #fce4e4; border-radius: 5px;">
|
||||
<div class="position-relative mb-5 mt-5" style="padding: 0 60px;">
|
||||
<div class="progress" style="height: 12px; background-color: #fce4e4; border-radius: 6px;">
|
||||
<div class="progress-bar" role="progressbar" style="width: ${progressWidth}%; background-color: #e30613;"></div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between position-absolute top-50 start-0 translate-middle-y w-100" style="padding: 0 20px;">
|
||||
<div class="d-flex justify-content-between position-absolute top-50 start-0 translate-middle-y w-100" style="padding: 0 30px;">
|
||||
${stepsHtml}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Section -->
|
||||
<div class="row mt-4 pt-4 border-top">
|
||||
<div class="row mt-5 pt-4 border-top">
|
||||
<div class="col-md-6 mb-2 mb-md-0">
|
||||
<p class="mb-1" style="font-weight: bold; color: #1a1a6e; font-size: 1.1rem;">Origen: <span style="color: #888; font-weight: normal;">${searchData.origen.nombre || 'N/A'}</span></p>
|
||||
<p class="mb-1" style="font-weight: bold; color: #1a1a6e; font-size: 1.2rem;">Origen: <span style="color: #888; font-weight: normal;">${searchData.origen.nombre || 'N/A'}</span></p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p class="mb-1" style="font-weight: bold; color: #1a1a6e; font-size: 1.1rem;">Destino: <span style="color: #888; font-weight: normal;">${searchData.destino.nombre || 'N/A'}</span></p>
|
||||
<p class="text-muted mb-0" style="font-size: 1rem;">${searchData.destino.direccion || ''}</p>
|
||||
<p class="mb-1" style="font-weight: bold; color: #1a1a6e; font-size: 1.2rem;">Destino: <span style="color: #888; font-weight: normal;">${searchData.destino.nombre || 'N/A'}</span></p>
|
||||
<p class="text-muted mb-0" style="font-size: 1.1rem;">${searchData.destino.direccion || ''}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
37
save_marketing_video.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
include 'db/config.php';
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$db = db();
|
||||
$producto_id = !empty($_POST['producto_id']) ? $_POST['producto_id'] : null;
|
||||
$instrucciones = $_POST['instrucciones'] ?? '';
|
||||
$foto_path = null;
|
||||
|
||||
// Manejo de la subida de foto
|
||||
if (isset($_FILES['foto_producto']) && $_FILES['foto_producto']['error'] == 0) {
|
||||
$target_dir = "assets/uploads/marketing_images/";
|
||||
$file_extension = pathinfo($_FILES["foto_producto"]["name"], PATHINFO_EXTENSION);
|
||||
$file_name = uniqid() . '.' . $file_extension;
|
||||
$target_file = $target_dir . $file_name;
|
||||
|
||||
if (move_uploaded_file($_FILES["foto_producto"]["tmp_name"], $target_file)) {
|
||||
$foto_path = $target_file;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $db->prepare("INSERT INTO marketing_videos (producto_id, foto_producto, instrucciones, estado) VALUES (?, ?, ?, 'Pendiente')");
|
||||
$stmt->execute([$producto_id, $foto_path, $instrucciones]);
|
||||
|
||||
header('Location: marketing_produccion.php?success=1');
|
||||
} catch (PDOException $e) {
|
||||
echo "Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -83,6 +83,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$estado = $_POST['estado'];
|
||||
$notas = trim($_POST['notas']);
|
||||
$observacion = trim($_POST['observacion'] ?? '');
|
||||
$descargo = trim($_POST['descargo'] ?? '');
|
||||
|
||||
if (!empty($productos_detalle)) {
|
||||
$notas .= "\n\n" . $notas_adicionales;
|
||||
@ -153,6 +154,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
'estado' => $estado,
|
||||
'notas' => $notas,
|
||||
'observacion' => $observacion,
|
||||
'descargo' => $descargo,
|
||||
'voucher_adelanto_path' => $voucher_adelanto_path,
|
||||
'voucher_restante_path' => $voucher_restante_path
|
||||
];
|
||||
@ -182,6 +184,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
"estado = :estado",
|
||||
"notas = :notas",
|
||||
"observacion = :observacion",
|
||||
"descargo = :descargo",
|
||||
"voucher_adelanto_path = :voucher_adelanto_path",
|
||||
"voucher_restante_path = :voucher_restante_path"
|
||||
];
|
||||
@ -234,8 +237,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// INSERT: The advisor is the user creating the order.
|
||||
$params['asesor_id'] = $_SESSION['user_id'];
|
||||
|
||||
$columns_sql = "dni_cliente, nombre_completo, celular, agencia, sede_envio, codigo_rastreo, codigo_tracking, clave, pendientes, producto, cantidad, monto_total, monto_adelantado, numero_operacion, banco, monto_debe, estado, asesor_id, notas, observacion, voucher_adelanto_path, voucher_restante_path";
|
||||
$values_sql = ":dni_cliente, :nombre_completo, :celular, :agencia, :sede_envio, :codigo_rastreo, :codigo_tracking, :clave, :pendientes, :producto, :cantidad, :monto_total, :monto_adelantado, :numero_operacion, :banco, :monto_debe, :estado, :asesor_id, :notas, :observacion, :voucher_adelanto_path, :voucher_restante_path";
|
||||
$columns_sql = "dni_cliente, nombre_completo, celular, agencia, sede_envio, codigo_rastreo, codigo_tracking, clave, pendientes, producto, cantidad, monto_total, monto_adelantado, numero_operacion, banco, monto_debe, estado, asesor_id, notas, observacion, descargo, voucher_adelanto_path, voucher_restante_path";
|
||||
$values_sql = ":dni_cliente, :nombre_completo, :celular, :agencia, :sede_envio, :codigo_rastreo, :codigo_tracking, :clave, :pendientes, :producto, :cantidad, :monto_total, :monto_adelantado, :numero_operacion, :banco, :monto_debe, :estado, :asesor_id, :notas, :observacion, :descargo, :voucher_adelanto_path, :voucher_restante_path";
|
||||
|
||||
$completed_states = ['Completado', 'COMPLETADO ✅'];
|
||||
if (in_array($estado, $completed_states)) {
|
||||
|
||||
@ -21,7 +21,7 @@ $field = $data['field'];
|
||||
$value = $data['value'];
|
||||
|
||||
// Whitelist allowed fields for security
|
||||
$allowed_fields = ['numero_operacion', 'banco', 'clave', 'fecha_recojo', 'observacion'];
|
||||
$allowed_fields = ['numero_operacion', 'banco', 'clave', 'fecha_recojo', 'observacion', 'descargo'];
|
||||
if (!in_array($field, $allowed_fields)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Campo no permitido.']);
|
||||
|
||||