kts-component-invoice-operate 3.2.165 → 3.2.166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/.dumi/theme/builtins/API.tsx +66 -66
  2. package/.editorconfig +16 -16
  3. package/.fatherrc.ts +4 -4
  4. package/.prettierignore +7 -7
  5. package/.prettierrc +11 -11
  6. package/.umirc.ts +8 -8
  7. package/README.md +9 -9
  8. package/dist/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/EndowCode/index.d.ts +4 -4
  9. package/dist/TaxClassificationCodeModal/index.d.ts +2 -1
  10. package/dist/index.esm.js +767 -721
  11. package/dist/index.js +766 -720
  12. package/docs/index.md +5 -5
  13. package/docs-dist/static/arrowDown.a1cbf0d8.svg +2 -2
  14. package/docs-dist/static/arrowUp.4c482054.svg +2 -2
  15. package/docs-dist/static/fork.5431267d.svg +11 -11
  16. package/docs-dist/static/plus.44013ce3.svg +11 -11
  17. package/docs-dist/static/plus.4fd1af30.svg +11 -11
  18. package/index.html +12 -12
  19. package/package.json +61 -61
  20. package/src/Invoice/Invoice-digtal/_test/disabled/index.tsx +40 -40
  21. package/src/Invoice/Invoice-digtal/_test/easiest/index.tsx +17 -17
  22. package/src/Invoice/Invoice-digtal/_test/header/index.tsx +84 -84
  23. package/src/Invoice/Invoice-digtal/_test/importGoods/index.tsx +868 -868
  24. package/src/Invoice/Invoice-digtal/_test/importStakeholder/index.tsx +18 -18
  25. package/src/Invoice/Invoice-digtal/_test/lineCredit/index.tsx +19 -19
  26. package/src/Invoice/Invoice-digtal/_test/prefab/index.tsx +150 -150
  27. package/src/Invoice/Invoice-digtal/_test/readOnly/index.tsx +55 -55
  28. package/src/Invoice/Invoice-digtal/_test/realEstateInfo/index.tsx +21 -21
  29. package/src/Invoice/Invoice-digtal/_test/stakeholder/index.tsx +12 -12
  30. package/src/Invoice/Invoice-digtal/_test/typeSelection/index.tsx +29 -29
  31. package/src/Invoice/Invoice-digtal/index.md +34 -34
  32. package/src/Invoice/InvoiceController/InvoiceControllerForm/index.ts +95 -95
  33. package/src/Invoice/InvoiceController/InvoiceControllerState/AutoComplete/index.ts +26 -26
  34. package/src/Invoice/InvoiceController/InvoiceControllerState/BuyerState/index.tsx +88 -88
  35. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/Drag/index.ts +15 -15
  36. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/EndowCode/index.tsx +104 -104
  37. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/IColumnsReplenish/index.ts +10 -10
  38. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/IGood/index.ts +87 -87
  39. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/ImportGoods/index.ts +81 -81
  40. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/LineAttributeType/index.ts +7 -7
  41. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/ProductComparison/index.ts +9 -9
  42. package/src/Invoice/InvoiceController/InvoiceControllerState/GoodsListState/index.ts +131 -131
  43. package/src/Invoice/InvoiceController/InvoiceControllerState/Stakeholder/index.ts +13 -13
  44. package/src/Invoice/InvoiceController/InvoiceControllerState/index.ts +65 -65
  45. package/src/Invoice/InvoiceController/fns/addGood.ts +11 -11
  46. package/src/Invoice/InvoiceController/fns/addGoodDiscount.ts +126 -126
  47. package/src/Invoice/InvoiceController/fns/addGoodDiscountV2.ts +86 -86
  48. package/src/Invoice/InvoiceController/fns/delGood.ts +41 -41
  49. package/src/Invoice/InvoiceController/fns/getGoodsSearch.ts +26 -26
  50. package/src/Invoice/InvoiceController/fns/importGoodsDrawer.ts +79 -79
  51. package/src/Invoice/InvoiceController/fns/itemBlur.ts +40 -40
  52. package/src/Invoice/InvoiceController/fns/mergeDetails.ts +201 -201
  53. package/src/Invoice/InvoiceController/fns/mergeDiscount.ts +35 -35
  54. package/src/Invoice/InvoiceController/fns/saveEditGood.ts +24 -24
  55. package/src/Invoice/InvoiceController/fns/setEditGood.ts +16 -16
  56. package/src/Invoice/InvoiceController/fns/setGoods.ts +10 -10
  57. package/src/Invoice/InvoiceController/fns/updateInvoiceNo.ts +8 -8
  58. package/src/Invoice/InvoiceController/index.ts +87 -87
  59. package/src/Invoice/_test/buyerNameSearch/index.tsx +42 -42
  60. package/src/Invoice/_test/children/index.tsx +214 -214
  61. package/src/Invoice/_test/deduction/index.tsx +935 -935
  62. package/src/Invoice/_test/draft/index.tsx +40 -40
  63. package/src/Invoice/_test/easiest/index.tsx +5 -5
  64. package/src/Invoice/_test/endowCode/index.tsx +1158 -1158
  65. package/src/Invoice/_test/goodsMenuExpand/index.tsx +32 -32
  66. package/src/Invoice/_test/importBuyer/index.tsx +74 -74
  67. package/src/Invoice/_test/importGoods/index.tsx +1197 -1197
  68. package/src/Invoice/_test/invoiceType/index.tsx +59 -59
  69. package/src/Invoice/_test/isInvoiceNo/index.tsx +12 -12
  70. package/src/Invoice/_test/replaceHead/index.tsx +22 -22
  71. package/src/Invoice/_test/retrieveData/index.tsx +22 -22
  72. package/src/Invoice/_test/seller/index.tsx +28 -28
  73. package/src/Invoice/_test/setDataSource/index.tsx +73 -73
  74. package/src/Invoice/_test/unit/index.tsx +19 -19
  75. package/src/Invoice/index.less +31 -31
  76. package/src/Invoice/index.md +56 -56
  77. package/src/Invoice/index.tsx +183 -183
  78. package/src/Invoice/tools/calculate/index.ts +132 -132
  79. package/src/Invoice/tools/coolingFn/index.ts +17 -17
  80. package/src/Invoice/tools/evaluate/index.ts +7 -7
  81. package/src/Invoice/tools/idGenerator/index.ts +2 -2
  82. package/src/Invoice/tools/itemName/index.ts +55 -55
  83. package/src/Invoice/tools/lazyFn/index.ts +19 -19
  84. package/src/Invoice/tools/mounting/index.ts +13 -13
  85. package/src/Invoice/tools/strringFn/index.ts +40 -40
  86. package/src/Invoice/tools/useToGenerateId/index.ts +8 -8
  87. package/src/Invoice/tools/utils/index.ts +1 -1
  88. package/src/Invoice/tools/utils/money/index.ts +20 -20
  89. package/src/Invoice/ui/default/AddComparisonDrawer/index.tsx +149 -149
  90. package/src/Invoice/ui/default/Buyer/index.less +219 -219
  91. package/src/Invoice/ui/default/Buyer/index.tsx +114 -114
  92. package/src/Invoice/ui/default/Buyer/ui/BuyerNameInput/index.tsx +166 -166
  93. package/src/Invoice/ui/default/Buyer/ui/ImportBuyerButton/index.tsx +21 -21
  94. package/src/Invoice/ui/default/EndowCodeDrawer/index.less +8 -8
  95. package/src/Invoice/ui/default/EndowCodeDrawer/index.tsx +592 -586
  96. package/src/Invoice/ui/default/GoodsList/hook/useColumns/autoFillFn/index.ts +647 -647
  97. package/src/Invoice/ui/default/GoodsList/hook/useColumns/index.tsx +711 -711
  98. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.less +20 -20
  99. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Drag/index.tsx +205 -205
  100. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/Expand/index.tsx +57 -57
  101. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.less +18 -18
  102. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemCodeInput/index.tsx +49 -49
  103. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemNameInput/index.less +17 -17
  104. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/ItemNameInput/index.tsx +91 -91
  105. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowEditButton/index.tsx +30 -30
  106. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/_useAddComparison/index.tsx +43 -43
  107. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useAddDiscount/index.tsx +118 -118
  108. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useDelItem/index.tsx +41 -41
  109. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/hook/useEndowCode/index.tsx +25 -25
  110. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/index.less +13 -13
  111. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowMenu/index.tsx +99 -99
  112. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/RowSaveButton/index.tsx +14 -14
  113. package/src/Invoice/ui/default/GoodsList/hook/useColumns/ui/TitleText/index.tsx +20 -20
  114. package/src/Invoice/ui/default/GoodsList/hook/useDeduction/index.tsx +24 -24
  115. package/src/Invoice/ui/default/GoodsList/hook/useOnRow/index.tsx +52 -52
  116. package/src/Invoice/ui/default/GoodsList/hook/useRowSelection/index.tsx +120 -120
  117. package/src/Invoice/ui/default/GoodsList/hook/useWindowClick/index.tsx +23 -23
  118. package/src/Invoice/ui/default/GoodsList/index.less +185 -185
  119. package/src/Invoice/ui/default/GoodsList/index.tsx +205 -205
  120. package/src/Invoice/ui/default/GoodsList/ui/AddRowButton/index.tsx +65 -65
  121. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.less +21 -21
  122. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.tsx +244 -244
  123. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useCommodityComparisonButton/index.tsx +75 -75
  124. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useDelRowButton/index.tsx +69 -69
  125. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useEndowCodeButton/index.tsx +65 -65
  126. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useMergeDetails/index.tsx +91 -91
  127. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useMergeDiscount/index.tsx +36 -36
  128. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useSalesDiscount/index.tsx +109 -109
  129. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/hooks/useSalesGifts/index.tsx +94 -94
  130. package/src/Invoice/ui/default/GoodsList/ui/BulkMenu/index.tsx +37 -37
  131. package/src/Invoice/ui/default/GoodsList/ui/DescribeSwitch/index.tsx +36 -36
  132. package/src/Invoice/ui/default/GoodsList/ui/Search/index.less +10 -10
  133. package/src/Invoice/ui/default/GoodsList/ui/Search/index.tsx +52 -52
  134. package/src/Invoice/ui/default/GoodsList/ui/Statistics/index.less +18 -18
  135. package/src/Invoice/ui/default/GoodsList/ui/Statistics/index.tsx +114 -114
  136. package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.less +40 -40
  137. package/src/Invoice/ui/default/GoodsList/ui/TableRow/index.tsx +71 -71
  138. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual/index.less +38 -38
  139. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual/index.tsx +130 -130
  140. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual.o/index.less +44 -44
  141. package/src/Invoice/ui/default/GoodsList/ui/TableVirtual.o/index.tsx +96 -96
  142. package/src/Invoice/ui/default/GoodsList/ui/TaxIncludedSwitch/index.tsx +31 -31
  143. package/src/Invoice/ui/default/ImportBuyerDrawer/index.tsx +75 -75
  144. package/src/Invoice/ui/default/ImportGoodsDrawer/index.tsx +198 -198
  145. package/src/Invoice/ui/default/InvoiceHeader/index.less +68 -68
  146. package/src/Invoice/ui/default/InvoiceHeader/index.tsx +246 -246
  147. package/src/Invoice/ui/default/Seller/index.less +113 -113
  148. package/src/Invoice/ui/default/Seller/index.tsx +98 -98
  149. package/src/Invoice/ui/default/Sign/index.less +14 -14
  150. package/src/Invoice/ui/default/Sign/index.tsx +71 -71
  151. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/autoFillFn/index.ts +639 -639
  152. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/index.tsx +660 -660
  153. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/svg/plus.svg +11 -11
  154. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.less +20 -20
  155. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/Drag/index.tsx +205 -205
  156. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/ItemNameInput/index.less +9 -9
  157. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/ItemNameInput/index.tsx +87 -87
  158. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowEditButton/index.tsx +30 -30
  159. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/_useAddComparison/index.tsx +43 -43
  160. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useAddDiscount/index.tsx +76 -76
  161. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useDelItem/index.tsx +41 -41
  162. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/hook/useEndowCode/index.tsx +34 -34
  163. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/index.less +13 -13
  164. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowMenu/index.tsx +98 -98
  165. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/RowSaveButton/index.tsx +14 -14
  166. package/src/Invoice/ui/digtal/GoodsList/hook/useColumns/ui/TitleText/index.tsx +20 -20
  167. package/src/Invoice/ui/digtal/GoodsList/hook/useOnRow/index.tsx +51 -51
  168. package/src/Invoice/ui/digtal/GoodsList/hook/useRowSelection/index.tsx +121 -121
  169. package/src/Invoice/ui/digtal/GoodsList/hook/useWindowClick/index.tsx +23 -23
  170. package/src/Invoice/ui/digtal/GoodsList/index.less +56 -56
  171. package/src/Invoice/ui/digtal/GoodsList/index.tsx +180 -180
  172. package/src/Invoice/ui/digtal/GoodsList/ui/AddRowButton/index.tsx +67 -67
  173. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/index.tsx +340 -340
  174. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useAddDiscountRowButton/svg/add.svg +11 -11
  175. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useCommodityComparisonButton/index.tsx +75 -75
  176. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useDelRowButton/index.tsx +50 -50
  177. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useEmptyRefill/index.tsx +37 -37
  178. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useEndowCodeButton/index.tsx +82 -82
  179. package/src/Invoice/ui/digtal/GoodsList/ui/BulkMenu/hooks/useReselectInvoiceType/index.tsx +57 -57
  180. package/src/Invoice/ui/digtal/GoodsList/ui/DescribeSwitch/index.tsx +36 -36
  181. package/src/Invoice/ui/digtal/GoodsList/ui/Search/index.less +11 -11
  182. package/src/Invoice/ui/digtal/GoodsList/ui/Search/index.tsx +50 -50
  183. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/index.less +53 -53
  184. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/index.tsx +98 -98
  185. package/src/Invoice/ui/digtal/GoodsList/ui/Statistics/svg/fork.svg +11 -11
  186. package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.less +28 -28
  187. package/src/Invoice/ui/digtal/GoodsList/ui/TableRow/index.tsx +53 -53
  188. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual/index.less +38 -38
  189. package/src/Invoice/ui/digtal/GoodsList/ui/TableVirtual/index.tsx +108 -108
  190. package/src/Invoice/ui/digtal/GoodsList/ui/TaxIncludedSwitch/index.tsx +31 -31
  191. package/src/Invoice/ui/digtal/InvoiceHeader/index.less +57 -57
  192. package/src/Invoice/ui/digtal/InvoiceHeader/index.tsx +77 -77
  193. package/src/Invoice/ui/digtal/RealEstateInfo/index.less +14 -14
  194. package/src/Invoice/ui/digtal/RealEstateInfo/index.tsx +192 -192
  195. package/src/Invoice/ui/digtal/Sign/index.less +48 -48
  196. package/src/Invoice/ui/digtal/Sign/index.tsx +99 -99
  197. package/src/Invoice/ui/digtal/StakeFarmerholder/index.less +99 -99
  198. package/src/Invoice/ui/digtal/StakeFarmerholder/index.tsx +436 -435
  199. package/src/Invoice/ui/digtal/StakeFarmerholder/svg/arrowDown.svg +2 -2
  200. package/src/Invoice/ui/digtal/StakeFarmerholder/svg/arrowUp.svg +2 -2
  201. package/src/Invoice/ui/digtal/StakeFarmerholder/svg/plus.svg +11 -11
  202. package/src/Invoice/ui/digtal/Stakeholder/index.less +99 -99
  203. package/src/Invoice/ui/digtal/Stakeholder/index.tsx +396 -396
  204. package/src/Invoice/ui/digtal/Stakeholder/svg/arrowDown.svg +2 -2
  205. package/src/Invoice/ui/digtal/Stakeholder/svg/arrowUp.svg +2 -2
  206. package/src/Invoice/ui/digtal/Stakeholder/svg/plus.svg +11 -11
  207. package/src/InvoiceTypeModal/_test/easiest/index.tsx +31 -31
  208. package/src/InvoiceTypeModal/index.less +7 -7
  209. package/src/InvoiceTypeModal/index.md +5 -5
  210. package/src/InvoiceTypeModal/index.tsx +161 -161
  211. package/src/TaxClassificationCodeModal/_test/easiest/index.tsx +184 -180
  212. package/src/TaxClassificationCodeModal/index.less +5 -5
  213. package/src/TaxClassificationCodeModal/index.md +6 -6
  214. package/src/TaxClassificationCodeModal/index.tsx +141 -107
  215. package/src/index.ts +12 -12
  216. package/tsconfig.json +31 -31
  217. package/typings.d.ts +3 -3
@@ -1,661 +1,661 @@
1
-
2
- import React from 'react';
3
- import Icon from '@ant-design/icons';
4
- import { Form } from 'kts-components-antd-x3';
5
- import { ReactComponent as PlusSvg } from './svg/plus.svg'
6
- import { AutoComplete, Select, Button, Input, Spin, Tooltip, InputProps } from 'kts-xui';
7
- import { WrappedFormUtils } from 'kts-components-antd-x3/lib/form/Form';
8
- import { getItemNameWithShorthand } from '../../../../../tools/itemName';
9
- import { IGood, LineAttributeType } from '../../../../../InvoiceController';
10
- import Invoice from '../../../../..';
11
- import TitleText from './ui/TitleText';
12
- import ItemNameInput from './ui/ItemNameInput';
13
- import {
14
- onChangeQuantity,
15
- onChangePriceIncludeTax,
16
- onChangePriceExcludeTax,
17
- onChangeLineAmountIncludeTax,
18
- onChangeLineAmountExcludeTax,
19
- onChangeTaxRate,
20
- onChangeItemName,
21
- } from './autoFillFn';
22
- import Drag from './ui/Drag';
23
- import { nonScientificNotation } from '../../../../../tools/calculate';
24
-
25
- export default (form: WrappedFormUtils) => {
26
- const { getFieldDecorator, getFieldValue } = form;
27
-
28
- const controller = Invoice.useInvoiceController();
29
-
30
- const rootElement = controller.useMemo(s => s.rootElement, []);
31
-
32
- /** 是否含税 */
33
- const isTaxIncluded = controller.useMemo(e => e.goodsListState.isTaxIncluded, []);
34
-
35
- /** 组件模式 */
36
- const model = controller.useMemo(e => e.model, []);
37
-
38
- /** 计算类型 */
39
- const calculateType = controller.useMemo(e => e.goodsListState.calculateType, []);
40
-
41
- /** 是否显示我方 */
42
- const isMyShow = controller.useMemo(e => e.goodsListState.isMyShow, []);
43
-
44
- /** 正在编辑的货物 */
45
- const editGood = controller.useMemo((e) => e.goodsListState.editGood, []);
46
-
47
- /** 是否启用拖拽 */
48
- const isStart = controller.useMemo((e) => e.goodsListState.drag.isStart, []);
49
-
50
- /** 禁用字段 */
51
- const disableds = controller.useMemo((e) => e.stakeholder.disableds || [], []);
52
-
53
- /** 搜索条件 */
54
- const searchValue = controller.useMemo((e) => e.goodsListState.searchValue, []);
55
-
56
- /** 税率列表 */
57
- const taxRateList = controller.useMemo((e) => e.goodsListState.taxRateList, []);
58
-
59
- /** 单位列表 */
60
- const unitList = controller.useMemo((e) => e.goodsListState.unitList, []);
61
-
62
- /** 商品表格补充配置 */
63
- const columnsReplenish = controller.useMemo((e) => e.goodsListState.columnsReplenish, []);
64
-
65
- /** 扣除额 */
66
- const deduction = controller.useMemo((e) => e.goodsListState.deduction, []);
67
-
68
- /** 计算中启动字段 */
69
- const changeField = controller.useMemo((e) => e.calculatingField, []);
70
-
71
- /** 计算中启动字段 */
72
- const setChangeField = React.useCallback((value: string) => controller.run(async s => { s.calculatingField = value }), []);
73
-
74
- const onNumberValueChange = React.useCallback((e) => {
75
- const value = e?.target?.value;
76
- if (value) {
77
- return value.replace(/[^0-9-\.]/g, '');
78
- }
79
- }, [])
80
-
81
- /** 获取补充校验规则 */
82
- const getReplenishRules = React.useCallback((id: string) => {
83
- return columnsReplenish[id] ? columnsReplenish[id].rules || [] : []
84
- }, [columnsReplenish])
85
-
86
- /** 金额整数位限制,不传默认9位 */
87
- const priceIntegerDigit = controller.useMemo((e) => e.priceIntegerDigit || 9, []);
88
-
89
- /** 表头 */
90
- const columns = React.useMemo(() => {
91
- return [
92
- {
93
- title: ' ',
94
- key: 'drag',
95
- width: 40,
96
- align: 'center',
97
- render: (_: any, record: IGood) => <Drag record={record} />
98
- },
99
- {
100
- title: '序号',
101
- key: 'serialNo',
102
- dataIndex: 'serialNo',
103
- width: 50,
104
- render: (e: number) => <span style={{ padding: '0 10px' }}>{e}</span>,
105
- },
106
- {
107
- title: <TitleText required >项目名称</TitleText>,
108
- key: 'itemName',
109
- render: (_: string, record: IGood) => {
110
- if (editGood?.$index === record.$index && !disableds.includes('itemName') && model !== 'prefab') {
111
- return (
112
- <Form.Item>
113
- <div style={{ display: 'flex' }} >
114
- {getFieldDecorator('itemName', {
115
- initialValue: isMyShow ? record.itemNameSelf : record.itemName,
116
- rules: [
117
- ...getReplenishRules('itemName'),
118
- {
119
- validator: async (_, __, callback) => {
120
- await controller.wait();
121
- const value = controller.state.goodsListState.editGood;
122
- if (!value?.itemName && !value?.itemNameSelf) {
123
- callback('项目名称不能为空');
124
- } else {
125
- return;
126
- }
127
- }
128
- }
129
- ]
130
- })(
131
- <ItemNameInput
132
- editGood={editGood}
133
- shorthand={editGood.shorthand}
134
- suffix={
135
- <Tooltip title="点击从商品管理中添加商品信息">
136
- <Button
137
- type="link"
138
- style={{ padding: 0, width: 20, fontSize: 20, fill: '#0074ff' }}
139
- icon={<PlusSvg />}
140
- onClick={controller.pipeline(async s => { s.goodsListState.importGoods.isVisibleDrawer = true })}
141
- />
142
- </Tooltip>
143
- }
144
- onChange={() => {
145
- onChangeItemName(controller, form, record);
146
- }}
147
- />
148
- )}
149
- </div>
150
- </Form.Item>
151
- );
152
- } else {
153
- return (
154
- <span>
155
- {record.lineAttribute === LineAttributeType.折扣行 ? <span className='goods-list-digtal-discount-tag'>折扣</span> : <></>}
156
- <MyItemNameDiv
157
- valueT={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemNameSelf || '' }), searchValue)}
158
- valueF={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemName || '' }), searchValue)}
159
- isMyShow={isMyShow}
160
- />
161
- </span>
162
- )
163
- }
164
- },
165
- },
166
- {
167
- title: <TitleText rules={columnsReplenish['itemModelName']?.rules} >规格型号</TitleText>,
168
- key: 'itemModelName',
169
- width: 119,
170
- render: (_: string, record: IGood) => {
171
- if (editGood?.$index === record.$index && !disableds.includes('itemModelName') && model !== 'prefab') {
172
- return (
173
- <Form.Item>
174
- {getFieldDecorator('itemModelName', {
175
- initialValue: isMyShow ? editGood.itemModelNameSelf : editGood.itemModelName,
176
- rules: getReplenishRules('itemModelName'),
177
- })(
178
- <MyInput
179
- onChange={async () => {
180
- await controller.wait()
181
- const key = isMyShow ? 'itemModelNameSelf' : 'itemModelName';
182
- const value = {} as any;
183
- value[key] = form.getFieldsValue().itemModelName;
184
- controller.setEditGood(value);
185
- }}
186
- />,
187
- )}
188
- </Form.Item>
189
- );
190
- } else {
191
- return (
192
- <MyItemNameDiv
193
- valueT={formatSearch(record.itemModelNameSelf, searchValue)}
194
- valueF={formatSearch(record.itemModelName, searchValue)}
195
- isMyShow={isMyShow}
196
- />
197
- )
198
- }
199
- },
200
- },
201
- {
202
- title: <TitleText rules={columnsReplenish['unit']?.rules} >单位</TitleText>,
203
- key: 'unit',
204
- width: 70,
205
- render: (_: string, record: IGood) => {
206
- if (editGood?.$index === record.$index && !disableds.includes('unit') && model !== 'prefab') {
207
- return (
208
- <Form.Item>
209
- {getFieldDecorator('unit', {
210
- initialValue: editGood.unit,
211
- rules: getReplenishRules('unit'),
212
- })(
213
- <AutoComplete
214
- style={{ width: '100%' }}
215
- dataSource={unitList}
216
- getPopupContainer={() => rootElement || document.body}
217
- onChange={async () => {
218
- await controller.wait()
219
- controller.setEditGood({ unit: form.getFieldsValue().unit });
220
- }}
221
- />,
222
- )}
223
- </Form.Item>
224
- );
225
- } else {
226
- return <span style={{ padding: '0 10px' }}>{record.unit}</span>;
227
- }
228
- },
229
- },
230
- {
231
- title: <TitleText rules={columnsReplenish['quantity']?.rules} >数量</TitleText>,
232
- dataIndex: 'quantity',
233
- key: 'quantity',
234
- align: 'right',
235
- width: 149,
236
- render: (value: string, record: IGood) => {
237
- if (editGood?.$index === record.$index && !disableds.includes('quantity') && model !== 'prefab') {
238
- return (
239
- <Form.Item>
240
- {getFieldDecorator('quantity', {
241
- initialValue: nonScientificNotation(editGood.quantity),
242
- getValueFromEvent: onNumberValueChange,
243
- rules: [
244
- ...getReplenishRules('quantity'),
245
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '数量必须为数字' },
246
- {
247
- validator: async (_, value, callback) => {
248
- await controller.wait();
249
- const isvalue = !!value || value === 0;
250
- const isPrice = !!getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') || getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') === 0;
251
- if (isvalue || isPrice === isvalue) return;
252
- callback('请输入数量');
253
- }
254
- }
255
- ],
256
- })(
257
- <MyInput
258
- style={{ textAlign: 'right' }}
259
- maxLength={16}
260
- loading={isCipher(changeField, "quantity")}
261
- onChange={async () => {
262
- setChangeField('quantity');
263
- await onChangeQuantity(controller, form, record);
264
- }}
265
- />,
266
- )}
267
- </Form.Item>
268
- );
269
- } else {
270
- return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
271
- }
272
- },
273
- },
274
- {
275
- title: <TitleText rules={columnsReplenish['priceIncludeTax']?.rules} >单价(含税)</TitleText>,
276
- dataIndex: 'priceIncludeTax',
277
- key: 'priceIncludeTax',
278
- align: 'right',
279
- width: 149,
280
- render: (value: string, record: IGood) => {
281
- if (editGood?.$index === record.$index && !disableds.includes('priceIncludeTax') && model !== 'prefab') {
282
- return (
283
- <Form.Item>
284
- {getFieldDecorator('priceIncludeTax', {
285
- initialValue: nonScientificNotation(editGood.priceIncludeTax),
286
- getValueFromEvent: onNumberValueChange,
287
- rules: [
288
- ...getReplenishRules('priceIncludeTax'),
289
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
290
- {
291
- validator: async (_, value, callback) => {
292
- await controller.wait();
293
- const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
294
- const isvalue = !!value || value === 0;
295
- if (isvalue || isQuantity === isvalue) return;
296
- callback('请输入单价');
297
- }
298
- }
299
- ],
300
- })(
301
- <MyInput
302
- style={{ textAlign: 'right' }}
303
- maxLength={16}
304
- loading={isCipher(changeField, 'priceIncludeTax')}
305
- onChange={() => {
306
- setChangeField('priceIncludeTax');
307
- onChangePriceIncludeTax(controller, form, record);
308
- }}
309
- />,
310
- )}
311
- </Form.Item>
312
- );
313
- } else {
314
- return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
315
- }
316
- },
317
- },
318
- {
319
- title: <TitleText rules={columnsReplenish['priceExcludeTax']?.rules} >单价(不含税)</TitleText>,
320
- dataIndex: 'priceExcludeTax',
321
- key: 'priceExcludeTax',
322
- align: 'right',
323
- width: 149,
324
- render: (value: string, record: IGood) => {
325
- if (editGood?.$index === record.$index && !disableds.includes('priceExcludeTax') && model !== 'prefab') {
326
- return (
327
- <Form.Item>
328
- {getFieldDecorator('priceExcludeTax', {
329
- initialValue: nonScientificNotation(editGood.priceExcludeTax),
330
- getValueFromEvent: onNumberValueChange,
331
- rules: [
332
- ...getReplenishRules('priceExcludeTax'),
333
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
334
- {
335
- validator: async (_, value, callback) => {
336
- await controller.wait();
337
- const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
338
- const isvalue = !!value || value === 0;
339
- if (isvalue || isQuantity === isvalue) return;
340
- callback('请输入单价');
341
- }
342
- }
343
- ],
344
- })(
345
- <MyInput
346
- style={{ textAlign: 'right' }}
347
- maxLength={16}
348
- loading={isCipher(changeField, 'priceExcludeTax')}
349
- onChange={() => {
350
- setChangeField('priceExcludeTax');
351
- onChangePriceExcludeTax(controller, form, record);
352
- }}
353
- />,
354
- )}
355
- </Form.Item>
356
- );
357
- } else {
358
- return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
359
- }
360
- },
361
- },
362
- {
363
- title: <TitleText required >金额(含税)</TitleText>,
364
- dataIndex: 'lineAmountIncludeTax',
365
- key: 'lineAmountIncludeTax',
366
- width: 119,
367
- align: 'right',
368
- render: (value: string, record: IGood) => {
369
- if (editGood?.$index === record.$index && !disableds.includes('lineAmountIncludeTax') && model !== 'prefab') {
370
- return (
371
- <Form.Item>
372
- {getFieldDecorator('lineAmountIncludeTax', {
373
- initialValue: editGood.lineAmountIncludeTax,
374
- getValueFromEvent: onNumberValueChange,
375
- rules: [
376
- ...getReplenishRules('lineAmountIncludeTax'),
377
- { required: true, message: '金额不能为空' },
378
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
379
- {
380
- validator: async (_, value, callback) => {
381
- if (`${value}`.split('.')[0].length > priceIntegerDigit) {
382
- callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
383
- }
384
- }
385
- },
386
- {
387
- validator: async (_, value, callback) => {
388
- if (deduction && parseFloat(value) <= deduction) {
389
- callback('扣除额不能大于等于价税合计');
390
- }
391
- }
392
- },
393
- ],
394
- })(
395
- <MyInput
396
- style={{ textAlign: 'right' }}
397
- loading={isCipher(changeField, 'lineAmountIncludeTax')}
398
- onChange={() => {
399
- setChangeField('lineAmountIncludeTax');
400
- onChangeLineAmountIncludeTax(controller, form, record);
401
- }}
402
- />,
403
- )}
404
- </Form.Item>
405
- );
406
- } else {
407
- return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
408
- }
409
- },
410
- },
411
- {
412
- title: <TitleText required >金额(不含税)</TitleText>,
413
- dataIndex: 'lineAmountExcludeTax',
414
- key: 'lineAmountExcludeTax',
415
- align: 'right',
416
- width: 119,
417
- render: (value: string, record: IGood) => {
418
- if (editGood?.$index === record.$index && !disableds.includes('lineAmountExcludeTax') && model !== 'prefab') {
419
- return (
420
- <Form.Item>
421
- {getFieldDecorator('lineAmountExcludeTax', {
422
- initialValue: editGood.lineAmountExcludeTax,
423
- getValueFromEvent: onNumberValueChange,
424
- rules: [
425
- ...getReplenishRules('lineAmountExcludeTax'),
426
- { required: true, message: '金额不能为空' },
427
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
428
- {
429
- validator: async (_, value: string, callback) => {
430
- if (`${value}`.split('.')[0].length > priceIntegerDigit) {
431
- callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
432
- }
433
- }
434
- },
435
- ],
436
- })(
437
- <MyInput
438
- style={{ textAlign: 'right' }}
439
- loading={isCipher(changeField, 'lineAmountExcludeTax')}
440
- onChange={() => {
441
- setChangeField('lineAmountExcludeTax');
442
- onChangeLineAmountExcludeTax(controller, form, record);
443
- }}
444
- />,
445
- )}
446
- </Form.Item>
447
- );
448
- } else {
449
- return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
450
- }
451
- },
452
- },
453
- {
454
- title: <TitleText required >税率</TitleText>,
455
- dataIndex: 'taxRate',
456
- key: 'taxRate',
457
- align: 'right',
458
- width: 70,
459
- render: (value: string, record: IGood) => {
460
- if (editGood?.$index === record.$index && !disableds.includes('taxRate') && !(model === 'prefab' && calculateType === '3')) {
461
- return (
462
- <Form.Item>
463
- {getFieldDecorator('taxRate', {
464
- initialValue: editGood.taxRate,
465
- rules: [
466
- ...getReplenishRules('taxRate'),
467
- { required: true, message: '请选择税率' },
468
- { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '请选择正确税率' },
469
- ],
470
- })(
471
- <Select
472
- className="kts-invoice-operate-goods-list-table-tax-rate"
473
- // dropdownMenuStyle={{ textAlign: "right" }}
474
- showArrow={false}
475
- style={{ width: '100%' }}
476
- getPopupContainer={() => rootElement || document.body}
477
- onChange={() => {
478
- setChangeField('taxRate');
479
- onChangeTaxRate(controller, form, record);
480
- }}
481
- >
482
- {(record.goodsTaxRateList || taxRateList).map((e, i) => {
483
- return (
484
- <Select.Option key={i} value={e}>
485
- {e}%
486
- </Select.Option>
487
- );
488
- })}
489
- </Select>,
490
- )}
491
- </Form.Item>
492
- );
493
- } else {
494
- return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '免税' : `${value}%`}</span>;
495
- }
496
- },
497
- },
498
- {
499
- title: <TitleText rules={columnsReplenish['taxAmount']?.rules} >税额</TitleText>,
500
- dataIndex: 'taxAmount',
501
- key: 'taxAmount',
502
- align: 'right',
503
- width: 119,
504
- render: (value: string, record: IGood) => {
505
- if (editGood?.$index === record.$index && !disableds.includes('taxAmount')) {
506
- return getFieldDecorator('taxAmount', {
507
- initialValue: editGood.taxAmount,
508
- rules: getReplenishRules('taxAmount'),
509
- })(<MyDiv loading={isCipher(changeField, 'taxAmount')} />);
510
- } else {
511
- return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '***' : parseFloat(value).toFixed(2)}</span>;
512
- }
513
- },
514
- },
515
- // {
516
- // title: '操作',
517
- // key: 'operating',
518
- // align: 'right',
519
- // width: 130,
520
- // fixed: 'right',
521
- // render: (_value: string, record: IGood) => <RowMenu key={record.lineAttribute} goods={record} />,
522
- // },
523
- ]
524
- // 含税不含税
525
- .filter((e) => {
526
- if (isTaxIncluded) {
527
- return !(e.key === 'priceExcludeTax' || e.key === 'lineAmountExcludeTax');
528
- } else {
529
- return !(e.key === 'priceIncludeTax' || e.key === 'lineAmountIncludeTax');
530
- }
531
- })
532
- // 是否启动拖拽
533
- .filter(e => e.key !== 'drag' || isStart)
534
- // 只读
535
- .filter(e => {
536
- if (model === 'readOnly') {
537
- return e.key !== 'operating';
538
- } else {
539
- return true;
540
- }
541
- })
542
- .map((e) => {
543
- return {
544
- ...e,
545
- ellipsis: true,
546
- };
547
- }) as any[];
548
- }, [isTaxIncluded, editGood, controller, taxRateList, changeField, deduction, isMyShow, searchValue, model, columnsReplenish, isStart, calculateType]);
549
-
550
- // React.useEffect(() => {
551
- // clearTimeout(t)
552
- // const t = setTimeout(() => { setChangeField('') }, 1000);
553
- // return () => { clearTimeout(t) }
554
- // }, [changeField]);
555
-
556
- return columns;
557
- };
558
-
559
- /** 字段 */
560
- function isCipher(name?: string, field?: string) {
561
- if (!name || !field) return false;
562
- return name !== field;
563
- }
564
-
565
- class MyInput extends React.Component<InputProps & { loading?: boolean }> {
566
- render() {
567
- if (this.props.loading) {
568
- return (
569
- <Spin size="small">
570
- <Input {...this.props} autoComplete="off" />
571
- </Spin>
572
- )
573
- } else {
574
- return <Input {...this.props} autoComplete="off" />
575
- }
576
- }
577
- }
578
-
579
- class MyDiv extends React.Component<{ value?: any, loading?: boolean }> {
580
-
581
- render() {
582
- if (this.props.loading) {
583
- return (
584
- <Spin size="small">
585
- <span style={{ padding: '0 10px' }}>{this.props.value}</span>
586
- </Spin>
587
- )
588
- } else {
589
- return <span style={{ padding: '0 10px' }}>{this.props.value}</span>
590
- }
591
- }
592
- }
593
-
594
- class MyItemNameDiv extends React.Component<{ valueT?: React.ReactNode, valueF?: React.ReactNode, isMyShow: boolean }> {
595
- render(): React.ReactNode {
596
-
597
- const { isMyShow, valueT, valueF } = this.props;
598
-
599
- if (isMyShow) {
600
- if (valueT) {
601
- return (
602
- <Tooltip title={valueT}>
603
- <span style={{ ...MyItemNameStyle, color: '#0074ff' }}>{valueT}</span>
604
- </Tooltip>
605
- )
606
- } else {
607
- return (
608
- <Tooltip title={valueF}>
609
- <span style={MyItemNameStyle}>{valueF}</span>
610
- </Tooltip>
611
- )
612
- }
613
- } else {
614
- if (valueF) {
615
- return (
616
- <Tooltip title={valueF}>
617
- <span style={MyItemNameStyle}>{valueF}</span>
618
- </Tooltip>
619
- )
620
- } else {
621
- return (
622
- <Tooltip title={valueT} style={MyItemNameStyle}>
623
- <span style={{ ...MyItemNameStyle, color: '#0074ff' }}>{valueT}</span>
624
- </Tooltip>
625
- )
626
- }
627
- }
628
- }
629
- }
630
-
631
- /** 格式搜索结果 */
632
- function formatSearch(value?: string, search?: string) {
633
- if (!value || !search) return value;
634
-
635
- const __html = ucoding(value).split(new RegExp(ucoding(search), 'g')).map(e => dcoding(e)).join(`<span class="kts-invoice-operate-goods-list-table-search-protrude" >${search}</span>`);
636
- return <span dangerouslySetInnerHTML={{ __html }} />
637
- }
638
-
639
- /** 编码 */
640
- function ucoding(v: string): string {
641
- return v.split('').map(e => `U${e.charCodeAt(0)}E`).join('');
642
- }
643
-
644
- /** 解码 */
645
- function dcoding(v: string): string {
646
- return v.split('U').map(e => e ? String.fromCharCode(parseInt(e.replace('E', ''))) : '').join('');
647
- }
648
-
649
- /** 是否免税 */
650
- function isDutyFree(record: IGood): boolean {
651
- return (record.taxFreeType as any) === 1 && record.favouredPolicyName === '免税';
652
- }
653
-
654
- const MyItemNameStyle: any = {
655
- padding: '0px 10px',
656
- whiteSpace: 'nowrap',
657
- overflow: 'hidden',
658
- width: "100%",
659
- display: 'block',
660
- textOverflow: 'ellipsis'
1
+
2
+ import React from 'react';
3
+ import Icon from '@ant-design/icons';
4
+ import { Form } from 'kts-components-antd-x3';
5
+ import { ReactComponent as PlusSvg } from './svg/plus.svg'
6
+ import { AutoComplete, Select, Button, Input, Spin, Tooltip, InputProps } from 'kts-xui';
7
+ import { WrappedFormUtils } from 'kts-components-antd-x3/lib/form/Form';
8
+ import { getItemNameWithShorthand } from '../../../../../tools/itemName';
9
+ import { IGood, LineAttributeType } from '../../../../../InvoiceController';
10
+ import Invoice from '../../../../..';
11
+ import TitleText from './ui/TitleText';
12
+ import ItemNameInput from './ui/ItemNameInput';
13
+ import {
14
+ onChangeQuantity,
15
+ onChangePriceIncludeTax,
16
+ onChangePriceExcludeTax,
17
+ onChangeLineAmountIncludeTax,
18
+ onChangeLineAmountExcludeTax,
19
+ onChangeTaxRate,
20
+ onChangeItemName,
21
+ } from './autoFillFn';
22
+ import Drag from './ui/Drag';
23
+ import { nonScientificNotation } from '../../../../../tools/calculate';
24
+
25
+ export default (form: WrappedFormUtils) => {
26
+ const { getFieldDecorator, getFieldValue } = form;
27
+
28
+ const controller = Invoice.useInvoiceController();
29
+
30
+ const rootElement = controller.useMemo(s => s.rootElement, []);
31
+
32
+ /** 是否含税 */
33
+ const isTaxIncluded = controller.useMemo(e => e.goodsListState.isTaxIncluded, []);
34
+
35
+ /** 组件模式 */
36
+ const model = controller.useMemo(e => e.model, []);
37
+
38
+ /** 计算类型 */
39
+ const calculateType = controller.useMemo(e => e.goodsListState.calculateType, []);
40
+
41
+ /** 是否显示我方 */
42
+ const isMyShow = controller.useMemo(e => e.goodsListState.isMyShow, []);
43
+
44
+ /** 正在编辑的货物 */
45
+ const editGood = controller.useMemo((e) => e.goodsListState.editGood, []);
46
+
47
+ /** 是否启用拖拽 */
48
+ const isStart = controller.useMemo((e) => e.goodsListState.drag.isStart, []);
49
+
50
+ /** 禁用字段 */
51
+ const disableds = controller.useMemo((e) => e.stakeholder.disableds || [], []);
52
+
53
+ /** 搜索条件 */
54
+ const searchValue = controller.useMemo((e) => e.goodsListState.searchValue, []);
55
+
56
+ /** 税率列表 */
57
+ const taxRateList = controller.useMemo((e) => e.goodsListState.taxRateList, []);
58
+
59
+ /** 单位列表 */
60
+ const unitList = controller.useMemo((e) => e.goodsListState.unitList, []);
61
+
62
+ /** 商品表格补充配置 */
63
+ const columnsReplenish = controller.useMemo((e) => e.goodsListState.columnsReplenish, []);
64
+
65
+ /** 扣除额 */
66
+ const deduction = controller.useMemo((e) => e.goodsListState.deduction, []);
67
+
68
+ /** 计算中启动字段 */
69
+ const changeField = controller.useMemo((e) => e.calculatingField, []);
70
+
71
+ /** 计算中启动字段 */
72
+ const setChangeField = React.useCallback((value: string) => controller.run(async s => { s.calculatingField = value }), []);
73
+
74
+ const onNumberValueChange = React.useCallback((e) => {
75
+ const value = e?.target?.value;
76
+ if (value) {
77
+ return value.replace(/[^0-9-\.]/g, '');
78
+ }
79
+ }, [])
80
+
81
+ /** 获取补充校验规则 */
82
+ const getReplenishRules = React.useCallback((id: string) => {
83
+ return columnsReplenish[id] ? columnsReplenish[id].rules || [] : []
84
+ }, [columnsReplenish])
85
+
86
+ /** 金额整数位限制,不传默认9位 */
87
+ const priceIntegerDigit = controller.useMemo((e) => e.priceIntegerDigit || 9, []);
88
+
89
+ /** 表头 */
90
+ const columns = React.useMemo(() => {
91
+ return [
92
+ {
93
+ title: ' ',
94
+ key: 'drag',
95
+ width: 40,
96
+ align: 'center',
97
+ render: (_: any, record: IGood) => <Drag record={record} />
98
+ },
99
+ {
100
+ title: '序号',
101
+ key: 'serialNo',
102
+ dataIndex: 'serialNo',
103
+ width: 50,
104
+ render: (e: number) => <span style={{ padding: '0 10px' }}>{e}</span>,
105
+ },
106
+ {
107
+ title: <TitleText required >项目名称</TitleText>,
108
+ key: 'itemName',
109
+ render: (_: string, record: IGood) => {
110
+ if (editGood?.$index === record.$index && !disableds.includes('itemName') && model !== 'prefab') {
111
+ return (
112
+ <Form.Item>
113
+ <div style={{ display: 'flex' }} >
114
+ {getFieldDecorator('itemName', {
115
+ initialValue: isMyShow ? record.itemNameSelf : record.itemName,
116
+ rules: [
117
+ ...getReplenishRules('itemName'),
118
+ {
119
+ validator: async (_, __, callback) => {
120
+ await controller.wait();
121
+ const value = controller.state.goodsListState.editGood;
122
+ if (!value?.itemName && !value?.itemNameSelf) {
123
+ callback('项目名称不能为空');
124
+ } else {
125
+ return;
126
+ }
127
+ }
128
+ }
129
+ ]
130
+ })(
131
+ <ItemNameInput
132
+ editGood={editGood}
133
+ shorthand={editGood.shorthand}
134
+ suffix={
135
+ <Tooltip title="点击从商品管理中添加商品信息">
136
+ <Button
137
+ type="link"
138
+ style={{ padding: 0, width: 20, fontSize: 20, fill: '#0074ff' }}
139
+ icon={<PlusSvg />}
140
+ onClick={controller.pipeline(async s => { s.goodsListState.importGoods.isVisibleDrawer = true })}
141
+ />
142
+ </Tooltip>
143
+ }
144
+ onChange={() => {
145
+ onChangeItemName(controller, form, record);
146
+ }}
147
+ />
148
+ )}
149
+ </div>
150
+ </Form.Item>
151
+ );
152
+ } else {
153
+ return (
154
+ <span>
155
+ {record.lineAttribute === LineAttributeType.折扣行 ? <span className='goods-list-digtal-discount-tag'>折扣</span> : <></>}
156
+ <MyItemNameDiv
157
+ valueT={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemNameSelf || '' }), searchValue)}
158
+ valueF={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemName || '' }), searchValue)}
159
+ isMyShow={isMyShow}
160
+ />
161
+ </span>
162
+ )
163
+ }
164
+ },
165
+ },
166
+ {
167
+ title: <TitleText rules={columnsReplenish['itemModelName']?.rules} >规格型号</TitleText>,
168
+ key: 'itemModelName',
169
+ width: 119,
170
+ render: (_: string, record: IGood) => {
171
+ if (editGood?.$index === record.$index && !disableds.includes('itemModelName') && model !== 'prefab') {
172
+ return (
173
+ <Form.Item>
174
+ {getFieldDecorator('itemModelName', {
175
+ initialValue: isMyShow ? editGood.itemModelNameSelf : editGood.itemModelName,
176
+ rules: getReplenishRules('itemModelName'),
177
+ })(
178
+ <MyInput
179
+ onChange={async () => {
180
+ await controller.wait()
181
+ const key = isMyShow ? 'itemModelNameSelf' : 'itemModelName';
182
+ const value = {} as any;
183
+ value[key] = form.getFieldsValue().itemModelName;
184
+ controller.setEditGood(value);
185
+ }}
186
+ />,
187
+ )}
188
+ </Form.Item>
189
+ );
190
+ } else {
191
+ return (
192
+ <MyItemNameDiv
193
+ valueT={formatSearch(record.itemModelNameSelf, searchValue)}
194
+ valueF={formatSearch(record.itemModelName, searchValue)}
195
+ isMyShow={isMyShow}
196
+ />
197
+ )
198
+ }
199
+ },
200
+ },
201
+ {
202
+ title: <TitleText rules={columnsReplenish['unit']?.rules} >单位</TitleText>,
203
+ key: 'unit',
204
+ width: 70,
205
+ render: (_: string, record: IGood) => {
206
+ if (editGood?.$index === record.$index && !disableds.includes('unit') && model !== 'prefab') {
207
+ return (
208
+ <Form.Item>
209
+ {getFieldDecorator('unit', {
210
+ initialValue: editGood.unit,
211
+ rules: getReplenishRules('unit'),
212
+ })(
213
+ <AutoComplete
214
+ style={{ width: '100%' }}
215
+ dataSource={unitList}
216
+ getPopupContainer={() => rootElement || document.body}
217
+ onChange={async () => {
218
+ await controller.wait()
219
+ controller.setEditGood({ unit: form.getFieldsValue().unit });
220
+ }}
221
+ />,
222
+ )}
223
+ </Form.Item>
224
+ );
225
+ } else {
226
+ return <span style={{ padding: '0 10px' }}>{record.unit}</span>;
227
+ }
228
+ },
229
+ },
230
+ {
231
+ title: <TitleText rules={columnsReplenish['quantity']?.rules} >数量</TitleText>,
232
+ dataIndex: 'quantity',
233
+ key: 'quantity',
234
+ align: 'right',
235
+ width: 149,
236
+ render: (value: string, record: IGood) => {
237
+ if (editGood?.$index === record.$index && !disableds.includes('quantity') && model !== 'prefab') {
238
+ return (
239
+ <Form.Item>
240
+ {getFieldDecorator('quantity', {
241
+ initialValue: nonScientificNotation(editGood.quantity),
242
+ getValueFromEvent: onNumberValueChange,
243
+ rules: [
244
+ ...getReplenishRules('quantity'),
245
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '数量必须为数字' },
246
+ {
247
+ validator: async (_, value, callback) => {
248
+ await controller.wait();
249
+ const isvalue = !!value || value === 0;
250
+ const isPrice = !!getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') || getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') === 0;
251
+ if (isvalue || isPrice === isvalue) return;
252
+ callback('请输入数量');
253
+ }
254
+ }
255
+ ],
256
+ })(
257
+ <MyInput
258
+ style={{ textAlign: 'right' }}
259
+ maxLength={16}
260
+ loading={isCipher(changeField, "quantity")}
261
+ onChange={async () => {
262
+ setChangeField('quantity');
263
+ await onChangeQuantity(controller, form, record);
264
+ }}
265
+ />,
266
+ )}
267
+ </Form.Item>
268
+ );
269
+ } else {
270
+ return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
271
+ }
272
+ },
273
+ },
274
+ {
275
+ title: <TitleText rules={columnsReplenish['priceIncludeTax']?.rules} >单价(含税)</TitleText>,
276
+ dataIndex: 'priceIncludeTax',
277
+ key: 'priceIncludeTax',
278
+ align: 'right',
279
+ width: 149,
280
+ render: (value: string, record: IGood) => {
281
+ if (editGood?.$index === record.$index && !disableds.includes('priceIncludeTax') && model !== 'prefab') {
282
+ return (
283
+ <Form.Item>
284
+ {getFieldDecorator('priceIncludeTax', {
285
+ initialValue: nonScientificNotation(editGood.priceIncludeTax),
286
+ getValueFromEvent: onNumberValueChange,
287
+ rules: [
288
+ ...getReplenishRules('priceIncludeTax'),
289
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
290
+ {
291
+ validator: async (_, value, callback) => {
292
+ await controller.wait();
293
+ const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
294
+ const isvalue = !!value || value === 0;
295
+ if (isvalue || isQuantity === isvalue) return;
296
+ callback('请输入单价');
297
+ }
298
+ }
299
+ ],
300
+ })(
301
+ <MyInput
302
+ style={{ textAlign: 'right' }}
303
+ maxLength={16}
304
+ loading={isCipher(changeField, 'priceIncludeTax')}
305
+ onChange={() => {
306
+ setChangeField('priceIncludeTax');
307
+ onChangePriceIncludeTax(controller, form, record);
308
+ }}
309
+ />,
310
+ )}
311
+ </Form.Item>
312
+ );
313
+ } else {
314
+ return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
315
+ }
316
+ },
317
+ },
318
+ {
319
+ title: <TitleText rules={columnsReplenish['priceExcludeTax']?.rules} >单价(不含税)</TitleText>,
320
+ dataIndex: 'priceExcludeTax',
321
+ key: 'priceExcludeTax',
322
+ align: 'right',
323
+ width: 149,
324
+ render: (value: string, record: IGood) => {
325
+ if (editGood?.$index === record.$index && !disableds.includes('priceExcludeTax') && model !== 'prefab') {
326
+ return (
327
+ <Form.Item>
328
+ {getFieldDecorator('priceExcludeTax', {
329
+ initialValue: nonScientificNotation(editGood.priceExcludeTax),
330
+ getValueFromEvent: onNumberValueChange,
331
+ rules: [
332
+ ...getReplenishRules('priceExcludeTax'),
333
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
334
+ {
335
+ validator: async (_, value, callback) => {
336
+ await controller.wait();
337
+ const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
338
+ const isvalue = !!value || value === 0;
339
+ if (isvalue || isQuantity === isvalue) return;
340
+ callback('请输入单价');
341
+ }
342
+ }
343
+ ],
344
+ })(
345
+ <MyInput
346
+ style={{ textAlign: 'right' }}
347
+ maxLength={16}
348
+ loading={isCipher(changeField, 'priceExcludeTax')}
349
+ onChange={() => {
350
+ setChangeField('priceExcludeTax');
351
+ onChangePriceExcludeTax(controller, form, record);
352
+ }}
353
+ />,
354
+ )}
355
+ </Form.Item>
356
+ );
357
+ } else {
358
+ return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
359
+ }
360
+ },
361
+ },
362
+ {
363
+ title: <TitleText required >金额(含税)</TitleText>,
364
+ dataIndex: 'lineAmountIncludeTax',
365
+ key: 'lineAmountIncludeTax',
366
+ width: 119,
367
+ align: 'right',
368
+ render: (value: string, record: IGood) => {
369
+ if (editGood?.$index === record.$index && !disableds.includes('lineAmountIncludeTax') && model !== 'prefab') {
370
+ return (
371
+ <Form.Item>
372
+ {getFieldDecorator('lineAmountIncludeTax', {
373
+ initialValue: editGood.lineAmountIncludeTax,
374
+ getValueFromEvent: onNumberValueChange,
375
+ rules: [
376
+ ...getReplenishRules('lineAmountIncludeTax'),
377
+ { required: true, message: '金额不能为空' },
378
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
379
+ {
380
+ validator: async (_, value, callback) => {
381
+ if (`${value}`.split('.')[0].length > priceIntegerDigit) {
382
+ callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
383
+ }
384
+ }
385
+ },
386
+ {
387
+ validator: async (_, value, callback) => {
388
+ if (deduction && parseFloat(value) <= deduction) {
389
+ callback('扣除额不能大于等于价税合计');
390
+ }
391
+ }
392
+ },
393
+ ],
394
+ })(
395
+ <MyInput
396
+ style={{ textAlign: 'right' }}
397
+ loading={isCipher(changeField, 'lineAmountIncludeTax')}
398
+ onChange={() => {
399
+ setChangeField('lineAmountIncludeTax');
400
+ onChangeLineAmountIncludeTax(controller, form, record);
401
+ }}
402
+ />,
403
+ )}
404
+ </Form.Item>
405
+ );
406
+ } else {
407
+ return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
408
+ }
409
+ },
410
+ },
411
+ {
412
+ title: <TitleText required >金额(不含税)</TitleText>,
413
+ dataIndex: 'lineAmountExcludeTax',
414
+ key: 'lineAmountExcludeTax',
415
+ align: 'right',
416
+ width: 119,
417
+ render: (value: string, record: IGood) => {
418
+ if (editGood?.$index === record.$index && !disableds.includes('lineAmountExcludeTax') && model !== 'prefab') {
419
+ return (
420
+ <Form.Item>
421
+ {getFieldDecorator('lineAmountExcludeTax', {
422
+ initialValue: editGood.lineAmountExcludeTax,
423
+ getValueFromEvent: onNumberValueChange,
424
+ rules: [
425
+ ...getReplenishRules('lineAmountExcludeTax'),
426
+ { required: true, message: '金额不能为空' },
427
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
428
+ {
429
+ validator: async (_, value: string, callback) => {
430
+ if (`${value}`.split('.')[0].length > priceIntegerDigit) {
431
+ callback(`金额整数部分不能大于${priceIntegerDigit}位,小数点后最多2位`);
432
+ }
433
+ }
434
+ },
435
+ ],
436
+ })(
437
+ <MyInput
438
+ style={{ textAlign: 'right' }}
439
+ loading={isCipher(changeField, 'lineAmountExcludeTax')}
440
+ onChange={() => {
441
+ setChangeField('lineAmountExcludeTax');
442
+ onChangeLineAmountExcludeTax(controller, form, record);
443
+ }}
444
+ />,
445
+ )}
446
+ </Form.Item>
447
+ );
448
+ } else {
449
+ return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
450
+ }
451
+ },
452
+ },
453
+ {
454
+ title: <TitleText required >税率</TitleText>,
455
+ dataIndex: 'taxRate',
456
+ key: 'taxRate',
457
+ align: 'right',
458
+ width: 70,
459
+ render: (value: string, record: IGood) => {
460
+ if (editGood?.$index === record.$index && !disableds.includes('taxRate') && !(model === 'prefab' && calculateType === '3')) {
461
+ return (
462
+ <Form.Item>
463
+ {getFieldDecorator('taxRate', {
464
+ initialValue: editGood.taxRate,
465
+ rules: [
466
+ ...getReplenishRules('taxRate'),
467
+ { required: true, message: '请选择税率' },
468
+ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '请选择正确税率' },
469
+ ],
470
+ })(
471
+ <Select
472
+ className="kts-invoice-operate-goods-list-table-tax-rate"
473
+ // dropdownMenuStyle={{ textAlign: "right" }}
474
+ showArrow={false}
475
+ style={{ width: '100%' }}
476
+ getPopupContainer={() => rootElement || document.body}
477
+ onChange={() => {
478
+ setChangeField('taxRate');
479
+ onChangeTaxRate(controller, form, record);
480
+ }}
481
+ >
482
+ {(record.goodsTaxRateList || taxRateList).map((e, i) => {
483
+ return (
484
+ <Select.Option key={i} value={e}>
485
+ {e}%
486
+ </Select.Option>
487
+ );
488
+ })}
489
+ </Select>,
490
+ )}
491
+ </Form.Item>
492
+ );
493
+ } else {
494
+ return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '免税' : `${value}%`}</span>;
495
+ }
496
+ },
497
+ },
498
+ {
499
+ title: <TitleText rules={columnsReplenish['taxAmount']?.rules} >税额</TitleText>,
500
+ dataIndex: 'taxAmount',
501
+ key: 'taxAmount',
502
+ align: 'right',
503
+ width: 119,
504
+ render: (value: string, record: IGood) => {
505
+ if (editGood?.$index === record.$index && !disableds.includes('taxAmount')) {
506
+ return getFieldDecorator('taxAmount', {
507
+ initialValue: editGood.taxAmount,
508
+ rules: getReplenishRules('taxAmount'),
509
+ })(<MyDiv loading={isCipher(changeField, 'taxAmount')} />);
510
+ } else {
511
+ return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '***' : parseFloat(value).toFixed(2)}</span>;
512
+ }
513
+ },
514
+ },
515
+ // {
516
+ // title: '操作',
517
+ // key: 'operating',
518
+ // align: 'right',
519
+ // width: 130,
520
+ // fixed: 'right',
521
+ // render: (_value: string, record: IGood) => <RowMenu key={record.lineAttribute} goods={record} />,
522
+ // },
523
+ ]
524
+ // 含税不含税
525
+ .filter((e) => {
526
+ if (isTaxIncluded) {
527
+ return !(e.key === 'priceExcludeTax' || e.key === 'lineAmountExcludeTax');
528
+ } else {
529
+ return !(e.key === 'priceIncludeTax' || e.key === 'lineAmountIncludeTax');
530
+ }
531
+ })
532
+ // 是否启动拖拽
533
+ .filter(e => e.key !== 'drag' || isStart)
534
+ // 只读
535
+ .filter(e => {
536
+ if (model === 'readOnly') {
537
+ return e.key !== 'operating';
538
+ } else {
539
+ return true;
540
+ }
541
+ })
542
+ .map((e) => {
543
+ return {
544
+ ...e,
545
+ ellipsis: true,
546
+ };
547
+ }) as any[];
548
+ }, [isTaxIncluded, editGood, controller, taxRateList, changeField, deduction, isMyShow, searchValue, model, columnsReplenish, isStart, calculateType]);
549
+
550
+ // React.useEffect(() => {
551
+ // clearTimeout(t)
552
+ // const t = setTimeout(() => { setChangeField('') }, 1000);
553
+ // return () => { clearTimeout(t) }
554
+ // }, [changeField]);
555
+
556
+ return columns;
557
+ };
558
+
559
+ /** 字段 */
560
+ function isCipher(name?: string, field?: string) {
561
+ if (!name || !field) return false;
562
+ return name !== field;
563
+ }
564
+
565
+ class MyInput extends React.Component<InputProps & { loading?: boolean }> {
566
+ render() {
567
+ if (this.props.loading) {
568
+ return (
569
+ <Spin size="small">
570
+ <Input {...this.props} autoComplete="off" />
571
+ </Spin>
572
+ )
573
+ } else {
574
+ return <Input {...this.props} autoComplete="off" />
575
+ }
576
+ }
577
+ }
578
+
579
+ class MyDiv extends React.Component<{ value?: any, loading?: boolean }> {
580
+
581
+ render() {
582
+ if (this.props.loading) {
583
+ return (
584
+ <Spin size="small">
585
+ <span style={{ padding: '0 10px' }}>{this.props.value}</span>
586
+ </Spin>
587
+ )
588
+ } else {
589
+ return <span style={{ padding: '0 10px' }}>{this.props.value}</span>
590
+ }
591
+ }
592
+ }
593
+
594
+ class MyItemNameDiv extends React.Component<{ valueT?: React.ReactNode, valueF?: React.ReactNode, isMyShow: boolean }> {
595
+ render(): React.ReactNode {
596
+
597
+ const { isMyShow, valueT, valueF } = this.props;
598
+
599
+ if (isMyShow) {
600
+ if (valueT) {
601
+ return (
602
+ <Tooltip title={valueT}>
603
+ <span style={{ ...MyItemNameStyle, color: '#0074ff' }}>{valueT}</span>
604
+ </Tooltip>
605
+ )
606
+ } else {
607
+ return (
608
+ <Tooltip title={valueF}>
609
+ <span style={MyItemNameStyle}>{valueF}</span>
610
+ </Tooltip>
611
+ )
612
+ }
613
+ } else {
614
+ if (valueF) {
615
+ return (
616
+ <Tooltip title={valueF}>
617
+ <span style={MyItemNameStyle}>{valueF}</span>
618
+ </Tooltip>
619
+ )
620
+ } else {
621
+ return (
622
+ <Tooltip title={valueT} style={MyItemNameStyle}>
623
+ <span style={{ ...MyItemNameStyle, color: '#0074ff' }}>{valueT}</span>
624
+ </Tooltip>
625
+ )
626
+ }
627
+ }
628
+ }
629
+ }
630
+
631
+ /** 格式搜索结果 */
632
+ function formatSearch(value?: string, search?: string) {
633
+ if (!value || !search) return value;
634
+
635
+ const __html = ucoding(value).split(new RegExp(ucoding(search), 'g')).map(e => dcoding(e)).join(`<span class="kts-invoice-operate-goods-list-table-search-protrude" >${search}</span>`);
636
+ return <span dangerouslySetInnerHTML={{ __html }} />
637
+ }
638
+
639
+ /** 编码 */
640
+ function ucoding(v: string): string {
641
+ return v.split('').map(e => `U${e.charCodeAt(0)}E`).join('');
642
+ }
643
+
644
+ /** 解码 */
645
+ function dcoding(v: string): string {
646
+ return v.split('U').map(e => e ? String.fromCharCode(parseInt(e.replace('E', ''))) : '').join('');
647
+ }
648
+
649
+ /** 是否免税 */
650
+ function isDutyFree(record: IGood): boolean {
651
+ return (record.taxFreeType as any) === 1 && record.favouredPolicyName === '免税';
652
+ }
653
+
654
+ const MyItemNameStyle: any = {
655
+ padding: '0px 10px',
656
+ whiteSpace: 'nowrap',
657
+ overflow: 'hidden',
658
+ width: "100%",
659
+ display: 'block',
660
+ textOverflow: 'ellipsis'
661
661
  }