Files
rkm-conectasus-ci-sandbox/frontend/src/components/almoxarifado/balancete/List.vue
Antonio Lopes dos Santos afec302c3e
All checks were successful
build-api-image / build (push) Successful in 51s
init commit
2026-08-04 16:52:02 -03:00

513 lines
17 KiB
Vue

<template>
<div v-if="loaded">
<rkm-alert v-if="additionals.dataUltimoBalanceteFechado">
<strong>Último balancete fechado:</strong> {{ additionals.dataUltimoBalanceteFechado }}.
</rkm-alert>
<rkm-area
type="fieldset"
title="Filtros"
>
<rkm-form ref="Form">
<rkm-row>
<rkm-col cols="6">
<rkm-form-date-picker
:end-validations="validations.periodo"
:max-date="additionals.dataAtual"
:range-inline="false"
:start-validations="validations.periodo"
end-label="Até"
range
start-label="Período de"
v-model="model.periodo"
/>
</rkm-col>
<rkm-col cols="6">
<rkm-form-select
:options="form.grupos"
default-option-text="Todos"
label="Grupo"
show-default-option
text-field="nome"
v-model="model.grupoId"
value-field="id"
/>
</rkm-col>
</rkm-row>
<rkm-row>
<rkm-col cols="6">
<rkm-form-select
:disabled="!model.grupoId"
:options="subgrupos"
default-option-text="Todos"
label="Subgrupo"
show-default-option
text-field="nome"
v-model="model.subgrupoId"
value-field="id"
/>
</rkm-col>
<rkm-col>
<rkm-form-select
:options="form.origensProgramaticas"
default-option-text="Todas"
label="Origem programática"
show-default-option
text-field="nome"
v-model="model.origemProgramaticaId"
value-field="id"
/>
</rkm-col>
<rkm-col
class="text-nowrap"
cols="auto"
>
<rkm-button
:label="false"
@click="$refs.Form.validate(search)"
color="primary"
>
Buscar
</rkm-button>
<rkm-button
:label="false"
@click="clear"
>
Limpar
</rkm-button>
</rkm-col>
</rkm-row>
</rkm-form>
</rkm-area>
<rkm-area
no-margin-top
title="Resultado"
>
<template v-slot:trailing>
<rkm-dropdown
class="mr-2 text-nowrap"
color="primary"
cols="1"
menu-class="auto-scroll"
no-caret
small
title="Colunas"
v-rkm-tooltip.hover
>
<template v-slot:button-content>
<rkm-icon icon="columns" />
</template>
<rkm-form-checkbox
:indeterminate="indeterminate"
:value="true"
@change="handleSelectedColumns"
class="mx-2"
v-model="selectedAll"
>
Todas
</rkm-form-checkbox>
<rkm-form-checkbox-group
:options="columns"
class="mx-2"
stacked
v-model="selectedCols"
/>
</rkm-dropdown>
<rkm-button
:disabled="itens.length === 0 || !(showSaldoFisico || showSaldoFinanceiro)"
@click="print()"
color="info"
small
title="Imprimir"
>
<rkm-icon icon="print" />
</rkm-button>
</template>
<rkm-table
:fields="fields"
:foot-clone="itens.length > 0 && (showSaldoFisico || showSaldoFinanceiro)"
:items="itens"
hide-filters
hide-pagination
no-footer-sorting
>
<template
v-if="showSaldoFisico || showSaldoFinanceiro"
#thead-top
>
<rkm-tr>
<rkm-th
:colspan="showMaterial
? (showSubgrupo ? 4 : 3)
: (showSubgrupo ? 2 : 1)"
>
</rkm-th>
<rkm-th
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
class="text-center text-nowrap"
>
Saldo anterior
</rkm-th>
<rkm-th
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
class="text-center"
>
Entrada
</rkm-th>
<rkm-th
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
class="text-center"
>
Saída
</rkm-th>
<rkm-th
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
class="text-center text-nowrap"
>
Saldo atual
</rkm-th>
</rkm-tr>
</template>
<template #foot(materialCodigo)>
<span></span>
</template>
<template #foot(materialDescricao)>
<span></span>
</template>
<template #foot(grupoNome)>
<span></span>
</template>
<template #foot(subgrupoNome)>
<span></span>
</template>
<template #foot(saldoAnteriorFisico)>
<strong>{{ resultado.totalizadores.saldoAnteriorFisico }}</strong>
</template>
<template #foot(saldoAnteriorFinanceiro)>
<strong>{{ resultado.totalizadores.saldoAnteriorFinanceiro }}</strong>
</template>
<template #foot(saldoEntradaFisico)>
<strong>{{ resultado.totalizadores.saldoEntradaFisico }}</strong>
</template>
<template #foot(saldoEntradaFinanceiro)>
<strong>{{ resultado.totalizadores.saldoEntradaFinanceiro }}</strong>
</template>
<template #foot(saldoSaidaFisico)>
<strong>{{ resultado.totalizadores.saldoSaidaFisico }}</strong>
</template>
<template #foot(saldoSaidaFinanceiro)>
<strong>{{ resultado.totalizadores.saldoSaidaFinanceiro }}</strong>
</template>
<template #foot(saldoAtualFisico)>
<strong>{{ resultado.totalizadores.saldoAtualFisico }}</strong>
</template>
<template #foot(saldoAtualFinanceiro)>
<strong>{{ resultado.totalizadores.saldoAtualFinanceiro }}</strong>
</template>
</rkm-table>
</rkm-area>
</div>
</template>
<script>
import { repository, error } from '@/mixins'
import { mapActions } from 'vuex'
import moment from 'moment'
export default {
computed: {
validations() {
return {
periodo: { required: true },
}
},
fields() {
const codigoMaterial = { key: 'materialCodigo', label: 'Código', sortable: true, class: 'col-min text-center' }
const descricaoMaterial = { key: 'materialDescricao', label: 'Material', sortable: true }
const nomeGrupo = { key: 'grupoNome', label: 'Grupo', sortable: true }
const nomeSubgrupo = { key: 'subgrupoNome', label: 'Subgrupo', sortable: true }
const saldoAnteriorFisico = { key: 'saldoAnteriorFisico', label: 'Físico', class: 'col-min text-center' }
const saldoAnteriorFinanceiro = { key: 'saldoAnteriorFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
const entradaFisico = { key: 'saldoEntradaFisico', label: 'Físico', class: 'col-min text-center' }
const entradaFinanceiro = { key: 'saldoEntradaFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
const saidaFisico = { key: 'saldoSaidaFisico', label: 'Físico', class: 'col-min text-center' }
const saidaFinanceiro = { key: 'saldoSaidaFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
const saldoAtualFisico = { key: 'saldoAtualFisico', label: 'Físico', class: 'col-min text-center' }
const saldoAtualFinanceiro = { key: 'saldoAtualFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
let fields = []
if (this.showMaterial) {
fields.push(codigoMaterial)
fields.push(descricaoMaterial)
}
fields.push(nomeGrupo)
if (this.showSubgrupo) {
fields.push(nomeSubgrupo)
}
if (this.showSaldoFisico && this.showSaldoFinanceiro) {
fields = fields.concat([
saldoAnteriorFisico,
saldoAnteriorFinanceiro,
entradaFisico,
entradaFinanceiro,
saidaFisico,
saidaFinanceiro,
saldoAtualFisico,
saldoAtualFinanceiro,
])
}
else if (this.showSaldoFisico) {
fields = fields.concat([
saldoAnteriorFisico,
entradaFisico,
saidaFisico,
saldoAtualFisico,
])
}
else if (this.showSaldoFinanceiro) {
fields = fields.concat([
saldoAnteriorFinanceiro,
entradaFinanceiro,
saidaFinanceiro,
saldoAtualFinanceiro,
])
}
return fields
},
subgrupos() {
if (this.model.grupoId) {
return this.form.grupos.find(g => g.id === this.model.grupoId).subgrupos
}
return []
},
showMaterial() {
return !!this.selectedCols.find(c => c === 'material')
},
showSubgrupo() {
return !!this.selectedCols.find(c => c === 'subgrupo')
},
showSaldoFisico() {
return !!this.selectedCols.find(c => c === 'saldoFisico')
},
showSaldoFinanceiro() {
return !!this.selectedCols.find(c => c === 'saldoFinanceiro')
},
itens() {
if (this.showMaterial) {
return this.resultado.porMaterial
}
else if (this.showSubgrupo) {
return this.resultado.porSubgrupo
}
return this.resultado.porGrupo
}
},
created() {
this.repositories = {
balancete: this.getConectaSusRepository('almoxarifado.balancete'),
impressao: this.getConectaSusRepository('impressao.almoxarifado'),
}
this.load()
},
data: () => ({
loaded: false,
additionals: {},
form: {},
model: {},
selectedAll: true,
indeterminate: false,
resultado: {
porMaterial: [],
porSubgrupo: [],
porGrupo: [],
totalizadores: {},
},
columns: [
{ value: 'material', text: 'Material' },
{ value: 'subgrupo', text: 'Sugrupo' },
{ value: 'saldoFisico', text: 'Saldo físico' },
{ value: 'saldoFinanceiro', text: 'Saldo financeiro' },
],
selectedCols: [
'material',
'subgrupo',
'saldoFisico',
'saldoFinanceiro',
],
}),
methods: {
...mapActions(['setLoading', 'unsetLoading']),
load() {
this.setLoading()
this.repositories.balancete.list()
.then(({ data }) => {
this.additionals = data.additionals
this.form = data.form
this.model = data.model
this.$emit('additionals-load', this.additionals)
this.loaded = true
})
.catch(this.handleError)
.finally(() => this.unsetLoading())
},
search() {
this.setLoading()
this.repositories.balancete.index(this.getParams())
.then(({ data }) => this.resultado = data)
.catch(this.handleError)
.finally(() => this.unsetLoading())
},
clear() {
this.model.periodo.start = null
this.model.periodo.end = null
this.model.grupoId = null
this.model.subgrupoId = null
this.model.origemProgramaticaId = null
this.$nextTick().then(() => this.$refs.Form.resetValidator())
},
fecharBalancete() {
this.setLoading()
this.repositories.balancete.store()
.then(() => {
this.showSaveNotification();
this.$emit('save')
})
.catch(this.handleError)
.finally(() => this.unsetLoading())
},
handleSelectedColumns(selected) {
if (selected) {
this.columns
.filter(c => !this.selectedCols.includes(c.value))
.forEach(c => this.selectedCols.push(c.value))
return
}
this.selectedCols = []
},
print() {
this.setLoading()
const params = this.getParams()
params.selectedCols = this.selectedCols
this.repositories.impressao.balancete(params)
.then(response => {
const content = new Blob([response.data], { type: response.headers['content-type'] })
const url = URL.createObjectURL(content)
const link = document.createElement('a')
link.href = url
link.target = '_blank'
link.click()
link.remove()
})
.catch(this.handleError)
.finally(() => this.unsetLoading())
},
getParams() {
return {
inicio: moment(this.model.periodo.start).format('DD/MM/YYYY'),
fim: moment(this.model.periodo.end).format('DD/MM/YYYY'),
grupo_id: this.model.grupoId,
subgrupo_id: this.model.subgrupoId,
origem_programatica_id: this.model.origemProgramaticaId,
}
},
},
mixins: [repository, error],
watch: {
model: {
deep: true,
handler() {
this.resultado = {
porMaterial: [],
porSubgrupo: [],
porGrupo: [],
totalizadores: {},
}
}
},
'model.grupoId': function () {
this.model.subgrupoId = null
},
'selectedCols': function (newValue) {
this.selectedAll = newValue.length > 0 && newValue.length == this.columns.length
this.indeterminate = newValue.length > 0 && newValue.length != this.columns.length
},
}
}
</script>