Import Precios

This commit is contained in:
Juan Pablo Vial
2025-08-27 19:27:18 -04:00
parent 4e4c0b7648
commit ad64ffa436
19 changed files with 1049 additions and 21 deletions

View File

@ -2,6 +2,7 @@
use Incoviba\Controller\API\Ventas\Precios;
$app->group('/precios', function($app) {
$app->post('/import[/]', [Precios::class, 'import']);
$app->post('[/]', [Precios::class, 'proyecto']);
});
$app->group('/precio', function($app) {

View File

@ -2,5 +2,5 @@
use Incoviba\Controller\Ventas\Precios;
$app->group('/precios', function($app) {
$app->get('[/]', Precios::class);
$app->get('[/{project_id}[/]]', Precios::class);
});

View File

@ -24,6 +24,9 @@
<button class="ui tiny green icon button" id="add_button">
<i class="plus icon"></i>
</button>
<button class="ui tiny green icon button" id="import_button">
<i class="upload icon"></i>
</button>
</div>
</div>
</h4>
@ -31,6 +34,7 @@
<table class="ui table" id="list_data"></table>
</div>
</div>
@include('ventas.precios.modal.import')
<div class="ui modal" id="list_modal">
<div class="header">
Actualizar <span id="modal_title"></span>
@ -97,7 +101,8 @@
return this.precio / this.superficie
}
draw(formatter) {
const date = new Date(this.fecha)
const dateParts = this.fecha.split('-')
const date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2])
const dateFormatter = new Intl.DateTimeFormat('es-CL')
return $('<tr></tr>').addClass('unidad').attr('data-linea', this.linea).append(
$('<td></td>').html(this.nombre)
@ -317,7 +322,8 @@
buttons: {
add: '',
up: '',
refresh: ''
refresh: '',
import: ''
}
},
data: {
@ -330,6 +336,11 @@
loading: {
precios: false
},
components: {
modals: {
import: null
}
},
get: function() {
return {
proyectos: () => {
@ -378,6 +389,24 @@
}
}
},
url() {
return {
proyectos: () => {
const currentUrl = window.location.href
const newUrl = `{{ $urls->base }}/ventas/precios`
if (newUrl !== currentUrl) {
window.history.replaceState(null, null, newUrl)
}
},
precios: proyecto_id => {
const currentUrl = window.location.href
const newUrl = `{{ $urls->base }}/ventas/precios/${proyecto_id}`
if (newUrl !== currentUrl) {
window.history.replaceState(null, null, newUrl)
}
}
}
},
add: function() {
return {
precio: data => {
@ -400,6 +429,7 @@
draw: function() {
return {
proyectos: () => {
this.url().proyectos()
const parent = $(this.ids.list)
const header = parent.find('#list_title')
const list = parent.find('.list')
@ -408,6 +438,7 @@
$(this.ids.buttons.add).hide()
$(this.ids.buttons.add).attr('data-id', '')
$(this.ids.buttons.add).attr('data-proyecto', '')
$(`#${this.ids.buttons.import}`).hide()
header.html('Proyectos')
table.hide()
@ -415,7 +446,8 @@
this.data.proyectos.forEach(proyecto => {
list.append(
$('<div></div>').addClass('item proyecto').attr('data-proyecto', proyecto.id).html(proyecto.descripcion).css('cursor', 'pointer')
$('<div></div>').addClass('item proyecto').attr('data-proyecto', proyecto.id)
.html(proyecto.descripcion).css('cursor', 'pointer')
)
})
list.show()
@ -431,6 +463,7 @@
})
},
precios: () => {
this.url().precios(this.data.id)
const parent = $(this.ids.list)
const header = parent.find('#list_title')
const list = parent.find('.list')
@ -440,6 +473,8 @@
$(this.ids.buttons.add).attr('data-proyecto', this.data.proyecto)
$(this.ids.buttons.add).show()
$(`#${this.ids.buttons.import}`).show()
header.html('Precios de ' + this.data.proyecto)
list.hide()
table.html('')
@ -581,18 +616,27 @@
}
}
},
import: event => {
event.preventDefault()
precios.components.modals.import.show(this.data.id)
return false
}
}
},
setup: function({list, proyectos, buttons_up, buttons_refresh, buttons_add}) {
setup: function({list, proyectos, buttons_up, buttons_refresh, buttons_add, buttons_import}) {
this.ids.list = list
this.ids.proyectos = proyectos
this.ids.buttons.up = buttons_up
this.ids.buttons.refresh = buttons_refresh
this.ids.buttons.add = buttons_add
this.ids.buttons.import = buttons_import
$(this.ids.buttons.up).click(this.actions().up)
$(this.ids.buttons.refresh).click(this.actions().refresh)
$(this.ids.buttons.add).click(this.actions().add().list)
document.getElementById(this.ids.buttons.import).addEventListener('click', this.actions().import)
this.components.modals.import = new ImportModal()
this.draw().proyectos()
}
@ -674,6 +718,10 @@
$(this.ids.button).click(this.actions().send)
}
}
function selectProject(projectId) {
const $project = $(`.item.proyecto[data-proyecto="${projectId}"]`)
$project.click()
}
$(document).ready(() => {
precios.setup({
@ -681,7 +729,8 @@
proyectos: '#proyectos',
buttons_up: '#up_button',
buttons_refresh: '#refresh_button',
buttons_add: '#add_button'
buttons_add: '#add_button',
buttons_import: 'import_button'
})
list_modal.setup({
modal: '#list_modal',
@ -692,6 +741,10 @@
fields_valor: '#valor',
button: '#send'
})
@if (isset($project_id))
selectProject({{$project_id}})
@endif
})
</script>
@endpush

View File

@ -0,0 +1,120 @@
<div class="ui modal" id="import_modal">
<div class="header">
Importar Precios
</div>
<div class="content">
<div class="ui form">
<input type="hidden" id="import_project_id" name="import_project_id" value="" />
<div class="three wide field">
<div class="ui calendar" id="import_date">
<div class="ui left icon input">
<i class="calendar icon"></i>
<input type="text" name="fecha" />
</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">
<i class="upload icon"></i>
Archivo de Precios
</div>
</label>
</div>
</div>
<div class="actions">
<div class="ui red cancel icon button">
<i class="remove icon"></i>
</div>
<div class="ui green ok icon button">
<i class="checkmark icon"></i>
Importar
</div>
</div>
@push('page_scripts')
<script>
class ImportModal {
ids = {
modal: '',
project: '',
calendar: '',
file: ''
}
components = {
$modal: null,
form: null,
project: null,
$calendar: null,
file: null,
$file: null
}
constructor() {
this.ids.modal = 'import_modal'
this.ids.project = 'import_project_id'
this.ids.calendar = 'import_date'
this.ids.file = 'import_file'
this.setup()
}
show(project_id) {
this.components.project.value = project_id
this.components.$modal.modal('show')
}
dragDrop(event) {
event.preventDefault()
if (event.originalEvent.dataTransfer && event.originalEvent.dataTransfer.files.length > 0) {
this.components.file.files = event.originalEvent.dataTransfer.files
}
}
import() {
const url = '{{ $urls->api }}/ventas/precios/import'
const method = 'post'
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('-'))
body.set('file', this.components.file.files[0])
APIClient.fetch(url, {method, body}).then(response => response.json()).then(json => {
if (json.status === true) {
window.location.reload()
return
}
console.debug(json)
})
}
setup() {
this.components.$modal = $(`#${this.ids.modal}`)
this.components.$modal.modal({
onApprove: () => {
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.components.file = document.getElementById(this.ids.file)
this.components.$file = $(this.components.file.parentNode.querySelector('label'))
this.components.$file.css('cursor', 'pointer')
this.components.$file.on('dragover', event => {
event.preventDefault()
event.stopPropagation()
})
this.components.$file.on('dragenter', event => {
event.preventDefault()
event.stopPropagation()
})
this.components.$file.on('drop', this.dragDrop.bind(this))
}
}
</script>
@endpush