kts-component-invoice-operate 3.2.13 → 3.2.15

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