11using System ;
22using System . Collections . Generic ;
3+ using System . Diagnostics ;
34using System . Linq ;
45using System . Threading . Tasks ;
56using DocuSign . eSign . Model ;
67using Docusign . IAM . SDK . Models . Components ;
8+ using Docusign . IAM . SDK . Models . Errors ;
79using DocuSign . Workspaces . Domain . CarePlans . Model ;
810using DocuSign . Workspaces . Infrastructure . Services . Interfaces ;
11+ using Microsoft . Extensions . Logging ;
912
1013namespace DocuSign . Workspaces . Domain . CarePlans ;
1114
12- public class CarePlansService ( IDocuSignApiProvider docuSignApiProvider , IAppConfiguration appConfiguration , IAccountRepository accountRepository )
15+ public class CarePlansService (
16+ IDocuSignApiProvider docuSignApiProvider ,
17+ IAppConfiguration appConfiguration ,
18+ IAccountRepository accountRepository ,
19+ ILogger < CarePlansService > logger )
1320 : ICarePlansService
1421{
1522 public async Task < List < PhysicianModel > > GetPhysician ( )
1623 {
1724 var physiciansWorkspaces = new List < PhysicianModel > ( ) ;
1825
1926 List < string > physicians = [ "Dr. Max Payne" , "Dr. Angela Kerr" , "Dr. Luke Heer" ] ;
20- var workspaces = await docuSignApiProvider . Workspace2 . GetWorkspacesAsync ( accountRepository . AccountId ) ;
27+ var workspaces = await ExecuteDocuSignCallAsync (
28+ "Workspace2.GetWorkspacesAsync" ,
29+ new { accountRepository . AccountId } ,
30+ ( ) => docuSignApiProvider . Workspace2 . GetWorkspacesAsync ( accountRepository . AccountId ) ) ;
31+
2132 if ( workspaces . Workspaces != null || workspaces . Workspaces ? . Count != 0 )
2233 {
2334 var createdPhysician = workspaces . Workspaces
@@ -42,7 +53,10 @@ public async Task<List<PhysicianModel>> GetPhysician()
4253 {
4354 Name = physician + " Workspace"
4455 } ;
45- var workspace = await docuSignApiProvider . Workspace2 . CreateWorkspaceAsync ( accountRepository . AccountId , workspaceBody ) ;
56+ var workspace = await ExecuteDocuSignCallAsync (
57+ "Workspace2.CreateWorkspaceAsync" ,
58+ new { accountRepository . AccountId , WorkspaceName = workspaceBody . Name } ,
59+ ( ) => docuSignApiProvider . Workspace2 . CreateWorkspaceAsync ( accountRepository . AccountId , workspaceBody ) ) ;
4660
4761 physiciansWorkspaces . Add ( new PhysicianModel
4862 {
@@ -58,22 +72,7 @@ public async Task<List<CareDocumentsModel>> SubmitToPhysician(SubmitToPhysicians
5872 {
5973 const string sentStatus = "sent" ;
6074 var documents = new List < CareDocumentsModel > ( ) ;
61-
62- var userForCreate = new WorkspaceUserForCreate
63- {
64- Email = model . Email ,
65- FirstName = model . Physician . Name ,
66- LastName = ""
67- } ;
68- try
69- {
70- await docuSignApiProvider . WorkspaceUsers . AddWorkspaceUserAsync ( accountRepository . AccountId , model . Physician . WorkspaceId , userForCreate ) ;
71- }
72- catch ( Exception e )
73- {
74- Console . WriteLine ( e ) ;
75- throw ;
76- }
75+ //await EnsureWorkspaceUserAsync(model);
7776
7877 foreach ( var document in model . Documents )
7978 {
@@ -84,10 +83,18 @@ public async Task<List<CareDocumentsModel>> SubmitToPhysician(SubmitToPhysicians
8483 EnvelopeName = document . Name
8584 } ;
8685
87- var envelopeResponse = await docuSignApiProvider . Workspace2 . CreateWorkspaceEnvelopeAsync (
88- accountRepository . AccountId ,
89- model . Physician . WorkspaceId ,
90- workspaceEnvelopeForCreate ) ;
86+ var envelopeResponse = await ExecuteDocuSignCallAsync (
87+ "Workspace2.CreateWorkspaceEnvelopeAsync" ,
88+ new
89+ {
90+ accountRepository . AccountId ,
91+ model . Physician . WorkspaceId ,
92+ DocumentName = document . Name
93+ } ,
94+ ( ) => docuSignApiProvider . Workspace2 . CreateWorkspaceEnvelopeAsync (
95+ accountRepository . AccountId ,
96+ model . Physician . WorkspaceId ,
97+ workspaceEnvelopeForCreate ) ) ;
9198
9299 var eventNotificationUrl = $ "{ appConfiguration . DocuSign . EventNotificationBaseUrl } /api/callback/event";
93100
@@ -135,12 +142,33 @@ public async Task<List<CareDocumentsModel>> SubmitToPhysician(SubmitToPhysicians
135142 Signers = [ signer1 ]
136143 } ;
137144
138- await docuSignApiProvider . EnvelopApi . UpdateRecipientsAsync ( accountRepository . AccountId , envelopeResponse . EnvelopeId , recipients ) ;
145+ await ExecuteDocuSignCallAsync (
146+ "EnvelopApi.UpdateRecipientsAsync" ,
147+ new
148+ {
149+ accountRepository . AccountId ,
150+ envelopeResponse . EnvelopeId ,
151+ RecipientEmail = model . Email
152+ } ,
153+ ( ) => docuSignApiProvider . EnvelopApi . UpdateRecipientsAsync ( accountRepository . AccountId , envelopeResponse . EnvelopeId , recipients ) ) ;
139154
140- await docuSignApiProvider . EnvelopApi . UpdateDocumentsAsync ( accountRepository . AccountId , envelopeResponse . EnvelopeId , env ) ;
155+ await ExecuteDocuSignCallAsync (
156+ "EnvelopApi.UpdateDocumentsAsync" ,
157+ new
158+ {
159+ accountRepository . AccountId ,
160+ envelopeResponse . EnvelopeId ,
161+ DocumentName = document . Name
162+ } ,
163+ ( ) => docuSignApiProvider . EnvelopApi . UpdateDocumentsAsync ( accountRepository . AccountId , envelopeResponse . EnvelopeId , env ) ) ;
141164
142- await docuSignApiProvider . EnvelopApi . UpdateAsync ( accountRepository . AccountId , envelopeResponse . EnvelopeId ,
143- new Envelope ( Status : sentStatus ) ) ;
165+ await ExecuteDocuSignCallAsync (
166+ "EnvelopApi.UpdateAsync" ,
167+ new { accountRepository . AccountId , envelopeResponse . EnvelopeId , Status = sentStatus } ,
168+ ( ) => docuSignApiProvider . EnvelopApi . UpdateAsync (
169+ accountRepository . AccountId ,
170+ envelopeResponse . EnvelopeId ,
171+ new Envelope ( Status : sentStatus ) ) ) ;
144172
145173 documents . Add ( new CareDocumentsModel ( document . Name , document . IsForSignature , sentStatus ) ) ;
146174 }
@@ -154,12 +182,118 @@ await docuSignApiProvider.EnvelopApi.UpdateAsync(accountRepository.AccountId, en
154182 FileName = document . Name
155183 }
156184 } ;
157- await docuSignApiProvider . WorkspaceDocuments . AddWorkspaceDocumentAsync ( accountRepository . AccountId , model . Physician . WorkspaceId , documentRequest ) ;
185+ await ExecuteDocuSignCallAsync (
186+ "WorkspaceDocuments.AddWorkspaceDocumentAsync" ,
187+ new
188+ {
189+ accountRepository . AccountId ,
190+ model . Physician . WorkspaceId ,
191+ DocumentName = document . Name ,
192+ RequiresSignature = document . IsForSignature
193+ } ,
194+ ( ) => docuSignApiProvider . WorkspaceDocuments . AddWorkspaceDocumentAsync (
195+ accountRepository . AccountId ,
196+ model . Physician . WorkspaceId ,
197+ documentRequest ) ) ;
158198
159199 documents . Add ( new CareDocumentsModel ( document . Name , document . IsForSignature , string . Empty ) ) ;
160200 }
161201 }
162202
163203 return documents ;
164204 }
205+
206+ private async Task EnsureWorkspaceUserAsync ( SubmitToPhysiciansModel model )
207+ {
208+ if ( string . IsNullOrWhiteSpace ( model . Email ) || string . IsNullOrWhiteSpace ( model . Physician ? . WorkspaceId ) )
209+ {
210+ return ;
211+ }
212+
213+ if ( await WorkspaceContainsUserAsync ( model . Physician . WorkspaceId , model . Email ) )
214+ {
215+ return ;
216+ }
217+
218+ var userForCreate = new WorkspaceUserForCreate
219+ {
220+ Email = model . Email ,
221+ FirstName = model . Physician . Name ,
222+ LastName = ""
223+ } ;
224+
225+ try
226+ {
227+ await ExecuteDocuSignCallAsync (
228+ "WorkspaceUsers.AddWorkspaceUserAsync" ,
229+ new
230+ {
231+ accountRepository . AccountId ,
232+ model . Physician . WorkspaceId ,
233+ model . Email
234+ } ,
235+ ( ) => docuSignApiProvider . WorkspaceUsers . AddWorkspaceUserAsync (
236+ accountRepository . AccountId ,
237+ model . Physician . WorkspaceId ,
238+ userForCreate ) ) ;
239+ }
240+ catch ( APIException )
241+ {
242+ if ( ! await WorkspaceContainsUserAsync ( model . Physician . WorkspaceId , model . Email ) )
243+ {
244+ throw ;
245+ }
246+ }
247+ }
248+
249+ private async Task < bool > WorkspaceContainsUserAsync ( string workspaceId , string email )
250+ {
251+ var request = new Docusign . IAM . SDK . Models . Requests . GetWorkspaceUsersRequest
252+ {
253+ AccountId = accountRepository . AccountId ,
254+ WorkspaceId = workspaceId
255+ } ;
256+ var users = await ExecuteDocuSignCallAsync (
257+ "WorkspaceUsers.GetWorkspaceUsersAsync" ,
258+ new
259+ {
260+ accountRepository . AccountId ,
261+ WorkspaceId = workspaceId ,
262+ LookupEmail = email
263+ } ,
264+ ( ) => docuSignApiProvider . WorkspaceUsers . GetWorkspaceUsersAsync ( request ) ) ;
265+
266+ return users . Users ? . Any ( u =>
267+ ! string . IsNullOrWhiteSpace ( u . Email ) &&
268+ string . Equals ( u . Email , email , StringComparison . OrdinalIgnoreCase ) ) == true ;
269+ }
270+
271+ private async Task ExecuteDocuSignCallAsync ( string operation , object context , Func < Task > operationCall )
272+ {
273+ await ExecuteDocuSignCallAsync < object > ( operation , context , async ( ) =>
274+ {
275+ await operationCall ( ) ;
276+ return null ;
277+ } ) ;
278+ }
279+
280+ private async Task < T > ExecuteDocuSignCallAsync < T > ( string operation , object context , Func < Task < T > > operationCall )
281+ {
282+ var stopwatch = Stopwatch . StartNew ( ) ;
283+ logger . LogInformation ( "DocuSign request started: {Operation}. Context: {@Context}" , operation , context ) ;
284+
285+ try
286+ {
287+ var result = await operationCall ( ) ;
288+ logger . LogInformation ( "DocuSign request succeeded: {Operation}. DurationMs: {DurationMs}. Context: {@Context}" ,
289+ operation , stopwatch . ElapsedMilliseconds , context ) ;
290+ return result ;
291+ }
292+ catch ( Exception ex )
293+ {
294+ logger . LogError ( ex , "DocuSign request failed: {Operation}. DurationMs: {DurationMs}. Context: {@Context}" ,
295+ operation , stopwatch . ElapsedMilliseconds , context ) ;
296+ throw ;
297+ }
298+ }
165299}
0 commit comments