Преглед изворни кода

feat: adiciona logica para criar/editar pacote

ebagabee пре 1 месец
родитељ
комит
de3e531184
2 измењених фајлова са 83 додато и 11 уклоњено
  1. 6 0
      src/api/product.js
  2. 77 11
      src/pages/packages/components/AddEditPackageDialog.vue

+ 6 - 0
src/api/product.js

@@ -0,0 +1,6 @@
+import api from "src/api";
+
+export const getProductsForSelect = async () => {
+  const { data } = await api.get("/product/all/select");
+  return data.payload;
+};

+ 77 - 11
src/pages/packages/components/AddEditPackageDialog.vue

@@ -65,16 +65,27 @@
                 >
                   <div class="row q-col-gutter-sm items-center">
                     <DefaultSelect
-                      v-model="material.type"
+                      v-model="material.product_id"
                       label="Material"
                       class="col"
-                      :options="[]"
+                      :options="productOptions"
+                      emit-value
+                      map-options
+                      @update:model-value="onProductSelected(material)"
+                    />
+
+                    <DefaultInput
+                      v-model="material.quantity"
+                      label="Qtd"
+                      class="col-2"
+                      type="number"
+                      min="1"
                     />
 
                     <DefaultCurrencyInput
-                      v-model="material.value"
-                      label="R$ 000,00"
-                      class="col-4"
+                      v-model="material.price"
+                      label="R$ Unitário"
+                      class="col-3"
                     />
 
                     <div class="col-auto">
@@ -86,7 +97,15 @@
                         style="border-radius: 8px; height: 40px; width: 40px"
                         @click="addMaterial"
                       />
-                      <div v-else style="width: 40px" />
+                      <q-btn
+                        v-else
+                        flat
+                        round
+                        dense
+                        icon="mdi-delete-outline"
+                        color="negative"
+                        @click="removeMaterial(index)"
+                      />
                     </div>
                   </div>
                 </div>
@@ -246,6 +265,7 @@ import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.v
 
 import { getUnitsForSelect } from "src/api/unit";
 import { getPackage, createPackage, updatePackage } from "src/api/package";
+import { getProductsForSelect } from "src/api/product";
 
 defineEmits([...useDialogPluginComponent.emits]);
 
@@ -269,20 +289,42 @@ const tabs = [
   { name: "unidades", label: "Unidades" },
 ];
 
+const products = ref([]);
+
+const productOptions = computed(() =>
+  products.value.map((p) => ({ label: p.name, value: p.id, price_sale: p.price_sale }))
+);
+
 const form = ref({
   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 }],
+  materials: [{ product_id: null, quantity: 1, price: null }],
 });
 
+const onProductSelected = (material) => {
+  const option = productOptions.value.find((o) => o.value === material.product_id);
+  if (option) material.price = option.price_sale;
+};
+
 const addMaterial = () => {
-  form.value.materials.push({ type: null, value: null });
+  form.value.materials.push({ product_id: null, quantity: 1, price: null });
 };
 
+const removeMaterial = (index) => {
+  form.value.materials.splice(index, 1);
+};
+
+const contractMaterialValue = computed(() =>
+  form.value.materials.reduce((sum, m) => {
+    const qty = Number(m.quantity) || 0;
+    const price = Number(m.price) || 0;
+    return sum + qty * price;
+  }, 0)
+);
+
 // Unidades tab
 const unitSearch = ref("");
 const units = ref([]);
@@ -302,14 +344,28 @@ const setAllVisible = (visible) => {
 onMounted(async () => {
   loadingUnits.value = true;
   try {
-    const allUnits = await getUnitsForSelect();
+    const [allUnits, allProducts] = await Promise.all([
+      getUnitsForSelect(),
+      getProductsForSelect(),
+    ]);
+
+    products.value = allProducts;
 
     let visibilityMap = {};
+    let savedMaterials = null;
+
     if (props.package?.id) {
       const pkg = await getPackage(props.package.id);
       (pkg.unit_visibilities ?? []).forEach((uv) => {
         visibilityMap[uv.unit_id] = uv.visible;
       });
+      if (pkg.materials?.length) {
+        savedMaterials = pkg.materials.map((m) => ({
+          product_id: m.product_id,
+          quantity: m.quantity,
+          price: m.price,
+        }));
+      }
     }
 
     units.value = allUnits.map((u) => ({
@@ -317,6 +373,10 @@ onMounted(async () => {
       fantasy_name: u.fantasy_name,
       visible: visibilityMap[u.id] ?? true,
     }));
+
+    if (savedMaterials) {
+      form.value.materials = savedMaterials;
+    }
   } finally {
     loadingUnits.value = false;
   }
@@ -325,17 +385,23 @@ onMounted(async () => {
 const onOKClick = async () => {
   loading.value = true;
   try {
+    const validMaterials = form.value.materials.filter((m) => m.product_id);
+
     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,
       })),
+      materials: validMaterials.map((m) => ({
+        product_id: m.product_id,
+        quantity: Number(m.quantity),
+        price: Number(m.price),
+      })),
     };
 
     const result = props.package?.id