Add price template file

This commit is contained in:
Juan Pablo Vial
2025-11-24 18:40:52 -03:00
parent caf0dfe4ab
commit 2b120a3bf5
2 changed files with 117 additions and 1 deletions

View File

@ -0,0 +1,4 @@
@push('page_scripts')
<!-- use version 0.20.3 -->
<script type="text/javascript" src="https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script>
@endpush

View File

@ -13,6 +13,24 @@
</div>
</div>
</div>
<div class="fields">
<div class="four wide field">
<button class="ui button" id="import_template">
<i class="file icon"></i>
Descargar plantilla
</button>
</div>
<div class="field">
<div class="ui radio checkbox import_format">
<input type="radio" name="format" value="csv" />
<label>CSV</label>
</div>
<div class="ui radio checkbox import_format">
<input type="radio" name="format" value="xlsx" checked />
<label>XLSX</label>
</div>
</div>
</div>
<input class="ui invisible file input" type="file" id="import_file" name="file" />
<label class="ui placeholder segment" for="import_file">
<div class="ui icon header">
@ -32,8 +50,95 @@
</div>
</div>
@include('layout.body.scripts.xlsx')
@push('page_scripts')
<script>
class ImportTemplate {
ids = {
button: '',
format: ''
}
components = {
button: null,
$format: null
}
data = {
filename: '',
format: '',
columns: [],
csv: {
separator: '',
},
}
buildData() {
const data = []
data.push(this.data.columns.map(column => column.charAt(0).toUpperCase() + column.slice(1)))
data.push(this.data.columns.map(column => ''))
return data
}
download(event) {
event.preventDefault()
if (this.data.format === 'csv') {
this.downloadCsv()
}
if (this.data.format === 'xlsx') {
this.downloadXlsx()
}
return false
}
downloadCsv() {
const data = []
data.push(Object.keys(this.data.columns))
data.push(Object.values(this.data.columns))
const blob = new Blob([data.map(row => row.join(this.data.csv.separator)).join('\n')], {type: 'text/csv'})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = this.data.filename + '.csv'
a.click()
URL.revokeObjectURL(url)
}
downloadXlsx() {
const workbook = XLSX.utils.book_new()
const worksheet = XLSX.utils.json_to_sheet([this.data.columns])
XLSX.utils.book_append_sheet(workbook, worksheet, 'Plantilla de Precios')
XLSX.writeFile(workbook, this.data.filename + '.xlsx', { compression: true })
}
constructor() {
this.ids.button = 'import_template'
this.ids.format = 'import_format'
this.data.filename = 'Plantilla de Precios'
this.data.format = 'xlsx'
this.data.columns = {
Fecha: '',
'Proyecto*': 'Proyecto es opcional. Se toma el proyecto seleccionado',
'Tipo*': 'Tipo es optional. Se toma departamento.',
Unidad: '',
Valor: ''
}
this.data.csv.separator = ';'
this.setup()
}
setup() {
this.components.button = document.getElementById(this.ids.button)
this.components.button.addEventListener('click', this.download.bind(this))
this.components.$format = $(`.${this.ids.format}`)
this.components.$format.checkbox({
fireOnInit: true,
onChange: () => {
const radios = this.components.$format.find('[name="format"]').toArray()
const checkedRadio = radios.filter(elem => elem.checked)[0]
this.data.format = checkedRadio.value
}
})
}
}
class ImportModal {
ids = {
modal: '',
@ -47,7 +152,8 @@
project: null,
$calendar: null,
file: null,
$file: null
$file: null,
template: null
}
constructor() {
this.ids.modal = 'import_modal'
@ -91,17 +197,23 @@
this.import()
}
})
this.components.form = this.components.$modal.find('form')
this.components.form.submit(event => {
event.preventDefault()
this.import()
return false
})
this.components.project = document.getElementById(this.ids.project)
this.components.$calendar = $(`#${this.ids.calendar}`)
const cdo = structuredClone(calendar_date_options)
cdo['maxDate'] = new Date()
this.components.$calendar.calendar(cdo)
this.template = new ImportTemplate()
this.components.file = document.getElementById(this.ids.file)
this.components.$file = $(this.components.file.parentNode.querySelector('label'))
this.components.$file.css('cursor', 'pointer')