Author SHA1 Message Date
ivanszabo 717becd1fc ServerSide Paging 2026-08-02 16:36:21 +02:00
ivanszabo 92acb42601 Na most jó a lapozás 2026-03-09 11:32:12 +01:00
ivanszabo 53dc9b326a Ez most szerver oldalon szűr és lapoz 2026-03-02 14:12:43 +01:00
ivanszabo ea9673c29b Login secure problem 2026-01-28 13:46:16 +01:00
ivanszabo 4c7e24c478 1.1.32 kiadás 2026-01-28 12:48:21 +01:00
ivanszabo c11ff65a3e Ellenőrzések szétválasztása + sorrend 2026-01-28 12:47:43 +01:00
ivanszabo 8c0796eb69 satatables hu language pack lokálisan 2026-01-28 11:54:11 +01:00
ivanszabo 10ad411b5e appsettings beállítása fejlesztéshez 2026-01-28 11:53:52 +01:00
ivanszabo 8d766ab988 publish cmd 2026-01-28 11:18:26 +01:00
ivanszabo 8177a60351 - 2026-01-21 13:01:06 +01:00
ivanszabo 0fd073755e Password első felhasználó rögzítésénél hiba 2026-01-21 12:59:56 +01:00
ivanszabo 6ea799dcdf WS2016DC\\SQLEXPRESS javítása 2026-01-21 10:22:33 +01:00
ivanszabo caf9746443 API pulish.cmd kiegészítése 2026-01-21 09:35:09 +01:00
ivanszabo 41542e492d E-mail küldése 10 próbálkozásra, 2 mp-es várakozással 2026-01-21 09:19:22 +01:00
ivanszabo 4f4ca5cec4 Login és ChangePassword formok változtatása spinner kiegészítés 2026-01-20 10:10:52 +01:00
ivanszabo f480269bc5 Maximumart gépre átállás VS 2026 2026-01-20 10:09:59 +01:00
ivanszabo 24c49567aa BUGFIX valu mentésére 2025-07-07 14:57:40 +02:00
ivanszabo affad21ab0 BUGFIX mentés, scrollozás 2025-07-03 08:55:09 +02:00
ivanszabo a646258837 Elvileg jó, meg a mentés is. 2025-07-02 19:38:33 +02:00
ivanszabo 7f3562fb73 MemoryStreamos a fotó ... 2025-07-02 18:30:10 +02:00
ivanszabo bc977af15c Alap BUGFIX javításhoz 2025-07-02 13:32:33 +02:00
ivanszabo 6be6bc533c Hogy az "élesre" menjen .. 2025-07-01 17:13:34 +02:00
ivanszabo 864c76f827 BUGFIX Scroll javítása 1.1.035 2025-07-01 10:47:47 +02:00
ivanszabo 8208b31d08 1.1.033 Fényképek beküldése javítása 2025-07-01 08:30:34 +02:00
ivanszabo 4f149f4eef 1.1.030 2025-06-30 07:24:55 +02:00
ivanszabo 8ce7268338 Merge branch 'master' of https://tfs.nuvolar.hu:8443/tfs/AtomERP/_git/WorkFlowCheck 2025-06-29 13:30:38 +02:00
ivanszabo d42900e8f6 MOBILE BugFix 2025-06-29 13:30:34 +02:00
ivanszabo 25cd092a08 Backend BUGFIX 2025-06-29 13:30:08 +02:00
ivanszabo e5dd9aad27 A PDF generálásának javítása 2025-06-17 11:35:36 +02:00
ivanszabo d1ad7e76c3 Na most van jól beállítva a dolog. 2025-06-10 17:26:14 +02:00
ivanszabo 5e94586a75 Jóváhagyási BUGFIX 2025-06-10 12:14:52 +02:00
ivanszabo d775ae82a0 GIT 2025-06-10 12:14:41 +02:00
ivanszabo e6b53d193c ok 2025-06-06 08:47:53 +02:00
ivanszabo 400a459479 Itt maradt 2025-06-06 08:46:12 +02:00
Iván Szabó ac74ef9cfc v1.1.030 2025-06-05 08:56:22 +02:00
Iván Szabó 4c7d71a404 Blokkolás és frissítés is 2025-06-05 08:47:17 +02:00
ivanszabo 75d8119880 Ellenőrző lap mdosíthatósága 2025-06-05 08:12:27 +02:00
ivanszabo ff9d6ae361 Fontos kezelési javítások 2025-06-04 12:25:04 +02:00
ivanszabo 6839fc0b78 Hibajavítás hegyek 2025-06-04 11:05:29 +02:00
ivanszabo 11aea1eb5d git change 2025-06-04 09:13:52 +02:00
ivanszabo fb58bfcde0 PDF javítása 2025-05-23 21:20:05 +02:00
ivanszabo 7be3a5c58a console.log kivétele 2025-05-23 20:42:42 +02:00
ivanszabo d3e63404a2 Jóváhagyás utáni automatikus mail + CheckListHeader ShortName és Description javítása 2025-05-23 20:41:44 +02:00
ivanszabo cd0b1da85b v1.1.025 release kiadása 2025-05-23 10:51:44 +02:00
ivanszabo dc12fe8709 v1.1.025 MOBILE 2025-05-23 10:51:31 +02:00
ivanszabo 92dcb645db Merge branch 'master' of https://tfs.nuvolar.hu:8443/tfs/AtomERP/_git/WorkFlowCheck 2025-05-23 10:50:22 +02:00
ivanszabo 0d83e30cd2 Lezárás javítása 2025-05-23 10:50:13 +02:00
ivanszabo 2318269f99 Manuális lezárás indokkal 2025-05-23 10:49:02 +02:00
ivanszabo 84f161585a Merge branch 'master' of https://tfs.nuvolar.hu:8443/tfs/AtomERP/_git/WorkFlowCheck 2025-05-22 21:02:14 +02:00
ivanszabo 05259a09ee CheckListInfoPage implementálása 2025-05-22 21:02:09 +02:00
ivanszabo 98442dfe90 PDF javítása + %-os készültség javítása 2025-05-22 21:01:27 +02:00
ivanszabo e745f313a8 Megfelelő hang lejátszása is javítva 2025-05-16 08:40:51 +02:00
ivanszabo 254ab86d03 Egy pici javítás 2025-05-16 08:40:33 +02:00
ivanszabo 4c25dd2105 FCM kifejlesztése 2025-05-16 07:45:58 +02:00
ivanszabo da92dc45b6 Firebase FCM kliens működik 2025-05-16 07:27:02 +02:00
ivanszabo e8f7ee7e36 Merge branch 'master' of https://tfs.nuvolar.hu:8443/tfs/AtomERP/_git/WorkFlowCheck 2025-05-15 14:45:51 +02:00
ivanszabo b6ffcca996 Firebird Cloud Message API előkészítése 2025-05-15 14:41:34 +02:00
ivanszabo 0a36544dce Klónozás javítása 2025-05-08 11:01:55 +02:00
ivanszabo 699110af10 Privacy kialakítása 2025-05-07 13:25:27 +02:00
ivanszabo 272bd1a3fd CheckListTemplateHeader klónozása 2025-05-07 13:05:28 +02:00
119 changed files with 3768 additions and 485 deletions
+2
View File
@@ -342,3 +342,5 @@ healthchecksdb
/src/WorkFlowCheck.API/Images /src/WorkFlowCheck.API/Images
*.pdf *.pdf
/src/WorkFlowCheck.API/Pdf/c86f3a6a-c646-4627-823c-7e24134b7725.docx /src/WorkFlowCheck.API/Pdf/c86f3a6a-c646-4627-823c-7e24134b7725.docx
/src/WorkFlowCheck.API/Downloads/APK/com.nuvolar.wfcapp-Signed.apk
/src/WorkFlowCheck.API/Pdf/3b9fd83a-dce8-4427-813b-9475726700be.docx
+2 -2
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 18
VisualStudioVersion = 17.12.35527.113 VisualStudioVersion = 18.2.11408.102 d18.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowCheck.API", "WorkFlowCheck.API\WorkFlowCheck.API.csproj", "{2466E04A-CB0C-4421-9074-A928F819926C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowCheck.API", "WorkFlowCheck.API\WorkFlowCheck.API.csproj", "{2466E04A-CB0C-4421-9074-A928F819926C}"
EndProject EndProject
@@ -2,6 +2,7 @@
using Serilog; using Serilog;
using WorkFlowCheck.BL.Services; using WorkFlowCheck.BL.Services;
using WorkFlowCheck.BL.Services.Interfaces; using WorkFlowCheck.BL.Services.Interfaces;
using WorkFlowCheck.Common.DataTables;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
namespace WorkFlowCheck.API.Controllers namespace WorkFlowCheck.API.Controllers
@@ -39,6 +40,28 @@ namespace WorkFlowCheck.API.Controllers
return retVal; return retVal;
} }
[HttpPost("GetFilteredCheckListHeader")]
public async Task<ApiResponseListDTO<List<CheckListHeaderDTO>>> GetFilteredCheckListHeader([FromBody] DataTablesRequest dataTablesRequest)
{
var retVal = new ApiResponseListDTO<List<CheckListHeaderDTO>>()
{
IsSuccess = true
};
try
{
var result = await _checkListService.GetFilteredCheckListHeaderAsync(dataTablesRequest);
retVal.Data = result.Data;
retVal.Total = result.Total;
retVal.Filtered = result.Filtered;
}
catch (Exception ex)
{
retVal.IsSuccess = false;
Log.Error(ex.Message);
}
return retVal;
}
[HttpGet("CreatePDF/{id}")] [HttpGet("CreatePDF/{id}")]
public async Task<ApiResponseDTO<byte[]>> CreatePDF(int id) public async Task<ApiResponseDTO<byte[]>> CreatePDF(int id)
{ {
@@ -63,14 +86,14 @@ namespace WorkFlowCheck.API.Controllers
return retVal; return retVal;
} }
[HttpGet("GetAllCheckListHeaders")] [HttpGet("GetAllCheckListHeaders/{mode}")]
public async Task<ApiResponseDTO<List<CheckListHeaderDTO>>> GetAllCheckListHeadersAsync() public async Task<ApiResponseDTO<List<CheckListHeaderDTO>>> GetAllCheckListHeadersAsync(int mode = 0)
{ {
var retVal = new ApiResponseDTO<List<CheckListHeaderDTO>>() var retVal = new ApiResponseDTO<List<CheckListHeaderDTO>>()
{ {
IsSuccess = true, IsSuccess = true,
}; };
var checkPointListDTO = await _checkListService.GetAllCheckListHeaderAsync(); var checkPointListDTO = await _checkListService.GetAllCheckListHeaderAsync(mode);
if (checkPointListDTO != null) if (checkPointListDTO != null)
{ {
@@ -139,6 +162,7 @@ namespace WorkFlowCheck.API.Controllers
{ {
var result = await _checkListService.CloseCheckListHeader(checkListHeaderCloseDTO); var result = await _checkListService.CloseCheckListHeader(checkListHeaderCloseDTO);
retVal.Data = result; retVal.Data = result;
retVal.IsSuccess = result;
} }
catch (Exception ex) catch (Exception ex)
@@ -301,6 +325,28 @@ namespace WorkFlowCheck.API.Controllers
return retVal; return retVal;
} }
[HttpGet("CloneCheckListTemplateHeader/{id}")]
public async Task<ApiResponseDTO<bool>> CloneCheckListTemplateHeader(int id)
{
var retVal = new ApiResponseDTO<bool>()
{
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}")] [HttpGet("GetCheckListTemplateRow/{id}")]
public async Task<ApiResponseDTO<CheckListTemplateRowDTO>> GetCheckListTemplateRow(int id) public async Task<ApiResponseDTO<CheckListTemplateRowDTO>> GetCheckListTemplateRow(int id)
@@ -0,0 +1,83 @@
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<ApiResponseDTO<bool>> SendFCMMessage([FromBody] FCMMessageDTO fCMMessageDTO)
{
var retVal = new ApiResponseDTO<bool>()
{
IsSuccess = true
};
try
{
retVal.IsSuccess = await _messageService.SendFCMMessage(fCMMessageDTO);
}
catch (Exception ex)
{
retVal.IsSuccess = false;
Log.Error(ex.Message);
}
return retVal;
}
[HttpPost("SendFCMMessageToLastToken")]
public async Task<ApiResponseDTO<bool>> SendFCMMessageToLastToken([FromBody] FCMMessageDTO fCMMessageDTO)
{
var retVal = new ApiResponseDTO<bool>()
{
IsSuccess = true
};
try
{
retVal.IsSuccess = await _messageService.SendFCMMessageToLastToken(fCMMessageDTO);
}
catch (Exception ex)
{
retVal.IsSuccess = false;
Log.Error(ex.Message);
}
return retVal;
}
[HttpPost("SendFCMToken")]
public async Task<ApiResponseDTO<bool>> SendFCMToken([FromBody] FCMMessageDTO fCMMessageDTO)
{
var retVal = new ApiResponseDTO<bool>()
{
IsSuccess = true
};
try
{
await _messageService.SendFCMTokenAsync(fCMMessageDTO.Token);
}
catch (Exception ex)
{
retVal.IsSuccess = false;
Log.Error(ex.Message);
}
return retVal;
}
}
}
Binary file not shown.
@@ -17,6 +17,16 @@
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
},
"WSL": {
"commandName": "WSL2",
"launchBrowser": true,
"launchUrl": "https://localhost:5069/swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "https://localhost:5069"
},
"distributionName": ""
} }
}, },
"$schema": "http://json.schemastore.org/launchsettings.json", "$schema": "http://json.schemastore.org/launchsettings.json",
@@ -10,6 +10,7 @@
<InvariantGlobalization>false</InvariantGlobalization> <InvariantGlobalization>false</InvariantGlobalization>
<PublishAot>false</PublishAot> <PublishAot>false</PublishAot>
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled> <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
<UserSecretsId>4081cb25-5ca2-40a1-a788-0d8396b4f50e</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\WorkFlowCheck.BL\WorkFlowCheck.BL.csproj" /> <ProjectReference Include="..\WorkFlowCheck.BL\WorkFlowCheck.BL.csproj" />
@@ -17,6 +18,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Apis.Auth" Version="1.69.0" />
<PackageReference Include="MailKit" Version="4.11.0" /> <PackageReference Include="MailKit" Version="4.11.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.11" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
@@ -1,11 +1,20 @@
{ {
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Data Source=WS2016DC\\SQLEXPRESS;Initial Catalog=WFC;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False" //"DefaultConnection": "Data Source=NSINB-37\\WFC;Initial Catalog=WFC;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
//"DefaultConnection": "Data Source=WS2016DC\\SQLEXPRESS;Initial Catalog=WFC;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False",
"DefaultConnection": "Data Source=WS2016DC\\SQLEXPRESS;Initial Catalog=WFCUAT;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
}, },
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:59027"
}
}
} }
} }
@@ -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"
}
+14 -2
View File
@@ -1,2 +1,14 @@
dotnet publish -c Release -o e:\wfcapi\ @echo off
pause
REM ha van paraméter, azt használjuk, különben default
set PUBLISH_DIR=%1
if "%PUBLISH_DIR%"=="" (
set PUBLISH_DIR=c:\Publish\wfcapi
)
echo Publish to: %PUBLISH_DIR%
dotnet publish -c Release -o "%PUBLISH_DIR%"
pause
@@ -41,7 +41,12 @@ namespace WorkFlowCheck.BL.DocumentGenerator
// LibreOffice parancssori konverzió // LibreOffice parancssori konverzió
ProcessStartInfo startInfo = new ProcessStartInfo ProcessStartInfo startInfo = new ProcessStartInfo
{ {
#if !DEBUG
FileName = "e:\\LibreOffice\\program\\soffice", // LibreOffice parancs FileName = "e:\\LibreOffice\\program\\soffice", // LibreOffice parancs
#else
//FileName = "c:\\Program Files\\LibreOffice\\program\\soffice", // LibreOffice parancs
FileName = "e:\\LibreOffice\\program\\soffice", // LibreOffice parancs
#endif
Arguments = $"--headless --convert-to pdf \"{tempWordPath}\" --outdir \"{pdfDirectory}", Arguments = $"--headless --convert-to pdf \"{tempWordPath}\" --outdir \"{pdfDirectory}",
RedirectStandardOutput = true, RedirectStandardOutput = true,
UseShellExecute = false, UseShellExecute = false,
@@ -169,8 +174,6 @@ namespace WorkFlowCheck.BL.DocumentGenerator
body.Append(new Paragraph(new Run(new Break() { Type = BreakValues.Page }))); body.Append(new Paragraph(new Run(new Break() { Type = BreakValues.Page })));
body.Append(table); body.Append(table);
} }
private static Drawing CreateImageDrawing(string relationshipId, long width, long height) private static Drawing CreateImageDrawing(string relationshipId, long width, long height)
{ {
return new Drawing( return new Drawing(
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<title>Értesítés jóváhagyásról</title>
</head>
<body style="font-family: Arial, sans-serif; background-color: #f9f9f9; padding: 20px;">
<p style="font-size: 18px;">
A következő munkafolyamat jóvá lett hagyva:
</p>
<p style="font-size: 28px; font-weight: bold; color: #333; margin-top: 10px;">
#DocumentNumber#
</p>
</body>
</html>
+206 -19
View File
@@ -15,6 +15,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WorkFlowCheck.BL.DocumentGenerator; using WorkFlowCheck.BL.DocumentGenerator;
using WorkFlowCheck.BL.Services.Interfaces; using WorkFlowCheck.BL.Services.Interfaces;
using WorkFlowCheck.Common.DataTables;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.Common.Enums; using WorkFlowCheck.Common.Enums;
using WorkFlowCheck.DL; using WorkFlowCheck.DL;
@@ -24,15 +25,18 @@ namespace WorkFlowCheck.BL.Services
{ {
public class CheckListService : BaseService, ICheckListService public class CheckListService : BaseService, ICheckListService
{ {
private readonly INumberGeneratorService _numberGeneratorService; private readonly INumberGeneratorService _numberGeneratorService;
private readonly IMessageService _messageService;
public CheckListService(AppDbContext dbContext, public CheckListService(AppDbContext dbContext,
IMapper mapper, IMapper mapper,
INumberGeneratorService numberGeneratorService, INumberGeneratorService numberGeneratorService,
IMessageService messageService,
IUserService userService) : base(dbContext, mapper) IUserService userService) : base(dbContext, mapper)
{ {
_numberGeneratorService = numberGeneratorService; _numberGeneratorService = numberGeneratorService;
_messageService = messageService;
} }
public async Task<CheckListHeaderDTO> GetCheckListHeaderAsync(int Id) public async Task<CheckListHeaderDTO> GetCheckListHeaderAsync(int Id)
@@ -78,21 +82,103 @@ namespace WorkFlowCheck.BL.Services
return retVal; return retVal;
} }
public async Task<List<CheckListHeaderDTO>> GetAllCheckListHeaderAsync() public async Task<ApiResponseListDTO<List<CheckListHeaderDTO>>> GetFilteredCheckListHeaderAsync(DataTablesRequest req)
{
var retVal = new ApiResponseListDTO<List<CheckListHeaderDTO>>();
try
{
var baseQuery = _dbContext.CheckListHeaders
.AsNoTracking()
.Where(x => !x.IsDeleted);
// MODE szűrés (csak WHERE, ORDER BY nélkül)
IQueryable<CheckListHeader> modeQuery = req.Mode switch
{
0 => baseQuery.Where(w => w.CheckStatus == CheckStatus.InProgress || w.CheckStatus == CheckStatus.Open),
1 => baseQuery.Where(w => w.CheckStatus == CheckStatus.Sent),
2 => baseQuery.Where(w => w.CheckStatus == CheckStatus.Closed),
3 => baseQuery.Where(w => w.CheckStatus == CheckStatus.Signed),
_ => baseQuery
};
// Total = mode szűrés után, keresés előtt
retVal.Total = await modeQuery.CountAsync();
// Search
var search = req.Search?.Value?.Trim();
IQueryable<CheckListHeader> filteredQuery = modeQuery;
if (!string.IsNullOrWhiteSpace(search))
{
filteredQuery = filteredQuery.Where(x =>
x.DocumentNumber.Contains(search) ||
(x.ShortName != null && x.ShortName.Contains(search)) ||
(x.Description != null && x.Description.Contains(search)) ||
(x.CreatedBy != null && x.CreatedBy.Contains(search)) ||
(x.AcceptUser != null && x.AcceptUser.UserName.Contains(search))
);
}
retVal.Filtered = await filteredQuery.CountAsync();
// Ordering (itt már jöhet)
filteredQuery = filteredQuery.OrderByDescending(o => o.CreatedAt);
// Paging
var list = await filteredQuery
.Include(x => x.CheckListRows)
.Include(x => x.User)
.Include(x => x.AcceptUser)
.AsSplitQuery()
.Skip(req.Start)
.Take(req.Length)
.ToListAsync();
retVal.Data = _mapper.Map<List<CheckListHeaderDTO>>(list);
}
catch (Exception ex)
{
Log.Error(ex, "GetFilteredCheckListHeaderAsync failed");
}
return retVal;
}
public async Task<List<CheckListHeaderDTO>> GetAllCheckListHeaderAsync(int mode = 0)
{ {
var retVal = new List<CheckListHeaderDTO>(); var retVal = new List<CheckListHeaderDTO>();
try try
{ {
var checkListHeaders = await _dbContext.CheckListHeaders IQueryable<CheckListHeader> query = _dbContext.CheckListHeaders
.Include(i => i.CheckListRows) .Include(i => i.CheckListRows)
.Include(i => i.User) .Include(i => i.User)
.Include(i => i.AcceptUser) .Include(i => i.AcceptUser)
.AsNoTracking() .AsNoTracking();
.ToListAsync(); switch (mode)
if (checkListHeaders != null)
{ {
retVal = _mapper.Map<List<CheckListHeaderDTO>>(checkListHeaders); case 0:
query = query.Where(w => w.CheckStatus == CheckStatus.InProgress || w.CheckStatus == CheckStatus.Open).OrderByDescending(o => o.CreatedAt);
break;
case 1:
query = query.Where(w => w.CheckStatus == CheckStatus.Sent).OrderByDescending(o => o.CreatedAt);
break;
case 2:
query = query.Where(w => w.CheckStatus == CheckStatus.Closed).OrderByDescending(o => o.CreatedAt);
break;
case 3:
query = query.Where(w => w.CheckStatus == CheckStatus.Signed).OrderByDescending(o => o.CreatedAt);
break;
default:
query = query.OrderByDescending(o => o.CreatedAt);
break;
} }
var list = await query.ToListAsync();
retVal = _mapper.Map<List<CheckListHeaderDTO>>(list);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -111,6 +197,7 @@ namespace WorkFlowCheck.BL.Services
{ {
CheckListTemplateHeaderId = checkListHeaderDTO.CheckListTemplateHeaderDTO.Id, CheckListTemplateHeaderId = checkListHeaderDTO.CheckListTemplateHeaderDTO.Id,
Description = checkListHeaderDTO.Description, Description = checkListHeaderDTO.Description,
ShortName = checkListHeaderDTO.ShortName,
GuidNumber = Guid.NewGuid(), GuidNumber = Guid.NewGuid(),
}; };
_dbContext.CheckListHeaders.Add(checkListHeader); _dbContext.CheckListHeaders.Add(checkListHeader);
@@ -126,7 +213,7 @@ namespace WorkFlowCheck.BL.Services
if (checkListHeader != null) if (checkListHeader != null)
{ {
checkListHeader.Description = checkListHeaderDTO.Description; checkListHeader.Description = checkListHeaderDTO.Description;
checkListHeader.ShortName = checkListHeaderDTO.ShortName;
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
retVal = _mapper.Map<CheckListHeaderDTO>(checkListHeader); retVal = _mapper.Map<CheckListHeaderDTO>(checkListHeader);
@@ -166,7 +253,7 @@ namespace WorkFlowCheck.BL.Services
IsEditable = true, IsEditable = true,
UserId = checkListHeaderNewDTO.UserId, UserId = checkListHeaderNewDTO.UserId,
ShortName = "", ShortName = "",
Description = "", Description = checkListTemplateHeader.Description ?? "",
DocumentNumber = documentNumber, DocumentNumber = documentNumber,
GuidNumber = Guid.NewGuid(), GuidNumber = Guid.NewGuid(),
IsDeleted = false, IsDeleted = false,
@@ -214,16 +301,24 @@ namespace WorkFlowCheck.BL.Services
try try
{ {
var user = await _dbContext.Users
.Where(w => w.Id == userid)
.FirstOrDefaultAsync();
if (user == null) return false;
var checkListHeader = await _dbContext.CheckListHeaders var checkListHeader = await _dbContext.CheckListHeaders
.Where(w => w.Id == id && w.CheckStatus == CheckStatus.Sent) .Where(w => w.Id == id && w.CheckStatus == CheckStatus.Sent)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
if (checkListHeader != null) if (checkListHeader != null)
{ {
checkListHeader.CheckStatus = CheckStatus.Signed; checkListHeader.CheckStatus = CheckStatus.Signed;
checkListHeader.IsEditable = false; checkListHeader.IsEditable = false;
checkListHeader.AcceptUserId = userid; checkListHeader.AcceptUserId = userid;
Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap státuszváltozása, jóváhasyás: Ellenőrzés:{id}, Felhasználó:{userid}");
checkListHeader.DateExecution = DateTime.Now;
Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap státuszváltozása, jóváhagyás: Ellenőrzés:{checkListHeader.DocumentNumber}, Felhasználó: {user.LastName} {user.FirstName}");
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
var pdf = await CreateCheckListHeaderPDFAsync(id); var pdf = await CreateCheckListHeaderPDFAsync(id);
@@ -236,17 +331,60 @@ namespace WorkFlowCheck.BL.Services
var filePath = Path.Combine(pdfDirectory, fileName); var filePath = Path.Combine(pdfDirectory, fileName);
await File.WriteAllBytesAsync(filePath, pdf); await File.WriteAllBytesAsync(filePath, pdf);
await SendMailToAcceptedUser(filePath, checkListHeader, userid);
retVal = true; retVal = true;
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
retVal = false;
Log.Error(ex.Message); Log.Error(ex.Message);
} }
return retVal; return retVal;
} }
private async Task SendMailToAcceptedUser(string filePath, CheckListHeader checkListHeader, int userId)
{
try
{
var user = _dbContext.Users.Where(W => W.Id == userId).FirstOrDefault();
if (user != null)
{
if (!string.IsNullOrEmpty(user.Email))
{
var recepients = new List<string>()
{
user.Email,
};
await _messageService.SendMailAsync(recepients,
$"Értesítés folyamat jóváhagyásáról {checkListHeader.DocumentNumber}",
GetAcceptCheckListHeaderMessageBody(checkListHeader),
filePath);
}
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
}
private string GetAcceptCheckListHeaderMessageBody(CheckListHeader checkListHeader)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "WorkFlowCheck.BL.HtmlTemplates.AcceptCheckListHeaderBody.html";
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
throw new FileNotFoundException($"Nem található a beágyazott erőforrás: {resourceName}");
using var reader = new StreamReader(stream);
var html = reader.ReadToEnd();
return html.Replace("#DocumentNumber#", checkListHeader.DocumentNumber);
}
public async Task<byte[]> CreateCheckListHeaderPDFAsync(int checkListHeaderId) public async Task<byte[]> CreateCheckListHeaderPDFAsync(int checkListHeaderId)
{ {
try try
@@ -258,8 +396,10 @@ namespace WorkFlowCheck.BL.Services
byte[] byteArray = File.ReadAllBytes(Path.Combine(pdfDirectory, "CheckList_Template_V1.docx")); byte[] byteArray = File.ReadAllBytes(Path.Combine(pdfDirectory, "CheckList_Template_V1.docx"));
SablonGenerator gen = new SablonGenerator(byteArray); SablonGenerator gen = new SablonGenerator(byteArray);
gen.SimpleReplace("#description#", checkListHeader.Description);
gen.SimpleReplace("#DocumentNumber#", checkListHeader.DocumentNumber); gen.SimpleReplace("#DocumentNumber#", checkListHeader.DocumentNumber);
gen.SimpleReplace("#DateExecution#", checkListHeader.DateExecution.ToString("yyyy.MM.dd HH:mm")); gen.SimpleReplace("#DateExecution#", checkListHeader.DateExecution.ToString("yyyy.MM.dd HH:mm"));
gen.SimpleReplace("#WorkUser#", $"{checkListHeader.UserDTO?.LastName} {checkListHeader.UserDTO?.FirstName}"); gen.SimpleReplace("#WorkUser#", $"{checkListHeader.UserDTO?.LastName} {checkListHeader.UserDTO?.FirstName}");
gen.SimpleReplace("#AcceptUser#", $"{checkListHeader.AcceptUserDTO?.LastName} {checkListHeader.AcceptUserDTO?.FirstName}"); gen.SimpleReplace("#AcceptUser#", $"{checkListHeader.AcceptUserDTO?.LastName} {checkListHeader.AcceptUserDTO?.FirstName}");
gen.SimpleReplace("#Guid#", checkListHeader.GuidNumber.ToString()); gen.SimpleReplace("#Guid#", checkListHeader.GuidNumber.ToString());
@@ -377,7 +517,7 @@ namespace WorkFlowCheck.BL.Services
{ {
checkListHeader.CheckStatus = CheckStatus.Closed; checkListHeader.CheckStatus = CheckStatus.Closed;
checkListHeader.IsEditable = false; 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}, " + Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap lezárva: Ellenőrzés:{closeCheckListHeaderCloseDTO.Id}, " +
$"Felhasználó:{closeCheckListHeaderCloseDTO.UserId}, " + $"Felhasználó:{closeCheckListHeaderCloseDTO.UserId}, " +
@@ -394,7 +534,7 @@ namespace WorkFlowCheck.BL.Services
} }
return retVal; return retVal;
} }
public async Task<CheckListTemplateHeaderDTO> GetCheckListTemplateHeaderAsync(int Id) public async Task<CheckListTemplateHeaderDTO> GetCheckListTemplateHeaderAsync(int Id)
{ {
var retVal = new CheckListTemplateHeaderDTO() var retVal = new CheckListTemplateHeaderDTO()
@@ -491,7 +631,54 @@ namespace WorkFlowCheck.BL.Services
} }
public async Task<bool> DeleteCheckListTemplateHeaderAsync(int id) public async Task<bool> DeleteCheckListTemplateHeaderAsync(int id)
{ {
return await DeleteEntityByIdAsync<CheckListTemplateHeader>(id); return await DeleteEntityByIdAsync<CheckListTemplateHeader>(id);
}
public async Task<bool> CloneCheckListTemplateHeaderAsync(int id)
{
var retVal = false;
try
{
var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders
.AsNoTracking()
.Include(i => i.CheckListTemplateRows)
.Where(w => w.Id == id).FirstOrDefaultAsync();
if (checkListTemplateHeader != null)
{
var newCheckListTemplateHeader = new CheckListTemplateHeader()
{
CheckListTemplateRows = new List<CheckListTemplateRow>(),
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<CheckListTemplateRowDTO> GetCheckListTemplateRowAsync(int id) public async Task<CheckListTemplateRowDTO> GetCheckListTemplateRowAsync(int id)
{ {
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using WorkFlowCheck.Common.DataTables;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
namespace WorkFlowCheck.BL.Services.Interfaces namespace WorkFlowCheck.BL.Services.Interfaces
@@ -6,12 +7,13 @@ namespace WorkFlowCheck.BL.Services.Interfaces
public interface ICheckListService public interface ICheckListService
{ {
Task<CheckListHeaderDTO> GetCheckListHeaderAsync(int Id); Task<CheckListHeaderDTO> GetCheckListHeaderAsync(int Id);
Task<List<CheckListHeaderDTO>> GetAllCheckListHeaderAsync(); Task<ApiResponseListDTO<List<CheckListHeaderDTO>>> GetFilteredCheckListHeaderAsync(DataTablesRequest dataTablesRequest);
Task<List<CheckListHeaderDTO>> GetAllCheckListHeaderAsync(int mode = 0);
Task<CheckListHeaderDTO> UpdateCheckListHeaderAsync(CheckListHeaderDTO checkListHeaderDTO); Task<CheckListHeaderDTO> UpdateCheckListHeaderAsync(CheckListHeaderDTO checkListHeaderDTO);
Task<bool> AcceptCheckListHeaderAsync(int id, int userid); Task<bool> AcceptCheckListHeaderAsync(int id, int userid);
Task<bool> BlockCheckListHeaderAsync(int id, int userid); Task<bool> BlockCheckListHeaderAsync(int id, int userid);
Task<bool> UnBlockCheckListHeaderAsync(int id, int userid); Task<bool> UnBlockCheckListHeaderAsync(int id, int userid);
Task<bool> CloseCheckListHeader(CheckListHeaderCloseDTO closeCheckListHeaderCloseDTO); Task<bool> CloseCheckListHeader(CheckListHeaderCloseDTO closeCheckListHeaderCloseDTO);
Task<byte[]> CreateCheckListHeaderPDFAsync(int checkListHeaderId); Task<byte[]> CreateCheckListHeaderPDFAsync(int checkListHeaderId);
Task<CheckListHeaderDTO> StartNewCheckListAsync(CheckListHeaderNewDTO checkListHeaderNewDTO); Task<CheckListHeaderDTO> StartNewCheckListAsync(CheckListHeaderNewDTO checkListHeaderNewDTO);
@@ -20,14 +22,15 @@ namespace WorkFlowCheck.BL.Services.Interfaces
Task<List<CheckListTemplateHeaderDTO>> GetAllCheckListTemplateHeaderAsync(); Task<List<CheckListTemplateHeaderDTO>> GetAllCheckListTemplateHeaderAsync();
Task<CheckListTemplateHeaderDTO> UpdateCheckListTemplateHeaderAsync(CheckListTemplateHeaderDTO checkListTemplateHeaderDTO); Task<CheckListTemplateHeaderDTO> UpdateCheckListTemplateHeaderAsync(CheckListTemplateHeaderDTO checkListTemplateHeaderDTO);
Task<bool> DeleteCheckListTemplateHeaderAsync(int id); Task<bool> DeleteCheckListTemplateHeaderAsync(int id);
Task<bool> CloneCheckListTemplateHeaderAsync(int id);
Task<CheckListTemplateRowDTO> GetCheckListTemplateRowAsync(int id); Task<CheckListTemplateRowDTO> GetCheckListTemplateRowAsync(int id);
Task<bool> DeleteCheckListTemplateRowAsync(int id); Task<bool> DeleteCheckListTemplateRowAsync(int id);
Task<CheckListTemplateRowDTO> UpdateCheckListTemplateRowAsync(CheckListTemplateRowDTO checkListTemplateRowDTO); Task<CheckListTemplateRowDTO> UpdateCheckListTemplateRowAsync(CheckListTemplateRowDTO checkListTemplateRowDTO);
Task<CheckListRowDTO> GetCheckListRowAsync(int id); Task<CheckListRowDTO> GetCheckListRowAsync(int id);
Task<CheckListRowDTO> UpdateCheckListRowAsync(CheckListRowDTO checkListRowDTO); Task<CheckListRowDTO> UpdateCheckListRowAsync(CheckListRowDTO checkListRowDTO);
} }
@@ -3,11 +3,17 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WorkFlowCheck.Common.DTO;
namespace WorkFlowCheck.BL.Services.Interfaces namespace WorkFlowCheck.BL.Services.Interfaces
{ {
public interface IMessageService public interface IMessageService
{ {
Task<bool> SendMailAsync(List<string> recipients, string subject, string htmlBody); Task<bool> SendMailAsync(List<string> recipients, string subject, string htmlBody, string? attachmentFilePath = null);
Task<bool> SendFCMTokenAsync(string token);
Task<string> GetLastFCMTokensAsync();
Task<bool> SendFCMMessage(FCMMessageDTO fCMMessageDTO);
Task<bool> SendFCMMessageToLastToken(FCMMessageDTO fCMMessageDTO);
} }
} }
+180 -10
View File
@@ -4,19 +4,31 @@ using MimeKit;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using WorkFlowCheck.BL.Models; using WorkFlowCheck.BL.Models;
using WorkFlowCheck.BL.Services.Interfaces; using WorkFlowCheck.BL.Services.Interfaces;
using Serilog;
using WorkFlowCheck.DL.Entities;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using WorkFlowCheck.DL;
using WorkFlowCheck.Common.DTO;
using System.Net.Http.Headers;
using System.Text;
using Google.Apis.Auth.OAuth2;
using Newtonsoft.Json;
namespace WorkFlowCheck.BL.Services namespace WorkFlowCheck.BL.Services
{ {
public class MessageService : IMessageService public class MessageService : BaseService, IMessageService
{ {
private readonly EmailSettings _settings; private readonly EmailSettings _settings;
public MessageService(IConfiguration configuration) public MessageService(AppDbContext dbContext,
IMapper mapper,
IConfiguration configuration) : base(dbContext, mapper)
{ {
_settings = configuration.GetSection("EmailSettings").Get<EmailSettings>()!; _settings = configuration.GetSection("EmailSettings").Get<EmailSettings>()!;
} }
public async Task<bool> SendMailAsync(List<string> recipients, string subject, string htmlBody) public async Task<bool> SendMailAsync(List<string> recipients, string subject, string htmlBody, string? attachmentFilePath = null)
{ {
var message = new MimeMessage(); var message = new MimeMessage();
message.From.Add(new MailboxAddress(_settings.SenderName, _settings.Username)); message.From.Add(new MailboxAddress(_settings.SenderName, _settings.Username));
@@ -28,19 +40,177 @@ namespace WorkFlowCheck.BL.Services
message.Subject = subject; message.Subject = subject;
message.Body = new TextPart("html") var builder = new BodyBuilder
{ {
Text = htmlBody HtmlBody = htmlBody
}; };
using var smtp = new SmtpClient(); if (!string.IsNullOrEmpty(attachmentFilePath) && File.Exists(attachmentFilePath))
await smtp.ConnectAsync(_settings.SmtpServer, _settings.SmtpPort, SecureSocketOptions.StartTls); {
await smtp.AuthenticateAsync(_settings.Username, _settings.Password); builder.Attachments.Add(attachmentFilePath);
await smtp.SendAsync(message); }
await smtp.DisconnectAsync(true);
message.Body = builder.ToMessageBody();
const int maxRetries = 10;
const int delayMs = 2000;
bool authenticated = false;
Exception lastException = null;
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
using var smtp = new SmtpClient();
await smtp.ConnectAsync(_settings.SmtpServer, _settings.SmtpPort, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync(_settings.Username, _settings.Password);
await smtp.SendAsync(message);
await smtp.DisconnectAsync(true);
authenticated = true;
break; // 🎯 siker
}
catch (Exception ex)
{
lastException = ex;
Log.ForContext("TAG", "BusinessFlow").Error(lastException?.Message ?? "E-mail küldése sikertelen!");
if (attempt == maxRetries)
break;
// ⏳ várunk 1 másodpercet és újrapróbáljuk
await Task.Delay(delayMs);
}
}
if (!authenticated)
{
// 🔴 IDE ÍRHATSZ MAJD SAJÁT LOGIKÁT
Log.ForContext("TAG", "BusinessFlow").Error(lastException?.Message ?? "E-mail küldése sikertelen!");
}
return true; return true;
} }
public async Task<bool> SendFCMTokenAsync(string token)
{
var retVal = true;
try
{
if (!string.IsNullOrEmpty(token))
{
var FCMToken = await _dbContext.FCMTokens.Where(w => w.Token == token).FirstOrDefaultAsync();
if (FCMToken == null)
{
FCMToken = new FCMToken();
FCMToken.Token = token;
await _dbContext.FCMTokens.AddAsync(FCMToken);
}
else
{
FCMToken.LastModAt = DateTime.UtcNow;
}
await _dbContext.SaveChangesAsync();
}
}
catch (Exception ex)
{
retVal = false;
Log.ForContext("TAG", "BusinessFlow").Error(ex.Message);
}
return retVal;
}
public async Task<string> GetLastFCMTokensAsync()
{
var retVal = "";
try
{
var FCMToken = await _dbContext.FCMTokens
.AsNoTracking()
.OrderByDescending(x => x.LastModAt)
.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;
}
public async Task<bool> SendFCMMessage(FCMMessageDTO fCMMessageDTO)
{
var retVal = 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,
},
android = new
{
notification = new
{
channel_id = "com.nuvolar.wfcapp.general"
}
}
}
};
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 = false;
Log.Error(ex.Message);
}
return retVal;
}
public async Task<bool> SendFCMMessageToLastToken(FCMMessageDTO fCMMessageDTO)
{
var retVal = true;
try
{
fCMMessageDTO.Token = await GetLastFCMTokensAsync();
retVal = await SendFCMMessage(fCMMessageDTO);
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
return retVal;
}
} }
} }
+52 -36
View File
@@ -19,15 +19,17 @@ namespace WorkFlowCheck.BL.Services
{ {
private readonly IRequestContext _requestContext; private readonly IRequestContext _requestContext;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly IMessageService _messageService;
public SyncService(AppDbContext dbContext, public SyncService(AppDbContext dbContext,
IMapper mapper, IMapper mapper,
IRequestContext requestContext, IRequestContext requestContext,
IMessageService messageService,
IUserService userService) : base(dbContext, mapper) IUserService userService) : base(dbContext, mapper)
{ {
_requestContext = requestContext; _requestContext = requestContext;
_userService = userService; _userService = userService;
_messageService = messageService;
} }
public async Task<List<CheckPointDTO>> GetAllCheckPointAsync() public async Task<List<CheckPointDTO>> GetAllCheckPointAsync()
@@ -210,8 +212,7 @@ namespace WorkFlowCheck.BL.Services
var res = await _dbContext.Locations.Where(w => w.Id == LocationDTO.Id).FirstOrDefaultAsync(); var res = await _dbContext.Locations.Where(w => w.Id == LocationDTO.Id).FirstOrDefaultAsync();
if (res != null) if (res != null)
{ {
res = _mapper.Map<DL.Entities.Location>(LocationDTO); res.FullName = LocationDTO.FullName;
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
retVal = _mapper.Map<LocationDTO>(res); retVal = _mapper.Map<LocationDTO>(res);
@@ -347,9 +348,10 @@ namespace WorkFlowCheck.BL.Services
try try
{ {
var res = await _dbContext.CheckListHeaders var res = await _dbContext.CheckListHeaders
.Where(w => (w.IsEditable && .Where(w => w.CheckStatus == CheckStatus.Open ||
w.IsDeleted != true) || (w.CheckStatus == CheckStatus.Blocked) w.CheckStatus == CheckStatus.InProgress ||
) w.CheckStatus == CheckStatus.Blocked ||
w.CheckStatus == CheckStatus.Sent)
.Include(i => i.CheckListRows) .Include(i => i.CheckListRows)
//.ThenInclude(i => i.CheckListTemplateRow) //.ThenInclude(i => i.CheckListTemplateRow)
.AsNoTracking() .AsNoTracking()
@@ -383,35 +385,6 @@ namespace WorkFlowCheck.BL.Services
if (res != null && (res.CheckStatus == CheckStatus.Open || if (res != null && (res.CheckStatus == CheckStatus.Open ||
res.CheckStatus == CheckStatus.InProgress)) res.CheckStatus == CheckStatus.InProgress))
{ {
if (NeedBlocking(checkListHeaderDTO))
{
/// TODO: blokkolás miatt
res.CheckStatus = CheckStatus.Blocked;
await _dbContext.SaveChangesAsync();
Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap blokkolva: Ellenőrzés:{checkListHeaderDTO.Id}, Felhasználó:{_requestContext.CurrentUsername}");
var user = await _userService.GetUserAsync(_requestContext.CurrentUserId ?? 1);
foreach (var item in user.RoleDTO)
{
var deviceMessageDTO = new DeviceMessageDTO()
{
IsReaded = false,
Message = "Ellenőrző lap blokkolva!",
SendDate = DateTime.UtcNow,
ExtraDataJSON = "",
RoleId = item.ParentId,
DeviceIdFrom = "",
DeviceIdTo = "",
};
await this.DeviceMessageSend(deviceMessageDTO);
}
return retVal;
}
res.CheckStatus = CheckStatus.InProgress;
var ids = checkListHeaderDTO.CheckListRowDTO?.Select(r => r.Id).ToList(); var ids = checkListHeaderDTO.CheckListRowDTO?.Select(r => r.Id).ToList();
if (ids != null && ids.Count > 0) if (ids != null && ids.Count > 0)
{ {
@@ -438,6 +411,47 @@ namespace WorkFlowCheck.BL.Services
} }
} }
} }
await _dbContext.SaveChangesAsync();
retVal = _mapper.Map<CheckListHeaderDTO>(res);
string Answer = "";
if (NeedBlocking(checkListHeaderDTO, out Answer))
{
/// TODO: blokkolás miatt
res.CheckStatus = CheckStatus.Blocked;
await _dbContext.SaveChangesAsync();
Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap blokkolva: Ellenőrzés:{checkListHeaderDTO.Id}, Felhasználó:{_requestContext.CurrentUsername}");
var user = await _userService.GetUserAsync(_requestContext.CurrentUserId ?? 1);
foreach (var item in user.RoleDTO)
{
var deviceMessageDTO = new DeviceMessageDTO()
{
IsReaded = false,
Message = $"Ellenőrző lap blokkolva! [{checkListHeaderDTO.DocumentNumber}]\n({Answer})",
SendDate = DateTime.UtcNow,
ExtraDataJSON = "",
RoleId = item.ParentId,
DeviceIdFrom = "",
DeviceIdTo = "",
};
await this.DeviceMessageSend(deviceMessageDTO);
var fCMMessageDTO = new FCMMessageDTO
{
Body = deviceMessageDTO.Message,
Title = "Blokkolási értesítés",
UserId = user.Id,
};
await _messageService.SendFCMMessageToLastToken(fCMMessageDTO);
}
return retVal;
}
res.CheckStatus = CheckStatus.InProgress;
if (CheckIfLastReached(checkListHeaderDTO)) if (CheckIfLastReached(checkListHeaderDTO))
{ {
/// TODO: most kell a CheckStatust állítani és menjen üzenet ! /// TODO: most kell a CheckStatust állítani és menjen üzenet !
@@ -460,9 +474,10 @@ namespace WorkFlowCheck.BL.Services
return retVal; return retVal;
} }
private bool NeedBlocking(CheckListHeaderDTO checkListHeaderDTO) private bool NeedBlocking(CheckListHeaderDTO checkListHeaderDTO, out string Answer)
{ {
var retVal = false; var retVal = false;
Answer = "";
if (checkListHeaderDTO.CheckListRowDTO != null && checkListHeaderDTO.CheckListRowDTO.Count > 0) if (checkListHeaderDTO.CheckListRowDTO != null && checkListHeaderDTO.CheckListRowDTO.Count > 0)
{ {
var checkListRows = checkListHeaderDTO.CheckListRowDTO; var checkListRows = checkListHeaderDTO.CheckListRowDTO;
@@ -472,6 +487,7 @@ namespace WorkFlowCheck.BL.Services
{ {
if (row.CheckListTemplateRowDTO != null) if (row.CheckListTemplateRowDTO != null)
{ {
Answer = row.CheckListTemplateRowDTO.OperationDescription;
if (row.CheckListTemplateRowDTO.AnswerType == "PI-N" && row.Answer == "Igen") if (row.CheckListTemplateRowDTO.AnswerType == "PI-N" && row.Answer == "Igen")
{ {
retVal = true; retVal = true;
+2 -2
View File
@@ -141,7 +141,7 @@ namespace WorkFlowCheck.BL.Services
var user = await _dbContext.Users var user = await _dbContext.Users
.Include(i => i.UserRoles) .Include(i => i.UserRoles)
.ThenInclude(i => i.Role) .ThenInclude(i => i.Role)
.Where(w => w.UserName == userName) .Where(w => w.UserName == userName && w.Active == true)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password)) if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password))
{ {
@@ -400,7 +400,7 @@ namespace WorkFlowCheck.BL.Services
user.Active = userDTO.Active; user.Active = userDTO.Active;
user.NFCActive = userDTO.NFCActive; user.NFCActive = userDTO.NFCActive;
user.NFCCode = userDTO.NFCCode; user.NFCCode = userDTO.NFCCode;
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
retVal = _mapper.Map<UserDTO>(user); retVal = _mapper.Map<UserDTO>(user);
@@ -11,12 +11,14 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="HtmlTemplates\AcceptCheckListHeaderBody.html" />
<EmbeddedResource Include="HtmlTemplates\Token2FBody.html" /> <EmbeddedResource Include="HtmlTemplates\Token2FBody.html" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" /> <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Google.Apis.Auth" Version="1.69.0" />
<PackageReference Include="MailKit" Version="4.11.0" /> <PackageReference Include="MailKit" Version="4.11.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Expressions" Version="5.0.0" /> <PackageReference Include="Serilog.Expressions" Version="5.0.0" />
@@ -35,9 +35,11 @@ namespace WorkFlowCheck.Common.DTO
{ {
public T Data { get; set; } public T Data { get; set; }
} }
public class ApiResponseListDTO<T> : ApiResponseBaseDTO public class ApiResponseListDTO<T> : ApiResponseBaseDTO
{ {
public T[] Data { get; set; } public T Data { get; set; }
public int Total { get; set; } public int Total { get; set; }
public int Filtered { get; set; }
} }
} }
@@ -19,8 +19,10 @@ namespace WorkFlowCheck.Common.DTO
[DisplayName("Készültség %")] [DisplayName("Készültség %")]
public string ReadyPercent { get; set; } public string ReadyPercent { get; set; }
[DisplayName("Ellenőrzési pontok száma")] [DisplayName("Ellenőrzési pontok száma")]
public int CheckPointCount { get; set; } public int CheckPointCount { get; set; }
} }
} }
@@ -14,7 +14,7 @@ namespace WorkFlowCheck.Common.DTO
public int CheckListHeaderId { get; set; } public int CheckListHeaderId { get; set; }
public int CheckListTemplateRowId { get; set; } public int CheckListTemplateRowId { get; set; }
public CheckListTemplateRowDTO? CheckListTemplateRowDTO { get; set; } public CheckListTemplateRowDTO? CheckListTemplateRowDTO { get; set; }
public string GroupName => $"AnswerGroup_{CheckListTemplateRowDTO?.RowIndex ?? 0}"; public string GroupName => $"AnswerGroup_{CheckListTemplateRowDTO?.Id ?? 0}";
[DisplayName("Eredmény")] [DisplayName("Eredmény")]
public string Answer { get; set; } = null!; public string Answer { get; set; } = null!;
@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,7 +11,13 @@ namespace WorkFlowCheck.Common.DTO
public class EquipmentDTO public class EquipmentDTO
{ {
public int Id { get; set; } public int Id { get; set; }
[Required(ErrorMessage = "A megnevezést megadása kötelező.")]
[DisplayName("Megnevezés")]
public string ShortName { get; set; } = null!; public string ShortName { get; set; } = null!;
[Required(ErrorMessage = "Az azonosító megadása kötelező.")]
[DisplayName("Azonosító")]
public string EquipmentNumber { get; set; } = null!; public string EquipmentNumber { get; set; } = null!;
} }
} }
@@ -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; }
}
}
@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,6 +11,9 @@ namespace WorkFlowCheck.Common.DTO
public class LocationDTO public class LocationDTO
{ {
public int Id { get; set; } public int Id { get; set; }
[Required(ErrorMessage = "A megnevezést megadása kötelező.")]
[DisplayName("Megnevezés")]
public string FullName { get; set; } = null!; public string FullName { get; set; } = null!;
} }
} }
@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -10,10 +12,19 @@ namespace WorkFlowCheck.Common.DTO
public class RoleCheckListTemplateHeaderDTO public class RoleCheckListTemplateHeaderDTO
{ {
public int Id { get; set; } public int Id { get; set; }
[Required(ErrorMessage = "A szabály megnevezésének megadása kötelező.")]
[DisplayName("Szabály")]
public int RoleId { get; set; } public int RoleId { get; set; }
public RoleDTO? RoleDTO { get; set; } = null!; public RoleDTO? RoleDTO { get; set; } = null!;
[Required(ErrorMessage = "Az ellenőrzési sablon megadása kötelező.")]
[DisplayName("Ellenőrzési sablon")]
public int CheckListTemplateHeaderId { get; set; } public int CheckListTemplateHeaderId { get; set; }
public CheckListTemplateHeaderDTO? CheckListTemplateHeaderDTO { get; set; } = null!; public CheckListTemplateHeaderDTO? CheckListTemplateHeaderDTO { get; set; } = null!;
[DisplayName("Engedélyezve?")]
public bool Enabled { get; set; } = false; public bool Enabled { get; set; } = false;
} }
} }
@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -10,10 +12,18 @@ namespace WorkFlowCheck.Common.DTO
public class RoleCheckPointDTO public class RoleCheckPointDTO
{ {
public int Id { get; set; } public int Id { get; set; }
[Required(ErrorMessage = "A szabály megadása kötelező.")]
[DisplayName("Szabály")]
public int RoleId { get; set; } public int RoleId { get; set; }
public RoleDTO? RoleDTO { get; set; } = null!; public RoleDTO? RoleDTO { get; set; } = null!;
[Required(ErrorMessage = "Az ellenőrzési pont megadása kötelező.")]
[DisplayName("Ellenőrzési pont")]
public int CheckPointId { get; set; } public int CheckPointId { get; set; }
public CheckPointDTO? CheckPointDTO { get; set; } = null!; public CheckPointDTO? CheckPointDTO { get; set; } = null!;
[DisplayName("Engedélyezve?")]
public bool Enabled { get; set; } = false; public bool Enabled { get; set; } = false;
} }
} }
@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -16,9 +17,13 @@ namespace WorkFlowCheck.Common.DTO
[DisplayName("Régi jelszó")] [DisplayName("Régi jelszó")]
public string OldPassword { get; set; } = null!; public string OldPassword { get; set; } = null!;
[Required(ErrorMessage = "A jelszó kötelező.")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{6,}$", ErrorMessage = "Az új jelszónak legalább 6 karakter hosszúnak kell lennie, és tartalmaznia kell kis- és nagybetűt, számot és speciális karaktert.")]
[DisplayName("Új jelszó")] [DisplayName("Új jelszó")]
public string NewPassword1 { get; set; } = null!; public string NewPassword1 { get; set; } = null!;
[Required(ErrorMessage = "A jelszó kötelező.")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{6,}$", ErrorMessage = "Az új jelszónak legalább 6 karakter hosszúnak kell lennie, és tartalmaznia kell kis- és nagybetűt, számot és speciális karaktert.")]
[DisplayName("Jelszó megerősítése")] [DisplayName("Jelszó megerősítése")]
public string NewPassword2 { get; set; } = null!; public string NewPassword2 { get; set; } = null!;
+5 -2
View File
@@ -25,9 +25,12 @@ namespace WorkFlowCheck.Common.DTO
[DisplayName("Felhasználó neve")] [DisplayName("Felhasználó neve")]
public string UserName { get;set; } = null!; public string UserName { get;set; } = null!;
[Required(ErrorMessage = "A jelszó kötelező.")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{6,}$", ErrorMessage = "A jelszónak legalább 6 karakter hosszúnak kell lennie, és tartalmaznia kell kis- és nagybetűt, számot és speciális karaktert.")]
[DisplayName("Jelszó")] [DisplayName("Jelszó")]
public string Password { get; set; } public string Password { get; set; } = null!;
public string JwtToken { get; set; } = null!; public string JwtToken { get; set; } = null!;
[DisplayName("Aktív")] [DisplayName("Aktív")]
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WorkFlowCheck.Common.DataTables
{
public class DataTablesRequest
{
public int Mode { get; set; }
public int Draw { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public DataTablesSearch Search { get; set; } = new();
public List<DataTablesOrder> Order { get; set; } = new();
public List<DataTablesColumn> Columns { get; set; } = new();
}
public class DataTablesSearch { public string? Value { get; set; } }
public class DataTablesOrder { public int Column { get; set; } public string? Dir { get; set; } }
public class DataTablesColumn { public string? Data { get; set; } public bool Searchable { get; set; } public bool Orderable { get; set; } }
}
@@ -34,6 +34,8 @@ namespace WorkFlowCheck.Common.Security
// Jelszó ellenőrzése // Jelszó ellenőrzése
public static bool VerifyPassword(string storedPasswordHash, string inputPassword) public static bool VerifyPassword(string storedPasswordHash, string inputPassword)
{ {
var inputPasswordHash = HashPassword(inputPassword);
byte[] hashBytes = Convert.FromBase64String(storedPasswordHash); byte[] hashBytes = Convert.FromBase64String(storedPasswordHash);
// Extract salt (first 16 bytes) and stored hash (next 32 bytes) // Extract salt (first 16 bytes) and stored hash (next 32 bytes)
+2
View File
@@ -27,6 +27,7 @@ namespace WorkFlowCheck.DL
public DbSet<Entities.CheckPoint> CheckPoints { get; set; } = null!; public DbSet<Entities.CheckPoint> CheckPoints { get; set; } = null!;
public DbSet<DeviceMessage> DeviceMessages { get; set; } = null!; public DbSet<DeviceMessage> DeviceMessages { get; set; } = null!;
public DbSet<Entities.Equipment> Equipments { get; set; } = null!; public DbSet<Entities.Equipment> Equipments { get; set; } = null!;
public DbSet<Entities.FCMToken> FCMTokens { get; set; } = null!;
public DbSet<Entities.Location> Locations { get; set; } = null!; public DbSet<Entities.Location> Locations { get; set; } = null!;
public DbSet<Entities.NumberGeneratorTemplate> NumberGeneratorTemplates { get; set; } = null!; public DbSet<Entities.NumberGeneratorTemplate> NumberGeneratorTemplates { get; set; } = null!;
public DbSet<Entities.NumberGeneratorTemplateDate> NumberGeneratorTemplateDates { get; set; } = null!; public DbSet<Entities.NumberGeneratorTemplateDate> NumberGeneratorTemplateDates { get; set; } = null!;
@@ -48,6 +49,7 @@ namespace WorkFlowCheck.DL
modelBuilder.ApplyConfiguration(new CheckPointTypeConfiguration()); modelBuilder.ApplyConfiguration(new CheckPointTypeConfiguration());
modelBuilder.ApplyConfiguration(new DeviceMessageTypeConfiguration()); modelBuilder.ApplyConfiguration(new DeviceMessageTypeConfiguration());
modelBuilder.ApplyConfiguration(new EquipmentTypeConfiguration()); modelBuilder.ApplyConfiguration(new EquipmentTypeConfiguration());
modelBuilder.ApplyConfiguration(new FCMTokenTypeConfiguration());
modelBuilder.ApplyConfiguration(new LocationTypeConfiguration()); modelBuilder.ApplyConfiguration(new LocationTypeConfiguration());
modelBuilder.ApplyConfiguration(new NumberGeneratorTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorTypeConfiguration());
modelBuilder.ApplyConfiguration(new NumberGeneratorDateTypeConfiguration()); modelBuilder.ApplyConfiguration(new NumberGeneratorDateTypeConfiguration());
@@ -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<Entities.FCMToken>
{
public void Configure(EntityTypeBuilder<Entities.FCMToken> builder)
{
builder.ToTable("FCMToken");
builder.HasKey(e => e.Id);
builder.Property(e => e.Id).ValueGeneratedOnAdd();
}
}
}
+20
View File
@@ -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!;
}
}
@@ -0,0 +1,997 @@
// <auto-generated />
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
{
/// <inheritdoc />
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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int?>("AcceptUserId")
.HasColumnType("int");
b.Property<int>("CheckListTemplateHeaderId")
.HasColumnType("int");
b.Property<int>("CheckStatus")
.HasColumnType("int");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DateExecution")
.HasColumnType("datetime2");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("DocumentNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid>("GuidNumber")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsEditable")
.HasColumnType("bit");
b.Property<bool>("IsStorno")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Answer")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("CheckListHeaderId")
.HasColumnType("int");
b.Property<int>("CheckListTemplateRowId")
.HasColumnType("int");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid>("GuidNumber")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("NumberGenerator1Id")
.HasColumnType("int");
b.Property<int?>("NumberGenerator2Id")
.HasColumnType("int");
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("AnswerType")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("CheckListTemplateHeaderId")
.HasColumnType("int");
b.Property<int>("CheckPointId")
.HasColumnType("int");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("EquipmentId")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("OperationDescription")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsEnabled")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RoleId")
.HasColumnType("int");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("CheckPoint", (string)null);
});
modelBuilder.Entity("WorkFlowCheck.DL.Entities.DeviceMessage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("DeviceIdFrom")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("DeviceIdTo")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<string>("ExtraDataJSON")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsReaded")
.HasColumnType("bit");
b.Property<string>("Message")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("ReceiveDate")
.HasColumnType("datetime2");
b.Property<int?>("RoleId")
.HasColumnType("int");
b.Property<DateTime>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Equipment", (string)null);
});
modelBuilder.Entity("WorkFlowCheck.DL.Entities.FCMToken", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("FCMToken", (string)null);
});
modelBuilder.Entity("WorkFlowCheck.DL.Entities.Location", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FullName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Location", (string)null);
});
modelBuilder.Entity("WorkFlowCheck.DL.Entities.NumberGeneratorTemplate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CurrentNumber")
.HasColumnType("int");
b.Property<string>("DigitFormat")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("GenerateType")
.HasColumnType("int");
b.Property<string>("LastGeneratedNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Prefix")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PrefixSeparator")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Suffix")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CurrentNumber")
.HasColumnType("int");
b.Property<string>("LastGeneratedNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("Month")
.HasColumnType("int");
b.Property<int>("NumberGeneratorTemplateId")
.HasColumnType("int");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<bool>("CanDownloadAPK")
.HasColumnType("bit");
b.Property<bool>("CanEnableBlocked")
.HasColumnType("bit");
b.Property<bool>("CanUseMobilApp")
.HasColumnType("bit");
b.Property<bool>("CanUseWebAdmin")
.HasColumnType("bit");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsAdmin")
.HasColumnType("bit");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ParentId")
.HasColumnType("int");
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CheckListTemplateHeaderId")
.HasColumnType("int");
b.Property<bool>("Enabled")
.HasColumnType("bit");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CheckPointId")
.HasColumnType("int");
b.Property<bool>("Enabled")
.HasColumnType("bit");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<bool>("Active")
.HasColumnType("bit");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<string>("JwtToken")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("NFCActive")
.HasColumnType("bit");
b.Property<string>("NFCCode")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("Token2FA")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int?>("RoleId")
.HasColumnType("int");
b.Property<int>("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
}
}
}
@@ -0,0 +1,68 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace WorkFlowCheck.DL.Migrations
{
/// <inheritdoc />
public partial class Extend021 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "FCMToken",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Token = table.Column<string>(type: "nvarchar(max)", nullable: false),
IsDeleted = table.Column<bool>(type: "bit", nullable: false),
LastModAt = table.Column<DateTime>(type: "datetime2", nullable: false),
LastModBy = table.Column<string>(type: "nvarchar(max)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatedBy = table.Column<string>(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) });
}
/// <inheritdoc />
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) });
}
}
}
@@ -377,6 +377,40 @@ namespace WorkFlowCheck.DL.Migrations
b.ToTable("Equipment", (string)null); b.ToTable("Equipment", (string)null);
}); });
modelBuilder.Entity("WorkFlowCheck.DL.Entities.FCMToken", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime>("LastModAt")
.HasColumnType("datetime2");
b.Property<string>("LastModBy")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("FCMToken", (string)null);
});
modelBuilder.Entity("WorkFlowCheck.DL.Entities.Location", b => modelBuilder.Entity("WorkFlowCheck.DL.Entities.Location", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -692,13 +726,13 @@ namespace WorkFlowCheck.DL.Migrations
{ {
Id = 1, Id = 1,
Active = true, 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", CreatedBy = "System",
Email = "admin@nuvolar.hu", Email = "admin@nuvolar.hu",
FirstName = "Administrator", FirstName = "Administrator",
IsDeleted = false, IsDeleted = false,
JwtToken = "", 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", LastModBy = "System",
LastName = "System", LastName = "System",
NFCActive = true, NFCActive = true,
@@ -711,13 +745,13 @@ namespace WorkFlowCheck.DL.Migrations
{ {
Id = 2, Id = 2,
Active = true, 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", CreatedBy = "System",
Email = "user@nuvolar.hu", Email = "user@nuvolar.hu",
FirstName = "User", FirstName = "User",
IsDeleted = false, IsDeleted = false,
JwtToken = "", 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", LastModBy = "System",
LastName = "System", LastName = "System",
NFCActive = true, NFCActive = true,
+2 -2
View File
@@ -29,14 +29,14 @@ namespace WorkFlowCheck.MAUI
_dbContext.Database.EnsureDeleted(); // Adatbázis törlése _dbContext.Database.EnsureDeleted(); // Adatbázis törlése
_dbContext.Database.EnsureCreated(); // Új adatbázis létrehozása _dbContext.Database.EnsureCreated(); // Új adatbázis létrehozása
StartBackgroundTask(); //StartBackgroundTask();
MainPage = new AppShell(); MainPage = new AppShell();
//MainPage = new NavigationPage(new MainPage(serviceProvider.GetRequiredService<IUserService>())); //MainPage = new NavigationPage(new MainPage(serviceProvider.GetRequiredService<IUserService>()));
} }
protected async override void OnResume() protected async override void OnResume()
{ {
StartBackgroundTask(); //StartBackgroundTask();
base.OnResume(); base.OnResume();
var isLogged = await SecureStorage.Default.GetAsync("WFCUser"); var isLogged = await SecureStorage.Default.GetAsync("WFCUser");
if (isLogged == null) if (isLogged == null)
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,6 +10,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class CheckListHeader public class CheckListHeader
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public int CheckListTemplateHeaderId { get; set; } public int CheckListTemplateHeaderId { get; set; }
public virtual CheckListTemplateHeader? CheckListTemplateHeader { get; set; } public virtual CheckListTemplateHeader? CheckListTemplateHeader { get; set; }
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class CheckListRow public class CheckListRow
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public int CheckListHeaderId { get; set; } public int CheckListHeaderId { get; set; }
public virtual CheckListHeader CheckListHeader { get; set; } = null!; public virtual CheckListHeader CheckListHeader { get; set; } = null!;
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class CheckListTemplateHeader public class CheckListTemplateHeader
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public string ShortName { get; set; } = null!; public string ShortName { get; set; } = null!;
public string Description { get; set; } = null!; public string Description { get; set; } = null!;
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class CheckListTemplateRow public class CheckListTemplateRow
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public int RowIndex { get; set; } public int RowIndex { get; set; }
public int CheckListTemplateHeaderId { get; set; } public int CheckListTemplateHeaderId { get; set; }
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class CheckPoint public class CheckPoint
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public string ShortName { get; set; } = null!; public string ShortName { get; set; } = null!;
public string Code { get; set; } = null!; public string Code { get; set; } = null!;
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class Equipment public class Equipment
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public string ShortName { get; set; } = null!; public string ShortName { get; set; } = null!;
public string EquipmentNumber { get; set; } = null!; public string EquipmentNumber { get; set; } = null!;
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class Location public class Location
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public string FullName { get; set; } = null!; public string FullName { get; set; } = null!;
} }
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,6 +9,7 @@ namespace WorkFlowCheck.MAUI.DataLayer.Entities
{ {
public class MobileUser public class MobileUser
{ {
[Key]
public int Id { get; set; } public int Id { get; set; }
public string? UserName { get; set; } public string? UserName { get; set; }
@@ -0,0 +1,62 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WorkFlowCheck.MAUI.Helper
{
public static class ImageHelper
{
public static string ResizeAndSaveImage(byte[] imageBytes, int id, int targetWidth = 50)
{
// Átméretezett fájl elérési útja
var filename = Path.Combine(FileSystem.CacheDirectory, $"wfc_{id}_photo.jpg");
if (File.Exists(filename))
{
try
{
File.Delete(filename);
// opcionálisan logolhatsz
// Console.WriteLine($"Törölve: {filename}");
}
catch (Exception ex)
{
//Console.WriteLine($"Hiba a fájl törlésekor: {ex.Message}");
}
}
// Eredeti kép betöltése
using var inputStream = new MemoryStream(imageBytes);
using var original = SKBitmap.Decode(inputStream);
if (original == null)
throw new InvalidOperationException("A kép nem olvasható vagy hibás.");
// Új szélesség és magasság arányosan
int targetHeight = (int)(original.Height * ((double)targetWidth / original.Width));
// Új üres bitmap létrehozása
using var resizedSurface = SKSurface.Create(new SKImageInfo(targetWidth, targetHeight));
using var canvas = resizedSurface.Canvas;
canvas.Clear(SKColors.White); // választható háttérszín
var srcRect = new SKRect(0, 0, original.Width, original.Height);
var destRect = new SKRect(0, 0, targetWidth, targetHeight);
canvas.DrawBitmap(original, srcRect, destRect);
using var resizedImage = resizedSurface.Snapshot();
using var imageData = resizedImage.Encode(SKEncodedImageFormat.Jpeg, 90);
// Mentés fájlba
using var fileStream = File.OpenWrite(filename);
imageData.SaveTo(fileStream);
return filename;
}
}
}
@@ -19,10 +19,12 @@ namespace WorkFlowCheck.MAUI.Helper
public static string DatabaseName = ""; public static string DatabaseName = "";
public static bool Syncronised = false; public static bool Syncronised = false;
public static UserDTO SystemUserDTO; public static UserDTO SystemUserDTO;
public static string ProgramVersion = "v1.1.020"; public static string ProgramVersion = "v1.1.039";
#if DEBUG #if DEBUG
public static string ApiBaseUrl = $"https://dev.wfcapi.nuvolar.hu/"; //public static string ApiBaseUrl = $"http://10.0.2.2:59027/";
//public static string ApiBaseUrl = $"https://dev.wfcapi.nuvolar.hu/";
public static string ApiBaseUrl = $"https://uat.wfcapi.nuvolar.hu/";
public static string ApiKey = $"RUJeLSpSMzVASUdaRCEzUyYxRSE0VyFISFRSJC0zRzhLM1hCSDU="; public static string ApiKey = $"RUJeLSpSMzVASUdaRCEzUyYxRSE0VyFISFRSJC0zRzhLM1hCSDU=";
#endif #endif
+1
View File
@@ -32,6 +32,7 @@ namespace WorkFlowCheck.MAUI
builder.Services.AddAutoMapper(typeof(MapperProfile)); builder.Services.AddAutoMapper(typeof(MapperProfile));
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
builder.Services.AddDbContext<AppDbContext>(); builder.Services.AddDbContext<AppDbContext>();
//builder.Services.AddSingleton<AppDbContext>();
builder.Services.AddSingleton<IUserService, UserService>(); builder.Services.AddSingleton<IUserService, UserService>();
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WorkFlowCheck.MAUI.Pages.CheckList.CheckListInfoPage"
Title="CheckListInfoPage">
<Shell.TitleView>
<Grid Padding="2" VerticalOptions="Center">
<Label x:Name="HeaderLabel" Text=""
FontSize="22"
FontAttributes="Bold"
VerticalOptions="Center"
HorizontalOptions="Start" />
<HorizontalStackLayout
VerticalOptions="Center"
HorizontalOptions="End"
Spacing="5">
<Frame CornerRadius="1"
Padding="5"
HasShadow="True"
VerticalOptions="Center"
HorizontalOptions="End">
<Label x:Name="DeviceId"
FontSize="10"
TextColor="Black"/>
</Frame>
<Frame CornerRadius="1"
Padding="5"
HasShadow="True"
VerticalOptions="Center"
HorizontalOptions="End">
<Label x:Name="UserInfo"
FontSize="10"
FontAttributes="Bold"
TextColor="Black"/>
</Frame>
</HorizontalStackLayout>
</Grid>
</Shell.TitleView>
<Grid RowDefinitions="*" Padding="30,30">
<Frame Grid.Row="0"
BorderColor="Gray"
Padding="5"
Margin="1"
CornerRadius="10"
HasShadow="True">
<StackLayout Grid.Column="1" Spacing="2">
<Label x:Name="row1" FontSize="20" FontAttributes="Bold" />
<Label x:Name="row2" Text="B" FontSize="20" />
<Label x:Name="row3" Text="C" FontSize="20" />
<Label x:Name="row4" Text="D" FontSize="20" />
<Label x:Name="row5" Text="D" FontSize="25" FontAttributes="Bold"/>
</StackLayout>
</Frame>
</Grid>
</ContentPage>
@@ -0,0 +1,71 @@
using Android.DeviceLock;
using Firebase.Auth;
using System.Globalization;
using System.Threading.Tasks;
using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.MAUI.Services.Interfaces;
namespace WorkFlowCheck.MAUI.Pages.CheckList;
public partial class CheckListInfoPage : ContentPage
{
private readonly ICheckListService _checkListService;
private readonly IUserService _userService;
private UserDTO _currentUser;
private CheckListHeaderDTO _checkListHeaderDTO;
private CheckListHeaderInfoDTO _checkListHeaderInfoDTO;
public CheckListInfoPage(CheckListHeaderDTO checkListHeaderDTO)
{
InitializeComponent();
_userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>();
_checkListService = MauiProgram.ServiceProvider.GetRequiredService<ICheckListService>();
_checkListHeaderDTO = checkListHeaderDTO;
}
private async Task SetInfo()
{
_currentUser = _userService.GetCurrentUser();
DeviceId.Text = _userService.DeviceId;
UserInfo.Text = $"{_currentUser?.LastName} {_currentUser?.FirstName}";
HeaderLabel.Text = _checkListHeaderDTO.DocumentNumber;
}
protected override async void OnAppearing()
{
base.OnAppearing();
BindingContext = this;
await SetInfo();
BuildCheckListHeaderInfo();
}
private async Task BuildCheckListHeaderInfo()
{
_checkListHeaderInfoDTO = new CheckListHeaderInfoDTO();
var result = _checkListHeaderDTO.CheckListRowDTO
.GroupBy(r => 1)
.Select(g => new
{
TotalRowCount = g.Count(),
EmptyAnswerCount = g.Count(r => string.IsNullOrEmpty(r.Answer)),
CheckPointCount = g.Select(r => r.CheckListTemplateRowDTO.CheckPointId).Distinct().Count()
})
.FirstOrDefault();
if (result != null)
{
_checkListHeaderInfoDTO.TotalRowCount = result.TotalRowCount;
_checkListHeaderInfoDTO.CheckPointCount = result.CheckPointCount;
_checkListHeaderInfoDTO.EmptyAnswerCount = result.EmptyAnswerCount;
if (_checkListHeaderInfoDTO.TotalRowCount > 0)
{
_checkListHeaderInfoDTO.ReadyPercent = ((double)(_checkListHeaderInfoDTO.TotalRowCount - _checkListHeaderInfoDTO.EmptyAnswerCount) / _checkListHeaderInfoDTO.TotalRowCount * 100)
.ToString("0.00", new CultureInfo("hu-HU")) + " %";
}
}
var checkPointDTO = await _checkListService.GetNextCheckpointNotSend(_checkListHeaderDTO);
row1.Text = $"Összes ellenõrizendõ lépés: {_checkListHeaderInfoDTO.TotalRowCount} db";
row2.Text = $"Összes még nem ellenõrzött lépés: {_checkListHeaderInfoDTO.EmptyAnswerCount} db";
row3.Text = $"Ellenõrzési pontok száma: {_checkListHeaderInfoDTO.CheckPointCount} db";
row4.Text = $"Készültség: {_checkListHeaderInfoDTO.ReadyPercent}";
row5.Text = $"Következõ ellenõrzési pont : {checkPointDTO.ShortName}";
}
}
@@ -38,7 +38,7 @@
</HorizontalStackLayout> </HorizontalStackLayout>
</Grid> </Grid>
</Shell.TitleView> </Shell.TitleView>
<Grid RowDefinitions="*,4*,2*" Padding="30,30"> <Grid RowDefinitions="*,4*,2*" Padding="30,30">
<VerticalStackLayout Grid.Row="0" Margin="0,0,0,0"> <VerticalStackLayout Grid.Row="0" Margin="0,0,0,0">
<Label x:Name="progressLabel" Text="Folyamatjelző" FontSize="Medium" HorizontalOptions="Center" /> <Label x:Name="progressLabel" Text="Folyamatjelző" FontSize="Medium" HorizontalOptions="Center" />
@@ -63,7 +63,7 @@
CornerRadius="25" CornerRadius="25"
VerticalOptions="Center" /> VerticalOptions="Center" />
</HorizontalStackLayout> </HorizontalStackLayout>
</VerticalStackLayout> </VerticalStackLayout>
<Frame Grid.Row="1" <Frame Grid.Row="1"
BorderColor="Gray" BorderColor="Gray"
@@ -82,67 +82,104 @@
<DataTemplate> <DataTemplate>
<Frame BorderColor="Gray" Padding="15" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke"> <Frame BorderColor="Gray" Padding="15" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke">
<Grid ColumnDefinitions="*,Auto"> <Grid ColumnDefinitions="*,Auto">
<!-- Bal oldali oszlop: Két Label egymás alatt --> <Grid ColumnSpacing="10">
<StackLayout Grid.Column="0" Spacing="2"> <Grid.ColumnDefinitions>
<Label Text="{Binding DocumentNumber}" FontSize="14" FontAttributes="Bold" /> <ColumnDefinition Width="Auto" />
<Label Text="{Binding DateExecution}" FontSize="12" /> <ColumnDefinition Width="*" />
<Label Text="{Binding CheckListTemplateHeaderDTO.ShortName}" FontSize="10" /> </Grid.ColumnDefinitions>
<Label Text="{Binding StatusName}" FontSize="10" /> <Grid.RowDefinitions>
</StackLayout> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Bal oldali gomb -->
<Button Grid.Column="0"
VerticalOptions="Center"
Text="i"
FontSize="17"
FontAttributes="Bold"
BackgroundColor="Purple"
HeightRequest="40"
WidthRequest="40"
CornerRadius="20"
BorderColor="Gray"
BorderWidth="1"
Command="{Binding BindingContext.InfoCommand, Source={x:Reference CheckList}}"
CommandParameter="{Binding .}" />
<!-- Jobb oldali szövegek -->
<StackLayout Grid.Column="1" Spacing="2">
<Label Text="{Binding DocumentNumber}" FontSize="14" FontAttributes="Bold" />
<Label Text="{Binding DateExecution}" FontSize="12" />
<Label Text="{Binding CheckListTemplateHeaderDTO.ShortName}" FontSize="10" />
<Label Text="{Binding StatusName}" FontSize="10" />
</StackLayout>
</Grid>
<!-- Jobb oldali oszlop: Két gomb egymás mellett --> <!-- Jobb oldali oszlop: Két gomb egymás mellett -->
<HorizontalStackLayout Grid.Column="1" HorizontalOptions="End" Spacing="3"> <HorizontalStackLayout Grid.Column="1" HorizontalOptions="End" Spacing="3">
<Button Text="" <Button Text="L"
Margin="0,0,0,0" Margin="0,0,0,0"
ImageSource="arrow_down.svg" BackgroundColor="DarkOrange"
BackgroundColor="Red" HeightRequest="50"
HeightRequest="50" MaximumHeightRequest="50"
MaximumHeightRequest="50" WidthRequest="50"
WidthRequest="50" MaximumWidthRequest="50"
MaximumWidthRequest="50" CornerRadius="25"
CornerRadius="25" IsVisible="{Binding CheckStatus, Converter={StaticResource CloseConverter}}"
IsVisible="{Binding CheckStatus, Converter={StaticResource BlockedConverter}}" Command="{Binding BindingContext.CloseCommand, Source={x:Reference CheckList}}"
Command="{Binding BindingContext.BlockCommand, Source={x:Reference CheckList}}" CommandParameter="{Binding .}">
CommandParameter="{Binding .}">
</Button> </Button>
<Button Text="" <Button Text=""
ImageSource="arrow_up.svg" Margin="0,0,0,0"
Margin="0,0,0,0" ImageSource="arrow_down.svg"
BackgroundColor="Green" BackgroundColor="Red"
HeightRequest="50" HeightRequest="50"
MaximumHeightRequest="50" MaximumHeightRequest="50"
WidthRequest="50" WidthRequest="50"
MaximumWidthRequest="50" MaximumWidthRequest="50"
CornerRadius="25" CornerRadius="25"
IsVisible="{Binding CheckStatus, Converter={StaticResource UnBlockedConverter}}" IsVisible="{Binding CheckStatus, Converter={StaticResource BlockedConverter}}"
Command="{Binding BindingContext.UnblockCommand, Source={x:Reference CheckList}}" Command="{Binding BindingContext.BlockCommand, Source={x:Reference CheckList}}"
CommandParameter="{Binding .}"> CommandParameter="{Binding .}">
</Button> </Button>
<Button Text="" <Button Text=""
ImageSource="check_circle.svg" ImageSource="arrow_up.svg"
Margin="0,0,0,0" Margin="0,0,0,0"
BackgroundColor="DarkGreen" BackgroundColor="Green"
HeightRequest="50" HeightRequest="50"
MaximumHeightRequest="50" MaximumHeightRequest="50"
WidthRequest="50" WidthRequest="50"
MaximumWidthRequest="50" MaximumWidthRequest="50"
CornerRadius="25" CornerRadius="25"
IsVisible="{Binding CheckStatus, Converter={StaticResource AcceptConverter}}" IsVisible="{Binding CheckStatus, Converter={StaticResource UnBlockedConverter}}"
Command="{Binding BindingContext.AcceptCommand, Source={x:Reference CheckList}}" Command="{Binding BindingContext.UnblockCommand, Source={x:Reference CheckList}}"
CommandParameter="{Binding .}"> CommandParameter="{Binding .}">
</Button> </Button>
<Button Text="" <Button Text=""
ImageSource="arrow_right.svg" ImageSource="check_circle.svg"
Margin="0,0,0,0" Margin="0,0,0,0"
BackgroundColor="Blue" BackgroundColor="DarkGreen"
CornerRadius="25" HeightRequest="50"
HeightRequest="50" MaximumHeightRequest="50"
MaximumHeightRequest="50" WidthRequest="50"
WidthRequest="50" MaximumWidthRequest="50"
MaximumWidthRequest="50" CornerRadius="25"
IsVisible="{Binding CheckStatus, Converter={StaticResource ContinueConverter}, ConverterParameter = {Binding IsNFCSupported}}" IsVisible="{Binding CheckStatus, Converter={StaticResource AcceptConverter}}"
Command="{Binding BindingContext.ContinueCommand, Source={x:Reference CheckList}}" Command="{Binding BindingContext.AcceptCommand, Source={x:Reference CheckList}}"
CommandParameter="{Binding .}"> CommandParameter="{Binding .}">
</Button>
<Button Text=""
ImageSource="arrow_right.svg"
Margin="0,0,0,0"
BackgroundColor="Blue"
CornerRadius="25"
HeightRequest="50"
MaximumHeightRequest="50"
WidthRequest="50"
MaximumWidthRequest="50"
IsVisible="{Binding CheckStatus, Converter={StaticResource ContinueConverter}, ConverterParameter = {Binding IsNFCSupported}}"
Command="{Binding BindingContext.ContinueCommand, Source={x:Reference CheckList}}"
CommandParameter="{Binding .}">
</Button> </Button>
</HorizontalStackLayout> </HorizontalStackLayout>
</Grid> </Grid>
@@ -161,20 +198,23 @@
Margin="1" Margin="1"
CornerRadius="10" CornerRadius="10"
HasShadow="True"> HasShadow="True">
<ScrollView> <RefreshView x:Name="CheckListTemplateRefreshView"
<VerticalStackLayout> IsRefreshing="{Binding IsRefreshingT}"
<Label Text="Új ellenőrzés" FontAttributes="Bold" FontSize="Medium" HorizontalOptions="Center" /> Command="{Binding RefreshCommandT}">
<CollectionView x:Name="CheckListTemplate"> <ScrollView>
<CollectionView.ItemTemplate> <VerticalStackLayout>
<DataTemplate> <Label Text="Új ellenőrzés" FontAttributes="Bold" FontSize="Medium" HorizontalOptions="Center" />
<Frame BorderColor="Gray" Padding="10" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke"> <CollectionView x:Name="CheckListTemplate">
<Grid ColumnDefinitions="*,Auto"> <CollectionView.ItemTemplate>
<StackLayout> <DataTemplate>
<Label Text="{Binding ShortName}" FontSize="16" FontAttributes="Bold" /> <Frame BorderColor="Gray" Padding="10" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke">
<Label Text="{Binding Description}" FontSize="14" /> <Grid ColumnDefinitions="*,Auto">
</StackLayout> <StackLayout>
<HorizontalStackLayout HorizontalOptions="End"> <Label Text="{Binding ShortName}" FontSize="16" FontAttributes="Bold" />
<Button Text="Új ellenőrzés" <Label Text="{Binding Description}" FontSize="14" />
</StackLayout>
<HorizontalStackLayout HorizontalOptions="End">
<Button Text="Új ellenőrzés"
BackgroundColor="Green" BackgroundColor="Green"
Margin="5,0,0,0" Margin="5,0,0,0"
HeightRequest="50" HeightRequest="50"
@@ -183,14 +223,15 @@
MaximumWidthRequest="120" MaximumWidthRequest="120"
Command="{Binding BindingContext.NewCommand, Source={x:Reference CheckListTemplate}}" Command="{Binding BindingContext.NewCommand, Source={x:Reference CheckListTemplate}}"
CommandParameter="{Binding .}" /> CommandParameter="{Binding .}" />
</HorizontalStackLayout> </HorizontalStackLayout>
</Grid> </Grid>
</Frame> </Frame>
</DataTemplate> </DataTemplate>
</CollectionView.ItemTemplate> </CollectionView.ItemTemplate>
</CollectionView> </CollectionView>
</VerticalStackLayout> </VerticalStackLayout>
</ScrollView> </ScrollView>
</RefreshView>
</Frame> </Frame>
<Grid BackgroundColor="#80000000" <Grid BackgroundColor="#80000000"
IsVisible="{Binding IsLoading}" IsVisible="{Binding IsLoading}"
@@ -213,6 +254,7 @@
<local:UnBlockedConverter x:Key="UnBlockedConverter" /> <local:UnBlockedConverter x:Key="UnBlockedConverter" />
<local:ContinueConverter x:Key="ContinueConverter" /> <local:ContinueConverter x:Key="ContinueConverter" />
<local:AcceptConverter x:Key="AcceptConverter" /> <local:AcceptConverter x:Key="AcceptConverter" />
<local:CloseConverter x:Key="CloseConverter" />
</ResourceDictionary> </ResourceDictionary>
</ContentPage.Resources> </ContentPage.Resources>
</ContentPage> </ContentPage>
@@ -9,6 +9,7 @@ using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.Common.Enums; using WorkFlowCheck.Common.Enums;
using WorkFlowCheck.MAUI.Helper; using WorkFlowCheck.MAUI.Helper;
using WorkFlowCheck.MAUI.Pages.NFC; using WorkFlowCheck.MAUI.Pages.NFC;
using WorkFlowCheck.MAUI.Pages.System;
using WorkFlowCheck.MAUI.Services.Interfaces; using WorkFlowCheck.MAUI.Services.Interfaces;
namespace WorkFlowCheck.MAUI.Pages.CheckList; namespace WorkFlowCheck.MAUI.Pages.CheckList;
@@ -27,7 +28,10 @@ public partial class CheckListPage : ContentPage
public ICommand UnblockCommand { get; set; } public ICommand UnblockCommand { get; set; }
public ICommand BlockCommand { get; set; } public ICommand BlockCommand { get; set; }
public ICommand AcceptCommand { get; set; } public ICommand AcceptCommand { get; set; }
public ICommand InfoCommand { get; set; }
public ICommand CloseCommand { get; set; }
public ICommand RefreshCommand { get; } public ICommand RefreshCommand { get; }
public ICommand RefreshCommandT { get; }
public bool IsLoading public bool IsLoading
{ {
@@ -49,6 +53,7 @@ public partial class CheckListPage : ContentPage
} }
private bool _isRefreshing; private bool _isRefreshing;
private bool _isRefreshingT;
public bool IsRefreshing public bool IsRefreshing
{ {
get => _isRefreshing; get => _isRefreshing;
@@ -61,6 +66,18 @@ public partial class CheckListPage : ContentPage
} }
} }
} }
public bool IsRefreshingT
{
get => _isRefreshingT;
set
{
if (_isRefreshingT != value)
{
_isRefreshingT = value;
OnPropertyChanged(nameof(IsRefreshingT));
}
}
}
public CheckListPage() public CheckListPage()
{ {
@@ -73,7 +90,10 @@ public partial class CheckListPage : ContentPage
UnblockCommand = new Command<CheckListHeaderDTO>(OnUnblockItem); UnblockCommand = new Command<CheckListHeaderDTO>(OnUnblockItem);
BlockCommand = new Command<CheckListHeaderDTO>(OnBlockItem); BlockCommand = new Command<CheckListHeaderDTO>(OnBlockItem);
AcceptCommand = new Command<CheckListHeaderDTO>(OnAcceptItem); AcceptCommand = new Command<CheckListHeaderDTO>(OnAcceptItem);
InfoCommand = new Command<CheckListHeaderDTO>(OnInfoItem);
CloseCommand = new Command<CheckListHeaderDTO>(OnCloseItem);
RefreshCommand = new Command(async () => await OnRefresh()); RefreshCommand = new Command(async () => await OnRefresh());
RefreshCommandT = new Command(async () => await OnRefreshT());
} }
private async void OnSyncClicked(object sender, EventArgs e) private async void OnSyncClicked(object sender, EventArgs e)
@@ -123,6 +143,16 @@ public partial class CheckListPage : ContentPage
IsRefreshing = false; IsRefreshing = false;
} }
private async Task OnRefreshT()
{
IsRefreshingT = true;
//await _syncService.SyncCheckListHeader_Down((d, s) => { });
await LoadCheckListTemplate();
IsRefreshingT = false;
}
private void SetInfo() private void SetInfo()
{ {
_currentUser = _userService.GetCurrentUser(); _currentUser = _userService.GetCurrentUser();
@@ -246,7 +276,7 @@ public partial class CheckListPage : ContentPage
} }
else else
{ {
await SystemHelper.ShowSnackBar("Blokkolás feloldás SIKERTELEN!", await SystemHelper.ShowSnackBar("Blokkolás feloldás SIKERTELEN!",
SystemHelper.ColorToHex(Colors.Red), SystemHelper.ColorToHex(Colors.Red),
SystemHelper.ColorToHex(Colors.Red), SystemHelper.ColorToHex(Colors.Red),
@@ -283,6 +313,43 @@ public partial class CheckListPage : ContentPage
} }
} }
} }
private async void OnCloseItem(CheckListHeaderDTO checkListHeaderDTO)
{
var popup = new InputPopup("Kérem adja meg a lezárás okát!");
var (isConfirmed, userInput) = await popup.ShowAsync();
if (isConfirmed && !string.IsNullOrEmpty(userInput))
{
var checkListHeaderCloseDTO = new CheckListHeaderCloseDTO()
{
Id = checkListHeaderDTO.Id,
CloseReason = userInput,
UserId = _userService.GetCurrentUser().Id
};
var success = await _checkListService.CloseCheckListHeader(checkListHeaderCloseDTO);
if (success)
{
IsRefreshing = true;
await LoadCheckList();
IsRefreshing = false;
await SystemHelper.ShowSnackBar("Lezárás sikeres!",
SystemHelper.ColorToHex(Colors.Green),
SystemHelper.ColorToHex(Colors.Green),
SystemHelper.ColorToHex(Colors.White),
5);
}
else
{
await SystemHelper.ShowSnackBar("Lezárás SIKERTELEN!",
SystemHelper.ColorToHex(Colors.Red),
SystemHelper.ColorToHex(Colors.Red),
SystemHelper.ColorToHex(Colors.Yellow),
15);
}
}
}
private async void OnAcceptItem(CheckListHeaderDTO checkListHeaderDTO) private async void OnAcceptItem(CheckListHeaderDTO checkListHeaderDTO)
{ {
bool answer = await DisplayAlert("Megerõsítés", "Biztosan jóváhagyod a folyamatot?", "Igen", "Mégsem"); bool answer = await DisplayAlert("Megerõsítés", "Biztosan jóváhagyod a folyamatot?", "Igen", "Mégsem");
@@ -311,6 +378,10 @@ public partial class CheckListPage : ContentPage
} }
} }
} }
private async void OnInfoItem(CheckListHeaderDTO checkListHeaderDTO)
{
await Navigation.PushAsync(new CheckListInfoPage(checkListHeaderDTO));
}
private async Task LoadCheckListTemplate() private async Task LoadCheckListTemplate()
{ {
IsLoading = true; IsLoading = true;
@@ -338,7 +409,11 @@ public partial class CheckListPage : ContentPage
if (!isAdmin) if (!isAdmin)
{ {
var result = checkListHeaderDTOs var result = checkListHeaderDTOs
.Where(w => w.UserId == userDTO.Id && w.CheckStatus != CheckStatus.Blocked).ToList(); .Where(w => w.UserId == userDTO.Id &&
//w.CheckStatus != CheckStatus.Blocked &&
w.CheckStatus != CheckStatus.Sent &&
w.CheckStatus != CheckStatus.Closed
).ToList();
CheckList.ItemsSource = result; CheckList.ItemsSource = result;
} }
@@ -372,6 +447,31 @@ public class BlockedConverter : IValueConverter
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
public class CloseConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var canEnableBlocked = false;
foreach (var roleDTO in SystemHelper.SystemUserDTO.RoleDTO)
{
if (roleDTO.CanEnableBlocked)
{
canEnableBlocked = true;
break;
}
}
if (value is CheckStatus status && canEnableBlocked)
{
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class UnBlockedConverter : IValueConverter public class UnBlockedConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
@@ -0,0 +1,91 @@
using SkiaSharp;
using System.ComponentModel;
using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.MAUI.Helper;
namespace WorkFlowCheck.MAUI.Pages.CheckList
{
public class CheckListRowCS : INotifyPropertyChanged
{
private byte[] _photoBytes;
//private ImageSource? _photo;
private string? _photoPath;
public event PropertyChangedEventHandler PropertyChanged;
public int Id { get; set; }
public string AnswerType { get; set; } = null!;
public int RowIndex { get; set; }
public string OperationDescription { get; set; } = null!;
public string GroupName { get; set; } = null!;
public string Answer { get; set; } = null!;
public bool? AnswerYes { get; set; } = null!;
public bool? AnswerNo { get; set; } = null!;
public byte[] PhotoBytes
{
get => _photoBytes;
set
{
if (_photoBytes != value)
{
_photoBytes = value;
//_photo = null;
_photoPath = null;
//OnPropertyChanged(nameof(PhotoBytes));
//OnPropertyChanged(nameof(Photo));
OnPropertyChanged(nameof(PhotoPath));
}
}
}
//public ImageSource Photo
//{
// get
// {
// if (_photo == null)
// {
// if (PhotoBytes != null && PhotoBytes.Length > 0)
// {
// try
// {
// var bytesCopy = PhotoBytes.ToArray();
// _photo = ImageSource.FromStream(() => new MemoryStream(bytesCopy));
// }
// catch
// {
// _photo = ImageSource.FromFile("noimage.png");
// }
// }
// else
// {
// _photo = ImageSource.FromFile("noimage.png");
// }
// }
// return _photo;
// }
//}
public string PhotoPath
{
get
{
if (_photoPath == null)
{
if (PhotoBytes != null && PhotoBytes.Length > 0)
{
_photoPath = ImageHelper.ResizeAndSaveImage(PhotoBytes, Id, 100);
}
else
{
_photoPath = "noimage.png";
}
}
return _photoPath;
}
}
protected void OnPropertyChanged(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
@@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WorkFlowCheck.MAUI.Pages.CheckList.CheckListWorkPage" x:Class="WorkFlowCheck.MAUI.Pages.CheckList.CheckListWorkPage"
xmlns:templateselectors="clr-namespace:WorkFlowCheck.MAUI.TemplateSelectors" xmlns:templateselectors="clr-namespace:WorkFlowCheck.MAUI.TemplateSelectors"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:local="clr-namespace:WorkFlowCheck.MAUI.Pages.CheckList" xmlns:local="clr-namespace:WorkFlowCheck.MAUI.Pages.CheckList"
BackgroundColor="#f0f0f0" BackgroundColor="#f0f0f0"
Title=""> Title="">
@@ -47,7 +48,7 @@
<Frame BorderColor="Gray" Padding="1" Margin="2" HasShadow="True" CornerRadius="2"> <Frame BorderColor="Gray" Padding="1" Margin="2" HasShadow="True" CornerRadius="2">
<CollectionView x:Name="CheckPointCheckListRows" <CollectionView x:Name="CheckPointCheckListRows"
HeightRequest="555" HeightRequest="555"
ItemsSource="{Binding CheckListRows}" ItemsSource="{Binding CheckListRowCSs}"
ItemTemplate="{StaticResource AnswerTemplateSelector}"> ItemTemplate="{StaticResource AnswerTemplateSelector}">
<CollectionView.EmptyView> <CollectionView.EmptyView>
<Label Text="Nincsenek feladatok." HorizontalOptions="Center" VerticalOptions="Center"/> <Label Text="Nincsenek feladatok." HorizontalOptions="Center" VerticalOptions="Center"/>
@@ -92,8 +93,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" /> <Label Text="{Binding RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" />
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*,*"> <Grid Grid.Column="2" ColumnDefinitions="*,*">
<Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center"/> <Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center"/>
<Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center"/> <Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center"/>
@@ -104,14 +105,14 @@
Content="Igen" Content="Igen"
Value="Igen" Value="Igen"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerYes}" IsChecked="{Binding AnswerYes, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
<local:BindableRadioButton <local:BindableRadioButton
Grid.Row="1" Grid.Row="1"
Content="Nem" Content="Nem"
Value="Nem" Value="Nem"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerNo}" IsChecked="{Binding AnswerNo, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid> </Grid>
</Grid> </Grid>
@@ -125,19 +126,20 @@
<ColumnDefinition Width="3*" /> <ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" /> <ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" /> <Label Text="{Binding RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="Auto,Auto" VerticalOptions="Center"> <Grid Grid.Column="2" ColumnDefinitions="Auto,Auto" VerticalOptions="Center">
<Image Grid.Column="0" <Image Grid.Column="0"
WidthRequest="95" WidthRequest="65"
HeightRequest="120" HeightRequest="90"
Aspect="AspectFill" Aspect="AspectFill"
Margin="0,0,10,0" Margin="0,0,10,0"
VerticalOptions="Center" VerticalOptions="Center"
Source="{Binding Photo, Converter={StaticResource ByteArrayToImageSourceConverter}}" /> Source="{Binding PhotoPath}" >
</Image>
<Button Text="📷" Grid.Column="1" <Button Text="📷" Grid.Column="1"
VerticalOptions="Center" VerticalOptions="Center"
Command="{Binding BindingContext.CreatePhoto, Source={x:Reference CheckPointCheckListRows}}" Command="{Binding BindingContext.TakePhoto, Source={x:Reference CheckPointCheckListRows}}"
CommandParameter="{Binding .}" /> CommandParameter="{Binding .}" />
</Grid> </Grid>
</Grid> </Grid>
@@ -152,14 +154,15 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" /> <Label Text="{Binding RowIndex,StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*"> <Grid Grid.Column="2" ColumnDefinitions="*">
<Label Text="Érték megadása szükséges" Grid.Column="0" HorizontalTextAlignment="Center"/> <Label Text="Érték megadása szükséges" Grid.Column="0" HorizontalTextAlignment="Center"/>
</Grid> </Grid>
<Entry Grid.Column="3" <Entry Grid.Column="3"
Text="{Binding Answer}" Text="{Binding Answer}"
HorizontalTextAlignment="Center" HorizontalTextAlignment="Center"
TextChanged="V_Entry_Text_Changed"
VerticalOptions="Center" /> VerticalOptions="Center" />
</Grid> </Grid>
</Frame> </Frame>
@@ -173,8 +176,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="{Binding RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*,*"> <Grid Grid.Column="2" ColumnDefinitions="*,*">
<Label Text="I" Grid.Column="0" BackgroundColor="Yellow" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="I" Grid.Column="0" BackgroundColor="Yellow" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
@@ -185,14 +188,14 @@
Content="Igen" Content="Igen"
Value="Igen" Value="Igen"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerYes}" IsChecked="{Binding AnswerYes, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
<local:BindableRadioButton <local:BindableRadioButton
Grid.Row="1" Grid.Row="1"
Content="Nem" Content="Nem"
Value="Nem" Value="Nem"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerNo}" IsChecked="{Binding AnswerNo, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid> </Grid>
</Grid> </Grid>
@@ -207,8 +210,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="{Binding RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*,*"> <Grid Grid.Column="2" ColumnDefinitions="*,*">
<Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="N" Grid.Column="1" BackgroundColor="Yellow" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="N" Grid.Column="1" BackgroundColor="Yellow" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
@@ -219,14 +222,14 @@
Content="Igen" Content="Igen"
Value="Igen" Value="Igen"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerYes}" IsChecked="{Binding AnswerYes, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
<local:BindableRadioButton <local:BindableRadioButton
Grid.Row="1" Grid.Row="1"
Content="Nem" Content="Nem"
Value="Nem" Value="Nem"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerNo}" IsChecked="{Binding AnswerNo, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid> </Grid>
</Grid> </Grid>
@@ -241,8 +244,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="{Binding RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*,*"> <Grid Grid.Column="2" ColumnDefinitions="*,*">
<Label Text="I" Grid.Column="0" BackgroundColor="Red" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="I" Grid.Column="0" BackgroundColor="Red" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="N" Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
@@ -253,14 +256,14 @@
Content="Igen" Content="Igen"
Value="Igen" Value="Igen"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerYes}" IsChecked="{Binding AnswerYes, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
<local:BindableRadioButton <local:BindableRadioButton
Grid.Row="1" Grid.Row="1"
Content="Nem" Content="Nem"
Value="Nem" Value="Nem"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerNo}" IsChecked="{Binding AnswerNo, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid> </Grid>
</Grid> </Grid>
@@ -275,8 +278,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Text="{Binding CheckListTemplateRowDTO.RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="{Binding RowIndex, StringFormat='{}{0:D1}.'}" BackgroundColor="WhiteSmoke" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding CheckListTemplateRowDTO.OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" /> <Label Text="{Binding OperationDescription}" BackgroundColor="WhiteSmoke" Grid.Column="1" />
<Grid Grid.Column="2" ColumnDefinitions="*,*"> <Grid Grid.Column="2" ColumnDefinitions="*,*">
<Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="I" Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="N" Grid.Column="1" BackgroundColor="Red" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/> <Label Text="N" Grid.Column="1" BackgroundColor="Red" TextColor="Black" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
@@ -287,14 +290,14 @@
Content="Igen" Content="Igen"
Value="Igen" Value="Igen"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerYes}" IsChecked="{Binding AnswerYes, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
<local:BindableRadioButton <local:BindableRadioButton
Grid.Row="1" Grid.Row="1"
Content="Nem" Content="Nem"
Value="Nem" Value="Nem"
BindableGroupName="{Binding GroupName}" BindableGroupName="{Binding GroupName}"
IsChecked="{Binding AnswerNo}" IsChecked="{Binding AnswerNo, Mode=TwoWay}"
HorizontalOptions="Center" VerticalOptions="Center"/> HorizontalOptions="Center" VerticalOptions="Center"/>
</Grid> </Grid>
</Grid> </Grid>
@@ -308,6 +311,5 @@
PI_N_Template="{StaticResource PI_N_Template}" PI_N_Template="{StaticResource PI_N_Template}"
I_PN_Template="{StaticResource I_PN_Template}" I_PN_Template="{StaticResource I_PN_Template}"
V_Template="{StaticResource V_Template}"/> V_Template="{StaticResource V_Template}"/>
<local:ByteArrayToImageSourceConverter x:Key="ByteArrayToImageSourceConverter"/>
</ContentPage.Resources> </ContentPage.Resources>
</ContentPage> </ContentPage>
@@ -29,8 +29,10 @@ public partial class CheckListWorkPage : ContentPage
OnPropertyChanged(nameof(IsLoading)); OnPropertyChanged(nameof(IsLoading));
} }
} }
public ObservableCollection<CheckListRowDTO> CheckListRows { get; set; } = new ObservableCollection<CheckListRowDTO>(); public ObservableCollection<CheckListRowCS> CheckListRowCSs { get; set; } = new ObservableCollection<CheckListRowCS>();
public ICommand CreatePhoto { get; set; } public List<CheckListRowDTO> CheckListRowDTOs { get; set; }
public ICommand TakePhoto { get; set; }
public ICommand SendCommand { get; set; } public ICommand SendCommand { get; set; }
public ICommand SaveCommand { get; set; } public ICommand SaveCommand { get; set; }
@@ -95,7 +97,7 @@ public partial class CheckListWorkPage : ContentPage
progressLabel.Text = "Szinkronizálás befejezve!"; progressLabel.Text = "Szinkronizálás befejezve!";
await Shell.Current.GoToAsync("//CheckListPage"); await Shell.Current.GoToAsync("//CheckListPage");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -109,26 +111,36 @@ public partial class CheckListWorkPage : ContentPage
} }
} }
private async Task OnSave() private async Task OnSave(bool withReload = true)
{ {
IsLoading = true; IsLoading = true;
try try
{ {
await Task.Run(async () => await Task.Run(async () =>
{ {
foreach (var checkListRow in CheckListRows) foreach (var checkListRowCS in CheckListRowCSs)
{ {
if (checkListRow.AnswerYes == true) var checkListRowDTO = CheckListRowDTOs.Where(w => w.Id == checkListRowCS.Id).FirstOrDefault();
if (checkListRowDTO != null)
{ {
checkListRow.Answer = "Igen"; checkListRowDTO.Answer = checkListRowCS.Answer;
if (checkListRowCS.AnswerYes == true)
{
checkListRowDTO.Answer = "Igen";
}
else if (checkListRowCS.AnswerNo == true)
{
checkListRowDTO.Answer = "Nem";
}
else
{
checkListRowDTO.Answer = checkListRowCS.Answer;
}
await _checkListService.UpdateCheckListRow(checkListRowDTO, withReload);
} }
if (checkListRow.AnswerNo == true)
{
checkListRow.Answer = "Nem";
}
await _checkListService.UpdateCheckListRow(checkListRow);
} }
await LoadCheckPointCheckListRows(); if (withReload) await LoadCheckPointCheckListRows();
}); });
} }
catch (Exception) catch (Exception)
@@ -146,46 +158,51 @@ public partial class CheckListWorkPage : ContentPage
base.OnAppearing(); base.OnAppearing();
BindingContext = this; BindingContext = this;
await SetInfo(); await SetInfo();
CreatePhoto = new Command<CheckListRowDTO>(OnTakePhoto); TakePhoto = new Command<CheckListRowCS>(OnTakePhoto);
await LoadCheckPointCheckListRows(); await LoadCheckPointCheckListRows();
} }
private async void OnTakePhoto(CheckListRowDTO checkListRowDTO) private async Task<byte[]> ResizePicture(FileResult? photo, int newWidth)
{
using var stream = await photo.OpenReadAsync();
using var originalBitmap = SKBitmap.Decode(stream);
int newHeight = (int)(originalBitmap.Height * ((double)newWidth / originalBitmap.Width));
using var surface = SKSurface.Create(new SKImageInfo(newWidth, newHeight));
using var canvas = surface.Canvas;
var sourceRect = new SKRect(0, 0, originalBitmap.Width, originalBitmap.Height);
var destRect = new SKRect(0, 0, newWidth, newHeight);
canvas.DrawBitmap(originalBitmap, sourceRect, destRect);
using var resizedImage = surface.Snapshot();
using var data = resizedImage.Encode(SKEncodedImageFormat.Jpeg, 100);
return data.ToArray();
}
private async void OnTakePhoto(CheckListRowCS checkListRowCS)
{ {
try try
{ {
if (MediaPicker.IsCaptureSupported) if (MediaPicker.IsCaptureSupported)
{ {
await OnSave(); //await OnSave(false);
var photo = await MediaPicker.CapturePhotoAsync(); var photo = await MediaPicker.CapturePhotoAsync();
if (photo != null) if (photo != null)
{ {
//using var stream = await photo.OpenReadAsync(); checkListRowCS.PhotoBytes = await ResizePicture(photo, 500);
//using var ms = new MemoryStream(); checkListRowCS.Answer = "Igen";
//await stream.CopyToAsync(ms);
//byte[] photoBytes = ms.ToArray();
using var stream = await photo.OpenReadAsync(); var checkListRowDTO = CheckListRowDTOs.FirstOrDefault(w => w.Id == checkListRowCS.Id);
using var originalBitmap = SKBitmap.Decode(stream); if (checkListRowDTO != null)
{
checkListRowDTO.Photo = checkListRowCS.PhotoBytes;
checkListRowDTO.Answer = "Igen";
int newWidth = 500; await _checkListService.UpdateCheckListRow(checkListRowDTO, true);
int newHeight = (int)(originalBitmap.Height * ((double)newWidth / originalBitmap.Width)); //await LoadCheckPointCheckListRows();
}
using var surface = SKSurface.Create(new SKImageInfo(newWidth, newHeight));
using var canvas = surface.Canvas;
var sourceRect = new SKRect(0, 0, originalBitmap.Width, originalBitmap.Height);
var destRect = new SKRect(0, 0, newWidth, newHeight);
canvas.DrawBitmap(originalBitmap, sourceRect, destRect);
using var resizedImage = surface.Snapshot();
using var data = resizedImage.Encode(SKEncodedImageFormat.Jpeg, 100);
checkListRowDTO.Photo = data.ToArray();
checkListRowDTO.Answer = "Igen";
await _checkListService.UpdateCheckListRow(checkListRowDTO);
await LoadCheckPointCheckListRows();
} }
} }
else else
@@ -202,9 +219,11 @@ public partial class CheckListWorkPage : ContentPage
{ {
IsLoading = true; IsLoading = true;
CheckListRows.Clear(); CheckListRowCSs.Clear();
var checkListRowDTOs = await _checkListService.GetCheckListRowsByCheckPointCode(_currentUser.Id, _checkListHeaderId, _checkPointCode);
foreach (var item in checkListRowDTOs) CheckListRowDTOs = await _checkListService.GetCheckListRowsByCheckPointCode(_currentUser.Id, _checkListHeaderId, _checkPointCode);
foreach (var item in CheckListRowDTOs)
{ {
if (item.Answer == "Igen") if (item.Answer == "Igen")
{ {
@@ -216,12 +235,34 @@ public partial class CheckListWorkPage : ContentPage
item.AnswerYes = false; item.AnswerYes = false;
item.AnswerNo = true; item.AnswerNo = true;
} }
CheckListRows.Add(item); var checkListRowCS = new CheckListRowCS()
{
Answer = item.Answer,
AnswerNo = item.AnswerNo,
AnswerYes = item.AnswerYes,
GroupName = $"AnswerGroup_{item.CheckListTemplateRowDTO?.Id ?? 0}",
Id = item.Id,
RowIndex = item.CheckListTemplateRowDTO?.RowIndex ?? 0,
OperationDescription = item.CheckListTemplateRowDTO?.OperationDescription ?? "N/A",
AnswerType = item.CheckListTemplateRowDTO?.AnswerType ?? "I-N",
PhotoBytes = item.Photo ?? Array.Empty<byte>(),
};
CheckListRowCSs.Add(checkListRowCS);
} }
IsLoading = false; IsLoading = false;
} }
private void V_Entry_Text_Changed(object sender, TextChangedEventArgs e)
{
var entry = sender as Entry;
var model = entry?.BindingContext as CheckListRowCS;
if (model != null)
{
model.Answer = e.NewTextValue;
}
}
} }
public class BindableRadioButton : RadioButton public class BindableRadioButton : RadioButton
{ {
@@ -241,20 +282,32 @@ public class BindableRadioButton : RadioButton
radioButton.GroupName = newGroupName; radioButton.GroupName = newGroupName;
} }
} }
} public BindableRadioButton()
public class ByteArrayToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
if (value is byte[] bytes && bytes.Length > 0) CheckedChanged += OnCheckedChangedInternal;
}
private void OnCheckedChangedInternal(object sender, CheckedChangedEventArgs e)
{
if (e.Value && BindingContext is CheckListRowCS checkListRowCS)
{ {
return ImageSource.FromStream(() => new MemoryStream(bytes)); if (Value?.ToString() == "Igen")
checkListRowCS.Answer = "Igen";
else if (Value?.ToString() == "Nem")
checkListRowCS.Answer = "Nem";
} }
return null;
} }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) protected override void OnBindingContextChanged()
{ {
throw new NotImplementedException(); base.OnBindingContextChanged();
if (BindingContext is CheckListRowCS checkListRowCS)
{
if (Value?.ToString() == "Igen")
IsChecked = checkListRowCS.Answer == "Igen";
else if (Value?.ToString() == "Nem")
IsChecked = checkListRowCS.Answer == "Nem";
}
} }
} }
@@ -15,7 +15,7 @@ public partial class LoginPage : BasePage
public LoginPage() public LoginPage()
{ {
InitializeComponent(); InitializeComponent();
InitFirebase();
SetContent(LoginContent); SetContent(LoginContent);
_userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>(); _userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>();
_syncService = MauiProgram.ServiceProvider.GetRequiredService<ISyncService>(); _syncService = MauiProgram.ServiceProvider.GetRequiredService<ISyncService>();
@@ -35,10 +35,22 @@ public partial class LoginPage : BasePage
if (response != null && response.IsSuccess) if (response != null && response.IsSuccess)
{ {
_userService.SetCurrentUser(response.Data); _userService.SetCurrentUser(response.Data);
SystemHelper.SystemUserDTO = response.Data; SystemHelper.SystemUserDTO = response.Data;
var needFCM = false;
foreach (var role in response.Data.RoleDTO)
{
if (role.CanEnableBlocked)
{
needFCM = true;
break;
}
}
if (needFCM)
{
await InitFirebase();
}
var wFCUser = Newtonsoft.Json.JsonConvert.SerializeObject(response.Data); var wFCUser = Newtonsoft.Json.JsonConvert.SerializeObject(response.Data);
await SecureStorage.Default.SetAsync("WFCUser", "wFCUser"); await SecureStorage.Default.SetAsync("WFCUser", "wFCUser");
await SecureStorage.Default.SetAsync("AuthToken", response.Data.JwtToken); await SecureStorage.Default.SetAsync("AuthToken", response.Data.JwtToken);
@@ -169,7 +181,7 @@ public partial class LoginPage : BasePage
} }
private async void InitFirebase() private async Task InitFirebase()
{ {
try try
{ {
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:popups="clr-namespace:WorkFlowCheck.MAUI.Pages.System"
x:Class="WorkFlowCheck.MAUI.Pages.System.InputPopup">
<toolkit:Popup.Resources>
<Style TargetType="{x:Type popups:InputPopup}">
<Setter Property="Size" Value="400,150" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Start" />
<Setter Property="CanBeDismissedByTappingOutsideOfPopup" Value="True" />
</Style>
</toolkit:Popup.Resources>
<VerticalStackLayout Padding="20" Spacing="10">
<Label x:Name="UserConfirmationLabel" />
<Entry x:Name="UserInputEntry" />
<HorizontalStackLayout HorizontalOptions="End" Spacing="10">
<Button Text="Mégsem" Clicked="OnCancelClicked" />
<Button Text="Megerősít" Clicked="OnOkClicked" />
</HorizontalStackLayout>
</VerticalStackLayout>
</toolkit:Popup>
@@ -0,0 +1,42 @@
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Views;
namespace WorkFlowCheck.MAUI.Pages.System;
public partial class InputPopup : Popup
{
private TaskCompletionSource<(bool IsConfirmed, string Result)> _taskCompletionSource;
public InputPopup(string userConfirmationLabel)
{
InitializeComponent();
_taskCompletionSource = new();
UserConfirmationLabel.Text = userConfirmationLabel;
this.Closed += OnPopupClosed;
}
public Task<(bool IsConfirmed, string Result)> ShowAsync()
{
Application.Current.MainPage.ShowPopup(this);
return _taskCompletionSource.Task;
}
private void OnOkClicked(object sender, EventArgs e)
{
Close((true, UserInputEntry.Text));
}
private void OnCancelClicked(object sender, EventArgs e)
{
Close((false, ""));
}
private void OnPopupClosed(object sender, PopupClosedEventArgs e)
{
if (e?.Result is ValueTuple<bool, string> value)
{
_taskCompletionSource.TrySetResult(value);
}
else
{
_taskCompletionSource.TrySetResult((false, null));
}
}
}
@@ -5,6 +5,7 @@
android:icon="@mipmap/appicon" android:icon="@mipmap/appicon"
android:supportsRtl="true" android:supportsRtl="true"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:networkSecurityConfig="@xml/network_security_config"
android:label="Workflow Check App"> android:label="Workflow Check App">
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
@@ -1,6 +1,7 @@
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.Content.PM; using Android.Content.PM;
using Android.Media;
using Android.Nfc; using Android.Nfc;
using Android.OS; using Android.OS;
using Firebase; using Firebase;
@@ -103,11 +104,24 @@ namespace WorkFlowCheck.MAUI
} }
private void CreateNotificationChannel() private void CreateNotificationChannel()
{ {
var soundUri = Android.Net.Uri.Parse($"android.resource://{Android.App.Application.Context.PackageName}/raw/siren_alert");
var audioAttributes = new AudioAttributes.Builder()
.SetUsage(AudioUsageKind.Notification)
.SetContentType(AudioContentType.Sonification)
.Build();
var channelId = $"{PackageName}.general"; var channelId = $"{PackageName}.general";
var channel = new NotificationChannel(channelId, "General", NotificationImportance.High);
channel.SetSound(soundUri, audioAttributes);
var notificationManager = (NotificationManager)GetSystemService(NotificationService); var notificationManager = (NotificationManager)GetSystemService(NotificationService);
var channel = new NotificationChannel(channelId, "General", NotificationImportance.Default);
notificationManager.CreateNotificationChannel(channel); notificationManager.CreateNotificationChannel(channel);
FirebaseCloudMessagingImplementation.ChannelId = channelId; FirebaseCloudMessagingImplementation.ChannelId = channelId;
} }
} }
} }
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!--Set application-wide security config using base-config tag.-->
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -2,6 +2,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Diagnostics;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
@@ -99,7 +100,8 @@ namespace WorkFlowCheck.MAUI.Services
.Include(i => i.CheckListTemplateHeader) .Include(i => i.CheckListTemplateHeader)
.Where(w => w.CheckStatus == CheckStatus.Open || .Where(w => w.CheckStatus == CheckStatus.Open ||
w.CheckStatus == CheckStatus.InProgress || w.CheckStatus == CheckStatus.InProgress ||
w.CheckStatus == CheckStatus.Blocked) w.CheckStatus == CheckStatus.Blocked ||
w.CheckStatus == CheckStatus.Sent)
.ToListAsync(); .ToListAsync();
retVal = _mapper.Map<List<CheckListHeaderDTO>>(res); retVal = _mapper.Map<List<CheckListHeaderDTO>>(res);
} }
@@ -155,24 +157,34 @@ namespace WorkFlowCheck.MAUI.Services
return retVal; return retVal;
} }
public async Task<CheckListRowDTO> UpdateCheckListRow(CheckListRowDTO checkListRowDTO) public async Task<CheckListRowDTO> UpdateCheckListRow(CheckListRowDTO checkListRowDTO, bool withPhoto = true)
{ {
var retVal = checkListRowDTO; var retVal = checkListRowDTO;
try try
{ {
var checkListRow = await _dbContext.CheckListRows.Where(w => w.Id == checkListRowDTO.Id).FirstOrDefaultAsync(); var checkListRow = await _dbContext.CheckListRows
//.AsNoTracking()
.Where(w => w.Id == checkListRowDTO.Id).FirstOrDefaultAsync();
if (checkListRow != null) if (checkListRow != null)
{ {
checkListRow.Answer = checkListRowDTO.Answer; if (checkListRow.Answer != checkListRowDTO.Answer)
if (checkListRowDTO.Photo != null && checkListRowDTO.Photo.Length > 0)
{ {
checkListRow.Photo = checkListRowDTO.Photo; checkListRow.Answer = checkListRowDTO.Answer;
}
if (checkListRowDTO.Photo != null && checkListRowDTO.Photo.Length > 0 && withPhoto)
{
if (!checkListRow.Photo.SequenceEqual(checkListRowDTO.Photo ?? Array.Empty<byte>()))
{
checkListRow.Photo = checkListRowDTO.Photo ?? Array.Empty<byte>();
}
} }
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
} }
} }
catch (Exception) catch (Exception ex)
{ {
Debug.WriteLine(ex.Message);
} }
return retVal; return retVal;
} }
@@ -239,6 +251,42 @@ namespace WorkFlowCheck.MAUI.Services
} }
return retVal; return retVal;
} }
public async Task<bool> CloseCheckListHeader(CheckListHeaderCloseDTO checkListHeaderCloseDTO)
{
var retVal = false;
try
{
var checkListHeader = await _dbContext.CheckListHeaders
.Where(w => w.Id == checkListHeaderCloseDTO.Id)
.FirstOrDefaultAsync();
if (checkListHeader != null)
{
var userDTO = _userService.GetCurrentUser();
var endpoint = $"{_httpClient.BaseAddress}api/CheckList/CloseCheckListHeader";
using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, checkListHeaderCloseDTO))
{
httpResponseMessage.EnsureSuccessStatusCode();
var jsonString = await httpResponseMessage.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<ApiResponseDTO<bool>>(jsonString);
if (response != null)
{
if (response.IsSuccess)
{
checkListHeader.CheckStatus = CheckStatus.Closed;
await _dbContext.SaveChangesAsync();
retVal = true;
}
}
}
}
}
catch (Exception ex)
{
retVal = false;
}
return retVal;
}
public async Task<bool> AcceptCheckListHeader(CheckListHeaderDTO checkListHeaderDTO) public async Task<bool> AcceptCheckListHeader(CheckListHeaderDTO checkListHeaderDTO)
{ {
var retVal = false; var retVal = false;
@@ -280,7 +328,8 @@ namespace WorkFlowCheck.MAUI.Services
.Include(i => i.CheckListTemplateRow) .Include(i => i.CheckListTemplateRow)
.ThenInclude(i => i.CheckPoint) .ThenInclude(i => i.CheckPoint)
.Where(w => w.CheckListHeaderId == checkListHeaderDTO.Id .Where(w => w.CheckListHeaderId == checkListHeaderDTO.Id
&& string.IsNullOrEmpty(w.Answer.Trim())) && string.IsNullOrEmpty(w.Answer.Trim())
&& w.CheckListTemplateRow.AnswerType != "PN")
.Select(w => w.CheckListTemplateRow.CheckPoint) .Select(w => w.CheckListTemplateRow.CheckPoint)
.OrderBy(cp => cp.ShortName) .OrderBy(cp => cp.ShortName)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
@@ -17,11 +17,12 @@ namespace WorkFlowCheck.MAUI.Services.Interfaces
Task<List<CheckListHeaderDTO>> GetCheckLists(int userId); Task<List<CheckListHeaderDTO>> GetCheckLists(int userId);
Task<List<CheckListTemplateHeaderDTO>> GetCheckListTemplates(int userId); Task<List<CheckListTemplateHeaderDTO>> GetCheckListTemplates(int userId);
Task<List<CheckListRowDTO>> GetCheckListRowsByCheckPointCode(int userId, int checkListHeaderId, string checkPointCode); Task<List<CheckListRowDTO>> GetCheckListRowsByCheckPointCode(int userId, int checkListHeaderId, string checkPointCode);
Task<CheckListRowDTO> UpdateCheckListRow(CheckListRowDTO checkListRowDTO); Task<CheckListRowDTO> UpdateCheckListRow(CheckListRowDTO checkListRowDTO, bool withPhoto = true);
Task<bool> UnBlockCheckListHeader(CheckListHeaderDTO checkListHeaderDTO); Task<bool> UnBlockCheckListHeader(CheckListHeaderDTO checkListHeaderDTO);
Task<bool> BlockCheckListHeader(CheckListHeaderDTO checkListHeaderDTO); Task<bool> BlockCheckListHeader(CheckListHeaderDTO checkListHeaderDTO);
Task<bool> AcceptCheckListHeader(CheckListHeaderDTO checkListHeaderDTO); Task<bool> CloseCheckListHeader(CheckListHeaderCloseDTO checkListHeaderCloseDTO);
Task<CheckPointDTO> GetNextCheckpointNotSend(CheckListHeaderDTO checkListHeaderDTO); Task<bool> AcceptCheckListHeader(CheckListHeaderDTO checkListHeaderDTO);
Task<CheckPointDTO> GetNextCheckpointNotSend(CheckListHeaderDTO checkListHeaderDTO);
} }
} }
@@ -27,6 +27,6 @@ namespace WorkFlowCheck.MAUI.Services.Interfaces
Task<ApiResponseDTO<string>> SyncUsers_Up(Action<double, string> reportProgress); Task<ApiResponseDTO<string>> SyncUsers_Up(Action<double, string> reportProgress);
Task SyncUsers_Down(Action<double, string> reportProgress); Task SyncUsers_Down(Action<double, string> reportProgress);
Task<bool> UploadFCMToken(string token); Task<ApiResponseDTO<bool>> UploadFCMToken(string token);
} }
} }
@@ -218,7 +218,7 @@ namespace WorkFlowCheck.MAUI.Services
{ {
if (responseList.IsSuccess) if (responseList.IsSuccess)
{ {
var entityList = await _dbContext.Locations.ToListAsync(); var entityList = await _dbContext.Equipments.ToListAsync();
var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList(); var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList();
var mappedMissingItems = _mapper.Map<List<Equipment>>(missingItems); var mappedMissingItems = _mapper.Map<List<Equipment>>(missingItems);
@@ -50,6 +50,21 @@ namespace WorkFlowCheck.MAUI.TemplateSelectors
_ => I_N_Template _ => I_N_Template
}; };
} }
if (item is CheckListRowCS model3)
{
return model3.AnswerType switch
{
"I-N" => I_N_Template,
"P" => P_Template,
"PN" => P_Template,
"V" => V_Template,
"SI-N" => SI_N_Template,
"I-SN" => I_SN_Template,
"PI-N" => PI_N_Template,
"I-PN" => I_PN_Template,
_ => I_N_Template
};
}
return null; return null;
} }
@@ -59,6 +59,9 @@
<ItemGroup> <ItemGroup>
<AndroidResource Remove="Platforms\Android\Resources\values\strings.xml" /> <AndroidResource Remove="Platforms\Android\Resources\values\strings.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Platforms\Android\Resources\xml\network_security_config.xml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Platforms\Android\Resources\xml\file_paths.xml" /> <AndroidResource Include="Platforms\Android\Resources\xml\file_paths.xml" />
@@ -130,6 +133,9 @@
<MauiXaml Update="Pages\BaseStock\Locations\LocationsPage.xaml"> <MauiXaml Update="Pages\BaseStock\Locations\LocationsPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Pages\CheckList\CheckListInfoPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Pages\CheckList\CheckListPage.xaml"> <MauiXaml Update="Pages\CheckList\CheckListPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
@@ -154,6 +160,9 @@
<MauiXaml Update="Pages\System\DownloadAPKPage.xaml"> <MauiXaml Update="Pages\System\DownloadAPKPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Pages\System\InputPopup.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Pages\System\SyncPage.xaml"> <MauiXaml Update="Pages\System\SyncPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
+1 -1
View File
@@ -1,2 +1,2 @@
dotnet publish -f net8.0-android -c Release -p:AndroidPackageFormat=apk dotnet publish -f net8.0-android -c Release -p:AndroidPackageFormat=apk
pause pause
@@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WorkFlowCheck.Web.Helpers
{
[HtmlTargetElement("input", Attributes = "asp-for-datatype")]
public class AspForDataTypeTagHelper : TagHelper
{
[HtmlAttributeName("asp-for-datatype")]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (For == null) return;
var type = For.ModelExplorer.ModelType;
string dataType = GetDataTypeString(type);
output.Attributes.SetAttribute("data-type", dataType);
// 🔥 EZ HIÁNYZIK → Rakd be!
output.Attributes.RemoveAll("asp-for-datatype");
}
private string GetDataTypeString(Type type)
{
// Nullable<T> esetén nyerjük ki az alaptípust
if (Nullable.GetUnderlyingType(type) is Type underlyingType)
{
type = underlyingType;
}
if (type == typeof(string)) return "string";
if (type == typeof(int) || type == typeof(long) || type == typeof(float) ||
type == typeof(double) || type == typeof(decimal)) return "number";
if (type == typeof(bool)) return "bool";
if (type == typeof(DateTime)) return "date";
return "string"; // default fallback
}
}
}
@@ -7,7 +7,7 @@ namespace WorkFlowCheck.Web.Helpers
public static class SystemHelper public static class SystemHelper
{ {
public static string DatabaseName = ""; public static string DatabaseName = "";
public static string ProgramVersion = "v1.1.019"; public static string ProgramVersion = "v1.1.032";
public async static Task GetAPIInfoAsync(IConfiguration configuration) public async static Task GetAPIInfoAsync(IConfiguration configuration)
{ {
@@ -21,6 +21,15 @@
<div class="card shadow p-4" style="min-width: 350px; max-width: 400px; width: 100%;"> <div class="card shadow p-4" style="min-width: 350px; max-width: 400px; width: 100%;">
<h2 class="mb-4 text-center">Jelszó módosítása</h2> <h2 class="mb-4 text-center">Jelszó módosítása</h2>
<!-- Loading overlay -->
<div id="formLoading" class="position-absolute top-0 start-0 w-100 h-100 d-none align-items-center justify-content-center"
style="background: rgba(255,255,255,.75); z-index: 10; border-radius: .375rem;">
<div class="text-center">
<div class="spinner-border" role="status" aria-hidden="true"></div>
<div class="mt-2 small text-muted">Kérlek várj…</div>
</div>
</div>
<div id="errorMessageContainer" class="alert alert-danger" style="display:none;"></div> <div id="errorMessageContainer" class="alert alert-danger" style="display:none;"></div>
<form method="post"> <form method="post">
@@ -55,14 +64,14 @@
</div> </div>
<hr class="mt-4 mb-3 border-secondary"> <hr class="mt-4 mb-3 border-secondary">
<div id="login2F1" class="d-grid"> <div id="login2F1" class="d-grid">
<button id="Login2F1Btn" type="button" class="btn btn-primary">Bejelentkezés</button> <button id="Login2F1Btn" type="button" class="btn btn-primary">Ellenőrzés</button>
</div> </div>
<div id="login2F2" class="d-grid"> <div id="login2F2" class="d-grid">
<button id="Login2F2Btn" type="button" class="btn btn-primary">Megerősítés</button> <button id="Login2F2Btn" type="button" class="btn btn-primary">Megerősítés</button>
</div> </div>
</form> </form>
</div> </div>
<!-- Message Modal --> <!-- Message Modal -->
<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true"> <div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
@@ -80,7 +89,7 @@
</div> </div>
</div> </div>
</div> </div>
<script src="~/js/site.js" asp-append-version="true"></script> <script src="~/js/site.js" asp-append-version="true"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
@@ -88,20 +97,46 @@
<script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script>
<script> <script>
function setLoading(isLoading) {
if (isLoading) {
$('#formLoading').removeClass('d-none').addClass('d-flex');
$('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
// opcionális: inputok tiltása is
// $('#User2FADTO_UserName, #User2FADTO_Password, #User2FADTO_Code').prop('disabled', true);
} else {
$('#formLoading').addClass('d-none').removeClass('d-flex');
$('#Login2F1Btn, #Login2F2Btn').prop('disabled', false);
// $('#User2FADTO_UserName, #User2FADTO_Password, #User2FADTO_Code').prop('disabled', false);
}
}
let requestInFlight = false;
function beginRequest() {
if (requestInFlight) return false;
requestInFlight = true;
setLoading(true);
return true;
}
function endRequest() {
requestInFlight = false;
setLoading(false);
}
$(document).ready(function () { $(document).ready(function () {
$('#VerificationCode').hide(); $('#VerificationCode').hide();
$('#login2F2').hide(); $('#login2F2').hide();
$('#Login2F2Btn').hide(); $('#Login2F2Btn').hide();
$('#UserChangePassword2FADTO_UserName').attr('readonly', true); $('#UserChangePassword2FADTO_UserName').attr('readonly', true);
$('#Login2F1Btn').on('click', function () { $('#Login2F1Btn').on('click', function () {
// $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true); // $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
if (!beginRequest()) return;
$('#errorMessageContainer').hide().text(''); $('#errorMessageContainer').hide().text('');
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const userName = $('#UserChangePassword2FADTO_UserName').val(); const userName = $('#UserChangePassword2FADTO_UserName').val();
const password = $('#UserChangePassword2FADTO_OldPassword').val(); const password = $('#UserChangePassword2FADTO_OldPassword').val();
$.ajax({ $.ajax({
url: '/Account/ChangePassword?handler=Login2F1', url: '/Account/ChangePassword?handler=Login2F1',
type: 'POST', type: 'POST',
@@ -136,6 +171,9 @@
// .prop('disabled', false) // .prop('disabled', false)
// .removeAttr('disabled') // .removeAttr('disabled')
// .removeClass('disabled'); // .removeClass('disabled');
},
complete: function () {
endRequest();
} }
}); });
@@ -143,6 +181,7 @@
$('#Login2F2Btn').on('click', function () { $('#Login2F2Btn').on('click', function () {
// $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true); // $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
if (!beginRequest()) return;
$('#errorMessageContainer').hide().text(''); $('#errorMessageContainer').hide().text('');
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
@@ -194,6 +233,9 @@
// .prop('disabled', false) // .prop('disabled', false)
// .removeAttr('disabled') // .removeAttr('disabled')
// .removeClass('disabled'); // .removeClass('disabled');
},
complete: function () {
endRequest();
} }
}); });
}); });
@@ -8,9 +8,6 @@
Layout = null; Layout = null;
ViewData["Title"] = "Bejelentkezés"; ViewData["Title"] = "Bejelentkezés";
} }
<!DOCTYPE html> <!DOCTYPE html>
<html lang="hu"> <html lang="hu">
<head> <head>
@@ -22,39 +19,48 @@
@* <body class="bg-light d-flex justify-content-center align-items-center vh-100"> *@ @* <body class="bg-light d-flex justify-content-center align-items-center vh-100"> *@
<body class="bg-light d-flex flex-column min-vh-100"> <body class="bg-light d-flex flex-column min-vh-100">
<main class="flex-grow-1 d-flex justify-content-center align-items-center"> <main class="flex-grow-1 d-flex justify-content-center align-items-center">
<div class="card shadow p-4" style="min-width: 350px; max-width: 400px; width: 100%;"> <div class="card shadow p-4" style="min-width: 350px; max-width: 400px; width: 100%;">
<h2 class="mb-4 text-center">Bejelentkezés</h2> <h2 class="mb-4 text-center">Bejelentkezés</h2>
<div id="errorMessageContainer" class="alert alert-danger" style="display:none;"></div> <!-- Loading overlay -->
<div id="formLoading" class="position-absolute top-0 start-0 w-100 h-100 d-none align-items-center justify-content-center"
<form method="post"> style="background: rgba(255,255,255,.75); z-index: 10; border-radius: .375rem;">
<meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" /> <div class="text-center">
<input type="hidden" asp-for="User2FADTO.Token2FA" /> <div class="spinner-border" role="status" aria-hidden="true"></div>
<div class="mb-3"> <div class="mt-2 small text-muted">Kérlek várj…</div>
<label asp-for="User2FADTO.UserName" class="form-label">Felhasználónév</label> </div>
<input asp-for="User2FADTO.UserName" class="form-control" />
<span asp-validation-for="User2FADTO.UserName" class="text-danger small"></span>
</div> </div>
<div class="mb-3"> <div id="errorMessageContainer" class="alert alert-danger" style="display:none;"></div>
<label asp-for="User2FADTO.Password" class="form-label">Jelszó</label>
<input asp-for="User2FADTO.Password" type="password" class="form-control" /> <form method="post">
<span asp-validation-for="User2FADTO.Password" class="text-danger small"></span> <meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" />
</div> <input type="hidden" asp-for="User2FADTO.Token2FA" />
<div id="VerificationCode" class="mb-3"> <div class="mb-3">
<label asp-for="User2FADTO.Code" class="form-label">Megerősítő kód</label> <label asp-for="User2FADTO.UserName" class="form-label">Felhasználónév</label>
<input asp-for="User2FADTO.Code" class="form-control" /> <input asp-for="User2FADTO.UserName" class="form-control" />
<span asp-validation-for="User2FADTO.Code" class="text-danger small"></span> <span asp-validation-for="User2FADTO.UserName" class="text-danger small"></span>
</div> </div>
<hr class="mt-4 mb-3 border-secondary">
<div id="login2F1" class="d-grid"> <div class="mb-3">
<button id="Login2F1Btn" type="button" class="btn btn-primary">Bejelentkezés</button> <label asp-for="User2FADTO.Password" class="form-label">Jelszó</label>
</div> <input asp-for="User2FADTO.Password" type="password" class="form-control" />
<div id="login2F2" class="d-grid"> <span asp-validation-for="User2FADTO.Password" class="text-danger small"></span>
<button id="Login2F2Btn" type="button" class="btn btn-primary">Megerősítés</button> </div>
</div> <div id="VerificationCode" class="mb-3">
</form> <label asp-for="User2FADTO.Code" class="form-label">Megerősítő kód</label>
</div> <input asp-for="User2FADTO.Code" class="form-control" />
<span asp-validation-for="User2FADTO.Code" class="text-danger small"></span>
</div>
<hr class="mt-4 mb-3 border-secondary">
<div id="login2F1" class="d-grid">
<button id="Login2F1Btn" type="button" class="btn btn-primary">Bejelentkezés</button>
</div>
<div id="login2F2" class="d-grid">
<button id="Login2F2Btn" type="button" class="btn btn-primary">Megerősítés</button>
</div>
</form>
</div>
</main> </main>
<footer class="border-top footer text-muted"> <footer class="border-top footer text-muted">
<div class="container"> <div class="container">
@@ -68,13 +74,41 @@
<script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script>
<script> <script>
function setLoading(isLoading) {
if (isLoading) {
$('#formLoading').removeClass('d-none').addClass('d-flex');
$('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
// opcionális: inputok tiltása is
// $('#User2FADTO_UserName, #User2FADTO_Password, #User2FADTO_Code').prop('disabled', true);
} else {
$('#formLoading').addClass('d-none').removeClass('d-flex');
$('#Login2F1Btn, #Login2F2Btn').prop('disabled', false);
// $('#User2FADTO_UserName, #User2FADTO_Password, #User2FADTO_Code').prop('disabled', false);
}
}
let requestInFlight = false;
function beginRequest() {
if (requestInFlight) return false;
requestInFlight = true;
setLoading(true);
return true;
}
function endRequest() {
requestInFlight = false;
setLoading(false);
}
$(document).ready(function () { $(document).ready(function () {
$('#VerificationCode').hide(); $('#VerificationCode').hide();
$('#login2F2').hide(); $('#login2F2').hide();
$('#Login2F2Btn').hide(); $('#Login2F2Btn').hide();
$('#Login2F1Btn').on('click', function () { $('#Login2F1Btn').on('click', function () {
// $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true); // $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
if (!beginRequest()) return;
$('#errorMessageContainer').hide().text(''); $('#errorMessageContainer').hide().text('');
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const userName = $('#User2FADTO_UserName').val(); const userName = $('#User2FADTO_UserName').val();
@@ -114,16 +148,20 @@
// .prop('disabled', false) // .prop('disabled', false)
// .removeAttr('disabled') // .removeAttr('disabled')
// .removeClass('disabled'); // .removeClass('disabled');
},
complete: function () {
endRequest();
} }
}); });
}); });
$('#Login2F2Btn').on('click', function () { $('#Login2F2Btn').on('click', function () {
// $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true); // $('#Login2F1Btn, #Login2F2Btn').prop('disabled', true);
if (!beginRequest()) return;
$('#errorMessageContainer').hide().text(''); $('#errorMessageContainer').hide().text('');
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const userName = $('#User2FADTO_UserName').val(); const userName = $('#User2FADTO_UserName').val();
const password = $('#User2FADTO_Password').val(); const password = $('#User2FADTO_Password').val();
const code = $('#User2FADTO_Code').val(); const code = $('#User2FADTO_Code').val();
@@ -147,6 +185,7 @@
if (result.success) { if (result.success) {
window.location.href = `/Index`; window.location.href = `/Index`;
} else { } else {
console.log(result);
$('#errorMessageContainer').text('Hibás felhasználónév vagy jelszó!').show(); $('#errorMessageContainer').text('Hibás felhasználónév vagy jelszó!').show();
// $('#Login2F1Btn, #Login2F2Btn') // $('#Login2F1Btn, #Login2F2Btn')
// .prop('disabled', false) // .prop('disabled', false)
@@ -162,6 +201,9 @@
// .prop('disabled', false) // .prop('disabled', false)
// .removeAttr('disabled') // .removeAttr('disabled')
// .removeClass('disabled'); // .removeClass('disabled');
},
complete: function () {
endRequest();
} }
}); });
}); });
@@ -55,8 +55,8 @@ namespace WorkFlowCheck.Web.Pages.Account
Response.Cookies.Append("AuthToken", token, new CookieOptions Response.Cookies.Append("AuthToken", token, new CookieOptions
{ {
HttpOnly = true, HttpOnly = true,
Secure = true, Secure = HttpContext.Request.IsHttps,
SameSite = SameSiteMode.Strict, SameSite = SameSiteMode.Lax,
Expires = DateTimeOffset.UtcNow.AddDays(1) Expires = DateTimeOffset.UtcNow.AddDays(1)
}); });
@@ -104,7 +104,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#tbCheckPointsEditPage').on('click', '.edit-btn', function () $('#tbCheckPointsEditPage').on('click', '.edit-btn', function ()
@@ -80,7 +80,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newCheckPointBtn').on('click', function () $('#newCheckPointBtn').on('click', function ()
@@ -62,7 +62,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newEquipmentBtn').on('click', function () $('#newEquipmentBtn').on('click', function ()
@@ -79,7 +79,7 @@
$('#tbEquipmentsPage').on('click', '.delete-btn', function () $('#tbEquipmentsPage').on('click', '.delete-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
deleteEntity(table, '/BaseStock/Equipments/EquipmentPage?handler=DeleteEquipment', row.id); deleteEntity(table, '/BaseStock/Equipments/EquipmentsPage?handler=DeleteEquipment', row.id);
}); });
</script> </script>
} }
@@ -68,7 +68,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#tbImageFilesPage').on('click', '.download-btn', function () $('#tbImageFilesPage').on('click', '.download-btn', function ()
@@ -17,14 +17,14 @@
<thead class="table-primary"> <thead class="table-primary">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>Full name</th> <th>@DisplayNameHelper.GetDisplayName(nameof(LocationDTO.FullName), typeof(LocationDTO))</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
</thead> </thead>
<tfoot class="table-light"> <tfoot class="table-light">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>Full name</th> <th>@DisplayNameHelper.GetDisplayName(nameof(LocationDTO.FullName), typeof(LocationDTO))</th>
<th>Action</th> <th>Action</th>
</tr> </tr>
</tfoot> </tfoot>
@@ -59,7 +59,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newLocationBtn').on('click', function () $('#newLocationBtn').on('click', function ()
@@ -68,7 +68,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#tbAuditFilesPage').on('click', '.download-btn', function () $('#tbAuditFilesPage').on('click', '.download-btn', function ()
@@ -68,7 +68,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#tbBusinessFilesPage').on('click', '.download-btn', function () $('#tbBusinessFilesPage').on('click', '.download-btn', function ()
@@ -68,7 +68,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#tbPDFFilesPage').on('click', '.download-btn', function () $('#tbPDFFilesPage').on('click', '.download-btn', function ()
@@ -33,16 +33,23 @@
<div class="tab-pane fade show active" id="general" role="tabpanel"> <div class="tab-pane fade show active" id="general" role="tabpanel">
<form method="post" id="CheckListHeaderForm"> <form method="post" id="CheckListHeaderForm">
<meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" /> <meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" />
<input type="hidden" asp-for="CheckListHeaderDTO.Id" /> <input type="hidden" asp-for="CheckListHeaderDTO.Id" data-type="int" />
<input type="hidden" asp-for="CheckListHeaderDTO.IsEditable" data-type="bool" />
<input type="hidden" asp-for="CheckListHeaderDTO.IsStorno" data-type="bool" />
<input type="hidden" asp-for="CheckListHeaderDTO.GuidNumber" />
<input type="hidden" asp-for="CheckListHeaderDTO.CheckListTemplateHeaderId" data-type="int" />
<input type="hidden" asp-for="CheckListHeaderDTO.UserId" data-type="int" />
<input type="hidden" name="CheckListHeaderDTO.DateExecution" value="@Model.CheckListHeaderDTO.DateExecution.ToString("yyyy-MM-dd")" />
<input type="hidden" asp-for="CheckListHeaderDTO.AcceptUserId" data-type="int" />
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<label asp-for="CheckListHeaderDTO.DocumentNumber"></label> <label asp-for="CheckListHeaderDTO.DocumentNumber"></label>
<input asp-for="CheckListHeaderDTO.DocumentNumber" class="form-control" readonly/> <input asp-for="CheckListHeaderDTO.DocumentNumber" class="form-control" readonly />
<span asp-validation-for="CheckListHeaderDTO.DocumentNumber" class="text-danger"></span> <span asp-validation-for="CheckListHeaderDTO.DocumentNumber" class="text-danger"></span>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<label asp-for="CheckListHeaderDTO.CheckStatus"></label> <label asp-for="CheckListHeaderDTO.CheckStatus"></label>
<select asp-for="CheckListHeaderDTO.CheckStatus" class="form-control" asp-items="Model.CheckStatus" readonly></select> <select asp-for="CheckListHeaderDTO.CheckStatus" class="form-control" asp-items="Model.CheckStatus" readonly data-type="int"></select>
<span asp-validation-for="CheckListHeaderDTO.CheckStatus" class="text-danger"></span> <span asp-validation-for="CheckListHeaderDTO.CheckStatus" class="text-danger"></span>
</div> </div>
</div> </div>
@@ -166,7 +173,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
@@ -201,8 +208,8 @@
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
var formData = getFormAsNestedObject('#CheckListHeaderForm'); var formData = getFormAsNestedObject('#CheckListHeaderForm');
const $form = $('#CheckListHeaderForm'); const $form = $('#CheckListHeaderForm');
formData.CheckListHeader.RoleDTO=[]; formData.CheckListHeaderDTO.CheckListRowDTO=[];
if ($form.valid()) if ($form.valid())
{ {
@@ -213,13 +220,24 @@
'X-CSRF-TOKEN': csrfToken, 'X-CSRF-TOKEN': csrfToken,
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
data: JSON.stringify(formData.CheckListHeader), data: JSON.stringify(formData.CheckListHeaderDTO),
success: function (response) { success: function (response) {
showMessageModal({ if (response.success)
title: 'Figyelmem!', {
message: 'Sikeres mentés.', showMessageModal({
okText: 'Értettem' title: 'Figyelmem!',
}); message: 'Sikeres mentés.',
okText: 'Értettem'
});
}
else
{
showMessageModal({
title: 'Figyelmem, HIBA!',
message: 'Sikertelen mentés.',
okText: 'Értettem'
});
}
}, },
error: function (xhr, status, error) { error: function (xhr, status, error) {
// Hiba esetén // Hiba esetén
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Serilog;
using System.Globalization; using System.Globalization;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.Web.Services.Interfaces; using WorkFlowCheck.Web.Services.Interfaces;
@@ -32,6 +33,27 @@ namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
CheckStatus = _checkListService.GetCheckStatus(); CheckStatus = _checkListService.GetCheckStatus();
BuildCheckListHeaderInfo(); BuildCheckListHeaderInfo();
} }
public async Task<IActionResult> OnPostSave([FromBody] CheckListHeaderDTO checkListHeaderDTO)
{
try
{
var result = await _checkListService.UpdateCheckListHeader(checkListHeaderDTO);
if (result.IsSuccess)
{
return new JsonResult(new { success = true });
}
else
{
return new JsonResult(new { success = false });
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
return new JsonResult(new { success = false });
}
private void BuildCheckListHeaderInfo() private void BuildCheckListHeaderInfo()
{ {
CheckListHeaderInfoDTO = new CheckListHeaderInfoDTO(); CheckListHeaderInfoDTO = new CheckListHeaderInfoDTO();
@@ -52,7 +74,7 @@ namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
CheckListHeaderInfoDTO.EmptyAnswerCount = result.EmptyAnswerCount; CheckListHeaderInfoDTO.EmptyAnswerCount = result.EmptyAnswerCount;
if (CheckListHeaderInfoDTO.TotalRowCount > 0) if (CheckListHeaderInfoDTO.TotalRowCount > 0)
{ {
CheckListHeaderInfoDTO.ReadyPercent = ((CheckListHeaderInfoDTO.TotalRowCount - CheckListHeaderInfoDTO.EmptyAnswerCount) / CheckListHeaderInfoDTO.TotalRowCount * 100) CheckListHeaderInfoDTO.ReadyPercent = ((double)(CheckListHeaderInfoDTO.TotalRowCount - CheckListHeaderInfoDTO.EmptyAnswerCount) / CheckListHeaderInfoDTO.TotalRowCount * 100)
.ToString("0.00", new CultureInfo("hu-HU")) + " %"; ; .ToString("0.00", new CultureInfo("hu-HU")) + " %"; ;
} }
} }
@@ -64,7 +86,7 @@ namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
{ {
foreach (var item in CheckListHeaderDTO.CheckListRowDTO) foreach (var item in CheckListHeaderDTO.CheckListRowDTO)
{ {
if (item.CheckListTemplateRowDTO?.AnswerType == "P") if (item.CheckListTemplateRowDTO?.AnswerType == "P" || item.CheckListTemplateRowDTO?.AnswerType == "PN")
{ {
if (item.Photo != null && item.Photo.Length > 0) if (item.Photo != null && item.Photo.Length > 0)
{ {
@@ -5,7 +5,14 @@
@using Microsoft.AspNetCore.Antiforgery @using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery Antiforgery @inject IAntiforgery Antiforgery
@{ @{
ViewData["Title"] = "Ellenőrzések"; ViewData["Title"] = Model.Mode switch
{
0 => "Ellenőrzések (folyamatban)",
1 => "Ellenőrzések (beküldött)",
2 => "Ellenőrzések (lezárt)",
3 => "Ellenőrzések (jóváhagyott)",
_ => "Ellenőrzések (összes)"
};
} }
<h1>@ViewData["Title"]</h1> <h1>@ViewData["Title"]</h1>
<meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" /> <meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" />
@@ -49,10 +56,17 @@
@section Scripts { @section Scripts {
<script> <script>
let currentMode = @Model.Mode;
const table = new DataTable('#tbCheckListHeadersPage', { const table = new DataTable('#tbCheckListHeadersPage', {
serverSide: true,
ordering: true,
order: [],
ajax: { ajax: {
url: "@Url.Page("./CheckListHeaderPage", "LoadCheckListHeaders")", url: "@Url.Page("./CheckListHeaderPage", "LoadCheckListHeaders")",
type: "GET", type: "POST",
data: function (d) {
d.mode = currentMode;
},
dataSrc : "data" dataSrc : "data"
}, },
columns: [ columns: [
@@ -104,7 +118,7 @@
], ],
processing: true, processing: true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newCheckListHeaderBtn').on('click', function () $('#newCheckListHeaderBtn').on('click', function ()
@@ -179,7 +193,7 @@
} }
}); });
}); });
$('#tbCheckListHeadersPage').on('click', '.accept-btn', function () $('#tbCheckListHeadersPage').on('click', '.accept-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
@@ -265,7 +279,7 @@
} }
}); });
}); });
$('#tbCheckListHeadersPage').on('click', '.unblock-btn', function () $('#tbCheckListHeadersPage').on('click', '.unblock-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
@@ -309,6 +323,6 @@
}); });
}); });
</script> </script>
} }
@@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@@ -9,11 +9,12 @@ using System.Security.Claims;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
{ {
[IgnoreAntiforgeryToken]
public class CheckListHeaderPageModel : PageModel public class CheckListHeaderPageModel : PageModel
{ {
private readonly ILogger<IndexModel> _logger; private readonly ILogger<IndexModel> _logger;
private readonly ICheckListService _checkListService; private readonly ICheckListService _checkListService;
public int Mode { get; private set; }
public List<SelectListItem> CheckStatus { get; set; } public List<SelectListItem> CheckStatus { get; set; }
public CheckListHeaderPageModel(ILogger<IndexModel> logger, ICheckListService checkListService) public CheckListHeaderPageModel(ILogger<IndexModel> logger, ICheckListService checkListService)
@@ -21,16 +22,57 @@ namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
_logger = logger; _logger = logger;
_checkListService = checkListService; _checkListService = checkListService;
} }
public async Task OnGet() public async Task OnGet(int mode = 0)
{ {
Mode = mode;
CheckStatus = _checkListService.GetCheckStatus(); CheckStatus = _checkListService.GetCheckStatus();
} }
public async Task<JsonResult> OnGetLoadCheckListHeaders() public async Task<JsonResult> OnPostLoadCheckListHeadersAsync()
{ {
var results = await _checkListService.GetAllCheckListHeaderAsync(); var mode = int.Parse(Request.Form["mode"]);
return new JsonResult(new { data = results });
var draw = int.Parse(Request.Form["draw"]);
var start = int.Parse(Request.Form["start"]);
var length = int.Parse(Request.Form["length"]);
var search = Request.Form["search[value]"].ToString();
var orderColIndexStr = Request.Query["order[0][column]"].ToString();
var orderDir = Request.Query["order[0][dir]"].ToString(); // "asc" / "desc"
int? orderColIndex = int.TryParse(orderColIndexStr, out var idx) ? idx : null;
// columns[x][data] alapján tudod, melyik mezőt rendezi
string? orderColData = null;
if (orderColIndex.HasValue)
orderColData = Request.Query[$"columns[{orderColIndex.Value}][data]"].ToString();
//var results = await _checkListService.GetAllCheckListHeaderAsync(mode);
var dataTablesRequest = new Common.DataTables.DataTablesRequest()
{
Mode = mode,
Length = length,
Start = start,
Draw = draw,
};
dataTablesRequest.Search.Value = search;
var results = await _checkListService.GetFilteredCheckListHeaderAsync(dataTablesRequest);
return new JsonResult(new
{
draw = draw,
recordsTotal = results.Total,
recordsFiltered = results.Filtered,
data = results.Data
});
//var results = await _checkListService.GetAllCheckListHeaderAsync(mode);
//return new JsonResult(new
//{
// draw = draw,
// data = results
//});
} }
public async Task<IActionResult> OnGetCreatePDF(int id) public async Task<IActionResult> OnGetCreatePDF(int id)
@@ -100,8 +142,8 @@ namespace WorkFlowCheck.Web.Pages.CheckList.CheckListHeader
public async Task<IActionResult> OnPostClose([FromBody] CheckListHeaderCloseDTO checkListHeaderCloseDTO) public async Task<IActionResult> OnPostClose([FromBody] CheckListHeaderCloseDTO checkListHeaderCloseDTO)
{ {
var userid = User.FindFirstValue(ClaimTypes.NameIdentifier); var userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
checkListHeaderCloseDTO.UserId=int.Parse(userid); ; checkListHeaderCloseDTO.UserId = int.Parse(userid); ;
var response = await _checkListService.CloseCheckListHeader(checkListHeaderCloseDTO); var response = await _checkListService.CloseCheckListHeader(checkListHeaderCloseDTO);
if (response.IsSuccess) if (response.IsSuccess)
@@ -116,7 +116,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
@@ -47,7 +47,7 @@
{ data: "shortName" }, { data: "shortName" },
{ data: "description" }, { data: "description" },
{ data: null, render: function (data, type, row) { { data: null, render: function (data, type, row) {
return renderActionButtons(row.id); return renderActionButtonsforCheckListTemplateHeader(row.id);
}} }}
], ],
columnDefs: [ columnDefs: [
@@ -63,20 +63,63 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newCheckListTemplateHeaderBtn').on('click', function () $('#newCheckListTemplateHeaderBtn').on('click', function ()
{ {
console.log('New button clicked!"');
window.location.href = `@Url.Page("./CheckListTemplateHeaderEditPage")?id=0`; window.location.href = `@Url.Page("./CheckListTemplateHeaderEditPage")?id=0`;
}); });
$('#tbCheckListTemplateHeadersPage').on('click', '.edit-btn', function () $('#tbCheckListTemplateHeadersPage').on('click', '.edit-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
window.location.href = `@Url.Page("./CheckListTemplateHeaderEditPage")?id=${row.id}`; 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 () $('#tbCheckListTemplateHeadersPage').on('click', '.delete-btn', function ()
{ {
@@ -27,5 +27,10 @@ namespace WorkFlowCheck.Web.Pages.CheckListTemplate.CheckListTemplateHeader
var isSuccess = await _checkListService.DeleteCheckListTemplateHeader(id); var isSuccess = await _checkListService.DeleteCheckListTemplateHeader(id);
return new JsonResult(new { result = isSuccess }); return new JsonResult(new { result = isSuccess });
} }
public async Task<JsonResult> OnGetCloneCheckListTemplateHeader(int id)
{
var isSuccess = await _checkListService.CloneCheckListTemplateHeader(id);
return new JsonResult(new { result = isSuccess });
}
} }
} }
+26 -2
View File
@@ -1,8 +1,32 @@
@page @page
@model PrivacyModel @model PrivacyModel
@{ @{
ViewData["Title"] = "Privacy Policy"; ViewData["Title"] = "Adatvédelmi tájékoztató";
} }
<h1>@ViewData["Title"]</h1> <h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p> <p>Ez az adatvédelmi tájékoztató bemutatja, hogy az oldal hogyan kezeli a felhasználók személyes adatait.</p>
<h2>Gyűjtött adatok</h2>
<ul>
<li>Felhasználó neve</li>
<li>Felhasználó e-mail címe</li>
<li>Bejelentkezési azonosító (JWT token a böngésző cookie-jában tárolva)</li>
</ul>
<h2>Adatok felhasználása</h2>
<p>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.</p>
<h2>Adatok megőrzése</h2>
<p>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.</p>
<h2>Adatok továbbítása</h2>
<p>Az adatokat harmadik fél számára nem adjuk át, kivéve jogszabályi kötelezettség esetén.</p>
<h2>Cookie-k</h2>
<p>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.</p>
<h2>Felhasználói jogok</h2>
<p>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.</p>
<p>Amennyiben kérdése van az adatkezeléssel kapcsolatban, kérjük, vegye fel velünk a kapcsolatot.</p>
@@ -49,7 +49,26 @@
Ellenőrzési adatok Ellenőrzési adatok
</a> </a>
<ul class="dropdown-menu" aria-labelledby="checkListDropdown"> <ul class="dropdown-menu" aria-labelledby="checkListDropdown">
<li><a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage">Ellenőrzések</a></li> <li>
<a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage"
asp-route-mode="0">Ellenőrzések (folyamatban)</a>
</li>
<li>
<a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage"
asp-route-mode="1">Ellenőrzések (beküldött)</a>
</li>
<li>
<a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage"
asp-route-mode="3">Ellenőrzések (jóváhagyott)</a>
</li>
<li>
<a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage"
asp-route-mode="2">Ellenőrzések (lezárt)</a>
</li>
<li>
<a class="dropdown-item" asp-area="" asp-page="/CheckList/CheckListHeader/CheckListHeaderPage"
asp-route-mode="4">Ellenőrzések (összes)</a>
</li>
<li><hr class="dropdown-divider"></li> <!-- EZ AZ ELVÁLASZTÓ VONAL --> <li><hr class="dropdown-divider"></li> <!-- EZ AZ ELVÁLASZTÓ VONAL -->
<li><a class="dropdown-item" asp-area="" asp-page="/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage">Ellenőrzési sablonok</a></li> <li><a class="dropdown-item" asp-area="" asp-page="/CheckListTemplate/CheckListTemplateHeader/CheckListTemplateHeaderPage">Ellenőrzési sablonok</a></li>
</ul> </ul>
@@ -67,9 +86,7 @@
<li><a class="dropdown-item" asp-area="" asp-page="/UserAndRole/RoleCheckPointsPage">Szabályok - Ellenőrzési pontok</a></li> <li><a class="dropdown-item" asp-area="" asp-page="/UserAndRole/RoleCheckPointsPage">Szabályok - Ellenőrzési pontok</a></li>
</ul> </ul>
</li> </li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul> </ul>
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item dropdown"> <li class="nav-item dropdown">
@@ -87,6 +104,10 @@
Jelszó módosítása Jelszó módosítása
</a> </a>
</li> </li>
<li><hr class="dropdown-divider"></li> <!-- EZ AZ ELVÁLASZTÓ VONAL -->
<li class="dropdown-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Adatvédelmi tájékoztatás</a>
</li>
</ul> </ul>
</li> </li>
@@ -182,7 +203,7 @@
<footer class="border-top footer text-muted"> <footer class="border-top footer text-muted">
<div class="container"> <div class="container">
&copy; @(DateTime.Now.Year) - Workflow Check App - Version @(SystemHelper.ProgramVersion) (@(SystemHelper.DatabaseName))<a asp-area="" asp-page="/Privacy">Privacy</a> &copy; @(DateTime.Now.Year) - Workflow Check App - Version @(SystemHelper.ProgramVersion) (@(SystemHelper.DatabaseName))<a asp-area="" asp-page="/Privacy"> Adatvédelmi tájékoztatás</a>
</div> </div>
</footer> </footer>
@@ -3,7 +3,7 @@
@using Microsoft.AspNetCore.Antiforgery @using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery Antiforgery @inject IAntiforgery Antiforgery
@{ @{
ViewData["Title"] = "Ellenőrzési pont"; ViewData["Title"] = "Szabály - ellenőrzési sablon";
var RoleCheckListTemplateHeaderId = Model.RoleCheckListTemplateHeaderDTO.Id; var RoleCheckListTemplateHeaderId = Model.RoleCheckListTemplateHeaderDTO.Id;
var urlPost = Url.Page("./RoleCheckListTemplateHeaderEditPage", "Save"); var urlPost = Url.Page("./RoleCheckListTemplateHeaderEditPage", "Save");
} }
@@ -15,18 +15,18 @@
<thead class="table-primary"> <thead class="table-primary">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>Role name</th> <th>Szabály neve</th>
<th>Template name</th> <th>Ellenőrzési sablon neve</th>
<th>Enabled</th> <th>Engedélyezve?</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
</thead> </thead>
<tfoot class="table-light"> <tfoot class="table-light">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>Role name</th> <th>Szabály neve</th>
<th>Template name</th> <th>Ellenőrzési sablon neve</th>
<th>Enabled</th> <th>Engedélyezve?</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
</tfoot> </tfoot>
@@ -72,7 +72,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newRoleCheckListTemplateHeadersBtn').on('click', function () $('#newRoleCheckListTemplateHeadersBtn').on('click', function ()
@@ -90,17 +90,7 @@
$('#tbRoleCheckListTemplateHeadersPage').on('click', '.delete-btn', function () $('#tbRoleCheckListTemplateHeadersPage').on('click', '.delete-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
console.log(row); deleteEntity(table, '/UserAndRole/RoleCheckListTemplateHeadersPage?handler=DeleteRoleCheckListTemplateHeader', row.id);
showConfirmModal({
title: 'Törlés megerősítése',
message: 'Biztosan törölni szeretnéd ezt az elemet?',
okText: 'Törlés',
cancelText: 'Mégsem'
}).then(function(result) {
if(result === 'ok') {
console.log('Törlés végrehajtva');
}
});
}); });
</script> </script>
} }
@@ -21,5 +21,10 @@ namespace WorkFlowCheck.Web.Pages.UserAndRole
var results = await _userService.GetAllRoleCheckListTemplates(); var results = await _userService.GetAllRoleCheckListTemplates();
return new JsonResult(new { data = results }); return new JsonResult(new { data = results });
} }
public async Task<JsonResult> OnGetDeleteRoleCheckListTemplateHeader(int id)
{
var isSuccess = await _userService.DeleteRoleCheckListTemplateHeader(id);
return new JsonResult(new { result = isSuccess });
}
} }
} }
@@ -3,7 +3,7 @@
@using Microsoft.AspNetCore.Antiforgery @using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery Antiforgery @inject IAntiforgery Antiforgery
@{ @{
ViewData["Title"] = "Ellenőrzési pont"; ViewData["Title"] = "Szabály - Ellenőrzési pont";
var RoleCheckPointId = Model.RoleCheckPointDTO.Id; var RoleCheckPointId = Model.RoleCheckPointDTO.Id;
var urlPost = Url.Page("./RoleCheckPointEditPage", "Save"); var urlPost = Url.Page("./RoleCheckPointEditPage", "Save");
} }
@@ -96,6 +96,8 @@
} }
}); });
$(document).ready(function () { $(document).ready(function () {
const $form = $("#RoleCheckPointForm"); const $form = $("#RoleCheckPointForm");
@@ -71,5 +71,6 @@ namespace WorkFlowCheck.Web.Pages.UserAndRole
this.RoleCheckPoints.Add(new SelectListItem() { Value = CheckPoint.Id.ToString(), Text = CheckPoint.ShortName }); this.RoleCheckPoints.Add(new SelectListItem() { Value = CheckPoint.Id.ToString(), Text = CheckPoint.ShortName });
} }
} }
} }
} }
@@ -3,7 +3,7 @@
@using WorkFlowCheck.Common.Helper @using WorkFlowCheck.Common.Helper
@using WorkFlowCheck.Common.DTO @using WorkFlowCheck.Common.DTO
@{ @{
ViewData["Title"] = "Szabályok - Ellenőrzési sablonok"; ViewData["Title"] = "Szabályok - Ellenőrzési pontok";
} }
<h1>@ViewData["Title"]</h1> <h1>@ViewData["Title"]</h1>
@@ -17,8 +17,8 @@
<thead class="table-primary"> <thead class="table-primary">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.RoleDTO.RoleName), typeof(RoleCheckPointDTO))</th> <th>Szabály @DisplayNameHelper.GetDisplayName(nameof(RoleDTO.RoleName), typeof(RoleDTO))</th>
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.CheckPointDTO.ShortName), typeof(RoleCheckPointDTO))</th> <th>Ellenőrzési pont @DisplayNameHelper.GetDisplayName(nameof(CheckPointDTO.ShortName), typeof(CheckPointDTO))</th>
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.Enabled), typeof(RoleCheckPointDTO))</th> <th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.Enabled), typeof(RoleCheckPointDTO))</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
@@ -26,8 +26,8 @@
<tfoot class="table-light"> <tfoot class="table-light">
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.RoleDTO.RoleName), typeof(RoleCheckPointDTO))</th> <th>Szabály @DisplayNameHelper.GetDisplayName(nameof(RoleDTO.RoleName), typeof(RoleDTO))</th>
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.CheckPointDTO.ShortName), typeof(RoleCheckPointDTO))</th> <th>Ellenőrzési pont @DisplayNameHelper.GetDisplayName(nameof(CheckPointDTO.ShortName), typeof(CheckPointDTO))</th>
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.Enabled), typeof(RoleCheckPointDTO))</th> <th>@DisplayNameHelper.GetDisplayName(nameof(RoleCheckPointDTO.Enabled), typeof(RoleCheckPointDTO))</th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
@@ -74,7 +74,7 @@
], ],
processing:true, processing:true,
language: { url: '//cdn.datatables.net/plug-ins/2.2.2/i18n/hu.json',} language: { url: '/lib/datatables/datatables.hu.json',}
}); });
$('#newRoleCheckPointsBtn').on('click', function () $('#newRoleCheckPointsBtn').on('click', function ()
@@ -91,18 +91,8 @@
$('#tbRoleCheckPointsPage').on('click', '.delete-btn', function () $('#tbRoleCheckPointsPage').on('click', '.delete-btn', function ()
{ {
const row = table.row($(this).closest('tr')).data(); const row = table.row($(this).closest('tr')).data();
console.log(row); deleteEntity(table, '/UserAndRole/RoleCheckPointsPage?handler=DeleteRoleCheckPoint', row.id);
showConfirmModal({
title: 'Törlés megerősítése',
message: 'Biztosan törölni szeretnéd ezt az elemet?',
okText: 'Törlés',
cancelText: 'Mégsem'
}).then(function(result) {
if(result === 'ok') {
console.log('Törlés végrehajtva');
}
});
}); });
</script> </script>
} }
@@ -21,5 +21,10 @@ namespace WorkFlowCheck.Web.Pages.UserAndRole
var results = await _userService.GetAllRoleCheckPoints(); var results = await _userService.GetAllRoleCheckPoints();
return new JsonResult(new { data = results }); return new JsonResult(new { data = results });
} }
public async Task<JsonResult> OnGetDeleteRoleCheckPoint(int id)
{
var isSuccess = await _userService.DeleteRoleCheckPoint(id);
return new JsonResult(new { result = isSuccess });
}
} }
} }

Some files were not shown because too many files have changed in this diff Show More