Переглянути джерело

feat(contracts): add automatic protocol toggle and preview in student contract dialog

alvesantos 1 тиждень тому
батько
коміт
653672702e

+ 5 - 0
src/api/studentContract.js

@@ -10,6 +10,11 @@ export const getAllContracts = async () => {
   return data.payload;
 };
 
+export const getNextContractProtocol = async () => {
+  const { data } = await api.get("/franchisee/contracts/next-protocol");
+  return data.payload;
+};
+
 export const createStudentContract = async (payload) => {
   const { data } = await api.post("/franchisee/contracts", payload);
   return data.payload;

+ 10 - 5
src/api/unit.js

@@ -17,13 +17,18 @@ export const getUnitMe = async () => {
   return data.payload;
 };
 
-export const updateUnitMe = async (formData) => {
-  formData.append("_method", "PUT");
+export const updateUnitMe = async (payload) => {
+  if (payload instanceof FormData) {
+    payload.append("_method", "PUT");
 
-  const { data } = await api.post("/franchisee/unit", formData, {
-    headers: { "Content-Type": "multipart/form-data" },
-  });
+    const { data } = await api.post("/franchisee/unit", payload, {
+      headers: { "Content-Type": "multipart/form-data" },
+    });
+
+    return data.payload;
+  }
 
+  const { data } = await api.put("/franchisee/unit", payload);
   return data.payload;
 };
 

+ 64 - 3
src/pages/students/components/AddEditContractDialog.vue

@@ -107,8 +107,19 @@
                 </div>
               </template>
 
-              <div class="text-subtitle1 q-mt-lg q-mb-md">
-                Dados do Contrato
+              <div class="row items-center justify-between q-mt-lg q-mb-md">
+                <div class="text-subtitle1">
+                  Dados do Contrato
+                </div>
+
+                <q-toggle
+                  v-model="isAutomaticProtocol"
+                  color="primary"
+                  label="Protocolo automático"
+                  left-label
+                  dense
+                  @update:model-value="handleToggleAutomaticProtocol"
+                />
               </div>
 
               <div class="row q-col-gutter-sm">
@@ -116,6 +127,8 @@
                   <DefaultInput
                     v-model="form.protocol"
                     v-model:error="validationErrors.protocol"
+                    :disable="isAutomaticProtocol"
+                    :loading="loadingProtocol"
                     label="Protocolo"
                     :rules="[inputRules.max(255)]"
                   />
@@ -422,13 +435,14 @@ import {
 
 import {
   createStudentContract,
+  getNextContractProtocol,
   updateStudentContract,
 } from "src/api/studentContract";
 
 import { computed, nextTick, onMounted, ref, useTemplateRef, watch } from "vue";
 import { formatDateDMYtoYMD, formatDateYMDtoDMY } from "src/helpers/utils";
 import { getStudentsForSelect } from "src/api/student";
-import { getUnitMe } from "src/api/unit";
+import { getUnitMe, updateUnitMe } from "src/api/unit";
 import { getUnitPackagesForSelect } from "src/api/package";
 import { permissionStore } from "src/stores/permission";
 import { useDialogPluginComponent, useQuasar } from "quasar";
@@ -481,6 +495,8 @@ const scrollAreaRef = useTemplateRef("scrollAreaRef");
 const dateConfirmationOpen = ref(false);
 const dateOverrideConfirmed = ref(false);
 const filteredStudents = ref([]);
+const isAutomaticProtocol = ref(true);
+const loadingProtocol = ref(false);
 const packages = ref([]);
 const restoringDefaultDates = ref(false);
 const selectedStudent = ref(props.student);
@@ -1042,6 +1058,36 @@ watch(
   },
 );
 
+const handleToggleAutomaticProtocol = async (value) => {
+  try {
+    await updateUnitMe({ automatic_protocol: value });
+
+    if (unitDetails.value) {
+      unitDetails.value.automatic_protocol = value;
+    }
+
+    if (store.selectedUnit) {
+      store.selectedUnit.automatic_protocol = value;
+    }
+
+    if (value && !props.contract) {
+      loadingProtocol.value = true;
+      try {
+        const next = await getNextContractProtocol();
+        form.protocol = next?.protocol ?? "000001";
+      } finally {
+        loadingProtocol.value = false;
+      }
+    }
+  } catch (error) {
+    console.error("Falha ao salvar configuração de protocolo automático:", error);
+    $q.notify({
+      message: "Não foi possível atualizar a preferência de protocolo da unidade.",
+      type: "negative",
+    });
+  }
+};
+
 onMounted(async () => {
   const unitRequest = getUnitMe().catch((error) => {
     console.error("Falha ao carregar os dados da unidade:", error);
@@ -1062,6 +1108,21 @@ onMounted(async () => {
 
   unitDetails.value = unitData ?? store.selectedUnit ?? {};
 
+  isAutomaticProtocol.value = unitDetails.value?.automatic_protocol ?? true;
+
+  if (!props.contract && isAutomaticProtocol.value) {
+    loadingProtocol.value = true;
+    try {
+      const next = await getNextContractProtocol();
+      form.protocol = next?.protocol ?? "000001";
+    } catch (error) {
+      console.error("Falha ao carregar próximo protocolo:", error);
+      form.protocol = "000001";
+    } finally {
+      loadingProtocol.value = false;
+    }
+  }
+
   students.value = unitStudents;
   filteredStudents.value = unitStudents;
 });