kts-component-invoice-operate 3.2.145 → 3.2.146

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