|
|
@@ -24,6 +24,12 @@
|
|
|
:columns="columns"
|
|
|
:delete-function="onDelete"
|
|
|
>
|
|
|
+ <template #body-cell-parent="{ row }">
|
|
|
+ <q-td class="text-left">
|
|
|
+ {{ row.parent ? `${row.parent.code} — ${row.parent.description}` : "—" }}
|
|
|
+ </q-td>
|
|
|
+ </template>
|
|
|
+
|
|
|
<template #body-cell-chart_type="{ row }">
|
|
|
<q-td class="text-left">
|
|
|
<q-chip
|
|
|
@@ -39,6 +45,7 @@
|
|
|
<template #body-cell-actions="{ row }">
|
|
|
<q-td auto-width>
|
|
|
<q-btn
|
|
|
+ v-if="row.unit_id"
|
|
|
color="primary-2"
|
|
|
label="Editar"
|
|
|
dense
|
|
|
@@ -47,6 +54,15 @@
|
|
|
class="q-px-sm"
|
|
|
@click="openEdit(row)"
|
|
|
/>
|
|
|
+ <q-chip
|
|
|
+ v-else
|
|
|
+ dense
|
|
|
+ square
|
|
|
+ color="blue-grey-1"
|
|
|
+ text-color="blue-grey-7"
|
|
|
+ icon="mdi-lock-outline"
|
|
|
+ label="Matriz"
|
|
|
+ />
|
|
|
</q-td>
|
|
|
</template>
|
|
|
</DefaultTable>
|
|
|
@@ -61,15 +77,23 @@
|
|
|
|
|
|
<q-form ref="formRef">
|
|
|
<q-card-section class="q-gutter-sm">
|
|
|
+ <q-option-group
|
|
|
+ v-model="accountKind"
|
|
|
+ :options="kindOptions"
|
|
|
+ color="primary"
|
|
|
+ inline
|
|
|
+ dense
|
|
|
+ />
|
|
|
<div class="row q-col-gutter-sm">
|
|
|
<DefaultInput
|
|
|
v-model="form.code"
|
|
|
label="Código (ex.: 1.1.01)"
|
|
|
- class="col-5"
|
|
|
+ :class="accountKind === 'parent' ? 'col-5' : 'col-12'"
|
|
|
outlined
|
|
|
:rules="[(v) => !!v || 'Informe o código']"
|
|
|
/>
|
|
|
<DefaultSelect
|
|
|
+ v-if="accountKind === 'parent'"
|
|
|
v-model="form.chart_type"
|
|
|
label="Tipo"
|
|
|
:options="chartTypeOptions"
|
|
|
@@ -80,12 +104,32 @@
|
|
|
:rules="[(v) => !!v || 'Selecione o tipo']"
|
|
|
/>
|
|
|
</div>
|
|
|
+ <DefaultSelect
|
|
|
+ v-if="accountKind === 'child'"
|
|
|
+ v-model="form.parent_id"
|
|
|
+ label="Conta Pai"
|
|
|
+ :options="parentOptions"
|
|
|
+ option-value="id"
|
|
|
+ option-label="label"
|
|
|
+ outlined
|
|
|
+ emit-value
|
|
|
+ map-options
|
|
|
+ :loading="loadingParents"
|
|
|
+ :rules="[(v) => !!v || 'Selecione a conta pai']"
|
|
|
+ />
|
|
|
<DefaultInput
|
|
|
v-model="form.description"
|
|
|
label="Descrição"
|
|
|
outlined
|
|
|
:rules="[(v) => !!v || 'Informe a descrição']"
|
|
|
/>
|
|
|
+ <div
|
|
|
+ v-if="accountKind === 'child' && selectedParent"
|
|
|
+ class="text-caption text-grey-7"
|
|
|
+ >
|
|
|
+ Tipo herdado do pai:
|
|
|
+ <b>{{ chartTypeLabel(selectedParent.chart_type) }}</b>
|
|
|
+ </div>
|
|
|
</q-card-section>
|
|
|
|
|
|
<q-card-actions align="right" class="q-pa-md">
|
|
|
@@ -104,7 +148,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { onMounted, ref } from "vue";
|
|
|
+import { onMounted, ref, computed } from "vue";
|
|
|
import { useQuasar } from "quasar";
|
|
|
import {
|
|
|
getPlanAccountsMe,
|
|
|
@@ -128,9 +172,20 @@ const editing = ref(false);
|
|
|
const editingId = ref(null);
|
|
|
const formRef = ref(null);
|
|
|
|
|
|
-const defaultForm = () => ({ code: "", description: "", chart_type: "despesa" });
|
|
|
+const defaultForm = () => ({
|
|
|
+ code: "",
|
|
|
+ description: "",
|
|
|
+ chart_type: "despesa",
|
|
|
+ parent_id: null,
|
|
|
+});
|
|
|
const form = ref(defaultForm());
|
|
|
|
|
|
+const accountKind = ref("parent");
|
|
|
+const kindOptions = [
|
|
|
+ { label: "Conta Pai", value: "parent" },
|
|
|
+ { label: "Conta Filho", value: "child" },
|
|
|
+];
|
|
|
+
|
|
|
const chartTypeOptions = [
|
|
|
{ label: "Receita", value: "receita" },
|
|
|
{ label: "Despesa", value: "despesa" },
|
|
|
@@ -140,24 +195,43 @@ function chartTypeLabel(type) {
|
|
|
return chartTypeOptions.find((o) => o.value === type)?.label ?? type;
|
|
|
}
|
|
|
|
|
|
+const loadingParents = ref(false);
|
|
|
+const parentOptions = computed(() =>
|
|
|
+ rows.value
|
|
|
+ .filter((a) => a.id !== editingId.value)
|
|
|
+ .map((a) => ({
|
|
|
+ id: a.id,
|
|
|
+ label: `${a.code} — ${a.description}`,
|
|
|
+ chart_type: a.chart_type,
|
|
|
+ })),
|
|
|
+);
|
|
|
+const selectedParent = computed(() =>
|
|
|
+ parentOptions.value.find((o) => o.id === form.value.parent_id),
|
|
|
+);
|
|
|
+
|
|
|
const columns = [
|
|
|
{ name: "code", label: "Código", field: "code", align: "left", sortable: true },
|
|
|
{ name: "description", label: "Descrição", field: "description", align: "left" },
|
|
|
+ { name: "parent", label: "Conta Pai", field: "parent", align: "left" },
|
|
|
{ name: "chart_type", label: "Tipo", field: "chart_type", align: "left" },
|
|
|
{ name: "actions", label: "Ações", field: "actions", align: "right" },
|
|
|
];
|
|
|
|
|
|
async function loadData() {
|
|
|
+ loadingParents.value = true;
|
|
|
try {
|
|
|
rows.value = await getPlanAccountsMe();
|
|
|
} catch (e) {
|
|
|
console.error("Erro ao carregar plano de contas:", e);
|
|
|
+ } finally {
|
|
|
+ loadingParents.value = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function openCreate() {
|
|
|
editing.value = false;
|
|
|
editingId.value = null;
|
|
|
+ accountKind.value = "parent";
|
|
|
form.value = defaultForm();
|
|
|
dialog.value = true;
|
|
|
}
|
|
|
@@ -165,10 +239,12 @@ function openCreate() {
|
|
|
function openEdit(row) {
|
|
|
editing.value = true;
|
|
|
editingId.value = row.id;
|
|
|
+ accountKind.value = row.parent_id ? "child" : "parent";
|
|
|
form.value = {
|
|
|
code: row.code,
|
|
|
description: row.description,
|
|
|
chart_type: row.chart_type,
|
|
|
+ parent_id: row.parent_id ?? null,
|
|
|
};
|
|
|
dialog.value = true;
|
|
|
}
|
|
|
@@ -176,12 +252,24 @@ function openEdit(row) {
|
|
|
async function onSave() {
|
|
|
const valid = await formRef.value?.validate();
|
|
|
if (!valid) return;
|
|
|
+
|
|
|
+ const payload = {
|
|
|
+ code: form.value.code,
|
|
|
+ description: form.value.description,
|
|
|
+ };
|
|
|
+ if (accountKind.value === "child") {
|
|
|
+ payload.parent_id = form.value.parent_id;
|
|
|
+ } else {
|
|
|
+ payload.chart_type = form.value.chart_type;
|
|
|
+ payload.parent_id = null;
|
|
|
+ }
|
|
|
+
|
|
|
saving.value = true;
|
|
|
try {
|
|
|
if (editing.value) {
|
|
|
- await updatePlanAccountMe(editingId.value, form.value);
|
|
|
+ await updatePlanAccountMe(editingId.value, payload);
|
|
|
} else {
|
|
|
- await createPlanAccountMe(form.value);
|
|
|
+ await createPlanAccountMe(payload);
|
|
|
}
|
|
|
dialog.value = false;
|
|
|
await loadData();
|
|
|
@@ -193,6 +281,14 @@ async function onSave() {
|
|
|
}
|
|
|
|
|
|
function onDelete(id) {
|
|
|
+ const row = rows.value.find((r) => r.id === id);
|
|
|
+ if (row && !row.unit_id) {
|
|
|
+ $q.notify({
|
|
|
+ type: "negative",
|
|
|
+ message: "O plano de contas da Matriz não pode ser excluído pela unidade.",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
$q.dialog({
|
|
|
title: "Excluir conta",
|
|
|
message: "Tem certeza que deseja excluir esta conta do plano?",
|