From 272bd1a3fd91469a55d94eefd3453987e24322d8 Mon Sep 17 00:00:00 2001 From: ivanszabo Date: Wed, 7 May 2025 13:05:28 +0200 Subject: [PATCH 1/4] =?UTF-8?q?CheckListTemplateHeader=20kl=C3=B3noz=C3=A1?= =?UTF-8?q?sa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/CheckListController.cs | 22 ++++++++ .../Services/CheckListService.cs | 54 +++++++++++++++++-- .../Services/Interfaces/ICheckListService.cs | 1 + src/WorkFlowCheck.Web/Helpers/SystemHelper.cs | 2 +- .../CheckListTemplateHeaderPage.cshtml | 47 +++++++++++++++- .../CheckListTemplateHeaderPage.cshtml.cs | 5 ++ .../Services/CheckListService.cs | 21 ++++++++ .../Services/Interfaces/ICheckListService.cs | 2 + src/WorkFlowCheck.Web/wwwroot/js/site.js | 13 +++++ 9 files changed, 160 insertions(+), 7 deletions(-) diff --git a/src/WorkFlowCheck.API/Controllers/CheckListController.cs b/src/WorkFlowCheck.API/Controllers/CheckListController.cs index 83672b0..6b60296 100644 --- a/src/WorkFlowCheck.API/Controllers/CheckListController.cs +++ b/src/WorkFlowCheck.API/Controllers/CheckListController.cs @@ -301,6 +301,28 @@ namespace WorkFlowCheck.API.Controllers return retVal; } + [HttpGet("CloneCheckListTemplateHeader/{id}")] + public async Task> CloneCheckListTemplateHeader(int id) + { + var retVal = new ApiResponseDTO() + { + IsSuccess = true, + }; + var result = await _checkListService.CloneCheckListTemplateHeaderAsync(id); + + if (result != null) + { + retVal.IsSuccess = true; + retVal.Data = result; + } + else + { + retVal.IsSuccess = false; + retVal.Errors.Add("No data!"); + } + + return retVal; + } [HttpGet("GetCheckListTemplateRow/{id}")] public async Task> GetCheckListTemplateRow(int id) diff --git a/src/WorkFlowCheck.BL/Services/CheckListService.cs b/src/WorkFlowCheck.BL/Services/CheckListService.cs index 83adad8..e29a958 100644 --- a/src/WorkFlowCheck.BL/Services/CheckListService.cs +++ b/src/WorkFlowCheck.BL/Services/CheckListService.cs @@ -24,7 +24,7 @@ namespace WorkFlowCheck.BL.Services { public class CheckListService : BaseService, ICheckListService { - + private readonly INumberGeneratorService _numberGeneratorService; public CheckListService(AppDbContext dbContext, @@ -377,7 +377,7 @@ namespace WorkFlowCheck.BL.Services { checkListHeader.CheckStatus = CheckStatus.Closed; checkListHeader.IsEditable = false; - checkListHeader.AcceptUserId = closeCheckListHeaderCloseDTO.UserId; + checkListHeader.AcceptUserId = closeCheckListHeaderCloseDTO.UserId; Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap lezárva: Ellenőrzés:{closeCheckListHeaderCloseDTO.Id}, " + $"Felhasználó:{closeCheckListHeaderCloseDTO.UserId}, " + @@ -394,7 +394,7 @@ namespace WorkFlowCheck.BL.Services } return retVal; } - + public async Task GetCheckListTemplateHeaderAsync(int Id) { var retVal = new CheckListTemplateHeaderDTO() @@ -491,7 +491,53 @@ namespace WorkFlowCheck.BL.Services } public async Task DeleteCheckListTemplateHeaderAsync(int id) { - return await DeleteEntityByIdAsync(id); + return await DeleteEntityByIdAsync(id); + } + public async Task CloneCheckListTemplateHeaderAsync(int id) + { + var retVal = false; + try + { + var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders + .Include(i => i.CheckListTemplateRows) + .Where(w => w.Id == id).FirstOrDefaultAsync(); + if (checkListTemplateHeader != null) + { + + var newCheckListTemplateHeader = new CheckListTemplateHeader() + { + CheckListTemplateRows = new List(), + Description = checkListTemplateHeader.Description, + IsDeleted = false, + NumberGenerator1Id = checkListTemplateHeader.NumberGenerator1Id, + NumberGenerator2Id = checkListTemplateHeader.NumberGenerator2Id, + ShortName = $"{checkListTemplateHeader.ShortName} (másolat)", + }; + foreach (var checkListTemplateRow in checkListTemplateHeader.CheckListTemplateRows) + { + var newCheckListTemplateRow = new CheckListTemplateRow() + { + AnswerType = checkListTemplateRow.AnswerType, + CheckListTemplateHeader = newCheckListTemplateHeader, + CheckPointId = checkListTemplateRow.CheckPointId, + EquipmentId = checkListTemplateRow.EquipmentId, + IsDeleted = false, + OperationDescription = checkListTemplateRow.OperationDescription, + RowIndex = checkListTemplateRow.RowIndex, + }; + newCheckListTemplateHeader.CheckListTemplateRows.Add(newCheckListTemplateRow); + } + _dbContext.CheckListTemplateHeaders.Add(newCheckListTemplateHeader); + await _dbContext.SaveChangesAsync(); + } + } + catch (Exception ex) + { + retVal = false; + Log.ForContext("TAG", "BusinessFlow").Error(ex.Message); + } + + return retVal; } public async Task GetCheckListTemplateRowAsync(int id) { diff --git a/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs b/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs index a5027cd..b33f7cc 100644 --- a/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs +++ b/src/WorkFlowCheck.BL/Services/Interfaces/ICheckListService.cs @@ -20,6 +20,7 @@ namespace WorkFlowCheck.BL.Services.Interfaces Task> GetAllCheckListTemplateHeaderAsync(); Task UpdateCheckListTemplateHeaderAsync(CheckListTemplateHeaderDTO checkListTemplateHeaderDTO); Task DeleteCheckListTemplateHeaderAsync(int id); + Task CloneCheckListTemplateHeaderAsync(int id); Task GetCheckListTemplateRowAsync(int id); Task DeleteCheckListTemplateRowAsync(int id); Task UpdateCheckListTemplateRowAsync(CheckListTemplateRowDTO checkListTemplateRowDTO); diff --git a/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs b/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs index 9715705..f6afb23 100644 --- a/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs +++ b/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs @@ -7,7 +7,7 @@ namespace WorkFlowCheck.Web.Helpers public static class SystemHelper { public static string DatabaseName = ""; - public static string ProgramVersion = "v1.1.019"; + public static string ProgramVersion = "v1.1.021"; public async static Task GetAPIInfoAsync(IConfiguration configuration) { diff --git a/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml b/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml index e04889c..83ca451 100644 --- a/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml +++ b/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml @@ -47,7 +47,7 @@ { data: "shortName" }, { data: "description" }, { data: null, render: function (data, type, row) { - return renderActionButtons(row.id); + return renderActionButtonsforCheckListTemplateHeader(row.id); }} ], columnDefs: [ @@ -68,15 +68,58 @@ $('#newCheckListTemplateHeaderBtn').on('click', function () { - console.log('New button clicked!"'); window.location.href = `@Url.Page("./CheckListTemplateHeaderEditPage")?id=0`; }); + $('#tbCheckListTemplateHeadersPage').on('click', '.edit-btn', function () { const row = table.row($(this).closest('tr')).data(); window.location.href = `@Url.Page("./CheckListTemplateHeaderEditPage")?id=${row.id}`; }); + + $('#tbCheckListTemplateHeadersPage').on('click', '.clone-btn', function () + { + const row = table.row($(this).closest('tr')).data(); + const url = './CheckListTemplateHeaderPage?handler=CloneCheckListTemplateHeader'; + showConfirmModal({ + title: 'Klónozás megerősítése', + message: 'Biztosan klónozni szeretnéd ezt az elemet?', + okText: 'Klónozás', + cancelText: 'Mégsem' + }).then(function (result) { + if (result === 'ok') { + $.ajax({ + url: url, + type: 'GET', + data: { id: row.id }, + success: function (data) { + if (data) { + showMessageModal({ + title: 'Információ', + message: 'A klónozás sikerült!', + okText: 'Értettem' + }); + table.ajax.reload(); + } else { + showMessageModal({ + title: 'Hiba!', + message: 'A klónozás NEM sikerült!', + okText: 'Értettem' + }); + } + }, + error: function (xhr, status, error) { + showMessageModal({ + title: 'Hiba!', + message: 'A klónozás NEM sikerült!', + okText: 'Értettem' + }); + } + }); + } + }); + }); $('#tbCheckListTemplateHeadersPage').on('click', '.delete-btn', function () { diff --git a/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml.cs b/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml.cs index 7942c43..7950b2e 100644 --- a/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml.cs +++ b/src/WorkFlowCheck.Web/Pages/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage.cshtml.cs @@ -27,5 +27,10 @@ namespace WorkFlowCheck.Web.Pages.CheckListTemplate.CheckListTemplateHeader var isSuccess = await _checkListService.DeleteCheckListTemplateHeader(id); return new JsonResult(new { result = isSuccess }); } + public async Task OnGetCloneCheckListTemplateHeader(int id) + { + var isSuccess = await _checkListService.CloneCheckListTemplateHeader(id); + return new JsonResult(new { result = isSuccess }); + } } } diff --git a/src/WorkFlowCheck.Web/Services/CheckListService.cs b/src/WorkFlowCheck.Web/Services/CheckListService.cs index 413c5a7..75cbe72 100644 --- a/src/WorkFlowCheck.Web/Services/CheckListService.cs +++ b/src/WorkFlowCheck.Web/Services/CheckListService.cs @@ -264,6 +264,27 @@ namespace WorkFlowCheck.Web.Services } return retVal; } + public async Task CloneCheckListTemplateHeader(int id) + { + string endpoint = $"{_httpClient.BaseAddress}api/CheckList/CloneCheckListTemplateHeader/{id}"; + var retVal = false; + try + { + var response = await _httpClient.GetFromJsonAsync>(endpoint); + if (response != null) + { + if (response.IsSuccess) + { + return response.Data; + } + } + } + catch (Exception ex) + { + Log.Error(ex.Message); + } + return retVal; + } public async Task GetCheckListTemplateRow(int id) diff --git a/src/WorkFlowCheck.Web/Services/Interfaces/ICheckListService.cs b/src/WorkFlowCheck.Web/Services/Interfaces/ICheckListService.cs index d3a48a8..ecd5622 100644 --- a/src/WorkFlowCheck.Web/Services/Interfaces/ICheckListService.cs +++ b/src/WorkFlowCheck.Web/Services/Interfaces/ICheckListService.cs @@ -19,9 +19,11 @@ namespace WorkFlowCheck.Web.Services.Interfaces Task> GetAllCheckListTemplateHeaderAsync(); Task> UpdateCheckListTemplateHeader(CheckListTemplateHeaderDTO checkListTemplateHeaderDTO); Task DeleteCheckListTemplateHeader(int id); + Task CloneCheckListTemplateHeader(int id); Task GetCheckListTemplateRow(int id); Task DeleteCheckListTemplateRow(int id); + Task> UpdateCheckListTemplateRow(CheckListTemplateRowDTO checkListTemplateRowDTO); diff --git a/src/WorkFlowCheck.Web/wwwroot/js/site.js b/src/WorkFlowCheck.Web/wwwroot/js/site.js index 7a5ab1e..a35e974 100644 --- a/src/WorkFlowCheck.Web/wwwroot/js/site.js +++ b/src/WorkFlowCheck.Web/wwwroot/js/site.js @@ -232,6 +232,19 @@ function renderActionButtonsforCheckListHeader(data, rowId) { //`; } +function renderActionButtonsforCheckListTemplateHeader(rowId) { + return ` + + + + `; +} function renderCheckStatus(data) { //Open = 0, From 699110af105aa82bc2625ce652a7383cb8b66644 Mon Sep 17 00:00:00 2001 From: ivanszabo Date: Wed, 7 May 2025 13:25:27 +0200 Subject: [PATCH 2/4] =?UTF-8?q?Privacy=20kialak=C3=ADt=C3=A1sa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/WorkFlowCheck.Web/Helpers/SystemHelper.cs | 2 +- src/WorkFlowCheck.Web/Pages/Privacy.cshtml | 28 +++++++++++++++++-- .../Pages/Shared/_Layout.cshtml | 10 ++++--- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs b/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs index f6afb23..86722e8 100644 --- a/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs +++ b/src/WorkFlowCheck.Web/Helpers/SystemHelper.cs @@ -7,7 +7,7 @@ namespace WorkFlowCheck.Web.Helpers public static class SystemHelper { public static string DatabaseName = ""; - public static string ProgramVersion = "v1.1.021"; + public static string ProgramVersion = "v1.1.022"; public async static Task GetAPIInfoAsync(IConfiguration configuration) { diff --git a/src/WorkFlowCheck.Web/Pages/Privacy.cshtml b/src/WorkFlowCheck.Web/Pages/Privacy.cshtml index 46ba966..5bf519a 100644 --- a/src/WorkFlowCheck.Web/Pages/Privacy.cshtml +++ b/src/WorkFlowCheck.Web/Pages/Privacy.cshtml @@ -1,8 +1,32 @@ @page @model PrivacyModel @{ - ViewData["Title"] = "Privacy Policy"; + ViewData["Title"] = "Adatvédelmi tájékoztató"; }

@ViewData["Title"]

-

Use this page to detail your site's privacy policy.

+

Ez az adatvédelmi tájékoztató bemutatja, hogy az oldal hogyan kezeli a felhasználók személyes adatait.

+ +

Gyűjtött adatok

+
    +
  • Felhasználó neve
  • +
  • Felhasználó e-mail címe
  • +
  • Bejelentkezési azonosító (JWT token a böngésző cookie-jában tárolva)
  • +
+ +

Adatok felhasználása

+

Az adatokat kizárólag a felhasználói fiók azonosítására és a szolgáltatás használatának biztosítására használjuk fel. Az e-mail címet például a fiók kezelésére, valamint a bejelentkezéshez és az azonosításhoz használjuk.

+ +

Adatok megőrzése

+

A személyes adatokat a fiók fennállásáig, illetve a törlési kérelem beérkezéséig tároljuk. A JWT token a cookie-ban tárolódik, és annak érvényességi ideje alatt használatos.

+ +

Adatok továbbítása

+

Az adatokat harmadik fél számára nem adjuk át, kivéve jogszabályi kötelezettség esetén.

+ +

Cookie-k

+

Oldalunk cookie-kat használ a bejelentkezési állapot megőrzése érdekében (JWT token). Ezek szükségesek a szolgáltatás megfelelő működéséhez. A cookie a böngésző bezárása után vagy a lejárati idő eltelte után automatikusan érvénytelenné válik.

+ +

Felhasználói jogok

+

A felhasználóknak joguk van tájékoztatást kérni a kezelt adataikról, kérhetik azok helyesbítését vagy törlését, valamint tiltakozhatnak az adatkezelés ellen a jogszabályi keretek között.

+ +

Amennyiben kérdése van az adatkezeléssel kapcsolatban, kérjük, vegye fel velünk a kapcsolatot.

diff --git a/src/WorkFlowCheck.Web/Pages/Shared/_Layout.cshtml b/src/WorkFlowCheck.Web/Pages/Shared/_Layout.cshtml index 46881ed..2fd0af3 100644 --- a/src/WorkFlowCheck.Web/Pages/Shared/_Layout.cshtml +++ b/src/WorkFlowCheck.Web/Pages/Shared/_Layout.cshtml @@ -67,9 +67,7 @@
  • Szabályok - Ellenőrzési pontok
  • - + @@ -182,7 +184,7 @@
    - © @(DateTime.Now.Year) - Workflow Check App - Version @(SystemHelper.ProgramVersion) (@(SystemHelper.DatabaseName))Privacy + © @(DateTime.Now.Year) - Workflow Check App - Version @(SystemHelper.ProgramVersion) (@(SystemHelper.DatabaseName)) Adatvédelmi tájékoztatás
    From 0a36544dce44ce3ccccf1a124403b47eb2fbf785 Mon Sep 17 00:00:00 2001 From: ivanszabo Date: Thu, 8 May 2025 11:01:55 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Kl=C3=B3noz=C3=A1s=20jav=C3=ADt=C3=A1sa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/WorkFlowCheck.BL/Services/CheckListService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WorkFlowCheck.BL/Services/CheckListService.cs b/src/WorkFlowCheck.BL/Services/CheckListService.cs index e29a958..02d21be 100644 --- a/src/WorkFlowCheck.BL/Services/CheckListService.cs +++ b/src/WorkFlowCheck.BL/Services/CheckListService.cs @@ -499,6 +499,7 @@ namespace WorkFlowCheck.BL.Services try { var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders + .AsNoTracking() .Include(i => i.CheckListTemplateRows) .Where(w => w.Id == id).FirstOrDefaultAsync(); if (checkListTemplateHeader != null) From b6ffcca996c991eccc2af619d295592276215c9d Mon Sep 17 00:00:00 2001 From: ivanszabo Date: Thu, 15 May 2025 14:41:34 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Firebird=20Cloud=20Message=20API=20el=C5=91?= =?UTF-8?q?k=C3=A9sz=C3=ADt=C3=A9se?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/FCMController.cs | 147 +++ .../WorkFlowCheck.API.csproj | 1 + ...pp-firebase-adminsdk-fbsvc-37642626e4.json | 13 + .../Services/Interfaces/IMessageService.cs | 2 + .../Services/MessageService.cs | 56 +- src/WorkFlowCheck.Common/DTO/FCMMessageDTO.cs | 17 + src/WorkFlowCheck.DL/AppDbContext.cs | 2 + .../FCMTokenTypeConfiguration.cs | 21 + src/WorkFlowCheck.DL/Entities/FCMToken.cs | 20 + .../20250515123614_Extend021.Designer.cs | 997 ++++++++++++++++++ .../Migrations/20250515123614_Extend021.cs | 68 ++ .../Migrations/AppDbContextModelSnapshot.cs | 42 +- 12 files changed, 1380 insertions(+), 6 deletions(-) create mode 100644 src/WorkFlowCheck.API/Controllers/FCMController.cs create mode 100644 src/WorkFlowCheck.API/com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json create mode 100644 src/WorkFlowCheck.Common/DTO/FCMMessageDTO.cs create mode 100644 src/WorkFlowCheck.DL/Configurations/FCMTokenTypeConfiguration.cs create mode 100644 src/WorkFlowCheck.DL/Entities/FCMToken.cs create mode 100644 src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.Designer.cs create mode 100644 src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.cs diff --git a/src/WorkFlowCheck.API/Controllers/FCMController.cs b/src/WorkFlowCheck.API/Controllers/FCMController.cs new file mode 100644 index 0000000..2ee378c --- /dev/null +++ b/src/WorkFlowCheck.API/Controllers/FCMController.cs @@ -0,0 +1,147 @@ +using Google.Apis.Auth.OAuth2; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Serilog; +using System.Net.Http.Headers; +using System.Text; +using WorkFlowCheck.BL.Services.Interfaces; +using WorkFlowCheck.Common.DTO; + +namespace WorkFlowCheck.API.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class FCMController : ControllerBase + { + private readonly IMessageService _messageService; + public FCMController(IMessageService messageService) + { + _messageService = messageService; + } + + [HttpPost("SendFCMMessage")] + public async Task> SendFCMMessage([FromBody] FCMMessageDTO fCMMessageDTO) + { + var retVal = new ApiResponseDTO() + { + IsSuccess = true + }; + + try + { + var pathToJsonKey = "com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json"; + var projectId = "com-nuvolar-wfcapp"; + var credential = GoogleCredential + .FromFile(pathToJsonKey) + .CreateScoped("https://www.googleapis.com/auth/firebase.messaging"); + var accessToken = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync(); + + var client = new HttpClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + + + var message = new + { + message = new + { + token = fCMMessageDTO.Token, + notification = new + { + title = fCMMessageDTO.Title, + body = fCMMessageDTO.Body, + } + } + }; + + var json = JsonConvert.SerializeObject(message); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + + var response = await client.PostAsync($"https://fcm.googleapis.com/v1/projects/{projectId}/messages:send", content); + + var result = await response.Content.ReadAsStringAsync(); + + + } + catch (Exception ex) + { + retVal.IsSuccess = false; + Log.Error(ex.Message); + } + return retVal; + } + + [HttpPost("SendFCMMessageToLastToken")] + public async Task> SendFCMMessageToLastToken([FromBody] FCMMessageDTO fCMMessageDTO) + { + var retVal = new ApiResponseDTO() + { + IsSuccess = true + }; + + try + { + var pathToJsonKey = "com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json"; + var projectId = "com-nuvolar-wfcapp"; + var credential = GoogleCredential + .FromFile(pathToJsonKey) + .CreateScoped("https://www.googleapis.com/auth/firebase.messaging"); + var accessToken = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync(); + + var client = new HttpClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + + + var message = new + { + message = new + { + token = await _messageService.GetLastFCMTokensAsync(), + notification = new + { + title = fCMMessageDTO.Title, + body = fCMMessageDTO.Body, + } + } + }; + + var json = JsonConvert.SerializeObject(message); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + + var response = await client.PostAsync($"https://fcm.googleapis.com/v1/projects/{projectId}/messages:send", content); + + var result = await response.Content.ReadAsStringAsync(); + + + } + catch (Exception ex) + { + retVal.IsSuccess = false; + Log.Error(ex.Message); + } + return retVal; + } + + [HttpPost("SendFCMToken")] + public async Task> SendFCMToken([FromBody] FCMMessageDTO fCMMessageDTO) + { + var retVal = new ApiResponseDTO() + { + IsSuccess = true + }; + + try + { + await _messageService.SendFCMTokenAsync(fCMMessageDTO.Token); + } + catch (Exception ex) + { + retVal.IsSuccess = false; + Log.Error(ex.Message); + } + return retVal; + } + } +} diff --git a/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj b/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj index 9b9caf5..596b3a7 100644 --- a/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj +++ b/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj @@ -17,6 +17,7 @@ + diff --git a/src/WorkFlowCheck.API/com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json b/src/WorkFlowCheck.API/com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json new file mode 100644 index 0000000..ecf2ea1 --- /dev/null +++ b/src/WorkFlowCheck.API/com-nuvolar-wfcapp-firebase-adminsdk-fbsvc-37642626e4.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "com-nuvolar-wfcapp", + "private_key_id": "37642626e4a61fea715f3ef02a35d53fa9227666", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCVQKzCOgEhaQFo\nxtOYCpOc6XQNOVfNm8Z1xu1uoQtSZZIH3ivJy1IBqlyP/+sQ+7FO3Af5v90ae3rf\nvzd42QC4hrbBPyLGbVJWDHNPOzwg7bbez3waaU4i/7m4YJ61hlOObo888mjAxG8t\nz0cDEQzWPPUlLBCvtzY8Zv3jWdYaBxGUUzHxfemjTVLG7YCUjyt057HJVSH7AJpV\ndhnBi+3xlogsnK227ou/rLWoNyZVDOUaSiMor+LNiQx82eXc+UUaJgjpbI5AMk9z\n7CgAM8CSMOw7BHhCImVXaxH9rLZCsw0xpZnCJuOJKRyIMhrfcWKcHjrgkEW+xErj\nWN9lSkHRAgMBAAECggEAAwH5FUcrVom13b9bfF3ysnPdKwbNvVrLN5yDFIKV7oK1\n3Bca42u3rulIqR15doe275GVLtASL+ZfABcrslGPr1hGIqvvusdRVGL2+CjXveti\nbvgoDmVyvddwzf2S9zIiOQ2i8PHK4P8YZTg/DGmVnFPhRg7utWbMFtClw0UQQKkd\nzRwRDsw0jx9wDpP4EaO+czNvVZnnj+miL8QICN4gjbTdyQiVw2D1KzabwmozfEkM\nqTP+yH9mSC4gAEkG+X3i48QxiXZXvLflfnhF58+mT4yjIBIQbRTi0w9yLWRkcs8n\nmCq/89PZMncpNdCSJqdNOsYXgVaW8OMePxPNER2g4QKBgQDHl47N9AGyukpqEJJK\nR/8u3IwcCjLBb0wk5UxtZyz2JpoyqXoaKw7teqCqhg6lVd8MdIcVITKe0nZ+P29z\nyL+RVC+hGm/OQj6mAVyFEZptMgtQZGA2ThLY4ozZgzTW7uNyChhnUcqTiMCJ0g5g\n05imd6nQFKxI1ZfCsE7qlq6yYQKBgQC/bxKYno/6OT+9TTS+OCYVx9WJ8JCzOqFh\n/S+7qV14Bmml/JmYoSo/umxNOlKu3c7QtjU6caD/r4q/r6RHvvBxMlBu4K+vTEXh\nhFeqYORwTcEkcTDpjAGDekeJsRSxv5bg6QtsW30mtreBBC1/fOAvHD03Tz8GmFsp\nHry7b1WlcQKBgQCrnb51iix3oETh5DPVWQirI4n5hi9UMb24L81CeKepU1Hc4+qQ\nW5uvSHSjizdGpIpwLDYGThA3jeHC9gp/9Qn7DPcTQCcIo984YA1MgfFVmOUvj89G\ngmUkRdA0KuQhNzEsWk/XbvWPW9Op7YrdaLNl15iUyWHGEpo2FeEVRtEZoQKBgF5Z\nM+UcYQGGLa/y2UfXDI43izsM4YQ0JU3SJzBqbLK3FmLEeD8NT3FRRAdb81xT3ZZn\n9xvy3NKnhc6rll/17zMbBSFgg7X19YsMWtiSIIRpDgQT9XNlmWlfXtqx9+0S7B21\nPfgNr0ThUNe5Y2Mt/J+7X0BfQkTR2jwN9h665I9BAoGADx/oQLMXgKGdes4adF1Z\np9miGNsmUgXHdT+CdWkRx5uRd1a5s1Di6sOEUBPyFJ9hYc5ObRuC5q1A24ApASak\n0YCbUV1lqzFI4loXyM5ABqRTRCVGH94PXDAvsRUTTLvRIOliOeOBa8bNGGPlXtFw\nXzrkDjsz71JdNxgvT2Zz7nA=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-fbsvc@com-nuvolar-wfcapp.iam.gserviceaccount.com", + "client_id": "109975038898567298706", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40com-nuvolar-wfcapp.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} diff --git a/src/WorkFlowCheck.BL/Services/Interfaces/IMessageService.cs b/src/WorkFlowCheck.BL/Services/Interfaces/IMessageService.cs index 4e9775b..1fd59ee 100644 --- a/src/WorkFlowCheck.BL/Services/Interfaces/IMessageService.cs +++ b/src/WorkFlowCheck.BL/Services/Interfaces/IMessageService.cs @@ -9,5 +9,7 @@ namespace WorkFlowCheck.BL.Services.Interfaces public interface IMessageService { Task SendMailAsync(List recipients, string subject, string htmlBody); + Task SendFCMTokenAsync(string token); + Task GetLastFCMTokensAsync(); } } diff --git a/src/WorkFlowCheck.BL/Services/MessageService.cs b/src/WorkFlowCheck.BL/Services/MessageService.cs index b4a38b8..b33a71e 100644 --- a/src/WorkFlowCheck.BL/Services/MessageService.cs +++ b/src/WorkFlowCheck.BL/Services/MessageService.cs @@ -4,14 +4,21 @@ using MimeKit; using Microsoft.Extensions.Configuration; using WorkFlowCheck.BL.Models; using WorkFlowCheck.BL.Services.Interfaces; +using Serilog; +using WorkFlowCheck.DL.Entities; +using AutoMapper; +using Microsoft.EntityFrameworkCore; +using WorkFlowCheck.DL; namespace WorkFlowCheck.BL.Services { - public class MessageService : IMessageService + public class MessageService : BaseService, IMessageService { private readonly EmailSettings _settings; - public MessageService(IConfiguration configuration) + public MessageService(AppDbContext dbContext, + IMapper mapper, + IConfiguration configuration) : base(dbContext, mapper) { _settings = configuration.GetSection("EmailSettings").Get()!; } @@ -41,6 +48,51 @@ namespace WorkFlowCheck.BL.Services return true; } + public async Task SendFCMTokenAsync(string token) + { + var retVal = true; + try + { + if (string.IsNullOrEmpty(token)) + { + var FCMToken = new FCMToken() + { + Token = token + }; + await _dbContext.FCMTokens.AddAsync(FCMToken); + await _dbContext.SaveChangesAsync(); + } + } + catch (Exception ex) + { + retVal = false; + Log.ForContext("TAG", "BusinessFlow").Error(ex.Message); + } + + return retVal; + } + public async Task GetLastFCMTokensAsync() + { + var retVal = ""; + try + { + var FCMToken = await _dbContext.FCMTokens + .AsNoTracking() + .OrderByDescending(x => x.CreatedAt) + .Take(1) + .FirstOrDefaultAsync(); + if (FCMToken != null && !string.IsNullOrEmpty(FCMToken.Token)) + { + retVal += FCMToken.Token; + } + } + catch (Exception ex) + { + retVal = ""; + Log.ForContext("TAG", "BusinessFlow").Error(ex.Message); + } + return retVal; + } } } diff --git a/src/WorkFlowCheck.Common/DTO/FCMMessageDTO.cs b/src/WorkFlowCheck.Common/DTO/FCMMessageDTO.cs new file mode 100644 index 0000000..9118499 --- /dev/null +++ b/src/WorkFlowCheck.Common/DTO/FCMMessageDTO.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorkFlowCheck.Common.DTO +{ + public class FCMMessageDTO + + { + public string? Token { get; set; } + public string? Body { get; set; } + public string? Title { get; set; } + public int? UserId { get; set; } + } +} diff --git a/src/WorkFlowCheck.DL/AppDbContext.cs b/src/WorkFlowCheck.DL/AppDbContext.cs index cd8ef44..269d5bd 100644 --- a/src/WorkFlowCheck.DL/AppDbContext.cs +++ b/src/WorkFlowCheck.DL/AppDbContext.cs @@ -27,6 +27,7 @@ namespace WorkFlowCheck.DL public DbSet CheckPoints { get; set; } = null!; public DbSet DeviceMessages { get; set; } = null!; public DbSet Equipments { get; set; } = null!; + public DbSet FCMTokens { get; set; } = null!; public DbSet Locations { get; set; } = null!; public DbSet NumberGeneratorTemplates { get; set; } = null!; public DbSet NumberGeneratorTemplateDates { get; set; } = null!; @@ -48,6 +49,7 @@ namespace WorkFlowCheck.DL modelBuilder.ApplyConfiguration(new CheckPointTypeConfiguration()); modelBuilder.ApplyConfiguration(new DeviceMessageTypeConfiguration()); modelBuilder.ApplyConfiguration(new EquipmentTypeConfiguration()); + modelBuilder.ApplyConfiguration(new FCMTokenTypeConfiguration()); modelBuilder.ApplyConfiguration(new LocationTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorDateTypeConfiguration()); diff --git a/src/WorkFlowCheck.DL/Configurations/FCMTokenTypeConfiguration.cs b/src/WorkFlowCheck.DL/Configurations/FCMTokenTypeConfiguration.cs new file mode 100644 index 0000000..4ac73cb --- /dev/null +++ b/src/WorkFlowCheck.DL/Configurations/FCMTokenTypeConfiguration.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorkFlowCheck.DL.Configurations +{ + public class FCMTokenTypeConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("FCMToken"); + builder.HasKey(e => e.Id); + builder.Property(e => e.Id).ValueGeneratedOnAdd(); + } + + } +} diff --git a/src/WorkFlowCheck.DL/Entities/FCMToken.cs b/src/WorkFlowCheck.DL/Entities/FCMToken.cs new file mode 100644 index 0000000..2bf6dd1 --- /dev/null +++ b/src/WorkFlowCheck.DL/Entities/FCMToken.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WorkFlowCheck.DL.Interfaces; + +namespace WorkFlowCheck.DL.Entities +{ + public class FCMToken:ISoftDeletableEntity, IAuditableEntity + { + public int Id { get; set; } + public string Token { get; set; } = null!; + public bool IsDeleted { get; set; } + public DateTime LastModAt { get; set; } + public string LastModBy { get; set; } = null!; + public DateTime CreatedAt { get; set; } + public string CreatedBy { get; set; } = null!; + } +} diff --git a/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.Designer.cs b/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.Designer.cs new file mode 100644 index 0000000..95cf081 --- /dev/null +++ b/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.Designer.cs @@ -0,0 +1,997 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WorkFlowCheck.DL; + +#nullable disable + +namespace WorkFlowCheck.DL.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250515123614_Extend021")] + partial class Extend021 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListHeader", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AcceptUserId") + .HasColumnType("int"); + + b.Property("CheckListTemplateHeaderId") + .HasColumnType("int"); + + b.Property("CheckStatus") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateExecution") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DocumentNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("GuidNumber") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditable") + .HasColumnType("bit"); + + b.Property("IsStorno") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ShortName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AcceptUserId"); + + b.HasIndex("CheckListTemplateHeaderId"); + + b.HasIndex("UserId"); + + b.ToTable("CheckListHeader", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListRow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Answer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CheckListHeaderId") + .HasColumnType("int"); + + b.Property("CheckListTemplateRowId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("GuidNumber") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhotoFileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CheckListHeaderId"); + + b.HasIndex("CheckListTemplateRowId"); + + b.ToTable("CheckListRow", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NumberGenerator1Id") + .HasColumnType("int"); + + b.Property("NumberGenerator2Id") + .HasColumnType("int"); + + b.Property("ShortName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("NumberGenerator1Id"); + + b.HasIndex("NumberGenerator2Id"); + + b.ToTable("CheckListTemplateHeader", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListTemplateRow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnswerType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CheckListTemplateHeaderId") + .HasColumnType("int"); + + b.Property("CheckPointId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EquipmentId") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OperationDescription") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RowIndex") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CheckListTemplateHeaderId"); + + b.HasIndex("CheckPointId"); + + b.HasIndex("EquipmentId"); + + b.ToTable("CheckListTemplateRow", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckPoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("ShortName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("CheckPoint", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.DeviceMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeviceIdFrom") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DeviceIdTo") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("ExtraDataJSON") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsReaded") + .HasColumnType("bit"); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReceiveDate") + .HasColumnType("datetime2"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("SendDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("DeviceIdTo") + .HasDatabaseName("IX_DeviceMessage_DeviceIdTo"); + + b.HasIndex("RoleId"); + + b.ToTable("DeviceMessage", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Equipment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EquipmentNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ShortName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Equipment", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.FCMToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FCMToken", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Location", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CurrentNumber") + .HasColumnType("int"); + + b.Property("DigitFormat") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("GenerateType") + .HasColumnType("int"); + + b.Property("LastGeneratedNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PrefixSeparator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ShortName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Suffix") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SuffixSeparator") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("NumberGeneratorTemplate", (string)null); + + b.HasData( + new + { + Id = 1, + CurrentNumber = 0, + DigitFormat = "D4", + GenerateType = 0, + LastGeneratedNumber = "", + Prefix = "CHK", + PrefixSeparator = "-", + ShortName = "Ellenőrzési dokumentum sorszámozása", + Suffix = "", + SuffixSeparator = "-" + }); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.NumberGeneratorTemplateDate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CurrentNumber") + .HasColumnType("int"); + + b.Property("LastGeneratedNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("NumberGeneratorTemplateId") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NumberGeneratorTemplateId"); + + b.ToTable("NumberGeneratorTemplateDate", (string)null); + + b.HasData( + new + { + Id = 1, + CurrentNumber = 0, + LastGeneratedNumber = "", + Month = 0, + NumberGeneratorTemplateId = 1, + Year = 1 + }); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CanDownloadAPK") + .HasColumnType("bit"); + + b.Property("CanEnableBlocked") + .HasColumnType("bit"); + + b.Property("CanUseMobilApp") + .HasColumnType("bit"); + + b.Property("CanUseWebAdmin") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsAdmin") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("int"); + + b.Property("RoleName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.RoleCheckListTemplateHeader", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CheckListTemplateHeaderId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CheckListTemplateHeaderId"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleCheckListTemplateHeader", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.RoleCheckPoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CheckPointId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CheckPointId"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleCheckPoint", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("JwtToken") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NFCActive") + .HasColumnType("bit"); + + b.Property("NFCCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("Token2FA") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + + b.HasData( + new + { + Id = 1, + Active = true, + CreatedAt = new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5079), + CreatedBy = "System", + Email = "admin@nuvolar.hu", + FirstName = "Administrator", + IsDeleted = false, + JwtToken = "", + LastModAt = new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5082), + LastModBy = "System", + LastName = "System", + NFCActive = true, + NFCCode = "00000000", + PasswordHash = "eGM0NUREZnJ0ISFFRDIxMKE5TYwthDBuUsTUEO1fBnCR3VdSCmdz47ue0RoVvnkY", + Token2FA = "", + UserName = "admin" + }, + new + { + Id = 2, + Active = true, + CreatedAt = new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8830), + CreatedBy = "System", + Email = "user@nuvolar.hu", + FirstName = "User", + IsDeleted = false, + JwtToken = "", + LastModAt = new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8834), + LastModBy = "System", + LastName = "System", + NFCActive = true, + NFCCode = "00000000", + PasswordHash = "eGM0NUREZnJ0ISFFRDIxMPwM2D9sQSj7zmaSBIsOGe0I9hBFwCGPVbyrYMA5EnKG", + Token2FA = "", + UserName = "user" + }); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.HasIndex("UserId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListHeader", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.User", "AcceptUser") + .WithMany() + .HasForeignKey("AcceptUserId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", "CheckListTemplateHeader") + .WithMany() + .HasForeignKey("CheckListTemplateHeaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AcceptUser"); + + b.Navigation("CheckListTemplateHeader"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListRow", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.CheckListHeader", "CheckListHeader") + .WithMany("CheckListRows") + .HasForeignKey("CheckListHeaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.CheckListTemplateRow", "CheckListTemplateRow") + .WithMany() + .HasForeignKey("CheckListTemplateRowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CheckListHeader"); + + b.Navigation("CheckListTemplateRow"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", "NumberGenerator1") + .WithMany() + .HasForeignKey("NumberGenerator1Id"); + + b.HasOne("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", "NumberGenerator2") + .WithMany() + .HasForeignKey("NumberGenerator2Id"); + + b.Navigation("NumberGenerator1"); + + b.Navigation("NumberGenerator2"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListTemplateRow", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", "CheckListTemplateHeader") + .WithMany("CheckListTemplateRows") + .HasForeignKey("CheckListTemplateHeaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.CheckPoint", "CheckPoint") + .WithMany("CheckListTemplateRows") + .HasForeignKey("CheckPointId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.Equipment", "Equipment") + .WithMany() + .HasForeignKey("EquipmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CheckListTemplateHeader"); + + b.Navigation("CheckPoint"); + + b.Navigation("Equipment"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.DeviceMessage", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.Role", "Role") + .WithMany() + .HasForeignKey("RoleId"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.NumberGeneratorTemplateDate", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", "NumberGeneratorTemplate") + .WithMany("NumberGeneratorTemplateDates") + .HasForeignKey("NumberGeneratorTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NumberGeneratorTemplate"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Role", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.Role", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.RoleCheckListTemplateHeader", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", "CheckListTemplateHeader") + .WithMany() + .HasForeignKey("CheckListTemplateHeaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.Role", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CheckListTemplateHeader"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.RoleCheckPoint", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.CheckPoint", "CheckPoint") + .WithMany() + .HasForeignKey("CheckPointId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WorkFlowCheck.DL.Entities.Role", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CheckPoint"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.UserRole", b => + { + b.HasOne("WorkFlowCheck.DL.Entities.Role", "Role") + .WithMany("UserRoles") + .HasForeignKey("RoleId"); + + b.HasOne("WorkFlowCheck.DL.Entities.User", "User") + .WithMany("UserRoles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListHeader", b => + { + b.Navigation("CheckListRows"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckListTemplateHeader", b => + { + b.Navigation("CheckListTemplateRows"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.CheckPoint", b => + { + b.Navigation("CheckListTemplateRows"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", b => + { + b.Navigation("NumberGeneratorTemplateDates"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Role", b => + { + b.Navigation("Children"); + + b.Navigation("UserRoles"); + }); + + modelBuilder.Entity("WorkFlowCheck.DL.Entities.User", b => + { + b.Navigation("UserRoles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.cs b/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.cs new file mode 100644 index 0000000..c52f0b3 --- /dev/null +++ b/src/WorkFlowCheck.DL/Migrations/20250515123614_Extend021.cs @@ -0,0 +1,68 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WorkFlowCheck.DL.Migrations +{ + /// + public partial class Extend021 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "FCMToken", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Token = table.Column(type: "nvarchar(max)", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + LastModAt = table.Column(type: "datetime2", nullable: false), + LastModBy = table.Column(type: "nvarchar(max)", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FCMToken", x => x.Id); + }); + + migrationBuilder.UpdateData( + table: "Users", + keyColumn: "Id", + keyValue: 1, + columns: new[] { "CreatedAt", "LastModAt" }, + values: new object[] { new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5079), new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5082) }); + + migrationBuilder.UpdateData( + table: "Users", + keyColumn: "Id", + keyValue: 2, + columns: new[] { "CreatedAt", "LastModAt" }, + values: new object[] { new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8830), new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8834) }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FCMToken"); + + migrationBuilder.UpdateData( + table: "Users", + keyColumn: "Id", + keyValue: 1, + columns: new[] { "CreatedAt", "LastModAt" }, + values: new object[] { new DateTime(2025, 4, 10, 9, 50, 12, 488, DateTimeKind.Utc).AddTicks(1377), new DateTime(2025, 4, 10, 9, 50, 12, 488, DateTimeKind.Utc).AddTicks(1382) }); + + migrationBuilder.UpdateData( + table: "Users", + keyColumn: "Id", + keyValue: 2, + columns: new[] { "CreatedAt", "LastModAt" }, + values: new object[] { new DateTime(2025, 4, 10, 9, 50, 12, 499, DateTimeKind.Utc).AddTicks(4095), new DateTime(2025, 4, 10, 9, 50, 12, 499, DateTimeKind.Utc).AddTicks(4096) }); + } + } +} diff --git a/src/WorkFlowCheck.DL/Migrations/AppDbContextModelSnapshot.cs b/src/WorkFlowCheck.DL/Migrations/AppDbContextModelSnapshot.cs index ef908ed..8be499a 100644 --- a/src/WorkFlowCheck.DL/Migrations/AppDbContextModelSnapshot.cs +++ b/src/WorkFlowCheck.DL/Migrations/AppDbContextModelSnapshot.cs @@ -377,6 +377,40 @@ namespace WorkFlowCheck.DL.Migrations b.ToTable("Equipment", (string)null); }); + modelBuilder.Entity("WorkFlowCheck.DL.Entities.FCMToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModAt") + .HasColumnType("datetime2"); + + b.Property("LastModBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FCMToken", (string)null); + }); + modelBuilder.Entity("WorkFlowCheck.DL.Entities.Location", b => { b.Property("Id") @@ -692,13 +726,13 @@ namespace WorkFlowCheck.DL.Migrations { Id = 1, Active = true, - CreatedAt = new DateTime(2025, 4, 10, 9, 50, 12, 488, DateTimeKind.Utc).AddTicks(1377), + CreatedAt = new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5079), CreatedBy = "System", Email = "admin@nuvolar.hu", FirstName = "Administrator", IsDeleted = false, JwtToken = "", - LastModAt = new DateTime(2025, 4, 10, 9, 50, 12, 488, DateTimeKind.Utc).AddTicks(1382), + LastModAt = new DateTime(2025, 5, 15, 12, 36, 12, 645, DateTimeKind.Utc).AddTicks(5082), LastModBy = "System", LastName = "System", NFCActive = true, @@ -711,13 +745,13 @@ namespace WorkFlowCheck.DL.Migrations { Id = 2, Active = true, - CreatedAt = new DateTime(2025, 4, 10, 9, 50, 12, 499, DateTimeKind.Utc).AddTicks(4095), + CreatedAt = new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8830), CreatedBy = "System", Email = "user@nuvolar.hu", FirstName = "User", IsDeleted = false, JwtToken = "", - LastModAt = new DateTime(2025, 4, 10, 9, 50, 12, 499, DateTimeKind.Utc).AddTicks(4096), + LastModAt = new DateTime(2025, 5, 15, 12, 36, 12, 656, DateTimeKind.Utc).AddTicks(8834), LastModBy = "System", LastName = "System", NFCActive = true,