Parcourir la source

Merge branch '采购退货'

lxf il y a 1 an
Parent
commit
a48e2c36a2

+ 161 - 0
src/components/process/returnGoods.vue

@@ -0,0 +1,161 @@
+<template>
+  <div>
+    <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" ref="submit">
+      <template #returnGoods>
+        <div style="width: 100%">
+          <div style="margin-bottom: 10px">
+            <el-button type="primary" @click="clickMateriel()" v-preReClick>新增退货</el-button>
+          </div>
+          <el-table :data="formData.data.purchaseReturnBomList" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
+            <el-table-column label="采购合同" prop="purchaseCode" width="160" />
+            <el-table-column label="品号" prop="bomSpecCode" width="140" />
+            <el-table-column label="品名" prop="bomSpecName" min-width="220" />
+            <el-table-column label="含税单价" prop="unitPrice" width="120" />
+            <el-table-column label="采购数量" prop="purchaseQuantity" width="120" />
+            <el-table-column label="已退货数量" prop="finishReturnQuantity" width="120" />
+            <el-table-column label="可退货数量" prop="canReturnQuantity" width="120" />
+            <el-table-column label="退货数量" prop="returnQuantity" width="120" />
+            <el-table-column label="当前退货金额" width="140">
+              <template #default="{ row }">
+                <span>{{ Number(Math.round(row.returnQuantity * row.unitPrice * 100) / 100) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="60">
+              <template #default="{ $index }">
+                <el-button type="danger" @click="clickDelete($index)" text>删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+    </byForm>
+
+    <el-dialog title="新增退货" v-if="openAdd" v-model="openAdd" width="90%">
+      <Goods @clickCancel="clickCancel"></Goods>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byForm from "/src/components/byForm/index";
+import { useRoute } from "vue-router";
+import { ElMessage } from "element-plus";
+import Goods from "/src/components/return-goods/index.vue";
+
+const route = useRoute();
+// 接收父组件的传值
+const props = defineProps({
+  queryData: Object,
+});
+const { proxy } = getCurrentInstance();
+const formData = reactive({
+  data: {
+    returnAmount: "",
+    purchaseReturnBomList: [],
+  },
+});
+const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
+  if (props.queryData.recordList && props.queryData.recordList.length > 0) {
+    let data = props.queryData.recordList.filter((item) => item.status === 2 && item.nodeType !== 1);
+    if (data && data.length > 0) {
+      return true;
+    }
+  }
+  return false;
+};
+const formOption = reactive({
+  inline: true,
+  labelWidth: "120px",
+  itemWidth: 100,
+  rules: [],
+  labelPosition: "right",
+  disabled: false,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "退货清单",
+      label: "",
+    },
+    {
+      type: "slot",
+      slotName: "returnGoods",
+    },
+  ];
+});
+const openAdd = ref(false);
+const clickMateriel = () => {
+  openAdd.value = true;
+};
+const clickCancel = (data) => {
+  openAdd.value = false;
+  if (data && data.length > 0) {
+    formData.data.purchaseReturnBomList = formData.data.purchaseReturnBomList.filter((item) => item.purchaseId !== data[0].purchaseId).concat(data);
+  }
+  console.log(getFormData());
+};
+const clickDelete = (index) => {
+  formData.data.purchaseReturnBomList.splice(index, 1);
+};
+const handleSubmit = async (flag) => {
+  if (flag) {
+    return true;
+  } else {
+    let status = await proxy.$refs.submit.handleSubmit(() => {});
+    if (status) {
+      if (!(formData.data.purchaseReturnBomList && formData.data.purchaseReturnBomList.length > 0)) {
+        ElMessage("请添加退货清单");
+        return false;
+      }
+      return true;
+    } else {
+      setTimeout(() => {
+        const errorDiv = document.getElementsByClassName("is-error");
+        errorDiv[0].scrollIntoView();
+      }, 0);
+    }
+    return false;
+  }
+};
+const getFormData = () => {
+  let returnAmount = 0;
+  for (let i = 0; i < formData.data.purchaseReturnBomList.length; i++) {
+    if (formData.data.purchaseReturnBomList[i].returnQuantity) {
+      returnAmount = Number(
+        Math.round((returnAmount + formData.data.purchaseReturnBomList[i].returnQuantity * formData.data.purchaseReturnBomList[i].unitPrice) * 100) / 100
+      );
+    }
+  }
+  formData.data.returnAmount = returnAmount;
+  return proxy.deepClone(formData.data);
+};
+watch(
+  () => props.queryData,
+  (newValue) => {
+    formOption.disabled = judgeStatus();
+    if (props.queryData && ["10", "20", "30", "40"].includes(route.query.processType)) {
+      formData.data = proxy.deepClone(newValue);
+    }
+  },
+  {
+    deep: true,
+  }
+);
+onMounted(() => {});
+// 向父组件暴露
+defineExpose({ getFormData, handleSubmit });
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+:deep(.el-dialog) {
+  margin-top: 10px !important;
+  margin-bottom: 10px !important;
+}
+</style>

+ 143 - 0
src/components/return-goods/index.vue

@@ -0,0 +1,143 @@
+<template>
+  <div>
+    <div style="max-height: calc(100vh - 174px); overflow-y: auto; overflow-x: hidden">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+        <template #purchaseId>
+          <div style="width: 100%">
+            <el-select v-model="formData.data.purchaseId" placeholder="采购合同" @change="changePurchase()">
+              <el-option v-for="item in purchaseList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+            </el-select>
+          </div>
+        </template>
+        <template #purchaseReturnBomList>
+          <div style="width: 100%">
+            <el-table :data="formData.data.purchaseReturnBomList" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
+              <el-table-column label="品号" prop="bomSpecCode" width="140" />
+              <el-table-column label="品名" prop="bomSpecName" min-width="220" />
+              <el-table-column label="含税单价" prop="unitPrice" width="120" />
+              <el-table-column label="采购数量" prop="purchaseQuantity" width="100" />
+              <el-table-column label="已退货数量" prop="finishReturnQuantity" width="100" />
+              <el-table-column label="剩余数量" prop="canReturnQuantity" width="100" />
+              <el-table-column label="含税小计" width="120">
+                <template #default="{ row }">
+                  <span>{{ Number(Math.round(row.purchaseQuantity * row.unitPrice * 100) / 100) }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="退货数量" width="120">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="'purchaseReturnBomList.' + $index + '.returnQuantity'" :rules="rules.returnQuantity" style="width: 100%">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.returnQuantity"
+                      placeholder="数量"
+                      style="width: 100%"
+                      :controls="false"
+                      :min="0"
+                      :max="row.canReturnQuantity" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="当前退货金额" width="140">
+                <template #default="{ row }">
+                  <span>{{ Number(Math.round(row.returnQuantity * row.unitPrice * 100) / 100) }}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+    </div>
+    <div style="text-align: center; margin: 10px">
+      <el-button @click="clickCancel()" size="large">取 消</el-button>
+      <el-button type="primary" @click="submitForm()" size="large" v-preReClick>确 定</el-button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import byForm from "/src/components/byForm/index";
+import { ElMessage } from "element-plus";
+
+const { proxy } = getCurrentInstance();
+const purchaseList = ref([]);
+const formOption = reactive({
+  inline: true,
+  labelWidth: "120px",
+  itemWidth: 100,
+  rules: [],
+  labelPosition: "right",
+});
+const formData = reactive({
+  data: {
+    purchaseId: "",
+    purchaseReturnBomList: [],
+  },
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      prop: "purchaseId",
+      slotName: "purchaseId",
+      label: "采购合同",
+      itemWidth: 50,
+    },
+    {
+      type: "slot",
+      slotName: "purchaseReturnBomList",
+      label: "",
+    },
+  ];
+});
+const rules = ref({
+  purchaseId: [{ required: true, message: "请选择采购合同", trigger: "change" }],
+  returnQuantity: [{ required: true, message: "请输入数量", trigger: "change" }],
+});
+const getDemandData = () => {
+  proxy.post("/purchase/getPurchaseSelectList", { pageNum: 1, pageSize: 9999, flowStatus: 2 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      purchaseList.value = purchaseList.value.concat(
+        res.rows.map((item) => {
+          return {
+            dictKey: item.id,
+            dictValue: item.code,
+          };
+        })
+      );
+    }
+  });
+};
+getDemandData();
+const changePurchase = () => {
+  formData.data.purchaseReturnBomList = [];
+  proxy.post("/purchaseReturn/getPurchaseBomPage", { id: formData.data.purchaseId }).then((res) => {
+    formData.data.purchaseReturnBomList = res;
+  });
+};
+const submitForm = () => {
+  proxy.$refs.submit.handleSubmit(() => {
+    if (formData.data.purchaseReturnBomList && formData.data.purchaseReturnBomList.length > 0) {
+      let list = formData.data.purchaseReturnBomList.filter((item) => item.returnQuantity > 0);
+      if (list && list.length > 0) {
+        list = list.map((item) => {
+          return {
+            ...item,
+            purchaseId: formData.data.purchaseId,
+          };
+        });
+        emit("clickCancel", list);
+      } else {
+        return ElMessage("请输入退货数量");
+      }
+    } else {
+      return ElMessage("请选择退货产品");
+    }
+  });
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", false);
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 202 - 0
src/views/group/purchase/return-goods/index.vue

@@ -0,0 +1,202 @@
+<template>
+  <el-card class="box-card">
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :searchConfig="searchConfig"
+      highlight-current-row
+      :action-list="[
+        {
+          text: '发起采购退货',
+          action: () => clickInitiateReturn(),
+        },
+      ]"
+      @get-list="getList"
+      @clickReset="clickReset">
+    </byTable>
+  </el-card>
+</template>
+
+<script setup>
+import byTable from "/src/components/byTable/index";
+import { flowStatus } from "/src/utils/flowStatus";
+
+const { proxy } = getCurrentInstance();
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+const loading = ref(false);
+const searchConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "flowStatus",
+      label: "流程状态",
+      data: flowStatus(),
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "采购退货单号",
+        prop: "code",
+        align: "center",
+      },
+    },
+    {
+      attrs: {
+        label: "关联合同数量",
+        prop: "purchaseCount",
+        align: "center",
+      },
+    },
+    {
+      attrs: {
+        label: "发起时间",
+        prop: "createTime",
+        align: "center",
+      },
+    },
+    {
+      attrs: {
+        label: "退货时间",
+        prop: "returnTime",
+        align: "center",
+      },
+    },
+    {
+      attrs: {
+        label: "发起人",
+        prop: "createName",
+        align: "center",
+      },
+    },
+    {
+      attrs: {
+        label: "流程状态",
+        prop: "flowStatus",
+        width: 120,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, flowStatus());
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: 260,
+        align: "center",
+        fixed: "right",
+      },
+      renderHTML(row) {
+        return [
+          row.flowStatus == 0
+            ? {
+                attrs: {
+                  label: "变更退货单",
+                  type: "danger",
+                  text: true,
+                },
+                el: "button",
+                click() {
+                  clickChange(row);
+                },
+              }
+            : {},
+          {
+            attrs: {
+              label: "打印退货单",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              console.log(row);
+            },
+          },
+          {
+            attrs: {
+              label: "查看详情",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickDetails(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getList = async (req, status) => {
+  if (status) {
+    sourceList.value.pagination = {
+      pageNum: sourceList.value.pagination.pageNum,
+      pageSize: sourceList.value.pagination.pageSize,
+    };
+  } else {
+    sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  }
+  loading.value = true;
+  proxy.post("/purchaseReturn/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getList();
+const clickReset = () => {
+  getList("", true);
+};
+const clickInitiateReturn = () => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "purchase_return",
+      flowName: "采购退货流程",
+      random: proxy.random(),
+    },
+  });
+};
+const clickDetails = (item) => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "purchase_return",
+      flowName: "采购退货流程",
+      processType: "20",
+      id: item.id,
+      flowId: item.flowId,
+      random: proxy.random(),
+    },
+  });
+};
+const clickChange = (item) => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "purchase_return",
+      flowName: "采购退货流程",
+      processType: "30",
+      businessId: item.id,
+      flowId: item.flowId,
+      random: proxy.random(),
+    },
+  });
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 10 - 8
src/views/process/processApproval/index.vue

@@ -32,8 +32,9 @@
         <Subscribe :queryData="detailsData.data" v-if="queryData.query.flowKey == 'apply_buy'" ref="makeDom"></Subscribe>
         <Purchase :queryData="detailsData.data" v-else-if="queryData.query.flowKey == 'purchase'" ref="makeDom"></Purchase>
         <Order :queryData="detailsData.data" v-else-if="queryData.query.flowKey == 'order'" ref="makeDom"></Order>
+        <ReturnGoods :queryData="detailsData.data" v-else-if="queryData.query.flowKey == 'purchase_return'" ref="makeDom"></ReturnGoods>
         <OrderDelete :queryData="detailsData.data" :recordList="recordList" v-else-if="queryData.query.flowKey == 'order_delete'" ref="makeDom"></OrderDelete>
-      </div>
+</div>
       <div class="bottom" v-if="route.query.processType != 20">
         <div class="commons-title title">处理意见</div>
         <el-form :model="flowForm" :rules="flowRules" ref="flowFormDom">
@@ -43,7 +44,7 @@
           <el-form-item>
             <el-button
               type="primary"
-              v-if="!queryData.query.processType || ['30', '40'].includes(queryData.query.processType)"
+              v-if="(!queryData.query.processType || ['30', '40'].includes(queryData.query.processType)) && queryData.query.flowKey != 'purchase_return'"
               @click="handleSaveDraft"
               v-preReClick>
               保存草稿
@@ -293,9 +294,9 @@ import Order from "/src/components/process/order";
 import refreshStore from "/src/store/modules/refresh";
 import SelectBOM from "/src/views/group/BOM/management/index";
 import SelectAssembly from "/src/components/selectAssembly/index";
+import ReturnGoods from "/src/components/process/returnGoods.vue";
 // 删除订单
 import OrderDelete from "/src/components/process/order-delete";
-
 const typeName = ref({
   10: "(审批)",
   20: "(详情)",
@@ -306,6 +307,7 @@ const keyName = ref({
   apply_buy: "申购流程",
   purchase: "采购流程",
   order: "新建订单流程",
+  purchase_return: "采购退货流程",
   order_delete: "订单删除流程",
 });
 const flowKeyCollect = reactive({
@@ -327,13 +329,16 @@ const flowKeyCollect = reactive({
     add: "/orderInfo/add",
     detail: "/orderInfo/detail",
   },
+  purchase_return: {
+    backPath: "/group/purchase/return-goods",
+    detail: "/purchaseReturn/detail",
+  },
   order_delete: {
     backPath: "/subsidiary/order/subsidiary-order-management",
     edit: "/orderInfo/edit",
     add: "/orderInfo/add",
     detail: "/orderInfo/detail",
-  },
-});
+  },});
 const detailsData = reactive({
   data: {},
 });
@@ -439,9 +444,6 @@ const skipPage = () => {
     });
   } else {
     ElMessage({ message: "操作成功!", type: "success" });
-    if (queryData.query.flowKey == "order") {
-      refreshStore().setRefresh("order");
-    }
     router.replace({
       path: flowKeyCollect[queryData.query.flowKey].backPath,
     });