FEAT: workplace display and document listing

This commit is contained in:
Frede Hundewadt 2023-05-13 07:04:29 +02:00
parent 745ccc478c
commit e96e10412e
15 changed files with 623 additions and 632 deletions

View file

@ -35,6 +35,7 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
private readonly HttpClient _client;
private readonly ApiConfig _api;
public AdvisorWorkplaceRepository(HttpClient client,
ILogger<AdvisorWorkplaceRepository> logger,
NavigationManager navigation,
@ -46,6 +47,7 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
_api = configuration.Value;
}
public async Task<List<WorkplaceListView>> GetWorkplaces(string companyId)
{
var result = await _client.GetAsync(
@ -58,6 +60,7 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
return JsonSerializer.Deserialize<List<WorkplaceListView>>(content, _options) ?? new List<WorkplaceListView>();
}
public async Task<WorkplaceDto> GetWorkplace(string companyId, string workplaceId)
{
var result = await _client.GetAsync(
@ -70,6 +73,7 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
return JsonSerializer.Deserialize<WorkplaceDto>(content, _options) ?? new WorkplaceDto();
}
public async Task<WorkplaceInventory> GetWorkplaceInventory(string companyId, string workplaceId)
{
var result = await _client.GetAsync(
@ -82,6 +86,7 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
return JsonSerializer.Deserialize<WorkplaceInventory>(content, _options) ?? new WorkplaceInventory();
}
public async Task<string> CreateWorkplace(string companyId, WorkplaceDto workplace)
{
var result = await _client.PostAsJsonAsync(
@ -94,18 +99,28 @@ public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
return content;
}
public async Task UpdateWorkplace(string companyId, WorkplaceDto workplace)
{
await _client.PutAsJsonAsync(
$"{_api.CrmCustomers}/{companyId}/{_api.CrmWorkplaceExt}/{workplace.WorkplaceId}", workplace, _options);
}
public async Task DeleteWorkplace(string companyId, string workplaceId)
{
await _client.DeleteAsync(
$"{_api.CrmCustomers}/{companyId}/{_api.CrmWorkplaceExt}/{workplaceId}");
}
public async Task DeleteWorkplaceDocuments(string companyId, string workplaceId, string documentId)
{
await _client.DeleteAsync(
$"{_api.CrmCustomers}/{companyId}/{_api.CrmWorkplaceExt}/{workplaceId}/documents/{documentId}");
}
public async Task DeleteWorkplaceDocuments(string companyId, string workplaceId, string apbDocumentId, string apvDocumentId)
{
await _client.DeleteAsync(

View file

@ -79,4 +79,6 @@ public interface IAdvisorWorkplaceRepository
/// <param name="apbDocumentId"></param>
/// <returns></returns>
Task DeleteWorkplaceDocuments(string companyId, string workplaceId, string apbDocumentId, string apvDocumentId);
Task DeleteWorkplaceDocuments(string companyId, string workplaceId, string documentId);
}

View file

@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Wonky.Client.Models;
public class DocView
{
public string ApbDocId { get; set; } = "";
public string ApbDocLink { get; set; } = "";
public string ApvDocId { get; set; } = "";
public string ApvDocLink { get; set; } = "";
public string DocumentDate { get; set; } = "";
public string ProductId { get; set; } = "";
public string VariantId { get; set; } = "";
public string VariantName { get; set; } = "";
}

View file

@ -53,14 +53,13 @@ else
{
<EditForm EditContext="ActivityContext">
<DataAnnotationsValidator/>
<div class="row mb-3 g-2">
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
<div class="col-sm-4">
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
@if (Kanvas)
{
<option value="canvas" selected>Kanvas</option>
<option value="canvas" selected>Kanvas</option>
}
else
{
@ -131,7 +130,7 @@ else
<InputTextArea id="crmNote" class="form-control" @bind-Value="Activity.CrmNote"/>
<ValidationMessage For="@(() => Activity.CrmNote)"></ValidationMessage>
</div>
}
}
else
{
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
@ -191,204 +190,204 @@ else
@if (!Kanvas)
{
<div class="row g-2 mb-3">
<div class="col-sm-3 d-grid mx-auto">
@*
<div class="row g-2 mb-3">
<div class="col-sm-3 d-grid mx-auto">
@*
***************** Invoice history overlay *****************************
*@
<button class="btn btn-danger" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowInvoiceOverlay">Faktura</button>
</div>
<div class="col-sm-3 d-grid mx-auto">
@*
<button class="btn btn-danger" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowInvoiceOverlay">Faktura</button>
</div>
<div class="col-sm-3 d-grid mx-auto">
@*
***************** Visit hisotry overlay *****************************
*@
<button class="btn btn-warning" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowVisitOverlay">Tidl. besøg</button>
</div>
<div class="col-sm-3 d-grid mx-auto">
@*
<button class="btn btn-warning" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowVisitOverlay">Tidl. besøg</button>
</div>
<div class="col-sm-3 d-grid mx-auto">
@*
***************** Product Inventory overlay *****************************
*@
<button class="btn btn-success" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowInventoryOverlay">Produkter</button>
</div>
</div>
<div id="this-draft" class="@(Activity.ActivityStatusEnum is "order" or "quote" ? "visible" : "invisible")">
@* Draft lines in draft -----------------------------------------------------*@
<div class="row">
<div class="col">
<table class="sticky-top table table-hover table-striped table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="7">
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
@*
***************** Reset draft *****************************
*@
<button type="button" class="btn btn-danger btn-sm" onclick="@DeleteDraft" disabled="@(DraftProvider.Draft.Items.Count == 0)"><i class="bi-trash"></i> Slet kladde</button>
</th>
</tr>
<tr class="bg-dark opacity-75 text-white">
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col" class="text-end">Antal</th>
<th scope="col" class="text-end">Enhedspris</th>
<th scope="col" class="text-center">%</th>
<th scope="col" class="text-end">Linjesum</th>
<th scope="col" class="text-end">SAS</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@if (DraftProvider.Draft.Items.Count > 0)
{
@foreach (var cartItem in DraftProvider.Draft.Items)
{
<tr>
<td class="align-middle">@cartItem.Item.Name</td>
<td class="align-middle">@cartItem.Item.Sku</td>
<td class="align-middle text-end">@cartItem.Quantity</td>
<td class="align-middle text-end">@($"{cartItem.Price:N2}")</td>
<td class="align-middle text-end">@($"{cartItem.Discount:N2}")</td>
<td class="align-middle text-end">@($"{cartItem.LineTotal:N2}")</td>
<td class="align-middle text-center">
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="align-middle text-end">
@*
***************** Remove item *****************************
*@
<button type="button" class="btn btn-danger" onclick="@(() => RemoveItem(cartItem))"><i class="bi-trash2"></i> Slet Linje</button>
</td>
</tr>
}
}
<tr>
<td colspan="4"></td>
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@($"{DraftProvider.Draft.Total:N2}")</td>
<td></td>
<td class="align-middle text-end">
@*
***************** Price catalog overlay button *****************************
*@
<button class="btn btn-primary" type="button" onclick="@ShowPriceListOverlay">
<i class="bi-plus"></i> Ny linje
</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-success" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" onclick="@ShowInventoryOverlay">Produkter</button>
</div>
</div>
@* Create Draft line ----------------------------------------------------- *@
<div class="row">
<div class="col">
@if (!string.IsNullOrWhiteSpace(SelectedItem.Name) && ShowItem)
{
<table id="draft-line" class="table table-bordered">
<div id="this-draft" class="@(Activity.ActivityStatusEnum is "order" or "quote" ? "inno-display" : "inno-hidden")">
@* Draft lines in draft -----------------------------------------------------*@
<div class="row">
<div class="col">
<table class="sticky-top table table-hover table-striped table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">Kladdelinje</th>
<th scope="col" colspan="7">
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
@*
***************** Reset draft *****************************
*@
<button type="button" class="btn btn-danger btn-sm" onclick="@DeleteDraft" disabled="@(DraftProvider.Draft.Items.Count == 0)"><i class="bi-trash"></i> Slet kladde</button>
</th>
</tr>
<tr>
<th style="min-width:100px;" scope="col">Antal</th>
<th style="min-width:200px;" scope="col">Pris</th>
<th style="min-width:100px;" scope="col">Rabat</th>
<th class="align-content-center justify-content-center" scope="col">SAS</th>
<th scope="col">Varenr.</th>
<tr class="bg-dark opacity-75 text-white">
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col" class="text-end">Antal</th>
<th scope="col" class="text-end">Enhedspris</th>
<th scope="col" class="text-center">%</th>
<th scope="col" class="text-end">Linjesum</th>
<th scope="col" class="text-end">SAS</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle" style="min-width:100px;">
<input type="number" class="form-control" @bind-value="Quantity"/>
</td>
<td class="align-middle" style="min-width:200px;">
<div class="input-group">
<input type="number" class="form-control" @bind-value="Price"/>
@*
***************** Product Price history overlay button *********************
@if (DraftProvider.Draft.Items.Count > 0)
{
@foreach (var cartItem in DraftProvider.Draft.Items)
{
<tr>
<td class="align-middle">@cartItem.Item.Name</td>
<td class="align-middle">@cartItem.Item.Sku</td>
<td class="align-middle text-end">@cartItem.Quantity</td>
<td class="align-middle text-end">@($"{cartItem.Price:N2}")</td>
<td class="align-middle text-end">@($"{cartItem.Discount:N2}")</td>
<td class="align-middle text-end">@($"{cartItem.LineTotal:N2}")</td>
<td class="align-middle text-center">
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="align-middle text-end">
@*
***************** Remove item *****************************
*@
<button class="btn btn-warning" type="button" onclick="@ShowPriceHistoryOverlay">
<i class="bi-list-ul"></i>
</button>
</div>
</td>
<td class="align-middle" style="min-width:100px;">
<input type="number" class="form-control" @bind-value="Discount"/>
</td>
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="Sas"/>
</td>
<td class="align-middle">@SelectedItem.Sku</td>
<td class="align-middle">
<button type="button" class="btn btn-danger" onclick="@(() => RemoveItem(cartItem))"><i class="bi-trash2"></i> Slet Linje</button>
</td>
</tr>
}
}
<tr>
<td colspan="4"></td>
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@($"{DraftProvider.Draft.Total:N2}")</td>
<td></td>
<td class="align-middle text-end">
@*
***************** Add item button *****************************
*@
<button type="button" class="btn btn-primary d-block text-sm-center" onclick="@(() => AddItem(SelectedItem))">@Quantity stk. @SelectedItem.Name</button>
***************** Price catalog overlay button *****************************
*@
<button class="btn btn-primary" type="button" onclick="@ShowPriceListOverlay">
<i class="bi-plus"></i> Ny linje
</button>
</td>
</tr>
</tbody>
</table>
}
</div>
</div>
@* Create Draft line ----------------------------------------------------- *@
<div class="row">
<div class="col">
@if (!string.IsNullOrWhiteSpace(SelectedItem.Name) && ShowItem)
{
<table id="draft-line" class="table table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">Kladdelinje</th>
</tr>
<tr>
<th style="min-width:100px;" scope="col">Antal</th>
<th style="min-width:200px;" scope="col">Pris</th>
<th style="min-width:100px;" scope="col">Rabat</th>
<th class="align-content-center justify-content-center" scope="col">SAS</th>
<th scope="col">Varenr.</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle" style="min-width:100px;">
<input type="number" class="form-control" @bind-value="Quantity"/>
</td>
<td class="align-middle" style="min-width:200px;">
<div class="input-group">
<input type="number" class="form-control" @bind-value="Price"/>
@*
***************** Product Price history overlay button *********************
*@
<button class="btn btn-warning" type="button" onclick="@ShowPriceHistoryOverlay">
<i class="bi-list-ul"></i>
</button>
</div>
</td>
<td class="align-middle" style="min-width:100px;">
<input type="number" class="form-control" @bind-value="Discount"/>
</td>
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="Sas"/>
</td>
<td class="align-middle">@SelectedItem.Sku</td>
<td class="align-middle">
@*
***************** Add item button *****************************
*@
<button type="button" class="btn btn-primary d-block text-sm-center" onclick="@(() => AddItem(SelectedItem))">@Quantity stk. @SelectedItem.Name</button>
</td>
</tr>
</tbody>
</table>
}
</div>
</div>
@* end draft line ------------------------------------------------- *@
</div>
@* end draft line ------------------------------------------------- *@
</div>
<div class="accordion" id="crmActivity">
@* Delivery address *@
<div class="accordion-item @(Activity.ActivityStatusEnum == "order" ? "visible" : "invisible")">
<h2 class="accordion-header" id="deliveryHeader">
<button class="accordion-button collapsed bg-light" type="button" data-bs-toggle="collapse" data-bs-target="#deliveryBody" aria-expanded="false" aria-controls="deliveryBody">
Leveringsadresse
</button>
</h2>
<div id="deliveryBody" class="accordion-collapse collapse"
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
<div class="accordion-body">
<div class="row mb-1">
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
<div class="col-md-10">
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
<div class="accordion" id="crmActivity">
@* Delivery address *@
<div class="accordion-item @(Activity.ActivityStatusEnum == "order" ? "inno-display" : "inno-hidden")">
<h2 class="accordion-header" id="deliveryHeader">
<button class="accordion-button collapsed bg-light" type="button" data-bs-toggle="collapse" data-bs-target="#deliveryBody" aria-expanded="false" aria-controls="deliveryBody">
Leveringsadresse
</button>
</h2>
<div id="deliveryBody" class="accordion-collapse collapse"
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
<div class="accordion-body">
<div class="row mb-1">
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
<div class="col-md-10">
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
</div>
</div>
</div>
<div class="row mb-1">
<label for="dlvAddress1" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
<div class="row mb-1">
<label for="dlvAddress1" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
</div>
</div>
</div>
<div class="row mb-1">
<label for="dlvAddress2" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
<div class="row mb-1">
<label for="dlvAddress2" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
</div>
</div>
</div>
<div class="row mb-1">
<label for="dlvZipCode" class="col-sm-2 col-form-label-sm">Lev. Postnr</label>
<div class="col-md-10">
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
<div class="row mb-1">
<label for="dlvZipCode" class="col-sm-2 col-form-label-sm">Lev. Postnr</label>
<div class="col-md-10">
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
</div>
</div>
</div>
<div class="row mb-1">
<label for="dlvCity" class="col-sm-2 col-form-label-sm">Lev. Bynavn</label>
<div class="col-md-10">
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
<div class="row mb-1">
<label for="dlvCity" class="col-sm-2 col-form-label-sm">Lev. Bynavn</label>
<div class="col-md-10">
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
</EditForm>
<div class="row mt-5 mb-2">
<div class="row mb-2">
<div class="col-sm-6">
<a class="btn btn-warning" href="/advisor/customers/@Company.CompanyId">Kundekort <i class="bi-arrow-left"></i></a>
<a class="btn btn-warning" href="/advisor/customers/@Company.CompanyId"><i class="bi-arrow-left"></i> Kundekort</a>
</div>
<div class="col-sm-4 text-end">
@*

View file

@ -52,7 +52,7 @@
}
<div class="row pt-2 mb-2 rounded rounded-2 bg-dark text-white">
<div class="col-sm-12">
<span class="h3">@Company.Name</span> <span>(@Company.Account)</span>
<span class="h3">@Company.Name</span> <span>(@Company.Account)</span>
</div>
</div>
// erp context
@ -128,7 +128,7 @@
@* <ValidationMessage For="@(() => )"></ValidationMessage> *@
</div>
<div class="col-sm-1">
<div class="led-box @(DateTime.Now < DateTime.Parse("2023-12-31") ? "visible" : "invisible")" >
<div class="led-box @(DateTime.Now < DateTime.Parse("2023-12-31") ? "inno-display" : "inno-hidden")">
<div class="led-red"></div>
</div>
</div>
@ -139,7 +139,7 @@
@* placeholder *@
</div>
}
@* Enable edit/save *@
<div class="col-sm-2 d-grid mx-auto">
<button type="button" class="btn btn-edit" onclick="@ToggleErpEdit"><i class="bi-pencil"></i> STAM data</button>
@ -305,19 +305,19 @@
<InputTextArea id="crmNotes" class="form-control" @bind-Value="Company.CrmNotes"/>
</div>
</div>
<div class="row pt-3">
<div class="col-sm-3 d-grid">
<button type="button" class="btn btn-danger" onclick="@ToggleVisibility">@ToggleButtonText</button>
</div>
<div class="col-sm-3 d-grid">
@if (AppInfo.Value.Rc)
{
<a class="btn btn-info" href="@($"/advisor/customers/{CompanyId}/workplaces")">Kemi Dokumentation</a>
}
</div>
</div>
}
</EditForm>
<div class="row pt-3 mb-5">
<div class="col-sm-4 d-grid">
<button type="button" class="btn btn-outline-dark" onclick="@ToggleVisibility">@ToggleButtonText</button>
</div>
<div class="col-sm-4 d-grid">
@if (AppInfo.Value.Rc)
{
<a class="btn btn-info" href="@($"/advisor/customers/{CompanyId}/workplaces")">Kemi Dokumentation</a>
}
</div>
</div>
}
@if (Working)

View file

@ -1,85 +0,0 @@
@* Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}/workplaces/{WorkplaceId}/documents"
<PageTitle>Dokumenter - @WorkplaceInventory.CompanyName - @WorkplaceInventory.WorkplaceName</PageTitle>
<div class="row">
<div class="col-sm-12">
<h2>@WorkplaceInventory.CompanyName</h2>
</div>
</div>
<div class="row">
<div class="col-sm-10"><h3>@WorkplaceInventory.WorkplaceName Produkt Dokumentation</h3></div>
<div class="col-sm-2"></div>
</div>
@if (WorkplaceInventory.Products.Any())
{
<ol class="list-group">
<li class="list-group-item d-flex row g-2 align-items-center">
<div class="row">
<div class="col-sm-4">
Produkt
</div>
<div class="col-sm-2">
APB
</div>
<div class="col-sm-2">
KAPV
</div>
<div class="col-sm-3">
Oprettet
</div>
<div class="col-sm-1">
</div>
</div>
</li>
@foreach (var document in Documents)
{
<li class="list-group-item d-flex row g-2 align-items-center">
<div class="col-sm-4">
@document.ProductName
</div>
<div class="col-sm-2">
<a class="btn btn-outline-dark btn-sm" href="@document.ApbLink" target="_blank">Vis APB</a>
</div>
<div class="col-sm-2">
<a class="btn btn-outline-dark btn-sm" href="@document.ApvLink" target="_blank">Vis KAPV</a>
</div>
<div class="col-sm-3">
@document.DocumentDate
</div>
<div class="col-sm-1 text-end">
<button type="button" class="btn btn-danger btn-sm" @onclick="@(() => RemoveDocument(document.ApbId, document.ApvId))">
<i class="bi-trash"></i>
</button>
</div>
</li>
}
</ol>
}
@if (Working)
{
<WorkingThreeDots/>
}

View file

@ -1,104 +0,0 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.Pages;
public partial class AdvisorCustomerWorkplaceDocumentListPage : IDisposable
{
// ##################################################################
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IAdvisorWorkplaceRepository WorkplaceRepo { get; set; }
// ##################################################################
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string WorkplaceId { get; set; } = "";
// ##################################################################
private bool Working { get; set; } = true;
private WorkplaceInventory WorkplaceInventory { get; set; } = new();
private List<Document> Documents { get; set; } = new();
protected override async Task OnParametersSetAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
Documents = await FetchDocuments();
Working = false;
}
private async Task RemoveDocument(string apbId, string apvId)
{
await WorkplaceRepo.DeleteWorkplaceDocuments(CompanyId, WorkplaceId, apbId, apvId);
Documents = await FetchDocuments();
}
private async Task<List<Document>> FetchDocuments()
{
Documents = new List<Document>();
WorkplaceInventory = await WorkplaceRepo.GetWorkplaceInventory(CompanyId, WorkplaceId);
foreach (var product in WorkplaceInventory.Products)
{
var newDoc = new Document();
foreach (var variant in product.Variants)
{
newDoc.ProductName = variant.VariantName;
foreach (var doc in variant.Docs)
{
if (doc.DocumentTypeEnum == "Apb")
{
newDoc.ApbLink = doc.DocumentLink;
newDoc.ApbId = doc.DocumentId;
}
else
{
newDoc.ApvLink = doc.DocumentLink;
newDoc.ApvId = doc.DocumentId;
}
newDoc.DocumentDate = doc.DocumentDate;
}
Documents.Add(newDoc);
}
}
return Documents;
}
public void Dispose()
{
Interceptor.DisposeEvent();
}
}
internal sealed class Document
{
public string ProductName { get; set; }
public string ApbLink { get; set; }
public string ApvLink { get; set; }
public string DocumentDate { get; set; }
public string ApvId { get; set; }
public string ApbId { get; set; }
}

View file

@ -24,13 +24,13 @@
<div class="card-header">
<div class="row">
<div class="col-sm-6">
<h2>@Company.Name</h2>
<h3>@Company.Name</h3>
</div>
<div class="col-sm-4 d-grid">
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces/new"><i class="bi-plus-lg"></i> Opret arbejdssted</a>
<div class="col-sm-3 d-flex">
<a class="btn btn-primary mx-auto" href="/advisor/customers/@CompanyId"><i class="bi-chevron-left"></i> Kundekort</a>
</div>
<div class="col-sm-2">
<div class="col-sm-3 d-flex">
<a class="btn btn-primary mx-auto" href="/advisor/customers/@CompanyId/workplaces/new"><i class="bi-plus-lg"></i> Arbejdssted</a>
</div>
</div>
</div>

View file

@ -17,98 +17,92 @@
@page "/advisor/customers/{CompanyId}/workplaces/new"
@using Microsoft.AspNetCore.Authorization
<PageTitle>Opret arbejdssted - @Company.Name</PageTitle>
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-sm-10">
<h2>Opret arbejdssted for @Company.Name</h2>
</div>
<div class="col-sm-2">
<PageTitle>@Company.Name - Opret Arbejdssted</PageTitle>
<div class="row g-1 mb-3">
<div class="col-sm-8">
<h3>@Company.Name Opret Arbejdssted</h3>
</div>
<div class="col-sm-2 d-flex">
<a class="btn btn-primary mx-auto d-block" href="/advisor/customers/@CompanyId"><i class="bi-chevron-left"></i> Kundekort</a>
</div>
<div class="col-sm-2 d-flex d-block">
<a class="btn btn-primary mx-auto" href="/advisor/customers/@CompanyId"><i class="bi-chevron-left"></i> Arbejdssteder</a>
</div>
</div>
<EditForm EditContext="FormContext" OnValidSubmit="SubmitWorkplace">
<DataAnnotationsValidator/>
<div class="row g-3 mb-3">
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="workplaceName" class="form-control" @bind-Value="Workplace.Name" placeholder="Navn for arbejdssted"/>
<label for="workplaceName">Navn for arbejdssted</label>
<ValidationMessage For="@(() => Workplace.Name)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="workplaceDescription" class="form-control" @bind-Value="Workplace.Description" placeholder="Kort beskrivelse"/>
<label for="workplaceDescription">Kort Beskrivelse</label>
<ValidationMessage For="@(() => Workplace.Description)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="eyeCleanerLocation" class="form-control" @bind-Value="Workplace.EyeCleanerLocation" placeholder="Øjenskylleflaske"/>
<label for="eyeCleanerLocation">Øjenskylleflaske</label>
<ValidationMessage For="@(() => Workplace.EyeCleanerLocation)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="firstAidStorage" class="form-control" @bind-Value="Workplace.FirstAidStorage" placeholder="Førstehjælp"/>
<label for="firstAidStorage">Førstehjælp</label>
<ValidationMessage For="@(() => Workplace.FirstAidStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="productStorage" class="form-control" @bind-Value="Workplace.ProductStorage" placeholder="Produkt opbevaring"/>
<label for="productStorage">Produkt Opbevaring</label>
<ValidationMessage For="@(() => Workplace.ProductStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="maskStorage" class="form-control" @bind-Value="Workplace.MaskStorage" placeholder="Maske opbevaring"/>
<label for="maskStorage">Maske Opbevaring</label>
<ValidationMessage For="@(() => Workplace.MaskStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="glovesStorage" class="form-control" @bind-Value="Workplace.GlovesStorage" placeholder="Handsker"/>
<label for="glovesStorage">Handsker</label>
<ValidationMessage For="@(() => Workplace.GlovesStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="gogglesStorage" class="form-control" @bind-Value="Workplace.GogglesStorage" placeholder="Beskyttelsesbriller"/>
<label for="gogglesStorage">Beskyttelsesbriller</label>
<ValidationMessage For="@(() => Workplace.GogglesStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="wasteDeposit" class="form-control" @bind-Value="Workplace.WasteDeposit" placeholder="Affald og Spild"/>
<label for="wasteDeposit">Affald og Spild</label>
<ValidationMessage For="@(() => Workplace.WasteDeposit)"></ValidationMessage>
</div>
</div>
</div>
<div class="card-body">
<EditForm EditContext="FormContext" OnValidSubmit="SubmitWorkplace">
<DataAnnotationsValidator/>
<table class="table">
<thead>
<tr>
<th class="align-middle" colspan="4">
<h3>Stamdata</h3>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle">Navn</td>
<td class="align-middle">
<InputText id="name" class="form-control" placeholder="plade, auto, klargøring, lab" @bind-Value="Workplace.Name"></InputText>
<ValidationMessage For="@(() => Workplace.Name)"></ValidationMessage>
</td>
<td class="align-middle">Beskrivelse</td>
<td class="align-middle">
<InputText id="description" class="form-control" placeholder="kort beskrivelse" @bind-Value="Workplace.Description"></InputText>
<ValidationMessage For="@(() => Workplace.Description)"></ValidationMessage>
</td>
</tr>
<tr>
<th class="align-middle" colspan="4">
<h3>Placering og Opbevaring</h3>
</th>
</tr>
<tr>
<td class="align-middle">Produkter</td>
<td class="align-middle">
<InputText id="productStorage" class="form-control" placeholder="produkt opbevaring" @bind-Value="Workplace.ProductStorage"></InputText>
<ValidationMessage For="@(() => Workplace.ProductStorage)"></ValidationMessage>
</td>
<td class="align-middle">Øjenskylleflaske</td>
<td class="align-middle">
<InputText id="eyeCleanerLocation" class="form-control" placeholder="placering af øjenskyller" @bind-Value="Workplace.EyeCleanerLocation"></InputText>
<ValidationMessage For="@(() => Workplace.EyeCleanerLocation)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Masker</td>
<td class="align-middle">
<InputText id="maskStorage" class="form-control" placeholder="maske opbevaring" @bind-Value="Workplace.MaskStorage"></InputText>
<ValidationMessage For="@(() => Workplace.MaskStorage)"></ValidationMessage>
</td>
<td class="align-middle">Førstehjælp</td>
<td class="align-middle">
<InputText id="firstAidStorage" class="form-control" placeholder="placering af førstehjælpskasse" @bind-Value="Workplace.FirstAidStorage"></InputText>
<ValidationMessage For="@(() => Workplace.FirstAidStorage)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Handsker</td>
<td class="align-middle">
<InputText id="glovesStorage" class="form-control" placeholder="placering af handsker" @bind-Value="Workplace.GlovesStorage"></InputText>
<ValidationMessage For="@(() => Workplace.GlovesStorage)"></ValidationMessage>
</td>
<td class="align-middle" colspan="2"></td>
</tr>
<tr>
<td class="align-middle">Sikkerhedsbriller</td>
<td class="align-middle">
<InputText id="gogglesStorage" class="form-control" placeholder="opbevaring beskyttelses briller" @bind-Value="Workplace.GogglesStorage"></InputText>
<ValidationMessage For="@(() => Workplace.GogglesStorage)"></ValidationMessage>
</td>
<td class="align-middle">Affald</td>
<td class="align-middle">
<InputText id="wasteDeposit" class="form-control" placeholder="deponering af affald og spild" @bind-Value="Workplace.WasteDeposit"></InputText>
<ValidationMessage For="@(() => Workplace.WasteDeposit)"></ValidationMessage>
</td>
</tr>
</tbody>
</table>
<div class="row mb-2">
<div class="col text-end">
<button type="submit" class="btn btn-success" disabled="@FormInvalid">Gem</button>
</div>
</div>
</EditForm>
<div class="row mb-5">
<div class="col-sm-4 d-flex">
<a class="btn btn-primary mx-auto" href="/advisor/customers/@CompanyId"><i class="bi-x-lg"></i> Fortryd</a>
</div>
<div class="col-sm-4 d-flex">
<button type="submit" class="btn btn-success mx-auto" disabled="@FormInvalid"><i class="bi-cloud-upload"></i> Gem</button>
</div>
</div>
</div>
</EditForm>

View file

@ -18,105 +18,139 @@
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}/workplaces/{WorkplaceId}"
<PageTitle>@Workplace.CompanyName - @Workplace.Name</PageTitle>
<div class="card">
<div class="card-header">
<div class="card-title">
<h2>@Workplace.CompanyName</h2>
<h3>@Workplace.Name @(!string.IsNullOrWhiteSpace(Workplace.Description) ? $"- {Workplace.Description}" : "")</h3>
</div>
<div class="row -mb-3">
<div class="col-sm-4">
<h2>@Workplace.CompanyName</h2>
</div>
<div class="card-body">
<EditForm EditContext="WorkplaceContext" OnValidSubmit="SubmitUpdate">
<table class="table">
<thead>
</thead>
<tbody>
<tr>
<td class="align-middle" colspan="4">
<h3>Stamdata</h3>
</td>
</tr>
<tr>
<td class="align-middle">Navn</td>
<td class="align-middle">
<InputText id="name" class="form-control" placeholder="plade, auto, klargøring, lab" @bind-Value="Workplace.Name"></InputText>
<ValidationMessage For="@(() => Workplace.Name)"></ValidationMessage>
</td>
<td class="align-middle">Beskrivelse</td>
<td class="align-middle">
<InputText id="description" class="form-control" placeholder="kort beskrivelse" @bind-Value="Workplace.Description"></InputText>
<ValidationMessage For="@(() => Workplace.Description)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle" colspan="4">
<h3>Placering og Opbevaring</h3>
</td>
</tr>
<tr>
<td class="align-middle">Produkter</td>
<td class="align-middle">
<InputText id="productStorage" class="form-control" placeholder="produkt opbevaring" @bind-Value="Workplace.ProductStorage"></InputText>
<ValidationMessage For="@(() => Workplace.ProductStorage)"></ValidationMessage>
</td>
<td class="align-middle">Øjenskylleflaske</td>
<td class="align-middle">
<InputText id="eyeCleanerLocation" class="form-control" placeholder="placering af øjenskyller" @bind-Value="Workplace.EyeCleanerLocation"></InputText>
<ValidationMessage For="@(() => Workplace.EyeCleanerLocation)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Masker</td>
<td class="align-middle">
<InputText id="maskStorage" class="form-control" placeholder="maske opbevaring" @bind-Value="Workplace.MaskStorage"></InputText>
<ValidationMessage For="@(() => Workplace.MaskStorage)"></ValidationMessage>
</td>
<td class="align-middle">Førstehjælp</td>
<td class="align-middle">
<InputText id="firstAidStorage" class="form-control" placeholder="placering af førstehjælpskasse" @bind-Value="Workplace.FirstAidStorage"></InputText>
<ValidationMessage For="@(() => Workplace.FirstAidStorage)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Handsker</td>
<td class="align-middle">
<InputText id="glovesStorage" class="form-control" placeholder="placering af handsker" @bind-Value="Workplace.GlovesStorage"></InputText>
<ValidationMessage For="@(() => Workplace.GlovesStorage)"></ValidationMessage>
</td>
<td class="align-middle" colspan="2"></td>
</tr>
<tr>
<td class="align-middle">Sikkerhedsbriller</td>
<td class="align-middle">
<InputText id="gogglesStorage" class="form-control" placeholder="opbevaring beskyttelses briller" @bind-Value="Workplace.GogglesStorage"></InputText>
<ValidationMessage For="@(() => Workplace.GogglesStorage)"></ValidationMessage>
</td>
<td class="align-middle">Affald</td>
<td class="align-middle">
<InputText id="wasteDeposit" class="form-control" placeholder="deponering af affald og spild" @bind-Value="Workplace.WasteDeposit"></InputText>
<ValidationMessage For="@(() => Workplace.WasteDeposit)"></ValidationMessage>
</td>
</tr>
</tbody>
</table>
<div class="row mb-2">
<div class="col-md-4">
<button type="button" class="btn btn-danger" onclick="@DeleteWorkplace">Slet</button>
</div>
<div class="col-md-4">
<button type="submit" class="btn btn-success">Gem</button>
</div>
<div class="col-md-4">
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces/@WorkplaceId/documents">Dokumenter</a>
</div>
</div>
</EditForm>
<div class="col-sm-4">
<h3>@Workplace.Name @(!string.IsNullOrWhiteSpace(Workplace.Description) ? $"- {Workplace.Description}" : "")</h3>
</div>
<div class="col-sm-2">
<a class="btn btn-primary" href="/advisor/customers/@CompanyId"><i class="bi-chevron-left"></i> Kundekort</a>
</div>
<div class="col-sm-2">
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces"><i class="bi-chevron-left"></i> Tilbage</a>
</div>
</div>
<EditForm EditContext="WorkplaceContext" OnValidSubmit="OnSubmitUpdate">
<div class="row g-1 mb-3">
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="workplaceName" class="form-control" @bind-Value="Workplace.Name" placeholder="Navn for arbejdssted"/>
<label for="workplaceName">Navn for arbejdssted</label>
<ValidationMessage For="@(() => Workplace.Name)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="workplaceDescription" class="form-control" @bind-Value="Workplace.Description" placeholder="Kort beskrivelse"/>
<label for="workplaceDescription">Kort Beskrivelse</label>
<ValidationMessage For="@(() => Workplace.Description)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="eyeCleanerLocation" class="form-control" @bind-Value="Workplace.EyeCleanerLocation" placeholder="Øjenskylleflaske"/>
<label for="eyeCleanerLocation">Øjenskylleflaske</label>
<ValidationMessage For="@(() => Workplace.EyeCleanerLocation)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="firstAidStorage" class="form-control" @bind-Value="Workplace.FirstAidStorage" placeholder="Førstehjælp"/>
<label for="firstAidStorage">Førstehjælp</label>
<ValidationMessage For="@(() => Workplace.FirstAidStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="productStorage" class="form-control" @bind-Value="Workplace.ProductStorage" placeholder="Produkt opbevaring"/>
<label for="productStorage">Produkt Opbevaring</label>
<ValidationMessage For="@(() => Workplace.ProductStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="maskStorage" class="form-control" @bind-Value="Workplace.MaskStorage" placeholder="Maske opbevaring"/>
<label for="maskStorage">Maske Opbevaring</label>
<ValidationMessage For="@(() => Workplace.MaskStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="glovesStorage" class="form-control" @bind-Value="Workplace.GlovesStorage" placeholder="Handsker"/>
<label for="glovesStorage">Handsker</label>
<ValidationMessage For="@(() => Workplace.GlovesStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="gogglesStorage" class="form-control" @bind-Value="Workplace.GogglesStorage" placeholder="Beskyttelsesbriller"/>
<label for="gogglesStorage">Beskyttelsesbriller</label>
<ValidationMessage For="@(() => Workplace.GogglesStorage)"></ValidationMessage>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-floating">
<InputText id="wasteDeposit" class="form-control" @bind-Value="Workplace.WasteDeposit" placeholder="Affald og Spild"/>
<label for="wasteDeposit">Affald og Spild</label>
<ValidationMessage For="@(() => Workplace.WasteDeposit)"></ValidationMessage>
</div>
</div>
<div class="col-sm-3 mt-3">
<button type="button" class="form-control btn btn-danger" @onclick="@OnConfirmDeleteWorkplace"><i class="bi-trash"></i> Slet</button>
</div>
<div class="col-sm-3 mt-3 text-end">
<button type="submit" class="form-control btn btn-success"><i class="bi-cloud-upload"></i> Gem</button>
</div>
</div>
</EditForm>
<ol class="list-group mb-3">
<li class="list-group-item">
<div class="row">
<div class="col-sm-10">
Produkt Liste
</div>
<div class="col-sm-2">
<button class="btn btn-primary btn-sm"><i class="bi-plus-lg"></i> Produkt(er)</button>
</div>
</div>
</li>
@if (WorkplaceInventory.Products.Any())
{
@foreach (var docView in DocViews)
{
<li class="list-group-item">
<div class="ms-2 me-auto">
<div class="fw-bold mb-1">@docView.VariantName.ToUpperInvariant()</div>
<div class="row">
<div class="col-sm-4">
<span class="me-3">APB</span><a class="btn btn-outline-dark btn-sm" href="@docView.ApbDocLink" target="_blank">@docView.ApbDocLink</a>
</div>
<div class="col-sm-4">
<span class="me-3">KAPV</span><a class="btn btn-outline-dark btn-sm" href="@docView.ApvDocLink" target="_blank">@docView.ApvDocLink</a>
</div>
<div class="col-sm-2">
@docView.DocumentDate
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm" @onclick="@(() => OnRemoveDocument(docView.ProductId, docView.VariantId))">
<i class="bi-trash"></i>
</button>
</div>
</div>
</div>
</li>
}
}
</ol>
@if (Working)
{
<WorkingThreeDots />
<WorkingThreeDots/>
}
<ConfirmDeleteModal BodyMessage="@DeleteMessage" OnOkClicked="OnDeleteWorkplace" @ref="ConfirmDelete" />

View file

@ -13,12 +13,15 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Client.Shared;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.Pages;
@ -28,8 +31,10 @@ public partial class AdvisorCustomerWorkplaceViewEditPage : IDisposable
// #############################################################
[Inject] public IAdvisorWorkplaceRepository Workplaces { get; set; }
[Inject] public IAdvisorCustomerRepository CustomerRepo { get; set; }
[Inject] public IAdvisorWorkplaceRepository WorkplaceRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILogger<AdvisorCustomerWorkplaceViewEditPage> Logger { get; set; }
// #############################################################
[Parameter] public string CompanyId { get; set; } = "";
@ -39,37 +44,108 @@ public partial class AdvisorCustomerWorkplaceViewEditPage : IDisposable
private WorkplaceDto Workplace { get; set; } = new();
private EditContext WorkplaceContext { get; set; }
private bool Working { get; set; } = true;
private WorkplaceInventory WorkplaceInventory { get; set; } = new();
private List<DocView> DocViews { get; set; } = new();
private ConfirmDeleteModal ConfirmDelete { get; set; }
private string DeleteMessage { get; set; } = "";
protected override async Task OnInitializedAsync()
{
WorkplaceContext = new EditContext(Workplace);
WorkplaceContext.OnFieldChanged += HandleFieldChanged;
WorkplaceContext.OnValidationStateChanged += ValidationChanged;
WorkplaceContext.OnFieldChanged += HandleFieldChanged!;
WorkplaceContext.OnValidationStateChanged += ValidationChanged!;
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
Workplace = await Workplaces.GetWorkplace(CompanyId, WorkplaceId);
WorkplaceInventory = await WorkplaceRepo.GetWorkplaceInventory(CompanyId, WorkplaceId);
DocViews = GenerateDocumentListView();
Working = false;
StateHasChanged();
DeleteMessage = $"Bekræft at du sletter<br/><strong>{Workplace.Name}</strong> fra <strong>{Workplace.CompanyName}</strong>?<br/>AL INFORMATION slettes og handlingen er uigenkaldelig.";
}
private async Task SubmitUpdate()
private async Task OnSubmitUpdate()
{
Working = true;
await Workplaces.UpdateWorkplace(CompanyId, Workplace);
Working = false;
}
private async Task DeleteWorkplace()
private void OnConfirmDeleteWorkplace()
{
Logger.LogDebug("ConfirmDeleteWorkplace");
ConfirmDelete.Show();
}
private async Task OnDeleteWorkplace()
{
Logger.LogDebug("DeleteWorkplace");
Working = true;
await Workplaces.DeleteWorkplace(CompanyId, Workplace.WorkplaceId);
await Workplaces.DeleteWorkplace(CompanyId, WorkplaceId);
Navigator.NavigateTo($"/advisor/customers/{CompanyId}/workplaces");
}
private async Task OnRemoveDocument(string productId, string variantId)
{
// delete the apb and apv
var product = WorkplaceInventory
.Products.First(x => x.ProductId == productId);
var variant = product.Variants.First(x => x.VariantId == variantId);
Logger.LogDebug("variant => {}", JsonSerializer.Serialize(variant, new JsonSerializerOptions(JsonSerializerDefaults.Web)));
foreach (var doc in variant.Docs)
{
await WorkplaceRepo.DeleteWorkplaceDocuments(CompanyId, WorkplaceId, doc.DocumentId);
}
WorkplaceInventory.Products.Remove(product);
DocViews = GenerateDocumentListView();
}
private List<DocView> GenerateDocumentListView()
{
var docViews = new List<DocView>();
var docProducts = WorkplaceInventory.Products.OrderBy(x => x.TradingName).ToList();
foreach (var product in docProducts)
{
foreach (var variant in product.Variants)
{
var newDoc = new DocView
{
ProductId = product.ProductId,
VariantId = variant.VariantId,
VariantName = variant.VariantName,
DocumentDate = variant.Docs[0].DocumentDate
};
var docs = variant.Docs.OrderBy(x => x.DocumentTypeEnum).ToList();
foreach (var doc in docs)
{
switch (doc.DocumentTypeEnum.ToLower())
{
case "apb":
newDoc.ApbDocLink = doc.DocumentLink;
newDoc.ApbDocId = doc.DocumentId;
break;
case "apv":
newDoc.ApvDocLink = doc.DocumentLink;
newDoc.ApvDocId = doc.DocumentId;
break;
}
}
docViews.Add(newDoc);
}
}
return docViews.OrderBy(x => x.VariantName).ToList();
}
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
@ -78,22 +154,23 @@ public partial class AdvisorCustomerWorkplaceViewEditPage : IDisposable
StateHasChanged();
}
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
WorkplaceContext.OnFieldChanged -= HandleFieldChanged;
WorkplaceContext.OnValidationStateChanged -= ValidationChanged;
WorkplaceContext.OnFieldChanged -= HandleFieldChanged!;
WorkplaceContext.OnValidationStateChanged -= ValidationChanged!;
WorkplaceContext = new EditContext(Workplace);
WorkplaceContext.OnFieldChanged += HandleFieldChanged;
WorkplaceContext.OnValidationStateChanged += ValidationChanged;
WorkplaceContext.OnFieldChanged += HandleFieldChanged!;
WorkplaceContext.OnValidationStateChanged += ValidationChanged!;
}
public void Dispose()
{
WorkplaceContext.OnFieldChanged += HandleFieldChanged;
WorkplaceContext.OnValidationStateChanged += ValidationChanged;
WorkplaceContext.OnFieldChanged += HandleFieldChanged!;
WorkplaceContext.OnValidationStateChanged += ValidationChanged!;
Interceptor.DisposeEvent();
}
}
}

View file

@ -0,0 +1,37 @@
@* Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header text-bg-danger">
<h2 class="modal-title">Bekræft Sletning</h2>
<button type="button" class="btn-close" onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
</div>
<div class="modal-body">
@((MarkupString)BodyMessage)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger me-auto" data-bs-dismiss="modal" onclick="@OkSelected"><i class="border-danger"></i> OK </button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="@CancelSelected"><i class="bi-x"></i> Afbryd </button>
</div>
</div>
</div>
</div>
@if (_showBackdrop)
{
<div class="modal-backdrop fade show"></div>
}

View file

@ -0,0 +1,57 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Shared;
public partial class ConfirmDeleteModal
{
private string _modalDisplay = "";
private bool _showBackdrop;
[Parameter] public string BodyMessage { get; set; } = "";
[Parameter] public EventCallback OnOkClicked { get; set; }
[Parameter] public EventCallback OnCancelClicked { get; set; }
private void OkSelected()
{
OnOkClicked.InvokeAsync();
Hide();
}
private void CancelSelected()
{
if (OnCancelClicked.HasDelegate)
{
OnCancelClicked.InvokeAsync();
}
Hide();
}
public void Show()
{
_modalDisplay = "block;";
_showBackdrop = true;
StateHasChanged();
}
public void Hide()
{
_modalDisplay = "none;";
_showBackdrop = false;
StateHasChanged();
}
}

View file

@ -1,58 +0,0 @@
{
"appInfo": {
"name": "Wonky Online",
"version": "138.15",
"rc": false,
"sandBox": false,
"image": "grumpy-coder.png"
},
"Logging": {
"LogLevel": {
"Default": "None",
"System": "None",
"Microsoft": "None"
},
"Debug": {
"LogLevel": {
"Default": "Critical"
}
}
},
"apiConfig": {
"baseUrl": "https://zeta.innotec.dk",
"catalog": "api/v2/catalog/country",
"crmCustomers": "api/v2/crm/companies",
"crmInventoryExt": "history/inventory",
"crmProductExt": "history/products",
"crmReports": "api/v2/crm/advisors/reports",
"crmActivities": "api/v2/crm/advisors/activities",
"crmTasks": "api/v2/crm/advisors/tasks",
"crmWorkplaceExt": "workplaces",
"officeBase": "api/v2/office",
"officeActivities": "api/v2/office/activities",
"officeAdvisors": "api/v2/office/users/advisors",
"officeCustomers": "api/v2/office/customers",
"officeReports": "api/v2/office/reports",
"officeUsers": "api/v2/office/users/admin",
"servicesGlsId": "",
"servicesGlsTrackUrl": "https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DK01/DA/5004.htm?txtAction=71000&txtRefNo=",
"servicesMail": "api/v2/services/sendmail",
"servicesSms": "api/v2/services/sms",
"servicesVatDk": "api/v2/services/virk",
"serviceVatEu": "api/v2/services/vies",
"servicesVatNo": "api/v2/services/brReg",
"servicesAuth": "v2/token",
"syncRpc": "api/v2/rpc",
"syncRpcInvoiceExt": "invoices",
"systemDocStringUrl": "api/v2/admin/doc",
"systemLabels": "api/v2/admin/doc/labels",
"systemTexts": "api/v2/admin/doc/texts",
"userInfoClient": "/api/v2/client/users",
"userInfoAuth": "api/v2/auth/userinfo",
"userManager": "api/v2/app/manage/users",
"userManagerSetPasswd": "api/v2/app/manage/passwd",
"userRoles": "api/v2/app/manage/roles",
"userSupport": "/api/v2/app/manage/support",
"warehouse": "api/v2/warehouse/packages"
}
}

View file

@ -43,6 +43,14 @@ a, .btn-link {
color: #ffaa00;
}
.inno-display {
display: block;
}
.inno-hidden {
display: none;
}
.content {
padding-top: 1.1rem;
}