Compare commits
196 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4304617181 | |||
| 7d6eb7bc60 | |||
| d4b2a45e7b | |||
| c9f47adab4 | |||
| 2ed939615c | |||
| 362e3b0aff | |||
| c02093ebec | |||
| cdcf627115 | |||
| 231f27292b | |||
| cbd3e42f0a | |||
| fa50214527 | |||
| 5d09b5f998 | |||
| dff6bf2201 | |||
| 305ae11d52 | |||
| 6e9fb8c6d1 | |||
| b6b9fc8005 | |||
| 026318ce1f | |||
| 0bd833ee83 | |||
| 43e62d31df | |||
| e214d44b5c | |||
| e125915bd5 | |||
| 3b4b4881f5 | |||
| c71bd6606b | |||
| 2c187849da | |||
| 02aaaeb1e7 | |||
| 3e5d40cd55 | |||
| c860042443 | |||
| cbcb6e3dba | |||
| 47afa9c546 | |||
| 5554cf5b27 | |||
| f0866f4197 | |||
| d00a8347d4 | |||
| 27eaf83f07 | |||
| 0364f264ba | |||
| e6f3e1715b | |||
| e6ebbfcc81 | |||
| 9b6ea3c983 | |||
| 08e037ac45 | |||
| a2d4ab9434 | |||
| 2004452f30 | |||
| edfb857755 | |||
| df1f541247 | |||
| ca255b10d4 | |||
| eee5b42e8d | |||
| d8aefaef96 | |||
| 7640156f85 | |||
| 69407c87fb | |||
| 5724eefa8e | |||
| cd8040686a | |||
| 07f840beb7 | |||
| 1b9ddd61b3 | |||
| 9cead83478 | |||
| d0407381d2 | |||
| 865c892e26 | |||
| d27d68a6c8 | |||
| 9d02f7208d | |||
| a8652e9df6 | |||
| c734bdce8d | |||
| 921d0b950b | |||
| 3eb429c46f | |||
| 51211b42b2 | |||
| 8d0e73a0bc | |||
| ea06b2732f | |||
| d92ee756cc | |||
| 2bffb77d2b | |||
| f4c7236efc | |||
| ddd9ba9f05 | |||
| fbfc20f282 | |||
| 425b8b84cc | |||
| 183f177a70 | |||
| 8ee0f6bcbc | |||
| 1bd8351de4 | |||
| 153597f44e | |||
| d85a98fe37 | |||
| 94f4697d64 | |||
| 46deed6787 | |||
| 2516d18f02 | |||
| 80587c76cd | |||
| be6bf2286b | |||
| 794ae6df67 | |||
| fda9430a7d | |||
| 0b16942154 | |||
| 2f5c4d822c | |||
| 2ecad55883 | |||
| 1a75678882 | |||
| 72289ed173 | |||
| a759ff89e0 | |||
| 07fbdb3075 | |||
| 4304ffbb52 | |||
| 54860393cb | |||
| 1f9f999240 | |||
| 6a43370a88 | |||
| f848addb54 | |||
| 691bf16289 | |||
| 7c5442ef76 | |||
| 92add869a8 | |||
| 1648ad0349 | |||
| 5f5aa727e4 | |||
| 76b3503429 | |||
| 498c6ee383 | |||
| 3f1e39c64e | |||
| 367cfbe468 | |||
| 4c65cb91fb | |||
| 4a44b3315b | |||
| 1831db5cbb | |||
| 847e502a7f | |||
| 8052250d86 | |||
| f653485cd2 | |||
| 6113a07042 | |||
| bf7d1073fb | |||
| b88a6483e2 | |||
| 1168167837 | |||
| 36d7674304 | |||
| c0e092b2fe | |||
| 3896778ba8 | |||
| 5a53cec01b | |||
| 78b8eac671 | |||
| a318d45cde | |||
| 6a57c5e7bc | |||
| 65931d29f9 | |||
| 291cbac5bc | |||
| 07b953dcd5 | |||
| bfc033108f | |||
| 3a149e679f | |||
| 7fc7aea82e | |||
| 5e94e828ec | |||
| dfee393e27 | |||
| bd7bdf3d72 | |||
| f8fca473f3 | |||
| 1fbc8b314a | |||
| 641eed422c | |||
| 17f27d0c8e | |||
| f4142aafdd | |||
| a4c29f26b1 | |||
| 291338a61e | |||
| 77f0550e83 | |||
| 1a00fe1a13 | |||
| 23275cc614 | |||
| e9de43db2b | |||
| deee79e8f7 | |||
| 833e9e2a93 | |||
| cd81220658 | |||
| e7671572da | |||
| 3d272c4fdb | |||
| 5bdd3bd601 | |||
| 2e593c9fdc | |||
| 49268c614f | |||
| d9b55223a7 | |||
| ef4586df24 | |||
| f8ee0e08e8 | |||
| 68da69ed64 | |||
| 82fea86b57 | |||
| 429c4c0086 | |||
| 00073c0199 | |||
| a067f706f1 | |||
| 625aab6f25 | |||
| 9a6686e210 | |||
| c60bb11e4a | |||
| 9ada45cd61 | |||
| 8b5ff27ef6 | |||
| edfe294cd4 | |||
| 321fe7a349 | |||
| da08bdfaa0 | |||
| 9f6dd2bf7d | |||
| 533db060b9 | |||
| b7172a7d85 | |||
| 0cb8a06741 | |||
| bbd575c032 | |||
| 5002d498cb | |||
| 2a706243a7 | |||
| fa89c11f67 | |||
| 9097b203a0 | |||
| f7f7e8962c | |||
| 20ea9acda0 | |||
| b086972605 | |||
| a4de1bd223 | |||
| 3a6c8836ce | |||
| 6bbbeb389d | |||
| 4682b22a14 | |||
| 5c810d7b78 | |||
| b830d7a54e | |||
| 9cdd57feab | |||
| 070ddf25ba | |||
| 807d74acf8 | |||
| b47981c46f | |||
| 56af3748f6 | |||
| 6ac492164c | |||
| 93d8ec8ceb | |||
| 8ff5749075 | |||
| ac634a27f1 | |||
| ded174dfda | |||
| 3ea72f9371 | |||
| b5694319cd | |||
| 52a52b3993 | |||
| 6f243eb188 | |||
| 28a7c403d9 |
+81
-4
@@ -69,6 +69,7 @@ stages:
|
||||
- release
|
||||
|
||||
|
||||
# ---------- BUILD ----------
|
||||
CORE.Api:build:
|
||||
stage: build
|
||||
tags:
|
||||
@@ -82,7 +83,6 @@ CORE.Api:build:
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
# ---------- BUILD ----------
|
||||
CORE.WLOG:build:
|
||||
stage: build
|
||||
tags:
|
||||
@@ -109,6 +109,19 @@ CORE.Smart:build:
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
CORE.ADM:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: GPW.CORE.ADM
|
||||
SOL_NAME: GPW.CORE.ADM
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore "$env:SOL_NAME.sln"
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
# ---------- STAGING ----------
|
||||
CORE.Api:staging:
|
||||
stage: staging
|
||||
@@ -164,6 +177,27 @@ CORE.Smart:staging:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
CORE.ADM:staging:
|
||||
stage: staging
|
||||
tags:
|
||||
- win
|
||||
environment:
|
||||
name: staging
|
||||
url: https://iis01.egalware.com/GPW/CORE.ADM8
|
||||
variables:
|
||||
APP_NAME: GPW.CORE.ADM
|
||||
SOL_NAME: GPW.CORE.ADM
|
||||
only:
|
||||
- develop
|
||||
needs: ["CORE.ADM:build"]
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore "$env:SOL_NAME.sln"
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
|
||||
# ---------- DEPLOY ----------
|
||||
CORE.Api:deploy:
|
||||
stage: deploy
|
||||
@@ -203,6 +237,7 @@ CORE.WLOG:deploy:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
# IIS PROD
|
||||
- dotnet publish -p:PublishProfile=IIS-PROD.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- dotnet publish -p:PublishProfile=IIS-PROD8.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
CORE.Smart:deploy:
|
||||
stage: deploy
|
||||
@@ -224,6 +259,26 @@ CORE.Smart:deploy:
|
||||
# IIS INT
|
||||
- dotnet publish -p:PublishProfile=IIS-INT.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
CORE.ADM:deploy:
|
||||
stage: deploy
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: GPW.CORE.ADM
|
||||
SOL_NAME: GPW.CORE.ADM
|
||||
only:
|
||||
- main
|
||||
needs: ["CORE.ADM:build"]
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore "$env:SOL_NAME.sln"
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
# IIS PROD
|
||||
- dotnet publish -p:PublishProfile=IIS-PROD.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
|
||||
# ---------- RELEASE ----------
|
||||
CORE.Api:release:
|
||||
stage: release
|
||||
tags:
|
||||
@@ -251,7 +306,6 @@ CORE.Api:release:
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish GPW.CORE.Api/GPW.CORE.Api.csproj
|
||||
|
||||
# ---------- RELEASE ----------
|
||||
CORE.WLOG:release:
|
||||
stage: release
|
||||
tags:
|
||||
@@ -276,7 +330,6 @@ CORE.WLOG:release:
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
|
||||
|
||||
|
||||
CORE.Smart:release:
|
||||
stage: release
|
||||
tags:
|
||||
@@ -299,4 +352,28 @@ CORE.Smart:release:
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
|
||||
# - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
|
||||
|
||||
# CORE.ADM:release:
|
||||
# stage: release
|
||||
# tags:
|
||||
# - win
|
||||
# variables:
|
||||
# APP_NAME: GPW.CORE.ADM
|
||||
# SOL_NAME: GPW.CORE.ADM
|
||||
# only:
|
||||
# - main
|
||||
# except:
|
||||
# - branches
|
||||
# needs: ["CORE.ADM:build"]
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - publish/
|
||||
# script:
|
||||
# - dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
# - dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish -p:verbosity=quiet
|
||||
# # qui il deploy su nexus...
|
||||
# - *hashBuild
|
||||
# - *nexusUpload
|
||||
# # script:
|
||||
# # - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/GPW.CORE.WRKLOG/bin/Debug/net6.0/GPW.CORE.WRKLOG.dll",
|
||||
"program": "${workspaceFolder}/GPW.CORE.WRKLOG/bin/Debug/net8.0/GPW.CORE.WRKLOG.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/GPW.CORE.WRKLOG",
|
||||
"stopAtEntry": false,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# GPW_NEXT Agent Instructions
|
||||
|
||||
## Architecture Overview
|
||||
- **Multi-Project Structure**: The solution consists of several interconnected projects.
|
||||
- **Smart10 Module**:
|
||||
- `GPW.CORE.Smart10`: The ASP.NET Core Server project. Hosts API Controllers and implements Server-side logic.
|
||||
- `GPW.CORE.Smart10.Client`: The Blazor WebAssembly project. Contains UI components and client-side services that consume APIs.
|
||||
- **Data Layer**:
|
||||
- `GPW.CORE.Data`: Contains EF Core models (`DbModels`), `GPWContext`, and the `GPWController` which acts as a data access layer.
|
||||
- `GPW.CORE.Dto`: Contains Data Transfer Objects used for communication between Client and Server to avoid direct dependency on EF Core models.
|
||||
- **Services Pattern**:
|
||||
- **Client-side**: Services implement interfaces (e.g., `ITimbraturesService`) and use `HttpClient` to call REST endpoints.
|
||||
- **Server-side (Prerendering)**: To support Blazor Web App prerendering, implement the same interfaces in the Server project using a "Server-side" implementation that calls `CoreSmartDataService` directly instead of via HTTP.
|
||||
|
||||
## Development Workflows
|
||||
|
||||
### Implementing New Features (Smart10 Example)
|
||||
1. **DTO**: Define the required data structure in `GPW.CORE.Dto`.
|
||||
2. **Server Data Access**: Ensure `CoreSmartDataService` (in `GPW.CORE.Smart10.Data`) or `GPWController` (in `GPW.CORE.Data`) has the necessary business logic.
|
||||
3. **API Controller**: Add an endpoint in `GPW.CORE.Smart10\Controllers` to expose the data via REST.
|
||||
4. **Client Interface**: Add the method signature to the interface in `GPW.CORE.Smart10.Client\Services`.
|
||||
5. **Client Implementation**: Implement the service in `GPW.CORE.Smart10.Client\Services` using `HttpClient`.
|
||||
6. **Server Implementation (Prerendering Support)**: Create a server-side implementation of the interface in `GPW.CORE.Smart10\Services` that calls `CoreSmartDataService` directly.
|
||||
7. **Dependency Injection**:
|
||||
- **Client**: Register the `HttpClient`-based service in `GPW.CORE.Smart10.Client\Program.cs`.
|
||||
- **Server**: Register the direct-access service in `GPW.CORE.Smart10\Program.cs`.
|
||||
|
||||
### Testing & Verification
|
||||
- **UI Testing**: Use the `Test...razor` pages in the Client project to validate end-to-end flows (Insert, Update, Delete, Search).
|
||||
- **Manual Check**: For UI changes, verify the interaction between `@bind` and event handlers (use `@bind:after` for .NET 7+).
|
||||
|
||||
## Key Constraints & Gotchas
|
||||
- **NLog**: Do not add `NLog.Web.AspNetCore` to the Client project; it is incompatible with the WASM runtime.
|
||||
- **UID Logic**: Many entities use a calculated `UID` (e.g., `IdxDipendente_DataOra_Ora`) for RESTful operations (like `DELETE /api/resource/{uid}`) instead of passing entire objects.
|
||||
- **Prerendering**: Always provide a server-side implementation of client-side services to avoid `InvalidOperationException` during the initial page load.
|
||||
- **Namespace Integrity**: Be careful with namespaces when moving logic between `GPW.CORE.Smart10` (Server) and `GPW.CORE.Smart10.Client` (Client).
|
||||
@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.ADM", "GPW.CORE.ADM\GPW.CORE.ADM.csproj", "{4D06AE30-AD81-42FC-B66D-B072A794C599}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE", "GPW.CORE\GPW.CORE.csproj", "{C83EC748-3D5A-27B4-E4E8-B12A09283A8A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -25,6 +27,10 @@ Global
|
||||
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C83EC748-3D5A-27B4-E4E8-B12A09283A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C83EC748-3D5A-27B4-E4E8-B12A09283A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C83EC748-3D5A-27B4-E4E8-B12A09283A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C83EC748-3D5A-27B4-E4E8-B12A09283A8A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<script src="lib/luxon/luxon.js"></script>
|
||||
<script src="lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js"></script>
|
||||
<script src="lib/chartBoot.js"></script>
|
||||
<script type="text/javascript" src="lib/qrcode.js"></script>
|
||||
<script type="text/javascript" src="lib/qrHelper.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
@@ -17,42 +17,72 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
<tr class="">
|
||||
<th>
|
||||
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
<tr class="">
|
||||
<th>
|
||||
@if (legacyMode)
|
||||
{
|
||||
<button class="mx-1 btn btn-info btn-sm" @onclick="SelectAll"><i class="fa-solid fa-circle"></i></button>
|
||||
<button class="btn btn-secondary opacity-50 btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-circle"></i></button>
|
||||
@if(ListUidSel.Count>0)
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (allSel)
|
||||
{
|
||||
<button class="mx-1 btn btn-success btn-sm" @onclick="() => DoApproveSel()"><i class="fa-solid fa-thumbs-up"></i> ALL</button>
|
||||
<i class="fa-solid fa-toggle-on text-primary fs-5" @onclick="ToggleSelection"></i>
|
||||
}
|
||||
</th>
|
||||
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>DataOra <Sorter ParamName="DataOra" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-center">IN</th>
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">OUT</th>
|
||||
<th class="text-end"></th>
|
||||
else
|
||||
{
|
||||
<i class="fa-solid fa-toggle-off text-secondary fs-5" @onclick="ToggleSelection"></i>
|
||||
}
|
||||
}
|
||||
@if ((legacyMode && ListUidSel.Count > 0) || (!legacyMode && HasRowSelected))
|
||||
{
|
||||
<button class="mx-1 btn btn-success btn-sm" @onclick="() => DoApproveSel()"><i class="fa-solid fa-thumbs-up"></i> Approva Sel</button>
|
||||
}
|
||||
</th>
|
||||
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>DataOra <Sorter ParamName="DataOra" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-center">IN</th>
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">OUT</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<tr class="align-middle">
|
||||
<td colspan="8">
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<tr class="align-middle">
|
||||
<td colspan="8">
|
||||
<div class="alert alert-info mb-0">Nessun record trovato</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="align-middle">
|
||||
<td>
|
||||
<button class="mx-1 btn @CssCheckSel(item.UID) btn-sm" @onclick="() => ToggleUid(item.UID)"><i class="fa-solid @IconCheckSel(item.UID)"></i></button>
|
||||
<button class="btn btn-success btn-sm" @onclick="() => DoApprove(item)"><i class="fa-solid fa-thumbs-up"></i></button>
|
||||
@if (legacyMode)
|
||||
{
|
||||
<button class="mx-1 btn @CssCheckSel(item.UID) btn-sm" @onclick="() => ToggleUid(item.UID)"><i class="fa-solid @IconCheckSel(item.UID)"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input class="form-check-input" type="checkbox" @bind="item.Selected"></input>
|
||||
}
|
||||
<button class="btn btn-success btn-sm ms-1" @onclick="() => DoApprove(item)"><i class="fa-solid fa-thumbs-up"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
@item.DipNav.Abbrev
|
||||
@@ -80,9 +110,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using GPW.CORE.Data;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
@@ -44,15 +45,13 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
protected async Task DoApprove(TimbratureModel selItem)
|
||||
{
|
||||
isLoading = true;
|
||||
#if false
|
||||
#endif
|
||||
// se non si tratta di una timbratura "last second"...
|
||||
if (selItem.DataOra.Hour != 23 && selItem.DataOra.Minute != 59 && selItem.DataOra.Second != 59)
|
||||
{
|
||||
// arrotondo ingresso/uscita ai 5 minuti secondo sia entrata o uscita...
|
||||
var dtTimb = Utils.DateRounded(selItem.DataOra, 5, !(selItem.Entrata ?? false));
|
||||
selItem.DataOra = dtTimb;
|
||||
}
|
||||
}
|
||||
// indico approvato
|
||||
selItem.Approv = true;
|
||||
// salvo!
|
||||
@@ -65,6 +64,13 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private bool legacyMode = false;
|
||||
|
||||
protected List<TimbratureDTO> ListSelected
|
||||
{
|
||||
get => ListRecords != null ? ListRecords.Where(x => x.Selected).ToList() : new List<TimbratureDTO>();
|
||||
}
|
||||
|
||||
protected async Task DoApproveSel()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler approvare i {ListUidSel.Count} record selezionati?"))
|
||||
@@ -73,10 +79,35 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
isLoading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
int numProc = 0;
|
||||
foreach (var item in ListRecords)
|
||||
if (legacyMode)
|
||||
{
|
||||
// se selezionato...
|
||||
if (ListUidSel.Contains(item.UID))
|
||||
foreach (var item in ListRecords)
|
||||
{
|
||||
// se selezionato...
|
||||
if (ListUidSel.Contains(item.UID))
|
||||
{
|
||||
// se non si tratta di una timbratura "last second"...
|
||||
if (item.DataOra.Hour != 23 && item.DataOra.Minute != 59 && item.DataOra.Second != 59)
|
||||
{
|
||||
// arrotondo ingresso/uscita ai 5 minuti secondo sia entrata o uscita...
|
||||
var dtTimb = Utils.DateRounded(item.DataOra, 5, !(item.Entrata ?? false));
|
||||
item.DataOra = dtTimb;
|
||||
}
|
||||
// indico approvato
|
||||
item.Approv = true;
|
||||
// salvo!
|
||||
bool fatto = await GDataServ.TimbratureUpdate(item);
|
||||
if (fatto)
|
||||
{
|
||||
numProc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
foreach (var item in ListSelected)
|
||||
{
|
||||
// se non si tratta di una timbratura "last second"...
|
||||
if (item.DataOra.Hour != 23 && item.DataOra.Minute != 59 && item.DataOra.Second != 59)
|
||||
@@ -88,16 +119,18 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
// indico approvato
|
||||
item.Approv = true;
|
||||
// salvo!
|
||||
bool fatto = await GDataServ.TimbratureUpdate(item);
|
||||
bool fatto = await GDataServ.TimbratureUpdate(item, false);
|
||||
if (fatto)
|
||||
{
|
||||
numProc++;
|
||||
}
|
||||
}
|
||||
// svuoto cache
|
||||
allSel = false;
|
||||
}
|
||||
await Task.Delay(1);
|
||||
if (numProc > 0)
|
||||
{
|
||||
await GDataServ.FlushRedisCache();
|
||||
await ReloadData();
|
||||
}
|
||||
await Task.Delay(1);
|
||||
@@ -185,6 +218,23 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua toggle selezione globale delle righe mostrateGpwDataService gDataServprivate async Task ReloadData
|
||||
/// </summary>
|
||||
protected void ToggleSelection()
|
||||
{
|
||||
allSel = !allSel;
|
||||
foreach (var item in ListRecords)
|
||||
{
|
||||
item.Selected = allSel;
|
||||
}
|
||||
}
|
||||
protected bool HasRowSelected
|
||||
{
|
||||
get => ListRecords != null && ListRecords.Count(x => x.Selected) > 0;
|
||||
//get => ListRecords != null && ListRecords.Where(x => x.Selected).Count() > 0;
|
||||
}
|
||||
|
||||
protected async void ToggleUid(string uid)
|
||||
{
|
||||
if (ListUidSel.Contains(uid))
|
||||
@@ -204,6 +254,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private bool allSel = false;
|
||||
private string gridKey = "ApprovTimbMan";
|
||||
private bool sortAsc = true;
|
||||
private string sortField = "";
|
||||
@@ -219,10 +270,10 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
private bool isLoading { get; set; } = false;
|
||||
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
|
||||
|
||||
private List<TimbratureModel>? ListRecords { get; set; } = null;
|
||||
private List<TimbratureDTO>? ListRecords { get; set; } = null;
|
||||
private List<string> ListUidSel { get; set; } = new List<string>();
|
||||
private int numRecord { get; set; } = 10;
|
||||
private List<TimbratureModel>? SearchRecords { get; set; } = null;
|
||||
private List<TimbratureDTO>? SearchRecords { get; set; } = null;
|
||||
private int totalCount { get; set; } = 0;
|
||||
|
||||
#endregion Private Properties
|
||||
@@ -243,12 +294,18 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
ListRecords = null;
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.TimbratureRichieste();
|
||||
var rawData = await GDataServ.TimbratureRichieste();
|
||||
SearchRecords = rawData
|
||||
.Where(x => (IdxDipSel == 0 || x.IdxDipendente == IdxDipSel))
|
||||
.Select(x => new TimbratureDTO(x))
|
||||
.ToList();
|
||||
#if false
|
||||
// verifico filtro per IdxDip
|
||||
if (IdxDipSel > 0)
|
||||
{
|
||||
SearchRecords = SearchRecords.Where(x => x.IdxDipendente == IdxDipSel).ToList();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -303,7 +360,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<TimbratureModel>();
|
||||
ListRecords = new List<TimbratureDTO>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
SearchRecords = null;
|
||||
await Task.Delay(1);
|
||||
SearchRecords = await GDataServ.CalFestFeriePeriodo(DtStart, DtEnd);
|
||||
SearchRecords = GDataServ.CalFestFeriePeriodo(DtStart, DtEnd);
|
||||
// conteggio!
|
||||
totalCount = SearchRecords.Count;
|
||||
// paginazione
|
||||
|
||||
@@ -16,17 +16,7 @@
|
||||
<b>Calendario Aziendale</b>
|
||||
</div>
|
||||
<div class="col-4 text-end">
|
||||
<div class="d-flex justify-content-around">
|
||||
@if (currView == "year" || currView == "planner")
|
||||
{
|
||||
<div class="small">
|
||||
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem" class="rz-px-2">
|
||||
<RadzenLabel Text="Mese:" />
|
||||
<RadzenDropDown @bind-Value="@startMonth" Change="StartMonthChange" TextProperty="Text" ValueProperty="Value" Data="@(Enum.GetValues(typeof(Month)).Cast<Month>().Where(x => ((int)x % 3 == 0)).Select(t => new { Text = $"{t}", Value = t }))" class="rz-display-inline-flex small" />
|
||||
</RadzenStack>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<b>@numEvFilt/@numEvAll</b> (selez/anno)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -35,7 +25,7 @@
|
||||
<RadzenScheduler @ref=@scheduler style="height: 100%;" Culture=@(new System.Globalization.CultureInfo("it-IT"))
|
||||
TItem="EventDTO" Data="@EvDtoFilt" SelectedIndex="@selectedIndex" Date="@SelDate"
|
||||
StartProperty="DtStart" EndProperty="DtEnd" TextProperty="CodTipo"
|
||||
SlotRender=@OnSlotRender SlotSelect=@OnSlotSelect
|
||||
SlotRender=@OnSlotRender SlotSelect=@OnSlotSelect TodayText="Oggi"
|
||||
AppointmentSelect=@OnAppointmentSelect AppointmentRender=@OnAppointmentRender
|
||||
LoadData=OnLoadData>
|
||||
<Template Context="EvDTO">
|
||||
@@ -53,9 +43,8 @@
|
||||
<RadzenDayView />
|
||||
<RadzenWeekView />
|
||||
<RadzenMonthView MaxAppointmentsInSlot="4" />
|
||||
<RadzenYearPlannerView StartMonth="@startMonth" MaxAppointmentsInSlot="3" />
|
||||
@* <RadzenYearTimelineView StartMonth="@startMonth" /> *@
|
||||
<RadzenYearView StartMonth="@startMonth" />
|
||||
<RadzenYearPlannerView StartMonth="Month.January" MaxAppointmentsInSlot="3" />
|
||||
<RadzenYearView StartMonth="Month.January" />
|
||||
</ChildContent>
|
||||
</RadzenScheduler>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using GPW.CORE.Data.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Identity.Client;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using Radzen.Blazor;
|
||||
using static EgwCoreLib.Razor.Toggler;
|
||||
using NLog;
|
||||
using Radzen;
|
||||
using Radzen.Blazor;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using System;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using System.Diagnostics;
|
||||
using static EgwCoreLib.Razor.Toggler;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
@@ -24,9 +25,6 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
[Parameter]
|
||||
public DateTime firstDate { get; set; } = new DateTime(DateTime.Today.Year, 1, 1);
|
||||
|
||||
[Parameter]
|
||||
public bool ShowNeedConf { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public DateTime maxDate { get; set; } = new DateTime(DateTime.Today.Year + 1, 1, 1);
|
||||
|
||||
@@ -43,6 +41,9 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
[Parameter]
|
||||
public EventCallback<int> MonthReq { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool ShowNeedConf { get; set; } = false;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Fields
|
||||
@@ -82,6 +83,8 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
[Inject]
|
||||
protected DialogService DialogService { get; set; } = null!;
|
||||
|
||||
protected Month StartMonth { get; set; } = Month.January;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
@@ -101,17 +104,63 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected string btnSel(string bName)
|
||||
{
|
||||
bool answ = false;
|
||||
switch (bName)
|
||||
{
|
||||
case "CHIU":
|
||||
answ = showChiu;
|
||||
break;
|
||||
|
||||
case "FER":
|
||||
answ = showFer;
|
||||
break;
|
||||
|
||||
case "FEST":
|
||||
answ = showFest;
|
||||
break;
|
||||
|
||||
case "MAL":
|
||||
answ = showMal;
|
||||
break;
|
||||
|
||||
case "PER":
|
||||
answ = showPer;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return answ ? "btn-primary" : "btn-secondary";
|
||||
}
|
||||
|
||||
#if false
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
// il mese viene preimpostato sul trimestre corrente...
|
||||
startMonth = (Month)((DateTime.Today.Month / 6) * 6);
|
||||
// il mese viene preimpostato sul semestre corrente...
|
||||
StartMonth = (Month)((DateTime.Today.Month / 6) * 6);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void OnParametersSet()
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
FilterData();
|
||||
scheduler.Reload();
|
||||
numEvAll = 0;
|
||||
numEvFilt = 0;
|
||||
if (EvDtoList != null && EvDtoList.Count > 0)
|
||||
{
|
||||
numEvAll = EvDtoList.Count();
|
||||
FilterData();
|
||||
try
|
||||
{
|
||||
await scheduler.Reload();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"eccezione durante OnParametersSet{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task StartMonthChange()
|
||||
@@ -119,10 +168,41 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await scheduler.Reload();
|
||||
}
|
||||
|
||||
protected void ToggChiu()
|
||||
{
|
||||
showChiu = !showChiu;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
protected void ToggFer()
|
||||
{
|
||||
showFer = !showFer;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
protected void ToggFest()
|
||||
{
|
||||
showFest = !showFest;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
protected void ToggMal()
|
||||
{
|
||||
showMal = !showMal;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
protected void ToggPer()
|
||||
{
|
||||
showPer = !showPer;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private int selectedIndex = 2;
|
||||
|
||||
#endregion Private Fields
|
||||
@@ -132,15 +212,24 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
private int cMonth { get; set; } = 3;
|
||||
private string currView { get; set; } = "";
|
||||
private List<EventDTO> EvDtoFilt { get; set; } = new List<EventDTO>();
|
||||
private int numEvAll { get; set; } = 0;
|
||||
private int numEvFilt { get; set; } = 0;
|
||||
private string schedHeight { get; set; } = "height: 50rem;";
|
||||
private DateTime SelDate { get; set; } = DateTime.Today;
|
||||
private Month startMonth { get; set; } = Month.January;
|
||||
private bool showChiu { get; set; } = true;
|
||||
|
||||
private bool showFer { get; set; } = true;
|
||||
|
||||
private bool showFest { get; set; } = true;
|
||||
|
||||
private bool showMal { get; set; } = true;
|
||||
|
||||
private bool showPer { get; set; } = true;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
|
||||
private void FilterData()
|
||||
{
|
||||
// in primis copio tutto
|
||||
@@ -180,77 +269,24 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
.Where(x => !x.CodTipo.Equals("PERM", StringComparison.InvariantCultureIgnoreCase) && !x.CodTipo.Equals("104", StringComparison.InvariantCultureIgnoreCase))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
}
|
||||
private bool showChiu { get; set; } = true;
|
||||
private bool showFer { get; set; } = true;
|
||||
private bool showFest { get; set; } = true;
|
||||
private bool showMal { get; set; } = true;
|
||||
private bool showPer { get; set; } = true;
|
||||
|
||||
protected string btnSel(string bName)
|
||||
{
|
||||
bool answ = false;
|
||||
switch (bName)
|
||||
{
|
||||
case "CHIU":
|
||||
answ = showChiu;
|
||||
break;
|
||||
|
||||
case "FER":
|
||||
answ = showFer;
|
||||
break;
|
||||
|
||||
case "FEST":
|
||||
answ = showFest;
|
||||
break;
|
||||
|
||||
case "MAL":
|
||||
answ = showMal;
|
||||
break;
|
||||
|
||||
case "PER":
|
||||
answ = showPer;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return answ ? "btn-primary" : "btn-secondary";
|
||||
}
|
||||
protected void ToggMal()
|
||||
{
|
||||
showMal = !showMal;
|
||||
FilterData();
|
||||
}
|
||||
|
||||
protected void ToggPer()
|
||||
{
|
||||
showPer = !showPer;
|
||||
FilterData();
|
||||
}
|
||||
protected void ToggFer()
|
||||
{
|
||||
showFer = !showFer;
|
||||
FilterData();
|
||||
}
|
||||
protected void ToggFest()
|
||||
{
|
||||
showFest = !showFest;
|
||||
FilterData();
|
||||
}
|
||||
protected void ToggChiu()
|
||||
{
|
||||
showChiu = !showChiu;
|
||||
FilterData();
|
||||
numEvFilt = EvDtoFilt.Count();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sistemazione colore sfonto di ogni evento mostrato
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private void OnAppointmentRender(SchedulerAppointmentRenderEventArgs<EventDTO> args)
|
||||
{
|
||||
// Never call StateHasChanged in AppointmentRender - would lead to infinite loop
|
||||
args.Attributes["style"] = $"background: {args.Data.Color}; color: {args.Data.ForeColor};";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selezione evento per display
|
||||
/// </summary>
|
||||
/// <param name="selEv"></param>
|
||||
/// <returns></returns>
|
||||
private async Task OnAppointmentSelect(SchedulerAppointmentSelectEventArgs<EventDTO> selEv)
|
||||
{
|
||||
var copy = selEv.Data.Clone();
|
||||
@@ -258,16 +294,26 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
var data = await DialogService.OpenAsync<TaskDetail>("", new Dictionary<string, object> { { "ThisTask", copy } });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gestione richeista caricamento dati dal controllo x avere nuovo set da mostrare
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
private async Task OnLoadData(SchedulerLoadDataEventArgs args)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
currView = scheduler.SelectedView.Text.ToLowerInvariant();
|
||||
|
||||
// controllo se sia cambiata data... di almeno 1 anno in questo caso...
|
||||
if (SelDate != scheduler.Date || Math.Abs(scheduler.Date.Subtract(args.Start).TotalDays) > 365)
|
||||
DateTime dtMid = args.Start.AddDays(args.End.Subtract(args.Start).TotalDays / 2);
|
||||
// controllo se sia cambiata data anno precedente...
|
||||
if (dtMid.Year != SelDate.Year)
|
||||
{
|
||||
SelDate = args.Start.AddMonths(1);
|
||||
// riporto data al controller parent...
|
||||
SelDate = dtMid;
|
||||
await DtReq.InvokeAsync(SelDate);
|
||||
}
|
||||
// di almeno 1 anno in questo caso...
|
||||
else if (SelDate != scheduler.Date || Math.Abs(scheduler.Date.Subtract(args.Start).TotalDays) > 365)
|
||||
{
|
||||
SelDate = args.Start.AddDays(4);
|
||||
await DtReq.InvokeAsync(SelDate);
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
ListRecords = null;
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.AnagClientiAll();
|
||||
SearchRecords = await GDataServ.AnagClientiAllAsync();
|
||||
// verifico condizioni filtro
|
||||
if (ToggleData.isActive)
|
||||
{
|
||||
|
||||
@@ -48,8 +48,11 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
aTimer.Stop();
|
||||
aTimer.Dispose();
|
||||
}
|
||||
int tOutPeriod = 300000;
|
||||
//int tOutPeriod = 1000;
|
||||
#if DEBUG
|
||||
int tOutPeriod = 1000;
|
||||
#else
|
||||
int tOutPeriod = 10000;
|
||||
#endif
|
||||
aTimer = new System.Timers.Timer(tOutPeriod);
|
||||
aTimer.Elapsed += ElapsedTimer;
|
||||
aTimer.Enabled = true;
|
||||
|
||||
@@ -65,7 +65,4 @@
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,321 @@
|
||||
@if (CurrMode == EditMode.FullEdit)
|
||||
{
|
||||
<div class="row g-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Cognome">
|
||||
<label class="small">Cognome</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Nome">
|
||||
<label class="small">Nome</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Matricola">
|
||||
<label class="small">Matricola</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-floating">
|
||||
<select @bind="@CurrRecord.CodOrario" class="form-select form-select-sm" title="Profilo Orario">
|
||||
<option value="">--- Selezionare ---</option>
|
||||
@foreach (var item in ListOrari)
|
||||
{
|
||||
<option value="@item.codOrario">@item.descOrario</option>
|
||||
}
|
||||
</select>
|
||||
<label class="small">Profilo Orario</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 align-content-center">
|
||||
<button class="btn btn-success btn-lg my-1 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-2 my-1">
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Dominio">
|
||||
<label class="small">Dominio</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Utente">
|
||||
<label class="small">Utente</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Email">
|
||||
<label class="small">Email</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 align-content-center">
|
||||
<button class="btn btn-warning btn-lg my-1 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-2 my-1">
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Cf">
|
||||
<label class="small">Codice Fiscale</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="date" class="form-control" @bind="@CurrRecord.DataNascita">
|
||||
<label class="small">Data Nascita</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.LuogoNascita">
|
||||
<label class="small">Luogo Nascita</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.ProvNascita">
|
||||
<label class="small">Prov</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.NazNascita">
|
||||
<label class="small">Naz</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.CodHw">
|
||||
<label class="small">CodHw</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-2 my-1">
|
||||
<div class="col-md-2">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.Gruppo">
|
||||
<label class="small">Gruppo</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<div class="form-control">
|
||||
<div class="form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Attivo">
|
||||
</div>
|
||||
</div>
|
||||
<label class="small">Att.</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<select @bind="@CurrRecord.idxResp" class="form-select form-select-sm" title="Responsabile">
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListDipendenti)
|
||||
{
|
||||
<option value="@item.IdxDipendente">@item.Cognome @item.Nome</option>
|
||||
}
|
||||
</select>
|
||||
<label class="small">Responsabile</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="date" class="form-control" @bind="@CurrRecord.DataAssunzione">
|
||||
<label class="small">Assunzione</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-floating">
|
||||
<input type="date" class="form-control" @bind="@CurrRecord.DataCessazione">
|
||||
<label class="small">Cessazione</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (CurrMode == EditMode.ResetRequest)
|
||||
{
|
||||
<div class="row g-2">
|
||||
<div class="col-8">
|
||||
<div class="row">
|
||||
<div class="col-4 pe-0">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@ReqReset.Richiedente">
|
||||
<label class="small"><i class="fa-solid fa-user"></i> Richiedente</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 px-0">
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" @bind="@ReqReset.Email">
|
||||
<label class="small"><i class="fa-regular fa-envelope"></i> Email</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 ps-0">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@ReqReset.Telefono">
|
||||
<label class="small"><i class="fa-solid fa-phone"></i> Telefono</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">Anagr:</div>
|
||||
<div class="px-1">@($"{CurrRecord.DataNascita:yyyy-MM-dd}") @CurrRecord.LuogoNascita (@CurrRecord.ProvNascita | @CurrRecord.NazNascita)</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">@CurrRecord.Cf</div>
|
||||
<div class="px-1">@CurrRecord.Email</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">
|
||||
@if (CurrRecord.DataCessazione <= DateTime.Today)
|
||||
{
|
||||
<span>Periodo:</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>Assunzione:</span>
|
||||
}
|
||||
</div>
|
||||
<div class="px-1">
|
||||
<span>@($"{CurrRecord.DataAssunzione:yyyy-MM-dd}")</span>
|
||||
@if (CurrRecord.DataCessazione <= DateTime.Today)
|
||||
{
|
||||
<span>
|
||||
→ @($"{CurrRecord.DataCessazione:yyyy-MM-dd}")
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">Lock Licenza</div>
|
||||
<div class="px-1">
|
||||
<span class="text-danger">
|
||||
<i class="fa-solid fa-lock"></i> <b>@($"{UnlockDateLic:dddd dd MMMM yyyy}")</b>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="row">
|
||||
@*
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@ReqReset.Richiedente">
|
||||
<label class="small"><i class="fa-solid fa-user"></i> Richiedente</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 pe-0">
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" @bind="@ReqReset.Email">
|
||||
<label class="small"><i class="fa-regular fa-envelope"></i> Email</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 ps-0">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@ReqReset.Telefono">
|
||||
<label class="small"><i class="fa-solid fa-phone"></i> Telefono</label>
|
||||
</div>
|
||||
</div>
|
||||
*@
|
||||
<div class="col-12">
|
||||
<div class="form-floating">
|
||||
<textarea class="form-control" @bind="@ReqReset.Causale" style="min-height: 8rem;"></textarea>
|
||||
<label class="small"><i class="fa-regular fa-message"></i> Causale</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-center mt-2">
|
||||
<button class="btn btn-primary btn-lg my-1 w-100" @onclick="() => DoActivate()" title="Invio richiesta sblocco licenza">Invio Richiesta <i class="far fa-paper-plane"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (CurrMode == EditMode.KeyRegen)
|
||||
{
|
||||
<div class="row g-2">
|
||||
<div class="col-8">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">Anagr:</div>
|
||||
<div class="px-1">@($"{CurrRecord.DataNascita:yyyy-MM-dd}") @CurrRecord.LuogoNascita (@CurrRecord.ProvNascita | @CurrRecord.NazNascita)</div>
|
||||
</li>
|
||||
@* <li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1"><b>@CurrRecord.Cognome</b> @CurrRecord.Nome</div>
|
||||
<div class="px-1">@CurrRecord.Matricola</div>
|
||||
</li> *@
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">@CurrRecord.Cf</div>
|
||||
<div class="px-1">@CurrRecord.Email</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between" aria-current="true">
|
||||
<div class="px-1">
|
||||
@if (CurrRecord.DataCessazione <= DateTime.Today)
|
||||
{
|
||||
<span>Periodo:</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>Assunzione:</span>
|
||||
}
|
||||
</div>
|
||||
<div class="px-1">
|
||||
<span>@($"{CurrRecord.DataAssunzione:yyyy-MM-dd}")</span>
|
||||
@if (CurrRecord.DataCessazione <= DateTime.Today)
|
||||
{
|
||||
<span>
|
||||
→ @($"{CurrRecord.DataCessazione:yyyy-MM-dd}")
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@if (CurrRecord.Attivo ?? false)
|
||||
{
|
||||
if (CheckActivationUnlocked)
|
||||
{
|
||||
<button class="btn btn-danger btn-lg my-1 w-100" @onclick="() => DoRelease()" title="Cessazione utente + Rilascio Licenza">Cessazione Utente <i class="fas fa-link-slash"></i></button>
|
||||
@if (!CheckActivation && (CurrRecord.Attivo ?? false))
|
||||
{
|
||||
<button class="btn btn-primary btn-lg my-1 w-100" @onclick="() => DoReissue()" title="Assegna Licenza ad utente già Attivo">Assegna Licenza <i class="fas fa-rotate"></i></button>
|
||||
}
|
||||
}
|
||||
<button class="btn btn-primary btn-lg my-1 w-100" @onclick="() => DoResync()" title="Rigenera Token Auth SMART + associa Licenza">Rigen + Sync Auth <i class="fas fa-rotate"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (LicenzeOk && LicenzeDisponibili)
|
||||
{
|
||||
<button class="btn btn-success btn-lg my-1 w-100" @onclick="() => DoActivate()" title="Attiva utente + Assegna Licenza">Attiva Utente <i class="fas fa-link"></i></button>
|
||||
}
|
||||
}
|
||||
<div class="text-center">
|
||||
@if (LockExpired)
|
||||
{
|
||||
<span class="text-success">
|
||||
<i class="fa-solid fa-unlock"></i> <b>@($"{UnlockDateLic:dddd dd MMMM yyyy}")</b>
|
||||
</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-danger">
|
||||
<i class="fa-solid fa-lock"></i> <b>@($"{UnlockDateLic:dddd dd MMMM yyyy}")</b>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="alert a fs-6">Modo controllo non definito</div>
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class DipendentiEdit
|
||||
{
|
||||
#region Public Enums
|
||||
|
||||
/// <summary>
|
||||
/// Modalità Edit
|
||||
/// </summary>
|
||||
public enum EditMode
|
||||
{
|
||||
None = 0,
|
||||
KeyRegen,
|
||||
ResetRequest,
|
||||
FullEdit
|
||||
}
|
||||
|
||||
#endregion Public Enums
|
||||
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public EditMode CurrMode { get; set; } = EditMode.None;
|
||||
|
||||
[Parameter]
|
||||
public DipendentiModel? CurrRecord { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DipendentiModel> EC_Activate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DipendentiModel> EC_Reissue { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DipendentiModel> EC_Release { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DipendentiModel> EC_Resync { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DipendentiModel> EC_update { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<DipendentiModel> ListDipendenti { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public List<AnagOrariModel> ListOrari { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected bool CheckActivation = false;
|
||||
|
||||
protected bool CheckActivationUnlocked = false;
|
||||
|
||||
protected string CodImpiego = "";
|
||||
|
||||
protected int IdxSubLic = 0;
|
||||
|
||||
protected bool LicenzeDisponibili = false;
|
||||
|
||||
protected bool LicenzeOk = false;
|
||||
|
||||
protected bool LockExpired = false;
|
||||
|
||||
protected int NumDipAct = 0;
|
||||
|
||||
protected DateTime UnlockDateLic = DateTime.Today.AddMonths(3);
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected LicenseService LicServ { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Attiva + Assegna Licenza
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoActivate()
|
||||
{
|
||||
await EC_Activate.InvokeAsync(CurrRecord);
|
||||
}
|
||||
|
||||
protected async Task DoCancel()
|
||||
{
|
||||
await EC_update.InvokeAsync(CurrRecord);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assegna Licenza
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoReissue()
|
||||
{
|
||||
await EC_Reissue.InvokeAsync(CurrRecord);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rilascia Licenza
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoRelease()
|
||||
{
|
||||
await EC_Release.InvokeAsync(CurrRecord);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Richiesta Rilascio Licenza
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoReqUnlock()
|
||||
{
|
||||
// invio richiesta sblocco licenza prima della scadenza naturale lock
|
||||
|
||||
//await EC_Release.InvokeAsync(CurrRecord);
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Genera una nuova chiave utente + riassegna Licenza
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoResync()
|
||||
{
|
||||
await EC_Resync.InvokeAsync(CurrRecord);
|
||||
}
|
||||
|
||||
protected async Task DoSave()
|
||||
{
|
||||
bool fatto = false;
|
||||
if (CurrRecord != null)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
|
||||
// chiama resync dati licenza (cod impiego / codAuth)
|
||||
fatto = LicServ.SendTicketReq(ReqReset.Richiedente.Trim(), ReqReset.Email.Trim(), ReqReset.Telefono.Trim(), ReqReset.Causale.Trim(), CodImpiego, IdxSubLic);
|
||||
// chiudo
|
||||
LicServ.ResetTicketCache();
|
||||
|
||||
// reset richiesta
|
||||
ReqReset = new DatiReqResetDTO();
|
||||
#if false
|
||||
// evento reset
|
||||
raiseReset();
|
||||
#endif
|
||||
await EC_update.InvokeAsync(CurrRecord);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
DoActivCheck();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private DatiReqResetDTO ReqReset = new DatiReqResetDTO();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Effettua verifiche attivazioni e dati vari
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void DoActivCheck()
|
||||
{
|
||||
if (ListDipendenti != null && ListDipendenti.Count > 0)
|
||||
{
|
||||
NumDipAct = ListDipendenti.Where(x => x.Attivo ?? false).Count();
|
||||
if (CurrRecord != null)
|
||||
{
|
||||
// calcolo CodImpiego
|
||||
CodImpiego = LicServ.HashDip(CurrRecord);
|
||||
UnlockDateLic = LockExpiry();
|
||||
LockExpired = UnlockDateLic <= DateTime.Today.AddDays(1);
|
||||
var onlineActInfo = LicServ.GetOnlineActivationInfo(CodImpiego);
|
||||
if (onlineActInfo != null)
|
||||
{
|
||||
// verifico unlock licenza online...
|
||||
#if false
|
||||
CheckActivationUnlocked = LicServ.CheckActivationUnlocked(CodImpiego);
|
||||
#endif
|
||||
CheckActivation = onlineActInfo.CodImpiego == CodImpiego;
|
||||
CheckActivationUnlocked = onlineActInfo.VetoUnlock <= DateTime.Today || string.IsNullOrEmpty(onlineActInfo.CodImpiego);
|
||||
IdxSubLic = onlineActInfo.IdxSubLic;
|
||||
}
|
||||
// verifico licenze
|
||||
LicenzeOk = NumDipAct <= LicServ.ActivList.Count();
|
||||
// verifico licenze disponibili
|
||||
LicenzeDisponibili = LicServ.AppLicense.NumLicenze > NumDipAct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restitusice la data di unlock del dipendente
|
||||
/// </summary>
|
||||
private DateTime LockExpiry()
|
||||
{
|
||||
DateTime cessato = CurrRecord.DataCessazione ?? DateTime.Today.AddDays(-1);
|
||||
bool isAttivo = CurrRecord.Attivo ?? false;
|
||||
DateTime answ = isAttivo ? DateTime.Today.AddDays(90) : cessato;
|
||||
|
||||
// verifico SE sia disponibile licenza...
|
||||
var activationsList = LicServ.ActivList;
|
||||
var currAct = activationsList.Where(x => x.CodImpiego == CodImpiego).FirstOrDefault();
|
||||
// se trovo record
|
||||
if (currAct != null)
|
||||
{
|
||||
answ = currAct.VetoUnlock;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
@if (RecordEdit != null)
|
||||
{
|
||||
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
|
||||
<div class="modal-dialog @modalSize">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header d-flex justify-content-between">
|
||||
<div class="px-1 fs-4 modal-title">
|
||||
<b>@RecordEdit.Cognome</b> @RecordEdit.Nome
|
||||
@if (CtrlMode == DipendentiEdit.EditMode.FullEdit)
|
||||
{
|
||||
<span>| Modifica Record @RecordEdit.IdxDipendente</span>
|
||||
}
|
||||
else if (CtrlMode == DipendentiEdit.EditMode.ResetRequest)
|
||||
{
|
||||
<span>| Sblocco Licenza</span>
|
||||
}
|
||||
</div>
|
||||
<div class="px-1">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick=ForceReload></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body p-1 small">
|
||||
<DipendentiEdit CurrMode="CtrlMode" CurrRecord="RecordEdit" EC_update="ForceReload" EC_Activate="DoActivate" EC_Release="ReleaseLicense" ListDipendenti="@ListDipendentiAttiviOrd" ListOrari="@ListOrari"></DipendentiEdit>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
<div class="card shadow">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0 d-flex">
|
||||
<div class="px-2">
|
||||
<h4>Dipendenti</h4>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<div class="px-1 py-2">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowInatt @bind:after=ForceReload>
|
||||
<label class="form-check-label">Mostra Inattivi</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-0 d-flex">
|
||||
<div class="d-flex">
|
||||
<div class="px-1 align-content-center">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
Mostra QRCode
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra QRCode">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowQrCode>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@if (ShowQrCode)
|
||||
{
|
||||
<div class="ps-1 pe-0 align-content-center">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
@TextQrLinkInt
|
||||
<span class="form-check form-switch align-content-center ms-2" title="@TextQrLinkInt">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowLinkInt>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ps-0 pe-1 align-content-center">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
@TextQrLinkCore
|
||||
<span class="form-check form-switch align-content-center ms-2" title="@TextQrLinkCore">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowLinkCore>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex bg-dark bg-gradient text-light p-1">
|
||||
<div class="px-2 mx-1 border border-2 border-info rounded rounded-3 align-content-center g-1"><i class="fa-solid fa-database"></i> Licenze Locali: disponibili <b>@NumLicDispLocal</b> / utenti attivi <b>@NumLicActLocal</b></div>
|
||||
<div class="px-2 mx-1 border border-2 border-success rounded rounded-3 align-content-center g-1"><i class="fa-solid fa-cloud"></i> Licenze Online: disponibili <b>@NumLicDispOnline</b> / utenti attivi <b>@NumLicActOnline</b></div>
|
||||
<button class="mx-1 btn btn-success" @onclick="DoRefresh"><i class="fa-solid fa-cloud-arrow-down g-1"></i> Refresh Status Online</button>
|
||||
@if (NeedAllocation)
|
||||
{
|
||||
<button class="mx-1 btn btn-primary" @onclick="DoFixMissing"><i class="fa-solid fa-cloud-arrow-up g-1"></i> Allocazione Licenze</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="mx-1 btn btn-secondary disabled" disabled><i class="fa-solid fa-cloud-arrow-up g-1"></i> Allocazione Licenze</button>
|
||||
}
|
||||
<button class="mx-1 btn btn-outline-secondary"><i class="fa-solid fa-ticket g-1"></i> Ticket Aperti <b>@NumTicket</b></button>
|
||||
<button class="mx-1 btn btn-warning g-1"><i class="fa-solid fa-key"></i> Rigenera AuthKey</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
@if (ShowQrCode)
|
||||
{
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-2">
|
||||
<div class="card shadow">
|
||||
<div class="card-header p-0">
|
||||
<UserQrCode LinkInt="ShowLinkInt" RecordDip="item" LinkCore="ShowLinkCore"></UserQrCode>
|
||||
</div>
|
||||
<div class="card-body py-1">
|
||||
<div class="fs-1 fw-bold">@item.Cognome</div>
|
||||
<div class="fs-4">@item.Nome</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-between">
|
||||
<div class="px-1"><img src="images/logoegw.png" class="imf-fluid" width="32" /> <span class="fs-6">Egalware</span></div>
|
||||
<div class="px-1 fs-6 align-content-center"><i>SMART a-link</i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-12">
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload()"><i class="fa-solid fa-rotate"></i></button>
|
||||
</th>
|
||||
<th>Cognome <Sorter ParamName="Cognome" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Nome <Sorter ParamName="Nome" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Matricola <Sorter ParamName="Matricola" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Profilo <Sorter ParamName="Profilo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Dominio <Sorter ParamName="Dominio" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Utente <Sorter ParamName="Utente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Email <Sorter ParamName="Email" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>CF <Sorter ParamName="CF" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>CodeHw <Sorter ParamName="CodeHw" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Dati anagrafici <Sorter ParamName="DatiAnag" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Gruppo <Sorter ParamName="Gruppo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Stato licenza <Sorter ParamName="StatoLic" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Responsabile <Sorter ParamName="Responsabile" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="@CheckSel(item)">
|
||||
<td class="text-nowrap">
|
||||
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)" title="Dettaglio Record"><i class="fa-solid fa-search"></i></button>
|
||||
@if (RecordEdit == null)
|
||||
{
|
||||
if (CheckFreeEdit(item.IdxDipendente))
|
||||
{
|
||||
<button class="btn btn-primary btn-sm mx-1" @onclick="() => DoEdit(item)" title="Modifica record">
|
||||
<i class="fa-solid fa-edit"></i>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-warning btn-sm mx-1" @onclick="() => RequestReset(item)" title="Richiesta sblocco Licenza">
|
||||
<i class="fa-solid fa-question-circle"></i>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm mx-1" disabled><i class="fa-solid fa-edit"></i></button>
|
||||
}
|
||||
</td>
|
||||
|
||||
<td class="text-start">@item.Cognome</td>
|
||||
<td class="text-start">@item.Nome</td>
|
||||
<td class="text-start">@item.Matricola</td>
|
||||
<td class="text-start">@item.CodOrario</td>
|
||||
<td class="text-start">@item.Dominio</td>
|
||||
<td class="text-start">@item.Utente</td>
|
||||
<td class="text-start">@item.Email</td>
|
||||
<td class="text-start">@item.Cf</td>
|
||||
<td class="text-start">@item.CodHw</td>
|
||||
<td class="text-start">@($"{item.LuogoNascita}") - @($"{item.ProvNascita}") - @($"{item.NazNascita}") - @($"{item.DataNascita:dd/MM/yyyy}")</td>
|
||||
<td class="text-start">@item.Gruppo</td>
|
||||
<td class="text-start">@($"{item.DataAssunzione:dd/MM/yyyy}") - @($"{item.DataCessazione:dd/MM/yyyy}")</td>
|
||||
<td class="text-end">
|
||||
<select @bind="@item.idxResp" class="form-select form-select-sm disabled" disabled style="min-width: 12rem;">
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var dip in ListDipendentiOrd)
|
||||
{
|
||||
<option value="@dip.IdxDipendente">@($"{dip.Cognome} {dip.Nome}")</option>
|
||||
}
|
||||
</select>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,568 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using NLog;
|
||||
using System.Buffers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class DipendentiMan : IDisposable
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected int NumLicActLocal = 0;
|
||||
|
||||
protected int NumLicActOnline = 0;
|
||||
|
||||
protected int NumLicDispLocal = 0;
|
||||
|
||||
protected int NumLicDispOnline = 0;
|
||||
|
||||
protected int NumTicket = 0;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected LicenseService LicServ { get; set; } = null!;
|
||||
|
||||
protected List<DipendentiModel> ListDipendentiAttiviOrd
|
||||
{
|
||||
get => ListDipendenti != null ? ListDipendenti.Where(x => x.Attivo ?? false).OrderBy(x => x.Cognome).ThenBy(x => x.Nome).ToList() : new List<DipendentiModel>();
|
||||
}
|
||||
|
||||
protected List<DipendentiModel> ListDipendentiOrd
|
||||
{
|
||||
get => ListDipendenti != null ? ListDipendenti.OrderBy(x => x.Cognome).ThenBy(x => x.Nome).ToList() : new List<DipendentiModel>();
|
||||
}
|
||||
|
||||
protected string modalSize
|
||||
{
|
||||
get => CtrlMode == DipendentiEdit.EditMode.FullEdit ? "modal-xl" : "modal-lg";
|
||||
}
|
||||
|
||||
protected bool NeedAllocation
|
||||
{
|
||||
get => NumLicActOnline == NumLicActLocal && NumLicActOnline != NumLicActLocal;
|
||||
}
|
||||
|
||||
protected string TextQrLinkCore
|
||||
{
|
||||
get => ShowLinkCore ? "GPW Core" : "GPW Legacy";
|
||||
}
|
||||
|
||||
protected string TextQrLinkInt
|
||||
{
|
||||
get => ShowLinkInt ? "Link Interno" : "Link Esterno";
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string CheckSel(DipendentiModel curItem)
|
||||
{
|
||||
string answ = curItem.Attivo ?? false ? "" : "text-secondary striked";
|
||||
if (RecordEdit != null)
|
||||
{
|
||||
answ = curItem.Cf == RecordEdit.Cf ? "table-info" : "";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected async Task CreateNew()
|
||||
{
|
||||
}
|
||||
|
||||
protected void DoEdit(DipendentiModel? selItem)
|
||||
{
|
||||
CtrlMode = DipendentiEdit.EditMode.FullEdit;
|
||||
RecordEdit = selItem;
|
||||
}
|
||||
protected void RequestReset(DipendentiModel? selItem)
|
||||
{
|
||||
CtrlMode = DipendentiEdit.EditMode.ResetRequest;
|
||||
RecordEdit = selItem;
|
||||
}
|
||||
|
||||
protected async Task DoFixMissing()
|
||||
{
|
||||
// procedo SOLO SE il numero online/offline è differente in primis...
|
||||
if (NeedAllocation)
|
||||
{
|
||||
// ciclo tutti gli utenti attivi
|
||||
// verifico SE sia disponibile licenza...
|
||||
var activationsList = LicServ.ActivList;
|
||||
Dictionary<string, string> CodList = new Dictionary<string, string>();
|
||||
|
||||
// ciclo x ogni dip attivo...
|
||||
foreach (var item in ListDipendentiAttiviOrd)
|
||||
{
|
||||
// calcolo codImpiego
|
||||
string currCodImp = LicServ.HashDip(item);
|
||||
// cerco se abbia attivazione
|
||||
var currActiv = activationsList.Where(x => x.CodImpiego == currCodImp).FirstOrDefault();
|
||||
if (currActiv == null || currActiv.CodImpiego != currCodImp)
|
||||
{
|
||||
CodList.Add(currCodImp, item.AuthKey);
|
||||
}
|
||||
}
|
||||
// provo attivazione in blocco
|
||||
await LicServ.TryActivationMult(CodList);
|
||||
// cmq faccio refresh
|
||||
await FullRefresh();
|
||||
// ricalcolo licenze
|
||||
await RefreshLicData(true);
|
||||
}
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task DoRefresh()
|
||||
{
|
||||
isLoading = true;
|
||||
await LicServ.resetActivList();
|
||||
await FullRefresh();
|
||||
await ReloadData();
|
||||
// ricalcolo licenze
|
||||
await RefreshLicData(false);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
protected void DoSelect(DipendentiModel currRec)
|
||||
{
|
||||
CtrlMode = DipendentiEdit.EditMode.KeyRegen;
|
||||
RecordEdit = currRec;
|
||||
}
|
||||
|
||||
protected async Task ForceReload()
|
||||
{
|
||||
currPage = 1;
|
||||
CtrlMode = DipendentiEdit.EditMode.None;
|
||||
RecordEdit = null;
|
||||
await ReloadData();
|
||||
// ricalcolo licenze
|
||||
await RefreshLicData(false);
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadConfData();
|
||||
await ReloadData();
|
||||
await RefreshLicData(true);
|
||||
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
|
||||
}
|
||||
|
||||
protected async Task SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
currPage = 1;
|
||||
await AppMServ.NumRowGridSet(gridKey, newNum);
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SortRequested(Sorter.SortCallBack e)
|
||||
{
|
||||
sortField = e.ParamName;
|
||||
sortAsc = e.IsAscending;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private int currPage = 1;
|
||||
|
||||
private DipendentiEdit.EditMode CtrlMode = DipendentiEdit.EditMode.None;
|
||||
|
||||
private string gridKey = "DipendentiMan";
|
||||
|
||||
private bool isLoading = false;
|
||||
|
||||
private int numRecord = 10;
|
||||
|
||||
private DipendentiModel? RecordEdit = null;
|
||||
|
||||
private string searchVal = "";
|
||||
|
||||
private bool ShowInatt = false;
|
||||
|
||||
private bool ShowLinkCore = true;
|
||||
|
||||
private bool ShowLinkInt = true;
|
||||
|
||||
private bool ShowQrCode = false;
|
||||
|
||||
private bool sortAsc = true;
|
||||
|
||||
private string sortField = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<DipendentiModel>? ListDipendenti { get; set; } = null;
|
||||
|
||||
private List<AnagOrariModel> ListOrari { get; set; } = null!;
|
||||
|
||||
private List<DipendentiModel>? ListRecords { get; set; } = null;
|
||||
|
||||
private List<DipendentiModel>? SearchRecords { get; set; } = null;
|
||||
|
||||
private int totalCount { get; set; } = 0;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void AppMServ_EA_SearchUpdated()
|
||||
{
|
||||
ReloadData().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifica licenza (se sia libera x modifica o prima associazione)
|
||||
/// </summary>
|
||||
/// <param name="IdxDip"></param>
|
||||
/// <returns></returns>
|
||||
public bool CheckFreeEdit(int IdxDip)
|
||||
{
|
||||
bool answ = false;
|
||||
if (IdxDip > 0)
|
||||
{
|
||||
// cerco!
|
||||
var currUser = ListDipendentiAttiviOrd.Where(x => x.IdxDipendente == IdxDip).FirstOrDefault();
|
||||
if (currUser != null)
|
||||
{
|
||||
// verifico SE sia disponibile licenza...
|
||||
var activationsList = LicServ.ActivList;
|
||||
var currHash = LicServ.HashDip(currUser);
|
||||
var currAct = activationsList.Where(x => x.CodImpiego == currHash).FirstOrDefault();
|
||||
// se NON c'è licenza è ok (editabile)
|
||||
answ = (currAct == null);
|
||||
// ora verifico: se NON ha licenza OK, altrimenti deve essere scaduta...
|
||||
if (!answ)
|
||||
{
|
||||
answ = currAct.VetoUnlock <= DateTime.Today;
|
||||
}
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
/// <summary>
|
||||
/// Rilascia licenza e rilegge conf
|
||||
/// </summary>
|
||||
/// <param name="CurrRecord"></param>
|
||||
/// <returns></returns>
|
||||
private async Task ReleaseLicense(DipendentiModel CurrRecord)
|
||||
{
|
||||
// verifica SE ci sono licenze disponibili
|
||||
if (NumLicDispOnline > NumLicActOnline)
|
||||
{
|
||||
// chiamo rimozione licenza
|
||||
var CodImpiego = LicServ.HashDip(CurrRecord);
|
||||
bool fatto = await LicServ.TryRemoveActivation(CodImpiego, CurrRecord.AuthKey);
|
||||
if (fatto)
|
||||
{
|
||||
// disattiva utente
|
||||
GDataServ.DipUpdateActive(CurrRecord.IdxDipendente, false);
|
||||
}
|
||||
LicServ.ResetLicenseData();
|
||||
}
|
||||
// disattivo record mostrato...
|
||||
RecordEdit = null;
|
||||
// ricarico
|
||||
await ReloadData();
|
||||
// ricalcolo licenze
|
||||
await RefreshLicData(true);
|
||||
}
|
||||
|
||||
private async Task DoActivate(DipendentiModel CurrRecord)
|
||||
{
|
||||
// verifica SE ci sono licenze disponibili
|
||||
if (NumLicDispOnline > NumLicActOnline)
|
||||
{
|
||||
// attiva utente
|
||||
GDataServ.DipUpdateActive(CurrRecord.IdxDipendente, true);
|
||||
|
||||
string CodImpiego = LicServ.HashDip(CurrRecord);
|
||||
|
||||
// effettua riassegnazione
|
||||
bool fatto = LicServ.TryActivation(CodImpiego, CurrRecord.AuthKey);
|
||||
}
|
||||
await ReloadData();
|
||||
// ricalcolo licenze
|
||||
await RefreshLicData(true);
|
||||
}
|
||||
|
||||
private async Task FullRefresh()
|
||||
{
|
||||
LicServ.ResetLicenseData();
|
||||
// eseguo call di recupero da online
|
||||
bool refreshApp = await LicServ.RefreshApplic();
|
||||
bool refreshAct = await LicServ.RefreshLicense();
|
||||
bool refreshPay = LicServ.RefreshPayload();
|
||||
// chiama update di TUTTE le authKey verso il server online
|
||||
int numLoc = 0;
|
||||
foreach (var item in ListDipendentiAttiviOrd)
|
||||
{
|
||||
var CodImpiego = LicServ.HashDip(item);
|
||||
bool fatto = await LicServ.TryRefreshActivation(CodImpiego, item.AuthKey);
|
||||
if (fatto)
|
||||
numLoc++;
|
||||
}
|
||||
Log.Trace($"NumLoc: {numLoc}");
|
||||
}
|
||||
|
||||
private async Task RefreshLicData(bool forceReload)
|
||||
{
|
||||
if (!LicServ.HasAppData || forceReload)
|
||||
{
|
||||
await FullRefresh();
|
||||
}
|
||||
NumLicDispLocal = LicServ.NumLicDb;
|
||||
NumLicActLocal = LicServ.ActivList.Count();
|
||||
NumLicDispOnline = LicServ.AppLicense.NumLicenze;
|
||||
NumLicActOnline = LicServ.AppLicense.NumLicenzeAttive;
|
||||
}
|
||||
|
||||
private async Task ReloadConfData()
|
||||
{
|
||||
ListOrari = await GDataServ.AnagOrarioAll();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
ListDipendenti = await GDataServ.DipendentiGetAll();
|
||||
if (ShowInatt)
|
||||
{
|
||||
SearchRecords = ListDipendenti;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = ListDipendenti.Where(x => (x.Attivo ?? false)).ToList();
|
||||
}
|
||||
|
||||
// eseguo filtro ricerca
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchVal))
|
||||
{
|
||||
SearchRecords = SearchRecords
|
||||
.Where(x => x.Cognome.Contains(searchVal) || x.Nome.Contains(searchVal) || x.Cf.Contains(searchVal) || x.Email.Contains(searchVal))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
|
||||
}
|
||||
totalCount = SearchRecords.Count;
|
||||
SortTable();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorting e paging tabella
|
||||
/// </summary>
|
||||
private void SortTable()
|
||||
{
|
||||
if (SearchRecords != null)
|
||||
{
|
||||
// se ho ordinamento riordino...
|
||||
if (!string.IsNullOrEmpty(sortField))
|
||||
{
|
||||
switch (sortField)
|
||||
{
|
||||
case "Cognome":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Cognome).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Cognome).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Nome":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Nome).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Nome).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Matricola":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Matricola).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Matricola).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Profilo":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.CodOrario).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.CodOrario).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Dominio":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Dominio).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Dominio).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Utente":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Utente).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Utente).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Email":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Email).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Email).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "CF":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Cf).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Cf).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "CodeHw":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.CodHw).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.CodHw).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "DatiAnag":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.LuogoNascita).ThenBy(x => x.ProvNascita).ThenBy(x => x.NazNascita).ThenBy(x => x.DataNascita).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.LuogoNascita).ThenBy(x => x.ProvNascita).ThenBy(x => x.NazNascita).ThenBy(x => x.DataNascita).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Gruppo":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Gruppo).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Gruppo).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "StatoLic":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.DataAssunzione).ThenBy(x => x.DataCessazione).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.DataAssunzione).ThenBy(x => x.DataCessazione).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Responsabile":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.idxResp).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.idxResp).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filtro x display
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<DipendentiModel>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
<span class="input-group-text" title="Cliente">C</span>
|
||||
<select @bind="@IdxCli" class="form-select form-select-sm" title="Cliente" @bind:after=SaveCli>
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListClienti)
|
||||
@foreach (var item in ListClientiFilt)
|
||||
{
|
||||
<option value="@item.IdxCliente">@($"{item.RagSociale}")</option>
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
<span class="input-group-text" title="Progetto">P</span>
|
||||
<select @bind="@IdxPrj" class="form-select form-select-sm" title="Progetto" @bind:after=SaveProj>
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListProgetti)
|
||||
@foreach (var item in ListProgettiFilt)
|
||||
{
|
||||
<option value="@item.IdxProgetto">@($"{item.NomeProj} | {item.DescrProj}")</option>
|
||||
}
|
||||
|
||||
@@ -86,6 +86,37 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
protected List<AnagClientiModel> ListClientiFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagClientiModel> answ = new List<AnagClientiModel>();
|
||||
if (ShowOnlyActive)
|
||||
{
|
||||
answ = ListClienti.Where(x => x.Attivo).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListClienti;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagProgettiModel> ListProgettiFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagProgettiModel> answ = new List<AnagProgettiModel>();
|
||||
if (IdxCli > 0)
|
||||
{
|
||||
ListProgetti = GDataServ.AnagProjByCli(IdxCli);
|
||||
answ = ListProgetti.Where(x => (x.Attivo ?? false) || !ShowOnlyActive).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
@@ -202,10 +233,10 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
/// init valori da config
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task InitConf()
|
||||
protected void InitConf()
|
||||
{
|
||||
// leggo conf standard controllo RegAtt
|
||||
var sWarningRatioPerc = await GDataServ.ConfigGetKey("WarningRatioPerc");
|
||||
var sWarningRatioPerc = GDataServ.ConfigGetKey("WarningRatioPerc");
|
||||
if (sWarningRatioPerc != null)
|
||||
{
|
||||
double.TryParse(sWarningRatioPerc.valore, out warnRatio);
|
||||
@@ -214,9 +245,9 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await InitConf();
|
||||
InitConf();
|
||||
await ReloadSel();
|
||||
await ReloadData();
|
||||
ReloadAnagBase();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
@@ -243,11 +274,14 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private string gridKey = "FasiMan";
|
||||
private int idxCli = 0;
|
||||
|
||||
private int idxPrj = 0;
|
||||
|
||||
private AnagFasiModel? RecordEdit = null;
|
||||
|
||||
private AnagFasiExplModel? RecordSel = null;
|
||||
|
||||
private double warnRatio = 50;
|
||||
|
||||
#endregion Private Fields
|
||||
@@ -255,11 +289,17 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
#region Private Properties
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private List<AnagClientiModel> ListClienti { get; set; } = new List<AnagClientiModel>();
|
||||
|
||||
private List<AnagProgettiModel> ListProgetti { get; set; } = new List<AnagProgettiModel>();
|
||||
|
||||
private List<AnagFasiExplModel>? listRecords { get; set; } = new List<AnagFasiExplModel>();
|
||||
|
||||
private List<TagFasiDTO> ListTagFasi { get; set; } = new List<TagFasiDTO>();
|
||||
|
||||
private string NewCodTagFase { get; set; } = "ND";
|
||||
|
||||
private int totalCount { get; set; } = 0;
|
||||
|
||||
#endregion Private Properties
|
||||
@@ -321,27 +361,18 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
return answ;
|
||||
}
|
||||
|
||||
private void ReloadAnagBase()
|
||||
{
|
||||
ListTagFasi = GDataServ.AnagTagFasiAll();
|
||||
ListClienti = GDataServ.AnagClientiAll();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
ListTagFasi = await GDataServ.AnagTagFasiAll();
|
||||
if (CanSelProj)
|
||||
{
|
||||
listRecords = new List<AnagFasiExplModel>();
|
||||
ListProgetti = new List<AnagProgettiModel>();
|
||||
ListClienti = await GDataServ.AnagClientiAll();
|
||||
if (ShowOnlyActive)
|
||||
{
|
||||
ListClienti = ListClienti.Where(x => x.Attivo).ToList();
|
||||
}
|
||||
// seleziono proj da client
|
||||
if (IdxCli > 0)
|
||||
{
|
||||
ListProgetti = await GDataServ.AnagProjByCli(IdxCli);
|
||||
if (ShowOnlyActive)
|
||||
{
|
||||
ListProgetti = ListProgetti.Where(x => x.Attivo ?? false).ToList();
|
||||
}
|
||||
}
|
||||
// se abilitato x rilettura locale --> leggo fasi!
|
||||
if (CanSelProj && IdxCli > 0 && IdxPrj > 0)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<div class="card shadow">
|
||||
<div class="card-header">
|
||||
Dettaglio Mensile
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Data <Sorter ParamName="Data" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Tag <Sorter ParamName="Tag" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@if (item.isActive)
|
||||
{
|
||||
<button class="btn btn-primary btn-sm px-1 py-0" @onclick="() => DoToggle(item)"><i class="fa-solid fa-thumbs-up"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm px-1 py-0" @onclick="() => DoToggle(item)"><i class="fa-solid fa-thumbs-down"></i></button>
|
||||
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@($"{item.DtRif:yyyy.MM.dd, dddd}")
|
||||
</td>
|
||||
<td class="text-end">@item.CodTag</td>
|
||||
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" totalCount="@totalCount" showLoading="@isLoading" numRecordChanged="SetNumRec" numPageChanged="SetPage"></EgwCoreLib.Razor.DataPager>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,213 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using EgwCoreLib.Utils;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using NLog;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class MonthTagDetail
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public MonthTagModel RecSel { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
protected int IdxDipSel { get; set; } = 0;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string CheckSel(TagFasiDTO curItem)
|
||||
{
|
||||
string answ = "";
|
||||
if (SelItem != null)
|
||||
{
|
||||
answ = curItem.CodTagFase == SelItem.CodTagFase ? "table-info" : "";
|
||||
}
|
||||
// verifico stato attivo
|
||||
answ += !curItem.Enabled ? " striked" : "";
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected void DoSelect(MonthTagModel currRec)
|
||||
{
|
||||
SelRecord = currRec;
|
||||
}
|
||||
|
||||
protected async Task DoToggle(ListTagDDModel selRec)
|
||||
{
|
||||
if (selRec != null)
|
||||
{
|
||||
GDataServ.ListTagDDToggle(selRec.IdxTagDD);
|
||||
}
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
CurrPeriodo.Fine = DateTime.Today.AddDays(1);
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
CurrPeriodo.Fine = new DateTime(RecSel.Anno, RecSel.Mese, 1).AddMonths(1);
|
||||
CurrPeriodo.Inizio = new DateTime(RecSel.Anno, RecSel.Mese, 1);
|
||||
IdxDipSel = RecSel.IdxDipendente;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async void Recalc()
|
||||
{
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
protected async Task SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
currPage = 1;
|
||||
await AppMServ.NumRowGridSet(gridKey, newNum);
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SortRequested(Sorter.SortCallBack e)
|
||||
{
|
||||
sortField = e.ParamName;
|
||||
sortAsc = e.IsAscending;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected string Traduci(string lemma)
|
||||
{
|
||||
return AuthServ.Traduci(lemma, AppMServ.UserLang);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private string gridKey = "TagsMan";
|
||||
private TagFasiDTO? SelItem = null;
|
||||
private bool sortAsc = true;
|
||||
private string sortField = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int currPage { get; set; } = 1;
|
||||
private DtUtils.Periodo CurrPeriodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisMonth);
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private List<ListTagDDModel>? ListRecords { get; set; } = null;
|
||||
private int numRecord { get; set; } = 50;
|
||||
private List<ListTagDDModel>? SearchRecords { get; set; } = null;
|
||||
private MonthTagModel? SelRecord { get; set; } = null;
|
||||
|
||||
private bool ShowInatt { get; set; } = false;
|
||||
|
||||
private int totalCount { get; set; } = 0;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.ListTagDD(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
|
||||
}
|
||||
totalCount = SearchRecords.Count;
|
||||
SortTable();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
|
||||
{
|
||||
CurrPeriodo = newPeiodo;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
private void SortTable()
|
||||
{
|
||||
if (SearchRecords != null)
|
||||
{
|
||||
// se ho ordinamento riordino...
|
||||
if (!string.IsNullOrEmpty(sortField))
|
||||
{
|
||||
switch (sortField)
|
||||
{
|
||||
#if true
|
||||
case "Data":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.DtRif).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.DtRif).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "IdxTagDD":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.IdxTagDD).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.IdxTagDD).ToList();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filtro x display
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<ListTagDDModel>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,91 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
<p>elenco da stored</p>
|
||||
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="@mainDivCss">
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload()"><i class="fa-solid fa-rotate"></i></button>
|
||||
</th>
|
||||
<th>Anno <Sorter ParamName="Anno" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Mese <Sorter ParamName="Mese" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Cognome Nome <Sorter ParamName="CognomeNome" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">CodTag <Sorter ParamName="CodTag" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end"># Tag <Sorter ParamName="NumTag" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end"># Dis <Sorter ParamName="NumDis" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
@*
|
||||
<th>Colonna 4 <Sorter ParamName="" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Colonna 5 <Sorter ParamName="" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th> *@
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="@CssCheckSel(item)">
|
||||
<td>
|
||||
@if (SelItem == null)
|
||||
{
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
|
||||
}
|
||||
</td>
|
||||
<td>@item.Anno</td>
|
||||
<td>@item.Mese</td>
|
||||
<td>@item.CognomeNome</td>
|
||||
<td class="text-end">@item.CodTag</td>
|
||||
<td class="text-end">@item.NumTag</td>
|
||||
<td class="text-end">@item.NumDis</td>
|
||||
|
||||
@*
|
||||
<td>
|
||||
@if (item.Enabled && item.NumFasi == 0)
|
||||
{
|
||||
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
|
||||
}
|
||||
</td> *@
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" totalCount="@totalCount" showLoading="@isLoading" numRecordChanged="SetNumRec" numPageChanged="SetPage"></EgwCoreLib.Razor.DataPager>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
@if (SelRecord != null)
|
||||
{
|
||||
<div class="@detDivCss">
|
||||
<MonthTagDetail RecSel="@SelRecord"></MonthTagDetail>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using EgwCoreLib.Utils;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using NLog;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
@@ -24,6 +27,38 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string CheckSel(TagFasiDTO curItem)
|
||||
{
|
||||
string answ = "";
|
||||
if (SelItem != null)
|
||||
{
|
||||
answ = curItem.CodTagFase == SelItem.CodTagFase ? "table-info" : "";
|
||||
}
|
||||
// verifico stato attivo
|
||||
answ += !curItem.Enabled ? " striked" : "";
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected void DoSelect(MonthTagModel currRec)
|
||||
{
|
||||
SelRecord = currRec;
|
||||
}
|
||||
|
||||
private string mainDivCss
|
||||
{
|
||||
get => SelRecord == null ? "col-12" : "col-12 col-lg-9";
|
||||
}
|
||||
private string detDivCss
|
||||
{
|
||||
get => SelRecord == null ? "col-0" : "col-12 col-lg-3";
|
||||
}
|
||||
|
||||
protected string CssCheckSel(MonthTagModel currRec)
|
||||
{
|
||||
bool isSel = SelRecord != null && SelRecord.IdxDipendente == currRec.IdxDipendente && SelRecord.Anno == currRec.Anno && SelRecord.Mese == currRec.Mese;
|
||||
return isSel ? "table-info" : "";
|
||||
}
|
||||
|
||||
protected async Task ForceReload()
|
||||
{
|
||||
currPage = 1;
|
||||
@@ -31,14 +66,25 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
CurrPeriodo.Fine = DateTime.Today.AddDays(1);
|
||||
}
|
||||
|
||||
protected async void Recalc()
|
||||
protected async Task Recalc()
|
||||
{
|
||||
await Task.Delay(200);
|
||||
// eseguo ricalcolo
|
||||
isLoading = true;
|
||||
GDataServ.MonthTagRecalc(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, "BP", 270);
|
||||
// rileggo
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task SortRequested(Sorter.SortCallBack e)
|
||||
{
|
||||
sortField = e.ParamName;
|
||||
sortAsc = e.IsAscending;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected string Traduci(string lemma)
|
||||
@@ -46,8 +92,33 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
return AuthServ.Traduci(lemma, AppMServ.UserLang);
|
||||
}
|
||||
|
||||
|
||||
protected async Task SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
currPage = 1;
|
||||
await AppMServ.NumRowGridSet(gridKey, newNum);
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private string gridKey = "TagsMan";
|
||||
private TagFasiDTO? SelItem = null;
|
||||
private bool sortAsc = true;
|
||||
private string sortField = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int currPage { get; set; } = 1;
|
||||
@@ -57,9 +128,8 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
|
||||
|
||||
private List<MonthTagModel>? ListRecords { get; set; } = null;
|
||||
|
||||
private int numRecord { get; set; } = 10;
|
||||
|
||||
private List<MonthTagModel>? SearchRecords { get; set; } = null;
|
||||
private MonthTagModel? SelRecord { get; set; } = null;
|
||||
|
||||
private bool ShowInatt { get; set; } = false;
|
||||
@@ -83,10 +153,9 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
ListDipendenti = rawList.Where(x => (x.Attivo ?? false)).ToList();
|
||||
}
|
||||
#if false
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.TeRaExplGetFilt(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, ShowInatt, ShowWE, MaxErrMin, MaxErrPlus);
|
||||
SearchRecords = await GDataServ.MonthTagList(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
|
||||
// verifico filtro per IdxDip
|
||||
if (IdxDipSel > 0)
|
||||
{
|
||||
@@ -100,10 +169,6 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
totalCount = SearchRecords.Count;
|
||||
SortTable();
|
||||
isLoading = false;
|
||||
// tolgo eventuale send data...
|
||||
isSendingData = false;
|
||||
#endif
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
|
||||
@@ -112,6 +177,100 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
private void SortTable()
|
||||
{
|
||||
if (SearchRecords != null)
|
||||
{
|
||||
// se ho ordinamento riordino...
|
||||
if (!string.IsNullOrEmpty(sortField))
|
||||
{
|
||||
switch (sortField)
|
||||
{
|
||||
#if true
|
||||
case "Anno":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Anno).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Anno).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Mese":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Mese).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Mese).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "CognomeNome":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.CognomeNome).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.CognomeNome).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "CodTag":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.CodTag).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.CodTag).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "NumTag":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.NumTag).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.NumTag).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "NumDis":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.NumDis).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.NumDis).ToList();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filtro x display
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<MonthTagModel>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -146,18 +146,17 @@
|
||||
@if (ShowFasi && RecordSel != null)
|
||||
{
|
||||
<tr class="align-middle @CheckSel(RecordSel)">
|
||||
<td>
|
||||
|
||||
<td class="text-nowrap">
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-search"></i></button>
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-angles-right"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-nowrap">
|
||||
<div class="fw-bold">
|
||||
@RecordSel.Gruppo
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-nowrap">
|
||||
<div class="fw-bold">
|
||||
@RecordSel.RagSociale
|
||||
</div>
|
||||
@@ -189,13 +188,12 @@
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="align-middle @CheckSel(item)">
|
||||
<td>
|
||||
<td class="text-nowrap">
|
||||
@if (RecordEdit == null)
|
||||
{
|
||||
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
|
||||
<button class="btn btn-warning btn-sm" @onclick="() => DoShowFasi(item)"><i class="fa-solid fa-angles-right"></i></button>
|
||||
@* <a class="btn btn-warning btn-sm" href="fasi" target="_blank"><i class="fa-solid fa-angles-right"></i></a> *@
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -204,12 +202,12 @@
|
||||
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-angles-right"></i></button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-nowrap">
|
||||
<div class="fw-bold">
|
||||
@item.Gruppo
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-nowrap">
|
||||
<div class="fw-bold">
|
||||
@item.RagSociale
|
||||
</div>
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
protected async Task initConf()
|
||||
{
|
||||
// leggo conf standard controllo RegAtt
|
||||
var sWarningRatioPerc = await GDataServ.ConfigGetKey("WarningRatioPerc");
|
||||
var sWarningRatioPerc = await GDataServ.ConfigGetKeyAsync("WarningRatioPerc");
|
||||
if (sWarningRatioPerc != null)
|
||||
{
|
||||
double.TryParse(sWarningRatioPerc.valore, out warnRatio);
|
||||
@@ -374,7 +374,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
ListGruppi = await GDataServ.AnagGruppiAll();
|
||||
ListClienti = await GDataServ.AnagClientiAll();
|
||||
ListClienti = await GDataServ.AnagClientiAllAsync();
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.AnagProjCalcFilt(Gruppo, IdxCliente, ShowPrjArc, ShowPrjZH, ShowPrjStr);
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
SearchRecords = null;
|
||||
await Task.Delay(1);
|
||||
SearchRecords = await GDataServ.RegMalattieGetByPeriod(DtStart, DtEnd);
|
||||
SearchRecords = GDataServ.RegMalattieGetByPeriod(DtStart, DtEnd);
|
||||
// conteggio!
|
||||
totalCount = SearchRecords.Count;
|
||||
// paginazione
|
||||
|
||||
@@ -294,12 +294,12 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
private async Task initConf()
|
||||
{
|
||||
// leggo conf standard giorni permessi/ferie
|
||||
var sNumDayFerieRichAntic = await GDataServ.ConfigGetKey("NumDayFerieRichAntic");
|
||||
var sNumDayFerieRichAntic = await GDataServ.ConfigGetKeyAsync("NumDayFerieRichAntic");
|
||||
if (sNumDayFerieRichAntic != null)
|
||||
{
|
||||
int.TryParse(sNumDayFerieRichAntic.valore, out NumDayFerieRichAntic);
|
||||
}
|
||||
var sNumDayPermMax = await GDataServ.ConfigGetKey("NumDayPermMax");
|
||||
var sNumDayPermMax = await GDataServ.ConfigGetKeyAsync("NumDayPermMax");
|
||||
if (sNumDayPermMax != null)
|
||||
{
|
||||
int.TryParse(sNumDayPermMax.valore, out NumDayPermMax);
|
||||
@@ -364,7 +364,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
await initConf();
|
||||
await Task.Delay(1);
|
||||
// carico richieste di TUTTI
|
||||
SearchRecords = await GDataServ.RegRichiesteGetByDip(0, dtInizio, dtFine);
|
||||
SearchRecords = GDataServ.RegRichiesteGetByDip(0, dtInizio, dtFine);
|
||||
// filtro x tipo richieste...
|
||||
if (ShowNeedConf)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
<div class="card shadow mb-5 border border-secondary">
|
||||
<div class="card-header">
|
||||
<h3>Elaborazioni disponibili</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<a target="_blank" href="@(fullUrl(item.ReportUrl))" class="col-12 col-md-6 col-lg-4 col-xl-3 p-2">
|
||||
<div class="border border-2 border-dark rounded rounded-4 shadow shadow-lg @item.CssClass">
|
||||
<div class="areaTesto px-2">
|
||||
<h3>@item.Nome</h3>
|
||||
<p class="small">@item.Descrizione</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class ReportProgettiMan
|
||||
{
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected IConfiguration config { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string fullUrl(string repUrl)
|
||||
{
|
||||
return $"{reportBaseUrl}{repUrl}";
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
reportBaseUrl = config.GetValue<string>("ServerConf:ReportBaseUrl") ?? "http://W2019-SQL-STEAM/ReportServer?";
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected string Traduci(string lemma)
|
||||
{
|
||||
return AuthServ.Traduci(lemma, AppMServ.UserLang);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private bool isLoading = false;
|
||||
private string reportBaseUrl = "";
|
||||
private int totalCount = 0;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<ElencoReportModel>? ListRecords { get; set; } = null;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
ListRecords = await GDataServ.ElencoReportFilt("A1");
|
||||
totalCount = ListRecords.Count;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
// svuoto temp folder dopo 1 min
|
||||
await clearDir(1);
|
||||
// carico conf specifica...
|
||||
var rCodTimbra = await GDataServ.ConfigGetKey("ExpOreCodTimbra");
|
||||
var rCodTimbra = await GDataServ.ConfigGetKeyAsync("ExpOreCodTimbra");
|
||||
if (rCodTimbra != null)
|
||||
{
|
||||
TimbExp = rCodTimbra.valore;
|
||||
@@ -322,7 +322,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
foreach (var item in list2fix)
|
||||
{
|
||||
// escludo date da oggi in poi...
|
||||
// escludo date da dtRif in poi...
|
||||
if (item.DataLav < DateTime.Today)
|
||||
{
|
||||
GiustificativiModel rec2del = new GiustificativiModel()
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
|
||||
<div class="card shadow mb-5 border border-secondary">
|
||||
<div class="card-header px-0">
|
||||
<div class="d-flex justify-content-between px-2">
|
||||
<div class="px-0 d-flex justify-content-between">
|
||||
<div class="px-2">
|
||||
<h3>Attività</h3>
|
||||
</div>
|
||||
|
||||
@* <div class="px-2">
|
||||
<button class="btn btn-success" @onclick=Recalc tooltip="Add New"><i class="fa-solid fa-plus"></i> @Traduci("Ricalcola")</button>
|
||||
</div> *@
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<div class="px-0">
|
||||
<div class="d-flex">
|
||||
<div class="px-1 align-content-center">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
Dipendente
|
||||
</span>
|
||||
<select @bind="@IdxDipSel" class="form-select form-select-sm" @bind:after=ForceReload>
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListDipendentiFilt)
|
||||
{
|
||||
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowDipInatt>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<PeriodoSel CurrPeriodo="@CurrPeriodo" E_PeriodoSel="@SavePeriodo"></PeriodoSel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end bg-secondary bg-gradient bg-opacity-75 py-1 px-0">
|
||||
<div class="px-1 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
Cliente
|
||||
</span>
|
||||
<select @bind="@IdxCliSelFrom" class="form-select form-select-sm" @bind:after=ForceReload>
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListClientiFiltFrom)
|
||||
{
|
||||
<option value="@item.IdxCliente">@($"{item.RagSociale}")</option>
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowCliInattFrom>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-1 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
Progetto
|
||||
</span>
|
||||
@if (IdxCliSelFrom == 0)
|
||||
{
|
||||
<select @bind="@IdxProjSelFrom" disabled class="form-select form-select-sm text-trim opacity-75" style="maxFrom-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select @bind="@IdxProjSelFrom" class="form-select form-select-sm text-trim" style="max-width:20rem;" @bind:after=ForceReload>
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListProgettiFiltFrom)
|
||||
{
|
||||
<option value="@item.IdxProgetto" title="@($"{item.DescrProj}")">@($"{item.NomeProj}")</option>
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowProjInattFrom>
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-2 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">Fase</span>
|
||||
@if (IdxProjSelFrom == 0)
|
||||
{
|
||||
<select @bind="@IdxFaseSelFrom" disabled class="form-select form-select-sm text-trim opacity-75" style="max-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select @bind="@IdxFaseSelFrom" class="form-select form-select-sm text-trim" style="max-width:20rem;" @bind:after=ForceReload>
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListFasiFiltFrom)
|
||||
{
|
||||
if (item.BudgetTime > 0)
|
||||
{
|
||||
<option value="@item.IdxFase" title="@($"{item.DescrizioneFase}")">@($"{item.NomeFase}")</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option disabled class="bg-secondary bg-opacity-25 fw-bold" value="@item.IdxFase" title="@($"{item.DescrizioneFase}")">@($"{item.NomeFase}")</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowFaseInattFrom>
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="@mainDivCss">
|
||||
<table class="table table-striped table-sm text-start small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center" title="Toggle Seleziona Tutti">
|
||||
@if (allSel)
|
||||
{
|
||||
<i class="fa-solid fa-toggle-on text-primary fs-5" @onclick="ToggleSelection"></i>
|
||||
}
|
||||
else
|
||||
{
|
||||
<i class="fa-solid fa-toggle-off text-secondary fs-5" @onclick="ToggleSelection"></i>
|
||||
}
|
||||
</th>
|
||||
<th class="text-start">Cognome Nome <Sorter ParamName="CognomeNome" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-start">Ore <Sorter ParamName="OreTot" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-start">Periodo <Sorter ParamName="Periodo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-start">Gruppo <Sorter ParamName="Gruppo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-start">Progetto <Sorter ParamName="Progetto" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-start">Descrizione <Sorter ParamName="Descrizione" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="@CssCheckSel(item)">
|
||||
<td class="text-center">
|
||||
<input class="form-check-input" type="checkbox" @bind="item.Selected"></input>
|
||||
</td>
|
||||
<td class="text-start">@item.CognomeNome</td>
|
||||
<td class="text-start">@($"{item.OreTot:N2}")</td>
|
||||
<td class="text-center">
|
||||
<div class="bg-secondary bg-gradient rounded-2 text-light text-nowrap px-3 py-1">
|
||||
@($"{item.Inizio:dd/MM/yy HH:mm}") - @($"{item.Fine:HH:mm}")
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-start">@($"{item.Gruppo}") - @($"{item.RagSociale}")</td>
|
||||
<td class="text-start">@($"{item.NomeProj}") - @($"{item.NomeFase}")</td>
|
||||
<td class="text-start text-truncate" style="max-width: 20rem;" title="@item.Descrizione">@item.Descrizione</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" totalCount="@totalCount" showLoading="@isLoading" numRecordChanged="SetNumRec" numPageChanged="SetPage"></EgwCoreLib.Razor.DataPager>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer bg-primary bg-gradient bg-opacity-75 px-0 py-0">
|
||||
<div class="d-flex justify-content-between py-1">
|
||||
<div class="px-1 d-flex">
|
||||
<div class="px-1 align-content-center">
|
||||
@if (IdxFaseSelTo > 0 && HasRowSelected)
|
||||
{
|
||||
<button class="btn btn-success shadow" @onclick="SpostaSel">Sposta Ore <i class="fa-solid fa-angles-right"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary disabled">Sposta Ore <i class="fa-solid fa-angles-right"></i></button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-1 d-flex justify-content-end">
|
||||
<div class="px-1 d-flex align-content-center">
|
||||
</div>
|
||||
<div class="px-1 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
Cliente
|
||||
</span>
|
||||
<select @bind="@IdxCliSelTo" class="form-select form-select-sm">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListClientiFiltTo)
|
||||
{
|
||||
<option value="@item.IdxCliente">@($"{item.RagSociale}")</option>
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowCliInattTo>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-1 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">Progetto</span>
|
||||
@if (IdxCliSelTo == 0)
|
||||
{
|
||||
<select @bind="@IdxProjSelTo" disabled class="form-select form-select-sm text-trim opacity-75" style="max-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select @bind="@IdxProjSelTo" class="form-select form-select-sm text-trim" style="max-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListProgettiFiltTo)
|
||||
{
|
||||
<option value="@item.IdxProgetto" title="@($"{item.DescrProj}")">@($"{item.NomeProj}")</option>
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowProjInattTo>
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-1 d-flex">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">Fase</span>
|
||||
@if (IdxProjSelTo == 0)
|
||||
{
|
||||
<select @bind="@IdxFaseSelTo" disabled class="form-select form-select-sm text-trim opacity-75" style="max-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select @bind="@IdxFaseSelTo" class="form-select form-select-sm text-trim" style="max-width:20rem;">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@foreach (var item in ListFasiFiltTo)
|
||||
{
|
||||
|
||||
if (item.BudgetTime > 0)
|
||||
{
|
||||
<option value="@item.IdxFase" title="@($"{item.DescrizioneFase}")">@($"{item.NomeFase}")</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option disabled class="bg-secondary bg-opacity-25 fw-bold" value="@item.IdxFase" title="@($"{item.DescrizioneFase}")">@($"{item.NomeFase}")</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text px-0">
|
||||
<span class="form-check form-switch align-content-center ms-2" title="Mostra inattivi">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowFaseInattTo>
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,546 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using EgwCoreLib.Utils;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.DTO;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using NLog;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class SpostaOreMan : IDisposable
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
protected bool HasRowSelected
|
||||
{
|
||||
get => ListRecords != null && ListRecords.Where(x => x.Selected).Count() > 0;
|
||||
}
|
||||
|
||||
protected int IdxCliSelFrom
|
||||
{
|
||||
get => idxCliFrom;
|
||||
set
|
||||
{
|
||||
if (idxCliFrom != value)
|
||||
{
|
||||
idxCliFrom = value;
|
||||
idxProjFrom = 0;
|
||||
idxFaseFrom = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int IdxCliSelTo
|
||||
{
|
||||
get => idxCliTo;
|
||||
set
|
||||
{
|
||||
if (idxCliTo != value)
|
||||
{
|
||||
idxCliTo = value;
|
||||
idxProjTo = 0;
|
||||
idxFaseTo = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int IdxDipSel
|
||||
{
|
||||
get => idxDipendente;
|
||||
set => idxDipendente = value;
|
||||
}
|
||||
|
||||
protected int IdxFaseSelFrom
|
||||
{
|
||||
get => idxFaseFrom;
|
||||
set => idxFaseFrom = value;
|
||||
}
|
||||
|
||||
protected int IdxFaseSelTo
|
||||
{
|
||||
get => idxFaseTo;
|
||||
set => idxFaseTo = value;
|
||||
}
|
||||
|
||||
protected int IdxProjSelFrom
|
||||
{
|
||||
get => idxProjFrom;
|
||||
set
|
||||
{
|
||||
if (idxProjFrom != value)
|
||||
{
|
||||
idxProjFrom = value;
|
||||
idxFaseFrom = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int IdxProjSelTo
|
||||
{
|
||||
get => idxProjTo;
|
||||
set
|
||||
{
|
||||
if (idxProjTo != value)
|
||||
{
|
||||
idxProjTo = value;
|
||||
idxFaseTo = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
protected List<AnagClientiModel> ListClientiFiltFrom
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagClientiModel> answ = new List<AnagClientiModel>();
|
||||
if (ShowCliInattFrom)
|
||||
{
|
||||
answ = ListClienti;
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListClienti.Where(x => x.Attivo).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagClientiModel> ListClientiFiltTo
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagClientiModel> answ = new List<AnagClientiModel>();
|
||||
if (ShowCliInattTo)
|
||||
{
|
||||
answ = ListClienti;
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListClienti.Where(x => x.Attivo).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<DipendentiModel> ListDipendentiFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
List<DipendentiModel> answ = new List<DipendentiModel>();
|
||||
if (ShowDipInatt)
|
||||
{
|
||||
answ = ListDipendenti;
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = ListDipendenti.Where(x => (x.Attivo ?? false)).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagFasiModel> ListFasiFiltFrom
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagFasiModel> answ = new List<AnagFasiModel>();
|
||||
if (idxProjFrom > 0)
|
||||
{
|
||||
answ = ListFasi
|
||||
.Where(x => x.IdxProgetto == IdxProjSelFrom && (x.Attivo || ShowFaseInattFrom))
|
||||
.OrderBy(x => x.CodFase)
|
||||
.ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagFasiModel> ListFasiFiltTo
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagFasiModel> answ = new List<AnagFasiModel>();
|
||||
if (idxProjTo > 0)
|
||||
{
|
||||
answ = ListFasi
|
||||
.Where(x => x.IdxProgetto == IdxProjSelTo && (x.Attivo || ShowFaseInattTo))
|
||||
.OrderBy(x => x.CodFase)
|
||||
.ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagProgettiModel> ListProgettiFiltFrom
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagProgettiModel> answ = new List<AnagProgettiModel>();
|
||||
if (idxCliFrom > 0)
|
||||
{
|
||||
answ = ListProgetti.Where(x => x.IdxCliente == IdxCliSelFrom && ((x.Attivo ?? false) || ShowProjInattFrom)).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<AnagProgettiModel> ListProgettiFiltTo
|
||||
{
|
||||
get
|
||||
{
|
||||
List<AnagProgettiModel> answ = new List<AnagProgettiModel>();
|
||||
if (idxCliTo > 0)
|
||||
{
|
||||
answ = ListProgetti.Where(x => x.IdxCliente == IdxCliSelTo && ((x.Attivo ?? false) || ShowProjInattTo)).ToList();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string CssCheckSel(RegAttDayExpDTO currRec)
|
||||
{
|
||||
bool isSel = SelRecord != null && SelRecord.IdxDipendente == currRec.IdxDipendente;
|
||||
return isSel ? "table-info" : "";
|
||||
}
|
||||
|
||||
protected async Task ForceReload()
|
||||
{
|
||||
currPage = 1;
|
||||
SelRecord = null;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task ForceReloadList()
|
||||
{
|
||||
await ReloadBaseData();
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
|
||||
await ReloadBaseData();
|
||||
}
|
||||
|
||||
protected async void Recalc()
|
||||
{
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
protected async Task SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
currPage = 1;
|
||||
await AppMServ.NumRowGridSet(gridKey, newNum);
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
allSel = false;
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
protected async Task SortRequested(Sorter.SortCallBack e)
|
||||
{
|
||||
sortField = e.ParamName;
|
||||
sortAsc = e.IsAscending;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua spostamento degli item selezionati verso la fase di destinazione
|
||||
/// </summary>
|
||||
protected async Task SpostaSel()
|
||||
{
|
||||
var cliente = ListClienti.FirstOrDefault(x => x.IdxCliente == IdxCliSelTo);
|
||||
var progetto = ListProgetti.FirstOrDefault(x => x.IdxProgetto == IdxProjSelTo);
|
||||
var fase = ListFasi.FirstOrDefault(x => x.IdxFase == IdxFaseSelTo);
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler spostare i record selezionati?{Environment.NewLine}{Environment.NewLine}Cliente: {cliente.RagSociale}{Environment.NewLine}Progetto: {progetto.NomeProj} | {progetto.DescrProj}{Environment.NewLine}Fase: {fase.DescrizioneFase}"))
|
||||
return;
|
||||
|
||||
// solo se ho una fase dest selezionata
|
||||
if (IdxFaseSelTo > 0)
|
||||
{
|
||||
Dictionary<int, int> list2move = new Dictionary<int, int>();
|
||||
foreach (var item in ListRecords)
|
||||
{
|
||||
if (item.Selected)
|
||||
{
|
||||
// inserisco in dizionario la riga da spostare
|
||||
list2move.Add(item.IdxRA, IdxFaseSelTo);
|
||||
}
|
||||
}
|
||||
// sposto righe!
|
||||
await GDataServ.RegAttUpdateFase(list2move);
|
||||
await ReloadData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua toggle selezione globale delle righe mostrateGpwDataService gDataServprivate async Task ReloadData
|
||||
/// </summary>
|
||||
protected void ToggleSelection()
|
||||
{
|
||||
allSel = !allSel;
|
||||
foreach (var item in ListRecords)
|
||||
{
|
||||
item.Selected = allSel;
|
||||
}
|
||||
}
|
||||
|
||||
protected string Traduci(string lemma)
|
||||
{
|
||||
return AuthServ.Traduci(lemma, AppMServ.UserLang);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private bool allSel = false;
|
||||
|
||||
private int currPage = 1;
|
||||
|
||||
private string gridKey = "TimbMan";
|
||||
|
||||
private int idxCliFrom = 0;
|
||||
|
||||
private int idxCliTo = 0;
|
||||
|
||||
private int idxDipendente = 0;
|
||||
|
||||
private int idxFaseFrom = 0;
|
||||
|
||||
private int idxFaseTo = 0;
|
||||
|
||||
private int idxProjFrom = 0;
|
||||
|
||||
private int idxProjTo = 0;
|
||||
|
||||
private bool isAncest = false;
|
||||
|
||||
private bool isLoading = false;
|
||||
|
||||
private int numRecord = 10;
|
||||
|
||||
private bool ShowCliInattFrom = false;
|
||||
|
||||
private bool ShowCliInattTo = false;
|
||||
|
||||
private bool ShowDipInatt = false;
|
||||
|
||||
private bool ShowFaseInattFrom = false;
|
||||
|
||||
private bool ShowFaseInattTo = false;
|
||||
|
||||
private bool ShowProjInattFrom = false;
|
||||
|
||||
private bool ShowProjInattTo = false;
|
||||
|
||||
private bool sortAsc = true;
|
||||
|
||||
private string sortField = "";
|
||||
|
||||
private int totalCount = 0;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private DtUtils.Periodo CurrPeriodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisMonth);
|
||||
|
||||
private List<AnagClientiModel> ListClienti { get; set; } = new List<AnagClientiModel>();
|
||||
|
||||
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
|
||||
|
||||
private List<AnagFasiModel> ListFasi { get; set; } = new List<AnagFasiModel>();
|
||||
|
||||
private List<AnagProgettiModel> ListProgetti { get; set; } = new List<AnagProgettiModel>();
|
||||
|
||||
private List<RegAttDayExpDTO>? ListRecords { get; set; } = null;
|
||||
|
||||
private string mainDivCss
|
||||
{
|
||||
get => SelRecord == null ? "col-12" : "col-12 col-lg-9";
|
||||
}
|
||||
|
||||
private List<RegAttDayExpDTO>? SearchRecords { get; set; } = null;
|
||||
|
||||
private RegAttDayExpDTO? SelRecord { get; set; } = null;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async void AppMServ_EA_SearchUpdated()
|
||||
{
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caricamento dati "statici" dei selettori
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task ReloadBaseData()
|
||||
{
|
||||
ListDipendenti = await GDataServ.DipendentiGetAll();
|
||||
ListClienti = await GDataServ.AnagClientiAllAsync();
|
||||
ListProgetti = await GDataServ.AnagProjAll();
|
||||
ListFasi = await GDataServ.AnagFasiAll();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
// tolgo selezione toggle
|
||||
allSel = false;
|
||||
|
||||
// carico i dati della tabella
|
||||
List<RegAttivitaDayExplModel> rawData = await GDataServ.RegAttDayExplList(idxDipendente, CurrPeriodo.Inizio, CurrPeriodo.Fine, idxCliFrom, idxProjFrom, idxFaseFrom, isAncest);
|
||||
|
||||
// se ho ricerca filtro (descrizione)
|
||||
if (!string.IsNullOrWhiteSpace(AppMServ.SearchVal))
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.Descrizione.Contains(AppMServ.SearchVal, StringComparison.InvariantCultureIgnoreCase))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// converto da model a DTO...
|
||||
SearchRecords = rawData
|
||||
.Select(x => new RegAttDayExpDTO(x))
|
||||
.ToList();
|
||||
totalCount = SearchRecords.Count;
|
||||
|
||||
// paginazione e sorting
|
||||
SortTable();
|
||||
|
||||
isLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
|
||||
{
|
||||
CurrPeriodo = newPeiodo;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
private void SortTable()
|
||||
{
|
||||
if (SearchRecords != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sortField))
|
||||
{
|
||||
switch (sortField)
|
||||
{
|
||||
case "CognomeNome":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.CognomeNome).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.CognomeNome).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "OreTot":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.OreTot).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.OreTot).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Periodo":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Inizio).ThenBy(x => x.Fine).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Inizio).ThenBy(x => x.Fine).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Gruppo":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Gruppo).ThenBy(x => x.RagSociale).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Gruppo).ThenBy(x => x.RagSociale).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Progetto":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.NomeProj).ThenBy(x => x.NomeFase).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.NomeProj).ThenBy(x => x.NomeFase).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Descrizione":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Descrizione).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Descrizione).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
<div class="alert alert-warning text-bg-danger align-content-center text-center fs-4">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
protected string CheckSel(TagFasiDTO curItem)
|
||||
{
|
||||
string answ = "";
|
||||
|
||||
if (SelItem != null)
|
||||
{
|
||||
answ = curItem.CodTagFase == SelItem.CodTagFase ? "table-info" : "";
|
||||
@@ -154,7 +155,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
ListRecords = null;
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.AnagTagFasiAll();
|
||||
SearchRecords = await GDataServ.AnagTagFasiAllAsync();
|
||||
// verifico filtro per ricerca
|
||||
if (!string.IsNullOrEmpty(CurrSearch))
|
||||
{
|
||||
@@ -166,7 +167,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
|
||||
}
|
||||
totalCount = SearchRecords.Count;
|
||||
SortTable();
|
||||
SortTable();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
@if (model.DtEnd.Subtract(model.DtStart).TotalDays < 1)
|
||||
@if (model.DtEnd.Subtract(model.DtStart).TotalDays < 1 && model.CodTipo != "FER")
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<div class="d-flex justify-content-between">
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
@if(!model.Conf)
|
||||
@if (!model.Conf)
|
||||
{
|
||||
<li class="list-group-item text-center bg-danger text-warning">
|
||||
<b>NON CONFERMATO</b>
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<div class="card shadow">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0 d-flex">
|
||||
<div class="px-0">
|
||||
<h3>@Traduci("timbMensili")</h3>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<button class="btn btn-success" @onclick=Recalc tooltip="Add New"><i class="fa-solid fa-plus"></i> @Traduci("Ricalcola")</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<div class="d-flex align-middle">
|
||||
<div class="px-1 py-2">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" @bind=@ShowInatt @bind:after=ForceReload>
|
||||
<label class="form-check-label">Mostra Inattivi</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="px-1 py-1">
|
||||
<select @bind="@IdxDipSel" class="form-select form-select-sm" @bind:after=ForceReload>
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListDipendenti)
|
||||
{
|
||||
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<PeriodoSel CurrPeriodo="@CurrPeriodo" E_PeriodoSel="@SavePeriodo"></PeriodoSel>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1 small">
|
||||
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="@mainDivCss">
|
||||
<table class="table table-striped table-sm text-start">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-end">Anno <Sorter ParamName="Anno" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Mese <Sorter ParamName="Mese" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Dipendente <Sorter ParamName="IdxDipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Ordinarie <Sorter ParamName="totOreOrd" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Lavorate <Sorter ParamName="totLav" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Non Lavorate <Sorter ParamName="totOreNonLav" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Permessi <Sorter ParamName="totOrePerm" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Ferie <Sorter ParamName="totOreFer" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Festive <Sorter ParamName="totOreFest" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end">Straordinarie <Sorter ParamName="totOreStra" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="@CssCheckSel(item)">
|
||||
<td class="text-end">@item.Anno</td>
|
||||
<td class="text-end">@item.Mese</td>
|
||||
<td class="text-end">@item.IdxDipendente</td>
|
||||
<td class="text-end">@item.totOreOrd</td>
|
||||
<td class="text-end">@item.totLav.ToString("N2")</td>
|
||||
<td class="text-end">@item.totOreNonLav.ToString("N2")</td>
|
||||
<td class="text-end">@item.totOrePerm.ToString("N2")</td>
|
||||
<td class="text-end">@item.totOreFer</td>
|
||||
<td class="text-end">@item.totOreFest</td>
|
||||
<td class="text-end">@item.totOreStra.ToString("N2")</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" totalCount="@totalCount" showLoading="@isLoading" numRecordChanged="SetNumRec" numPageChanged="SetPage"></EgwCoreLib.Razor.DataPager>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using EgwCoreLib.Utils;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using NLog;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class TimbMensMan
|
||||
{
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
protected int IdxDipSel { get; set; } = 0;
|
||||
|
||||
|
||||
protected string Traduci(string lemma)
|
||||
{
|
||||
return AuthServ.Traduci(lemma, AppMServ.UserLang);
|
||||
}
|
||||
|
||||
|
||||
protected async void Recalc()
|
||||
{
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
protected async Task ForceReload()
|
||||
{
|
||||
currPage = 1;
|
||||
SelRecord = null;
|
||||
await ReloadData();
|
||||
}
|
||||
protected async Task SortRequested(Sorter.SortCallBack e)
|
||||
{
|
||||
sortField = e.ParamName;
|
||||
sortAsc = e.IsAscending;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected string CssCheckSel(TimbMeseExplModel currRec)
|
||||
{
|
||||
bool isSel = SelRecord != null && SelRecord.IdxDipendente == currRec.IdxDipendente && SelRecord.Anno == currRec.Anno && SelRecord.Mese == currRec.Mese;
|
||||
return isSel ? "table-info" : "";
|
||||
}
|
||||
|
||||
|
||||
protected async Task SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
currPage = 1;
|
||||
await AppMServ.NumRowGridSet(gridKey, newNum);
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
protected async Task SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
await InvokeAsync(ReloadData);
|
||||
}
|
||||
|
||||
private bool sortAsc = true;
|
||||
|
||||
private string sortField = "";
|
||||
private bool ShowInatt { get; set; } = false;
|
||||
private int currPage { get; set; } = 1;
|
||||
private TimbMeseExplModel? SelRecord { get; set; } = null;
|
||||
private bool isLoading { get; set; } = false;
|
||||
private List<TimbMeseExplModel>? ListRecords { get; set; } = null;
|
||||
private int numRecord { get; set; } = 10;
|
||||
private int totalCount { get; set; } = 0;
|
||||
private DtUtils.Periodo CurrPeriodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisMonth);
|
||||
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
|
||||
private List<TimbMeseExplModel>? SearchRecords { get; set; } = null;
|
||||
|
||||
private string gridKey = "TimbMan";
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
private string mainDivCss
|
||||
{
|
||||
get => SelRecord == null ? "col-12" : "col-12 col-lg-9";
|
||||
}
|
||||
private string detDivCss
|
||||
{
|
||||
get => SelRecord == null ? "col-0" : "col-12 col-lg-3";
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
var rawList = await GDataServ.DipendentiGetAll();
|
||||
|
||||
#if true
|
||||
|
||||
if (ShowInatt)
|
||||
{
|
||||
ListDipendenti = rawList;
|
||||
}
|
||||
else
|
||||
{
|
||||
ListDipendenti = rawList.Where(x => (x.Attivo ?? false)).ToList();
|
||||
}
|
||||
try
|
||||
{
|
||||
SearchRecords = await GDataServ.TimbMeseExplList(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
|
||||
// verifico filtro per IdxDip
|
||||
if (IdxDipSel > 0)
|
||||
{
|
||||
SearchRecords = SearchRecords.Where(x => x.IdxDipendente == IdxDipSel).ToList();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
|
||||
}
|
||||
totalCount = SearchRecords.Count;
|
||||
SortTable();
|
||||
#endif
|
||||
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
private void SortTable()
|
||||
{
|
||||
if (SearchRecords != null)
|
||||
{
|
||||
// se ho ordinamento riordino...
|
||||
if (!string.IsNullOrEmpty(sortField))
|
||||
{
|
||||
switch (sortField)
|
||||
{
|
||||
case "Anno":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Anno).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Anno).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Mese":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.Mese).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.Mese).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "IdxDipendente":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.IdxDipendente).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.IdxDipendente).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOreOrd":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOreOrd).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOreOrd).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totLav":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totLav).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totLav).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOreNonLav":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOreNonLav).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOreNonLav).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOrePerm":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOrePerm).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOrePerm).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOreFer":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOreFer).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOreFer).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOreFest":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOreFest).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOreFest).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
case "totOreStra":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.totOreStra).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.totOreStra).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filtro x display
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<TimbMeseExplModel>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
|
||||
{
|
||||
CurrPeriodo = newPeiodo;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="card-body text-center">
|
||||
<div class="img-fluid" id="qrCodeImg_@idxDipendente"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
public partial class UserQrCode
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public bool LinkInt { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool LinkCore { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public DipendentiModel? RecordDip { get; set; } = null;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected string rawCode = "";
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected int idxDipendente
|
||||
{
|
||||
get => RecordDip != null ? RecordDip.IdxDipendente : 0;
|
||||
}
|
||||
|
||||
|
||||
protected string getUrlCode(string baseUrl, string authKey)
|
||||
{
|
||||
return $"{baseUrl}jumper?idxDipendente={RecordDip.IdxDipendente}&authKey={authKey}";
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (RecordDip != null)
|
||||
{
|
||||
string baseUrl = LinkInt ? UrlLinkInt : UrlLinkExt;
|
||||
// aggiungo parte core/legacy
|
||||
baseUrl += LinkCore ? UrlLinkCore : UrlLinkLega;
|
||||
//calcolo authKey valida x url --> escaped!
|
||||
string authKeyFix = System.Web.HttpUtility.UrlEncode(RecordDip.AuthKey);
|
||||
string newCode = getUrlCode(baseUrl, authKeyFix);
|
||||
if (rawCode != newCode)
|
||||
{
|
||||
rawCode = newCode;
|
||||
await JSRuntime.InvokeVoidAsync("clearContent", $"qrCodeImg_{RecordDip.IdxDipendente}");
|
||||
await JSRuntime.InvokeVoidAsync("displayQr", $"qrCodeImg_{RecordDip.IdxDipendente}", rawCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
initConf();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private string UrlLinkExt = "";
|
||||
|
||||
private string UrlLinkInt = "";
|
||||
|
||||
private string UrlLinkCore = "";
|
||||
|
||||
private string UrlLinkLega = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _idxDip { get; set; } = 0;
|
||||
|
||||
[Inject]
|
||||
private IConfiguration Configuration { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// init valori da config
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private void initConf()
|
||||
{
|
||||
UrlLinkInt = Configuration.GetValue<string>("OptPar:UrlLinkInt") ?? "";
|
||||
UrlLinkExt = Configuration.GetValue<string>("OptPar:UrlLinkExt") ?? "";
|
||||
UrlLinkCore = Configuration.GetValue<string>("OptPar:UrlLinkCore") ?? "";
|
||||
UrlLinkLega = Configuration.GetValue<string>("OptPar:UrlLinkLega") ?? "";
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -83,9 +83,9 @@ namespace GPW.CORE.ADM.Components.Layout
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
protected string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private string? TextCss => onlyIcon ? "d-none" : "";
|
||||
protected string? TextCss => onlyIcon ? "d-none" : "";
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
@page "/Dipendenti"
|
||||
@inject MessageService AppMServ
|
||||
@inject AppAuthService AuthServ
|
||||
|
||||
<WIP></WIP>
|
||||
<DipendentiMan></DipendentiMan>
|
||||
|
||||
@code {
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
AppMServ.ShowSearch = true;
|
||||
AppMServ.PageName = AuthServ.Traduci("ManDipendenti", AppMServ.UserLang);
|
||||
AppMServ.PageIcon = AuthServ.Traduci("ManDipendentiExpl");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,17 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
[Inject]
|
||||
protected MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected GpwDataService GDataServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected NavigationManager NavManager { get; set; } = null!;
|
||||
protected LicenseService LicServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected AppAuthService AuthService { get; set; } = null!;
|
||||
protected NavigationManager NavManager { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
@@ -35,6 +39,8 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
await Task.Delay(10);
|
||||
await AuthService.FlushRedisCache();
|
||||
await Task.Delay(10);
|
||||
LicServ.ResetLicenseData();
|
||||
await Task.Delay(10);
|
||||
|
||||
AppMServ.clonedRA = null;
|
||||
AppMServ.recordRA = null;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
protected int anno = DateTime.Today.Year;
|
||||
|
||||
protected DateTime dtMax = DateTime.Today.AddYears(1);
|
||||
protected DateTime dtMax = DateTime.Today.AddMonths(1);
|
||||
|
||||
protected DateTime dtMin = DateTime.Today;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
await Task.Delay(5);
|
||||
}
|
||||
isLoading = false;
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
protected async Task AddFerie()
|
||||
@@ -93,13 +93,13 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
await Task.Delay(5);
|
||||
}
|
||||
isLoading = false;
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// recupero mesi da gestire
|
||||
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
|
||||
var monthConf = await DataService.ConfigGetKeyAsync("NumMesiCalAzienda");
|
||||
if (monthConf != null)
|
||||
{
|
||||
int intVal = 0;
|
||||
@@ -107,10 +107,10 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
numMesi = intVal > 0 ? intVal : numMesi;
|
||||
}
|
||||
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
|
||||
DateTime oggi = DateTime.Today;
|
||||
dtMin = new DateTime(oggi.Year - 1, 1, 1);
|
||||
dtMax = dtMin.AddYears(3);
|
||||
await ReloadData();
|
||||
dtRif = DateTime.Today;
|
||||
dtMin = new DateTime(dtRif.Year, 1, 1);
|
||||
dtMax = dtMin.AddYears(1);
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
@@ -118,6 +118,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
#region Private Fields
|
||||
|
||||
private string DescrFerie = "CHIUSURA UFFICIO";
|
||||
private DateTime dtRif = DateTime.Today;
|
||||
private bool isLoading = false;
|
||||
private bool ShowAddFer = false;
|
||||
private bool ShowAddFes = false;
|
||||
@@ -126,11 +127,8 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
|
||||
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
|
||||
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
|
||||
private DateTime DtInizio { get; set; } = DateTime.Today;
|
||||
private DateTime DtFine { get; set; } = DateTime.Today;
|
||||
private DateTime DtInizio { get; set; } = DateTime.Today;
|
||||
|
||||
/// <summary>
|
||||
/// Elenco eventi formato originale (EventDTO)
|
||||
@@ -153,44 +151,38 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task ForceReloadCal()
|
||||
private void ForceReloadCal()
|
||||
{
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
private void ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
// recupero direttamente da oggetto DB
|
||||
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
SchedEvList = DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SetDate(DateTime newDate)
|
||||
private void SetDate(DateTime newDate)
|
||||
{
|
||||
// se la data fosse esterna all'intervallo considerato...)
|
||||
if (newDate < dtMin || newDate > dtMax)
|
||||
{
|
||||
// verifico se "allargare" alla minima o alla massima
|
||||
if (newDate < dtMin)
|
||||
{
|
||||
dtMin = new DateTime(newDate.Year - 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dtMax = new DateTime(newDate.Year + 1, 1, 1);
|
||||
}
|
||||
await ReloadData();
|
||||
dtRif = newDate;
|
||||
dtMin = new DateTime(newDate.Year, 1, 1);
|
||||
dtMax = new DateTime(newDate.Year + 1, 1, 1);
|
||||
ReloadData();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetMonth(int newNum)
|
||||
private void SetMonth(int newNum)
|
||||
{
|
||||
if (numMesi != newNum)
|
||||
{
|
||||
numMesi = newNum;
|
||||
}
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
private void TglAddFer()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<div class="row">
|
||||
<div class="row px-0 mx-0">
|
||||
<div class="col-12 col-lg-10 col-xl-8 offset-lg-1 offset-xl-2">
|
||||
<div class="mt-2 p-4 bg-secondary bg-gradient bg-opacity-25 border border-light rounded shadow">
|
||||
<div class="row">
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m1-4 py-4">
|
||||
<div class="mt-5">
|
||||
@if (ListMenu == null || ListMenu.Count == 0)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
protected int anno = DateTime.Today.Year;
|
||||
|
||||
protected DateTime dtMax = DateTime.Today.AddYears(1);
|
||||
protected DateTime dtMax = DateTime.Today.AddMonths(1);
|
||||
|
||||
protected DateTime dtMin = DateTime.Today;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// recupero mesi da gestire
|
||||
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
|
||||
var monthConf = await DataService.ConfigGetKeyAsync("NumMesiCalAzienda");
|
||||
if (monthConf != null)
|
||||
{
|
||||
int intVal = 0;
|
||||
@@ -48,28 +48,23 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
numMesi = intVal > 0 ? intVal : numMesi;
|
||||
}
|
||||
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
|
||||
DateTime oggi = DateTime.Today;
|
||||
dtMin = new DateTime(oggi.Year - 1, 1, 1);
|
||||
dtMax = dtMin.AddYears(3);
|
||||
await ReloadData();
|
||||
dtRif = DateTime.Today;
|
||||
dtMin = new DateTime(dtRif.Year, 1, 1);
|
||||
dtMax = dtMin.AddYears(1);
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private DateTime dtRif = DateTime.Today;
|
||||
private bool isLoading = false;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
|
||||
|
||||
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
|
||||
|
||||
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco eventi formato originale (EventDTO)
|
||||
/// </summary>
|
||||
@@ -79,44 +74,38 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task ForceReloadCal()
|
||||
private void ForceReloadCal()
|
||||
{
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
private void ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
// recupero direttamente da oggetto DB
|
||||
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
SchedEvList = DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SetDate(DateTime newDate)
|
||||
private void SetDate(DateTime newDate)
|
||||
{
|
||||
// se la data fosse esterna all'intervallo considerato...)
|
||||
if (newDate < dtMin || newDate > dtMax)
|
||||
{
|
||||
// verifico se "allargare" alla minima o alla massima
|
||||
if (newDate < dtMin)
|
||||
{
|
||||
dtMin = new DateTime(newDate.Year - 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dtMax = new DateTime(newDate.Year + 1, 1, 1);
|
||||
}
|
||||
await ReloadData();
|
||||
dtRif = newDate;
|
||||
dtMin = new DateTime(newDate.Year, 1, 1);
|
||||
dtMax = new DateTime(newDate.Year + 1, 1, 1);
|
||||
ReloadData();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetMonth(int newNum)
|
||||
private void SetMonth(int newNum)
|
||||
{
|
||||
if (numMesi != newNum)
|
||||
{
|
||||
numMesi = newNum;
|
||||
}
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
@page "/ReportProgetti"
|
||||
@inject MessageService AppMServ
|
||||
@inject AppAuthService AuthServ
|
||||
|
||||
<WIP></WIP>
|
||||
<ReportProgettiMan></ReportProgettiMan>
|
||||
|
||||
@code {
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// imposto pagina e info testata
|
||||
AppMServ.ShowSearch = true;
|
||||
AppMServ.PageName = AuthServ.Traduci("ReportPrj", AppMServ.UserLang);
|
||||
AppMServ.PageIcon = AuthServ.Traduci("ReportPrjExpl");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,14 @@
|
||||
}
|
||||
</div>
|
||||
<div class="col-8 ps-0">
|
||||
<CalendarioAziendale EvDtoList="@SchedEvList" MonthDispl="@numMesi" firstDate="@dtMin" minDate="@dtMin" maxDate="@dtMax" MonthReq="SetMonth" DtReq="SetDate" ShowNeedConf="@OnlyNeedConf"></CalendarioAziendale>
|
||||
@if (isLoading)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else
|
||||
{
|
||||
<CalendarioAziendale EvDtoList="@SchedEvList" MonthDispl="@numMesi" firstDate="@dtMin" minDate="@dtMin" maxDate="@dtMax" MonthReq="SetMonth" DtReq="SetDate" ShowNeedConf="@OnlyNeedConf"></CalendarioAziendale>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
protected int anno = DateTime.Today.Year;
|
||||
|
||||
protected DateTime dtMax = DateTime.Today.AddYears(1);
|
||||
protected DateTime dtMax = DateTime.Today.AddMonths(1);
|
||||
|
||||
protected DateTime dtMin = DateTime.Today;
|
||||
|
||||
@@ -41,20 +41,21 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
{
|
||||
initToggler();
|
||||
// recupero mesi da gestire
|
||||
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
|
||||
var monthConf = await DataService.ConfigGetKeyAsync("NumMesiCalAzienda");
|
||||
if (monthConf != null)
|
||||
{
|
||||
int intVal = 0;
|
||||
int.TryParse(monthConf.valore, out intVal);
|
||||
numMesi = intVal > 0 ? intVal : numMesi;
|
||||
}
|
||||
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
|
||||
DateTime oggi = DateTime.Today;
|
||||
dtMin = new DateTime(oggi.Year - 1, 1, 1);
|
||||
dtMax = dtMin.AddYears(3);
|
||||
await ReloadData();
|
||||
dtRif = DateTime.Today;
|
||||
dtMin = new DateTime(dtRif.Year, 1, 1);
|
||||
dtMax = dtMin.AddYears(1);
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
private DateTime dtRif = DateTime.Today;
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
@@ -65,12 +66,6 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
|
||||
|
||||
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
|
||||
|
||||
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
|
||||
|
||||
private bool OnlyNeedConf { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
@@ -91,9 +86,9 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
private async Task ForceReloadCal()
|
||||
private void ForceReloadCal()
|
||||
{
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
private void initToggler()
|
||||
@@ -106,39 +101,34 @@ namespace GPW.CORE.ADM.Components.Pages
|
||||
};
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
private void ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
// recupero direttamente da oggetto DB
|
||||
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
SchedEvList = DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SetDate(DateTime newDate)
|
||||
private void SetDate(DateTime newDate)
|
||||
{
|
||||
// se la data fosse esterna all'intervallo considerato...)
|
||||
if (newDate < dtMin || newDate > dtMax)
|
||||
{
|
||||
// verifico se "allargare" alla minima o alla massima
|
||||
if (newDate < dtMin)
|
||||
{
|
||||
dtMin = new DateTime(newDate.Year - 1, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dtMax = new DateTime(newDate.Year + 1, 1, 1);
|
||||
}
|
||||
await ReloadData();
|
||||
dtRif = newDate;
|
||||
// ricalcolo periodo
|
||||
dtMin = new DateTime(dtRif.Year, 1, 1);
|
||||
dtMax = new DateTime(dtRif.Year + 1, 1, 1);
|
||||
ReloadData();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetMonth(int newNum)
|
||||
private void SetMonth(int newNum)
|
||||
{
|
||||
if (numMesi != newNum)
|
||||
{
|
||||
numMesi = newNum;
|
||||
}
|
||||
await ReloadData();
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
@page "/SpostaOre"
|
||||
@page "/SpostaOre"
|
||||
@inject MessageService AppMServ
|
||||
@inject AppAuthService AuthServ
|
||||
|
||||
<WIP></WIP>
|
||||
|
||||
@code {
|
||||
<SpostaOreMan></SpostaOreMan>
|
||||
|
||||
@code {
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// imposto pagina e info testata
|
||||
AppMServ.ShowSearch = true;
|
||||
AppMServ.PageName = AuthServ.Traduci("SpostaOre", AppMServ.UserLang);
|
||||
AppMServ.PageIcon = AuthServ.Traduci("SpostaOreExpl");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
@page "/TimbratureMensili"
|
||||
@inject MessageService AppMServ
|
||||
@inject AppAuthService AuthServ
|
||||
|
||||
<WIP></WIP>
|
||||
<TimbMensMan></TimbMensMan>
|
||||
|
||||
@code {
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// imposto pagina e info testata
|
||||
AppMServ.ShowSearch = false;
|
||||
AppMServ.PageName = AuthServ.Traduci("timbMensili", AppMServ.UserLang);
|
||||
AppMServ.PageIcon = AuthServ.Traduci("timbMensiliExpl");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<!-- Questa soluzione gestisce le funzionalità amministrative del sistema GPW, inclusa la gestione di dipendenti, progetti, fasi, calendari aziendali, timbrature, malattie e richieste dei dipendenti. -->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>4.1.2502.0418</Version>
|
||||
<Version>4.1.2605.0611</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -33,14 +33,13 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" Version="1.11.4" />
|
||||
<PackageReference Include="Blazored.FluentValidation" Version="2.2.0" />
|
||||
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2501.1716" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2501.1716" />
|
||||
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2511.312" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
|
||||
<PackageReference Include="NLog" Version="5.4.0" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.4.0" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="5.9.7" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.0" />
|
||||
<PackageReference Include="NLog" Version="6.1.1" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="7.0.8" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,7 +7,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAw3dMMgC4FUywyOTV2xvCRgAAAAACAAAAAAADZgAAwAAAABAAAADrbAogtj/xpZqylbgs9Hb3AAAAAASAAACgAAAAEAAAAFm1lcdH7oj+NFy4QgZ7q18YAAAAROPsyRR12dhPTKfMEQ5yNCAZJ5K7C4pvFAAAAEFBVTwItjyYP2BlOTsuK1g9myQ8</EncryptedPassword>
|
||||
<History>True|2025-02-04T17:54:56.3466849Z||;True|2024-10-04T10:17:22.7335334+02:00||;True|2024-09-13T19:29:52.0716814+02:00||;True|2024-09-13T18:38:16.4907845+02:00||;True|2024-09-13T09:22:22.8253732+02:00||;True|2024-09-12T16:07:39.0226825+02:00||;True|2024-09-12T10:58:30.2473031+02:00||;True|2024-09-12T10:03:37.9121520+02:00||;True|2024-09-11T19:18:09.6865317+02:00||;True|2024-09-11T17:21:29.6285775+02:00||;True|2024-09-11T17:06:36.9651346+02:00||;True|2024-09-10T17:58:48.6965236+02:00||;True|2024-09-10T15:56:39.2931971+02:00||;True|2024-09-10T12:27:20.6683309+02:00||;True|2024-09-07T10:37:21.9427027+02:00||;True|2024-09-06T19:01:32.2132061+02:00||;True|2024-09-06T18:20:28.3994458+02:00||;True|2024-09-05T10:43:51.3246848+02:00||;True|2024-09-05T10:26:17.6114175+02:00||;True|2024-09-05T09:25:03.5122942+02:00||;True|2024-09-04T18:21:49.9717603+02:00||;True|2023-04-11T10:12:15.0154900+02:00||;False|2023-04-11T10:11:47.1977827+02:00||;True|2023-04-11T09:18:55.4555319+02:00||;True|2023-04-11T09:16:05.8827677+02:00||;True|2022-06-06T12:56:03.5790550+02:00||;False|2022-06-06T12:54:19.4739620+02:00||;False|2022-06-06T12:53:46.4246554+02:00||;</History>
|
||||
<History>True|2025-06-10T05:22:28.6193301Z||;False|2025-06-10T07:20:26.1957391+02:00||;True|2025-02-04T18:54:56.3466849+01:00||;True|2024-10-04T10:17:22.7335334+02:00||;True|2024-09-13T19:29:52.0716814+02:00||;True|2024-09-13T18:38:16.4907845+02:00||;True|2024-09-13T09:22:22.8253732+02:00||;True|2024-09-12T16:07:39.0226825+02:00||;True|2024-09-12T10:58:30.2473031+02:00||;True|2024-09-12T10:03:37.9121520+02:00||;True|2024-09-11T19:18:09.6865317+02:00||;True|2024-09-11T17:21:29.6285775+02:00||;True|2024-09-11T17:06:36.9651346+02:00||;True|2024-09-10T17:58:48.6965236+02:00||;True|2024-09-10T15:56:39.2931971+02:00||;True|2024-09-10T12:27:20.6683309+02:00||;True|2024-09-07T10:37:21.9427027+02:00||;True|2024-09-06T19:01:32.2132061+02:00||;True|2024-09-06T18:20:28.3994458+02:00||;True|2024-09-05T10:43:51.3246848+02:00||;True|2024-09-05T10:26:17.6114175+02:00||;True|2024-09-05T09:25:03.5122942+02:00||;True|2024-09-04T18:21:49.9717603+02:00||;True|2023-04-11T10:12:15.0154900+02:00||;False|2023-04-11T10:11:47.1977827+02:00||;True|2023-04-11T09:18:55.4555319+02:00||;True|2023-04-11T09:16:05.8827677+02:00||;True|2022-06-06T12:56:03.5790550+02:00||;False|2022-06-06T12:54:19.4739620+02:00||;False|2022-06-06T12:53:46.4246554+02:00||;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,37 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5145",
|
||||
"nativeDebugging": true,
|
||||
"sqlDebugging": true
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7000;http://localhost:5145",
|
||||
"nativeDebugging": true,
|
||||
"sqlDebugging": true
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"nativeDebugging": true,
|
||||
"sqlDebugging": true
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": true,
|
||||
@@ -7,32 +40,5 @@
|
||||
"applicationUrl": "http://localhost:18461",
|
||||
"sslPort": 44382
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5145",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7000;http://localhost:5145",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# GPW.CORE.ADM
|
||||
|
||||
Modulo amministrativo e di gestione master della suite GPW, deputato alla manutenzione delle anagrafiche, alla configurazione dei parametri aziendali e alla risoluzione di anomalie nei dati operativi.
|
||||
|
||||
## Descrizione Generale
|
||||
`GPW.CORE.ADM` è lo strumento di controllo per il personale amministrativo e i responsabili HR. Mentre il modulo `Smart8` è orientato all'utente finale per l'imputazione dei dati, `ADM` è progettato per la gestione della struttura organizzativa (progetti, gruppi, dipendenti) e per la correzione di errori o incongruenze che emergono durante l'attività quotidiana.
|
||||
|
||||
Il modulo combina funzioni di **Master Data Management (MDM)** con strumenti di **Data Cleaning** e **Audit**, garantendo che la base dati sia coerente e pronta per la reportistica.
|
||||
|
||||
## Funzionalità Principali
|
||||
|
||||
### 1. Gestione Anagrafica (Master Data Management)
|
||||
Il modulo permette il controllo completo del catalogo dati utilizzato in tutta la suite:
|
||||
- **Dipendenti**: Gestione del database personale, controllo delle licenze software attive/disponibili e gestione delle autorizzazioni (es. reset chiavi di autenticazione).
|
||||
- **Struttura Organizzativa**: Gestione dei **Gruppi** di lavoro e della gerarchia dei **Progetti** (inclusa la gestione delle **Fasi** di progetto).
|
||||
- **Clienti e Orari**: Gestione del catalogo clienti e configurazione degli orari aziendali.
|
||||
- **Giustificazioni**: Definizione dei codici giustificativi (es. FER, PERM, 104) utilizzati per le assenze.
|
||||
|
||||
### 2. Strumenti di Manutenzione e Correzione (Data Cleaning)
|
||||
Per correggere errori di inserimento o riconfigurare la struttura, il modulo offre strumenti avanzati:
|
||||
- **Spostamento Gerarchico**: Strumenti per spostare fasi di progetto tra diversi progetti o per riorganizzare la gerarchia delle sub-fasi (`SpostaFasiMan`).
|
||||
- **Correzione Imputazioni**: Possibilità di spostare masse di ore/attività da una struttura (Cliente/Progetto/Fase) a un'altra per rimediare a errori di selezione durante la timbratura (`SpostaOreMan`).
|
||||
- **Ricalcolo Anomalie**: Capacità di eseguire ricalcoli massivi per sincronizzare le timbrature con le attività e generare automaticamente giustificativi di copertura in caso di buchi di presenza (`ReviewTimbMan`).
|
||||
|
||||
### 3. Audit e Supervisione
|
||||
- **Review Timbrature**: Monitoraggio delle anomalie (es. timbrature mancanti, incongruenze temporali) con possibilità di intervento diretto su timbrature e giustificativi.
|
||||
- **Monitoraggio Licenze**: Controllo in tempo reale del numero di licenze attive e disponibili per garantire la continuità del servizio.
|
||||
|
||||
## Architettura Tecnica
|
||||
- **Framework**: Sviluppato in **Blazor** (Server/WASM) con .NET 8.0.
|
||||
- **Data Access**: Utilizza `GpwDataService` per tutte le operazioni CRUD e per le procedure di ricalcolo complesso lato server.
|
||||
- **Comunicazione**: Integrazione con `UIMessageService` per la sincronizzazione degli stati tra i vari componenti dell'interfaccia.
|
||||
- **Export**: Supporto per l'esportazione di dati in formati standard (CSV, TXT) ottimizzati per integrazioni con software terzi (es. Zucchetti).
|
||||
|
||||
## Note per l'Uso
|
||||
- **Autorizzazioni**: Molte funzioni (es. eliminazione record, ricalcoli massivi, gestione licenze) sono protette da controlli di ruolo tramite `AppAuthService`.
|
||||
- **Sicurezza**: Le operazioni critiche (eliminazione, spostamento masse) richiedono sempre una conferma esplicita tramite interfaccia JavaScript.
|
||||
@@ -4,5 +4,6 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DetailedErrors": true
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"DetailedErrors": true,
|
||||
"NLog": {
|
||||
"variables": {
|
||||
"baseFileDir": "${basedir}/logs/",
|
||||
@@ -51,7 +52,7 @@
|
||||
"ConnectionStrings": {
|
||||
"GPW.DB": "Server=W2019-SQL-STEAM;Database=GPW; User ID=UserGPW; Password=Us3rGpw!75x93$77; integrated security=False; MultipleActiveResultSets=True; App=GPW.CORE.WRKLOG; TrustServerCertificate=True;",
|
||||
"GPW.DB.Auth": "Server=W2019-SQL-STEAM;Database=SteamWare_Anagrafica;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=GPW.ADM; TrustServerCertificate=True;",
|
||||
"Redis": "localhost:26379,serviceName=prod,DefaultDatabase=15,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG"
|
||||
"Redis": "redis.ufficio:26379,serviceName=prod,DefaultDatabase=15,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG"
|
||||
},
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
@@ -59,7 +60,7 @@
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "587",
|
||||
"Account": "services@steamware.net",
|
||||
"Password": "vpsad24068!",
|
||||
"Password": "ruejpcwgycvbmmsr",
|
||||
"SenderEmail": "services@steamware.net",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
@@ -73,10 +74,17 @@
|
||||
"ServerConf": {
|
||||
"AdmList": "1,6",
|
||||
"BaseUrl": "/GPW/CORE.ADM",
|
||||
"BasePathExport": "c:\\\\temp\\GPW_ADM_Export"
|
||||
"BasePathExport": "c:\\\\temp\\GPW_ADM_Export",
|
||||
"ReportBaseUrl": "http://w2019-sql-steam/ReportServer/Pages/ReportViewer.aspx?/Steamware/"
|
||||
},
|
||||
"AdmApp": {
|
||||
"LinkMal": "https://office.egalware.com/GPW/CORE.ADM/malattia",
|
||||
"LinkRich": "https://office.egalware.com/GPW/CORE.ADM/richiesteDip"
|
||||
},
|
||||
"OptPar": {
|
||||
"UrlLinkInt": "https://office.egalware.com/GPW/",
|
||||
"UrlLinkExt": "https://seriate.egalware.com/GPW/",
|
||||
"UrlLinkCore": "CORE.SMART/",
|
||||
"UrlLinkLega": "SMART/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,9 +220,6 @@ a,
|
||||
.shortcuts {
|
||||
text-align: center;
|
||||
}
|
||||
.shortcuts .shortcut-icon {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.shortcuts .shortcut {
|
||||
min-width: 10rem;
|
||||
min-height: 5rem;
|
||||
@@ -329,4 +326,109 @@ a,
|
||||
font-size: 0.9em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
/* gestione btn report */
|
||||
.reportPivot {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/PivotData.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.reportOre {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportGerarchico.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.reportFolders {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportFolders.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.reportBadge {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/Barcode.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
/* Text position */
|
||||
.areaTesto {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 50%;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
min-height: 25%;
|
||||
line-height: 1.5;
|
||||
color: White;
|
||||
background: #333;
|
||||
background: rgba(50, 50, 50, 0.9);
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
/* versioni small */
|
||||
.areaTestoSmall {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 50%;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0 3px;
|
||||
min-height: 50%;
|
||||
line-height: 1.5;
|
||||
font-size: 7pt;
|
||||
color: White;
|
||||
background: #999;
|
||||
background: rgba(160, 160, 160, 0.9);
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
.reportFoldersSmall {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportGerarchico.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
background-size: 60px 60px;
|
||||
min-height: 36px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
@@ -202,10 +202,6 @@ a, .btn-link {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.shortcuts .shortcut-icon {
|
||||
font-size: 2*@blSCut;
|
||||
}
|
||||
|
||||
.shortcuts .shortcut {
|
||||
min-width: @blSCut * 10;
|
||||
min-height: @blSCut * 5;
|
||||
@@ -328,3 +324,116 @@ a, .btn-link {
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* gestione btn report */
|
||||
.reportPivot {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/PivotData.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.reportOre {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportGerarchico.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.reportFolders {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportFolders.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.reportBadge {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/Barcode.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top;
|
||||
background-position: left;
|
||||
min-height: 250px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Text position */
|
||||
.areaTesto {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 50%;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
min-height: 25%;
|
||||
line-height: 1.5;
|
||||
color: White;
|
||||
background: #333;
|
||||
background: rgba(50,50,50,.9);
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
|
||||
/* versioni small */
|
||||
.areaTestoSmall {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 50%;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
padding: 0 3px;
|
||||
min-height: 50%;
|
||||
line-height: 1.5;
|
||||
font-size: 7pt;
|
||||
color: White;
|
||||
background: #999;
|
||||
background: rgba(160,160,160,.9);
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
|
||||
.reportFoldersSmall {
|
||||
background: #EFEFEF;
|
||||
background-image: url(../images/ReportGerarchico.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
background-size: 60px 60px;
|
||||
min-height: 36px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,25 @@
|
||||
function clearContent(elementID) {
|
||||
//console.log("Remove " + elementID);
|
||||
document.getElementById(elementID).innerHTML = "";
|
||||
}
|
||||
// gestione qrcode... da https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-enable-qrcodes?view=aspnetcore-5.0
|
||||
//var qrcode = new QRCode("qrCodeImg");
|
||||
function displayQr(elementName, rawData) {
|
||||
//console.log("Add " + elementName);
|
||||
try {
|
||||
if (elementName != "" && rawData != "") {
|
||||
qrcode = new QRCode(document.getElementById(elementName),
|
||||
{
|
||||
text: rawData,
|
||||
width: 240,
|
||||
height: 240,
|
||||
correctLevel: QRCode.CorrectLevel.L
|
||||
//correctLevel: QRCode.CorrectLevel.M
|
||||
//correctLevel: QRCode.CorrectLevel.Q
|
||||
//correctLevel: QRCode.CorrectLevel.H
|
||||
});
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "9.0.7",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,13 +580,44 @@ namespace GPW.CORE.Api.Data
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue flush memoria redis dato pattern
|
||||
/// Esegue flush memoria redis dato pat2Flush
|
||||
/// </summary>
|
||||
/// <param name="pattern"></param>
|
||||
/// <param name="pat2Flush"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
|
||||
private async Task<bool> ExecFlushRedisPattern(RedisValue pat2Flush)
|
||||
{
|
||||
bool answ = false;
|
||||
var masterEndpoint = redisConn.GetEndPoints()
|
||||
.Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica)
|
||||
.FirstOrDefault();
|
||||
|
||||
// sepattern è "*" elimino intero DB...
|
||||
if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null))
|
||||
{
|
||||
redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database);
|
||||
}
|
||||
else
|
||||
{
|
||||
var server = redisConn.GetServer(masterEndpoint);
|
||||
var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000);
|
||||
|
||||
var deleteTasks = new List<Task>();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
deleteTasks.Add(redisDb.KeyDeleteAsync(key));
|
||||
if (deleteTasks.Count >= 1000)
|
||||
{
|
||||
await Task.WhenAll(deleteTasks);
|
||||
deleteTasks.Clear();
|
||||
}
|
||||
}
|
||||
if (deleteTasks.Count > 0)
|
||||
{
|
||||
await Task.WhenAll(deleteTasks);
|
||||
}
|
||||
}
|
||||
answ = true;
|
||||
#if false
|
||||
var listEndpoints = redisConn.GetEndPoints();
|
||||
foreach (var endPoint in listEndpoints)
|
||||
{
|
||||
@@ -601,7 +632,8 @@ namespace GPW.CORE.Api.Data
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.4.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.37" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
|
||||
|
||||
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>True</_SavePWD>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>True</_SavePWD>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>True</_SavePWD>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>True</_SavePWD>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -51,7 +51,7 @@
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"GPW.DB": "Server=W2019-SQL-STEAM; Database=GPW; User ID=UserGPW; Password=Us3rGpw!75x93$77; integrated security=False; MultipleActiveResultSets=True;App=LiMan.API; TrustServerCertificate=True;",
|
||||
"Redis": "localhost:26379,serviceName=prod,DefaultDatabase=15,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG"
|
||||
"Redis": "redis.ufficio:26379,serviceName=prod,DefaultDatabase=15,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,password=BtN9Py1wtLfLRvmzWnOPJ7RytDM+CLiVsJ/16zduNTlV8IOPGNrtzJSXPUnImA5PqmUMhKaUqo9NdHIG"
|
||||
},
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
@@ -59,7 +59,7 @@
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "587",
|
||||
"Account": "services@steamware.net",
|
||||
"Password": "vpsad24068",
|
||||
"Password": "ruejpcwgycvbmmsr",
|
||||
"SenderEmail": "services@steamware.net",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
<!-- Questa soluzione contiene componenti UI personalizzati per applicazioni Blazor, come ad esempio grafici circolari (CircleGauge). -->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System.Data;
|
||||
|
||||
namespace GPW.CORE.Data.Controllers
|
||||
{
|
||||
@@ -43,7 +44,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in AnagClientiAll:{Environment.NewLine}{exc}");
|
||||
Log.Error($"Errore in AnagClientiAllAsync:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
@@ -1054,7 +1055,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in AnagProjByCli:{Environment.NewLine}{exc}");
|
||||
Log.Error($"Errore in AnagProjByCliAsync:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
@@ -1337,7 +1338,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in AnagTagFasiAll:{Environment.NewLine}{exc}");
|
||||
Log.Error($"Errore in AnagTagFasiAllAsync:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
@@ -2030,11 +2031,61 @@ namespace GPW.CORE.Data.Controllers
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ricalcola Tag Mensili dato dipendente, periodo, tag
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente">IdxDipendente</param>
|
||||
/// <param name="attivo">Stato attivo richiesto</param>
|
||||
/// <returns></returns>
|
||||
public bool DipUpdateActive(int idxDipendente, bool attivo)
|
||||
{
|
||||
// init dati necessari
|
||||
bool fatto = false;
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pAttivo = new SqlParameter("@attivo", attivo);
|
||||
var pIdxDip = new SqlParameter("@Original_idxDipendente", idxDipendente);
|
||||
|
||||
var dbResult = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC dbo.stp_AD_updateActive @attivo, @Original_idxDipendente", pAttivo, pIdxDip);
|
||||
fatto = dbResult > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in DipUpdateActive:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Log.Info("Dispose di GPWController");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera Elenco Report x mostrare link
|
||||
/// </summary>
|
||||
/// <param name="Area">Se vuoto = tutti</param>
|
||||
/// <returns></returns>
|
||||
public List<ElencoReportModel> ElencoReportFilt(string Area)
|
||||
{
|
||||
List<ElencoReportModel> dbResult = new List<ElencoReportModel>();
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
DateTime oggi = DateTime.Today;
|
||||
dbResult = dbCtx
|
||||
.DbSetElencoReport
|
||||
.Where(x => string.IsNullOrEmpty(Area) || x.Area == Area)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue recupero dati in formato ExportCommessa
|
||||
/// </summary>
|
||||
@@ -2047,7 +2098,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
List<ExpCommessaModel> dbResult = new List<ExpCommessaModel>();
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
SqlParameter pIdxDip = new SqlParameter("@idxDipendente", idxDipendente);
|
||||
SqlParameter pIdxDip = new SqlParameter("@idxRA", idxDipendente);
|
||||
SqlParameter pInizio = new SqlParameter("@dataFrom", dtInizio);
|
||||
SqlParameter pFine = new SqlParameter("@dataTo", dtFine);
|
||||
|
||||
@@ -2055,7 +2106,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetExpCommessa
|
||||
.FromSqlRaw("EXEC stp_RA_pivot_getByIdxDipData @idxDipendente, @dataFrom, @dataTo", pIdxDip, pInizio, pFine)
|
||||
.FromSqlRaw("EXEC stp_RA_pivot_getByIdxDipData @idxRA, @dataFrom, @dataTo", pIdxDip, pInizio, pFine)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -2457,6 +2508,137 @@ namespace GPW.CORE.Data.Controllers
|
||||
return done;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dettaglio tag da stored dedicata
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente"></param>
|
||||
/// <param name="dataFrom"></param>
|
||||
/// <param name="dataTo"></param>
|
||||
/// <returns></returns>
|
||||
public List<ListTagDDModel> ListTagDD(int idxDipendente, DateTime dataFrom, DateTime dataTo)
|
||||
{
|
||||
// init dati necessari
|
||||
List<ListTagDDModel> dbResult = new List<ListTagDDModel>();
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pidxDipendente = new SqlParameter("@idxRA", idxDipendente);
|
||||
var pdataFrom = new SqlParameter("@dataFrom", dataFrom);
|
||||
var pdataTo = new SqlParameter("@dataTo", dataTo);
|
||||
|
||||
dbResult = dbCtx
|
||||
.DbSetListTagDD
|
||||
.FromSqlRaw("EXEC dbo.stp_LTDD_ByUserDate @idxRA, @dataFrom, @dataTo", pidxDipendente, pdataFrom, pdataTo)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in ListTagDD:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle attiazione record da stored dedicata
|
||||
/// </summary>
|
||||
/// <param name="idxTagDD"></param>
|
||||
/// <returns></returns>
|
||||
public bool ListTagDDToggle(int idxTagDD)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pIdxTagDD = new SqlParameter("@IdxTagDD", idxTagDD);
|
||||
|
||||
var dbResult = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC dbo.stp_LTDD_toggleActive @IdxTagDD", pIdxTagDD);
|
||||
answ = dbResult > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in ListTagDDToggle:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati month tag da stored dedicata
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente"></param>
|
||||
/// <param name="dataFrom"></param>
|
||||
/// <param name="dataTo"></param>
|
||||
/// <returns></returns>
|
||||
public List<MonthTagModel> MonthTagList(int idxDipendente, DateTime dataFrom, DateTime dataTo)
|
||||
{
|
||||
// init dati necessari
|
||||
List<MonthTagModel> dbResult = new List<MonthTagModel>();
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pidxDipendente = new SqlParameter("@idxDipendente", idxDipendente);
|
||||
var pdataFrom = new SqlParameter("@dataFrom", dataFrom);
|
||||
var pdataTo = new SqlParameter("@dataTo", dataTo);
|
||||
|
||||
dbResult = dbCtx
|
||||
.DbSetMonthTag
|
||||
.FromSqlRaw("EXEC dbo.stp_LTM_ByUserDate @idxDipendente, @dataFrom, @dataTo", pidxDipendente, pdataFrom, pdataTo)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in MonthTagList:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ricalcola Tag Mensili dato dipendente, periodo, tag
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente">IdxDipendente</param>
|
||||
/// <param name="dataFrom">Inizio periodo ricalcolo</param>
|
||||
/// <param name="dataTo">Fine periodo ricalcolo</param>
|
||||
/// <param name="codTag">Cod TAG da ricalcolare</param>
|
||||
/// <param name="minParam">Valore minimo parametri</param>
|
||||
/// <returns></returns>
|
||||
public bool MonthTagRecalc(int idxDipendente, DateTime dataFrom, DateTime dataTo, string codTag, int minParam)
|
||||
{
|
||||
// init dati necessari
|
||||
bool fatto = false;
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pCodTag = new SqlParameter("@CodTag", codTag);
|
||||
var pIdxDipendente = new SqlParameter("@idxDipendente", idxDipendente);
|
||||
var pDataFrom = new SqlParameter("@DtStart", dataFrom);
|
||||
var pDataTo = new SqlParameter("@DtEnd", dataTo);
|
||||
var pMinParam = new SqlParameter("@minParam", minParam);
|
||||
|
||||
var dbResult = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC dbo.stp_LTDD_checkCreateByDipDate @CodTag, @idxDipendente, @DtStart, @DtEnd, @minParam", pCodTag, pIdxDipendente, pDataFrom, pDataTo, pMinParam);
|
||||
fatto = dbResult > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in MonthTagRecalc:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco pareto progetti ordinati da filtro
|
||||
/// </summary>
|
||||
@@ -2503,6 +2685,47 @@ namespace GPW.CORE.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati delle attività filtrate x spostamento ore tra progetti
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente"></param>
|
||||
/// <param name="dataFrom"></param>
|
||||
/// <param name="dataTo"></param>
|
||||
/// <param name="idxCliente"></param>
|
||||
/// <param name="idxProgetto"></param>
|
||||
/// <param name="idxFase"></param>
|
||||
/// <param name="isAncest"></param>
|
||||
/// <returns></returns>
|
||||
public List<RegAttivitaDayExplModel> RegAttDayExplList(int idxDipendente, DateTime dataFrom, DateTime dataTo, int idxCliente, int idxProgetto, int idxFase, bool isAncest)
|
||||
{
|
||||
// init dati necessari
|
||||
List<RegAttivitaDayExplModel> dbResult = new List<RegAttivitaDayExplModel>();
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pIdxDipendente = new SqlParameter("@idxRA", idxDipendente);
|
||||
var pInizio = new SqlParameter("@dataFrom", dataFrom);
|
||||
var pFine = new SqlParameter("@dataTo", dataTo);
|
||||
var pIdxCliente = new SqlParameter("@idxCliente", idxCliente);
|
||||
var pIdxProgetto = new SqlParameter("@idxProgetto", idxProgetto);
|
||||
var pIdxFase = new SqlParameter("@idxFase", idxFase);
|
||||
var pIsAncest = new SqlParameter("@soloAncest", isAncest);
|
||||
|
||||
dbResult = dbCtx
|
||||
.DbSetDayRaExpl
|
||||
.FromSqlRaw("EXEC dbo.stp_RAD_Expl_getByIdxDipPeriodo @idxRA, @dataFrom, @dataTo, @idxCliente, @idxProgetto, @idxFase, @soloAncest", pIdxDipendente, pInizio, pFine, pIdxCliente, pIdxProgetto, pIdxFase, pIsAncest)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in RegAttDayExplList:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
public bool RegAttDelete(RegAttivitaModel currItem)
|
||||
{
|
||||
bool answ = false;
|
||||
@@ -2598,13 +2821,13 @@ namespace GPW.CORE.Data.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
var pIdxDip = new SqlParameter("@idxDipendente", IdxDip);
|
||||
var pIdxDip = new SqlParameter("@idxRA", IdxDip);
|
||||
var pDtStart = new SqlParameter("@inizio", DtStart);
|
||||
var pDtEnd = new SqlParameter("@fine", DtEnd);
|
||||
|
||||
result = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC stp_ricalcolaRegAttivitaExpl_byPeriodoUser @idxDipendente, @inizio, @fine", pIdxDip, pDtStart, pDtEnd);
|
||||
.ExecuteSqlRaw("EXEC stp_ricalcolaRegAttivitaExpl_byPeriodoUser @idxRA, @inizio, @fine", pIdxDip, pDtStart, pDtEnd);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -2668,6 +2891,37 @@ namespace GPW.CORE.Data.Controllers
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua spostamento di un record RA alla nuova fase indicata
|
||||
/// </summary>
|
||||
/// <param name="idxRA"></param>
|
||||
/// <param name="idxFase"></param>
|
||||
/// <returns></returns>
|
||||
public bool RegAttUpdateFase(int idxRA, int idxFase)
|
||||
{
|
||||
// init dati necessari
|
||||
bool answ = false;
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pIdxRA = new SqlParameter("@Original_idxRA", idxRA);
|
||||
var pIdxFase = new SqlParameter("@idxFase", idxFase);
|
||||
|
||||
var dbResult = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC dbo.stp_RA_updateFase @idxFase, @Original_idxRA", pIdxFase, pIdxRA);
|
||||
answ = dbResult > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in RegAttUpdateFase:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera eventi dato criteri filtro
|
||||
/// </summary>
|
||||
@@ -3198,7 +3452,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
List<TeRaExplModel> dbResult = new List<TeRaExplModel>();
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
SqlParameter pIdxDip = new SqlParameter("@idxDipendente", IdxDip);
|
||||
SqlParameter pIdxDip = new SqlParameter("@idxRA", IdxDip);
|
||||
SqlParameter pDataFrom = new SqlParameter("@dataFrom", DtFrom);
|
||||
SqlParameter pDataTo = new SqlParameter("@dataTo", DtTo);
|
||||
SqlParameter pInatt = new SqlParameter("@showInattivi", ShowIn);
|
||||
@@ -3208,7 +3462,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
|
||||
dbResult = dbCtx
|
||||
.DbSetTeRaExpl
|
||||
.FromSqlRaw("EXEC stp_TE_RA_ByUserDate @idxDipendente, @dataFrom, @dataTo, @showInattivi, @showWE, @maxErrMin, @maxErrPlus", pIdxDip, pDataFrom, pDataTo, pInatt, pShowWE, pMaxErrMin, pMaxErrPlus)
|
||||
.FromSqlRaw("EXEC stp_TE_RA_ByUserDate @idxRA, @dataFrom, @dataTo, @showInattivi, @showWE, @maxErrMin, @maxErrPlus", pIdxDip, pDataFrom, pDataTo, pInatt, pShowWE, pMaxErrMin, pMaxErrPlus)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
@@ -3283,13 +3537,13 @@ namespace GPW.CORE.Data.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
var pIdxDip = new SqlParameter("@idxDipendente", IdxDip);
|
||||
var pIdxDip = new SqlParameter("@idxRA", IdxDip);
|
||||
var pDtStart = new SqlParameter("@inizio", DtStart);
|
||||
var pDtEnd = new SqlParameter("@fine", DtEnd);
|
||||
|
||||
result = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC stp_ricalcolaTimbExpl_byPeriodoUser @idxDipendente, @inizio, @fine", pIdxDip, pDtStart, pDtEnd);
|
||||
.ExecuteSqlRaw("EXEC stp_ricalcolaTimbExpl_byPeriodoUser @idxRA, @inizio, @fine", pIdxDip, pDtStart, pDtEnd);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -3299,6 +3553,39 @@ namespace GPW.CORE.Data.Controllers
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati di sunto delle timbrature mensili x dipendente da stored dedicata
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente"></param>
|
||||
/// <param name="dataFrom"></param>
|
||||
/// <param name="dataTo"></param>
|
||||
/// <returns></returns>
|
||||
public List<TimbMeseExplModel> TimbMeseExplList(int idxDipendente, DateTime dataFrom, DateTime dataTo)
|
||||
{
|
||||
// init dati necessari
|
||||
List<TimbMeseExplModel> dbResult = new List<TimbMeseExplModel>();
|
||||
// cerco su DB recuperando set di dati....
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pidxDipendente = new SqlParameter("@idxRA", idxDipendente);
|
||||
var pInizio = new SqlParameter("@inizio", dataFrom);
|
||||
var pFine = new SqlParameter("@fine", dataTo);
|
||||
|
||||
dbResult = dbCtx
|
||||
.DbSetTimbMeseExpl
|
||||
.FromSqlRaw("EXEC dbo.stp_TimbMeseExpl @inizio, @fine, @idxRA", pInizio, pFine, pidxDipendente)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in TimbMeseExplList:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco timbrature successive alla data odierna x ogni dipendente (x recupero errori
|
||||
/// timbrature future)
|
||||
@@ -3350,6 +3637,33 @@ namespace GPW.CORE.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
public async Task<TimbratureModel?> TimbratureByUidAsync(string UID)
|
||||
{
|
||||
TimbratureModel? dbRec = null;
|
||||
using (GPWContext dbCtx = new GPWContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
// UID = $"{IdxDipendente:000}_{DataOra:yyyyMMdd}_{DataOra:HHmmss}"
|
||||
var parts = UID.Split('_');
|
||||
if (parts.Length == 3)
|
||||
{
|
||||
int idxDip = int.Parse(parts[0]);
|
||||
DateTime dataOra = DateTime.ParseExact(parts[1] + "_" + parts[2], "yyyyMMdd_HHmmss", null);
|
||||
|
||||
dbRec = await dbCtx
|
||||
.DbSetTimbrature
|
||||
.FirstOrDefaultAsync(x => x.IdxDipendente == idxDip && x.DataOra == dataOra);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in TimbratureByUidAsync: {Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbRec;
|
||||
}
|
||||
|
||||
public bool TimbratureDelete(TimbratureModel currItem)
|
||||
{
|
||||
bool answ = false;
|
||||
@@ -3453,7 +3767,6 @@ namespace GPW.CORE.Data.Controllers
|
||||
.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DataOra == currItem.DataOra);
|
||||
if (currRec != null)
|
||||
{
|
||||
|
||||
// se non si tratta di una timbratura "last second"...
|
||||
if (currItem.DataOra.Hour != 23 && currItem.DataOra.Minute != 59 && currItem.DataOra.Second != 59)
|
||||
{
|
||||
@@ -3493,6 +3806,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco delle ultime attività inserite da un dipendente
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GPW.CORE.Data.DTO
|
||||
{
|
||||
public class DatiReqResetDTO
|
||||
{
|
||||
public string Richiedente { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string Telefono { get; set; } = "";
|
||||
public string Causale { get; set; } = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GPW.CORE.Data.DTO
|
||||
{
|
||||
public class RegAttDayExpDTO : RegAttivitaDayExplModel
|
||||
{
|
||||
public RegAttDayExpDTO(RegAttivitaDayExplModel origRec)
|
||||
{
|
||||
this.CognomeNome=origRec.CognomeNome;
|
||||
this.Descrizione=origRec.Descrizione;
|
||||
this.Fine=origRec.Fine;
|
||||
this.Inizio = origRec.Inizio;
|
||||
this.RagSociale= origRec.RagSociale;
|
||||
this.Gruppo=origRec.Gruppo;
|
||||
this.NomeProj=origRec.NomeProj;
|
||||
this.IdxProgetto=origRec.IdxProgetto;
|
||||
this.IdxDipendente=origRec.IdxDipendente;
|
||||
this.IdxRA=origRec.IdxRA;
|
||||
this.IdxFase=origRec.IdxFase;
|
||||
this.Importo=origRec.Importo;
|
||||
this.MinTot=origRec.MinTot;
|
||||
this.NomeFase=origRec.NomeFase;
|
||||
this.OreTot=origRec.OreTot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper per selezione in tabella
|
||||
/// </summary>
|
||||
public bool Selected { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GPW.CORE.Data.DTO
|
||||
{
|
||||
public class TimbratureDTO : TimbratureModel
|
||||
{
|
||||
public TimbratureDTO(TimbratureModel origRec)
|
||||
{
|
||||
this.DataOra = origRec.DataOra;
|
||||
this.IdxDipendente = origRec.IdxDipendente;
|
||||
this.Entrata = origRec.Entrata;
|
||||
this.Ipv4 = origRec.Ipv4;
|
||||
this.CodTipoTimb = origRec.CodTipoTimb;
|
||||
this.Approv = origRec.Approv;
|
||||
this.DipNav = origRec.DipNav;
|
||||
this.CodTipoTimbNav=origRec.CodTipoTimbNav;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper per selezione in tabella
|
||||
/// </summary>
|
||||
public bool Selected { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,28 @@ namespace GPW.CORE.Data
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Calcolo Hash data stringa input
|
||||
/// </summary>
|
||||
/// <param name="rawData"></param>
|
||||
/// <returns></returns>
|
||||
public static string CalcHash(string rawData)
|
||||
{
|
||||
string hash = "";
|
||||
// hashing!
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
byte[] InputBytes = Encoding.UTF8.GetBytes(rawData);
|
||||
var byteHash = md5.ComputeHash(InputBytes);
|
||||
hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private DipendentiModel? rigaDip = null;
|
||||
@@ -55,6 +77,8 @@ namespace GPW.CORE.Data
|
||||
}
|
||||
if (!string.IsNullOrEmpty(buffData))
|
||||
{
|
||||
hash = CalcHash(buffData);
|
||||
#if false
|
||||
// hashing!
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
@@ -62,6 +86,7 @@ namespace GPW.CORE.Data
|
||||
var byteHash = md5.ComputeHash(InputBytes);
|
||||
hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -69,11 +69,13 @@ namespace GPW.CORE.Data.DbModels
|
||||
[ForeignKey("CodOrario")]
|
||||
public virtual AnagOrariModel? OrarioNav { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (!(obj is DipendentiModel item))
|
||||
return false;
|
||||
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (IdxDipendente != item.IdxDipendente)
|
||||
return false;
|
||||
if (AuthKey != item.AuthKey)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace GPW.CORE.Data.DbModels
|
||||
{
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
[Table("ElencoReport")]
|
||||
public partial class ElencoReportModel
|
||||
{
|
||||
[Key]
|
||||
public int IdxRep { get; set; } = 0;
|
||||
|
||||
public string Area { get; set; } = "";
|
||||
|
||||
[Column("nome")]
|
||||
public string? Nome { get; set; } = "";
|
||||
|
||||
[Column("descrizione")]
|
||||
public string? Descrizione { get; set; } = "";
|
||||
|
||||
[Column("cssClass")]
|
||||
public string? CssClass { get; set; } = "";
|
||||
|
||||
public string ReportUrl { get; set; } = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GPW.CORE.Data.DbModels
|
||||
{
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
[Table("ListTagDD")]
|
||||
public partial class ListTagDDModel
|
||||
{
|
||||
[Key]
|
||||
public int IdxTagDD { get; set; } = 0;
|
||||
public int IdxDipendente { get; set; } = 0;
|
||||
public DateTime DtRif { get; set; } = DateTime.Today;
|
||||
|
||||
public string CodTag { get; set; } = "";
|
||||
public bool isActive { get; set; } = true;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace GPW.CORE.Data.DbModels
|
||||
{
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
public partial class RegAttivitaDayExplModel
|
||||
{
|
||||
[Key, Column("idxRA")]
|
||||
public int IdxRA { get; set; } = 0;
|
||||
|
||||
[Column("idxDipendente")]
|
||||
public int IdxDipendente { get; set; } = 0;
|
||||
[Column("idxFase")]
|
||||
public int IdxFase { get; set; } = 0;
|
||||
[Column("idxProgetto")]
|
||||
public int IdxProgetto { get; set; } = 0;
|
||||
[Column("inizio")]
|
||||
public DateTime Inizio { get; set; } = DateTime.Today;
|
||||
[Column("fine")]
|
||||
public DateTime Fine { get; set; } = DateTime.Today;
|
||||
|
||||
[Column("descrizione")]
|
||||
public string Descrizione { get; set; } = "";
|
||||
|
||||
public string RagSociale { get; set; } = "";
|
||||
[Column("nomeProj")]
|
||||
public string NomeProj { get; set; } = "";
|
||||
[Column("nomeFase")]
|
||||
public string NomeFase { get; set; } = "";
|
||||
[Column("cognomeNome")]
|
||||
public string CognomeNome { get; set; } = "";
|
||||
[Column("gruppo")]
|
||||
public string Gruppo { get; set; } = "";
|
||||
|
||||
[Column("oreTot")]
|
||||
public decimal OreTot { get; set; } = 0;
|
||||
[Column("importo")]
|
||||
public decimal Importo { get; set; } = 0;
|
||||
[Column("minTot")]
|
||||
public decimal MinTot { get; set; } = 0;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data;
|
||||
|
||||
namespace GPW.CORE.Data.DbModels
|
||||
{
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
public partial class TimbMeseExplModel
|
||||
{
|
||||
public int Anno { get; set; } = 0;
|
||||
public int Mese { get; set; } = 0;
|
||||
public int IdxDipendente { get; set; } = 0;
|
||||
//public string? CognomeNome { get; set; } = "";
|
||||
public double totOreOrd { get; set; } = 0;
|
||||
public double totOreFest { get; set; }= 0;
|
||||
public double totOreDaLav { get; set; } = 0;
|
||||
public double totOrePerm { get; set; }= 0;
|
||||
public double totOreFer { get; set; } = 0;
|
||||
public double totOreMal { get; set; }= 0;
|
||||
public double totLav { get; set; } = 0;
|
||||
public double totOreNonLav { get; set; } = 0;
|
||||
public double totOreStra { get; set; } = 0;
|
||||
public double totOreCassa { get; set; } = 0;
|
||||
public double totOre104 { get; set; } = 0;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ namespace GPW.CORE.Data
|
||||
ND = 0,
|
||||
Lavoro = 1
|
||||
}
|
||||
|
||||
//public enum TestUser
|
||||
//{
|
||||
// LocatelliSamuele = 1,
|
||||
|
||||
@@ -4,24 +4,30 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" Version="1.11.4" />
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2501.1716" />
|
||||
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2511.312" />
|
||||
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.64.0" />
|
||||
<PackageReference Include="NLog" Version="5.4.0" />
|
||||
<PackageReference Include="RestSharp" Version="112.0.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.12" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
|
||||
<PackageReference Include="NLog" Version="6.1.1" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.37" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.25" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.25" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.25" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.25" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.25">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.1" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -77,9 +77,10 @@ namespace GPW.CORE.Data
|
||||
public virtual DbSet<ExpZucchettiModel> DbSetExpZucchetti { get; set; } = null!;
|
||||
public virtual DbSet<ExpCommessaModel> DbSetExpCommessa { get; set; } = null!;
|
||||
public virtual DbSet<MonthTagModel> DbSetMonthTag { get; set; } = null!;
|
||||
|
||||
|
||||
|
||||
public virtual DbSet<ListTagDDModel> DbSetListTagDD { get; set; } = null!;
|
||||
public virtual DbSet<TimbMeseExplModel> DbSetTimbMeseExpl { get; set; } = null!;
|
||||
public virtual DbSet<RegAttivitaDayExplModel> DbSetDayRaExpl { get; set; } = null!;
|
||||
public virtual DbSet<ElencoReportModel> DbSetElencoReport { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
@@ -953,6 +954,11 @@ namespace GPW.CORE.Data
|
||||
entity.HasKey(e => new { e.Anno, e.Mese, e.IdxDipendente });
|
||||
});
|
||||
|
||||
modelBuilder.Entity<TimbMeseExplModel>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.Anno, e.Mese, e.IdxDipendente });
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,16 @@ namespace GPW.CORE.Data
|
||||
CheckSumKey
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia di ticket
|
||||
/// </summary>
|
||||
public enum TipologiaTicket
|
||||
{
|
||||
ND = 0,
|
||||
Licenze,
|
||||
FileUpload
|
||||
}
|
||||
|
||||
#endregion Public Enums
|
||||
|
||||
#region Public Classes
|
||||
@@ -127,6 +137,7 @@ namespace GPW.CORE.Data
|
||||
|
||||
public string MasterKey { get; set; } = "";
|
||||
public string ReqBody { get; set; } = "";
|
||||
public TipologiaTicket Tipo { get; set; } = TipologiaTicket.ND;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
@@ -217,4 +228,4 @@ namespace GPW.CORE.Data
|
||||
|
||||
#endregion Public Classes
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using GPW.CORE.Dto;
|
||||
|
||||
namespace GPW.CORE.Data.Mappings
|
||||
{
|
||||
public static class DailyDataMappingExtensions
|
||||
{
|
||||
public static DailyDataDto ToDto(this GPW.CORE.Data.DTO.DailyDataDTO model)
|
||||
{
|
||||
return new DailyDataDto
|
||||
{
|
||||
IdxDipendente = model.IdxDipendente,
|
||||
DtRif = model.DtRif,
|
||||
ListRA = model.ListRA?.Select(ra => new RegAttivitaDto
|
||||
{
|
||||
IdxRa = ra.IdxRa,
|
||||
IdxDipendente = ra.IdxDipendente,
|
||||
IdxFase = ra.IdxFase,
|
||||
Inizio = ra.Inizio,
|
||||
Fine = ra.Fine,
|
||||
Descrizione = ra.Descrizione,
|
||||
OreTot = ra.OreTot,
|
||||
Importo = ra.Importo
|
||||
}).ToList(),
|
||||
ListTimbr = model.ListTimbr?.Select(t => new TimbraturaDto
|
||||
{
|
||||
DataOra = t.DataOra,
|
||||
IdxDipendente = t.IdxDipendente,
|
||||
Entrata = t.Entrata,
|
||||
CodTipoTimb = t.CodTipoTimb,
|
||||
Approv = t.Approv
|
||||
}).ToList(),
|
||||
TimbrExpl = model.TimbrExpl != null ? new TimbraturaExplDto
|
||||
{
|
||||
DataLav = model.TimbrExpl.DataLav,
|
||||
IdxDipendente = model.TimbrExpl.IdxDipendente,
|
||||
CognomeNome = model.TimbrExpl.CognomeNome,
|
||||
Entrata1 = model.TimbrExpl.Entrata1,
|
||||
Uscita1 = model.TimbrExpl.Uscita1,
|
||||
Entrata2 = model.TimbrExpl.Entrata2,
|
||||
Uscita2 = model.TimbrExpl.Uscita2,
|
||||
Entrata3 = model.TimbrExpl.Entrata3,
|
||||
Uscita3 = model.TimbrExpl.Uscita3,
|
||||
Entrata4 = model.TimbrExpl.Entrata4,
|
||||
Uscita4 = model.TimbrExpl.Uscita4,
|
||||
HLav = model.TimbrExpl.HLav,
|
||||
MinLav = model.TimbrExpl.MinLav,
|
||||
MinOrd = model.TimbrExpl.MinOrd,
|
||||
MinNonLav = model.TimbrExpl.MinNonLav,
|
||||
MinStra = model.TimbrExpl.MinStra,
|
||||
MinPerm = model.TimbrExpl.MinPerm,
|
||||
MinFer = model.TimbrExpl.MinFer,
|
||||
MinMal = model.TimbrExpl.MinMal,
|
||||
MinFest = model.TimbrExpl.MinFest,
|
||||
MinCassa = model.TimbrExpl.MinCassa,
|
||||
Min104 = model.TimbrExpl.Min104,
|
||||
MinMpp = model.TimbrExpl.MinMpp,
|
||||
MinArcoPres = model.TimbrExpl.MinArcoPres,
|
||||
IsOkTim = model.TimbrExpl.IsOkTim,
|
||||
IsOkApp = model.TimbrExpl.IsOkApp,
|
||||
Block = model.TimbrExpl.Block,
|
||||
ChkFunCod = model.TimbrExpl.ChkFunCod,
|
||||
ChkFunRes = model.TimbrExpl.ChkFunRes,
|
||||
IsOk = model.TimbrExpl.IsOk,
|
||||
IsOkLav = model.TimbrExpl.IsOkLav,
|
||||
HGiust = model.TimbrExpl.HGiust,
|
||||
TempRil = model.TimbrExpl.TempRil
|
||||
} : null,
|
||||
ListRilTemp = model.ListRilTemp?.Select(r => new RilievoTempDto
|
||||
{
|
||||
IdxDipendente = r.IdxDipendente,
|
||||
DtRilievo = r.DtRilievo,
|
||||
TempRil = r.TempRil
|
||||
}).ToList(),
|
||||
ListCheckC19 = model.ListCheckC19?.Select(c => new CheckVc19Dto
|
||||
{
|
||||
IdxCheckVc19 = c.IdxCheckVc19,
|
||||
DtCheck = c.DtCheck,
|
||||
IdxDipendente = c.IdxDipendente,
|
||||
Cognome = c.Cognome,
|
||||
Nome = c.Nome,
|
||||
Dob = c.Dob,
|
||||
Payload = c.Payload
|
||||
}).ToList(),
|
||||
ListFermateAzienda = model.ListFermateAzienda?.Select(f => new CalFesteFerieDto
|
||||
{
|
||||
Data = f.data,
|
||||
CodGiust = f.codGiust,
|
||||
Descrizione = f.descrizione
|
||||
}).ToList(),
|
||||
ListMalattie = model.ListMalattie?.Select(m => new RegMalattieDto
|
||||
{
|
||||
IdxRegMal = m.IdxRegMal,
|
||||
IdxDipendente = m.IdxDipendente,
|
||||
DtInizio = m.DtInizio,
|
||||
NumGG = m.NumGG,
|
||||
CodCert = m.CodCert,
|
||||
Conf = m.Conf
|
||||
}).ToList(),
|
||||
ListFerieDip = model.ListFerieDip?.Select(r => new RegRichiesteDto
|
||||
{
|
||||
IdxRegRich = r.IdxRegRich,
|
||||
IdxDipendente = r.IdxDipendente,
|
||||
CodGiust = r.CodGiust,
|
||||
DtStart = r.DtStart,
|
||||
DtEnd = r.DtEnd,
|
||||
Note = r.Note,
|
||||
Conf = r.Conf
|
||||
}).ToList(),
|
||||
ListRichiesteDip = model.ListRichiesteDip?.Select(r => new RegRichiesteDto
|
||||
{
|
||||
IdxRegRich = r.IdxRegRich,
|
||||
IdxDipendente = r.IdxDipendente,
|
||||
CodGiust = r.CodGiust,
|
||||
DtStart = r.DtStart,
|
||||
DtEnd = r.DtEnd,
|
||||
Note = r.Note,
|
||||
Conf = r.Conf
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
public static GPW.CORE.Data.DTO.DailyDataDTO ToModel(this DailyDataDto dto)
|
||||
{
|
||||
// Nota: Questa conversione è complessa perché il modello EF (DailyDataDTO)
|
||||
// è una struttura aggregata che non esiste direttamente come singola tabella.
|
||||
// In un'architettura reale, questa operazione verrebbe fatta tramite un servizio
|
||||
// che ricostruisce l'oggetto aggregato partendo dai singoli modelli.
|
||||
// Per ora restituiamo un oggetto vuoto o implementiamo solo la parte base
|
||||
// se necessario, ma solitamente dal DTO non si torna al modello aggregato EF
|
||||
// a meno di operazioni di salvataggio specifico.
|
||||
|
||||
throw new NotImplementedException("Mapping da DailyDataDto a DailyDataDTO (modello aggregato) non implementato. Questa conversione è solitamente gestita dal servizio tramite i singoli modelli.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Dto;
|
||||
|
||||
namespace GPW.CORE.Data.Mappings
|
||||
{
|
||||
public static class TimbratureMappingExtensions
|
||||
{
|
||||
public static TimbraturaDto ToDto(this TimbratureModel model)
|
||||
{
|
||||
return new TimbraturaDto
|
||||
{
|
||||
DataOra = model.DataOra,
|
||||
IdxDipendente = model.IdxDipendente,
|
||||
Entrata = model.Entrata,
|
||||
CodTipoTimb = model.CodTipoTimb,
|
||||
Approv = model.Approv
|
||||
};
|
||||
}
|
||||
|
||||
public static TimbratureModel ToModel(this TimbraturaDto dto)
|
||||
{
|
||||
return new TimbratureModel
|
||||
{
|
||||
DataOra = dto.DataOra,
|
||||
IdxDipendente = dto.IdxDipendente,
|
||||
Entrata = dto.Entrata,
|
||||
CodTipoTimb = dto.CodTipoTimb,
|
||||
Approv = dto.Approv
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# GPW.CORE.Data
|
||||
|
||||
Progetto responsabile dell'accesso ai dati e della gestione della persistenza per l'ecosistema GPW.
|
||||
|
||||
## Caratteristiche principali
|
||||
- **Accesso al Database**: Utilizza Entity Framework Core con SQL Server.
|
||||
- **Modelli di Dati**: Contiene la definizione di tutti i modelli del database (es. `DipendentiModel`, `RegAttivitaModel`, `AnagProgettiModel`).
|
||||
- **Autenticazione e Autorizzazione**: Gestisce il contesto di autenticazione utente (`UserAuthContext`) e l'integrazione con ASP.NET Core Identity.
|
||||
- **Servizi di Dati**: Fornisce servizi per la gestione delle licenze, invio email (via MailKit) e gestione dei messaggi.
|
||||
- **DTO**: Include oggetti di trasferimento dati per le operazioni di input/output.
|
||||
- **Integrazione**: Supporta l'uso di Redis per il caching e l'integrazione con Azure Identity.
|
||||
|
||||
## Dipendenze principali
|
||||
- Microsoft.EntityFrameworkCore (SQL Server)
|
||||
- Microsoft.AspNetCore.Identity.UI
|
||||
- MailKit
|
||||
- StackExchange.Redis
|
||||
- Azure.Identity
|
||||
- NLog
|
||||
- RestSharp
|
||||
@@ -388,13 +388,44 @@ namespace GPW.CORE.Data.Services
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue flush memoria redis dato pattern
|
||||
/// Esegue flush memoria redis dato pat2Flush
|
||||
/// </summary>
|
||||
/// <param name="pattern"></param>
|
||||
/// <param name="pat2Flush"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
|
||||
private async Task<bool> ExecFlushRedisPattern(RedisValue pat2Flush)
|
||||
{
|
||||
bool answ = false;
|
||||
var masterEndpoint = redisConn.GetEndPoints()
|
||||
.Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica)
|
||||
.FirstOrDefault();
|
||||
|
||||
// sepattern è "*" elimino intero DB...
|
||||
if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null))
|
||||
{
|
||||
redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database);
|
||||
}
|
||||
else
|
||||
{
|
||||
var server = redisConn.GetServer(masterEndpoint);
|
||||
var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000);
|
||||
|
||||
var deleteTasks = new List<Task>();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
deleteTasks.Add(redisDb.KeyDeleteAsync(key));
|
||||
if (deleteTasks.Count >= 1000)
|
||||
{
|
||||
await Task.WhenAll(deleteTasks);
|
||||
deleteTasks.Clear();
|
||||
}
|
||||
}
|
||||
if (deleteTasks.Count > 0)
|
||||
{
|
||||
await Task.WhenAll(deleteTasks);
|
||||
}
|
||||
}
|
||||
answ = true;
|
||||
#if false
|
||||
var listEndpoints = redisConn.GetEndPoints();
|
||||
foreach (var endPoint in listEndpoints)
|
||||
{
|
||||
@@ -409,7 +440,8 @@ namespace GPW.CORE.Data.Services
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using RestSharp;
|
||||
using StackExchange.Redis;
|
||||
using System.Web;
|
||||
using static GPW.CORE.Data.LiManObj;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace GPW.CORE.Data.Services
|
||||
{
|
||||
@@ -44,6 +47,18 @@ namespace GPW.CORE.Data.Services
|
||||
public string Applicazione { get; set; } = "";
|
||||
public LiManObj.ApplicativoDTO AppLicense { get; set; } = new LiManObj.ApplicativoDTO();
|
||||
|
||||
public bool DoCheckLicOk
|
||||
{
|
||||
get
|
||||
{
|
||||
// verifico num dip attivi <= num licenze attive...
|
||||
|
||||
return true;
|
||||
// verificare vecchia implementazione x check licenze (utenti attivi <= utenti licenza) + check payload (elenco hash utenti)
|
||||
//return (licenzeGPW.checkLicenze && licenzeGPW.checkPayload);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasActivData
|
||||
{
|
||||
get
|
||||
@@ -89,9 +104,27 @@ namespace GPW.CORE.Data.Services
|
||||
}
|
||||
|
||||
public DateTime infoExpiry { get; set; } = DateTime.Today.AddDays(1);
|
||||
|
||||
public string Installazione { get; set; } = "";
|
||||
|
||||
public string MasterKey { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Num licenze autorizzate dal DB
|
||||
/// </summary>
|
||||
public int NumLicDb
|
||||
{
|
||||
get
|
||||
{
|
||||
int answ = 0;
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
answ = getAVKInt(Installazione);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidData
|
||||
{
|
||||
get
|
||||
@@ -102,16 +135,6 @@ namespace GPW.CORE.Data.Services
|
||||
}
|
||||
}
|
||||
|
||||
public bool DoCheckLicOk
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
// verificare vecchia implementazione x check licenze (utenti attivi <= utenti licenza) + check payload (elenco hash utenti)
|
||||
//return (licenzeGPW.checkLicenze && licenzeGPW.checkPayload);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
@@ -150,6 +173,50 @@ namespace GPW.CORE.Data.Services
|
||||
return await Task.FromResult(dbResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera DTO dati attivazione licenza dato codice impiego
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
public AttivazioneDTO? GetOnlineActivationInfo(string CodImpiego)
|
||||
{
|
||||
AttivazioneDTO? answ = null;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/verifica?chiave={MKeyEnc}&CodImpiego={CodImpiego}");
|
||||
var response = client.Get(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// deserializzo
|
||||
answ = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola HASH del codice impiego = payload utente
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string HashDip(DipendentiModel recDip)
|
||||
{
|
||||
DataValidator cDV = new DataValidator(recDip);
|
||||
string hash = cDV.HashDip;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init della classe con variabili di base da Redis/DB
|
||||
/// </summary>
|
||||
@@ -179,7 +246,6 @@ namespace GPW.CORE.Data.Services
|
||||
fatto = await setAppLicData(AppLicense, numDays);
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
@@ -201,10 +267,45 @@ namespace GPW.CORE.Data.Services
|
||||
fatto = await setActivList(onlineAct, numDays);
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua refresh Payload su server (Remoto) e recupera info licenza in locale (sovrascrivendo info locali Redis)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool RefreshPayload()
|
||||
{
|
||||
bool answ = false;
|
||||
// svuoto payload calcolato
|
||||
ExecFlushRedisPattern((RedisValue)$"{rkeyPayload}:*");
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/licenza/refreshPayload");
|
||||
string newEnigma = DataValidator.CalcHash($"{DateTime.Now:yyyyMMddHHmmss}");
|
||||
LicenseCoord newBody = new LicenseCoord()
|
||||
{
|
||||
MasterKey = MasterKey,
|
||||
CodInst = Installazione,
|
||||
CodApp = Applicazione,
|
||||
Enigma = newEnigma
|
||||
};
|
||||
request.AddJsonBody(newBody);
|
||||
var response = client.Post(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
answ = true;
|
||||
// salvo in redis contenuto serializzato
|
||||
string rawData = $"{response.Content}";
|
||||
// salvo in redis per 7 gg
|
||||
setRSV(rKeyLic, rawData, TimeSpan.FromDays(7));
|
||||
}
|
||||
Log.Info($"Richiesta RefreshPayload eseguita");
|
||||
return answ;
|
||||
}
|
||||
|
||||
public async Task<bool> resetActivList()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
@@ -226,12 +327,89 @@ namespace GPW.CORE.Data.Services
|
||||
return answ;
|
||||
}
|
||||
|
||||
public void ResetLicenseData()
|
||||
{
|
||||
ExecFlushRedisPattern((RedisValue)$"{rKeyAttByLic}:*");
|
||||
ExecFlushRedisPattern((RedisValue)$"{rKeyLic}:*");
|
||||
ExecFlushRedisPattern((RedisValue)$"{rkeyPayload}:*");
|
||||
ExecFlushRedisPattern((RedisValue)$"{rkeyTickets}:*");
|
||||
}
|
||||
|
||||
public void ResetTicketCache()
|
||||
{
|
||||
ExecFlushRedisPattern((RedisValue)$"{rkeyTickets}:*");
|
||||
// ricarico
|
||||
var newList = getTickets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tenta invio di un ticket x licenza indicata
|
||||
/// </summary>
|
||||
/// <param name="contName"></param>
|
||||
/// <param name="contEmail"></param>
|
||||
/// <param name="contPhone"></param>
|
||||
/// <param name="reqBody"></param>
|
||||
/// <param name="codImpiego"></param>
|
||||
/// <param name="idxSubLic"></param>
|
||||
/// <returns></returns>
|
||||
public bool SendTicketReq(string contName, string contEmail, string contPhone, string reqBody, string codImpiego, int idxSubLic)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/ticket/sendReq");
|
||||
|
||||
SupportRequest richiesta = new SupportRequest()
|
||||
{
|
||||
ContactName = contName,
|
||||
ContactEmail = contEmail,
|
||||
ContactPhone = contPhone,
|
||||
ReqBody = reqBody,
|
||||
CodInst = Installazione,
|
||||
CodApp = Applicazione,
|
||||
MasterKey = MasterKey,
|
||||
idxSubLic = idxSubLic,
|
||||
CodImp = codImpiego,
|
||||
Tipo = TipologiaTicket.Licenze
|
||||
};
|
||||
|
||||
request.AddJsonBody(richiesta);
|
||||
var response = client.Post(request);
|
||||
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = response.Content;
|
||||
try
|
||||
{
|
||||
if (rawData.StartsWith("["))
|
||||
{
|
||||
// deserializzo
|
||||
List<TicketDTO> tickets = JsonConvert.DeserializeObject<List<TicketDTO>>(rawData);
|
||||
answ = tickets != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// deserializzo singolo
|
||||
TicketDTO tickets = JsonConvert.DeserializeObject<TicketDTO>(rawData);
|
||||
answ = tickets != null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
Log.Info($"Richiesta SendTicketReq inviata | idxSub: {idxSubLic}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
public async Task<bool> setActivList(List<LiManObj.AttivazioneDTO> newActList, int numDays)
|
||||
{
|
||||
bool fatto = false;
|
||||
string rKey = $"{rKeyAttByLic}:{MasterKey}";
|
||||
var rawData = JsonConvert.SerializeObject(newActList);
|
||||
await setRSV(rKey, rawData, numDays * 24);
|
||||
await setRSVAsync(rKey, rawData, numDays * 24);
|
||||
fatto = true;
|
||||
if (EA_InfoUpdated != null)
|
||||
{
|
||||
@@ -245,7 +423,7 @@ namespace GPW.CORE.Data.Services
|
||||
bool fatto = false;
|
||||
string cacheKey = $"{rKeyLic}:{MasterKey}";
|
||||
var rawData = JsonConvert.SerializeObject(newAppDto);
|
||||
await setRSV(cacheKey, rawData, numDays * 24);
|
||||
await setRSVAsync(cacheKey, rawData, numDays * 24);
|
||||
fatto = true;
|
||||
if (EA_InfoUpdated != null)
|
||||
{
|
||||
@@ -254,6 +432,187 @@ namespace GPW.CORE.Data.Services
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tenta attivazione licenza dato codice impiego
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryActivation(string CodImpiego, string Chiave)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni");
|
||||
Dictionary<string, string> parDict = new Dictionary<string, string>();
|
||||
parDict.Add(CodImpiego, Chiave);
|
||||
UserLicenseRequest newBody = new UserLicenseRequest()
|
||||
{
|
||||
MasterKey = MasterKey,
|
||||
ParamDict = parDict
|
||||
};
|
||||
request.AddJsonBody(newBody);
|
||||
var response = client.Post(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
// deserializzo
|
||||
AttivazioneDTO datiAttivazione = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
answ = datiAttivazione != null;
|
||||
ResetLicenseData();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
Log.Info($"Richiesta tryActivation | CodImpiego: {CodImpiego}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tenta attivazione licenze dato dizionario codici impiego + chiavi
|
||||
/// </summary>
|
||||
/// <param name="ParamsList">Dizionario parametri attivazione di tipo (CodImpiego,Chiave)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> TryActivationMult(Dictionary<string, string> ParamsList)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni");
|
||||
UserLicenseRequest newBody = new UserLicenseRequest()
|
||||
{
|
||||
MasterKey = MasterKey,
|
||||
ParamDict = ParamsList
|
||||
};
|
||||
request.AddJsonBody(newBody);
|
||||
var response = client.Post(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
if (rawData.Contains("["))
|
||||
{
|
||||
// deserializzo
|
||||
List<AttivazioneDTO> datiAttivazione = JsonConvert.DeserializeObject<List<AttivazioneDTO>>(rawData);
|
||||
answ = datiAttivazione != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// deserializzo singolo
|
||||
AttivazioneDTO datiAttivazione = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
answ = datiAttivazione != null;
|
||||
ResetLicenseData();
|
||||
await RefreshLicense();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
Log.Info($"Richiesta tryActivationMult | num params: {ParamsList.Count}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tenta refresh licenza dato codice impiego (aggiorna la authKey...)
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> TryRefreshActivation(string CodImpiego, string Chiave)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/refreshKey");
|
||||
Dictionary<string, string> parDict = new Dictionary<string, string>();
|
||||
parDict.Add(CodImpiego, Chiave);
|
||||
UserLicenseRequest newBody = new UserLicenseRequest()
|
||||
{
|
||||
MasterKey = MasterKey,
|
||||
ParamDict = parDict
|
||||
};
|
||||
request.AddJsonBody(newBody);
|
||||
var response = client.Post(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
if (rawData.Contains("["))
|
||||
{
|
||||
// deserializzo
|
||||
List<AttivazioneDTO> datiAttivazione = JsonConvert.DeserializeObject<List<AttivazioneDTO>>(rawData);
|
||||
answ = datiAttivazione != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// deserializzo singolo
|
||||
AttivazioneDTO datiAttivazione = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
answ = datiAttivazione != null;
|
||||
ResetLicenseData();
|
||||
await RefreshLicense();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
Log.Info($"Richiesta TryRefreshActivation | CodImpiego: {CodImpiego}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tenta rimozione licenza dato codice impiego
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> TryRemoveActivation(string CodImpiego, string Chiave)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/removeKey");
|
||||
Dictionary<string, string> parDict = new Dictionary<string, string>();
|
||||
parDict.Add(CodImpiego, Chiave);
|
||||
UserLicenseRequest newBody = new UserLicenseRequest()
|
||||
{
|
||||
MasterKey = MasterKey,
|
||||
ParamDict = parDict
|
||||
};
|
||||
request.AddJsonBody(newBody);
|
||||
var response = client.Post(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
bool.TryParse(rawData, out answ);
|
||||
ResetLicenseData();
|
||||
await RefreshLicense();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
Log.Info($"Richiesta TryRemoveActivation | CodImpiego: {CodImpiego} | answ: {answ}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
@@ -261,12 +620,22 @@ namespace GPW.CORE.Data.Services
|
||||
/// <summary>
|
||||
/// Chiave redis x attivazioni della licenza
|
||||
/// </summary>
|
||||
protected const string rKeyAttByLic = "LongCache:AttByLic";
|
||||
protected const string rKeyAttByLic = "GPW.CORE:LongCache:AttByLic";
|
||||
|
||||
/// <summary>
|
||||
/// Chiave redis x info licenza
|
||||
/// </summary>
|
||||
protected const string rKeyLic = "LongCache:LicData";
|
||||
protected const string rKeyLic = "GPW.CORE:LongCache:LicData";
|
||||
|
||||
/// <summary>
|
||||
/// Info payload
|
||||
/// </summary>
|
||||
protected const string rkeyPayload = "GPW.CORE:LongCache:Payload";
|
||||
|
||||
/// <summary>
|
||||
/// Info tickets
|
||||
/// </summary>
|
||||
protected const string rkeyTickets = "GPW.CORE:LongCache:Tickets";
|
||||
|
||||
protected Random rnd = new Random();
|
||||
|
||||
@@ -274,6 +643,113 @@ namespace GPW.CORE.Data.Services
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Verifica attivazione licenza dato codice impiego
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> CheckActivation(string CodImpiego)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/verifica?chiave={MKeyEnc}&CodImpiego={CodImpiego}");
|
||||
var response = client.Get(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
// deserializzo
|
||||
var datiAttivazione = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
if (datiAttivazione != null)
|
||||
{
|
||||
answ = datiAttivazione != null && datiAttivazione.CodImpiego == CodImpiego;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
return await Task.FromResult(answ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica attivazione licenza dato codice impiego
|
||||
/// </summary>
|
||||
/// <param name="CodImpiego"></param>
|
||||
/// <returns></returns>
|
||||
protected bool CheckActivationUnlocked(string CodImpiego)
|
||||
{
|
||||
bool answ = false;
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/verifica?chiave={MKeyEnc}&CodImpiego={CodImpiego}");
|
||||
var response = client.Get(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// verifico risposta
|
||||
string rawData = $"{response.Content}";
|
||||
try
|
||||
{
|
||||
// deserializzo
|
||||
var datiAttivazione = JsonConvert.DeserializeObject<AttivazioneDTO>(rawData);
|
||||
if (datiAttivazione != null)
|
||||
{
|
||||
// verifico se il veto sia scaduto
|
||||
answ = datiAttivazione.VetoUnlock <= DateTime.Today;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore double da elenco AKV
|
||||
/// </summary>
|
||||
/// <param name="varReq">Chiave AKV richiesta</param>
|
||||
/// <returns></returns>
|
||||
protected double getAVKDouble(string varReq)
|
||||
{
|
||||
double answ = 0;
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
answ = currRec.ValFloat ?? 0;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore int da elenco AKV
|
||||
/// </summary>
|
||||
/// <param name="varReq">Chiave AKV richiesta</param>
|
||||
/// <returns></returns>
|
||||
protected int getAVKInt(string varReq)
|
||||
{
|
||||
int answ = 0;
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
answ = currRec.ValInt ?? 0;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore string da elenco AKV
|
||||
/// </summary>
|
||||
@@ -310,13 +786,41 @@ namespace GPW.CORE.Data.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave in redis
|
||||
/// Salvataggio chiave in Redis
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rVal"></param>
|
||||
/// <param name="TTL"></param>
|
||||
/// <returns></returns>
|
||||
protected bool setRSV(string rKey, string rVal, TimeSpan TTL)
|
||||
{
|
||||
bool fatto = false;
|
||||
fatto = redisDb.StringSet(rKey, rVal, TTL);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave in Redis Async
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rVal"></param>
|
||||
/// <param name="TTL"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> setRSVAsync(string rKey, string rVal, TimeSpan TTL)
|
||||
{
|
||||
bool fatto = false;
|
||||
fatto = await redisDb.StringSetAsync(rKey, rVal, TTL);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave in Redis Async
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rVal"></param>
|
||||
/// <param name="cacheMult"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> setRSV(string rKey, string rVal, int cacheMult)
|
||||
protected async Task<bool> setRSVAsync(string rKey, string rVal, int cacheMult)
|
||||
{
|
||||
bool fatto = false;
|
||||
fatto = await redisDb.StringSetAsync(rKey, rVal, getCache(cacheMult));
|
||||
@@ -324,15 +828,15 @@ namespace GPW.CORE.Data.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave INT in redis
|
||||
/// Salvataggio chiave INT in Redis Async
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rValInt"></param>
|
||||
/// <param name="cacheMult"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> setRSV(string rKey, int rValInt, int cacheMult)
|
||||
protected async Task<bool> setRSVAsync(string rKey, int rValInt, int cacheMult)
|
||||
{
|
||||
return await setRSV(rKey, $"{rValInt}", cacheMult);
|
||||
return await setRSVAsync(rKey, $"{rValInt}", cacheMult);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
@@ -363,6 +867,68 @@ namespace GPW.CORE.Data.Services
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue flush memoria redis dato pat2Flush
|
||||
/// </summary>
|
||||
/// <param name="pat2Flush"></param>
|
||||
/// <returns></returns>
|
||||
private bool ExecFlushRedisPattern(RedisValue pat2Flush)
|
||||
{
|
||||
bool answ = false;
|
||||
var masterEndpoint = redisConn.GetEndPoints()
|
||||
.Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica)
|
||||
.FirstOrDefault();
|
||||
|
||||
// sepattern è "*" elimino intero DB...
|
||||
if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null))
|
||||
{
|
||||
redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database);
|
||||
}
|
||||
else
|
||||
{
|
||||
var server = redisConn.GetServer(masterEndpoint);
|
||||
var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000);
|
||||
var batch = new List<RedisKey>();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
batch.Add(key);
|
||||
|
||||
// Flush in batches of 1000
|
||||
if (batch.Count >= 1000)
|
||||
{
|
||||
foreach (var item in batch)
|
||||
redisDb.KeyDelete(item);
|
||||
|
||||
batch.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Flush remaining keys
|
||||
foreach (var item in batch)
|
||||
redisDb.KeyDelete(item);
|
||||
}
|
||||
answ = true;
|
||||
#if false
|
||||
var listEndpoints = redisConn.GetEndPoints();
|
||||
foreach (var endPoint in listEndpoints)
|
||||
{
|
||||
//var server = redisConnAdmin.GetServer(listEndpoints[0]);
|
||||
var server = redisConn.GetServer(endPoint);
|
||||
if (server != null)
|
||||
{
|
||||
var keyList = server.Keys(redisDb.Database, pattern);
|
||||
foreach (var item in keyList)
|
||||
{
|
||||
redisDb.KeyDelete(item);
|
||||
}
|
||||
answ = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache da moltiplicatore (orario) + perturbazione percentuale (+/-10%)
|
||||
/// </summary>
|
||||
@@ -371,6 +937,44 @@ namespace GPW.CORE.Data.Services
|
||||
return TimeSpan.FromHours((double)cacheMult * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera num ticket da sistema LiMan online
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<List<TicketDTO>> getTickets()
|
||||
{
|
||||
List<TicketDTO> answ = new List<TicketDTO>();
|
||||
#if false
|
||||
// cerco in cache locale...
|
||||
string rawData = memLayer.ML.getRSV(rkeyTickets);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
answ = JsonConvert.DeserializeObject<List<TicketDTO>>(rawData);
|
||||
}
|
||||
// se vuoto rileggo
|
||||
if (answ.Count == 0)
|
||||
{
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/ticket/{installazione}?CodApp={applicazione}&Chiave={MKeyEnc}");
|
||||
var response = client.Get(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// salvo in redis contenuto serializzato
|
||||
rawData = response.Content;
|
||||
// deserializzo
|
||||
answ = JsonConvert.DeserializeObject<List<TicketDTO>>(rawData);
|
||||
// salvo in redis per TTL std
|
||||
memLayer.ML.setRSV(rkeyTickets, rawData, 20);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco attivazioni attuali
|
||||
/// </summary>
|
||||
|
||||
+12
-2
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.4.11605.240
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.Data", "GPW.CORE.Data\GPW.CORE.Data.csproj", "{32DE3E46-CCED-4F7E-8EC1-A854DA4F51C1}"
|
||||
EndProject
|
||||
@@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE.Smart8.Client", "G
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE", "GPW.CORE\GPW.CORE.csproj", "{98EF4DDB-F268-40C1-BACF-13BCFF41F19D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE.Smart8.Shared", "GPW.CORE.Smart8.Shared\GPW.CORE.Smart8.Shared.csproj", "{F3D5D10F-22CC-414F-B86F-37A926112D79}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -33,6 +35,14 @@ Global
|
||||
{98EF4DDB-F268-40C1-BACF-13BCFF41F19D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98EF4DDB-F268-40C1-BACF-13BCFF41F19D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98EF4DDB-F268-40C1-BACF-13BCFF41F19D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F3D5D10F-22CC-414F-B86F-37A926112D79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3D5D10F-22CC-414F-B86F-37A926112D79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F3D5D10F-22CC-414F-B86F-37A926112D79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3D5D10F-22CC-414F-B86F-37A926112D79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0E8C2F3B-C5D0-84BB-3C55-3212282C5BF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E8C2F3B-C5D0-84BB-3C55-3212282C5BF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E8C2F3B-C5D0-84BB-3C55-3212282C5BF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E8C2F3B-C5D0-84BB-3C55-3212282C5BF3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>-->
|
||||
<ItemGroup>
|
||||
<!-- API Blazor necessarie per ComponentBase, InvokeAsync, StateHasChanged -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.25" />
|
||||
<PackageReference Include="NLog" Version="6.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GPW.CORE\GPW.CORE.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Smart\Pages\" />
|
||||
<Folder Include="Smart\Timbra\" />
|
||||
<Folder Include="Smart\Admin\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
# GPW.CORE.Shared
|
||||
|
||||
Progetto contenente componenti UI e logica condivisa per le applicazioni Blazor.
|
||||
|
||||
## Caratteristiche principali
|
||||
- **Componenti Blazor**: Fornisce componenti riutilizzabili per l'interfaccia utente (es. `CmpTop.razor`).
|
||||
- **Layout**: Definisce i layout comuni per le applicazioni (es. `MainLayout.razor`, `NavMenu.razor`).
|
||||
- **Logica Condivisa**: Contiene logica di navigazione e gestione dello stato dell'interfaccia utente per i moduli `Smart`.
|
||||
- **Target Framework**: Progettato per .NET 10 (in fase di aggiornamento).
|
||||
|
||||
## Struttura
|
||||
- `Smart/`: Contiene componenti, pagine e layout specifici per il modulo Smart (presenze/timbrature).
|
||||
|
||||
## Dipendenze
|
||||
- Microsoft.AspNetCore.Components.Web
|
||||
- NLog
|
||||
- Dipende da `GPW.CORE`
|
||||
@@ -0,0 +1,139 @@
|
||||
using GPW.CORE.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace GPW.CORE.Shared.Smart.Common
|
||||
{
|
||||
public partial class CmpTop : IDisposable
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public ConfigDTO CurrConf { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public UserDTO? CurrUser { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> EC_ForceReset { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> EC_ReturnHome { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool IpIsLocal { get; set; } = false;
|
||||
|
||||
|
||||
[Parameter]
|
||||
public string LocalNet { get; set; } = "###";
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
[Inject]
|
||||
private UserStateService UState { get; set; } = null!;
|
||||
|
||||
#if false
|
||||
[Inject]
|
||||
private MessageService MService { get; set; } = null!;
|
||||
#endif
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_subscribed)
|
||||
{
|
||||
UState.OnChange -= UState_OnChange;
|
||||
_subscribed = false;
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await Task.Delay(10);
|
||||
//await InvokeAsync(StateHasChanged);
|
||||
//return base.OnParametersSetAsync();
|
||||
|
||||
// verifico isLocal...
|
||||
if (!string.IsNullOrEmpty(LocalNet))
|
||||
{
|
||||
}
|
||||
}
|
||||
private string currIpv4 = "";
|
||||
|
||||
private bool _subscribed = false;
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
//if (firstRender)
|
||||
//{
|
||||
// // iscriviti qui nell'istanza client
|
||||
// UState.OnChange += UState_OnChange;
|
||||
// _subscribed = true;
|
||||
//}
|
||||
if (!_subscribed)
|
||||
{
|
||||
_subscribed = true;
|
||||
UState.OnChange += UState_OnChange;
|
||||
}
|
||||
if (CurrUser == null)
|
||||
{
|
||||
if (UState.CurrentUser != null)
|
||||
{
|
||||
CurrUser = UState.CurrentUser;
|
||||
//await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
//await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
|
||||
private void UState_OnChange()
|
||||
{
|
||||
// siamo in un callback non-UI thread: usa InvokeAsync
|
||||
_ = InvokeAsync(() =>
|
||||
{
|
||||
CurrUser = UState.CurrentUser;
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected string currDip
|
||||
{
|
||||
get => CurrUser != null ? CurrUser.DisplayName : "N.A. [0]";
|
||||
}
|
||||
|
||||
protected string homeCss
|
||||
{
|
||||
get => IpIsLocal ? "text-light" : "text-danger";
|
||||
}
|
||||
|
||||
protected string homeMessage
|
||||
{
|
||||
get => IpIsLocal ? "INT" : "EXT";
|
||||
}
|
||||
|
||||
[Inject]
|
||||
protected NavigationManager NavMan { get; set; } = null!;
|
||||
|
||||
protected string Nome { get; set; } = "";
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected async Task ForceReset()
|
||||
{
|
||||
await EC_ForceReset.InvokeAsync(true);
|
||||
}
|
||||
|
||||
protected async Task ReturnHome()
|
||||
{
|
||||
await EC_ReturnHome.InvokeAsync(true);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user