Move to add date

This commit is contained in:
Juan Pablo Vial
2025-11-25 11:45:52 -03:00
parent 07a1607554
commit c9056451eb
3 changed files with 215 additions and 57 deletions

View File

@ -33,12 +33,12 @@
<label for="proyecto">Proyecto</label> <label for="proyecto">Proyecto</label>
<div class="four wide field"> <div class="four wide field">
<div class="ui fluid search selection dropdown" id="proyecto"> <div class="ui fluid search selection dropdown" id="proyecto">
<input type="hidden" name="proyecto" /> <input type="hidden" name="proyecto" value="{{ $proyecto_id ?? '' }}" />
<i class="dropdown icon"></i> <i class="dropdown icon"></i>
<div class="default text">Proyecto</div> <div class="default text">Proyecto</div>
<div class="menu"> <div class="menu">
@foreach($proyectos as $proyecto) @foreach($proyectos as $proyecto)
<div class="item" data-value="{{$proyecto->id}}">{{$proyecto->descripcion}}</div> <div class="item {{ (isset($proyecto_id) && $proyecto_id == $proyecto->id) ? 'active selected' : '' }}" data-value="{{$proyecto->id}}">{{$proyecto->descripcion}}</div>
@endforeach @endforeach
</div> </div>
</div> </div>
@ -68,7 +68,7 @@
<label for="valor">Valor</label> <label for="valor">Valor</label>
<div class="inline field"> <div class="inline field">
<div class="ui right labeled input"> <div class="ui right labeled input">
<input type="text" name="valor" id="valor" required /> <input type="text" name="valor" id="valor" value="{{ $valor ?? '' }}" required />
<div class="ui label">UF</div> <div class="ui label">UF</div>
</div> </div>
</div> </div>
@ -807,60 +807,105 @@
console.error(errors) console.error(errors)
} }
$(document).ready(() => { const venta = {
const cdo = structuredClone(calendar_date_options) ids: {
cdo['maxDate'] = new Date() form: ''
$('#fecha_venta_calendar').calendar(cdo) },
new Propietario({id: '#propietario', id_tipo: 'persona_propietario', id_cantidad: 'cantidad_propietario'}) components: {
new Proyecto({unidades_id: '#unidades', proyecto_id: '#proyecto'}) date: null,
project: null,
const payments = [ buyer: null,
'pie', payments: [],
'subsidio', $form: null
'credito', },
'bono_pie' setup({dateId, buyerId, buyerTypeId, buyerNId, unitsId, projectId, fromReservation = false}) {
] this.ids = {
payments.forEach(payment => { dateId,
new Payment({ buyerId,
id: '#' + payment, buyerTypeId,
checkbox_id: 'has_' + payment buyerNId,
}) unitsId,
}) projectId
$('#add_form').submit(event => {
event.preventDefault()
const button = $(event.currentTarget).find(".ui.button[type='submit']")
button.prop('disabled', true)
button.css('cursor', 'wait')
const body = new FormData(event.currentTarget)
const unidades = event.currentTarget.querySelectorAll("[name^='unidad']")
const emptyUnidades = []
unidades.forEach(unidad => {
if (unidad.value.trim() === '') {
emptyUnidades.push(unidad)
body.delete(unidad.name)
}
})
if (unidades.length === emptyUnidades.length) {
alert("No hay unidades seleccionadas")
return;
} }
const uri = '{{$urls->api}}/ventas/add'
return fetchAPI(uri, {method: 'post', body}).then(response => { this.components.$date = $(dateId)
if (!response) { const cdo = structuredClone(calendar_date_options)
return false cdo['maxDate'] = new Date()
} this.components.$date.calendar(cdo)
return response.json().then(data => {
if (data.status) { this.components.project = new Proyecto({unidades_id: unitsId, proyecto_id: projectId})
window.location = '{{$urls->base}}/venta/' + data.venta_id this.components.buyer = new Propietario({id: buyerId, id_tipo: buyerTypeId, id_cantidad: buyerNId})
return true
const payments = [
'pie',
'subsidio',
'credito',
'bono_pie'
]
payments.forEach(payment => {
this.components.payments.push(new Payment({
id: '#' + payment,
checkbox_id: 'has_' + payment
}))
})
this.components.$form = $(this.ids.form)
this.components.$form.submit(event => {
event.preventDefault()
const button = $(event.currentTarget).find(".ui.button[type='submit']")
button.prop('disabled', true)
button.css('cursor', 'wait')
const body = new FormData(event.currentTarget)
const unidades = event.currentTarget.querySelectorAll("[name^='unidad']")
const emptyUnidades = []
unidades.forEach(unidad => {
if (unidad.value.trim() === '') {
emptyUnidades.push(unidad)
body.delete(unidad.name)
} }
button.prop('disabled', false) })
button.css('cursor', 'pointer') if (unidades.length === emptyUnidades.length) {
showErrors(data.errors) alert("No hay unidades seleccionadas")
return false return;
}
const uri = '{{$urls->api}}/ventas/add'
return APIClient.fetch(uri, {method: 'post', body}).then(response => {
if (!response) {
return false
}
return response.json().then(data => {
if (data.status) {
window.location = '{{$urls->base}}/venta/' + data.venta_id
return true
}
button.prop('disabled', false)
button.css('cursor', 'pointer')
showErrors(data.errors)
return false
})
}) })
}) })
if (fromReservation) {
const date = new Date('{{ $date?->format('Y-m-d') }}')
date.setDate(date.getDate() + 1)
this.components.$date.calendar('set date', date)
$(this.ids.projectId).dropdown('set selection', {{ $proyecto_id }})
}
}
}
$(document).ready(() => {
const fromReservation = '{{ $fromReservation ?? false }}'
venta.setup({
dateId: '#fecha_venta_calendar',
buyerId: '#propietario',
buyerTypeId: 'persona_propietario',
buyerNId: 'cantidad_propietario',
unitsId: '#unidades',
projectId: '#proyecto',
fromReservation: fromReservation === 'true'
}) })
}) })
</script> </script>

View File

@ -562,6 +562,60 @@
reservations.components.modals.edit.show({type: 'active', reservation_id: id}) reservations.components.modals.edit.show({type: 'active', reservation_id: id})
return false return false
}, },
promise: event => {
event.preventDefault()
const reservationId = event.currentTarget.dataset.id
const reservation = this.find(reservationId)
// Create a form to submit the data via POST
const form = document.createElement('form')
form.method = 'POST'
form.action = '{{ $urls->base }}/ventas/add'
// Add CSRF token
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
const csrfInput = document.createElement('input')
csrfInput.type = 'hidden'
csrfInput.name = '_token'
csrfInput.value = csrfToken
form.appendChild(csrfInput)
// Add reservation data
const addInput = (name, value) => {
if (value) {
const input = document.createElement('input')
input.type = 'hidden'
input.name = name
input.value = value
form.appendChild(input)
}
}
addInput('from_reservation', 'true')
addInput('reservation_id', reservationId)
if (reservation.cliente) {
addInput('cliente_nombre', reservation.cliente.nombre)
addInput('cliente_rut', reservation.cliente.rut)
addInput('cliente_email', reservation.cliente.email)
addInput('cliente_telefono', reservation.cliente.telefono)
}
if (reservation.propiedad) {
addInput('proyecto_id', reservation.propiedad.proyecto_id)
// Add other property-related parameters as needed
}
if (reservation.oferta) {
addInput('valor', reservation.oferta.valor)
// Add other offer-related parameters as needed
}
// Submit the form
document.body.appendChild(form)
form.submit()
return false
},
remove: event => { remove: event => {
event.preventDefault() event.preventDefault()
const reservation_id = event.currentTarget.dataset.id const reservation_id = event.currentTarget.dataset.id

View File

@ -1,6 +1,10 @@
<?php <?php
namespace Incoviba\Controller; namespace Incoviba\Controller;
use Exception;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
use Incoviba\Common\Alias\View; use Incoviba\Common\Alias\View;
use Incoviba\Common\Implement\Exception\EmptyRedis; use Incoviba\Common\Implement\Exception\EmptyRedis;
use Incoviba\Common\Implement\Exception\EmptyResult; use Incoviba\Common\Implement\Exception\EmptyResult;
@ -10,8 +14,6 @@ use Incoviba\Exception\ServiceAction\Update;
use Incoviba\Model; use Incoviba\Model;
use Incoviba\Repository; use Incoviba\Repository;
use Incoviba\Service; use Incoviba\Service;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class Ventas class Ventas
{ {
@ -91,14 +93,71 @@ class Ventas
return $view->render($response, 'ventas.pies.edit', compact('venta')); return $view->render($response, 'ventas.pies.edit', compact('venta'));
} }
public function add(ServerRequestInterface $request, ResponseInterface $response, View $view, public function add(ServerRequestInterface $request, ResponseInterface $response, View $view,
Repository\Region $regionRepository, Repository\Proyecto $proyectoRepository): ResponseInterface Repository\Region $regionRepository, Repository\Proyecto $proyectoRepository,
LoggerInterface $logger,
?Service\Venta\Reservation $reservaService = null): ResponseInterface
{ {
$regiones = $regionRepository->fetchAll(); $regiones = $regionRepository->fetchAll();
usort($regiones, function(Model\Region $a, Model\Region $b) { usort($regiones, function(Model\Region $a, Model\Region $b) {
return $a->numeracion - $b->numeracion; return $a->numeracion - $b->numeracion;
}); });
$proyectos = $proyectoRepository->fetchAllActive(); $proyectos = $proyectoRepository->fetchAllActive();
return $view->render($response, 'ventas.add', compact('regiones', 'proyectos'));
$viewData = [
'regiones' => $regiones,
'proyectos' => $proyectos,
'from_reservation' => false
];
// Check if this is a conversion from a reservation
if ($request->getMethod() === 'POST') {
$data = $request->getParsedBody();
if (isset($data['from_reservation']) && $data['from_reservation'] === 'true' && !empty($data['reservation_id'])) {
try {
$reservation = $reservaService->get((int)$data['reservation_id']);
$viewData['from_reservation'] = true;
$viewData['reservation_id'] = $reservation->id;
$viewData['date'] = $reservation->date;
$viewData['comments'] = explode("\n", $reservation->comments);
$viewData['propietario_rut'] = $reservation->buyer->rut;
// Add property data
$viewData['proyecto_id'] = $reservation->project->id;
$viewData['unidades'] = [];
foreach ($reservation->units as $unitValue) {
$type = $unitValue->unit->proyectoTipoUnidad->tipoUnidad->descripcion;
if (!array_key_exists($type, $viewData['unidades'])) {
$viewData['unidades'][$type] = [];
}
$viewData['unidades'][$type] []= $unitValue->unit->id;
}
$viewData['valor'] = $reservation->offer();
if ($reservation->payment !== null) {
$viewData['forma_pago'] = [];
if ($reservation->payment->pie !== null) {
$viewData['forma_pago']['pie'] = [
'valor' => $reservation->payment->pie->valor,
'cuotas' => $reservation->payment->pie->cuotas,
];
}
if ($reservation->payment->credito !== null) {
$viewData['forma_pago']['credito'] = $reservation->payment->credito->valor;
}
}
} catch (Exception $exception) {
// Log error or handle as needed
$logger->error('Error loading reservation data', ['exception' => $exception]);
}
}
}
return $view->render($response, 'ventas.add', $viewData);
} }
public function cuotas(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, public function cuotas(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
Service\Contabilidad\Banco $bancoService, Service\Contabilidad\Banco $bancoService,