|
|
@@ -30,7 +30,7 @@
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
- v-model="form.quantity"
|
|
|
+ v-model="form.quantity_classes"
|
|
|
label="Quantidade de Aulas"
|
|
|
class="col-12"
|
|
|
type="number"
|
|
|
@@ -38,19 +38,19 @@
|
|
|
/>
|
|
|
|
|
|
<DefaultCurrencyInput
|
|
|
- v-model="form.enrollment_fee"
|
|
|
+ v-model="form.contract_register_value"
|
|
|
label="R$ Matrícula"
|
|
|
class="col-4"
|
|
|
/>
|
|
|
|
|
|
<DefaultCurrencyInput
|
|
|
- v-model="form.total_contract"
|
|
|
+ v-model="form.contract_value"
|
|
|
label="R$ Total do Contrato"
|
|
|
class="col-4"
|
|
|
/>
|
|
|
|
|
|
<DefaultInput
|
|
|
- v-model="form.discount_percentage"
|
|
|
+ v-model="form.contrat_discount_value"
|
|
|
label="Desconto em %"
|
|
|
class="col-4"
|
|
|
type="number"
|
|
|
@@ -96,7 +96,7 @@
|
|
|
<!-- Tab: Unidades -->
|
|
|
<div v-show="currentTab === 'unidades'">
|
|
|
<div class="column q-gutter-y-sm">
|
|
|
- <!-- Visível para todas as Unidades / Grupos -->
|
|
|
+ <!-- Visível para todas as Unidades -->
|
|
|
<q-input
|
|
|
outlined
|
|
|
readonly
|
|
|
@@ -129,7 +129,7 @@
|
|
|
</template>
|
|
|
</q-input>
|
|
|
|
|
|
- <!-- Buscar Unidade / Grupo + botão + -->
|
|
|
+ <!-- Buscar -->
|
|
|
<div class="row items-center q-gutter-x-sm">
|
|
|
<q-input
|
|
|
v-model="unitSearch"
|
|
|
@@ -158,50 +158,57 @@
|
|
|
<!-- Lista de Unidades -->
|
|
|
<div
|
|
|
class="rounded-borders q-pa-sm"
|
|
|
- style="background-color: #f5f5f5"
|
|
|
+ style="background-color: #f5f5f5; max-height: 280px; overflow-y: auto"
|
|
|
>
|
|
|
- <div class="row items-center q-mb-xs q-px-sm">
|
|
|
- <q-icon
|
|
|
- name="mdi-account-multiple"
|
|
|
- color="secondary"
|
|
|
- size="sm"
|
|
|
- class="q-mr-xs"
|
|
|
- />
|
|
|
- <span class="text-body2">
|
|
|
- Unidades Ativas ({{ filteredUnits.length }})
|
|
|
- </span>
|
|
|
+ <div v-if="loadingUnits" class="flex flex-center q-py-md">
|
|
|
+ <q-spinner color="secondary" size="sm" />
|
|
|
</div>
|
|
|
|
|
|
- <q-separator class="q-mb-xs" />
|
|
|
+ <template v-else>
|
|
|
+ <div class="row items-center q-mb-xs q-px-sm">
|
|
|
+ <q-icon
|
|
|
+ name="mdi-account-multiple"
|
|
|
+ color="secondary"
|
|
|
+ size="sm"
|
|
|
+ class="q-mr-xs"
|
|
|
+ />
|
|
|
+ <span class="text-body2">
|
|
|
+ Unidades Ativas ({{ filteredUnits.length }})
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="row q-px-sm q-py-xs">
|
|
|
- <span class="col text-caption text-grey-6">Unidade</span>
|
|
|
- <span class="col-auto text-caption text-grey-6">Status</span>
|
|
|
- </div>
|
|
|
+ <q-separator class="q-mb-xs" />
|
|
|
|
|
|
- <template v-for="unit in filteredUnits" :key="unit.id">
|
|
|
- <q-separator />
|
|
|
- <div class="row items-center q-px-sm q-py-sm">
|
|
|
- <span class="col text-body2">{{ unit.name }}</span>
|
|
|
- <div class="col-auto row q-gutter-x-xs">
|
|
|
- <q-btn
|
|
|
- round
|
|
|
- unelevated
|
|
|
- color="positive"
|
|
|
- icon="mdi-check"
|
|
|
- size="xs"
|
|
|
- @click="unit.active = true"
|
|
|
- />
|
|
|
- <q-btn
|
|
|
- round
|
|
|
- outline
|
|
|
- color="negative"
|
|
|
- icon="mdi-close"
|
|
|
- size="xs"
|
|
|
- @click="unit.active = false"
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <div class="row q-px-sm q-py-xs">
|
|
|
+ <span class="col text-caption text-grey-6">Unidade</span>
|
|
|
+ <span class="col-auto text-caption text-grey-6">Status</span>
|
|
|
</div>
|
|
|
+
|
|
|
+ <template v-for="unit in filteredUnits" :key="unit.id">
|
|
|
+ <q-separator />
|
|
|
+ <div class="row items-center q-px-sm q-py-sm">
|
|
|
+ <span class="col text-body2">{{ unit.fantasy_name }}</span>
|
|
|
+ <div class="col-auto row q-gutter-x-xs">
|
|
|
+ <q-btn
|
|
|
+ round
|
|
|
+ unelevated
|
|
|
+ :color="unit.visible ? 'positive' : 'grey-4'"
|
|
|
+ icon="mdi-check"
|
|
|
+ size="xs"
|
|
|
+ @click="unit.visible = true"
|
|
|
+ />
|
|
|
+ <q-btn
|
|
|
+ round
|
|
|
+ :outline="unit.visible"
|
|
|
+ :unelevated="!unit.visible"
|
|
|
+ :color="unit.visible ? 'negative' : 'negative'"
|
|
|
+ icon="mdi-close"
|
|
|
+ size="xs"
|
|
|
+ @click="unit.visible = false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -229,7 +236,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, computed } from "vue";
|
|
|
+import { ref, computed, onMounted } from "vue";
|
|
|
import { useDialogPluginComponent } from "quasar";
|
|
|
|
|
|
import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
|
|
|
@@ -237,9 +244,12 @@ import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
|
|
|
|
|
|
+import { getUnitsForSelect } from "src/api/unit";
|
|
|
+import { getPackage, createPackage, updatePackage } from "src/api/package";
|
|
|
+
|
|
|
defineEmits([...useDialogPluginComponent.emits]);
|
|
|
|
|
|
-defineProps({
|
|
|
+const props = defineProps({
|
|
|
package: {
|
|
|
type: Object,
|
|
|
default: null,
|
|
|
@@ -251,6 +261,7 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
|
|
|
|
|
const formRef = ref(null);
|
|
|
const loading = ref(false);
|
|
|
+const loadingUnits = ref(false);
|
|
|
const currentTab = ref("informacoes");
|
|
|
|
|
|
const tabs = [
|
|
|
@@ -259,11 +270,12 @@ const tabs = [
|
|
|
];
|
|
|
|
|
|
const form = ref({
|
|
|
- name: null,
|
|
|
- quantity: null,
|
|
|
- enrollment_fee: null,
|
|
|
- total_contract: null,
|
|
|
- discount_percentage: null,
|
|
|
+ name: props.package?.name ?? null,
|
|
|
+ quantity_classes: props.package?.quantity_classes ?? null,
|
|
|
+ contract_register_value: props.package?.contract_register_value ?? null,
|
|
|
+ contract_value: props.package?.contract_value ?? null,
|
|
|
+ contrat_discount_value: props.package?.contrat_discount_value ?? null,
|
|
|
+ contract_material_value: props.package?.contract_material_value ?? null,
|
|
|
materials: [{ type: null, value: null }],
|
|
|
});
|
|
|
|
|
|
@@ -271,26 +283,68 @@ const addMaterial = () => {
|
|
|
form.value.materials.push({ type: null, value: null });
|
|
|
};
|
|
|
|
|
|
-// Unidades tab state
|
|
|
+// Unidades tab
|
|
|
const unitSearch = ref("");
|
|
|
-
|
|
|
-const units = ref([
|
|
|
- { id: 1, name: "Unidade 1", active: true },
|
|
|
- { id: 2, name: "Unidade 2", active: true },
|
|
|
- { id: 3, name: "Unidade 3", active: true },
|
|
|
-]);
|
|
|
+const units = ref([]);
|
|
|
|
|
|
const filteredUnits = computed(() => {
|
|
|
const q = unitSearch.value.toLowerCase();
|
|
|
if (!q) return units.value;
|
|
|
- return units.value.filter((u) => u.name.toLowerCase().includes(q));
|
|
|
+ return units.value.filter((u) =>
|
|
|
+ u.fantasy_name.toLowerCase().includes(q)
|
|
|
+ );
|
|
|
});
|
|
|
|
|
|
-const setAllVisible = (active) => {
|
|
|
- units.value.forEach((u) => (u.active = active));
|
|
|
+const setAllVisible = (visible) => {
|
|
|
+ units.value.forEach((u) => (u.visible = visible));
|
|
|
};
|
|
|
|
|
|
-const onOKClick = () => {
|
|
|
- onDialogOK(form.value);
|
|
|
+onMounted(async () => {
|
|
|
+ loadingUnits.value = true;
|
|
|
+ try {
|
|
|
+ const allUnits = await getUnitsForSelect();
|
|
|
+
|
|
|
+ let visibilityMap = {};
|
|
|
+ if (props.package?.id) {
|
|
|
+ const pkg = await getPackage(props.package.id);
|
|
|
+ (pkg.unit_visibilities ?? []).forEach((uv) => {
|
|
|
+ visibilityMap[uv.unit_id] = uv.visible;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ units.value = allUnits.map((u) => ({
|
|
|
+ id: u.id,
|
|
|
+ fantasy_name: u.fantasy_name,
|
|
|
+ visible: visibilityMap[u.id] ?? true,
|
|
|
+ }));
|
|
|
+ } finally {
|
|
|
+ loadingUnits.value = false;
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const onOKClick = async () => {
|
|
|
+ loading.value = true;
|
|
|
+ try {
|
|
|
+ const payload = {
|
|
|
+ name: form.value.name,
|
|
|
+ quantity_classes: form.value.quantity_classes,
|
|
|
+ contract_value: form.value.contract_value,
|
|
|
+ contract_material_value: form.value.contract_material_value,
|
|
|
+ contract_register_value: form.value.contract_register_value,
|
|
|
+ contrat_discount_value: form.value.contrat_discount_value,
|
|
|
+ unit_visibilities: units.value.map((u) => ({
|
|
|
+ unit_id: u.id,
|
|
|
+ visible: u.visible,
|
|
|
+ })),
|
|
|
+ };
|
|
|
+
|
|
|
+ const result = props.package?.id
|
|
|
+ ? await updatePackage(props.package.id, payload)
|
|
|
+ : await createPackage(payload);
|
|
|
+
|
|
|
+ onDialogOK(result);
|
|
|
+ } finally {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
};
|
|
|
</script>
|