Skip to content

Commit 14f6150

Browse files
committed
Adding the new helper method for setting google sheet information for time planning.
1 parent 602b445 commit 14f6150

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Google.Apis.Auth.OAuth2;
6+
using Google.Apis.Services;
7+
using Google.Apis.Sheets.v4;
8+
using Google.Apis.Sheets.v4.Data;
9+
using Microsoft.EntityFrameworkCore;
10+
using Microsoft.Extensions.Logging;
11+
using Microting.eForm.Infrastructure.Constants;
12+
using Microting.eFormApi.BasePn.Abstractions;
13+
using Microting.eFormApi.BasePn.Infrastructure.Helpers.PluginDbOptions;
14+
using Microting.TimePlanningBase.Infrastructure.Data;
15+
using TimePlanning.Pn.Infrastructure.Models.Settings;
16+
17+
namespace TimePlanning.Pn.Infrastructure.Helpers;
18+
19+
public class GoogleSheetHelper
20+
{
21+
public static async Task PushToGoogleSheet(IPluginDbOptions<TimePlanningBaseSettings> options,
22+
IEFormCoreService coreHelper, TimePlanningPnDbContext dbContext, ILogger logger)
23+
{
24+
var privateKeyId = Environment.GetEnvironmentVariable("PRIVATE_KEY_ID");
25+
if (string.IsNullOrEmpty(privateKeyId))
26+
{
27+
return;
28+
}
29+
30+
var applicationName = "Google Sheets API Integration";
31+
var spreadsheetId = options.Value.GoogleSheetId;
32+
var sheetName = "PlanTimer";
33+
34+
var core = await coreHelper.GetCore();
35+
await using var sdkDbContext = core.DbContextHelper.GetDbContext();
36+
37+
var privateKey = Environment.GetEnvironmentVariable("PRIVATE_KEY"); // Replace with your private key
38+
var clientEmail = Environment.GetEnvironmentVariable("CLIENT_EMAIL"); // Replace with your client email
39+
var projectId = Environment.GetEnvironmentVariable("PROJECT_ID"); // Replace with your project ID
40+
var clientId = Environment.GetEnvironmentVariable("CLIENT_ID"); // Replace with your client ID
41+
42+
// Construct the JSON for the service account credentials
43+
string serviceAccountJson = $@"
44+
{{
45+
""type"": ""service_account"",
46+
""project_id"": ""{projectId}"",
47+
""private_key_id"": ""{privateKeyId}"",
48+
""private_key"": ""{privateKey}"",
49+
""client_email"": ""{clientEmail}"",
50+
""client_id"": ""{clientId}"",
51+
""auth_uri"": ""https://accounts.google.com/o/oauth2/auth"",
52+
""token_uri"": ""https://oauth2.googleapis.com/token"",
53+
""auth_provider_x509_cert_url"": ""https://www.googleapis.com/oauth2/v1/certs"",
54+
""client_x509_cert_url"": ""https://www.googleapis.com/robot/v1/metadata/x509/{clientEmail}""
55+
}}";
56+
57+
// Authenticate using the dynamically constructed JSON
58+
var credential = GoogleCredential.FromJson(serviceAccountJson)
59+
.CreateScoped(SheetsService.Scope.Spreadsheets);
60+
61+
var service = new SheetsService(new BaseClientService.Initializer
62+
{
63+
HttpClientInitializer = credential,
64+
ApplicationName = applicationName
65+
});
66+
67+
try
68+
{
69+
var headerRequest = service.Spreadsheets.Values.Get(spreadsheetId, $"{sheetName}!A1:1");
70+
var headerResponse = await headerRequest.ExecuteAsync();
71+
var existingHeaders = headerResponse.Values?.FirstOrDefault() ?? new List<object>();
72+
73+
var assignedSites = await dbContext.AssignedSites
74+
.Where(x => x.WorkflowState != Constants.WorkflowStates.Removed)
75+
.Select(x => x.SiteId)
76+
.Distinct()
77+
.ToListAsync();
78+
79+
var siteNames = await sdkDbContext.Sites
80+
.Where(x => assignedSites.Contains(x.MicrotingUid!.Value))
81+
.OrderBy(x => x.Name)
82+
.Select(x => x.Name)
83+
.ToListAsync();
84+
85+
var newHeaders = existingHeaders.Cast<string>().ToList();
86+
foreach (var siteName in siteNames)
87+
{
88+
var timerHeader = $"{siteName} - timer";
89+
var textHeader = $"{siteName} - tekst";
90+
if (!newHeaders.Contains(timerHeader))
91+
{
92+
newHeaders.Add(timerHeader);
93+
}
94+
95+
if (!newHeaders.Contains(textHeader))
96+
{
97+
newHeaders.Add(textHeader);
98+
}
99+
}
100+
101+
if (!existingHeaders.Cast<string>().SequenceEqual(newHeaders))
102+
{
103+
var updateRequest = new ValueRange
104+
{
105+
Values = new List<IList<object>> { newHeaders.Cast<object>().ToList() }
106+
};
107+
108+
var columnLetter = GetColumnLetter(newHeaders.Count);
109+
updateRequest = new ValueRange
110+
{
111+
Values = new List<IList<object>> { newHeaders.Cast<object>().ToList() }
112+
};
113+
var updateHeaderRequest =
114+
service.Spreadsheets.Values.Update(updateRequest, spreadsheetId, $"{sheetName}!A1:{columnLetter}1");
115+
updateHeaderRequest.ValueInputOption =
116+
SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;
117+
await updateHeaderRequest.ExecuteAsync();
118+
119+
logger.LogInformation("Headers updated successfully.");
120+
}
121+
122+
AutoAdjustColumnWidths(service, spreadsheetId, sheetName, logger);
123+
124+
SetAlternatingColumnColors(service, spreadsheetId, 0, newHeaders.Count, logger);
125+
126+
logger.LogInformation("Headers are already up-to-date.");
127+
}
128+
catch (Exception ex)
129+
{
130+
logger.LogError($"An error occurred: {ex.Message}");
131+
}
132+
}
133+
134+
static void AutoAdjustColumnWidths(SheetsService service, string spreadsheetId, string sheetName, ILogger logger)
135+
{
136+
try
137+
{
138+
var sheet = service.Spreadsheets.Get(spreadsheetId).Execute().Sheets
139+
.FirstOrDefault(s => s.Properties.Title == sheetName);
140+
if (sheet == null) throw new Exception($"Sheet '{sheetName}' not found.");
141+
142+
var sheetId = sheet.Properties.SheetId;
143+
144+
var autoResizeRequest = new Request
145+
{
146+
AutoResizeDimensions = new AutoResizeDimensionsRequest
147+
{
148+
Dimensions = new DimensionRange
149+
{
150+
SheetId = sheetId,
151+
Dimension = "COLUMNS",
152+
StartIndex = 0, // Start from the first column
153+
EndIndex = sheet.Properties.GridProperties.ColumnCount // Auto-adjust all columns
154+
}
155+
}
156+
};
157+
158+
var batchRequest = new BatchUpdateSpreadsheetRequest
159+
{
160+
Requests = new List<Request> { autoResizeRequest }
161+
};
162+
163+
service.Spreadsheets.BatchUpdate(batchRequest, spreadsheetId).Execute();
164+
165+
logger.LogInformation("Column widths auto-adjusted successfully.");
166+
}
167+
catch (Exception ex)
168+
{
169+
logger.LogError($"An error occurred while auto-adjusting column widths: {ex.Message}");
170+
}
171+
}
172+
173+
private static string GetColumnLetter(int columnIndex)
174+
{
175+
string columnLetter = "";
176+
while (columnIndex > 0)
177+
{
178+
int modulo = (columnIndex - 1) % 26;
179+
columnLetter = Convert.ToChar(65 + modulo) + columnLetter;
180+
columnIndex = (columnIndex - modulo) / 26;
181+
}
182+
183+
return columnLetter;
184+
}
185+
186+
static void SetAlternatingColumnColors(SheetsService service, string spreadsheetId, int sheetId, int columnCount, ILogger logger)
187+
{
188+
var requests = new List<Request>();
189+
190+
for (int i = 3; i < columnCount; i++) // Start from column D (index 3)
191+
{
192+
var color = (i % 2 == 0)
193+
? new Color { Red = 1, Green = 1, Blue = 1 }
194+
: new Color { Red = 0.9f, Green = 0.9f, Blue = 0.9f };
195+
196+
var updateCellsRequest = new Request
197+
{
198+
RepeatCell = new RepeatCellRequest
199+
{
200+
Range = new GridRange
201+
{
202+
SheetId = sheetId,
203+
StartColumnIndex = i,
204+
EndColumnIndex = i + 1
205+
},
206+
Cell = new CellData
207+
{
208+
UserEnteredFormat = new CellFormat
209+
{
210+
BackgroundColor = color
211+
}
212+
},
213+
Fields = "userEnteredFormat.backgroundColor"
214+
}
215+
};
216+
217+
requests.Add(updateCellsRequest);
218+
}
219+
220+
var batchUpdateRequest = new BatchUpdateSpreadsheetRequest
221+
{
222+
Requests = requests
223+
};
224+
225+
service.Spreadsheets.BatchUpdate(batchUpdateRequest, spreadsheetId).Execute();
226+
227+
logger.LogInformation("Alternating column colors set successfully.");
228+
}
229+
}

eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/TimePlanning.Pn.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
<ItemGroup>
2525
<PackageReference Include="ExcelDataReader" Version="3.7.0" />
26+
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3568" />
2627
<PackageReference Include="Microting.eForm" Version="8.0.71" />
2728
<PackageReference Include="Microting.EformAngularFrontendBase" Version="8.0.74" />
2829
<PackageReference Include="Microting.eFormApi.BasePn" Version="8.0.72" />

0 commit comments

Comments
 (0)