kts-component-invoice-operate 3.2.154 → 3.2.156

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