Compare commits
5 Commits
caf0dfe4ab
...
07a1607554
| Author | SHA1 | Date | |
|---|---|---|---|
| 07a1607554 | |||
| a0019b51a5 | |||
| 49f5aa21f9 | |||
| 111c7df6b4 | |||
| 2b120a3bf5 |
4
app/resources/views/layout/body/scripts/xlsx.blade.php
Normal file
4
app/resources/views/layout/body/scripts/xlsx.blade.php
Normal 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
|
||||
@ -13,6 +13,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui two column grid">
|
||||
<div class="column">
|
||||
<button class="ui button" id="import_template">
|
||||
<i class="file icon"></i>
|
||||
Descargar plantilla
|
||||
</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="ui radio checkbox import_format">
|
||||
<input type="radio" name="format" value="csv" />
|
||||
<label>CSV</label>
|
||||
</div>
|
||||
<br />
|
||||
<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 +51,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*': 'Fecha es opcional. Se toma la fecha seleccionada',
|
||||
'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 +153,8 @@
|
||||
project: null,
|
||||
$calendar: null,
|
||||
file: null,
|
||||
$file: null
|
||||
$file: null,
|
||||
template: null
|
||||
}
|
||||
constructor() {
|
||||
this.ids.modal = 'import_modal'
|
||||
@ -74,7 +181,9 @@
|
||||
const body = new FormData()
|
||||
body.set('project_id', this.components.project.value)
|
||||
const date = this.components.$calendar.calendar('get date')
|
||||
body.set('date', [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'))
|
||||
if (date) {
|
||||
body.set('date', [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'))
|
||||
}
|
||||
body.set('file', this.components.file.files[0])
|
||||
APIClient.fetch(url, {method, body}).then(response => response.json()).then(json => {
|
||||
if (json.status === true) {
|
||||
@ -91,17 +200,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')
|
||||
|
||||
@ -61,7 +61,12 @@ class Precios
|
||||
{
|
||||
$body = $request->getParsedBody();
|
||||
$projectId = $body['project_id'];
|
||||
$date = $body['date'];
|
||||
if (array_key_exists('date', $body)) {
|
||||
$date = $body['date'];
|
||||
$date = DateTime::createFromFormat('Y-m-d', $date);
|
||||
} else {
|
||||
$date = new DateTime();
|
||||
}
|
||||
$file = $request->getUploadedFiles()['file'];
|
||||
$output = [
|
||||
'input' => $body,
|
||||
@ -69,7 +74,6 @@ class Precios
|
||||
'precios' => [],
|
||||
'status' => false
|
||||
];
|
||||
$date = DateTime::createFromFormat('Y-m-d', $date);
|
||||
try {
|
||||
$output['precios'] = $precioService->import($projectId, $date, $file);
|
||||
$output['total'] = count($output['precios']);
|
||||
|
||||
@ -75,19 +75,19 @@ class Import extends Ideal\Service
|
||||
'precio' => [],
|
||||
'unidad' => ['departamento'],
|
||||
'tipo' => ['tipo unidad'],
|
||||
'fecha' => []
|
||||
'fecha' => [],
|
||||
];
|
||||
|
||||
$realTitlesMap = [];
|
||||
$titles = array_keys($data[0]);
|
||||
foreach ($baseTitlesMap as $base => $optionals) {
|
||||
foreach ($titles as $title) {
|
||||
if (str_contains($title, $base)) {
|
||||
if (str_contains(strtolower($title), $base)) {
|
||||
$realTitlesMap[$title] = $base;
|
||||
break;
|
||||
}
|
||||
foreach ($optionals as $optional) {
|
||||
if (str_contains($title, $optional)) {
|
||||
if (str_contains(strtolower($title), $optional)) {
|
||||
$realTitlesMap[$title] = $base;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user