feat: 仓库二期,出入库单打印预览,产品范围,计价数量,换算数量
Reviewed-on: daoyoucloud/tachycode#503 Co-authored-by: hello@lv <2256334253@qq.com> Co-committed-by: hello@lv <2256334253@qq.com>
This commit is contained in:
		
							parent
							
								
									6251551ded
								
							
						
					
					
						commit
						eb090572c6
					
				@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@hera/plugin-core",
 | 
			
		||||
  "version": "1.6.1",
 | 
			
		||||
  "version": "1.6.2",
 | 
			
		||||
  "displayName": "Hera platform",
 | 
			
		||||
  "displayName.zh-CN": "赫拉平台",
 | 
			
		||||
  "description": "Hera platform as nocobase plugin.",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@hera/plugin-rental",
 | 
			
		||||
  "version": "1.6.2",
 | 
			
		||||
  "version": "1.6.3",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "displayName": "professional construction materials rental system - customized based on hera",
 | 
			
		||||
  "displayName.zh-CN": "专业建材租赁系统 - 基于赫拉定制",
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,8 @@ import { Spin } from 'antd';
 | 
			
		||||
import { useCachedRequest } from '../hooks';
 | 
			
		||||
 | 
			
		||||
export const RecordItemCount = observer((props) => {
 | 
			
		||||
  const form = useForm();
 | 
			
		||||
  const field = useField();
 | 
			
		||||
  const param = {
 | 
			
		||||
    resource: 'product_category',
 | 
			
		||||
    action: 'list',
 | 
			
		||||
@ -15,19 +17,17 @@ export const RecordItemCount = observer((props) => {
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  const { loading, data } = useCachedRequest<any>(param);
 | 
			
		||||
  const form = useForm();
 | 
			
		||||
  const field = useField();
 | 
			
		||||
 | 
			
		||||
  if (!data && loading) {
 | 
			
		||||
    return <Spin />;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const item = form.getValuesIn(field.path.slice(0, -2).entire);
 | 
			
		||||
  if (item?.product && item?.count && data) {
 | 
			
		||||
    const category = data.data.find((category) => category.id === item.product.category_id);
 | 
			
		||||
  if (item?.product && item?.count) {
 | 
			
		||||
    const category = data.data?.find((category) => category.id === item?.product.category_id);
 | 
			
		||||
    if (!category) return;
 | 
			
		||||
    const value = category.convertible ? (item.product.ratio || 0) * item.count : item.count;
 | 
			
		||||
    const unit = category.convertible ? category.conversion_unit : category.unit;
 | 
			
		||||
    const unit = category.convertible ? category.conversion_unit : category.unit || '';
 | 
			
		||||
 | 
			
		||||
    return <span>{formatQuantity(value, 2) + unit}</span>;
 | 
			
		||||
  }
 | 
			
		||||
  return <span> - </span>;
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import { observer, useField, useForm } from '@formily/react';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import { ConversionLogics, RecordCategory } from '../../utils/constants';
 | 
			
		||||
import { formatQuantity } from '../../utils/currencyUtils';
 | 
			
		||||
import { useCachedRequest, useLeaseItems } from '../hooks';
 | 
			
		||||
import { useCachedRequest, useLeaseItems, useProductFeeItems } from '../hooks';
 | 
			
		||||
 | 
			
		||||
// 计价数量
 | 
			
		||||
export const RecordItemValuationQuantity = observer((props) => {
 | 
			
		||||
@ -33,6 +33,9 @@ export const RecordItemValuationQuantity = observer((props) => {
 | 
			
		||||
  const { data: leaseItems } = useLeaseItems(contractPlanId);
 | 
			
		||||
  const { data: inLeaseItems } = useLeaseItems(inContractPlanId);
 | 
			
		||||
  const { data: outLeaseItems } = useLeaseItems(outContractPlanId);
 | 
			
		||||
  const { data: ProductFeeItems } = useProductFeeItems(contractPlanId);
 | 
			
		||||
  const { data: inProductFeeItems } = useProductFeeItems(inContractPlanId);
 | 
			
		||||
  const { data: outProductFeeItems } = useProductFeeItems(outContractPlanId);
 | 
			
		||||
 | 
			
		||||
  const item = form.getValuesIn(field.path.slice(0, -2).entire);
 | 
			
		||||
  if (item?.product && item?.count) {
 | 
			
		||||
@ -50,7 +53,13 @@ export const RecordItemValuationQuantity = observer((props) => {
 | 
			
		||||
          (product) => product.id - 99999 === item.product?.category_id || product.id === item.product?.id,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      const count = subtotal(rule, item, productCategory, reqWeightRules);
 | 
			
		||||
      const feeRule = ProductFeeItems.data.find((feeItem) => feeItem.fee_product_id === item.product?.id);
 | 
			
		||||
      let count;
 | 
			
		||||
      if (!rule && feeRule) {
 | 
			
		||||
        count = subtotal(feeRule, item, productCategory, reqWeightRules, 'fee');
 | 
			
		||||
      } else {
 | 
			
		||||
        count = subtotal(rule, item, productCategory, reqWeightRules);
 | 
			
		||||
      }
 | 
			
		||||
      count && result.push({ label: '合同', value: count });
 | 
			
		||||
    }
 | 
			
		||||
    // 采购
 | 
			
		||||
@ -78,12 +87,22 @@ export const RecordItemValuationQuantity = observer((props) => {
 | 
			
		||||
        const count = subtotal(rule, item, productCategory, reqWeightRules);
 | 
			
		||||
        count && result.push({ label: '报价', value: count });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const leaseRule = inLeaseItems.data.find((leaseItem) =>
 | 
			
		||||
        leaseItem.products.find(
 | 
			
		||||
          (product) => product.id - 99999 === item.product?.category_id || product.id === item.product?.id,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      const count = subtotal(leaseRule, item, productCategory, reqWeightRules);
 | 
			
		||||
      const feeRule = inProductFeeItems.data.find(
 | 
			
		||||
        (feeItem) =>
 | 
			
		||||
          feeItem.fee_product_id === item.product?.id || item.product?.category_id === feeItem.fee_product.category_id,
 | 
			
		||||
      );
 | 
			
		||||
      let count;
 | 
			
		||||
      if (!leaseRule && feeRule) {
 | 
			
		||||
        count = subtotal(feeRule, item, productCategory, reqWeightRules, 'fee');
 | 
			
		||||
      } else {
 | 
			
		||||
        count = subtotal(leaseRule, item, productCategory, reqWeightRules);
 | 
			
		||||
      }
 | 
			
		||||
      count && result.push({ label: '入库合同', value: count });
 | 
			
		||||
    }
 | 
			
		||||
    // 租赁直发
 | 
			
		||||
@ -93,14 +112,32 @@ export const RecordItemValuationQuantity = observer((props) => {
 | 
			
		||||
          (product) => product.id - 99999 === item.product?.category_id || product.id === item.product?.id,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      const count_out = subtotal(contractPlain_out, item, productCategory, reqWeightRules);
 | 
			
		||||
      const contractPlain_out_fee = outProductFeeItems.data.find(
 | 
			
		||||
        (feeItem) =>
 | 
			
		||||
          feeItem.fee_product_id === item.product?.id || item.product?.category_id === feeItem.fee_product.category_id,
 | 
			
		||||
      );
 | 
			
		||||
      let count_out;
 | 
			
		||||
      if (!contractPlain_out && contractPlain_out_fee) {
 | 
			
		||||
        count_out = subtotal(contractPlain_out_fee, item, productCategory, reqWeightRules, 'fee');
 | 
			
		||||
      } else {
 | 
			
		||||
        count_out = subtotal(contractPlain_out, item, productCategory, reqWeightRules);
 | 
			
		||||
      }
 | 
			
		||||
      count_out && result.push({ label: '出库合同', value: count_out });
 | 
			
		||||
      const contractPlain_in = inLeaseItems.data.find((leaseItem) =>
 | 
			
		||||
        leaseItem.products.find(
 | 
			
		||||
          (product) => product.id - 99999 === item.product?.category_id || product.id === item.product?.id,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      const count_in = subtotal(contractPlain_in, item, productCategory, reqWeightRules);
 | 
			
		||||
      const contractPlain_in_fee = outProductFeeItems.data.find(
 | 
			
		||||
        (feeItem) =>
 | 
			
		||||
          feeItem.fee_product_id === item.product?.id || item.product?.category_id === feeItem.fee_product.category_id,
 | 
			
		||||
      );
 | 
			
		||||
      let count_in;
 | 
			
		||||
      if (!contractPlain_in && contractPlain_in_fee) {
 | 
			
		||||
        count_in = subtotal(contractPlain_in_fee, item, productCategory, reqWeightRules, 'fee');
 | 
			
		||||
      } else {
 | 
			
		||||
        count_in = subtotal(contractPlain_in, item, productCategory, reqWeightRules);
 | 
			
		||||
      }
 | 
			
		||||
      count_in && result.push({ label: '入库合同', value: count_in });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -119,17 +156,17 @@ RecordItemValuationQuantity.displayName = 'RecordItemValuationQuantity';
 | 
			
		||||
RecordItemValuationQuantity.__componentType = CustomComponentType.CUSTOM_FIELD;
 | 
			
		||||
RecordItemValuationQuantity.__componentLabel = '记录单 - 明细 - 计价数量';
 | 
			
		||||
 | 
			
		||||
const subtotal = (rule: any, itemData: any, productCategory: any, reqWeightRules: any) => {
 | 
			
		||||
const subtotal = (rule: any, itemData: any, productCategory: any, reqWeightRules: any, item?: any) => {
 | 
			
		||||
  let count: number;
 | 
			
		||||
  let unit: string;
 | 
			
		||||
  if (rule?.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
    count = itemData.count;
 | 
			
		||||
    unit = productCategory.unit;
 | 
			
		||||
    unit = item ? rule.unit : productCategory.unit;
 | 
			
		||||
  } else if (rule?.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
    count = productCategory.convertible ? itemData.count * itemData.product.ratio : itemData.count;
 | 
			
		||||
    unit = productCategory.convertible ? productCategory.conversion_unit : productCategory.unit;
 | 
			
		||||
    unit = item ? rule.unit : productCategory.convertible ? productCategory.conversion_unit : productCategory.unit;
 | 
			
		||||
  } else if (rule?.conversion_logic_id === ConversionLogics.ProductWeight) {
 | 
			
		||||
    count = (itemData.count * itemData.product.weight) / 1000;
 | 
			
		||||
    count = item ? itemData.count : (itemData.count * itemData.product.weight) / 1000;
 | 
			
		||||
    unit = '吨';
 | 
			
		||||
  } else if (rule?.conversion_logic_id === ConversionLogics.ActualWeight) {
 | 
			
		||||
    count = 0;
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import React from 'react';
 | 
			
		||||
import { observer, useForm } from '@formily/react';
 | 
			
		||||
import { RecordCategory } from '../../utils/constants';
 | 
			
		||||
import { CustomComponentType, CustomFC } from '@hera/plugin-core/client';
 | 
			
		||||
import { useCachedRequest, useLeaseItems } from '../hooks';
 | 
			
		||||
import { useCachedRequest, useLeaseItems, useProductFeeItems } from '../hooks';
 | 
			
		||||
import { useDeepCompareEffect } from 'ahooks';
 | 
			
		||||
 | 
			
		||||
export const RecordProductScope = observer(() => {
 | 
			
		||||
@ -15,36 +15,75 @@ export const RecordProductScope = observer(() => {
 | 
			
		||||
 | 
			
		||||
  let required = { price: false, contract: false, inContract: false, outContract: false };
 | 
			
		||||
  const { data, loading } = useCachedRequest<any>({
 | 
			
		||||
    resource: 'product_category',
 | 
			
		||||
    resource: 'product',
 | 
			
		||||
    action: 'list',
 | 
			
		||||
    params: {
 | 
			
		||||
      pageSize: 99999,
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
  const { data: leaseItems, loading: leaseItemsLoading } = useLeaseItems(contractPlanId);
 | 
			
		||||
  const { data: feeseItems, loading: feeItemsLoading } = useProductFeeItems(contractPlanId);
 | 
			
		||||
  const { data: inLeaseItems, loading: inLeaseItemsLoading } = useLeaseItems(inContractPlanId);
 | 
			
		||||
  const { data: inFeeseItems, loading: inFeeItemsLoading } = useProductFeeItems(inContractPlanId);
 | 
			
		||||
  const { data: outLeaseItems, loading: outLeaseItemsLoading } = useLeaseItems(outContractPlanId);
 | 
			
		||||
  const { data: outFeeseItems, loading: outFeeItemsLoading } = useProductFeeItems(outContractPlanId);
 | 
			
		||||
 | 
			
		||||
  const contractProducts =
 | 
			
		||||
    leaseItems?.data.reduce((acc, current) => {
 | 
			
		||||
      acc.push(...current.products.map((item) => ({ id: item.category_id })));
 | 
			
		||||
      return acc;
 | 
			
		||||
    }, []) ?? [];
 | 
			
		||||
 | 
			
		||||
  const inContractProducts =
 | 
			
		||||
    inLeaseItems?.data.reduce((acc, current) => {
 | 
			
		||||
      acc.push(...current.products.map((item) => ({ id: item.category_id })));
 | 
			
		||||
      return acc;
 | 
			
		||||
    }, []) ?? [];
 | 
			
		||||
 | 
			
		||||
  const outContractProducts =
 | 
			
		||||
    outLeaseItems?.data.reduce((acc, current) => {
 | 
			
		||||
      acc.push(...current.products.map((item) => ({ id: item.category_id })));
 | 
			
		||||
  /**
 | 
			
		||||
   * 合同费用数据格式trans
 | 
			
		||||
   */
 | 
			
		||||
  const transFee = (fee: any[]) => {
 | 
			
		||||
    if (fee) {
 | 
			
		||||
      const feeData = fee.map((fee) => {
 | 
			
		||||
        const data = {
 | 
			
		||||
          ...fee,
 | 
			
		||||
        };
 | 
			
		||||
        data.products = [data.fee_product];
 | 
			
		||||
        return data;
 | 
			
		||||
      });
 | 
			
		||||
      return feeData || [];
 | 
			
		||||
    } else {
 | 
			
		||||
      return [];
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 生成合同产品/费用的id或category_id数据
 | 
			
		||||
   */
 | 
			
		||||
  const contractLeaseFee = (leaseData, feeData) => {
 | 
			
		||||
    const data =
 | 
			
		||||
      [...leaseData, ...transFee(feeData)].reduce((acc, current) => {
 | 
			
		||||
        acc.push(
 | 
			
		||||
          ...current.products.map((item) => {
 | 
			
		||||
            if (item.id < 99999) {
 | 
			
		||||
              return { id: item.id };
 | 
			
		||||
            } else {
 | 
			
		||||
              return { category_id: item.id - 99999 };
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
        );
 | 
			
		||||
        return acc;
 | 
			
		||||
      }, []) ?? [];
 | 
			
		||||
    return data;
 | 
			
		||||
  };
 | 
			
		||||
  const contractProducts = contractLeaseFee(leaseItems?.data || [], feeseItems?.data);
 | 
			
		||||
  const inContractProducts = contractLeaseFee(inLeaseItems?.data || [], inFeeseItems?.data);
 | 
			
		||||
  const inContractFee = contractLeaseFee([], inFeeseItems?.data);
 | 
			
		||||
  const outContractProducts = contractLeaseFee(outLeaseItems?.data || [], outFeeseItems?.data);
 | 
			
		||||
 | 
			
		||||
  const priceProducts =
 | 
			
		||||
    form.values.price_items?.filter((item) => item.product).map((item) => ({ id: item.product.category_id })) ?? [];
 | 
			
		||||
    form.values.price_items
 | 
			
		||||
      ?.filter((item) => item.product)
 | 
			
		||||
      .map((item) => {
 | 
			
		||||
        if (item.product.id > 99999) {
 | 
			
		||||
          return {
 | 
			
		||||
            category_id: item.product.category_id,
 | 
			
		||||
          };
 | 
			
		||||
        } else {
 | 
			
		||||
          return {
 | 
			
		||||
            id: item.product.id,
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
      }) ?? [];
 | 
			
		||||
 | 
			
		||||
  switch (form.values.category) {
 | 
			
		||||
    case RecordCategory.lease:
 | 
			
		||||
@ -53,10 +92,10 @@ export const RecordProductScope = observer(() => {
 | 
			
		||||
    case RecordCategory.purchase:
 | 
			
		||||
      required = { price: true, contract: false, inContract: false, outContract: false };
 | 
			
		||||
      break;
 | 
			
		||||
    case RecordCategory.lease2lease: // 出库合同,入库合同的产品范围交集
 | 
			
		||||
    case RecordCategory.lease2lease:
 | 
			
		||||
      required = { price: false, contract: false, inContract: true, outContract: true };
 | 
			
		||||
      break;
 | 
			
		||||
    case RecordCategory.purchase2lease: // 报价,入库合同的产品范围交集
 | 
			
		||||
    case RecordCategory.purchase2lease: // 报价,入库合同的产品范围交集, 加入入库合同的费用数据
 | 
			
		||||
      required = { price: true, contract: false, inContract: true, outContract: false };
 | 
			
		||||
      break;
 | 
			
		||||
    case RecordCategory.inventory:
 | 
			
		||||
@ -69,24 +108,56 @@ export const RecordProductScope = observer(() => {
 | 
			
		||||
  let result = data?.data ?? [];
 | 
			
		||||
  if (required.inContract && required.outContract) {
 | 
			
		||||
    // 租赁直发单
 | 
			
		||||
    const intersection = _.intersectionBy(inContractProducts, outContractProducts, 'id');
 | 
			
		||||
    result = _.intersectionBy(result, intersection, 'id');
 | 
			
		||||
    const intersection = [
 | 
			
		||||
      _.intersectionBy(inContractProducts, outContractProducts, 'id'),
 | 
			
		||||
      _.intersectionBy(inContractProducts, outContractProducts, 'category_id'),
 | 
			
		||||
    ].flat();
 | 
			
		||||
    const data = intersectionByMultiple(result, intersection, 'category_id');
 | 
			
		||||
    result = [_.intersectionBy(result, intersection, 'id'), data].flat();
 | 
			
		||||
  } else if (required.price && required.inContract) {
 | 
			
		||||
    const intersection = _.intersectionBy(inContractProducts, priceProducts, 'id');
 | 
			
		||||
    result = _.intersectionBy(result, intersection, 'id');
 | 
			
		||||
    const intersection = [
 | 
			
		||||
      _.intersectionBy(inContractProducts, priceProducts, 'id'),
 | 
			
		||||
      _.intersectionBy(inContractProducts, priceProducts, 'category_id'),
 | 
			
		||||
    ].flat();
 | 
			
		||||
    intersection.push(...inContractFee);
 | 
			
		||||
    const data = intersectionByMultiple(result, intersection, 'category_id');
 | 
			
		||||
    result = [_.intersectionBy(result, intersection, 'id'), data].flat();
 | 
			
		||||
  } else if (required.price) {
 | 
			
		||||
    result = _.intersectionBy(result, priceProducts, 'id');
 | 
			
		||||
    const data = intersectionByMultiple(result, priceProducts, 'category_id');
 | 
			
		||||
    result = [_.intersectionBy(result, priceProducts, 'id'), data].flat();
 | 
			
		||||
  } else if (required.contract) {
 | 
			
		||||
    result = _.intersectionBy(result, contractProducts, 'id');
 | 
			
		||||
    const data = intersectionByMultiple(result, contractProducts, 'category_id');
 | 
			
		||||
    result = [_.intersectionBy(result, contractProducts, 'id'), data].flat();
 | 
			
		||||
  }
 | 
			
		||||
  useDeepCompareEffect(() => {
 | 
			
		||||
    form.setValues({
 | 
			
		||||
      product_scope: result,
 | 
			
		||||
    });
 | 
			
		||||
  }, [result, form]);
 | 
			
		||||
  return loading || leaseItemsLoading || inLeaseItemsLoading || outLeaseItemsLoading ? <Spin /> : <></>;
 | 
			
		||||
  return loading ||
 | 
			
		||||
    leaseItemsLoading ||
 | 
			
		||||
    inLeaseItemsLoading ||
 | 
			
		||||
    outLeaseItemsLoading ||
 | 
			
		||||
    feeItemsLoading ||
 | 
			
		||||
    inFeeItemsLoading ||
 | 
			
		||||
    outFeeItemsLoading ? (
 | 
			
		||||
    <Spin />
 | 
			
		||||
  ) : (
 | 
			
		||||
    <></>
 | 
			
		||||
  );
 | 
			
		||||
}) as CustomFC;
 | 
			
		||||
 | 
			
		||||
RecordProductScope.displayName = 'RecordProductScope';
 | 
			
		||||
RecordProductScope.__componentType = CustomComponentType.CUSTOM_ASSOCIATED_FIELD;
 | 
			
		||||
RecordProductScope.__componentLabel = '记录单 - 产品范围';
 | 
			
		||||
 | 
			
		||||
const intersectionByMultiple = (arr1, arr2, propName) => {
 | 
			
		||||
  const result = [];
 | 
			
		||||
  arr1.forEach((item) => {
 | 
			
		||||
    const index = arr2.findIndex((i) => i[propName] === item[propName]);
 | 
			
		||||
    if (index !== -1) {
 | 
			
		||||
      result.push(item);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  return result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,30 @@ export const useLeaseItems = (planId) => {
 | 
			
		||||
  return { data, loading };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useProductFeeItems = (planId) => {
 | 
			
		||||
  const feeParams = {
 | 
			
		||||
    resource: 'contract_plan_fee_items',
 | 
			
		||||
    action: 'list',
 | 
			
		||||
    params: {
 | 
			
		||||
      appends: ['fee_product'],
 | 
			
		||||
      filter: {
 | 
			
		||||
        contract_plan_id: planId,
 | 
			
		||||
      },
 | 
			
		||||
      pageSize: 99999,
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const { data, loading, run } = useCachedRequest<any>(feeParams, {
 | 
			
		||||
    manual: true,
 | 
			
		||||
  });
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (planId) {
 | 
			
		||||
      run();
 | 
			
		||||
    }
 | 
			
		||||
  }, [planId]);
 | 
			
		||||
  return { data, loading };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useFeeItems = (categoryId, planId) => {
 | 
			
		||||
  const { data, loading, run } = useCachedRequest<any>(
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -133,6 +133,7 @@ const styles = StyleSheet.create({
 | 
			
		||||
    marginLeft: '-1px',
 | 
			
		||||
    borderTop: '1px solid black',
 | 
			
		||||
    marginTop: '-1px',
 | 
			
		||||
    borderBottom: '1px solid black',
 | 
			
		||||
  },
 | 
			
		||||
  tableCellLast: {
 | 
			
		||||
    flex: 1,
 | 
			
		||||
@ -302,6 +303,81 @@ const PreviewDocument = ({
 | 
			
		||||
      dobuleRecord.push(result);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  const renderRecord = (data, isDouble) => {
 | 
			
		||||
    const columns = isDouble ? ['left_', 'right_'] : [''];
 | 
			
		||||
    const page = data.map((item, index) => (
 | 
			
		||||
      <View key={index} style={styles.tableContent}>
 | 
			
		||||
        {columns.map((column, columnIndex) => (
 | 
			
		||||
          <React.Fragment key={columnIndex}>
 | 
			
		||||
            <Text style={styles.tableCell2}>{item[column + 'name']}</Text>
 | 
			
		||||
            <Text style={styles.tableCell}>
 | 
			
		||||
              {!item[column + 'count'] ? '' : formatQuantity(item[column + 'count'], 2) + item[column + 'unit']}
 | 
			
		||||
            </Text>
 | 
			
		||||
            <Text style={styles.tableCell}>
 | 
			
		||||
              {!item[column + 'total']
 | 
			
		||||
                ? ''
 | 
			
		||||
                : formatQuantity(item[column + 'total'], 2) + item[column + 'conversion_unit']}
 | 
			
		||||
            </Text>
 | 
			
		||||
            <Text style={!isDouble || column === 'right_' ? styles.tableCellLast : styles.tableCell}>
 | 
			
		||||
              {item[column + 'isExcluded']
 | 
			
		||||
                ? '不计入合同  ' + (item[column + 'comment'] || '')
 | 
			
		||||
                : item[column + 'comment'] || ''}
 | 
			
		||||
            </Text>
 | 
			
		||||
          </React.Fragment>
 | 
			
		||||
        ))}
 | 
			
		||||
      </View>
 | 
			
		||||
    ));
 | 
			
		||||
    let addCol = <></>;
 | 
			
		||||
    if (detail.category === RecordCategory.purchase) {
 | 
			
		||||
      const allprice = getAllPrice();
 | 
			
		||||
      addCol = (
 | 
			
		||||
        <View style={styles.tableContent}>
 | 
			
		||||
          {columns.map((column, columnIndex) => (
 | 
			
		||||
            <React.Fragment key={columnIndex}>
 | 
			
		||||
              <Text style={styles.tableCell2}></Text>
 | 
			
		||||
              <Text style={styles.tableCell}>{column === 'left_' ? '' : '总金额'}</Text>
 | 
			
		||||
              <Text style={styles.tableCell}>{column === 'left_' ? '' : allprice}</Text>
 | 
			
		||||
              <Text style={!isDouble || column === 'right_' ? styles.tableCellLast : styles.tableCell}></Text>
 | 
			
		||||
            </React.Fragment>
 | 
			
		||||
          ))}
 | 
			
		||||
        </View>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return detail.category === RecordCategory.purchase ? (
 | 
			
		||||
      <>
 | 
			
		||||
        {page}
 | 
			
		||||
        {addCol}
 | 
			
		||||
      </>
 | 
			
		||||
    ) : (
 | 
			
		||||
      page
 | 
			
		||||
    );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const renderPrice = (data, isDouble) => {
 | 
			
		||||
    const columns = isDouble ? ['left_', 'right_'] : [''];
 | 
			
		||||
    return data.map((item, index) => (
 | 
			
		||||
      <View key={index} style={styles.tableContent}>
 | 
			
		||||
        {columns.map((column, columnIndex) => (
 | 
			
		||||
          <React.Fragment key={columnIndex}>
 | 
			
		||||
            <Text style={styles.tableCell2}>{item[column + 'name']}</Text>
 | 
			
		||||
            <Text style={styles.tableCell}>
 | 
			
		||||
              {formatQuantity(item[column + 'unit_price'], 2) + '元/' + item[column + 'unit']}
 | 
			
		||||
            </Text>
 | 
			
		||||
            <Text style={styles.tableCell}>
 | 
			
		||||
              {formatQuantity(item[column + 'count'], 2)}
 | 
			
		||||
              {item[column + 'unit']}
 | 
			
		||||
            </Text>
 | 
			
		||||
            <Text style={styles.tableCell}>{formatCurrency(item[column + 'all_price'], 2)}</Text>
 | 
			
		||||
            <Text style={!isDouble || column === 'right_' ? styles.tableCellLast : styles.tableCell}>
 | 
			
		||||
              {item[column + 'comment'] || ''}
 | 
			
		||||
            </Text>
 | 
			
		||||
          </React.Fragment>
 | 
			
		||||
        ))}
 | 
			
		||||
      </View>
 | 
			
		||||
    ));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Document>
 | 
			
		||||
      <Page size="A4" style={{ ...styles.page, marginTop: detail.margingTop }}>
 | 
			
		||||
@ -365,216 +441,44 @@ const PreviewDocument = ({
 | 
			
		||||
                <Text style={styles.headerLeftRight}>车号:{car}</Text>
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {/* 单列定价 */}
 | 
			
		||||
            {!isDouble && detail.category === RecordCategory.purchase && (
 | 
			
		||||
            {/* 定价 */}
 | 
			
		||||
            {detail.category === RecordCategory.purchase && (
 | 
			
		||||
              <View style={styles.tableContentTitle}>
 | 
			
		||||
                <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>单价</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>金额</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitleLast}>备注</Text>
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {!isDouble &&
 | 
			
		||||
              detail.category === RecordCategory.purchase &&
 | 
			
		||||
              priceRule.length &&
 | 
			
		||||
              priceRule.map((item) => (
 | 
			
		||||
                <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {item?.unit_price && formatQuantity(item.unit_price, 2) + '元/' + item.unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {formatQuantity(item.count, 2)}
 | 
			
		||||
                    {item.unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>{formatCurrency(item.all_price, 2)}</Text>
 | 
			
		||||
                  <Text style={styles.tableCellLast}>{item.comment || ''}</Text>
 | 
			
		||||
                </View>
 | 
			
		||||
              ))}
 | 
			
		||||
            {/* 双列定价 */}
 | 
			
		||||
            {isDouble && detail.category === RecordCategory.purchase && (
 | 
			
		||||
              <View style={styles.tableContentTitle}>
 | 
			
		||||
                <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>单价</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>金额</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>备注</Text>
 | 
			
		||||
                <Text style={!isDouble ? styles.tableCellTitleLast : styles.tableCellTitle}>备注</Text>
 | 
			
		||||
                {isDouble && (
 | 
			
		||||
                  <>
 | 
			
		||||
                    <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
                    <Text style={styles.tableCellTitle}>单价</Text>
 | 
			
		||||
                    <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
                    <Text style={styles.tableCellTitle}>金额</Text>
 | 
			
		||||
                    <Text style={styles.tableCellTitleLast}>备注</Text>
 | 
			
		||||
                  </>
 | 
			
		||||
                )}
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {isDouble &&
 | 
			
		||||
              detail.category === RecordCategory.purchase &&
 | 
			
		||||
              priceRule.length &&
 | 
			
		||||
              dobulePriceRule.map((item) => (
 | 
			
		||||
                <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.left_name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {item?.left_unit_price && formatQuantity(item.left_unit_price, 2) + '元/' + item.left_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {formatQuantity(item.left_count, 2)}
 | 
			
		||||
                    {item.left_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>{formatCurrency(item.left_all_price, 2)}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>{item.left_comment || ''}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.right_name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {item?.right_unit_price && formatQuantity(item.right_unit_price, 2) + '元/' + item.right_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {item.right_count && formatQuantity(item.right_count)}
 | 
			
		||||
                    {item.right_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {item.right_all_price && formatCurrency(item.right_all_price, 2)}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCellLast}>{item.right_comment || ''}</Text>
 | 
			
		||||
                </View>
 | 
			
		||||
              ))}
 | 
			
		||||
            {detail.category === RecordCategory.purchase &&
 | 
			
		||||
              renderPrice(isDouble ? dobulePriceRule : priceRule, isDouble)}
 | 
			
		||||
            {/* ============================================================两表分割================================================================================= */}
 | 
			
		||||
            {/* 单列租金及费用 */}
 | 
			
		||||
            {!isDouble && (
 | 
			
		||||
            <View style={styles.tableContentTitle}>
 | 
			
		||||
              <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
              <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
              <Text style={styles.tableCellTitle}>小计</Text>
 | 
			
		||||
                <Text
 | 
			
		||||
                  style={
 | 
			
		||||
                    detail.category === RecordCategory.purchase ? styles.tableCell2TitleLast : styles.tableCellTitleLast
 | 
			
		||||
                  }
 | 
			
		||||
                >
 | 
			
		||||
                  备注
 | 
			
		||||
                </Text>
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {!isDouble &&
 | 
			
		||||
              record.map((item) => (
 | 
			
		||||
                <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {!item.count || item.isFee ? '' : formatQuantity(item.count, 2) + item.unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {(printSetup === PrintSetup.Display && !item.product_id && !item.isTotal) ||
 | 
			
		||||
                    (printSetup === PrintSetup.Manual && !item.product_id && !item.isTotal)
 | 
			
		||||
                      ? ''
 | 
			
		||||
                      : item.total
 | 
			
		||||
                        ? formatQuantity(item.total, 2)
 | 
			
		||||
                        : ''}
 | 
			
		||||
                    {item.isFee && !item.product_id // 判断未无产品关联费用
 | 
			
		||||
                      ? printSetup === PrintSetup.DisplayAndPrice && item.total
 | 
			
		||||
                        ? '元'
 | 
			
		||||
                        : ''
 | 
			
		||||
                      : item.conversion_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text
 | 
			
		||||
                    style={detail.category === RecordCategory.purchase ? styles.tableCell2Last : styles.tableCellLast}
 | 
			
		||||
                  >
 | 
			
		||||
                    {item.isExcluded ? '不计入合同  ' + (item.comment || '') : item.comment || ''}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                </View>
 | 
			
		||||
              ))}
 | 
			
		||||
            {!isDouble && detail.category === RecordCategory.purchase && (
 | 
			
		||||
              <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                <Text style={styles.tableCell2}></Text>
 | 
			
		||||
                <Text style={styles.tableCell}>总金额</Text>
 | 
			
		||||
                <Text style={styles.tableCell}>{getAllPrice()}</Text>
 | 
			
		||||
                <Text
 | 
			
		||||
                  style={detail.category === RecordCategory.purchase ? styles.tableCell2Last : styles.tableCellLast}
 | 
			
		||||
                ></Text>
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {/* 双列租及费用 */}
 | 
			
		||||
              <Text style={!isDouble ? styles.tableCellTitleLast : styles.tableCellTitle}>备注</Text>
 | 
			
		||||
              {isDouble && (
 | 
			
		||||
              <View style={styles.tableContentTitle}>
 | 
			
		||||
                <>
 | 
			
		||||
                  <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
                  <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
                  <Text style={styles.tableCellTitle}>小计</Text>
 | 
			
		||||
                <Text
 | 
			
		||||
                  style={detail.category === RecordCategory.purchase ? styles.tableCell2Title : styles.tableCellTitle}
 | 
			
		||||
                >
 | 
			
		||||
                  备注
 | 
			
		||||
                </Text>
 | 
			
		||||
                <Text style={styles.tableCellLargeTitle}>物料名称及规格</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>数量</Text>
 | 
			
		||||
                <Text style={styles.tableCellTitle}>小计</Text>
 | 
			
		||||
                <Text
 | 
			
		||||
                  style={
 | 
			
		||||
                    detail.category === RecordCategory.purchase ? styles.tableCell2TitleLast : styles.tableCellTitleLast
 | 
			
		||||
                  }
 | 
			
		||||
                >
 | 
			
		||||
                  备注
 | 
			
		||||
                </Text>
 | 
			
		||||
              </View>
 | 
			
		||||
                  <Text style={styles.tableCellTitleLast}>备注</Text>
 | 
			
		||||
                </>
 | 
			
		||||
              )}
 | 
			
		||||
            {isDouble &&
 | 
			
		||||
              dobuleRecord.map((item) => (
 | 
			
		||||
                <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.left_name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {!item.left_count || item.left_isFee ? '' : formatQuantity(item.left_count, 2) + item.left_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {(printSetup === PrintSetup.Display && !item.left_product_id && !item.left_isTotal) ||
 | 
			
		||||
                    (printSetup === PrintSetup.Manual && !item.left_product_id && !item.left_isTotal)
 | 
			
		||||
                      ? ''
 | 
			
		||||
                      : item.left_total
 | 
			
		||||
                        ? formatQuantity(item.left_total, 2)
 | 
			
		||||
                        : ''}
 | 
			
		||||
                    {item.left_isFee && !item.left_product_id // 判断未无产品关联费用
 | 
			
		||||
                      ? printSetup === PrintSetup.DisplayAndPrice && item.left_total
 | 
			
		||||
                        ? '元'
 | 
			
		||||
                        : '' // 不记录合同不需要单位
 | 
			
		||||
                      : item.left_conversion_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={detail.category === RecordCategory.purchase ? styles.tableCell2 : styles.tableCell}>
 | 
			
		||||
                    {item.left_isExcluded ? '不计入合同  ' + (item.left_comment || '') : item.left_comment || ''}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell2}>{item.right_name}</Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {!item.right_count || item.right_isFee ? '' : formatQuantity(item.right_count, 2) + item.right_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text style={styles.tableCell}>
 | 
			
		||||
                    {(printSetup === PrintSetup.Display && !item.right_product_id && !item.right_isTotal) ||
 | 
			
		||||
                    (printSetup === PrintSetup.Manual && !item.right_product_id && !item.right_isTotal)
 | 
			
		||||
                      ? ''
 | 
			
		||||
                      : item.right_total
 | 
			
		||||
                        ? formatQuantity(item.right_total, 2)
 | 
			
		||||
                        : ''}
 | 
			
		||||
                    {item.right_isFee && !item.right_product_id // 判断未无产品关联费用
 | 
			
		||||
                      ? printSetup === PrintSetup.DisplayAndPrice && item.right_total
 | 
			
		||||
                        ? '元'
 | 
			
		||||
                        : '' // 不记录合同不需要单位
 | 
			
		||||
                      : item.right_conversion_unit}
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  <Text
 | 
			
		||||
                    style={detail.category === RecordCategory.purchase ? styles.tableCell2Last : styles.tableCellLast}
 | 
			
		||||
                  >
 | 
			
		||||
                    {item.right_name && item.right_isExcluded
 | 
			
		||||
                      ? '不计入合同  ' + (item.right_comment || '')
 | 
			
		||||
                      : item.right_comment || ''}
 | 
			
		||||
                  </Text>
 | 
			
		||||
            </View>
 | 
			
		||||
              ))}
 | 
			
		||||
            {isDouble && detail.category === RecordCategory.purchase && (
 | 
			
		||||
              <View key={'key'} style={styles.tableContent}>
 | 
			
		||||
                <Text style={styles.tableCell2}></Text>
 | 
			
		||||
                <Text style={styles.tableCell}></Text>
 | 
			
		||||
                <Text style={styles.tableCell}></Text>
 | 
			
		||||
                <Text style={detail.category === RecordCategory.purchase ? styles.tableCell2 : styles.tableCell}></Text>
 | 
			
		||||
                <Text style={styles.tableCell2}></Text>
 | 
			
		||||
                <Text style={styles.tableCell}>总金额</Text>
 | 
			
		||||
                <Text style={styles.tableCell}>{getAllPrice()}</Text>
 | 
			
		||||
                <Text
 | 
			
		||||
                  style={detail.category === RecordCategory.purchase ? styles.tableCell2Last : styles.tableCellLast}
 | 
			
		||||
                ></Text>
 | 
			
		||||
              </View>
 | 
			
		||||
            )}
 | 
			
		||||
            {renderRecord(isDouble ? dobuleRecord : record, isDouble)}
 | 
			
		||||
            <View style={styles.tableFooter}>
 | 
			
		||||
              <View style={styles.tableFooterQr}>
 | 
			
		||||
                <Image src={imageUrl} />
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,14 @@
 | 
			
		||||
import { ConversionLogics, RecordCategory, RulesNumber, SourcesType, countCource } from '../../utils/constants';
 | 
			
		||||
import { renderItV2 } from '../pdf-documents/records-documentV2';
 | 
			
		||||
import { Service } from '@nocobase/utils';
 | 
			
		||||
import { Db, Service } from '@nocobase/utils';
 | 
			
		||||
import { RecordPdfOptions } from '../../interfaces/options';
 | 
			
		||||
import { PrintSetup } from '../../utils/system';
 | 
			
		||||
import Database from '@nocobase/database';
 | 
			
		||||
 | 
			
		||||
@Service()
 | 
			
		||||
export class RecordPdfService {
 | 
			
		||||
  @Db()
 | 
			
		||||
  private db: Database;
 | 
			
		||||
  async transformPdfV2(recordData: any, lease_data: any, fee_data: any, options: RecordPdfOptions) {
 | 
			
		||||
    const { isDouble, printSetup } = options;
 | 
			
		||||
 | 
			
		||||
@ -79,7 +82,7 @@ export class RecordPdfService {
 | 
			
		||||
      make_price = setData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 计算租金数据
 | 
			
		||||
    // !产品
 | 
			
		||||
    const leaseData = lease_data
 | 
			
		||||
      .map((lease) => {
 | 
			
		||||
        const data = {
 | 
			
		||||
@ -117,8 +120,7 @@ export class RecordPdfService {
 | 
			
		||||
      })
 | 
			
		||||
      .sort((a, b) => a.category_id - b.category_id);
 | 
			
		||||
 | 
			
		||||
    // 计算费用数据,包括有产品关联跟无产品关联
 | 
			
		||||
    // 关联产品的赔偿(人工录入/全部)
 | 
			
		||||
    // !产品赔偿
 | 
			
		||||
    const product_fee =
 | 
			
		||||
      printSetup === PrintSetup.Manual
 | 
			
		||||
        ? fee_data.filter((item) => item.product_id && item.count_source === SourcesType.staff)
 | 
			
		||||
@ -148,68 +150,109 @@ export class RecordPdfService {
 | 
			
		||||
        category_id: item.product_category_id,
 | 
			
		||||
      };
 | 
			
		||||
      if (item.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
        data['count'] = data.count1;
 | 
			
		||||
        data['total'] = data.count1;
 | 
			
		||||
      } else if (item.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
        if (item.convertible) data['count'] = data.count1 * item.product_ratio;
 | 
			
		||||
        else data['count'] = data.count1;
 | 
			
		||||
        if (item.convertible) data['total'] = data.count1 * item.product_ratio;
 | 
			
		||||
        else data['total'] = data.count1;
 | 
			
		||||
      } else if (item.conversion_logic_id === ConversionLogics.ProductWeight) {
 | 
			
		||||
        data['count'] = data.count1 * item.product_weight;
 | 
			
		||||
        data['total'] = data.count1 * item.product_weight;
 | 
			
		||||
      } else if (item.conversion_logic_id === ConversionLogics.ActualWeight) {
 | 
			
		||||
        data['count'] = item.actual_weight || item.record_weight;
 | 
			
		||||
        data['total'] = item.actual_weight || item.record_weight;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (item.weight_rules?.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
          data['count'] = data.count1 * item.weight_rules.weight;
 | 
			
		||||
          data['total'] = data.count1 * item.weight_rules.weight;
 | 
			
		||||
        } else if (item.weight_rules?.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
          data['count'] = data.count1 * item.weight_rules.weight * item.product_ratio;
 | 
			
		||||
          data['total'] = data.count1 * item.weight_rules.weight * item.product_ratio;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 如果 printSetup === PrintSetup.DisplayAndPrice 要计算费用产生的价格
 | 
			
		||||
      data['conversion_unit'] = item.unit;
 | 
			
		||||
      if (printSetup === PrintSetup.DisplayAndPrice) {
 | 
			
		||||
        data['total'] = data['count'] * item.unit_price;
 | 
			
		||||
        data['count'] = data['total'];
 | 
			
		||||
        data['total'] = data['total'] * item.unit_price;
 | 
			
		||||
        data['conversion_unit'] = '元';
 | 
			
		||||
      }
 | 
			
		||||
      return data;
 | 
			
		||||
    });
 | 
			
		||||
    // 无关联产品赔偿, 人工录取的情况直接为空,因为excludedFee已经处理,正常情况取非手动录入情况数据,excludedFee已经处理
 | 
			
		||||
    // !无关联赔偿 item中
 | 
			
		||||
    let manualData = [];
 | 
			
		||||
    const noProductFee = fee_data.filter((item) => !item.product_id && item.count_source === SourcesType.staff);
 | 
			
		||||
    if (noProductFee.length) {
 | 
			
		||||
      const itemFee = await this.db.sequelize.query(`
 | 
			
		||||
        select ri.product_id, ri.count, p.category_id, ri.comment
 | 
			
		||||
        from records r
 | 
			
		||||
        left join record_items ri on ri.record_id = r.id and ri.product_id in (${noProductFee.map((item) => item.fee_product_id).join(',')})
 | 
			
		||||
        join product p on p.id = ri.product_id
 | 
			
		||||
        where r.id = ${recordData.id}
 | 
			
		||||
      `);
 | 
			
		||||
      const result: any = itemFee[0];
 | 
			
		||||
      manualData = result.map((item) => {
 | 
			
		||||
        const feeRule = noProductFee.find((f) => f.fee_product_id === item.product_id);
 | 
			
		||||
        if (!feeRule) return;
 | 
			
		||||
        const data = {
 | 
			
		||||
          name: feeRule.custom_name || feeRule.label,
 | 
			
		||||
          unit: feeRule.unit,
 | 
			
		||||
          conversion_unit: feeRule.unit,
 | 
			
		||||
          comment: item.comment || '',
 | 
			
		||||
        };
 | 
			
		||||
        if (feeRule.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
          data['total'] = item.count;
 | 
			
		||||
        } else if (feeRule.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
          data['total'] = feeRule.convertible ? item.count * feeRule.product_ratio : item.count;
 | 
			
		||||
        } else if (feeRule.conversion_logic_id === ConversionLogics.ProductWeight) {
 | 
			
		||||
          data['total'] = item.count * feeRule.weight;
 | 
			
		||||
        } else if (feeRule.conversion_logic_id === ConversionLogics.ActualWeight) {
 | 
			
		||||
          data['total'] = feeRule.record_weight;
 | 
			
		||||
        } else {
 | 
			
		||||
          const weight_rule = item.weight_rules.find(
 | 
			
		||||
            (l) => l.product_id === item.product_id || l.product - RulesNumber === item.category_id,
 | 
			
		||||
          );
 | 
			
		||||
          if (weight_rule && weight_rule.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
            return item.count * weight_rule.weight;
 | 
			
		||||
          } else if (weight_rule && weight_rule.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
            return item.count * feeRule.product_ratio * weight_rule.weight;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (printSetup === PrintSetup.DisplayAndPrice) {
 | 
			
		||||
          data['count'] = data['total'];
 | 
			
		||||
          data['total'] = data['total'] * feeRule.unit_price;
 | 
			
		||||
          data['conversion_unit'] = '元';
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    // !无关联赔偿,出入库量
 | 
			
		||||
    const fee =
 | 
			
		||||
      printSetup === PrintSetup.Manual
 | 
			
		||||
        ? []
 | 
			
		||||
        : fee_data.filter((item) => !item.product_id && item.count_source !== SourcesType.staff);
 | 
			
		||||
    const no_product_fee = fee
 | 
			
		||||
      .map((item) => {
 | 
			
		||||
        // 购销/暂存/盘点无费用信息
 | 
			
		||||
        if (
 | 
			
		||||
          recordData.category === RecordCategory.purchase ||
 | 
			
		||||
          recordData.category === RecordCategory.staging ||
 | 
			
		||||
          recordData.category === RecordCategory.inventory
 | 
			
		||||
        )
 | 
			
		||||
        ) {
 | 
			
		||||
          return;
 | 
			
		||||
        if (item.count_source === countCource.artificial) {
 | 
			
		||||
          const data = recordData.record_fee_items?.find((hava) => hava.product?.id === item.fee_product_id);
 | 
			
		||||
          if (!data) return;
 | 
			
		||||
        }
 | 
			
		||||
        if (item.record_movement === '-1' && item.count_source === SourcesType.inbound) return;
 | 
			
		||||
        if (item.record_movement === '1' && item.count_source === SourcesType.outbound) return;
 | 
			
		||||
        const data = {
 | 
			
		||||
          isFee: true,
 | 
			
		||||
          name: item.custom_name || item.label,
 | 
			
		||||
          unit: '',
 | 
			
		||||
          conversion_unit: item.unit,
 | 
			
		||||
          unit: item.unit,
 | 
			
		||||
          comment: '',
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (item.conversion_logic_id === ConversionLogics.Keep) {
 | 
			
		||||
          data['count'] = lease_data.reduce((a, b) => a + b.count, 0);
 | 
			
		||||
          data['total'] = lease_data.reduce((a, b) => a + b.count, 0);
 | 
			
		||||
        } else if (item.conversion_logic_id === ConversionLogics.Product) {
 | 
			
		||||
          data['count'] = lease_data.reduce((a, b) => a + (item.convertible ? b.count * b.ratio : b.count), 0);
 | 
			
		||||
          data['total'] = lease_data.reduce((a, b) => a + (item.convertible ? b.count * b.ratio : b.count), 0);
 | 
			
		||||
        } else if (item.conversion_logic_id === ConversionLogics.ProductWeight) {
 | 
			
		||||
          data['count'] = lease_data.reduce((a, b) => a + b.count * b.weight, 0) / 1000;
 | 
			
		||||
          data['total'] = lease_data.reduce((a, b) => a + b.count * b.weight, 0) / 1000;
 | 
			
		||||
        } else if (item.conversion_logic_id === ConversionLogics.ActualWeight) {
 | 
			
		||||
          data['count'] = item.record_weight;
 | 
			
		||||
          data['total'] = item.record_weight;
 | 
			
		||||
        } else {
 | 
			
		||||
          if (item.weight_rules?.length) {
 | 
			
		||||
            // 计算有误,需要检查
 | 
			
		||||
            data['count'] = lease_data.reduce((a, b) => {
 | 
			
		||||
            data['total'] = lease_data.reduce((a, b) => {
 | 
			
		||||
              const weight_rule = item.weight_rules.find(
 | 
			
		||||
                (l) => l.product_id === b.product_id || l.product - RulesNumber === b.category_id,
 | 
			
		||||
              );
 | 
			
		||||
@ -221,34 +264,15 @@ export class RecordPdfService {
 | 
			
		||||
            }, 0);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // 如果 printSetup === PrintSetup.DisplayAndPrice 要计算费用产生的价格
 | 
			
		||||
        data['conversion_unit'] = '吨';
 | 
			
		||||
        if (printSetup === PrintSetup.DisplayAndPrice) {
 | 
			
		||||
          data['total'] = data['count'] * item.unit_price;
 | 
			
		||||
          data['count'] = data['total'];
 | 
			
		||||
          data['total'] = data['total'] * item.unit_price;
 | 
			
		||||
          data['conversion_unit'] = '元';
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
      })
 | 
			
		||||
      .filter((item) => item && item.count);
 | 
			
		||||
    // 注意把手动录入的加入
 | 
			
		||||
    const manualData = recordData.record_fee_items;
 | 
			
		||||
    // 因为以往逻辑是根据规则查询,这个订单中数据智能单独查询
 | 
			
		||||
    const excludedFee =
 | 
			
		||||
      manualData
 | 
			
		||||
        ?.map((item) => {
 | 
			
		||||
          const data = {
 | 
			
		||||
            isFee: true,
 | 
			
		||||
            name: item.product.custom_name || item.product.label,
 | 
			
		||||
            comment: '',
 | 
			
		||||
            count: item.count,
 | 
			
		||||
            isExcluded: item.is_excluded,
 | 
			
		||||
          };
 | 
			
		||||
          const feeRule = fee_data.find((fee) => fee.fee_product_id === item.product_id);
 | 
			
		||||
          if (feeRule) {
 | 
			
		||||
            data['total'] = feeRule.unit_price * item.count;
 | 
			
		||||
            data['unit'] = '';
 | 
			
		||||
          }
 | 
			
		||||
          return data;
 | 
			
		||||
        })
 | 
			
		||||
        .filter(Boolean) || [];
 | 
			
		||||
      .filter((item) => item && item.total);
 | 
			
		||||
 | 
			
		||||
    const product_fees = transFormProductFee.filter(Boolean);
 | 
			
		||||
    // 内容(租金+费用)
 | 
			
		||||
@ -280,10 +304,10 @@ export class RecordPdfService {
 | 
			
		||||
        product_correlation.push(itemB);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    const recordPdfData = [...product_correlation, ...no_product_fee, ...excludedFee];
 | 
			
		||||
    const recordPdfData = [...product_correlation, ...manualData, ...no_product_fee].filter(Boolean);
 | 
			
		||||
    return await renderItV2({
 | 
			
		||||
      detail: recordData,
 | 
			
		||||
      record: recordPdfData, // 租金+费用,无关联费用
 | 
			
		||||
      record: recordPdfData,
 | 
			
		||||
      priceRule: make_price,
 | 
			
		||||
      isDouble,
 | 
			
		||||
      printSetup,
 | 
			
		||||
 | 
			
		||||
@ -99,19 +99,6 @@ SELECT
 | 
			
		||||
    WHERE
 | 
			
		||||
      r.id = rv.record_id
 | 
			
		||||
  ) AS vehicles,
 | 
			
		||||
  (
 | 
			
		||||
    SELECT
 | 
			
		||||
      JSONB_AGG(
 | 
			
		||||
        TO_JSONB(
 | 
			
		||||
          JSONB_SET(TO_JSONB(rfi), '{product}', TO_JSONB(p))
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
    FROM
 | 
			
		||||
      record_fee_items rfi
 | 
			
		||||
      JOIN product p ON p.id = rfi.product_id
 | 
			
		||||
    WHERE
 | 
			
		||||
      rfi.record_id = r.id
 | 
			
		||||
  ) AS record_fee_items,
 | 
			
		||||
  -- 查询分组实际重量
 | 
			
		||||
  (
 | 
			
		||||
    SELECT
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user