Optimizacion de monedas
This commit is contained in:
@ -4,5 +4,6 @@ use Incoviba\Controller\API\Money;
|
||||
$app->group('/money', function($app) {
|
||||
$app->post('/ipc[/]', [Money::class, 'ipc']);
|
||||
$app->post('/uf[/]', [Money::class, 'uf']);
|
||||
$app->post('/many[/]', [Money::class, 'getMany']);
|
||||
$app->post('[/]', [Money::class, 'get']);
|
||||
});
|
||||
|
@ -1,5 +1,14 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@push('page_styles')
|
||||
<style>
|
||||
#data {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<h2 class="ui header">Matriz Facturación</h2>
|
||||
@ -33,61 +42,150 @@
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
const money = {
|
||||
data: {
|
||||
ufs: {},
|
||||
ipcs: {}
|
||||
},
|
||||
ufs: {},
|
||||
ipcs: {},
|
||||
sent: {
|
||||
uf: {},
|
||||
ipc: {}
|
||||
},
|
||||
get() {
|
||||
return {
|
||||
uf: date => {
|
||||
if (typeof this.sent.uf[date.toISOString()] !== 'undefined') {
|
||||
return this.sent.uf[date.toISOString()]
|
||||
queue: {
|
||||
size: 0,
|
||||
array: () => {
|
||||
const array = []
|
||||
Object.entries(money.queue).forEach(([type, dates]) => {
|
||||
if (['uf', 'ipc'].includes(type) === false) {
|
||||
return
|
||||
}
|
||||
const url = '{{$urls->api}}/money/uf'
|
||||
const data = new FormData()
|
||||
data.set('fecha', date.toISOString())
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: data
|
||||
if (type === 'uf') {
|
||||
Object.entries(dates).forEach(([dateString, ventas]) => {
|
||||
const temp = []
|
||||
ventas.forEach(venta => {
|
||||
temp.push(venta)
|
||||
})
|
||||
array.push({
|
||||
type,
|
||||
date: dateString,
|
||||
ventas: temp
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
return this.sent.uf[date.toISOString()] = fetchAPI(url, options).then(response => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
}).then(json => {
|
||||
return this.ufs[json.input.fecha] = json.uf
|
||||
})
|
||||
},
|
||||
ipc: ({end, start}) => {
|
||||
const dateKey = [start.getFullYear(), (start.getMonth()+1), end.getFullYear(), (end.getMonth()+1)].join('-')
|
||||
if (typeof this.sent.ipc[dateKey] !== 'undefined') {
|
||||
return this.sent.ipc[dateKey]
|
||||
}
|
||||
let mult = 1
|
||||
if (start > end) {
|
||||
const tmp = structuredClone(end)
|
||||
end = structuredClone(start)
|
||||
start = tmp
|
||||
mult = -1
|
||||
}
|
||||
const url = '{{$urls->api}}/money/ipc'
|
||||
const data = new FormData()
|
||||
data.set('start', [start.getFullYear() + ((start.getMonth() > 0) ? 0 : -1), start.getMonth(), start.getDate()].join('-'))
|
||||
data.set('end', [end.getFullYear() + ((end.getMonth() > 0) ? 0 : -1), end.getMonth(), end.getDate()].join('-'))
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: data
|
||||
}
|
||||
return this.sent.ipc[dateKey] = fetchAPI(url, options).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(json => {
|
||||
return this.ipcs[dateKey] = json.ipc * mult
|
||||
Object.entries(dates).forEach(([dateString, data]) => {
|
||||
const temp = []
|
||||
data.ventas.forEach(venta => {
|
||||
temp.push(venta)
|
||||
})
|
||||
array.push({
|
||||
type,
|
||||
start: data.start,
|
||||
end: data.end,
|
||||
ventas: temp
|
||||
})
|
||||
})
|
||||
})
|
||||
return array
|
||||
}
|
||||
},
|
||||
enqueue() {
|
||||
return {
|
||||
uf: ({date, venta_id}) => {
|
||||
const type = 'uf'
|
||||
const data = {
|
||||
date: [date.getFullYear(), date.getMonth()+1, date.getDate()].join('-'),
|
||||
}
|
||||
if (!(type in this.queue)) {
|
||||
this.queue[type] = {}
|
||||
}
|
||||
if (!(data.date in this.queue[type])) {
|
||||
this.queue[type][data.date] = []
|
||||
}
|
||||
if (this.queue[type][data.date].includes(data)) {
|
||||
return
|
||||
}
|
||||
this.queue[type][data.date].push(venta_id)
|
||||
this.queue['size'] ++
|
||||
},
|
||||
ipc: ({start, end, venta_id}) => {
|
||||
const type = 'ipc'
|
||||
let mult = 1
|
||||
if (start > end) {
|
||||
mult = -1
|
||||
let temp = end
|
||||
end = start
|
||||
start = temp
|
||||
}
|
||||
const data = {
|
||||
start: [start.getFullYear(), start.getMonth()+1, start.getDate()].join('-'),
|
||||
end: [end.getFullYear(), end.getMonth()+1, end.getDate()].join('-'),
|
||||
}
|
||||
if (!(type in this.queue)) {
|
||||
this.queue[type] = {}
|
||||
}
|
||||
if (!([data.start, data.end].join('|') in this.queue[type])) {
|
||||
this.queue[type][[data.start, data.end].join('|')] = {
|
||||
start: data.start,
|
||||
end: data.end,
|
||||
ventas: []
|
||||
}
|
||||
}
|
||||
if (this.queue[type][[data.start, data.end].join('|')].ventas.includes(data)) {
|
||||
return
|
||||
}
|
||||
this.queue[type][[data.start, data.end].join('|')].ventas.push({venta_id, mult})
|
||||
this.queue['size'] ++
|
||||
},
|
||||
}
|
||||
},
|
||||
get() {
|
||||
return {
|
||||
many: () => {
|
||||
const url = '{{$urls->api}}/money/many'
|
||||
const method = 'post'
|
||||
const chunkSize = 100
|
||||
const promises = []
|
||||
for (let i = 0; i < this.queue.size; i += chunkSize) {
|
||||
const chunk = this.queue.array().slice(i, i + chunkSize)
|
||||
const missing = chunk.filter(data => {
|
||||
if (data.type === 'uf') {
|
||||
return !(data.date in this.data.ufs)
|
||||
}
|
||||
if (data.type === 'ipc') {
|
||||
const dateKey = [data.start, data.end].join('|')
|
||||
return !(dateKey in this.data.ipcs)
|
||||
}
|
||||
})
|
||||
if (missing.length === 0) {
|
||||
continue
|
||||
}
|
||||
const body = new FormData()
|
||||
body.set('dates', JSON.stringify(missing))
|
||||
const options = {
|
||||
method,
|
||||
body
|
||||
}
|
||||
promises.push(fetchAPI(url, options).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(json => {
|
||||
json.values.forEach(data => {
|
||||
if (data.type === 'uf') {
|
||||
this.data.ufs[data.date] = data.value
|
||||
}
|
||||
if (data.type === 'ipc') {
|
||||
const dateKey = [data.start, data.end].join('|')
|
||||
this.data.ipcs[dateKey] = data.value
|
||||
}
|
||||
})
|
||||
return json.values
|
||||
})
|
||||
}))
|
||||
}
|
||||
return Promise.all(promises)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,13 +250,14 @@
|
||||
const venta = this.principal.descripcion
|
||||
const cantidad = this.unidades.length
|
||||
this.unidades.forEach(unidad => {
|
||||
const valor = (unidad.valor > 0) ? unidad.valor : unidad.precio
|
||||
const values = [
|
||||
'<a href="{{$urls->base}}/ventas/factura/' + this.id + '">' + venta + '</a>',
|
||||
cantidad,
|
||||
unidad.tipo,
|
||||
unidad.descripcion,
|
||||
dateFormatter.format(this.fecha),
|
||||
ufFormatter.format(unidad.precio) + ' UF',
|
||||
ufFormatter.format(valor) + ' UF',
|
||||
unidad.prorrateo,
|
||||
'',
|
||||
'',
|
||||
@ -173,21 +272,21 @@
|
||||
if (this.escritura !== null) {
|
||||
const ipc = (this.ipc >= 0) ? (1 + this.ipc) : 1 / (1 + this.ipc)
|
||||
const descuento = valor_terreno * ipc * unidad.prorrateo
|
||||
const precio_venta = unidad.precio * this.uf
|
||||
const precio_venta = valor * this.uf
|
||||
const precio_bruto = precio_venta - descuento
|
||||
const precio_neto = precio_bruto / 1.19
|
||||
const iva = precio_bruto - precio_neto
|
||||
|
||||
let i = 7
|
||||
values[i++] = pesosFormatter.format(descuento)
|
||||
values[i++] = pesosFormatter.format(precio_venta)
|
||||
values[i++] = pesosFormatter.format(precio_bruto)
|
||||
values[i++] = pesosFormatter.format(iva)
|
||||
values[i++] = pesosFormatter.format(precio_neto)
|
||||
values[i++] = (iva / precio_venta * 100).toFixed(2) + '%'
|
||||
values[i++] = (!isNaN(descuento)) ? pesosFormatter.format(descuento) : '<div class="ui active inline loader"></div>'
|
||||
values[i++] = (!isNaN(precio_venta)) ? pesosFormatter.format(precio_venta) : ''
|
||||
values[i++] = (!isNaN(precio_bruto)) ? pesosFormatter.format(precio_bruto) : ''
|
||||
values[i++] = (!isNaN(iva)) ? pesosFormatter.format(iva) : ''
|
||||
values[i++] = (!isNaN(precio_neto)) ? pesosFormatter.format(precio_neto) : ''
|
||||
values[i++] = (!isNaN(iva) && !isNaN(precio_venta)) ? (iva / precio_venta * 100).toFixed(2) + '%' : ''
|
||||
values[i++] = dateFormatter.format(this.escritura)
|
||||
values[i++] = ufFormatter.format(this.uf)
|
||||
values[i++] = ufFormatter.format(this.ipc >= 0 ? this.ipc * 100 : -this.ipc * 100) + '%'
|
||||
values[i++] = (!isNaN(this.uf)) ? ufFormatter.format(this.uf) : ''
|
||||
values[i++] = (!isNaN(this.ipc)) ? (ufFormatter.format(this.ipc >= 0 ? this.ipc * 100 : -this.ipc * 100) + '%') : ''
|
||||
}
|
||||
const row = $('<tr></tr>')
|
||||
values.forEach(value => {
|
||||
@ -234,12 +333,26 @@
|
||||
ventas.push(this.get().chunk({idx, chunk}))
|
||||
}
|
||||
Promise.all(ventas).then(() => {
|
||||
const promises = []
|
||||
promises.push(...this.get().ufs(idx))
|
||||
promises.push(...this.get().ipcs(idx))
|
||||
Promise.all(promises).then(() => {
|
||||
this.draw().ventas(idx)
|
||||
this.sent = false
|
||||
money.get().many().then(response => {
|
||||
response.forEach(dates => {
|
||||
dates.forEach(values => {
|
||||
values.ventas.forEach(venta => {
|
||||
let vidx = 0
|
||||
if (values.type === 'uf') {
|
||||
vidx = this.data[idx].ventas.findIndex(v => v.id === venta)
|
||||
this.data[idx].ventas[vidx].uf = values.value
|
||||
return
|
||||
}
|
||||
if (values.type === 'ipc') {
|
||||
vidx = this.data[idx].ventas.findIndex(v => v.id === venta.venta_id)
|
||||
this.data[idx].ventas[vidx].ipc = values.value * venta.mult
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
this.draw().ventas(idx)
|
||||
this.sent = false
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -262,33 +375,6 @@
|
||||
});
|
||||
})
|
||||
},
|
||||
ufs: idx => {
|
||||
const promises = []
|
||||
Object.entries(this.queues.uf).forEach(([dateString, ventas]) => {
|
||||
const date = new Date(dateString)
|
||||
promises.push(money.get().uf(date).then(uf => {
|
||||
ventas.forEach(id => {
|
||||
const vidx = this.data[idx].ventas.findIndex(venta => venta.id === id)
|
||||
this.data[idx].ventas[vidx].uf = uf
|
||||
})
|
||||
}))
|
||||
})
|
||||
return promises
|
||||
},
|
||||
ipcs: idx => {
|
||||
const fecha_terreno = (typeof this.data[idx].terreno.date === 'undefined') ? new Date() : new Date(this.data[idx].terreno.date)
|
||||
const promises = []
|
||||
Object.entries(this.queues.ipc).forEach(([dateString, ventas]) => {
|
||||
const date = new Date(dateString)
|
||||
promises.push(money.get().ipc({end: date, start: fecha_terreno}).then(ipc => {
|
||||
ventas.forEach(id => {
|
||||
const vidx = this.data[idx].ventas.findIndex(venta => venta.id === id)
|
||||
this.data[idx].ventas[vidx].ipc = ipc
|
||||
})
|
||||
}))
|
||||
})
|
||||
return promises
|
||||
}
|
||||
}
|
||||
},
|
||||
add() {
|
||||
@ -296,10 +382,11 @@
|
||||
venta: ({proyecto_idx, venta}) => {
|
||||
const v = new Venta(venta)
|
||||
this.data[proyecto_idx].ventas.push(v)
|
||||
const fecha_terreno = (typeof this.data[proyecto_idx].terreno.fecha === 'undefined') ? new Date() : new Date(this.data[proyecto_idx].terreno.fecha)
|
||||
|
||||
if (v.escritura !== null) {
|
||||
const dateString = v.escritura.toString()
|
||||
this.register().uf({dateString, venta_id: v.id})
|
||||
this.register().ipc({dateString, venta_id: v.id})
|
||||
money.enqueue().uf({date: v.escritura, venta_id: v.id})
|
||||
money.enqueue().ipc({start: v.escritura, end: fecha_terreno, venta_id: v.id})
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -342,18 +429,17 @@
|
||||
this.table = null
|
||||
parent.html('')
|
||||
}
|
||||
const table = $('<table></table>').addClass('ui table')
|
||||
const table = $('<table></table>').addClass('ui compact table')
|
||||
table.append(this.draw().thead())
|
||||
table.append(this.draw().tbody(proyecto_idx))
|
||||
parent.show()
|
||||
parent.html(table)
|
||||
$(this.ids.proyectos).hide()
|
||||
if (this.table === null) {
|
||||
this.table = table.DataTable({
|
||||
orders: [
|
||||
[0, 'asc']
|
||||
]
|
||||
})
|
||||
const dtD = structuredClone(datatables_defaults)
|
||||
dtD['pageLength'] = 100
|
||||
dtD['order'] = [[0, 'asc']]
|
||||
this.table = table.DataTable(dtD)
|
||||
}
|
||||
},
|
||||
thead: () => {
|
||||
|
@ -97,4 +97,45 @@ class Money
|
||||
$output['ipc'] = $ipcService->get($start, $end);
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function getMany(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
|
||||
Service\Money $moneyService): ResponseInterface
|
||||
{
|
||||
$input = $request->getParsedBody();
|
||||
$output = [
|
||||
'input' => $input,
|
||||
'values' => []
|
||||
];
|
||||
$data = json_decode($input['dates']);
|
||||
$ufs = [];
|
||||
$ipcs = [];
|
||||
try {
|
||||
$ufs = (array) $this->fetchRedis($redisService, 'ufs');
|
||||
} catch (EmptyRedis) {}
|
||||
try {
|
||||
$ipcs = (array) $this->fetchRedis($redisService, 'ipcs');
|
||||
} catch (EmptyRedis) {}
|
||||
foreach ($data as $date) {
|
||||
if ($date->type === 'uf') {
|
||||
if (!in_array($date->date, $ufs)) {
|
||||
$uf = $moneyService->getUF(new DateTimeImmutable($date->date));
|
||||
$ufs[$date->date] = $uf;
|
||||
}
|
||||
$date->value = $ufs[$date->date];
|
||||
$output['values'] []= $date;
|
||||
continue;
|
||||
}
|
||||
if ($date->type === 'ipc') {
|
||||
$dateString = "{$date->start}|{$date->end}";
|
||||
if (!in_array($dateString, $ipcs)) {
|
||||
$ipc = $moneyService->getIPC(new DateTimeImmutable($date->start), new DateTimeImmutable($date->end));
|
||||
$ipcs[$dateString] = $ipc;
|
||||
}
|
||||
$date->value = $ipcs[$dateString];
|
||||
$output['values'] []= $date;
|
||||
}
|
||||
}
|
||||
$this->saveRedis($redisService, 'ufs', $ufs, $this->time);
|
||||
$this->saveRedis($redisService, 'ipcs', $ipcs, $this->time);
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ class Money
|
||||
}
|
||||
public function getIPC(DateTimeInterface $start, DateTimeInterface $end): float
|
||||
{
|
||||
if ($start >= $end) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return $this->getProvider('ipc')->getVar($start, $end);
|
||||
} catch (EmptyResponse) {
|
||||
|
@ -110,6 +110,7 @@ class Venta extends Service
|
||||
'tipo' => ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion),
|
||||
'descripcion' => $unidad->descripcion,
|
||||
'prorrateo' => $unidad->prorrateo,
|
||||
'valor' => $unidad->valor,
|
||||
'precio' => (isset($unidad->currentPrecio)) ? $unidad->currentPrecio->valor : 0
|
||||
];
|
||||
}
|
||||
|
Reference in New Issue
Block a user