Merge branch 'main' into 'dev/pdf_albaranes'

Main

See merge request jjimenez/safekat!274
This commit is contained in:
Ignacio Martinez Navajas
2024-06-16 06:30:06 +00:00
28 changed files with 2921 additions and 76 deletions

View File

@ -0,0 +1,709 @@
<div class="accordion accordion-bordered mt-3" id="accordioAlbaranes">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingAlbaranes">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionAlbaranesTip" aria-expanded="false" aria-controls="accordionAlbaranesTip">
<h3><?= lang("Pedidos.albaranes") ?></h3>
</button>
</h2>
<div id="accordionAlbaranesTip" class="accordion-collapse collapse show" data-bs-parent="#accordioAlbaranes">
<div class="accordion-body">
<div id="bonotes_albaranes" class="col-12 d-flex flex-row-reverse mt-4 gap-2">
<div id="generar_albaranes" class="btn mt-3 btn-success waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.generarAlbaranes') ?></span>
<i class="ti ti-player-play ti-xs"></i>
</div>
<div id="borrar_albaranes" class="btn mt-3 btn-danger waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.borrarAlbaranes') ?></span>
<i class="ti ti-trash ti-xs"></i>
</div>
</div>
</div> <!-- /.accordion-body -->
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
$('#generar_albaranes').on('click', function(){
var lineasPedido = $('#tableOfLineasPedido').DataTable();
var presupuestos = lineasPedido.column(0).data().unique().toArray();
$.ajax({
url: '<?= route_to('crearAlbaranesPedido') ?>',
type: 'POST',
data: {
pedido_id: <?= $pedidoEntity->id ?>,
presupuestos_id: presupuestos,
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
},
success: function(response){
if(response.data.length > 0){
Object.values(response.data).forEach(function(item){
generarAlbaran(item);
});
}
}
});
})
const deleteLineaBtns = function(data) {
return `
<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-linea mx-2" data-id="${data.id}"></i></a>
</div>
</td>`;
};
function generarAlbaran(item){
// Crear los elementos necesarios
const accordion = $('<div>', {
class: 'accordion accordion-bordered mt-3 accordion-albaran',
id: 'accordioAlbaran' + item.albaran.id,
albaran: item.albaran.id
});
const card = $('<div>', {
class: 'card accordion-item active'
});
const header = $('<h2>', {
class: 'accordion-header',
id: 'headingAlbaran' + item.albaran.id
});
const button = $('<button>', {
type: 'button',
class: 'accordion-button collapsed',
'data-bs-toggle': 'collapse',
'data-bs-target': '#accordionAlbaranTip' + item.albaran.id,
'aria-expanded': 'false',
'aria-controls': 'accordionAlbaranTip' + item.albaran.id,
'albaran': item.albaran.id,
}).css({
'background-color': '#F0F8FF'
});
const h3 = $('<h5>').html(item.albaran.numero_albaran);
const collapseDiv = $('<div>', {
id: 'accordionAlbaranTip' + item.albaran.id,
class: 'accordion-collapse collapse',
'data-bs-parent': '#accordioAlbaran' + item.albaran.id
});
const body = $('<div>', {
class: 'accordion-body'
});
const cabecera =
`
<div class="col-12 d-flex justify-content-between mb-3">
<div class="col-6 d-flex flex-row">
<div class="col-2">
<label><?= lang('Pedidos.fecha') ?>:</label>
</div>
<div class="col-2">
<label>${item.albaran.fecha_albaran}</label>
</div>
</div>
<div class="col-6 d-flex flex-row-reverse">
<div class="col-2">
<label style="text-align: right; display:block">${item.albaran.pedido_id}</label>
</div>
<div class="col-2">
<label style="text-align: right"><?= lang('Pedidos.pedido') ?>:</label>
</div>
</div>
</div>
<div class="col-12 d-flex justify-content-between mb-3">
<div class="col-6 d-flex flex-row">
<div class="col-2">
<label><?= lang('Pedidos.cliente') ?>:</label>
</div>
<div class="col-4">
<label>${$('#cliente').val()}</label>
</div>
</div>
<div class="col-6 d-flex flex-row-reverse">
<div class="col-2">
<label style="text-align: right; display:block">${item.albaran.numero_albaran}</label>
</div>
<div class="col-2">
<label style="text-align: right"><?= lang('Pedidos.albaran') ?>:</label>
</div>
</div>
</div>
<div class="col-12 d-flex justify-content-between mb-3">
<div class="col-1">
<label><?= lang('Pedidos.att') ?>:</label>
</div>
<div class="col-11">
<input id="att_${item.albaran.id}" class="cambios-albaran form-control" albaran_id=${item.albaran.id} value="${item.albaran.att_albaran}" class="form-control"></input>
</div>
</div>
<div class="col-12 d-flex justify-content-between mb-3">
<div class="col-1">
<label><?= lang('Pedidos.direccion') ?>:</label>
</div>
<div class="col-11">
<input id="direccion_${item.albaran.id}" albaran_id=${item.albaran.id} value="${item.albaran.direccion_albaran}" class="cambios-albaran form-control"></input>
</div>
</div>
`;
const table = $('<table>',
{ id: 'tablaAlbaran' + item.albaran.id, width:'100%', class: 'table table-responsive table-striped table-hover' })
.css({
'width': '100%',
}).append(
$('<thead>').append(
$('<tr>').append(
$('<th>').css({'max-width':'20px'}),
$('<th>'),
$('<th>', { class:'lp-header', scope: 'col' }).css({'font-size':'smaller'}).text('Unidades'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('Título'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('ISBN'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('Ref. Cliente'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('Cajas'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('Ej./Cajas'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('€/u'),
$('<th>', { class:'lp-header',scope: 'col' }).css({'font-size':'smaller'}).text('Subtotal')
)
),
$('<tbody>'),
$('<tfoot>').append(
$('<tr>').append(
$('<th>', { colspan: '9', style: 'text-align:right' }).text('')
)
),
);
let isChecked = item.albaran.mostrar_precios == 1 ? 'checked' : '';
const botones_albaran =
`
<div class="row mt-1">
<div id="div_mostrar_precios_${item.albaran.id}" class="col-2 d-flex flex-row gap-2">
<div class="d-flex align-items-center">
<label><?= lang('Pedidos.mostrarPrecios') ?>:</label>
</div>
<div class="d-flex align-items-center">
<input type="checkbox" id="mostrar_precios" name="mostrar_precios" albaran_id=${item.albaran.id} class="mostrar-precios custom-control-input" ${isChecked} >
</div>
</div>
<div id="bonotes_albaran_${item.albaran.id}" class="col-10 d-flex flex-row-reverse gap-2">
<div id="borrar_albaran_${item.albaran.id}" class="borrar-albaran btn mt-3 button-albaran btn-label-danger waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.borrarAlbaran') ?></span>
<i class="ti ti-trash ti-xs"></i>
</div>
<div id="imprimir_albaran_${item.albaran.id}" class="imprimir-albaran btn mt-3 btn-label-secondary button-albaran waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.imprimirAlbaran') ?></span>
<i class="ti ti-printer ti-xs"></i>
</div>
<div id="nueva_linea_albaran_${item.albaran.id}" class="nueva-linea-albaran btn mt-3 btn-label-secondary button-albaran waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.nuevaLinea') ?></span>
<i class="ti ti-plus ti-xs"></i>
</div>
<div id="add_iva_albaran_${item.albaran.id}" class="add-iva-albaran btn mt-3 btn-label-secondary button-albaran waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.addIva') ?></span>
<i class="ti ti-plus ti-xs"></i>
</div>
</div>
</div>
`;
// Armar la estructura
button.append(h3);
header.append(button);
card.append(header);
collapseDiv.append(body);
body.append(cabecera);
body.append(table);
body.append(botones_albaran);
card.append(collapseDiv);
accordion.append(card);
// Agregar el elemento al accordioAlbaranes
$('#bonotes_albaranes').before(accordion);
const datatableAlbaran = new DataTable('#tablaAlbaran' + item.albaran.id,{
scrollX: true,
searching: false,
paging: false,
info: false,
ordering: false,
responsive: true,
select: false,
dom: 't',
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
columns: [
{ data: 'id'},
{
data: deleteLineaBtns,
className: 'dt-center'
},
{
data: 'cantidad',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'cantidad_' + row.id,
name: 'cantidad_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'max-width': '50px'
});
return input.prop('outerHTML');
}
},
{
data: 'titulo',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'titulo_' + row.id,
name: 'titulo_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'min-width': '300px'
});
return input.prop('outerHTML');
}
},
{
data: 'isbn',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'isbn_' + row.id,
name: 'isbn_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller'
});
return input.prop('outerHTML');
}
},
{
data: 'ref_cliente',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'ref_cliente_' + row.id,
name: 'ref_cliente_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller'
});
return input.prop('outerHTML');
}
},
{
data: 'cajas',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'cajas_' + row.id,
name: 'cajas_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'max-width': '50px'
});
return input.prop('outerHTML');
}
},
{
data: 'ejemplares_por_caja',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'ejemplares_por_caja_' + row.id,
name: 'ejemplares_por_caja_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'max-width': '50px'
});
return input.prop('outerHTML');
}
},
{
data: 'precio_unidad',
render: function ( data, type, row, meta ) {
value = parseFloat(data).toFixed(4);
var input = $('<input>', {
id: 'precio_unidad_' + row.id,
name: 'precio_unidad_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: value,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'max-width': '50px'
});
return input.prop('outerHTML');
}
},
{
data: 'total',
render: function ( data, type, row, meta ) {
var input = $('<input>', {
id: 'total_' + row.id,
name: 'total_' + row.id,
class: 'lp-cell lp-input albaran_linea',
albaran: item.albaran.numero_albaran,
type: 'text',
value: data,
linea: row.id
}).css({
'text-align': 'center',
'font-size': 'smaller',
'max-width': '50px'
});
return input.prop('outerHTML');
}
}
],
columnDefs: [
{ targets: [0], visible: false, searchable: false },
{ targets: [1], orderable: false },
{ targets: [2, 3, 4, 5, 6, 7, 8, 9], className: 'dt-center' }
],
initComplete: function(settings){
var numColumns = this.api().columns().count();
if(item.albaran.mostrar_precios == 0){
this.api().column(numColumns - 1).visible(false);
this.api().column(numColumns - 2).visible(false);
} else {
this.api().column(numColumns - 1).visible(true);
this.api().column(numColumns - 2).visible(true);
}
},
footerCallback: function (row, data, start, end, display) {
/*
let api = this.api();
var numColumns = api.columns().count();
if(item.albaran.mostrar_precios == 1){
// Remove the formatting to get integer data for summation
let intVal = function (i) {
return typeof i === 'string'
? i.replace(/[\$,]/g, '') * 1
: typeof i === 'number'
? i
: 0;
};
// Total over all pages
total = api
.column(9)
.data()
.reduce((a, b) => intVal(a) + intVal(b), 0);
// Update footer
api.column(numColumns-1).footer().innerHTML =
'Total: ' + total.toFixed(2);
}
else{
api.column(numColumns-1).footer().innerHTML = '';
}
*/
},
});
// Añadir la nueva fila a la tabla
if(Array.isArray(item.lineas)) {
item.lineas.forEach(function(linea) {
datatableAlbaran.row.add(linea).draw();
});
}
}
$(document).on('click', '.accordion-button', function(){
var albaran_id = $(this).attr('albaran');
var table = $('#tablaAlbaran' + albaran_id).DataTable();
table.columns.adjust();
});
$(document).on('change', '.cambios-albaran', function(){
var elementId = $(this).attr('id');
data = {
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
};
data[elementId.split('_')[0] + '_albaran'] = $(this).val();
var albaran_id = $(this).attr('albaran_id');
var url = '<?= route_to('actualizarAlbaran', ':id') ?>';
url = url.replace(':id', albaran_id );
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response){
if('error' in response){
}
}
});
});
$(document).on('change', '.mostrar-precios', function(){
var checked = $(this).prop('checked');
var albaran_id = $(this).attr('albaran_id');
var table = $('#tablaAlbaran' + albaran_id).DataTable();
var url = '<?= route_to('actualizarAlbaran', ':id') ?>';
url = url.replace(':id', albaran_id );
$.ajax({
url: url,
type: 'POST',
data: {
mostrar_precios: checked?1:0,
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
},
success: function(response){
if('error' in response){
if(response.error == 0){
if(checked){
table.column(9).visible(true);
table.column(8).visible(true);
} else {
table.column(9).visible(false);
table.column(8).visible(false);
}
}
}
}
});
});
$(document).on('click', '.btn-delete-linea', function(){
var elementId = $(this).attr('id');
var domTable = $(this).closest('table');
var table = domTable.DataTable();
const row = $(this).closest('tr');
var url = '<?= route_to('borrarAlbaranLinea') ?>';
$.ajax({
url: url,
type: 'POST',
data: {
id: $(this).attr('data-id'),
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
},
success: function(response){
if('error' in response){
if(response.error == 0){
table.row($(row)).remove().draw();
}
}
}
});
});
$(document).on('change', '.albaran_linea', function(){
var elementId = $(this).attr('id');
data = {
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
};
data[elementId.split('_').slice(0, -1).join('_')] = $(this).val();
var linea_id = $(this).attr('linea');
var url = '<?= route_to('actualizarLineaAlbaran', ':id') ?>';
url = url.replace(':id', linea_id );
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response){
if('error' in response){
}
}
});
});
$(document).on('click', '#borrar_albaranes', function(){
// seleccionan todos los accordion dentro del body del accordion accordioAlbaranes
$('.accordion-albaran').each(function() {
// Aquí puedes trabajar con cada acordeón interno encontrado
var albaran_id = $(this).attr('albaran');
var url = '<?= route_to('borrarAlbaran', ':id') ?>';
url = url.replace(':id', albaran_id );
$.ajax({
url: url,
type: 'GET',
success: function(response){
if(response){
if('error' in response){
if(response.error == 0){
$('#accordioAlbaran' + albaran_id).remove();
}
}
}
}
});
});
});
$(document).on('click', '.borrar-albaran', function(){
var albaran_id = $(this).attr('id').split('_').slice(-1)[0];
var url = '<?= route_to('borrarAlbaran', ':id') ?>';
url = url.replace(':id', albaran_id );
$.ajax({
url: url,
type: 'GET',
success: function(response){
if(response){
if('error' in response){
if(response.error == 0){
$('#accordioAlbaran' + albaran_id).remove();
}
}
}
}
});
});
$(document).on('click', '.nueva-linea-albaran', function(){
var albaran_id = $(this).attr('id').split('_').slice(-1)[0];
var url = '<?= route_to('addAlbaranLinea', ':id') ?>';
url = url.replace(':id', albaran_id );
$.ajax({
url: url,
type: 'GET',
success: function(response){
if(response){
if('error' in response){
if(response.error == 0){
var table = $('#tablaAlbaran' + albaran_id).DataTable();
table.row.add(response.data).draw();
}
}
}
}
});
});
$(document).on('click', '.add-iva-albaran', function(){
var albaran_id = $(this).attr('id').split('_').slice(-1)[0];
var url = '<?= route_to('addIVA', ':id') ?>';
url = url.replace(':id', albaran_id );
data = {
albaran_id: albaran_id,
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
};
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response){
if(response){
if('error' in response){
if(response.error == 0){
var table = $('#tablaAlbaran' + albaran_id).DataTable();
table.row.add(response.data).draw();
}
}
}
}
});
});
$(document).on('click', '.imprimir-albaran', function(){
var albaran_id = $(this).attr('id').split('_').slice(-1)[0];
//NACHO AQUI
});
$.ajax({
url: '<?= route_to('getAlbaranes', $pedidoEntity->id) ?>',
type: 'GET',
success: function(response){
if(response.data.length > 0){
Object.values(response.data).forEach(function(item){
generarAlbaran(item);
});
}
}
});
<?=$this->endSection() ?>

View File

@ -0,0 +1,304 @@
<div class="accordion accordion-bordered mt-3" id="cabeceraPedido">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingPedido">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionPedidoTip" aria-expanded="false" aria-controls="accordionPedidoTip">
<h3><?= lang("Pedidos.datosPedido") ?></h3>
</button>
</h2>
<div id="accordionPedidoTip" class="accordion-collapse collapse show" data-bs-parent="#accordioPedido">
<div class="accordion-body">
<div class="row">
<div class="col-md-12 col-lg-2 px-4">
<div class="mb-1">
<label for="id" class="form-label">
<?= lang('Pedidos.id') ?>
</label>
<input readonly id="id" name="id" tabindex="1" maxLength="11" class="form-control" value="<?= old('id', $pedidoEntity->id) ?>" >
</div>
</div><!--//.mb-3 -->
<div class="col-md-12 col-lg-4 px-4">
<div class="mb-1">
<label for="cliente" class="form-label">
<?= lang('Pedidos.cliente') ?>
<div class="btn-group btn-group-sm">
<a href="<?= route_to('editarCliente', $pedidoEntity->cliente_id); ?>" target="_blank" ><i class="ti ti-file-search ti-sm btn-edit mx-2" data-id="${data.id}"></i></a>
</div>
</label>
<input readonly id="cliente" name="cliente" tabindex="2" maxLength="11" class="form-control" value="<?= old('cliente', $pedidoEntity->cliente) ?>" >
</div>
</div><!--//.mb-3 -->
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="comercial" class="form-label">
<?= lang('Pedidos.comercial') ?>
</label>
<input readonly id="comercial" name="comercial" tabindex="1" maxLength="11" class="form-control" value="<?= old('comercial', $pedidoEntity->comercial) ?>" >
</div>
</div><!--//.mb-3 -->
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="estadoText" class="form-label">
<?= lang('Pedidos.estado') ?>
</label>
<input readonly id="estadoText" name="estadoText" tabindex="1" maxLength="11" class="form-control" value="<?= old('estadoText', $pedidoEntity->estadoText) ?>" >
</div>
</div><!--//.mb-3 -->
<div class="accordion accordion mt-3 accordion-without-arrow" id="FechasPedido">
<div class="card accordion-item active mt-3 mx-2">
<h2 class="accordion-header" id="headingFechas">
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionIcon-1" aria-controls="accordionIcon-1">
<i class="ti ti-businessplan ti-sm mx-2"></i><?= lang('Pedidos.totales') ?>
</button>
</h2>
<div id="accordionFechasTip" class="accordion show" data-bs-parent="#accordioFechas">
<div class="accordion-body">
<div class="row">
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="total_precio" class="form-label">
<?= lang('Pedidos.total_precio') ?>
</label>
<input readonly id="total_precio" name="total_precio" tabindex="1" maxLength="11" class="form-control" value="<?= old('total_precio', $pedidoEntity->total_precio) ?>" >
</div>
</div><!--//.mb-3 -->
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="total_tirada" class="form-label">
<?= lang('Pedidos.total_tirada') ?>
</label>
<input readonly id="total_tirada" name="total_tirada" tabindex="1" maxLength="11" class="form-control" value="<?= old('total_tirada', $pedidoEntity->total_tirada ) ?>" >
</div>
</div><!--//.mb-3 -->
</div>
</div> <!--//accordion-body -->
</div> <!--//accordionFechasTip-->
</div> <!--//card-->
</div>
<div class="accordion accordion mt-3 accordion-without-arrow" id="FechasPedido">
<div class="card accordion-item active mt-3 mx-2">
<h2 class="accordion-header" id="headingFechas">
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionIcon-1" aria-controls="accordionIcon-1">
<i class="ti ti-calendar ti-sm mx-2"></i><?= lang("Pedidos.fechas") ?>
</button>
</h2>
<div id="accordionFechasTip" class="accordion show" data-bs-parent="#accordioFechas">
<div class="accordion-body">
<div class="row">
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="fecha_entrega_real" class="fecha-pedido form-label">
<?= lang('Pedidos.fecha_entrega_real') ?>
</label>
<input type="text" value="" id="fecha_entrega_real" name="fecha_entrega_real" tabindex="1" maxLength="11" class="form-control" value="<?= old('fecha_entrega_real', $pedidoEntity->fecha_entrega_real) ?>" >
</div>
</div>
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="fecha_impresion" class="form-label">
<?= lang('Pedidos.fecha_impresion') ?>
</label>
<input type="text" id="fecha_impresion" name="fecha_impresion" tabindex="1" maxLength="11" class="fecha-pedido form-control" value="<?= old('fecha_impresion', $pedidoEntity->fecha_impresion) ?>" >
</div>
</div>
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="fecha_encuadernado" class="form-label">
<?= lang('Pedidos.fecha_encuadernado') ?>
</label>
<input type="text" id="fecha_encuadernado" name="fecha_encuadernado" tabindex="1" maxLength="11" class="fecha-pedido form-control" value="<?= old('fecha_encuadernado', $pedidoEntity->fecha_encuadernado) ?>" >
</div>
</div>
<div class="col-md-12 col-lg-3 px-4">
<div class="mb-1">
<label for="fecha_entrega_externo" class="form-label">
<?= lang('Pedidos.fecha_entrega_externo') ?>
</label>
<input type="text" id="fecha_entrega_externo" name="fecha_entrega_externo" tabindex="1" maxLength="11" class="fecha-pedido form-control" value="<?= old('fecha_entrega_externo', $pedidoEntity->fecha_entrega_externo) ?>" >
</div>
</div>
</div>
</div>
</div> <!--//accordionFechasTip-->
</div> <!--//card-->
</div>
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
<div class="col-12 d-flex flex-row-reverse mt-4 gap-2">
<div id="pedido_finalizado" class="buton-estado btn mt-3 btn-success waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.finalizar') ?></span>
<i class="ti ti-hourglass-empty ti-xs"></i>
</div>
<div id="pedido_cancelado" class="buton-estado btn mt-3 btn-danger waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('Pedidos.cancelar') ?></span>
<i class="ti ti-circle-x ti-xs"></i>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
$("#fecha_entrega_real").flatpickr({
defaultDate: <?= $pedidoEntity->fecha_entrega_real_text ? "'".$pedidoEntity->fecha_entrega_real_text."'" : 'null' ?>,
dateFormat: "d/m/Y",
locale: {
firstDayOfWeek: 1,
weekdays: {
shorthand: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
longhand: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
},
months: {
shorthand: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Оct', 'Nov', 'Dic'],
longhand: ['Enero', 'Febreo', 'Мarzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
},
},
onChange: function(selectedDates, dateStr, instance) {
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
updateDate('fecha_entrega_real', dateStr);
<?php endif; ?>
}
});
$("#fecha_impresion").flatpickr({
defaultDate: <?= $pedidoEntity->fecha_impresion_text ? "'".$pedidoEntity->fecha_impresion_text."'" : 'null' ?>,
dateFormat: "d/m/Y",
locale: {
firstDayOfWeek: 1,
weekdays: {
shorthand: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
longhand: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
},
months: {
shorthand: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Оct', 'Nov', 'Dic'],
longhand: ['Enero', 'Febreo', 'Мarzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
},
},
onChange: function(selectedDates, dateStr, instance) {
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
updateDate('fecha_impresion', dateStr);
<?php endif; ?>
}
});
$("#fecha_encuadernado").flatpickr({
defaultDate: <?= $pedidoEntity->fecha_encuadernado_text ? "'".$pedidoEntity->fecha_encuadernado_text."'" : 'null' ?>,
dateFormat: "d/m/Y",
locale: {
firstDayOfWeek: 1,
weekdays: {
shorthand: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
longhand: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
},
months: {
shorthand: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Оct', 'Nov', 'Dic'],
longhand: ['Enero', 'Febreo', 'Мarzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
},
},
onChange: function(selectedDates, dateStr, instance) {
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
updateDate('fecha_encuadernado', dateStr);
<?php endif; ?>
}
});
$("#fecha_entrega_externo").flatpickr({
defaultDate: <?= $pedidoEntity->fecha_entrega_externo_text ? "'".$pedidoEntity->fecha_entrega_externo_text."'" : 'null' ?>,
dateFormat: "d/m/Y",
locale: {
firstDayOfWeek: 1,
weekdays: {
shorthand: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
longhand: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
},
months: {
shorthand: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Оct', 'Nov', 'Dic'],
longhand: ['Enero', 'Febreo', 'Мarzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
},
},
onChange: function(selectedDates, dateStr, instance) {
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
updateDate('fecha_entrega_externo', dateStr);
<?php endif; ?>
}
});
<?php if ($pedidoEntity->estado !== 'finalizado' && $pedidoEntity->estado !== 'cancelado'): ?>
$('.buton-estado').on('click', function() {
var id = <?=$pedidoEntity->id ?>;
var estado = $(this).attr('id').split('_')[1];
var url = '<?= route_to('cambiarEstadoPedido') ?>';
var data = {
id: id,
estado: estado
};
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response) {
try{
if (response.status=="success") {
location.reload();
}
}
catch(e){
console.log(e);
}
}
});
});
<?php endif; ?>
function updateDate(elementId, dateStr) {
var id = <?=$pedidoEntity->id ?>;
data = {
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
};
var parts = dateStr.split('/');
var newFormat = parts[2] + '-' + parts[1] + '-' + parts[0]; // Asume dateStr en formato d/m/Y.
data[elementId] = newFormat;
var url = '<?= route_to('actualizarPedido', ':id') ?>';
url = url.replace(':id', id );
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response){
if('error' in response){
}
}
});
}
<?=$this->endSection() ?>

View File

@ -0,0 +1,24 @@
<div class="accordion accordion-bordered mt-3" id="accordioFacturas">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingFacturas">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionFacturasTip" aria-expanded="false" aria-controls="accordionFacturasTip">
<h3><?= lang("Pedidos.facturas") ?></h3>
</button>
</h2>
<div id="accordionFacturasTip" class="accordion-collapse collapse show" data-bs-parent="#accordioFacturas">
<div class="accordion-body">
</div> <!-- /.accordion-body -->
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
<?=$this->endSection() ?>

View File

@ -0,0 +1,140 @@
<div class="accordion accordion-bordered mt-3" id="accordioLineas">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingLineas">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionLineasTip" aria-expanded="false" aria-controls="accordionLineasTip">
<h3><?= lang("Pedidos.lineas") ?></h3>
</button>
</h2>
<div id="accordionLineasTip" class="accordion-collapse collapse show" data-bs-parent="#accordioLineas">
<div class="accordion-body">
<table id="tableOfLineasPedido" class="table table-striped table-hover" style="width: 100%;">
<thead>
<tr>
<th></th>
<th><?= lang('Pedidos.presupuesto') ?></th>
<th><?= lang('Pedidos.unidades')?></th>
<th><?= lang('Pedidos.concepto') ?></th>
<th><?= lang('Pedidos.total') ?></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th colspan="5" style="text-align:right">Total:</th>
</tr>
</tfoot>
</table>
</div> <!-- /.accordion-body -->
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
const viewPresupuestoBtns = function(data) {
return `
<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-file-search ti-sm btn-view mx-2" data-id="${data.numero}"></i></a>
</div>
</td>`;
};
var tableOfLineasPedido = new DataTable('#tableOfLineasPedido',{
processing: true,
serverSide: true,
autoWidth: true,
responsive: true,
scrollX: true,
searchable: false,
info: false,
dom: 't',
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
ajax : $.fn.dataTable.pipeline( {
url: '<?= route_to('tablaLineasPedido') ?>',
data: function ( d ) {
d.pedido_id = <?= $pedidoEntity->id ?>;
},
method: 'POST',
headers: {'X-Requested-With': 'XMLHttpRequest'},
async: true,
}),
columns: [
{data: 'numero'},
{
data: viewPresupuestoBtns,
className: 'dt-center'
},
{data: 'unidades'},
{data: 'concepto'},
{data: 'total'},
],
columnDefs: [
{
targets: 0,
visible: false,
orderable: false,
searchable: false
},
{
targets: 1,
orderable: false,
data: null,
defaultContent: ''
},
{
targets: [2,3,4],
orderable: false,
},
],
footerCallback: function (row, data, start, end, display) {
let api = this.api();
// Remove the formatting to get integer data for summation
let intVal = function (i) {
return typeof i === 'string'
? i.replace(/[\$,]/g, '') * 1
: typeof i === 'number'
? i
: 0;
};
// Total over all pages
total = api
.column(4)
.data()
.reduce((a, b) => intVal(a) + intVal(b), 0);
// Update footer
api.column(4).footer().innerHTML =
'Total: ' + total;
},
});
$(document).on('click', '.btn-view', function(e) {
<?php if (auth()->user()->inGroup('admin') || auth()->user()->inGroup('beta')): ?>
var url = '<?= route_to('editarPresupuesto', ':id') ?>';
<?php else: ?>
var url = '<?= route_to('editarPresupuestoCliente2', ':id') ?>';
<?php endif; ?>
url = url.replace(':id', `${$(this).attr('data-id')}` );
console.log(url);
window.open(
url,
'_blank' // <- This is what makes it open in a new window.
);
});
<?=$this->endSection() ?>

View File

@ -0,0 +1,50 @@
<?= $this->include("themes/_commonPartialsBs/datatables") ?>
<?= $this->include("themes/_commonPartialsBs/select2bs5") ?>
<?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
<?=$this->extend('themes/vuexy/main/defaultlayout') ?>
<?= $this->section("content") ?>
<div class="row">
<div class="col-12">
<div class="card card-info">
<div class="card-header">
<h3 class="card-title"><?= $boxTitle ?? $pageTitle ?></h3>
</div><!--//.card-header -->
<form id="pedidoForm" method="post" class="card-body" action="<?= $formAction ?>">
<?= csrf_field() ?>
<div class="card-body">
<?= view("themes/_commonPartialsBs/_alertBoxes") ?>
<?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?>
<?= view("themes/vuexy/form/pedidos/_cabeceraItems") ?>
<?= view("themes/vuexy/form/pedidos/_lineasItems") ?>
<?= view("themes/vuexy/form/pedidos/_albaranesItems") ?>
<?= view("themes/vuexy/form/pedidos/_facturasItems") ?>
</div><!-- /.card-body -->
<div class="pt-4">
<?= anchor(route_to("listaPresupuestos"), lang("Basic.global.Cancel"), ["class" => "btn btn-secondary float-start"]) ?>
</div><!-- /.card-footer -->
</form>
</div><!-- //.card -->
</div><!--//.col -->
</div><!--//.row -->
<?= $this->endSection() ?>
<?=$this->section('css') ?>
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/flatpickr/flatpickr.css") ?>">
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/sk-datatables.css') ?>">
<?=$this->endSection() ?>
<?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/flatpickr/flatpickr.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/datatables-sk/plugins/select/dataTables.select.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<?=$this->endSection() ?>

View File

@ -0,0 +1,178 @@
<?=$this->include('themes/_commonPartialsBs/datatables') ?>
<?= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
<?=$this->extend('themes/vuexy/main/defaultlayout') ?>
<?=$this->section('content'); ?>
<div class="row">
<div class="col-md-12">
<div class="card card-info">
<div class="card-header">
<h3 class="card-title"><?=lang('Pedidos.pedidosList') ?></h3>
</div><!--//.card-header -->
<div class="card-body">
<?= view('themes/_commonPartialsBs/_alertBoxes'); ?>
<table id="tableOfPedidos" class="table table-striped table-hover" style="width: 100%;">
<thead>
<tr>
<th><?= lang('Pedidos.id') ?></th>
<th><?= lang('Pedidos.fecha') ?></th>
<th><?= lang('Pedidos.fecha_entrega') ?></th>
<th><?= lang('Pedidos.cliente') ?></th>
<th><?= lang('Pedidos.comercial') ?></th>
<th><?= lang('Pedidos.titulo') ?></th>
<th><?= lang('Pedidos.ubicacion') ?></th>
<th><?= lang('Pedidos.inc_rei') ?></th>
<th><?= lang('Pedidos.num_paginas') ?></th>
<th><?= lang('Pedidos.tiradas') ?></th>
<th><?= lang('Pedidos.total_presupuesto') ?></th>
<th><?= lang('Pedidos.estado') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div><!--//.card-body -->
<div class="card-footer">
</div><!--//.card-footer -->
</div><!--//.card -->
</div><!--//.col -->
</div><!--//.row -->
<?=$this->endSection() ?>
<?=$this->section('additionalInlineJs') ?>
const lastColNr = $('#tableOfPedidos').find("tr:first th").length - 1;
const actionBtns = function(data) {
return `
<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="${data.id}"></i></a>
</div>
</td>`;
};
theTable = $('#tableOfPedidos').DataTable({
processing: true,
serverSide: true,
autoWidth: true,
responsive: true,
scrollX: true,
lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ],
pageLength: 50,
lengthChange: true,
"dom": 'lfBrtip',
"buttons": [
'copy', 'csv', 'excel', 'print', {
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'A4'
}
],
stateSave: true,
order: [[0, 'asc']],
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
ajax : $.fn.dataTable.pipeline( {
url: '<?= route_to('dataTableOfPedidos') ?>',
method: 'POST',
data: {
estado: "<?= $estadoPedidos ?>",
},
headers: {'X-Requested-With': 'XMLHttpRequest'},
async: true,
}),
columnDefs: [
{
orderable: false,
searchable: false,
targets: [lastColNr]
}
],
columns : [
{ 'data': 'id' },
{ 'data': 'fecha' },
{ 'data': 'fecha_entrega' },
{ 'data': 'cliente' },
{ 'data': 'comercial' },
{ 'data': 'titulo' },
{ 'data': 'ubicacion' },
{ 'data': 'inc_rei' },
{ 'data': 'paginas' },
{ 'data': 'tirada' },
{ 'data': 'total_presupuesto' },
{ 'data': 'estado',
render: function(data, type, row, meta) {
switch(data){
case "validacion":
return '<?= lang('Pedidos.validacion') ?>';
break;
case "produccion":
return '<?= lang('Pedidos.produccion') ?>';
break;
case "finalizado":
return '<?= lang('Pedidos.finalizado') ?>';
break;
case "enviado":
return '<?= lang('Pedidos.enviado') ?>';
break;
case "cancelado":
return '<?= lang('Pedidos.cancelado') ?>';
break;
default:
return data; // Debug
break;
}
}
},
{ 'data': actionBtns }
]
});
theTable.on( 'draw.dt', function () {
const boolCols = [];
for (let coln of boolCols) {
theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) {
cell.innerHTML = cell.innerHTML == '1' ? '<i class="ti ti-check"></i>' : '';
});
}
});
$(document).on('click', '.btn-edit', function(e) {
var url = '<?= route_to('editarPedido', ':id') ?>';
url = url.replace(':id', `${$(this).attr('data-id')}` );
window.location.href = url;
});
<?=$this->endSection() ?>
<?=$this->section('css') ?>
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<?=$this->endSection() ?>
<?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<?=$this->endSection() ?>

View File

@ -117,10 +117,10 @@
</a>
</li>
<?php endif; ?>
<?php if (count(getArrayItem($temp, 'methods', 'manuales', true)) > 0): ?>
<?php if (count(getArrayItem($temp, 'methods', 'todos', true)) > 0): ?>
<li class="menu-item">
<a href="<?= site_url("pedidos/pedido/manuales") ?>" class="menu-link">
<div data-i18n="<?= lang("App.menu_pedidos_manuales") ?>"><?= lang("App.menu_pedidos_manuales") ?></div>
<a href="<?= site_url("pedidos/pedido/todos") ?>" class="menu-link">
<div data-i18n="<?= lang("App.menu_pedidos_todos") ?>"><?= lang("App.menu_pedidos_todos") ?></div>
</a>
</li>
<?php endif; ?>

View File

@ -138,10 +138,10 @@
</a>
</li>
<?php endif; ?>
<?php if (count(getArrayItem($temp, 'methods', 'manuales', true)) > 0): ?>
<?php if (count(getArrayItem($temp, 'methods', 'todos', true)) > 0): ?>
<li class="menu-item">
<a href="<?= site_url("pedidos/pedido/manuales") ?>" class="menu-link">
<div data-i18n="<?= lang("App.menu_pedidos_manuales") ?>"><?= lang("App.menu_pedidos_manuales") ?></div>
<a href="<?= site_url("pedidos/pedido/todos") ?>" class="menu-link">
<div data-i18n="<?= lang("App.menu_pedidos_todos") ?>"><?= lang("App.menu_pedidos_todos") ?></div>
</a>
</li>
<?php endif; ?>

View File

@ -27,8 +27,8 @@ if (auth()->user()->inGroup('beta')) {
</a>
</li>
<li class="menu-item">
<a href="<?= site_url("pedidos/pedido/manuales") ?>" class="menu-link">
<?= lang("App.menu_pedidos_manuales") ?>
<a href="<?= site_url("pedidos/pedido/todos") ?>" class="menu-link">
<?= lang("App.menu_pedidos_todos") ?>
</a>
</li>
</ul>