Listado de promociones
This commit is contained in:
@ -18,30 +18,33 @@
|
||||
}
|
||||
draw() {}
|
||||
prices(units) {
|
||||
const prices = []
|
||||
units.forEach(unit => {
|
||||
let price = unit.valor ?? (unit.precio?.valor ?? 0)
|
||||
let amount = 1
|
||||
let diff = 0
|
||||
unit.promotions?.forEach(promotion => {
|
||||
return units.map(unit => {
|
||||
let price = unit.valor ?? (unit.precio?.valor ?? 0)
|
||||
const broker = price / (1 - this.commission)
|
||||
const promotions = unit.promotions?.map(promotion => {
|
||||
if (promotion.type === 1) {
|
||||
diff += promotion.amount
|
||||
return
|
||||
return {
|
||||
name: promotion.description,
|
||||
type: promotion.type,
|
||||
amount: promotion.amount,
|
||||
final: broker + promotion.amount
|
||||
}
|
||||
}
|
||||
amount /= 1/(1 - promotion.amount)
|
||||
})
|
||||
amount = 1 - amount
|
||||
price += diff
|
||||
prices.push({
|
||||
return {
|
||||
name: promotion.description,
|
||||
type: promotion.type,
|
||||
amount: promotion.amount,
|
||||
final: broker / (1 - promotion.amount)
|
||||
}
|
||||
}) ?? []
|
||||
return {
|
||||
id: unit.id,
|
||||
base: price,
|
||||
commission: this.commission,
|
||||
broker: price / (1 - this.commission),
|
||||
amount,
|
||||
final: price / (1 - this.commission) / (1 - amount)
|
||||
})
|
||||
broker,
|
||||
promotions
|
||||
}
|
||||
})
|
||||
return prices
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -7,7 +7,6 @@
|
||||
<th class="center aligned">Cantidad</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Base</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Comisión</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Porcentaje</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Operador</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Final</th>
|
||||
</tr>
|
||||
@ -63,16 +62,78 @@
|
||||
`Max: ${formatters.ufs.format(Math.max(...prices.map(p => p.broker)))}`,
|
||||
`Desv: ${formatters.ufs.format(Stat.standardDeviation(prices.map(p => p.broker)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const amount_tooltip = [
|
||||
`Min: ${formatters.percent.format(Math.min(...prices.map(p => p.amount)))}`,
|
||||
`Max: ${formatters.percent.format(Math.max(...prices.map(p => p.amount)))}`,
|
||||
`Desv: ${formatters.percent.format(Stat.standardDeviation(prices.map(p => p.amount)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const final_tooltip = [
|
||||
`Min: UF ${formatters.ufs.format(Math.min(...prices.map(p => p.final)))}`,
|
||||
`Max: UF ${formatters.ufs.format(Math.max(...prices.map(p => p.final)))}`,
|
||||
`Desv: UF ${formatters.ufs.format(Stat.standardDeviation(prices.map(p => p.final)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
|
||||
let promotions = {}
|
||||
prices.map(price => price.promotions).forEach(promotionArray => {
|
||||
promotionArray.forEach(p => {
|
||||
if (!Object.hasOwn(promotions, p.name)) {
|
||||
promotions[p.name] = {
|
||||
name: p.name,
|
||||
type: p.type,
|
||||
amount: [],
|
||||
final: []
|
||||
}
|
||||
}
|
||||
promotions[p.name].amount.push(p.amount)
|
||||
promotions[p.name].final.push(p.final)
|
||||
})
|
||||
})
|
||||
promotions = Object.values(promotions)
|
||||
let subTable = false
|
||||
if (promotions.length > 0) {
|
||||
promotions = promotions.map(p => {
|
||||
return {
|
||||
name: p.name,
|
||||
type: p.type,
|
||||
amount: {
|
||||
min: Math.min(...p.amount),
|
||||
max: Math.max(...p.amount),
|
||||
desv: Stat.standardDeviation(p.amount),
|
||||
mean: Stat.mean(p.amount)
|
||||
},
|
||||
final: {
|
||||
min: Math.min(...p.final),
|
||||
max: Math.max(...p.final),
|
||||
desv: Stat.standardDeviation(p.final),
|
||||
mean: Stat.mean(p.final)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
subTable = document.createElement('table')
|
||||
subTable.className = 'ui table'
|
||||
const subTHead = document.createElement('thead')
|
||||
promotions.forEach(p => {
|
||||
subTHead.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
'<th class="center aligned">Nombre</th>',
|
||||
'<th class="center aligned">Forma</th>',
|
||||
'<th class="right aligned">Precio Final</th>',
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
const subTbody = document.createElement('tbody')
|
||||
promotions.forEach(p => {
|
||||
const amount_tooltip = [
|
||||
`Min: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.min) : formatters.percent.format(p.amount.min)}`,
|
||||
`Max: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.max) : formatters.percent.format(p.amount.max)}`,
|
||||
`Desv: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.desv) : formatters.percent.format(p.amount.desv)}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const final_tooltip = [
|
||||
`Min: UF ${formatters.ufs.format(p.final.min)}`,
|
||||
`Max: UF ${formatters.ufs.format(p.final.max)}`,
|
||||
`Desv: UF ${formatters.ufs.format(p.final.desv)}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
subTbody.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
`<td class="center aligned">${p.name}</td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${amount_tooltip}" data-position="right center" data-variation="wide multiline">${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.mean) : formatters.percent.format(p.amount.mean)}</td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${final_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(p.final.mean)}</td></td>`,
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
subTable.appendChild(subTHead).appendChild(subTbody)
|
||||
}
|
||||
|
||||
tbody.innerHTML += [
|
||||
`<tr>`,
|
||||
@ -83,8 +144,7 @@
|
||||
`<td class="right aligned"><span data-tooltip="${base_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.base)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${commission_tooltip}" data-position="right center" data-variation="wide multiline">${formatters.percent.format(Stat.mean(prices.map(p => p.commission)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${broker_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.broker)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${amount_tooltip}" data-position="right center" data-variation="wide multiline">${formatters.percent.format(Stat.mean(prices.map(p => p.amount)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${final_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.final)))}</span></td>`,
|
||||
`<td class="right aligned">${subTable ? subTable.outerHTML : `UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.broker)))}`}</td>`,
|
||||
`</tr>`
|
||||
].join("\n")
|
||||
})
|
||||
|
@ -6,8 +6,7 @@
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Base</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Comisión</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Operador</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Porcentaje</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Precio Final</th>
|
||||
<th class="right aligned" style="text-decoration: overline">Promociones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
@ -46,16 +45,77 @@
|
||||
`Max: ${formatters.ufs.format(Math.max(...prices.map(p => p.broker)))}`,
|
||||
`Desv: ${formatters.ufs.format(Stat.standardDeviation(prices.map(p => p.broker)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const amount_tooltip = [
|
||||
`Min: ${formatters.percent.format(Math.min(...prices.map(p => p.amount)))}`,
|
||||
`Max: ${formatters.percent.format(Math.max(...prices.map(p => p.amount)))}`,
|
||||
`Desv: ${formatters.percent.format(Stat.standardDeviation(prices.map(p => p.amount)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const final_tooltip = [
|
||||
`Min: UF ${formatters.ufs.format(Math.min(...prices.map(p => p.final)))}`,
|
||||
`Max: UF ${formatters.ufs.format(Math.max(...prices.map(p => p.final)))}`,
|
||||
`Desv: UF ${formatters.ufs.format(Stat.standardDeviation(prices.map(p => p.final)))}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
|
||||
let promotions = {}
|
||||
prices.map(price => price.promotions).forEach(promotionArray => {
|
||||
promotionArray.forEach(p => {
|
||||
if (!Object.hasOwn(promotions, p.name)) {
|
||||
promotions[p.name] = {
|
||||
name: p.name,
|
||||
type: p.type,
|
||||
amount: [],
|
||||
final: []
|
||||
}
|
||||
}
|
||||
promotions[p.name].amount.push(p.amount)
|
||||
promotions[p.name].final.push(p.final)
|
||||
})
|
||||
})
|
||||
promotions = Object.values(promotions)
|
||||
let subTable = false
|
||||
if (promotions.length > 0) {
|
||||
promotions = promotions.map(p => {
|
||||
return {
|
||||
name: p.name,
|
||||
type: p.type,
|
||||
amount: {
|
||||
min: Math.min(...p.amount),
|
||||
max: Math.max(...p.amount),
|
||||
desv: Stat.standardDeviation(p.amount),
|
||||
mean: Stat.mean(p.amount)
|
||||
},
|
||||
final: {
|
||||
min: Math.min(...p.final),
|
||||
max: Math.max(...p.final),
|
||||
desv: Stat.standardDeviation(p.final),
|
||||
mean: Stat.mean(p.final)
|
||||
}
|
||||
}
|
||||
})
|
||||
subTable = document.createElement('table')
|
||||
subTable.className = 'ui table'
|
||||
const subTHead = document.createElement('thead')
|
||||
promotions.forEach(p => {
|
||||
subTHead.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
'<th class="center aligned">Nombre</th>',
|
||||
'<th class="center aligned">Forma</th>',
|
||||
'<th class="right aligned">Precio Final</th>',
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
const subTbody = document.createElement('tbody')
|
||||
promotions.forEach(p => {
|
||||
const amount_tooltip = [
|
||||
`Min: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.min) : formatters.percent.format(p.amount.min)}`,
|
||||
`Max: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.max) : formatters.percent.format(p.amount.max)}`,
|
||||
`Desv: ${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount.desv) : formatters.percent.format(p.amount.desv)}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
const final_tooltip = [
|
||||
`Min: UF ${formatters.ufs.format(p.final.min)}`,
|
||||
`Max: UF ${formatters.ufs.format(p.final.max)}`,
|
||||
`Desv: UF ${formatters.ufs.format(p.final.desv)}`
|
||||
].join("\n").replaceAll(' ', ' ')
|
||||
subTbody.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
`<td class="center aligned">${p.name}</td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${amount_tooltip}" data-position="right center" data-variation="wide multiline">${p.type === 1 ? formatters.ufs.format(p.amount.mean) : formatters.percent.format(p.amount.mean)}</td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${final_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(p.final.mean)}</td></td>`,
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
subTable.appendChild(subTHead).appendChild(subTbody)
|
||||
}
|
||||
|
||||
tbody.innerHTML += [
|
||||
`<tr>`,
|
||||
@ -64,8 +124,7 @@
|
||||
`<td class="right aligned"><span data-tooltip="${base_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.base)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${commission_tooltip}" data-position="right center" data-variation="wide multiline">${formatters.percent.format(Stat.mean(prices.map(p => p.commission)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${broker_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.broker)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${amount_tooltip}" data-position="right center" data-variation="wide multiline">${formatters.percent.format(Stat.mean(prices.map(p => p.amount)))}</span></td>`,
|
||||
`<td class="right aligned"><span data-tooltip="${final_tooltip}" data-position="right center" data-variation="wide multiline">UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.final)))}</span></td>`,
|
||||
`<td class="right aligned">${subTable ? subTable.outerHTML : `UF ${formatters.ufs.format(Stat.mean(prices.map(p => p.broker)))}`}</td>`,
|
||||
`</tr>`
|
||||
].join("\n")
|
||||
})
|
||||
|
@ -9,13 +9,15 @@
|
||||
<th>Tipología</th>
|
||||
<th>Piso</th>
|
||||
<th>Orientación</th>
|
||||
<th>m²</th>
|
||||
<th>m² Interior</th>
|
||||
<th>m² Terraza</th>
|
||||
<th>m² Vendibles</th>
|
||||
<th>m² Total</th>
|
||||
<th class="right aligned">Precio Base</th>
|
||||
<th class="right aligned">Comisión</th>
|
||||
<th class="right aligned">Precio Operador</th>
|
||||
<th class="right aligned">UF/m²</th>
|
||||
<th class="right aligned">Porcentaje</th>
|
||||
<th class="right aligned">Precio Final</th>
|
||||
<th class="right aligned">Promociones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
@ -36,13 +38,15 @@
|
||||
'tipologia',
|
||||
'piso',
|
||||
'orientacion',
|
||||
'metros_interior',
|
||||
'metros_terraza',
|
||||
'metros',
|
||||
'metros_total',
|
||||
'precio_base',
|
||||
'commission',
|
||||
'precio_operador',
|
||||
'UF/m²',
|
||||
'porcentaje',
|
||||
'precio_final',
|
||||
'promociones',
|
||||
]
|
||||
constructor(commission) {
|
||||
super(commission)
|
||||
@ -86,7 +90,7 @@
|
||||
title: 'Lista de Precios - {{ $contract->broker->name }} - {{ $contract->project->descripcion }} - {{ (new DateTime())->format('Y-m-d') }}',
|
||||
download: 'open',
|
||||
exportOptions: {
|
||||
columns: ['tipo', 'unidad', 'tipologia', 'piso', 'orientacion', 'metros', 'precio_operador', 'porcentaje', 'precio_final']
|
||||
columns: ['tipo', 'unidad', 'tipologia', 'piso', 'orientacion', 'metros_interior', 'metros_terraza', 'metros', 'metros_total', 'precio_operador', 'promociones']
|
||||
.map(column => this.columns.indexOf(column)),
|
||||
rows: (idx, data, node) => {
|
||||
return data[this.columns.indexOf('estado')] === 'Libre'
|
||||
@ -117,6 +121,35 @@
|
||||
units.forEach(unidad => {
|
||||
const tipo = unidad.proyecto_tipo_unidad.tipo_unidad.descripcion
|
||||
const price = prices.find(p => p.id === unidad.id)
|
||||
|
||||
let subTable = false
|
||||
|
||||
if (price.promotions.length > 0) {
|
||||
subTable = document.createElement('table')
|
||||
subTable.className = 'ui table'
|
||||
const subTHead = document.createElement('thead')
|
||||
price.promotions.forEach(p => {
|
||||
subTHead.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
'<th class="center aligned">Nombre</th>',
|
||||
'<th class="center aligned">Forma</th>',
|
||||
'<th class="right aligned">Precio Final</th>',
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
const subTBody = document.createElement('tbody')
|
||||
price.promotions.forEach(p => {
|
||||
subTBody.insertAdjacentHTML('beforeend', [
|
||||
'<tr>',
|
||||
`<td class="center aligned">${p.name}</td>`,
|
||||
`<td class="right aligned">${p.type === 1 ? 'UF ' + formatters.ufs.format(p.amount) : formatters.percent.format(p.amount)}</td>`,
|
||||
`<td class="right aligned">UF ${formatters.ufs.format(p.final)}</td>`,
|
||||
'</tr>'
|
||||
].join("\n"))
|
||||
})
|
||||
subTable.appendChild(subTHead).appendChild(subTBody)
|
||||
}
|
||||
|
||||
tableData.push([
|
||||
unidad.sold ? `<span class="ui yellow text">Vendida</span>` : 'Libre',
|
||||
tipo.charAt(0).toUpperCase() + tipo.slice(1),
|
||||
@ -126,15 +159,15 @@
|
||||
unidad.proyecto_tipo_unidad.tipologia,
|
||||
unidad.piso,
|
||||
unidad.orientacion,
|
||||
formatters.ufs.format(unidad.proyecto_tipo_unidad.util) ?? 0,
|
||||
formatters.ufs.format(unidad.proyecto_tipo_unidad.terraza) ?? 0,
|
||||
formatters.ufs.format(unidad.proyecto_tipo_unidad.vendible) ?? 0,
|
||||
formatters.ufs.format(unidad.proyecto_tipo_unidad.superficie) ?? 0,
|
||||
'UF ' + formatters.ufs.format(price.base ?? 0),
|
||||
formatters.percent.format(price.commission ?? 0),
|
||||
'UF ' + formatters.ufs.format(price.broker ?? 0),
|
||||
formatters.ufs.format(price.broker / unidad.proyecto_tipo_unidad.vendible),
|
||||
formatters.percent.format(price.amount ?? 0),
|
||||
'UF ' + formatters.ufs.format(price.final ?? 0),
|
||||
unidad.promotion?.start_date ?? '',
|
||||
unidad.promotion?.end_date ?? '',
|
||||
subTable ? subTable.outerHTML : 'UF ' + formatters.ufs.format(price.broker ?? 0),
|
||||
])
|
||||
})
|
||||
table.rows.add(tableData)
|
||||
|
Reference in New Issue
Block a user