Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgram.cs
More file actions
Latest commit
188 lines (159 loc) · 7.53 KB
/
Copy pathProgram.cs
File metadata and controls
188 lines (159 loc) · 7.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// NOTE: In order for the example to work you need to
// override the following configuration:
// contractingWorks:clientId - The identifier of the Contracting Works client you to interact with
// contractingWorks:subjectId - The identifier of the user used to interact with Contracting Works
// contractingWorks:apiKey - The api key used to authentaticate the user above
// Loads the necessary configuration settings from various sources.
// It's recommended to inject these settings using user secrets in Visual Studio.
// The configuration includes client ID, subject ID, API key, and endpoints.
varconfiguration=newConfigurationBuilder()
.AddJsonFile("appsettings.json",true,true)
.AddUserSecrets<MainApp>(optional:true)
.AddEnvironmentVariables()
.Build();
// Extract configuration values for different components.
// These values will be used to set up API connections.
varclientId=configuration.GetValue<string>("contractingWorks:clientId");
varsubjectId=configuration.GetValue<string>("contractingWorks:subjectId");
varapiKey=configuration.GetValue<string>("contractingWorks:apiKey");
varauthenticationHost=configuration.GetValue<string>("contractingWorks:authenticationHost");
vargraphQlHost=configuration.GetValue<string>("contractingWorks:graphQlHost");
varrestHost=configuration.GetValue<string>("contractingWorks:restHost");
// Construct base URLs for different endpoints.
// These URLs will be used as a foundation for constructing API requests.
varauthenticationBaseUrl=$"https://{authenticationHost}/";
vargraphQlBaseUrl=$"https://{graphQlHost}/client/{clientId}/graphql";
varrestBaseUrl=$"https://{restHost}";
// Set up the HttpClient for making API requests.
// Configuration includes automatic decompression and a timeout.
varhttpMessageHandler=newSocketsHttpHandler()
{
AutomaticDecompression=DecompressionMethods.All,
};
usingvarhttpClient=newHttpClient(httpMessageHandler)
{
Timeout=TimeSpan.FromSeconds(170),
};
// Initialize the authentication client to obtain an access token.
varauthClient=newDevincoConnectClient(authenticationBaseUrl,httpClient);
// Call the authentication API to get an access token for interacting with other APIs.
varauthenticationResponse=awaitauthClient.TokenGenerateAccessTokenAsJsonAsync(
new()
{
ApiKey=apiKey,
ClientId=1,
SubjectId=subjectId,
TenantId=clientId,
});
// cwToken is now the token used to interact with the graphQL and restAPI
// Note the token is valid for 1 hour
varcwToken=authenticationResponse.AccessToken;
// Set up dependency injection using the Host class.
varbuilder=Host.CreateApplicationBuilder(args);
// Add the HttpClient as a singleton service for efficient HTTP requests.
builder.Services.AddSingleton(httpClient);
// Set up the CW GQL Client (generated by Strawberry Shake) using dependency injection.
builder.Services
.AddCWGQLClient()
.ConfigureHttpClient(client =>
{
client.BaseAddress=new(graphQlBaseUrl);
client.DefaultRequestHeaders.Authorization=new("Bearer",cwToken);
});
// Add the MainApp class as a singleton service.
builder.Services.AddSingleton<MainApp>();
// Build the host using the configured services.
usingvarhost=builder.Build();
varmainApp=host.Services.GetRequiredService<MainApp>();
// Run main app
awaitmainApp.Run(cwToken,clientId??"<Unknown>",restBaseUrl);
// The MainApp class encapsulates the core functionality of the example.
classMainApp
{
readonlyILogger<MainApp>_logger;
readonlyCWGQLClient_graphQl;
readonlyHttpClient_httpClient;
// Constructor injects necessary services for GraphQL and HTTP interactions.
publicMainApp(
ILogger<MainApp>logger,
CWGQLClientgraphQl,
HttpClienthttpClient)
{
_logger=logger;
_graphQl=graphQl;
_httpClient=httpClient;
}
// The Run method performs the main functionality of the application.
// It retrieves payment terms and customers using GraphQL,
// updates payment terms for customers using REST API.
publicasyncTaskRun(stringcwToken,stringclientId,stringrestBaseUrl)
{
// Give us the first 10 payment terms that are not deactivated (soft deleted)
varpaymentTermResponse=await_graphQl.GetPaymentTerm.ExecuteAsync(
top:10,
filter:"sys_Deactivated = false");
// Throws if there are any errors.
paymentTermResponse.EnsureNoErrors();
// Find the first payment term. Note that values might be null
// so using ?. to avoid null reference exceptions is recommended
varpaymentTerm=paymentTermResponse.Data?.PaymentTerms?.Items?.FirstOrDefault();
if(paymentTermisnull)
{
_logger.LogWarning($"No payment terms found :(");
return;
}
varpaymentTermDescription=paymentTerm?.Description??"No description";
_logger.LogInformation($"Found payment term: {paymentTermDescription}");
// Give us the first 10 customers that are not deactivated (soft deleted)
varcustomerResponse=await_graphQl.GetCustomer.ExecuteAsync(
top:10,
filter:"sys_Deactivated = false");
// Throws if there are any errors.
customerResponse.EnsureNoErrors();
// Find the customers payload. Note that values might be null
// so using ?. to avoid null reference exceptions is recommended
varcustomers=customerResponse?.Data?.Customers?.Items;
if(customersisnull)
{
_logger.LogWarning($"No customers found :(");
return;
}
// Print customer information using a loop.
foreach(varcustomerincustomers)
{
_logger.LogInformation($"Customer - {customer.CustomerNumber} - {customer.Name} - {customer.PaymentTerm?.Description??"No payment term"}");
}
_logger.LogInformation($"Do you want me to change the payment term of all the customers above to {paymentTermDescription}\nType YES if you do");
// Prompt user for confirmation before making changes.
varresponse=Console.ReadLine()??"";
if(response!="YES")
{
_logger.LogInformation($"Ok I won't do anything then, bye!");
return;
}
_logger.LogInformation($"Ok, updating payment terms of all customers");
// Prepare an upsert request for changing payment terms of customers.
varchangedCustomers=newList<CustomerDto>();
foreach(varcustomerincustomers)
{
changedCustomers.Add(new()
{
// CustomerId is the primary key of the Customer table
// By setting this to a non-null value, it indicates that we want to
// update an existing customer. If it is null, it signifies creating a new customer.
CustomerId=customer.CustomerId,
// Set the payment term foreign key of the customer to
// the payment term id
PaymentTermId=paymentTerm!.PaymentTermId
});
}
// Initialize a REST client and perform the upsert operation.
varrestClient=newContractingWorksClient(restBaseUrl,_httpClient)
{
CwToken=cwToken,
Logger=_logger
};
varrepsonse=awaitrestClient.V3ClientCustomerUpsertAsync(clientId,null,0,changedCustomers);
_logger.LogInformation($"So, the customers are now updated");
}
}