Просмотр исходного кода

feat: 添加报价方式、折让比例字段及收款计划功能,发货单发货数量需要大于0

liujt 5 месяцев назад
Родитель
Сommit
1e4c98e29f

+ 80 - 4
src/BIZComponents/inventoryTableNew.vue

@@ -710,6 +710,53 @@
           </el-input>
         </el-form-item>
       </template>
+
+      <template v-slot:quoteWay="scope">
+        <el-form-item prop="quoteWay">
+          <el-select
+            v-model="scope.row.quoteWay"
+            clearable
+            filterable
+          >
+            <el-option
+              v-for="i in quoteTypeOp"
+              :key="i.value"
+              :value="i.value"
+              :label="i.label"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </template>
+      <template v-slot:headerQuoteWay="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:discountRatio="scope">
+        <el-form-item
+          :prop="'datasource.' + scope.$index + '.discountRatio'"
+          :rules="{
+            required: isDiscount == 1 ? true : false,
+            message: '请输入折让比例',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            v-model="scope.row.discountRatio"
+            placeholder="请输入"
+            type="number"
+            :disabled="quoteType === 2"
+            @input="getDiscountRatioPrice(scope.row)"
+          >
+            <template slot="append">%</template>
+          </el-input>
+        </el-form-item>
+      </template>
+
+      <template v-slot:headerDiscountRatio="{ column }">
+        <span :class="isDiscount ? 'is-required' : ''">{{
+          column.label
+        }}</span>
+      </template>
       <!-- <template v-slot:saleUnit="scope">
         <el-form-item
           :prop="'datasource.' + scope.$index + '.' + countObj.unitIdKey"
@@ -938,7 +985,7 @@
   import tabMixins from '@/mixins/tableColumnsMixin';
   import commodityPriceListDialog from '@/views/commodityManagement/commodityPriceList/components/commodityPriceListDialog.vue';
   const dayjs = require('dayjs');
-  import { levelList } from '@/enum/dict.js';
+  import { levelList, quoteTypeOp } from '@/enum/dict.js';
   import {
     getGoodsPriceByCondition,
     getGoodsByCategoryId
@@ -1116,7 +1163,7 @@
         extraTax: '',
         quotationSubtotalTax: '',
         // 新增未税小记字段
-        quotationSubtotalBeforeTax: ''
+        quotationSubtotalBeforeTax: '',
       };
       return {
         levelList,
@@ -1138,7 +1185,8 @@
           { label: '分批到货', value: 2 }
         ],
         columnsVersion: 1,
-        selection: []
+        selection: [],
+        quoteTypeOp
       };
     },
     computed: {
@@ -1229,7 +1277,15 @@
             slot: 'saleCount',
             headerSlot: this.isTotalCount ? 'headerTotalCount' : '',
             align: 'center'
-          }
+          },
+          {
+            width: 250,
+            prop: 'quoteWay',
+            label: '报价方式',
+            slot: 'quoteWay',
+            headerSlot: 'headerQuoteWay',
+            align: 'center'
+          },
         ];
 
         // 当quoteType为2时添加生产加工相关列
@@ -1419,6 +1475,15 @@
 
             isNone: this.quoteType === 2
           },
+          {
+            width: 160,
+            prop: 'discountRatio',
+            label: '折让比例',
+            align: 'center',
+            isNone: !this.isDiscount,
+            slot: 'discountRatio',
+            headerSlot: 'headerDiscountRatio'
+          },
           {
             width: 160,
             prop: 'discountSinglePrice',
@@ -1947,6 +2012,17 @@
         });
       },
 
+      // 计算优惠后单价
+      getDiscountRatioPrice(row) {
+        // if (row.discountRatio) {
+        //   row.discountSinglePrice = (
+        //     row.singlePrice * (1 - row.discountRatio / 100)
+        //   ).toFixed(2);
+        // } else {
+        //   row.discountSinglePrice = '';
+        // }
+      },
+
       //计算不含税单价
       getNotaxSinglePrice() {
         this.form.datasource.forEach((item, index) => {

+ 34 - 29
src/BIZComponents/paymentCollectionPlan/Index.vue

@@ -23,8 +23,8 @@
             </el-button>
 
             <div class="pricebox">
-                <span class="amount">比例合计:{{ allRatio }}</span>
-                <span class="amount">计划收款金额合计:{{ allPrice }}元</span>
+                <span class="amount">比例合计:{{ allRatio }}%</span>
+                <span class="amount">计划收款金额合计:{{ discountAmount }}元</span>
 
                 <!-- <el-form-item
                     style="width: 300px"
@@ -53,12 +53,16 @@
         </div>
       </template>
 
-      <template v-slot:headerPeriod="{ column }">
+      <template v-slot:headerIssueNumber="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template> 
+
+      <template v-slot:headerType="{ column }">
         <span class="is-required">{{ column.label }}</span>
       </template>
 
-      <template v-slot:period="scope">
-        <span>第{{ scope.row.period }}期</span>
+      <template v-slot:issueNumber="scope">
+        <span>第{{ scope.row.issueNumber }}期</span>
       </template>
 
       <template v-slot:moneyName="scope">
@@ -234,10 +238,10 @@
         ratio: null,
         remark: '',
         type: '',
-        period: null
+        issueNumber: null
       };
       return {
-        // allPrice: 0,
+        allPrice: 0,
         // allRatio: 0,
         numberReg,
         defaultForm,
@@ -264,10 +268,10 @@
             fixed: 'left'
           },
           {
-            prop: 'period',
+            prop: 'issueNumber',
             label: '期数',
-            slot: 'period',
-            headerSlot: 'headerPeriod',
+            slot: 'issueNumber',
+            headerSlot: 'headerIssueNumber',
             align: 'center'
           },
           {
@@ -275,7 +279,7 @@
             prop: 'type',
             label: '款项类型',
             slot: 'type',
-            headerSlot: 'headerMoneyName',
+            headerSlot: 'headerType',
             align: 'center'
           },
           {
@@ -332,9 +336,9 @@
       allRatio() {
         return this.form.datasource.reduce((acc, cur) => acc + Number(cur.ratio), 0).toFixed(2);
       },
-      allPrice() {
-        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.price), 0).toFixed(2);
-      },
+      // allPrice() {
+      //   return this.form.datasource.reduce((acc, cur) => acc + Number(cur.price), 0).toFixed(2);
+      // },
     },
     watch: {
       discountAmount(newval) {
@@ -437,29 +441,29 @@
           n.key = index + 1;
         });
       },
-      defaultList(method, period, dateRange) {
-        console.log('method, period', method, period);
+      defaultList(method, issueNumber, dateRange) {
+        console.log('method, issueNumber', method, issueNumber);
         const tempList = []
         if(dateRange) {
-          this.setDefaultList(dateRange, period);
+          this.setDefaultList(dateRange, issueNumber);
           return
         }
         if(method == 3) {
           let params = ['预付款', '交货款'];
-          for(let i = 0; i < period; i++) {
-            let i = JSON.parse(JSON.stringify(this.defaultForm));
-              i.moneyName = item;
-              i.type = i < params.length ? this.paymentTypeOp[index].value : '';
-              i.key = index + 1;
-              i.period = index + 1;
-              tempList.push(i);
+          for(let i = 0; i < issueNumber; i++) {
+            let item = JSON.parse(JSON.stringify(this.defaultForm));
+              item.moneyName = i < params.length ? params[i] : '';
+              item.type = i < params.length ? this.paymentTypeOp[i].value : '';
+              item.key = i + 1;
+              item.issueNumber = i + 1;
+              tempList.push(item);
           }
           // params.forEach((item, index) => {
           //     let i = JSON.parse(JSON.stringify(this.defaultForm));
           //     i.moneyName = item;
           //     i.type = this.paymentTypeOp[index].value;
           //     i.key = index + 1;
-          //     i.period = index + 1;
+          //     i.issueNumber = index + 1;
           //     tempList.push(i);
           // });
         } else {
@@ -468,10 +472,11 @@
           params.forEach((item, index) => {
               let i = JSON.parse(JSON.stringify(this.defaultForm));
               i.key = index + 1;
-              i.period = index + 1;
+              i.issueNumber = index + 1;
               tempList.push(i);
           });
         }
+        console.log('tempList~~~', tempList);
         this.form.datasource = tempList;
       },
 
@@ -536,8 +541,8 @@
         }
         return allMonthDates;
       },
-      setDefaultList(dateRange, period) {
-        const tempPeriod = period || 0;
+      setDefaultList(dateRange, issueNumber) {
+        const tempPeriod = issueNumber || 0;
 
         // 计算基本比例
         const basicRatio = 100 / tempPeriod;
@@ -553,7 +558,7 @@
           const deadLine = i < dateRange.length ? dateRange[i] : '';
           const ratio = parseFloat(basicRatio.toFixed(2));
 
-          item.period = i + 1;
+          item.issueNumber = i + 1;
           item.deadLine = deadLine;
           item.ratio = ratio;
 

+ 57 - 0
src/enum/dict.js

@@ -264,6 +264,63 @@ export const relationTypeOption = {
   3: '销售退货单'
 };
 
+export const shippingModeOp = [
+  {
+    value: 1,
+    label: '发货再对账'
+  },
+  {
+    value: 2,
+    label: '对账再发货'
+  }
+];
+
+export const quoteTypeOp = [
+  {
+    value: 1,
+    label: '常规价'
+  },
+  {
+    value: 2,
+    label: '内部价'
+  },
+  {
+    value: 3,
+    label: '议价'
+  }
+];
+
+export const transactionMethodsOp = [
+  {
+    value: 1,
+    label: '先票后款'
+  },
+  {
+    value: 2,
+    label: '先款后票'
+  }
+];
+
+// 付款类型下拉
+export const paymentTypeOp = [
+  {
+    value: 1,
+    label: '预付款'
+  },
+  {
+    value: 2,
+    label: '交货款'
+  },
+  {
+    value: 3,
+    label: '质保金'
+  },
+  {
+    value: 4,
+    label: '尾款'
+  }
+]
+
 //委外订单来源类型
 
 export const orderSourceType = ['3', '4', '5', '6', '7'];

+ 136 - 36
src/views/saleManage/saleOrder/components/addDialogNew.vue

@@ -97,14 +97,14 @@
             <el-input v-model="form.createDeptName" :disabled="true"></el-input>
           </el-form-item>
 
-          <el-form-item prop="productionRequirements" label="备注">
+          <!-- <el-form-item prop="productionRequirements" label="备注">
             <el-input
               clearable
               v-model="form.productionRequirements"
               placeholder="请输入"
               type="textarea"
             />
-          </el-form-item>
+          </el-form-item> -->
 
           <!-- <el-form-item label="预销售订单编码" prop="preOrderNo">
             <el-input
@@ -272,18 +272,11 @@
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="交易方式" prop="transactionMethods">
-            <!-- <DictSelection
-              dictName="结算方式"
-              clearable
-              @itemChange="settlementModeChange"
-              v-model="form.settlementMode"
-            >
-            </DictSelection> -->
+          <el-form-item label="交易方式" prop="transactionMode">
             <el-select
-              v-model="form.transactionMethods"
+              v-model="form.transactionMode"
               placeholder="请选择"
-              @change="onchangeLink"
+              @change="transactionModeChange"
               style="width: 100%"
             >
               <el-option
@@ -295,18 +288,11 @@
               </el-option>
             </el-select>
           </el-form-item>
-          <el-form-item label="发货模式" prop="shippingMode">
-            <!-- <DictSelection
-              dictName="结算方式"
-              clearable
-              @itemChange="settlementModeChange"
-              v-model="form.settlementMode"
-            >
-            </DictSelection> -->
+          <el-form-item label="发货模式" prop="deliveryMode">
             <el-select
-              v-model="form.shippingMode"
+              v-model="form.deliveryMode"
               placeholder="请选择"
-              @change="onchangeLink"
+              @change="deliveryModeChange"
               style="width: 100%"
             >
               <el-option
@@ -327,7 +313,7 @@
             >
             </DictSelection>
           </el-form-item>
-          <el-form-item v-if="form.settlementMode == 1" label="结算日期范围" prop="trafficDate">
+          <el-form-item v-if="form.settlementMode == 1" label="结算日期范围" prop="settlementDate">
             <!-- <el-date-picker
               v-model="form.contractStartDate"
               @change="setDeliveryDays"
@@ -338,17 +324,17 @@
             </el-date-picker> -->
             <el-date-picker
               style="width: 100%"
-              v-model="trafficDate"
+              v-model="settlementDate"
               type="daterange"
               value-format="yyyy-MM-dd"
               range-separator="至"
               start-placeholder="开始日期"
               end-placeholder="结束日期"
-              @change="trafficDateChange">
+              @change="settlementDateChange">
             </el-date-picker>
           </el-form-item>
 
-          <el-form-item v-if="form.settlementMode == 2" label="结算月份范围" prop="trafficDate">
+          <el-form-item v-if="form.settlementMode == 2" label="结算月份范围" prop="settlementDate">
             <!-- <el-date-picker
               v-model="form.contractEndDate"
               type="date"
@@ -357,14 +343,14 @@
             >
             </el-date-picker> -->
             <el-date-picker
-              v-model="trafficDate"
+              v-model="settlementDate"
               type="monthrange"
               range-separator="至"
               start-placeholder="开始月份"
               end-placeholder="结束月份"
               value-format="yyyy-MM"
               style="width: 100%"
-              @change="trafficDateChange"
+              @change="settlementDateChange"
             >
             </el-date-picker>
           </el-form-item>
@@ -376,9 +362,9 @@
           </el-form-item>
           <el-form-item
             label="期数"
-            prop="period"
+            prop="issueNumber"
           >
-            <el-input type="number" :min="1" v-model="form.period">
+            <el-input type="number" :min="1" v-model="form.issueNumber" @input="issueNumberChange">
               <template slot="append">
                 <span>期</span>
               </template>
@@ -654,6 +640,15 @@
           </el-form-item>
         </el-col>
       </el-row>
+
+      <headerTitle
+        title="收款计划"
+        style="margin-top: 30px"
+      ></headerTitle>
+      <PaymentCollectionPlan
+        ref="paymentCollectionPlanRef"
+      ></PaymentCollectionPlan>
+
     </el-form>
 
     <div slot="footer" class="footer">
@@ -725,7 +720,7 @@
 
 <script>
   import { emailReg, numberReg, telReg } from 'ele-admin';
-  import inventoryTable from '@/BIZComponents/inventoryTable.vue';
+  import inventoryTable from '@/BIZComponents/inventoryTableNew.vue';
   import fileUpload from '@/components/upload/fileUpload';
   import dictMixins from '@/mixins/dictMixins';
   import parentList from '@/views/saleManage/contact/components/parentList.vue';
@@ -768,6 +763,7 @@
   import opportunityDialog from '@/views/financialManage/components/opportunityDialog.vue';
   import { mapGetters } from 'vuex';
   import personSelect from '@/components/CommomSelect/person-select.vue';
+  import PaymentCollectionPlan from '@/BIZComponents/paymentCollectionPlan/Index.vue'
   import { shippingModeOp, transactionMethodsOp } from '@/enum/dict.js';
   export default {
     mixins: [dictMixins],
@@ -788,6 +784,7 @@
       saleOrderListDialog,
       opportunityDialog,
       personSelect,
+      PaymentCollectionPlan
     },
     props: {
       contactData: {
@@ -851,10 +848,19 @@
         relationCode: '',
         relationId: '',
         createDeptName: '',
-        salesmanId: ''
+        salesmanId: '',
+        issueNumber: 1,
+        transactionMode: 1,
+        deliveryMode: 1,
+        settlementDate: [],
+        endSettlementDate: '',
+        startSettlementDate: ''
       };
 
       return {
+        shippingModeOp,
+        transactionMethodsOp,
+        settlementDate: [],
         returnOrderDialogFlag: false,
         customerMark: '',
         opportunityDialogFlag: false,
@@ -1043,12 +1049,14 @@
       setCountAmount(allPrice) {
         this.form.totalAmount = allPrice;
         this.form.payAmount = allPrice;
+        this.$refs.paymentCollectionPlanRef.setDiscountAmount(this.form.payAmount);
       },
       setTotalPlanNum(totalPlanNum) {
         this.$set(this.form, 'totalPlanNum', totalPlanNum);
       },
       discountInput() {
         this.$refs.inventoryTable.discountInputByOrder(this.form.payAmount);
+        this.$refs.paymentCollectionPlanRef.setDiscountAmount(this.form.payAmount);
       },
       // 选择负责人部门
       change_principalDep(id) {
@@ -1684,6 +1692,9 @@
           }
           this.form.createDeptName = this.user.info.groupName;
           this.form.saleType = 1;
+          this.$nextTick(() => {
+            this.issueNumberChange(this.form.issueNumber);
+          })
           // this.form.progress = 700;
           //嘉实默认值
           if (this.clientEnvironmentId == 5) {
@@ -1751,9 +1762,29 @@
         this.form.partbAddress = data.address;
       },
 
-      settlementModeChange(info) {
-        this.form.settlementModeName = info.dictValue;
-      },
+      // 交易方式改变
+      transactionModeChange(v) {
+
+      }, 
+      // 配送方式改变
+      deliveryModeChange(v) {
+
+      }, 
+
+      // 结算方式改变
+      settlementModeChange(v) {
+        console.log('v~~~', v.dictCode);
+        // this.$set(this.form, 'issueNumber', 1);
+        this.$set(this.form, 'settlementDate', []);
+        this.$set(this.form, 'receiptDate', '');
+        
+        if(v.dictCode == 3) {
+          this.$set(this.form, 'issueNumber', 2);
+        } else {
+          this.$set(this.form, 'issueNumber', 1);
+        }
+        this.$refs.paymentCollectionPlanRef.defaultList(v.dictCode, this.form.issueNumber);
+      }, 
       ifChiefChange(value, idx) {
         if (value === 1) {
           this.tableLinkData.forEach((e) => (e.ifChief = 0));
@@ -1952,7 +1983,76 @@
           }
         }
         return null;
-      }
+      },
+      // 日期范围变化
+      settlementDateChange(val) {
+        // console.log(val);
+        let dateRange = [];
+        if(this.form.settlementMode == 1) {
+        //   // this.transformDays(val)
+          dateRange = this.transformDaysFun(val);
+        }
+        if(this.form.settlementMode == 2) {
+        //   // this.transformMonth(val)
+          dateRange = this.transformMonthFun(val);
+        }
+        // console.log('dateRange~~~', dateRange);
+        this.$set(this.form, 'issueNumber', dateRange.length);
+        // this.setDefaultList(dateRange)
+        this.$refs.paymentCollectionPlanRef.defaultList(this.form.settlementMode, this.form.issueNumber, dateRange);
+      },
+      // 收款日变化
+      receiptDateChange(v) {
+        // this.transformMonth(this.form.settlementDate)
+        if(this.form.settlementDate.length > 0 && this.form.issueNumber) {
+          const dateRange = this.transformMonthFun(this.form.settlementDate, v);
+          this.$refs.paymentCollectionPlanRef.defaultList(this.form.settlementMode, this.form.issueNumber, dateRange);
+        }
+      },
+      // 期数变化
+      issueNumberChange(v) {
+        let dateRange = [];
+        if(this.form.settlementMode == 1) {
+          dateRange = this.transformDaysFun(this.form.settlementDate, v);
+          this.$refs.paymentCollectionPlanRef.defaultList(this.form.settlementMode, v, dateRange); 
+        } else if(this.form.settlementMode == 2) {
+          dateRange = this.transformMonthFun(this.form.settlementDate, v);
+          this.$refs.paymentCollectionPlanRef.defaultList(this.form.settlementMode, v, dateRange);
+        } else {
+          this.$refs.paymentCollectionPlanRef.defaultList(this.form.settlementMode, v);
+        }
+      },
+      transformMonthFun(date, day) {
+        // 处理月份数据(转换为Date对象)
+        const parseMonthDate = (dateStr) => {
+          return dateStr instanceof Date ? dateStr : new Date(dateStr + '-01');
+        };
+        
+        const start = parseMonthDate(date[0]);
+        const end = parseMonthDate(date[1]);
+        
+        // 先生成所有月份的日期数组
+        const allMonthDates = [];
+        const currentDate = new Date(start);
+        
+        // 遍历从开始月份到结束月份的所有月份
+        while (currentDate <= end) {
+          const year = currentDate.getFullYear();
+          const month = currentDate.getMonth() + 1; // 月份从0开始,需要+1
+          const receiptDate = day;
+          
+          // 格式化日期为YYYY-MM-dd
+          const formattedMonth = String(month).padStart(2, '0');
+          const formattedDate = String(receiptDate).padStart(2, '0');
+          const deadLine = receiptDate ? `${year}-${formattedMonth}-${formattedDate}` : '';
+          
+          allMonthDates.push(deadLine);
+          
+          // 使用Date对象的setMonth方法正确移动到下一个月(自动处理年份变化)
+          currentDate.setMonth(currentDate.getMonth() + 1);
+        }
+        return allMonthDates;
+      },
     }
   };
 </script>

+ 13 - 2
src/views/saleManage/saleOrder/invoice/components/inventoryTable.vue

@@ -259,11 +259,22 @@
         <el-form-item
           style="margin-bottom: 20px"
           :prop="'datasource.' + scope.$index + '.saleCount'"
-          :rules="{
+          :rules="[{
             required: true,
             message: '请输入数量',
             trigger: 'change'
-          }"
+          },{
+              validator: (rule, value, callback) => {
+                if (value === undefined || value === null || value === '') {
+                  callback('请输入数量');
+                } else if (parseFloat(value) <= 0) {
+                  callback('数量必须大于0');
+                } else {
+                  callback();
+                }
+              },
+              trigger: 'blur'
+            }]"
         >
           <el-input
             v-model="scope.row.saleCount"