1
- import { useState } from 'react' ;
2
- import { useDispatch , useSelector } from 'react-redux' ;
3
- import { Container , Row , Form , Alert } from 'react-bootstrap' ;
4
- import { t } from '../utils' ;
5
- import { saveClient } from '../../actions/index' ;
6
- import { defaultClientProperties } from './models/ClientConfig' ;
7
- import { getNewClient } from './models/getNewClient' ;
8
- import { ClientModel } from './models/ClientModels' ;
9
- import { ConfacState } from '../../reducers/app-state' ;
10
- import { ConfigModel } from '../config/models/ConfigModel' ;
11
- import { StickyFooter } from '../controls/other/StickyFooter' ;
12
- import { NewClient } from './NewClient' ;
13
- import { ArrayInput } from '../controls/form-controls/inputs/ArrayInput' ;
14
- import { BusyButton } from '../controls/form-controls/BusyButton' ;
15
- import { useDocumentTitle } from '../hooks/useDocumentTitle' ;
16
- import { ClientAttachmentsForm } from './controls/ClientAttachmentsForm' ;
17
- import { Audit } from '../admin/audit/Audit' ;
18
- import { Claim } from '../users/models/UserModel' ;
19
- import { useParams } from 'react-router-dom' ;
20
- import { InvoiceLine } from '../invoice/models/InvoiceLineModels' ;
1
+ import { useDispatch } from 'react-redux' ;
2
+ import { useParams } from 'react-router-dom' ;
3
+ import { Container , Row , Form , Alert } from 'react-bootstrap' ;
4
+ import { t } from '../utils' ;
5
+ import { saveClient } from '../../actions/index' ;
6
+ import { defaultClientProperties } from './models/ClientConfig' ;
7
+ import { ClientModel } from './models/ClientModels' ;
8
+ import { StickyFooter } from '../controls/other/StickyFooter' ;
9
+ import { NewClient } from './NewClient' ;
10
+ import { ArrayInput } from '../controls/form-controls/inputs/ArrayInput' ;
11
+ import { BusyButton } from '../controls/form-controls/BusyButton' ;
12
+ import { useDocumentTitle } from '../hooks/useDocumentTitle' ;
13
+ import { ClientAttachmentsForm } from './controls/ClientAttachmentsForm' ;
14
+ import { Audit } from '../admin/audit/Audit' ;
15
+ import { Claim } from '../users/models/UserModel' ;
21
16
import useEntityChangedToast from '../hooks/useEntityChangedToast' ;
22
17
import { NotesWithCommentsModalButton } from '../controls/form-controls/button/NotesWithCommentsModalButton' ;
23
-
24
-
25
- /** Different spellings of "Belgium": TODO: this should just be 'BE' now */
26
- export const belgiums = [ 'België' , 'Belgium' , 'Belgie' , 'BE' ] ;
27
-
28
-
29
- function getClient ( client : ClientModel | undefined , config : ConfigModel ) {
30
- if ( client ) {
31
- return JSON . parse ( JSON . stringify ( client ) ) ;
32
- }
33
- return getNewClient ( config ) ;
34
- }
18
+ import { useClientState } from './client-helpers' ;
35
19
36
20
37
21
const EditClient = ( ) => {
38
22
const params = useParams ( ) ;
39
- const config = useSelector ( ( state : ConfacState ) => state . config ) ;
40
- const storeClient = useSelector ( ( state : ConfacState ) => state . clients . find ( x => x . slug === params . id ) ) ;
41
- const initClient = getClient ( storeClient , config ) ;
42
- const [ client , setClient ] = useState < ClientModel > ( initClient ) ;
43
- const clientWithSameKbo = useSelector ( ( state : ConfacState ) => state . clients . filter ( x => x . btw === client . btw ) . find ( x => x . slug !== params . id ) ) ;
44
-
45
- useEntityChangedToast ( client . _id ) ;
46
-
47
23
const dispatch = useDispatch ( ) ;
48
- // useEffect(() => window.scrollTo(0, 0)); // TODO: each keystroke made it scroll to top :(
49
- useDocumentTitle ( 'clientEdit' , { name : client . name } ) ;
50
-
51
-
52
- if ( storeClient && ! client . _id ) {
53
- setClient ( storeClient ) ;
54
- }
55
-
56
- const clientAlreadyExists = ! ! clientWithSameKbo && client . btw && client . btw !== t ( 'taxRequest' ) ;
57
- const isClientDisabled = ( client : ClientModel ) : boolean => {
58
- if ( clientAlreadyExists || client . name . length === 0 ) {
59
- return true ;
60
- }
61
- if ( client . slug && client . slug . length === 0 ) {
62
- // slug can only be filled in for an existing invoice
63
- // (it's set on the backend create)
64
- return true ;
65
- }
66
- if ( ! client . btw )
67
- return true ;
68
-
69
- return false ;
70
- }
24
+ const { client, setClient, clientAlreadyExists, canSaveClient} = useClientState ( params . id ) ;
71
25
26
+ useEntityChangedToast ( client ?. _id ) ;
27
+ useDocumentTitle ( 'clientEdit' , { name : client ?. name || '' } ) ;
72
28
73
29
if ( ! client ) {
74
- return null ;
75
- }
76
-
77
- const setClientIntercept = ( newClient : ClientModel ) : void => {
78
- if ( newClient . country && client . country !== newClient . country && ! client . defaultInvoiceLines . length && ! belgiums . includes ( newClient . country ) ) {
79
- let btwRemark : string ;
80
- switch ( newClient . country ) {
81
- case 'UK' :
82
- btwRemark = 'Belgian VAT not applicable - Article 44 EU Directive 2006/112/EC' ;
83
- break ;
84
- default :
85
- btwRemark = 'Vrijgesteld van BTW overeenkomstig art. 39bis W. BTW' ;
86
- }
87
-
88
- const invoiceLines = config . defaultInvoiceLines . map ( x => ( { ...x , tax : 0 } ) ) ;
89
- invoiceLines . push ( { type : 'section' , desc : btwRemark , sort : invoiceLines . length } as InvoiceLine ) ;
90
- newClient . defaultInvoiceLines = invoiceLines ;
91
- }
92
- setClient ( newClient ) ;
93
- } ;
94
-
95
- if ( ! client . btw && ! initClient . _id ) {
96
30
return (
97
- < NewClient
98
- client = { client }
99
- onChange = { ( value : ClientModel ) => setClientIntercept ( { ...client , ...value } ) }
100
- />
31
+ < NewClient onChange = { ( value : ClientModel ) => setClient ( value ) } />
101
32
) ;
102
33
}
103
34
@@ -106,7 +37,7 @@ const EditClient = () => {
106
37
< Form >
107
38
< Row >
108
39
< h1 style = { { marginBottom : 10 } } >
109
- { client . name || ( initClient . _id ? '' : t ( 'client.createNew' ) ) }
40
+ { client . name || ( client . _id ? '' : t ( 'client.createNew' ) ) }
110
41
< NotesWithCommentsModalButton
111
42
claim = { Claim . ManageClients }
112
43
value = { { comments : client . comments || [ ] } }
@@ -115,27 +46,29 @@ const EditClient = () => {
115
46
style = { { marginLeft : 6 , marginBottom : 6 } }
116
47
showNote = { false }
117
48
/>
118
- < Audit model = { storeClient } modelType = "client" />
49
+ < Audit model = { client } modelType = "client" />
119
50
</ h1 >
120
- { clientAlreadyExists && < Alert variant = "danger" > { t ( 'client.alreadyExists' , { btw : client . btw } ) } </ Alert > }
51
+ { clientAlreadyExists && (
52
+ < Alert variant = "danger" > { t ( 'client.alreadyExists' , { btw : client . btw } ) } </ Alert >
53
+ ) }
121
54
</ Row >
122
55
< Row >
123
56
< ArrayInput
124
57
config = { defaultClientProperties }
125
58
model = { client }
126
- onChange = { value => setClientIntercept ( { ...client , ...value } ) }
59
+ onChange = { value => setClient ( { ...client , ...value } ) }
127
60
tPrefix = "client."
128
61
/>
129
62
</ Row >
130
63
131
- < ClientAttachmentsForm model = { initClient } />
64
+ < ClientAttachmentsForm model = { client } />
132
65
133
66
</ Form >
134
67
< StickyFooter claim = { Claim . ManageClients } >
135
68
< BusyButton
136
69
onClick = { ( ) => dispatch ( saveClient ( client ) as any ) }
137
70
className = "tst-save-client"
138
- disabled = { isClientDisabled ( client ) }
71
+ disabled = { ! canSaveClient }
139
72
>
140
73
{ t ( 'save' ) }
141
74
</ BusyButton >
0 commit comments