Kaynağa Gözat

fix(财务模块): 修复应付应收管理及对账表单验证问题

liujt 6 ay önce
ebeveyn
işleme
367fb507b1

+ 29 - 8
src/views/financialManage/invoiceManage/components/collectionPlanDialog.vue

@@ -14,7 +14,7 @@
       <div>
         <el-form label-width="90px" :inline="true" ref="form" :rules="rules" labelWidth="120px" :model="searchForm">
             <el-form-item
-              label="客户名称"
+              :label="type == 2 ? '供应商名称' : '客户名称'"
               prop="customerName"
             >
               <el-input
@@ -87,6 +87,7 @@
         class="dict-table"
         :selection.sync="selection"
         @columns-change="handleColumnChange"
+        :initLoad="false"
       >
         <!-- 表头工具栏 -->
         <template v-slot:action="{ row }">
@@ -110,8 +111,14 @@
       :account-info-dialog-flag.sync="accountInfoDialogFlag"
       @getAccountInfo="getAccountInfo"
     ></accountInfoDialog>
-
-    <parentList ref="parentRef" @changeParent="changeParent"></parentList>
+    <!-- 客户 -->
+    <customerList ref="curtomerRef" @changeParent="changeParent"></customerList>
+    <!-- 供应商 -->
+    <supplierList
+      ref="supplierRef"
+      @changeParent="changeParent"
+      :classType="2"
+    ></supplierList>
   </el-dialog>
 </template>
 
@@ -121,13 +128,15 @@
   import accountInfoDialog from './accountInfoDialog.vue';
   import { shippingModeOp, transactionMethodsOp, paymentStatus, paymentType, invoiceStatusOp } from '@/enum/dict.js';
   import { receiptPaymentPlanPage } from '@/api/financialManage/payAndCollectPlan';
-  import parentList from '@/views/saleManage/contact/components/parentList.vue';
+  import customerList from '@/views/saleManage/contact/components/parentList.vue';
+  import supplierList from '@/views/purchasingManage/supplierManage/components/parentList.vue';
   import { enterprisePage } from '@/api/contractManage/contractBook';
   export default {
     mixins: [dictMixins, tabMixins],
     components: {
       accountInfoDialog,
-      parentList
+      customerList,
+      supplierList
     },
     props: {
       form: {
@@ -253,6 +262,13 @@
             showOverflowTooltip: true,
             minWidth: 200
           },
+          {
+          prop: 'initiatorName',
+          label: this.type == 2 ? '购买方名称':'销售方名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
           {
             prop: 'settlementMode',
             label: '结算方式',
@@ -464,7 +480,7 @@
           initiatorId: [
             { required: true, message: '请选择', trigger: 'blur' }
           ],
-          customerId: [
+          customerName: [
             { required: true, message: '请选择', trigger: 'blur' }
           ],
           transactionMode: [
@@ -503,7 +519,11 @@
         let item = {
           id: this.searchForm.customerId
         };
-        this.$refs.parentRef.open(item);
+        if (this.type == 2) {
+          this.$refs.supplierRef.open(item);
+        } else {
+          this.$refs.curtomerRef.open(item);
+        }
       },
       search() {
         this.$refs.form.validate(async (valid) => {
@@ -521,6 +541,7 @@
         this.reload(this.searchForm);
       },
       changeParent(item) {
+        this.searchForm.customerName = item.name;
         this.searchForm.customerId = item.id;
       },
       getEnterprisePage() {
@@ -538,7 +559,7 @@
         let data = this.enterprisePage.find(
           (item) => item.id == val
         );
-        this.searchForm.customerName = data.name;
+        // this.searchForm.customerName = data.name;
         // this.searchForm.initiatorId = data.id;
       },
       init(item = {}, currentIndex = '') {

+ 14 - 2
src/views/financialManage/payableManage/components/paymentListDialog.vue

@@ -50,7 +50,7 @@
 <script>
   import { finPayablePageListAPI } from '@/api/financialManage/payableManage';
   import detailDialog1 from './detailDialog1.vue';
-  import { paymentType, invoiceStatusOp } from '@/enum/dict.js';
+  import { paymentStatus, invoiceStatusOp, transactionMethodsOp } from '@/enum/dict.js';
   import { reviewStatus } from '@/enum/dict';
   export default {
     name: 'collectionDialog',
@@ -234,6 +234,16 @@
             slot: 'accountingSubjectName',
             showOverflowTooltip: true
           },
+          {
+            prop: 'transactionMode',
+            label: '交易方式',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 200,
+            formatter: (row) => {
+              return this.transactionMethodsOp.find(item => item.value == row.transactionMode)?.label || '';
+            }
+          },
           {
             prop: 'invoiceStatus',
             label: '开票状态',
@@ -299,13 +309,14 @@
       canAddInvoice() {
         return function(row) {
           if (!row) return false;
-          return [2].includes(row.approvalStatus) && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
+          return [2].includes(row.approvalStatus) && row.transactionMode == 2 && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
         };
       }
     },
     data() {
       return {
         title: '应付列表',
+        transactionMethodsOp,
         detailDialogFlag1: false,
         paymentType,
         invoiceStatusOp,
@@ -355,6 +366,7 @@
           pageNum: page,
           size: limit,
           approvalStatus:2,
+          transactionMode:2,
           ...where
         });
       }

+ 1 - 1
src/views/financialManage/payableManage/index.vue

@@ -178,7 +178,7 @@
       canAddInvoice() {
         return function(row) {
           if (!row) return false;
-          return [2].includes(row.approvalStatus) && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
+          return [2].includes(row.approvalStatus) && row.transactionMode == 2 && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
         };
       },
       columns() {

+ 14 - 2
src/views/financialManage/receivableManage/components/receivableDialog.vue

@@ -50,7 +50,7 @@
 <script>
   import { finReceivablePageListAPI } from '@/api/financialManage/receivableManage';
   import detailDialog1 from './detailDialog1.vue';
-  import { paymentStatus, invoiceStatusOp } from '@/enum/dict.js';
+  import { paymentStatus, invoiceStatusOp, transactionMethodsOp } from '@/enum/dict.js';
   import { reviewStatus } from '@/enum/dict';
   export default {
     name: 'collectionDialog',
@@ -234,6 +234,16 @@
             slot: 'accountingSubjectName',
             showOverflowTooltip: true
           },
+          {
+            prop: 'transactionMode',
+            label: '交易方式',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 200,
+            formatter: (row) => {
+              return this.transactionMethodsOp.find(item => item.value == row.transactionMode)?.label || '';
+            }
+          },
           {
             prop: 'invoiceStatus',
             label: '开票状态',
@@ -307,13 +317,14 @@
       canAddInvoice() {
         return function(row) {
           if (!row) return false;
-          return [2].includes(row.approvalStatus) && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
+          return [2].includes(row.approvalStatus) && row.transactionMode == 2 && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
         };
       }
     },
     data() {
       return {
         title: '应收列表',
+        transactionMethodsOp,
         detailDialogFlag1: false,
         paymentStatus,
         invoiceStatusOp,
@@ -363,6 +374,7 @@
           pageNum: page,
           size: limit,
           approvalStatus:2,
+          transactionMode:2,
           ...where
         });
       }

+ 1 - 9
src/views/financialManage/receivableManage/index.vue

@@ -414,14 +414,6 @@
           formatter: (_row, _column, cellValue) => {
             return _row.externalId? '已推送' : '未推送';
           }
-        },
-        {
-          minWidth: 100,
-          prop: 'createTime',
-          label: '创建时间',
-          align: 'center',
-          slot: 'createTime',
-          showOverflowTooltip: true
         },
           {
             minWidth: 100,
@@ -449,7 +441,7 @@
       canAddInvoice() {
         return function(row) {
           if (!row) return false;
-          return [2].includes(row.approvalStatus) && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
+          return [2].includes(row.approvalStatus) && row.transactionMode == 2 && row.invoiceStatus != 2 && row.unInvoiceAmount && +row.unInvoiceAmount > 0;
         };
       }
     },

+ 17 - 0
src/views/saleManage/saleOrder/accountstatement/components/addAccountDialog.vue

@@ -236,7 +236,20 @@
           let data = await getStatementRecordListAPI(searchQuery);
           console.log(data, 'data');
           this.loading = false;
+          data = data.map(item => {
+            item.deliveryProducts = item.deliveryProducts.map(i => {
+              return {
+                ...i,
+                taxRate: i.taxRate || 0,
+                discountRatio: i.discountRatio || 100,
+                singlePrice: i.singlePrice || 0,
+              }
+            })
+            return item;
+          })
           this.datasource = data || [];
+
+          console.log(this.datasource, 'this.datasource~~~');
           // this.recorpayList = data.recorpayList || [];
           this.dataForm = {
             ...this.dataForm,
@@ -260,6 +273,10 @@
       async save(is) {
         if (!this.datasource.length)
           return this.$message.warning('暂无对账信息');
+        
+        if (!this.getValidForm()){
+          return this.$message.warning('请完善对账信息');
+        }
         let api =
           this.dialogType == 'add'
             ? createAccountStatementAPI

+ 220 - 65
src/views/saleManage/saleOrder/accountstatement/components/inventoryTable.vue

@@ -91,72 +91,95 @@
         <div>
           <el-tabs type="border-card">
             <el-tab-pane :label="type === 'purchase' ? '收货单' : '发货单'">
-              <ele-pro-table :show-summary="false" :summary-method="getSummaries" ref="table" row-key="id" :needPage="false"
-                          :columns="getColumns(item, 'deliveryProducts')" max-height="500px" style="margin-bottom: 10px" :datasource="item.deliveryProducts || []"
-                          cache-key="systemRoleTable17-11121" class="time-form">
-                <template v-slot:toolbar>
-                  <div class="headbox">
-                    <div>
-                      <span class="amount">对账金额合计:{{ getSummariesA(item.deliveryProducts || []) }}元</span>
+              <el-form :ref="'form' + index" :model="item">
+                <ele-pro-table :show-summary="false" :summary-method="getSummaries" ref="table" row-key="id" :needPage="false"
+                            :columns="getColumns(item, 'deliveryProducts')" max-height="500px" style="margin-bottom: 10px" :datasource="item.deliveryProducts || []"
+                            cache-key="systemRoleTable17-11121" class="time-form">
+                  <template v-slot:toolbar>
+                    <div class="headbox">
+                      <div>
+                        <span class="amount">对账金额合计:{{ getSummariesA(item.deliveryProducts || []) }}元</span>
+                      </div>
                     </div>
-                  </div>
-                </template>
+                  </template>
 
-                <template v-slot:singlePrice="scope">
-                  <el-form-item
-                    style="margin-bottom: 20px"
-                    :prop="'datasource.' + scope.$index + '.singlePrice'"
-                    :rules="{
-                      required: true,
-                      message: '请输入正确的单价',
-                      trigger: 'change'
-                    }"
-                  >
-                    <el-input
-                      v-model="scope.row.singlePrice"
-                      placeholder="请输入"
-                      @input="changeCount(scope.row, scope.$index)"
-                      type="number"
+                  <template v-slot:singlePrice="scope">
+                    <el-form-item
+                      style="margin-bottom: 20px"
+                      :prop="'deliveryProducts.' + scope.$index + '.singlePrice'"
+                      :rules="{
+                        required: true,
+                        message: '请输入正确的单价',
+                        trigger: 'change'
+                      }"
                     >
-                      <template slot="append">元</template>
-                    </el-input>
-                  </el-form-item>
-                </template>
+                      <el-input
+                        v-model="scope.row.singlePrice"
+                        placeholder="请输入"
+                        @input="changeCount(scope.row, scope.$index)"
+                        :disabled="scope.row.orderCategory != 4"
+                        type="number"
+                      >
+                        <template slot="append">元</template>
+                      </el-input>
+                    </el-form-item>
+                  </template>
 
-                <template v-slot:singleWeight="scope">
-                  <el-form-item
-                    style="margin-bottom: 20px"
-                    :rules="{
-                      required: false,
+                  <template v-slot:taxRate="scope">
+                    <el-form-item
+                      :prop="'deliveryProducts.' + scope.$index + '.taxRate'"
+                      :rules="{
+                        required: isTaxRate == 1 ? true : false,
+                        message: '请输入税率',
+                        trigger: 'change'
+                      }"
+                    >
+                      <el-input
+                        v-model="scope.row.taxRate"
+                        placeholder="请输入"
+                        type="number"
+                        @input="getNotaxSinglePrice(scope.row, scope.$index)"
+                        :disabled="scope.row.orderCategory != 4"
+                      >
+                        <template slot="append">%</template>
+                      </el-input>
+                    </el-form-item>
+                  </template>
 
-                      trigger: 'change'
-                    }"
-                    :prop="'datasource.' + scope.$index + '.singleWeight'"
-                  >
-                    <el-input
-                      v-model="scope.row.singleWeight"
-                      type="number"
-                      placeholder="请输入"
-                      :disabled="needProduce == 4"
-                      @input="changeCount(scope.row, scope.$index)"
+                  <template v-slot:discountRatio="scope">
+                    <el-form-item
+                      :prop="'deliveryProducts.' + scope.$index + '.discountRatio'"
+                      :rules="{
+                        required: true,
+                        message: '请输入折让比例',
+                        trigger: 'change'
+                      }"
                     >
-                      <template slot="append">
-                        {{ scope.row.weightUnit }}
-                      </template>
-                    </el-input>
-                  </el-form-item>
-                </template>
+                      <el-input
+                        v-model="scope.row.discountRatio"
+                        placeholder="请输入"
+                        type="number"
+                        :min="0"
+                        :max="100"
+                        :disabled="scope.row.orderCategory != 4"
+                        @input="getDiscountRatioPrice(scope.row, scope.$index)"
+                      >
+                        <template slot="append">%</template>
+                      </el-input>
+                    </el-form-item>
+                  </template>
 
-                <template v-slot:action="{ row,$index }">
-                  <el-popconfirm class="ele-action" title="确定要删除吗?" @confirm="remove(index,$index,'line')">
-                    <template v-slot:reference>
-                      <el-link type="danger" v-if="dialogType!=='view'" :underline="false" icon="el-icon-delete">
-                        删除
-                      </el-link>
-                    </template>
-                  </el-popconfirm>
-                </template>
-              </ele-pro-table>
+                  <template v-slot:action="{ row,$index }">
+                    <el-popconfirm class="ele-action" title="确定要删除吗?" @confirm="remove(index,$index,'line')">
+                      <template v-slot:reference>
+                        <el-link type="danger" v-if="dialogType!=='view'" :underline="false" icon="el-icon-delete">
+                          删除
+                        </el-link>
+                      </template>
+                    </el-popconfirm>
+                  </template>
+                </ele-pro-table>
+              </el-form>
             </el-tab-pane>
             <el-tab-pane label="退货单">
               <ele-pro-table :show-summary="false" :summary-method="getSummaries" ref="table" row-key="id" :needPage="false"
@@ -202,6 +225,8 @@
 <script>
 import dictMixins from '@/mixins/dictMixins';
 import { pricingWayList } from '@/enum/dict';
+import { parameterGetByCode } from '@/api/main/index.js';
+import { changeCount } from '@/BIZComponents/setProduct.js';
 
 export default {
   mixins: [dictMixins],
@@ -353,20 +378,21 @@ export default {
             align: "center"
           },
           {
-            minWidth: 90,
+            minWidth: 160,
             prop: 'singlePrice',
             label: '单价',
             align: 'center',
-            // slot: 'singlePrice',
+            slot: 'singlePrice',
           },
           {
-            minWidth: 100,
+            minWidth: 160,
             prop: 'taxRate',
             label: '税率',
             align: 'center',
+            slot: 'taxRate',
           },
           {
-            width: 150,
+            width: 140,
             prop: 'notTaxSinglePrice',
             label: '不含税单价',
             align: 'center'
@@ -379,10 +405,11 @@ export default {
             align: 'center',
           },
           {
-            minWidth: 100,
+            minWidth: 160,
             prop: 'discountRatio',
             label: '折让比例',
             align: 'center',
+            slot: 'discountRatio',
           },
           {
             minWidth: 100,
@@ -552,10 +579,14 @@ export default {
         return (item)=>{
           return item.subList?.detailList
         }
-      }
+      },
+      clientEnvironmentId() {
+        return this.$store.state.user.info.clientEnvironmentId;
+      },
   },
   data() {
     return {
+      isTaxRate: 0,
       activeNames: [],
       rules: {},
       form: {},
@@ -585,12 +616,93 @@ export default {
   },
   created(){
     this.requestDict('产地');
+    // 税率是否必填//0否 1是
+      parameterGetByCode({
+        code: 'eom_saleOrder_order-taxRate'
+      }).then((res) => {
+        this.isTaxRate = res.value;
+      });
   },
   mounted() {
     // this.activeNames = this.datasource.map((item, index) => index.toString());
     // console.log('activeNames~~~', this.activeNames)
   },
   methods: {
+    //改变数量
+      changeCount(item, index) {
+        console.log('changeCount~~~', item)
+        console.log('this.datasource[index]~~~', this.datasource[index])
+        // row.totalPrice = parseFloat((item.totalCount * item.singlePrice).toFixed(2))
+        if (item.singlePrice && item.taxRate) {
+          // this.$set(
+          //   this.datasource[index],
+          //   'totalPrice',
+          //   parseFloat((item.totalCount * item.singlePrice).toFixed(2))
+          // );
+          item.totalPrice = parseFloat((item.totalCount * item.singlePrice).toFixed(2))
+        } else {
+          // this.$set(this.form.datasource[index], 'totalPrice', '');
+          item.totalPrice = ''
+        }
+        this.getNotaxSinglePrice(item, index);
+        this.getDiscountRatioPrice(item, index);
+        this.$forceUpdate();
+        // if (this.clientEnvironmentId == 4 && !isBlockCount) {
+        //   this.tableHandleKeyUp(row, index, 'sum');
+        // }
+      },
+      //计算不含税单价
+      getNotaxSinglePrice(item, index) {
+        if (item.singlePrice && item.taxRate) {
+          // this.$set(
+          //   this.datasource[index],
+          //   'notTaxSinglePrice',
+          //   parseFloat(
+          //     (item.singlePrice / (1 + item.taxRate / 100)).toFixed(2)
+          //   )
+          // );
+          item.notTaxSinglePrice = parseFloat(
+            (item.singlePrice / (1 + item.taxRate / 100)).toFixed(2)
+          )
+        } else {
+          // this.$set(this.form.datasource[index], 'notTaxSinglePrice', '');
+          item.notTaxSinglePrice = ''
+        }
+      },
+
+      // 计算折让单价,折让总价
+      getDiscountRatioPrice(item, index) {
+
+          if (item.singlePrice && item.discountRatio) {
+            // this.$set(
+            //   this.datasource[index],
+            //   'discountSinglePrice',
+            //   parseFloat(
+            //     (item.singlePrice * (item.discountRatio / 100)).toFixed(2)
+            //   )
+            // );
+            item.discountSinglePrice = parseFloat(
+              (item.singlePrice * (item.discountRatio / 100)).toFixed(2)
+            )
+
+            // this.$set(
+            //   this.datasource[index],
+            //   'discountTotalPrice',
+            //   parseFloat(
+            //     (item.totalPrice * (item.discountRatio / 100)).toFixed(2)
+            //   )
+            // );
+            item.discountTotalPrice = parseFloat(
+              (item.totalPrice * (item.discountRatio / 100)).toFixed(2)
+            )
+            
+          } else {
+            // this.$set(this.datasource[index], 'discountSinglePrice', 0);
+            // this.$set(this.datasource[index], 'discountTotalPrice', 0);
+            item.discountSinglePrice = ''
+            item.discountTotalPrice = ''
+          }
+      },
     remove(tableIndex, lineIndex, delType) {
       let params = {
         tableIndex,
@@ -630,6 +742,49 @@ export default {
       return table.reduce((prev, curr) => {
         return prev + Number(curr.discountTotalPrice || 0)
       }, 0)
+    },
+    getValidForm() {
+      return new Promise((resolve, reject) => {
+        const validationPromises = [];
+        
+        this.datasource.forEach((item, index) => {
+          validationPromises.push(
+            new Promise((formResolve, formReject) => {
+              const formRef = this.$refs['form' + index];
+              if (formRef) {
+                formRef.validate((valid, errors) => {
+                  if (!valid) {
+                    formReject({ index, errors });
+                  } else {
+                    formResolve(true);
+                  }
+                });
+              } else {
+                // 如果表单引用不存在,检查数据直接验证
+                if (!item.singlePrice || !item.taxRate || !item.discountRatio) {
+                  formReject({ index, message: `第${index + 1}项缺少必填字段` });
+                } else {
+                  formResolve(true);
+                }
+              }
+            })
+          );
+        });
+        
+        Promise.all(validationPromises)
+          .then(() => {
+            resolve(true);
+          })
+          .catch(error => {
+            console.error('表单验证失败:', error);
+            if (error.message) {
+              this.$message.error(error.message);
+            } else {
+              this.$message.error(`第${error.index + 1}项表单验证失败`);
+            }
+            reject(false);
+          });
+      });
     }
   }
 };

+ 16 - 5
src/views/saleManage/saleOrder/invoice/components/inventoryTable.vue

@@ -1268,6 +1268,7 @@
       },
       //选择产品回调
       changeParentBiz(obj = [], idx) {
+        console.log('obj~~~', obj, idx);
         obj.forEach(async (item, index) => {
           let i = idx == -1 ? index : idx;
           let row = JSON.parse(JSON.stringify(this.defaultForm));
@@ -1275,6 +1276,7 @@
           row['tempId'] = this.form.datasource.length + 1;
 
           let parasm = idx == -1 ? row : this.form.datasource[i];
+          console.log('parasm~~~~222', parasm);  
           this.$set(parasm, 'productId', item.id);
           this.$set(parasm, 'categoryName', item.name);
           this.$set(parasm, 'productCategoryId', item.categoryLevelId);
@@ -1327,16 +1329,20 @@
             })
           );
 
+          const templist = await getBatchList({
+                categoryCode: item.productCode,
+                warehouseId: item.warehouseId,
+                size: -1
+              });
+
           this.$set(
             parasm,
             'batchNoList',
-            await getBatchList({
-              categoryCode: item.productCode,
-              warehouseId: item.warehouseId,
-              size: -1
-            })
+            templist?.list
           );
 
+          console.log('parasm~~~~333', parasm);
+
           this.$set(
             parasm,
             'packingSpecification',
@@ -1351,9 +1357,12 @@
             item.purchaseOrigins = item.purchaseOrigins.map((val) => val + '');
           }
           this.$set(parasm, 'provenance', item.purchaseOrigins || []);
+          console.log('parasm~~~~', parasm);
+          console.log('row~~~~', row);
           if (idx == -1) {
             this.form.datasource.push(row);
           }
+          console.log('this.form.datasource~~~~', this.form.datasource);
         });
       },
       replaceTable(list) {
@@ -1606,12 +1615,14 @@
       },
       //选择产品
       handParent() {
+        console.log('this.type~~~~111', this.orderId);
         if (!this.orderId && !this.orderIds)
           return this.$message.error('请先选择订单');
         this.$refs.BIZproductListRef.open('', -1);
       },
       // 添加
       handlAdd() {
+        console.log('this.type~~~~222', this.orderId);
         if (!this.orderId && !this.orderIds)
           return this.$message.error('请先选择订单');
         this.$refs.productListRef.open(this.oldProductList);