Compare commits
200 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f69ac663c | |||
| 08c4b4a0fb | |||
| 0de6b02b9d | |||
| 04ef5fb938 | |||
| 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;
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
|
||||
<div class="card shadow">
|
||||
<div class="card-header">
|
||||
<h4>Dipendenti</h4>
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<div class="input-group" runat="server">
|
||||
<span class="input-group-text">Clona</span>
|
||||
<select @bind="@idxDipSel" class="form-select form-select-sm">
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListDipendenti)
|
||||
<div class="card-header d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
<h4>Dipendenti</h4>
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<div class="input-group input-group-sm" runat="server">
|
||||
<span class="input-group-text">Clona</span>
|
||||
<select @bind="@idxDipSel" class="form-select form-select-sm">
|
||||
<option value="0">--- Selezionare ---</option>
|
||||
@foreach (var item in ListDipendenti)
|
||||
{
|
||||
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
|
||||
}
|
||||
</select>
|
||||
@if (idxDipSel > 0)
|
||||
{
|
||||
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
|
||||
<button class="btn btn-success" @onclick="AddSelected"><i class="fa fa-plus px-2" title="Aggiungi Assegnazione"></i></button>
|
||||
}
|
||||
</select>
|
||||
@if (idxDipSel > 0)
|
||||
{
|
||||
<button class="btn btn-success" @onclick="AddSelected"><i class="fa fa-plus px-2" title="Aggiungi Assegnazione"></i></button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Show Inatt.</span>
|
||||
<span class="form-control">
|
||||
<span class="form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" @bind="@ShowInactive" @bind:after="ReloadData">
|
||||
<div class="col-3 ps-0">
|
||||
<div class="input-group input-group-sm" title="Mostra Inattivi">
|
||||
<span class="input-group-text">All</span>
|
||||
<span class="form-control py-0">
|
||||
<span class="form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" @bind="@ShowInactive" @bind:after="ReloadData">
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,12 +47,12 @@
|
||||
else
|
||||
{
|
||||
<table class="table table-striped table-sm text-start">
|
||||
<thead>
|
||||
@* <thead>
|
||||
<tr class="">
|
||||
<th>Dipendente</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</thead> *@
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
@@ -62,10 +66,16 @@
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
@* <tfoot>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot> *@
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-footer p-0">
|
||||
<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)
|
||||
{
|
||||
|
||||
@@ -21,16 +21,26 @@
|
||||
<label class="small">Exp. Abil</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-1">
|
||||
<div class="form-floating">
|
||||
<span class="form-control">
|
||||
<div class="form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.IsActive">
|
||||
</div>
|
||||
</span>
|
||||
<label class="small">Attivo</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-success btn-lg mt-2 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
|
||||
</div>
|
||||
<div class="col-md-9 my-2">
|
||||
<div class="col-md-10 my-2">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" @bind="@CurrRecord.DescrGruppo">
|
||||
<label class="small">Descrizione</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-warning btn-lg mt-2 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,11 +65,11 @@
|
||||
<div class="col-7">
|
||||
<div class="card shadow">
|
||||
<div class="card-header">
|
||||
<div class="px-0 d-flex">
|
||||
<div class="px-2">
|
||||
<div class="px-0 d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
<h4>Gruppi</h4>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<div class="px-0">
|
||||
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,6 +96,7 @@
|
||||
<th>CodExt Grp. <Sorter ParamName="CodExt" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th># Dip. <Sorter ParamName="NumDip" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end"><Sorter ParamName="Export" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Exp. Abil</th>
|
||||
<th class="text-end"><Sorter ParamName="IsActive" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Attivo</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -123,14 +124,17 @@
|
||||
@item.DescrGruppo
|
||||
</td>
|
||||
<td>
|
||||
@item.NumDip
|
||||
@item.CodExt
|
||||
</td>
|
||||
<td>
|
||||
@item.CodExt
|
||||
@item.NumDip
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.ExportEnab">
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.IsActive">
|
||||
</td>
|
||||
<td>
|
||||
@if (@item.NumDip == 0)
|
||||
{
|
||||
|
||||
@@ -246,6 +246,17 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
}
|
||||
break;
|
||||
|
||||
case "IsActive":
|
||||
if (sortAsc)
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderBy(x => x.IsActive).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRecords = SearchRecords.OrderByDescending(x => x.IsActive).ToList();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -42,9 +42,23 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
|
||||
protected async Task DoClone()
|
||||
{
|
||||
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler procedere con la clonazione del progetto(+fasi) selezionato?"))
|
||||
return;
|
||||
|
||||
// verifico se il gruppo sia attivo, se non lo fosse avvisa che andrà cambiato...
|
||||
var listGroup = await GDataServ.AnagGruppiAll();
|
||||
if (listGroup != null)
|
||||
{
|
||||
var currRec = listGroup.FirstOrDefault(x => x.Gruppo == CurrRecord.Gruppo);
|
||||
if (currRec != null && !(currRec.IsActive??false))
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Attenzione! l record è associato ad un gruppo disattivo, ricordati di cambiarlo dopo la modifica. Confermi di voler procedere?"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool fatto = false;
|
||||
await Task.Delay(1);
|
||||
if (CurrRecord != null)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -128,8 +128,8 @@ else
|
||||
<thead>
|
||||
<tr class="bg-dark text-light align-middle">
|
||||
<th></th>
|
||||
<th>Dipendente</th>
|
||||
<th>Periodo</th>
|
||||
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th>Periodo <Sorter ParamName="Periodo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -3,7 +3,9 @@ using GPW.CORE.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using NLog;
|
||||
using static EgwCoreLib.Razor.Sorter;
|
||||
using static EgwCoreLib.Razor.Toggler;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace GPW.CORE.ADM.Components.Compo
|
||||
{
|
||||
@@ -294,12 +296,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 +366,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)
|
||||
{
|
||||
@@ -372,11 +374,7 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
}
|
||||
// conteggio!
|
||||
totalCount = SearchRecords.Count;
|
||||
// paginazione
|
||||
ListRecords = SearchRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
private void toggleEdit()
|
||||
@@ -385,5 +383,38 @@ namespace GPW.CORE.ADM.Components.Compo
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
private bool sortAsc = false;
|
||||
private string sortField = "";
|
||||
|
||||
protected void SortRequested(SortCallBack e)
|
||||
{
|
||||
if (sortField == e.ParamName)
|
||||
{
|
||||
sortAsc = e.IsAscending;
|
||||
}
|
||||
sortField = e.ParamName;
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
private void UpdateTable()
|
||||
{
|
||||
// 1. Prepariamo la query base
|
||||
var query = SearchRecords.AsEnumerable();
|
||||
|
||||
// 2. Applichiamo l'ordinamento dinamico
|
||||
query = sortField switch
|
||||
{
|
||||
"Dipendente" => sortAsc ? query.OrderBy(x => x.DipNav.Abbrev) : query.OrderByDescending(x => x.DipNav.Abbrev),
|
||||
"Periodo" => sortAsc ? query.OrderBy(x => x.DtStart) : query.OrderByDescending(x => x.DtStart),
|
||||
_ => query.OrderByDescending(x => x.DtStart) // Ordinamento di default obbligatorio per la paginazione
|
||||
};
|
||||
|
||||
// 3. Paginazione finale
|
||||
ListRecords = query
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,77 +1,77 @@
|
||||
<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.2607.0211</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>4.1.2502.0418</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Remove="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS-PROD.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS01.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS03.pubxml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS-PROD.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS01.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS03.pubxml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" Version="1.11.4" />
|
||||
<PackageReference Include="Blazored.FluentValidation" Version="2.2.0" />
|
||||
<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="6.1.1" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="7.0.8" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.7.2" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<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="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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\app.css">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.ico">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.png">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\manifest.json">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\app.css">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.ico">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\favicon.png">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\manifest.json">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="logs\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="temp\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="logs\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="temp\.placeholder">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
|
||||
</Target>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -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;
|
||||
@@ -774,6 +775,7 @@ namespace GPW.CORE.Data.Controllers
|
||||
dbRec.CodExt = upsRec.CodExt;
|
||||
dbRec.DescrGruppo = upsRec.DescrGruppo;
|
||||
dbRec.ExportEnab = upsRec.ExportEnab;
|
||||
dbRec.IsActive = upsRec.IsActive;
|
||||
dbRec.Gruppo = upsRec.Gruppo;
|
||||
//set modificato
|
||||
dbCtx.Entry(dbRec).State = EntityState.Modified;
|
||||
@@ -1054,7 +1056,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 +1339,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 +2032,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 +2099,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 +2107,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 +2509,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 +2686,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 +2822,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 +2892,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 +3453,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 +3463,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 +3538,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 +3554,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 +3638,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 +3768,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 +3807,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;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,18 @@ namespace GPW.CORE.Data.DbModels
|
||||
public string Gruppo { get; set; } = null!;
|
||||
public string? DescrGruppo { get; set; }
|
||||
public string? CodExt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// determina se sia abilitato x export dati
|
||||
/// </summary>
|
||||
public bool? ExportEnab { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gestione stato attivo/disattivo
|
||||
/// </summary>
|
||||
[Column("isActive")]
|
||||
public bool? IsActive { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public int NumDip
|
||||
{
|
||||
|
||||
@@ -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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user