añadida tabla de credito al presupuesto

This commit is contained in:
2025-03-29 11:31:03 +01:00
parent 8d289fde15
commit d1a9aaac77
10 changed files with 250 additions and 20 deletions

View File

@ -418,6 +418,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$this->model->removeIsDuplicado($presupuestoEntity->id);
}
$this->viewData['credito'] = model('App\Models\Clientes\ClienteModel')->getResumenPagos($presupuestoEntity->cliente_id);
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . $this->viewData['pageTitle'] . ' ' . lang('Basic.global.edit3');
return $this->displayForm(__METHOD__, $id);

View File

@ -29,13 +29,14 @@ class Test extends BaseController
}
private function index()
public function index()
{
$this->emailService = service('emailService');
$clienteModel = model('App\Models\Clientes\ClienteModel');
$datos = $clienteModel->getResumenPagos(1870);
echo '<pre>';
var_dump($datos);
echo '</pre>';
$a= $this->emailService->send('prueba', 'Esto es una prueba', ['imnavajas@coit.es','imnavajas@gmail.com']);
echo var_dump($a);
}

View File

@ -332,6 +332,8 @@ return [
'tiradaImpresion' => 'Coste Impresión',
'duplicado' => 'DUPLICADO',
'credito' => 'Crédito',
'duplicarConTipologias' => 'El presupuesto contiene lineas de presupuesto con datos de tipologías. Se va a duplicar el presupuesto con las mismas tipologías',
'presupuestoDuplicadoActualizacion' => 'El presupuesto ha sido creado duplicando un presupuesto existente. Se han actualizado los precios y las líneas de presupuesto con las tarifas actuales. Por favor, revíse la información.',

View File

@ -498,4 +498,97 @@ class ClienteModel extends \App\Models\BaseModel
return 0;
}
}
public function getResumenPagos($cliente_id = -1){
$result = [];
$data = $this->db->table('facturas f')
->select('sum(f.total)-sum(f.pendiente) as total')
->where('f.cliente_id', $cliente_id)
->where('f.deleted_at IS NULL')
->where('f.estado_pago', 'pendiente')
->get()
->getResultObject();
$result['total_facturas_sin_pagar'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
$data = $this->db->table('facturas_pagos fp')
->select('sum(fp.total) as total')
->join('facturas f', 'fp.factura_id = f.id', 'left')
->where('f.cliente_id', $cliente_id)
->where('f.estado_pago', 'pendiente')
->where('fp.fecha_pago_at IS NOT NULL')
->where('fp.deleted_at IS NULL')
->where('f.deleted_at IS NULL')
->get()
->getResultObject();
$result['total_facturas_pagadas'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
$data = $this->db->table('facturas f')
->select('sum(fp.total) as total')
->join('facturas_pagos fp', 'fp.factura_id = f.id', 'left')
->where('f.cliente_id', $cliente_id)
->where('f.estado_pago', 'pendiente')
->where('fp.fecha_vencimiento_at <', date('Y-m-d'))
->where('fp.fecha_pago_at IS NULL')
->where('f.deleted_at IS NULL')
->where('fp.deleted_at IS NULL')
->get()
->getResultObject();
$result['total_facturas_vencidas'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
// Subconsulta para verificar la existencia en facturas_lineas
$subquery_facturas = "(SELECT 1
FROM facturas_lineas fl
JOIN facturas f2 ON fl.factura_id = f2.id
WHERE (fl.pedido_linea_impresion_id = p.id OR fl.pedido_maquetacion_id = p.id)
AND f2.estado = 'validada')";
// Subconsulta para calcular el total de pedidos en produccion
$data = $this->db->table('pedidos p')
->select('SUM(p.total_precio) as total', false)
->join('pedidos_linea pl', 'p.id = pl.pedido_id', 'left')
->join('presupuestos pr', 'pl.presupuesto_id = pr.id', 'left')
->where('pr.cliente_id', $cliente_id)
->whereIn('p.estado', ['produccion'])
->where("NOT EXISTS $subquery_facturas", null, false) // Implementación manual de NOT EXISTS
->get()
->getResultObject();
$result['total_pedidos_produccion'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
// Subconsulta para calcular el total de pedidos finalizados
$data = $this->db->table('pedidos p')
->select('SUM(p.total_precio) as total', false)
->join('pedidos_linea pl', 'p.id = pl.pedido_id', 'left')
->join('presupuestos pr', 'pl.presupuesto_id = pr.id', 'left')
->where('pr.cliente_id', $cliente_id)
->whereIn('p.estado', ['finalizado', 'enviado'])
->where("NOT EXISTS $subquery_facturas", null, false) // Implementación manual de NOT EXISTS
->get()
->getResultObject();
$result['total_pedidos_finalizados'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
$result['total_pendiente'] =
$result['total_facturas_sin_pagar']
- $result['total_facturas_pagadas']
+ $result['total_pedidos_produccion']
+ $result['total_pedidos_finalizados'];
$result['total_pendiente'] = round(floatval($result['total_pendiente']), 2);
$result['limite_credito'] = $this->db->table('clientes')
->select('limite_credito')
->where('id', $cliente_id)
->where('is_deleted', 0)
->get()
->getResultObject()[0]->limite_credito;
$result['limite_credito'] = round(floatval($result['limite_credito']), 2);
$result['margen_disponible'] = round(floatval( $result['limite_credito']-$result['total_pendiente']), 2);
return $result;
}
}

View File

@ -22,8 +22,12 @@
<tbody></tbody>
<tfoot>
<tr>
<td colspan="6" style="text-align:right">Total:</td>
<td id="totalCobrado-sum"></td>
<td colspan="6" style="text-align:right">Total cobrado:</td>
<td><span id="totalCobrado-sum" class="autonumeric"></span></td>
</tr>
<tr>
<td colspan="6" style="text-align:right">Total pendiente:</td>
<td><span id="pendienteCobro-sum" class="autonumeric"></span></td>
</tr>
</tfoot>
</table>
@ -225,21 +229,38 @@ var tablePagos = $('#tableOfLineasPagos').DataTable({
footerCallback: function (row, data, start, end, display) {
var api = this.api();
// Remove the formatting to get integer data for summation
var intVal = function (i) {
// Convertir a número o devolver 0 si no es válido
return typeof i === 'string' ? i.replace(/[\$,]/g, '')*1 : typeof i === 'number' ? i : 0;
};
// Total over all pages
var totalPagos = api
.column(6)
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
var filas = [];
api.rows().every(function() {
var data = this.data();
if (data['fecha_pago_at'] !== undefined && data['fecha_pago_at'] !== null && data['fecha_pago_at'] !== '') {
filas.push(data); // Agregar la fila a la variable
}
});
var totalPagos = filas
.reduce(function(a, data) {
return a + intVal(data['total']); // Aquí asumimos que la columna 6 está en el índice 5
}, 0);
var filas = [];
api.rows().every(function() {
var data = this.data();
if (data['fecha_pago_at'] === undefined || data['fecha_pago_at'] === null || data['fecha_pago_at'] === '') {
filas.push(data); // Agregar la fila a la variable
}
});
var totalPendiente = filas
.reduce(function(a, data) {
return a + intVal(data['total']); // Aquí asumimos que la columna 6 está en el índice 5
}, 0);
// Update footer
$('#totalCobrado-sum').html(totalPagos.toFixed(2));
$('#pendienteCobro-sum').html(totalPendiente.toFixed(2));
// call footerCallback of the other table
if (typeof tableLineas !== 'undefined') {

View File

@ -0,0 +1,99 @@
<div class="accordion accordion-bordered mt-3 col-xl-6 " id="accordionCredito">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingOne">
<button type="button" class="accordion-button" data-bs-toggle="collapse"
data-bs-target="#accordionCreditoTip" aria-expanded="false" aria-controls="accordionCreditoTip">
<h4><?= lang("Presupuestos.credito") ?></h4>
</button>
</h2>
<div id="accordionCreditoTip" class="accordion-collapse collapse show" data-bs-parent="#accordionCredito">
<div class="accordion-body">
<div class="col-xl-12">
<div class="table-responsive text-nowrap">
<table class="table table-bordered">
<tbody>
<tr>
<td><?= lang('Presupuestos.clienteId') ?></td>
<td>
<button type="button" class="btn btn-label-primary waves-effect"
onclick="<?= route_to('editarCliente', $presupuestoEntity->cliente_id) ?>">
Ir a cliente</button>
</td>
</tr>
<tr>
<td>Facturas sin pagar: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_facturas_sin_pagar'] ?>
</span>
</td>
</tr>
<tr>
<td>Facturas pagadas: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_facturas_pagadas'] ?>
</span>
</td>
</tr>
<tr>
<td>Pagos vencidos: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_facturas_vencidas'] ?>
</span>
</td>
</tr>
<tr>
<td>Pedidos produccion: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_pedidos_produccion'] ?>
</span>
</td>
</tr>
<tr>
<td>Pedidos finalizados: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_pedidos_finalizados'] ?>
</span>
</td>
</tr>
<tr>
<td>Total pendiente: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['total_pendiente'] ?>
</span>
</td>
</tr>
<tr>
<td>Límite crédito: </td>
<td class="right">
<span class="autonumeric autonumeric-currency">
<?= $credito['limite_credito'] ?>
</span>
</td>
</tr>
<tr>
<td><span class="fw-bold">Margen disponible:</span></td>
<td class="right">
<span class="autonumeric autonumeric-currency fw-bold
<?= $credito['margen_disponible'] < 0 ? 'text-danger' : 'text-success' ?>">
<?= $credito['margen_disponible'] ?>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div> <!-- //.accordion-body -->
</div> <!-- //.accordion-collapse -->
</div> <!-- //.accordion-item -->
</div> <!-- //.accordion -->

View File

@ -1,4 +1,4 @@
<div class="accordion accordion-bordered mt-3 col-xl-4" id="accordionResumen">
<div class="accordion accordion-bordered mt-3" id="accordionResumen">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingOne">
<button type="button" class="accordion-button" data-bs-toggle="collapse"

View File

@ -1,4 +1,4 @@
<div class="accordion accordion-bordered mt-3 col-xl-8" id="accordionTiradas">
<div class="accordion accordion-bordered mt-3" id="accordionTiradas">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingOne">
<button type="button" class="accordion-button" data-bs-toggle="collapse"

View File

@ -66,9 +66,17 @@
<?php if ($presupuestoEntity->estado_id == 2) : ?>
<?= view("themes/vuexy/components/dropzone",data: ['id' => 'dropzone-presupuesto-admin-files','modelId' => $presupuestoId]) ?>
<?php endif ?>
<div class="container">
<div class="row px-0">
<div class="col-xl-4" style="padding-left: 0;">
<?= view("themes/vuexy/form/presupuestos/admin/_resumenPresupuestoItems") ?>
</div>
<div class="col-xl-8" style="padding-right: 0;">
<?= view("themes/vuexy/form/presupuestos/admin/_tiradasAlternativasItems") ?>
<?= view("themes/vuexy/form/presupuestos/admin/_resumenCreditoItems") ?>
</div>
</div>
</div>
<?php else: ?>
<input type="hidden" name="total_presupuesto" id="total_presupuesto" class="form-control"
value="0.0"></input>

View File

@ -80,6 +80,10 @@ class PresupuestoAdminEdit {
document.querySelector('.select2-search__field').focus();
});
// Autonumeric
AutoNumeric.multiple('.autonumeric-currency', { decimalPlaces: 2, currencySymbol: '€', currencySymbolPlacement: 's', digitGroupSeparator: '.', decimalCharacter: ',' });
AutoNumeric.multiple('.autonumeric-percent', { decimalPlaces: 2, currencySymbol: '%', currencySymbolPlacement: 's', digitGroupSeparator: '.', decimalCharacter: ',' });
const impresion_id = $('#tipo_impresion_id').val();
let tipoLibro = '';
if (impresion_id == 1 || impresion_id == 2) {