Editar credito

This commit is contained in:
Juan Pablo Vial
2024-02-15 18:57:56 -03:00
parent 1621d6fe30
commit 51cabee824
10 changed files with 383 additions and 15 deletions

View File

@ -31,6 +31,9 @@ $app->group('/venta/{venta_id:[0-9]+}', function($app) {
$app->group('/escritura', function($app) { $app->group('/escritura', function($app) {
$app->get('/add[/]', [Ventas\Escrituras::class, 'add']); $app->get('/add[/]', [Ventas\Escrituras::class, 'add']);
}); });
$app->group('/credito', function($app) {
$app->get('[/]', [Ventas\Creditos::class, 'show']);
});
$app->get('/escriturar[/]', [Ventas::class, 'escriturar']); $app->get('/escriturar[/]', [Ventas::class, 'escriturar']);
$app->get('/desistir[/]', [Ventas::class, 'desistir']); $app->get('/desistir[/]', [Ventas::class, 'desistir']);
$app->get('/desistida[/]', [Ventas::class, 'desistida']); $app->get('/desistida[/]', [Ventas::class, 'desistida']);

View File

@ -30,6 +30,9 @@ $app->group('/venta/{venta_id}', function($app) {
$app->group('/escritura', function($app) { $app->group('/escritura', function($app) {
$app->post('/add[/]', [Ventas\Escrituras::class, 'add']); $app->post('/add[/]', [Ventas\Escrituras::class, 'add']);
}); });
$app->group('/credito', function($app) {
$app->post('[/]', [Ventas\Creditos::class, 'edit']);
});
$app->post('/escriturar[/]', [Ventas::class, 'escriturar']); $app->post('/escriturar[/]', [Ventas::class, 'escriturar']);
$app->group('/desistir', function($app) { $app->group('/desistir', function($app) {
$app->get('/eliminar[/]', [Ventas::class, 'insistir']); $app->get('/eliminar[/]', [Ventas::class, 'insistir']);

View File

@ -0,0 +1,294 @@
@extends('ventas.base')
@section('venta_subtitle')
Crédito
@endsection
@section('venta_content')
@php($credito = $venta->formaPago()->credito)
<div class="ui grid">
<div class="row">
<div class="two wide column">Fecha</div>
<div class="six wide column" id="fecha" data-status="static">
<span id="fecha_data">
{{$credito->pago->fecha->format('d-m-Y')}}
</span>
<a href="#" id="fecha_edit">
<i class="edit icon"></i>
</a>
<div class="ui calendar hidden" id="fecha_input">
<div class="ui left icon input">
<i class="calendar icon"></i>
<input type="text" name="fecha" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">Banco</div>
<div class="six wide column" id="banco" data-status="static">
<span id="banco_data">
@if (isset($credito->pago->banco))
{{$credito->pago->banco->nombre}}
@else
No definido
@endif
</span>
<a href="#" id="banco_edit">
<i class="edit icon"></i>
</a>
<div class="ui search selection dropdown hidden" id="banco_input">
<input type="hidden" name="banco" />
<i class="dropdown icon"></i>
<div class="default text">Banco</div>
<div class="menu">
@foreach ($bancos as $banco)
<div class="item" data-value="{{$banco->id}}">{{$banco->nombre}}</div>
@endforeach
</div>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">Valor</div>
<div class="six wide column" id="valor" data-status="static">
<span id="valor_data">
{{$format->ufs($credito->pago->valor())}}
</span>
<a href="#" id="valor_edit">
<i class="edit icon"></i>
</a>
<div class="ui right labeled input hidden" id="valor_input">
<input type="text" name="valor" />
<div class="ui basic label">UF</div>
</div>
</div>
</div>
</div>
@endsection
@push('page_styles')
<style>
.hidden {
display: none !important;
}
</style>
@endpush
@push('page_scripts')
<script>
const credito = {
ids: {},
data: {
venta: {{$venta->id}},
credito: {{$credito->id}},
fecha: new Date({{$credito->pago->fecha->format('Y')}},
{{$credito->pago->fecha->format('m')}}+1,
{{$credito->pago->fecha->format('d')}}),
banco: {
@if (isset($credito->pago->banco))
id: {{$credito->pago->banco->id}},
nombre: '{{$credito->pago->banco->nombre}}'
@else
id: 0,
nombre: ''
@endif
},
valor: {{$credito->pago->valor()}},
bancos: JSON.parse('{!! json_encode($bancos) !!}')
},
elements: {},
change() {
return {
status: (id, status) => {
this.elements[id].dataset.status = status
}
}
},
hide() {
return {
data: id => {
this.elements[id + '.data'].innerHTML = ''
this.elements[id + '.data'].classList.add('hidden')
this.elements[id + '.data'].hidden = true
},
input: id => {
this.elements[id + '.input'].classList.add('hidden')
this.elements[id + '.input'].hidden = true
}
}
},
show() {
return {
data: id => {
this.elements[id + '.data'].classList.remove('hidden')
this.elements[id + '.data'].hidden = false
},
input: id => {
this.elements[id + '.input'].classList.remove('hidden')
this.elements[id + '.input'].hidden = false
}
}
},
draw() {
return {
edit: (id) => {
this.change().status(id, 'edit')
this.show().input(id)
this.update()[id]()
},
static: (id, text) => {
this.change().status(id, 'static')
this.hide().input(id)
this.elements[this.ids.fields[id] + '.data'].innerHTML = this.format()[id](text)
}
}
},
send(id, value) {
const url = '{{$urls->api}}/venta/{{$venta->id}}/credito'
const body = new FormData()
body.set(id, value)
return fetchAPI(url, {method: 'post', body}).then(response => {
if (!response) {
return
}
return response.json().then(json => {
if (!json.status) {
return
}
this.data.fecha = new Date(json.credito.pago.fecha)
this.data.banco.id = json.credito.pago.banco.id
this.data.banco.nombre = json.credito.pago.banco.nombre
this.data.valor = json.credito.pago.valor / json.credito.pago.uf
})
})
},
edit() {
return {
fecha: fecha => {
this.send('fecha', fecha).then(() => {
this.draw().static('fecha', this.data.fecha)
})
},
banco: banco_id => {
this.send('banco', banco_id).then(() => {
this.draw().static('banco', this.data.banco.nombre)
})
},
valor: valor => {
this.send('valor', valor).then(() => {
this.draw().static('valor', this.data.valor)
})
}
}
},
format() {
return {
fecha: value => {
const dateFormatter = new Intl.DateTimeFormat('es-CL', {year: 'numeric', month: 'numeric', day: 'numeric'})
return dateFormatter.format(value)
},
banco: value => {
if (value === '') {
value = 'No definido'
}
return value
},
valor: value => {
const numberFormatter = new Intl.NumberFormat('es-CL', {minimumFractionDigits: 2, maximumFractionDigits: 2})
return numberFormatter.format(value) + ' UF'
}
}
},
update() {
return {
fecha: () => {
const $fecha = $(this.elements.fecha.querySelector('div.ui.calendar'))
$fecha.calendar('set date', this.data.fecha)
$fecha.calendar('focus')
},
banco: () => {
const $dropdown = $(this.elements.banco.querySelector('div.ui.dropdown'))
$dropdown.dropdown('clear')
if (this.data.banco.id !== 0) {
$dropdown.dropdown('set selected', this.data.banco.id)
}
$dropdown.dropdown('toggle')
},
valor: () => {
const input = this.elements.valor.querySelector('input')
input.value = this.data.valor ?? ''
input.focus()
}
}
},
watch(id) {
this.elements[id + '.edit'].addEventListener('click', event => {
const elem = event.currentTarget.parentNode
const id = elem.id
const status = elem.dataset.status
if (status !== 'static') {
return
}
this.draw().edit(id)
})
},
register(name, elem_id) {
this.elements[name] = document.getElementById(elem_id)
},
setup(ids) {
this.ids = ids
Object.entries(this.ids.fields).forEach(entry => {
const name = entry[0]
const field = entry[1]
this.register(name, field)
this.register(name + '.data', field + '_data')
this.register(name + '.input', field + '_input')
this.register(name + '.edit', field + '_edit')
this.watch(field)
})
calendar_date_options['onChange'] = (date, text, mode) => {
if (date === this.data.fecha) {
return
}
this.edit().fecha([date.getFullYear(), date.getMonth()+1, date.getDate()].join('-'))
}
calendar_date_options['onHide'] = () => {
this.draw().static('fecha', this.data.fecha)
}
$(this.elements.fecha).find('div.ui.calendar').calendar(calendar_date_options)
$(this.elements.banco).find('div.ui.dropdown').dropdown({
onChange: (value, text, $element) => {
if (value === '' || value === this.data.banco.id) {
return
}
this.edit().banco(value)
},
onHide: () => {
this.draw().static('banco', this.data.banco.nombre)
}
})
this.elements.valor.querySelector('input').addEventListener('blur', event => {
let valor = event.currentTarget.value
if (valor.includes(',')) {
valor = valor.replaceAll('.', '').replace(',', '.')
}
if (parseFloat(valor) === this.data.valor) {
this.draw().static('valor', this.data.valor)
return
}
this.edit().fecha(valor)
})
}
}
$(document).ready(() => {
credito.setup({
fields: {
fecha: 'fecha',
banco: 'banco',
valor: 'valor'
}
})
})
</script>
@endpush

View File

@ -0,0 +1,31 @@
<?php
namespace Incoviba\Controller\API\Ventas;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Ideal\Controller;
use Incoviba\Controller\API\withJson;
use Incoviba\Service;
class Creditos extends Controller
{
use withJson;
public function edit(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
Service\Venta\Credito $creditoService, int $venta_id): ResponseInterface
{
$body = $request->getParsedBody();
$output = [
'input' => $body,
'credito' => null,
'status' => false
];
try {
$venta = $ventaService->getById($venta_id);
$output['credito'] = $creditoService->edit($venta->formaPago()->credito, $body);
$output['status'] = true;
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Incoviba\Controller\Ventas;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Alias\View;
use Incoviba\Common\Ideal\Controller;
use Incoviba\Repository;
class Creditos extends Controller
{
public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
Repository\Venta $ventaRepository, Repository\Banco $bancoRepository,
int $venta_id): ResponseInterface
{
$venta = $ventaRepository->fetchById($venta_id);
$bancos = $bancoRepository->fetchAll('nombre');
return $view->render($response, 'ventas.creditos', compact('venta', 'bancos'));
}
}

View File

@ -14,7 +14,7 @@ class Pie extends Model
public ?Pie $asociado; public ?Pie $asociado;
public ?Pago $reajuste; public ?Pago $reajuste;
public array $cuotasArray; public array $cuotasArray = [];
public function cuotas(bool $pagadas = false, bool $vigentes = false): array public function cuotas(bool $pagadas = false, bool $vigentes = false): array
{ {
if ($this->asociado !== null) { if ($this->asociado !== null) {

View File

@ -159,15 +159,6 @@ class Venta extends Ideal\Repository
->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado') ->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
->where('ptu.proyecto = ? AND tev.activa') ->where('ptu.proyecto = ? AND tev.activa')
->group('a.id'); ->group('a.id');
/*$query = "SELECT a.*
FROM `{$this->getTable()}` a
JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`
JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1
JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`
JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`
JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`
WHERE ptu.`proyecto` = ? AND tev.`activa`
GROUP BY a.`id`";*/
return $this->fetchMany($query, [$proyecto_id]); return $this->fetchMany($query, [$proyecto_id]);
} }
public function fetchIdsByProyecto(int $proyecto_id): array public function fetchIdsByProyecto(int $proyecto_id): array

View File

@ -17,7 +17,7 @@ class Credito extends Ideal\Repository
public function create(?array $data = null): Model\Venta\Credito public function create(?array $data = null): Model\Venta\Credito
{ {
$map = (new Implement\Repository\MapperParser()) $map = (new Implement\Repository\MapperParser(['valor']))
->register('pago', (new Implement\Repository\Mapper()) ->register('pago', (new Implement\Repository\Mapper())
->setFunction(function($data) { ->setFunction(function($data) {
return $this->pagoService->getById($data['pago']); return $this->pagoService->getById($data['pago']);

View File

@ -209,8 +209,8 @@ class Tesoreria extends Ideal\Service
'cuenta' => $deposito->cuenta, 'cuenta' => $deposito->cuenta,
'fecha' => $deposito->termino, 'fecha' => $deposito->termino,
'cargo' => 0, 'cargo' => 0,
'abono' => $deposito->futuro, 'abono' => $deposito->capital,
'saldo' => $deposito->futuro, 'saldo' => $deposito->capital,
'glosa' => 'RESCATE DAP' 'glosa' => 'RESCATE DAP'
]]); ]]);
} }

View File

@ -2,20 +2,25 @@
namespace Incoviba\Service\Venta; namespace Incoviba\Service\Venta;
use DateTimeImmutable; use DateTimeImmutable;
use Incoviba\Common\Ideal\Service;
use Incoviba\Repository; use Incoviba\Repository;
use Incoviba\Model; use Incoviba\Model;
use Incoviba\Service\Money; use Incoviba\Service\Money;
use Psr\Log\LoggerInterface;
class Credito class Credito extends Service
{ {
public function __construct( public function __construct(
LoggerInterface $logger,
protected Repository\Venta\Credito $creditoRepository, protected Repository\Venta\Credito $creditoRepository,
protected Repository\Venta\Pago $pagoRepository, protected Repository\Venta\Pago $pagoRepository,
protected Repository\Venta\TipoPago $tipoPagoRepository, protected Repository\Venta\TipoPago $tipoPagoRepository,
protected Repository\Venta\EstadoPago $estadoPagoRepository, protected Repository\Venta\EstadoPago $estadoPagoRepository,
protected Repository\Venta\TipoEstadoPago $tipoEstadoPagoRepository, protected Repository\Venta\TipoEstadoPago $tipoEstadoPagoRepository,
protected Money $moneyService protected Money $moneyService
) {} ) {
parent::__construct($logger);
}
public function add(array $data): Model\Venta\Credito public function add(array $data): Model\Venta\Credito
{ {
@ -30,6 +35,27 @@ class Credito
]); ]);
return $this->creditoRepository->save($credito); return $this->creditoRepository->save($credito);
} }
public function edit(Model\Venta\Credito $credito, array $data): Model\Venta\Credito
{
$uf = $this->moneyService->getUF($credito->pago->fecha);
if (array_key_exists('fecha', $data)) {
$fecha = new DateTimeImmutable($data['fecha']);
$data['fecha'] = $fecha->format('Y-m-d');
$uf = $this->moneyService->getUF($fecha);
$data['uf'] = $uf;
}
if (array_key_exists('valor', $data)) {
$data['valor'] = round(((float) $data['valor']) * $uf);
}
$filteredData = array_intersect_key($data, array_fill_keys([
'fecha',
'uf',
'valor',
'banco'
], 0));
$credito->pago = $this->pagoRepository->edit($credito->pago, $filteredData);
return $this->creditoRepository->edit($credito, $filteredData);
}
protected function addPago(array $data): Model\Venta\Pago protected function addPago(array $data): Model\Venta\Pago
{ {
$pago = $this->pagoRepository->create($data); $pago = $this->pagoRepository->create($data);