FEAT add salesRep to office customer list

FEAT add streetName to office customer search component
FEAT customer product history -> item history
This commit is contained in:
Frede Hundewadt 2023-06-27 13:50:05 +02:00
parent a5a7c0893a
commit cb00711bbc
17 changed files with 668 additions and 465 deletions

View file

@ -29,7 +29,7 @@
{
[Inject] IOptions<AppInfo?>? AppInfo { get; set; }
private AppInfo? _app;
private bool _production = true;
// private bool _production = true;
protected override void OnInitialized()
{

View file

@ -19,67 +19,69 @@
@using Wonky.Client.OverlayOffice
@if (CompanyList.Any())
{
<div class="row d-flex g-3">
<div class="row mt-2 d-flex g-3">
@foreach (var company in CompanyList)
{
<div class="col-sm-6">
<div class="card">
<div class="card-header">
<span class="fw-bold">@company.Name</span>
@company.Name
</div>
<div class="card-body">
<div class="row">
<div class="col-sm-3 col-md-3 fw-bold">Sidst besøgt</div>
<div class="col-sm-3 col-md-3">@company.LastVisit <DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.MapVisitState(company.NextVisit))"/></div>
<div class="col-sm-3 col-md-3 fw-bold">Næste besøg</div>
<div class="col-sm-3 col-md-3">@company.NextVisit <DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.MapVisitState(company.NextVisit))"/></div>
</div>
</div>
@*
<div class="card-body">
<div class="row">
<div class="col">
<span class="">Sidst besøgt: @company.LastVisit</span>
</div>
<div class="col">
<span class="">Næste besøg: @company.NextVisit</span>
</div>
</div>
</div>
*@
<div class="card-body">
<div class="row">
<div class="col-sm-3 col-md-3 fw-bold">Konto</div>
<div class="col-sm-3 col-dm-3">@company.Account</div>
<div class="col-sm-3 col-md-3 fw-bold">Org Nr.</div>
<div class="col-sm-3 col-md-3">@company.VatNumber</div>
</div>
<div class="row">
<div class="col-sm-3 col-md-3 fw-bold">Telefon</div>
<div class="col-sm-9 col-md-9">@company.Phone</div>
</div>
<div class="row">
<div class="col-sm-3 col-md-3 fw-bold">Adresse</div>
<div class="col-sm-9 col-md-9">@company.Address1 @(string.IsNullOrWhiteSpace(company.Address2) ? "" : ",") @company.Address2</div>
</div>
<div class="row">
<div class="col-sm-3 col-md-3 fw-bold">Post By</div>
<div class="col-sm-9 col-md-9">@company.CountryCode.ToUpper()-@company.ZipCode @company.City</div>
</div>
<table class="table">
<tr>
<th scope="row">Konto</th>
<td>@company.Account</td>
<th scope="row">Org Nr.</th>
<td>@(string.IsNullOrWhiteSpace(@company.VatNumber) ? "~/~" : @company.VatNumber) </td>
</tr>
<tr>
<th scope="row">Telefon</th>
<td colspan="3">@company.Phone</td>
</tr>
<tr>
<th scope="row">Adresse</th>
<td colspan="3">@company.Address1 @(string.IsNullOrWhiteSpace(company.Address2) ? "" : ",") @company.Address2</td>
</tr>
<tr>
<th scope="row">Post By</th>
<td colspan="3">@company.CountryCode.ToUpper()-@company.ZipCode @company.City</td>
</tr>
<tr>
<th scope="row">
Sælgernr.
</th>
<td>
@company.SalesRep
</td>
</tr>
<tr>
<th scope="row">Sidst besøgt</th>
<td>
@company.LastVisit <DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.MapVisitState(company.NextVisit))"/>
</td>
</tr>
<tr>
<th scope="row">Næste besøg</th>
<td>
@company.NextVisit <DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.MapVisitState(company.NextVisit))"/>
</td>
</tr>
</table>
</div>
<div class="card-footer">
<div class="row">
<div class="col">
<button class="btn btn-danger" @onclick="@(() => ShowInvoiceList(company.CompanyId))">Faktura</button>
<button class="btn btn-sm btn-danger" @onclick="@(() => ShowInvoiceList(company.CompanyId))">Faktura</button>
</div>
<div class="col">
<button class="btn btn-warning" @onclick="@(() => ShowActivityList(company.CompanyId))">Aktivitet</button>
<button class="btn btn-sm btn-warning" @onclick="@(() => ShowActivityList(company.CompanyId))">Aktiviteter</button>
</div>
<div class="col">
<button class="btn btn-success" @onclick="@(() => ShowInventory(company.CompanyId))">Produkt</button>
<button class="btn btn-sm btn-success" @onclick="@(() => ShowInventory(company.CompanyId))">Produkter</button>
</div>
<div class="col">
<a class="btn btn-primary" href="/office/customers/@company.CountryCode.ToLower()/@company.CompanyId/order">Bestilling</a>
<a class="btn btn-sm btn-primary" href="/office/customers/@company.CountryCode.ToLower()/@company.CompanyId/order">Bestilling</a>
</div>
</div>
</div>
@ -87,9 +89,9 @@
</div>
}
</div>
<OfficeCustomerInvoiceListOverlay Company="@SelectedCompany" InvoiceList="@InvoiceList" @ref="InvoiceListOverlay"/>
<OfficeCustomerActivityListOverlay Company="SelectedCompany" ActivityList="ActivityList" @ref="ActivityListOverlay"/>
<OfficeCustomerListInventoryOverlay Company="SelectedCompany" Inventory="ProductList" @ref="InventoryListOverlay"/>
<OfficeCustomerInvoiceListOverlay Company="@SelectedCompany" InvoiceList="@InvoiceList" @ref="@InvoiceListOverlay"/>
<OfficeCustomerActivityListOverlay Company="@SelectedCompany" ActivityList="@ActivityList" @ref="@ActivityListOverlay"/>
<OfficeCustomerListInventoryOverlay Company="@SelectedCompany" Inventory="@ProductList" @ref="@InventoryListOverlay"/>
}
else
{

View file

@ -16,6 +16,7 @@
<select class="form-select bg-warning text-bg-warning" @bind-value="SearchCol" @bind-value:event="oninput" @onchange="@OnSelectionChanged">
<option value="-1" disabled>SØGNING</option>
<option value="name">Navn</option>
<option value="streetName">Vejnavn</option>
<option value="city">Bynavn</option>
<option value="zip">Postnr</option>
<option value="account">Konto</option>

View file

@ -86,7 +86,7 @@ public class HttpInterceptorService
if (e.Response == null || e.Response.IsSuccessStatusCode)
return;
var message = $"En fejl er opstået \n {JsonSerializer.Serialize(e)}";
var message = $"Status {e.Response.StatusCode}";
var currDoc = _navigation.ToBaseRelativePath(_navigation.Uri);
if (currDoc.Contains("login/"))
currDoc = "";
@ -115,6 +115,62 @@ public class HttpInterceptorService
_logger.LogDebug("InternalServerError <= {}", currDoc);
_logger.LogDebug("{}", message);
break;
case HttpStatusCode.Continue:
case HttpStatusCode.SwitchingProtocols:
case HttpStatusCode.Processing:
case HttpStatusCode.EarlyHints:
case HttpStatusCode.OK:
case HttpStatusCode.Created:
case HttpStatusCode.Accepted:
case HttpStatusCode.NonAuthoritativeInformation:
case HttpStatusCode.NoContent:
case HttpStatusCode.ResetContent:
case HttpStatusCode.PartialContent:
case HttpStatusCode.MultiStatus:
case HttpStatusCode.AlreadyReported:
case HttpStatusCode.IMUsed:
case HttpStatusCode.Ambiguous:
case HttpStatusCode.Moved:
case HttpStatusCode.Found:
case HttpStatusCode.RedirectMethod:
case HttpStatusCode.NotModified:
case HttpStatusCode.UseProxy:
case HttpStatusCode.Unused:
case HttpStatusCode.RedirectKeepVerb:
case HttpStatusCode.PermanentRedirect:
case HttpStatusCode.PaymentRequired:
case HttpStatusCode.Forbidden:
case HttpStatusCode.MethodNotAllowed:
case HttpStatusCode.NotAcceptable:
case HttpStatusCode.ProxyAuthenticationRequired:
case HttpStatusCode.RequestTimeout:
case HttpStatusCode.Gone:
case HttpStatusCode.LengthRequired:
case HttpStatusCode.PreconditionFailed:
case HttpStatusCode.RequestEntityTooLarge:
case HttpStatusCode.RequestUriTooLong:
case HttpStatusCode.UnsupportedMediaType:
case HttpStatusCode.RequestedRangeNotSatisfiable:
case HttpStatusCode.ExpectationFailed:
case HttpStatusCode.MisdirectedRequest:
case HttpStatusCode.UnprocessableEntity:
case HttpStatusCode.Locked:
case HttpStatusCode.FailedDependency:
case HttpStatusCode.UpgradeRequired:
case HttpStatusCode.PreconditionRequired:
case HttpStatusCode.TooManyRequests:
case HttpStatusCode.RequestHeaderFieldsTooLarge:
case HttpStatusCode.UnavailableForLegalReasons:
case HttpStatusCode.NotImplemented:
case HttpStatusCode.BadGateway:
case HttpStatusCode.ServiceUnavailable:
case HttpStatusCode.GatewayTimeout:
case HttpStatusCode.HttpVersionNotSupported:
case HttpStatusCode.VariantAlsoNegotiates:
case HttpStatusCode.InsufficientStorage:
case HttpStatusCode.LoopDetected:
case HttpStatusCode.NotExtended:
case HttpStatusCode.NetworkAuthenticationRequired:
default:
_logger.LogDebug("{}", message);
break;

View file

@ -0,0 +1,61 @@
@* 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 Wonky.Client.Components
@using Wonky.Client.Helpers
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
@* <div class="modal-dialog modal-dialog-scrollable modal-fullscreen-lg-down modal-xl modal-lg"> *@
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">@InventoryItem.Description @InventoryItem.Sku</h4>
<button type="button" class="btn btn-danger" @onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk"><i class="bi-x-lg"></i></button>
</div>
<div class="modal-body">
@if (InventoryItem.Discontinued)
{
<h3>Udgået produkt</h3>
}
@* product history ------------------------------------------------ *@
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Dato</th>
<th scope="col">Antal</th>
<th scope="col">Rabat</th>
<th scope="col">Pris</th>
</tr>
</thead>
<tbody>
@foreach (var entry in History)
{
<tr>
<td class="align-middle">@entry.DeliveryDate</td>
<td class="align-middle">@entry.Quantity</td>
<td class="align-middle">@entry.Discount</td>
<td class="align-middle">@entry.Price</td>
</tr>
}
</tbody>
</table>
@* end product history -------------------------------------------- *@
</div>
</div>
</div>
</div>
@if (_showBackdrop)
{
<div class="modal-backdrop fade show"></div>
}

View file

@ -0,0 +1,62 @@
// 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 System.Globalization;
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.OverlayOffice;
public partial class OfficeCustomerInventoryItemHistoryOverlay
{
// ##############################################################
[Parameter] public CompanyDto Company { get; set; }
[Parameter] public ProductInventoryItemView InventoryItem { get; set; } = new();
[Inject] public ICountryCustomerHistoryRepository HistoryRepo { get; set; }
// ##############################################################
private List<ProductHistoryView> History { get; set; } = new();
private string _productName = "";
private string _modalDisplay = "";
private bool _showBackdrop;
private bool ShowDraft { get; set; }
protected override async Task OnParametersSetAsync()
{
if (string.IsNullOrWhiteSpace(InventoryItem.Sku))
return;
History = await HistoryRepo.GetSkuHistory(Company.CountryCode, Company.CompanyId, InventoryItem.Sku);
}
public void Show()
{
_modalDisplay = "block;";
_showBackdrop = true;
StateHasChanged();
}
private void Hide()
{
_modalDisplay = "none;";
_showBackdrop = false;
StateHasChanged();
}
}

View file

@ -77,7 +77,7 @@
}
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-3">
<div class="position-relative">
@product.Description
@if (product.Discontinued)
@ -93,10 +93,14 @@
<div class="col-sm-2 text-center">
@product.Quantity
</div>
<div class="col-sm-2 text-center">
<button type="button" class="btn btn-primary" @onclick="@(() => ShowItem(product))"><i class="bi-clock-history"></i> Historik</button>
</div>
</div>
</div>
}
</div>
<OfficeCustomerInventoryItemHistoryOverlay Company="Company" InventoryItem="_selectedItem" @ref="@_itemHistoryOverlay" />
}
else
{

View file

@ -44,7 +44,8 @@ public partial class OfficeCustomerListInventoryOverlay
private string DisplayFilter { get; set; } = "";
private List<ProductInventoryItemView> DisplayList { get; set; } = new();
private SortColumn SortColumn { get; set; } = SortColumn.LastInvoiceDate;
private OfficeCustomerInventoryItemHistoryOverlay _itemHistoryOverlay = new();
private ProductInventoryItemView _selectedItem = new();
protected override void OnParametersSet()
{
@ -53,10 +54,16 @@ public partial class OfficeCustomerListInventoryOverlay
// initialize FilteredList
ApplyInventoryFilter(DisplayFilter);
Logger.LogDebug("OffCustListInvenOverlay {}", JsonSerializer.Serialize(DisplayList));
Logger.LogDebug("OfficeCustomerListInventoryOverlay {}", JsonSerializer.Serialize(DisplayList));
}
private void ShowItem(ProductInventoryItemView item)
{
_selectedItem = item;
_itemHistoryOverlay.Show();
}
private void SetSortOrder()
{
Descending = !Descending;

View file

@ -21,26 +21,12 @@
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}/activities/new"
<PageTitle>Ny aktivitet - @_company.Name</PageTitle>
<div class="row bg-dark text-white rounded-2 mb-2 py-2 align-items-center">
<div class="col">
<WorkDateComponent OnWorkDateChangedCallback="WorkDateChangedCallback"/>
</div>
</div>
@if (!string.IsNullOrWhiteSpace(_company.Blocked))
{
<div class="alert alert-danger">
<h4>Ring til kontoret. Denne konto er spærret med kode '@_company.Blocked'</h4>
</div>
}
<div class="row mb-2 bg-dark text-white rounded-3 p-3">
<div class="col">
<span class="h3">@_activity.Name</span> <span>(@_activity.Account)</span>
</div>
</div>
@if (ReportClosed)
{
<div class="row">
@ -51,299 +37,315 @@
}
else
{
<EditForm EditContext="_formContext">
<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>
}
else
{
<option value="">&rarr; TAG MIG &larr;</option>
<option value="onSite">Besøg</option>
<option value="phone">Telefon</option>
}
</InputSelect>
<ValidationMessage For="@(() => _activity.ActivityTypeEnum)"></ValidationMessage>
if (!string.IsNullOrWhiteSpace(_company.Name))
{
<PageTitle>Ny aktivitet - @_company.Name</PageTitle>
@if (!string.IsNullOrWhiteSpace(_company.Blocked))
{
<div class="alert alert-danger">
<h4>Ring til kontoret. Denne konto er spærret med kode '@_company.Blocked'</h4>
</div>
}
<div class="row mb-2 bg-dark text-white rounded-3 p-3">
<div class="col">
<span class="h3">@_activity.Name</span> <span>(@_activity.Account)</span>
</div>
</div>
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
<div class="col-sm-4">
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@_activity.ActivityStatusEnum">
@if (_kanvas)
{
<option selected value="canvas">Kanvas</option>
}
else
{
<option selected value="noSale">Ingen salg</option>
/*@if (!string.IsNullOrEmpty(_activity.VatNumber) && !string.IsNullOrWhiteSpace(_activity.Address1) && _company.HasFolded == 0)*/
@if (!string.IsNullOrWhiteSpace(_activity.VatNumber) && !string.IsNullOrWhiteSpace(_activity.Address1) && _company.HasFolded == 0)
<EditForm EditContext="_formContext">
<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)
{
@if (DraftProvider.Draft.DraftType == "order")
{
<option selected value="order">Bestilling</option>
}
else
{
<option value="order">Bestilling</option>
}
<option value="canvas" selected>Kanvas</option>
}
else
{
<option value="">&rarr; TAG MIG &larr;</option>
<option value="onSite">Besøg</option>
<option value="phone">Telefon</option>
}
</InputSelect>
<ValidationMessage For="@(() => _activity.ActivityTypeEnum)"></ValidationMessage>
</div>
@if (DraftProvider.Draft.DraftType == "quote")
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
<div class="col-sm-4">
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@_activity.ActivityStatusEnum">
@if (_kanvas)
{
<option selected value="canvas">Kanvas</option>
}
else
{
<option selected value="noSale">Ingen salg</option>
/*@if (!string.IsNullOrEmpty(_activity.VatNumber) && !string.IsNullOrWhiteSpace(_activity.Address1) && _company.HasFolded == 0)*/
@if (!string.IsNullOrWhiteSpace(_activity.VatNumber) && !string.IsNullOrWhiteSpace(_activity.Address1) && _company.HasFolded == 0)
{
<option selected value="quote">Tilbud</option>
}
else
{
<option value="quote">Tilbud</option>
@if (DraftProvider.Draft.DraftType == "order")
{
<option selected value="order">Bestilling</option>
}
else
{
<option value="order">Bestilling</option>
}
@if (DraftProvider.Draft.DraftType == "quote")
{
<option selected value="quote">Tilbud</option>
}
else
{
<option value="quote">Tilbud</option>
}
}
}
</InputSelect>
<ValidationMessage For="@(() => _activity.ActivityStatusEnum)"></ValidationMessage>
@if (_activity.ActivityStatusEnum == "order")
{
<div class="form-check">
<InputCheckbox id="express" class="form-check-input" @bind-Value="@_activity.Express"/>
<label class="form-check-label" for="express">Express</label>
</div>
}
</InputSelect>
<ValidationMessage For="@(() => _activity.ActivityStatusEnum)"></ValidationMessage>
@if (_activity.ActivityStatusEnum == "order")
</div>
@if (_kanvas)
{
<div class="form-check">
<InputCheckbox id="express" class="form-check-input" @bind-Value="@_activity.Express"/>
<label class="form-check-label" for="express">Express</label>
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
<div class="col-sm-10">
<InputText id="demo" class="form-control" @bind-Value="_activity.Demo"/>
<ValidationMessage For="@(() => _activity.Demo)"></ValidationMessage>
</div>
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
<div class="col-sm-10">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_activity.OrderMessage"/>
<ValidationMessage For="@(() => _activity.OrderMessage)"></ValidationMessage>
</div>
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
<div class="col-sm-10">
<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>
<div class="col-sm-4">
<InputText id="demo" class="form-control" @bind-Value="_activity.Demo"/>
<ValidationMessage For="@(() => _activity.Demo)"></ValidationMessage>
</div>
<label for="email" class="col-sm-2 col-form-label-sm">Epost</label>
<div class="col-sm-4">
<InputText id="email" class="form-control" @bind-Value="_activity.Email"/>
<ValidationMessage For="@(() => _activity.Email)"></ValidationMessage>
</div>
<label for="referenceNumber" class="col-sm-2 col-form-label-sm">Rekvisition</label>
<div class="col-sm-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="_activity.ReferenceNumber"/>
<ValidationMessage For="@(() => _activity.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-sm-2 col-form-label-sm">Indkøber</label>
<div class="col-sm-4">
<InputText id="yourRef" class="form-control" @bind-Value="_activity.YourRef"/>
<ValidationMessage For="@(() => _activity.YourRef)"></ValidationMessage>
</div>
<label for="attention" class="col-sm-2 col-form-label-sm">Att.</label>
<div class="col-sm-4">
<InputText id="attention" class="form-control" @bind-Value="_activity.Attention"/>
<ValidationMessage For="@(() => _activity.Attention)"></ValidationMessage>
</div>
<label for="phone" class="col-sm-2 col-form-label-sm">Tlf.</label>
<div class="col-sm-4">
<InputText id="phone" class="form-control" @bind-Value="_activity.Phone"/>
<ValidationMessage For="@(() => _activity.Phone)"></ValidationMessage>
</div>
<div class="col-sm-6"></div>
<label for="vatNumber" class="col-sm-2 col-form-label-sm">Cvr/Org nr.</label>
<div class="col-sm-2">
<InputText id="vatNumber" class="form-control" @bind-Value="_activity.VatNumber"/>
<ValidationMessage For="@(() => _activity.VatNumber)"/>
</div>
<div class="col-sm-2">
@if (_activity.CountryCode.ToLower() == "se")
{
<button type="button" class="btn btn-warning" @onclick="@TestOrgNumber">ORG Nr.</button>
}
</div>
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
<div class="col-sm-4">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_activity.OrderMessage"/>
<ValidationMessage For="@(() => _activity.OrderMessage)"></ValidationMessage>
</div>
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
<div class="col-sm-4">
<InputTextArea id="crmNote" class="form-control" @bind-Value="_activity.CrmNote"/>
<ValidationMessage For="@(() => _activity.CrmNote)"></ValidationMessage>
</div>
}
</div>
@if (_kanvas)
@if (!_kanvas)
{
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
<div class="col-sm-10">
<InputText id="demo" class="form-control" @bind-Value="_activity.Demo"/>
<ValidationMessage For="@(() => _activity.Demo)"></ValidationMessage>
</div>
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
<div class="col-sm-10">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_activity.OrderMessage"/>
<ValidationMessage For="@(() => _activity.OrderMessage)"></ValidationMessage>
</div>
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
<div class="col-sm-10">
<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>
<div class="col-sm-4">
<InputText id="demo" class="form-control" @bind-Value="_activity.Demo"/>
<ValidationMessage For="@(() => _activity.Demo)"></ValidationMessage>
</div>
<label for="email" class="col-sm-2 col-form-label-sm">Epost</label>
<div class="col-sm-4">
<InputText id="email" class="form-control" @bind-Value="_activity.Email"/>
<ValidationMessage For="@(() => _activity.Email)"></ValidationMessage>
</div>
<label for="referenceNumber" class="col-sm-2 col-form-label-sm">Rekvisition</label>
<div class="col-sm-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="_activity.ReferenceNumber"/>
<ValidationMessage For="@(() => _activity.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-sm-2 col-form-label-sm">Indkøber</label>
<div class="col-sm-4">
<InputText id="yourRef" class="form-control" @bind-Value="_activity.YourRef"/>
<ValidationMessage For="@(() => _activity.YourRef)"></ValidationMessage>
</div>
<label for="attention" class="col-sm-2 col-form-label-sm">Att.</label>
<div class="col-sm-4">
<InputText id="attention" class="form-control" @bind-Value="_activity.Attention"/>
<ValidationMessage For="@(() => _activity.Attention)"></ValidationMessage>
</div>
<label for="phone" class="col-sm-2 col-form-label-sm">Tlf.</label>
<div class="col-sm-4">
<InputText id="phone" class="form-control" @bind-Value="_activity.Phone"/>
<ValidationMessage For="@(() => _activity.Phone)"></ValidationMessage>
</div>
<div class="col-sm-6"></div>
<label for="vatNumber" class="col-sm-2 col-form-label-sm">Cvr/Org nr.</label>
<div class="col-sm-2">
<InputText id="vatNumber" class="form-control" @bind-Value="_activity.VatNumber"/>
<ValidationMessage For="@(() => _activity.VatNumber)"/>
</div>
<div class="col-sm-2">
@if (_activity.CountryCode.ToLower() == "se")
{
<button type="button" class="btn btn-warning" @onclick="@TestOrgNumber">ORG Nr.</button>
}
</div>
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
<div class="col-sm-4">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_activity.OrderMessage"/>
<ValidationMessage For="@(() => _activity.OrderMessage)"></ValidationMessage>
</div>
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
<div class="col-sm-4">
<InputTextArea id="crmNote" class="form-control" @bind-Value="_activity.CrmNote"/>
<ValidationMessage For="@(() => _activity.CrmNote)"></ValidationMessage>
</div>
}
</div>
@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="@ShowActivitiesOverlay">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="@ShowActivitiesOverlay">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" ? "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="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="@ShowPriceCatalogOverlay">
<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="@ShowPriceCatalogOverlay">
<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="card" id="crm_activity"> *@
@* Delivery address *@
<div class="card mb-3 @(_activity.ActivityStatusEnum == "order" ? "inno-display" : "inno-hidden")">
@ -387,47 +389,47 @@ else
</div>
</div>
</div>
}
</EditForm>
}
</EditForm>
<div class="row mb-2">
<div class="col-sm-6">
<a class="btn btn-warning" href="/advisor/customers/@_company.CompanyId"><i class="bi-chevron-left"></i> Stamkort</a>
</div>
<div class="col-sm-4 text-end">
@*
<div class="row mb-2">
<div class="col-sm-6">
<a class="btn btn-warning" href="/advisor/customers/@_company.CompanyId"><i class="bi-chevron-left"></i> Stamkort</a>
</div>
<div class="col-sm-4 text-end">
@*
***************** Confirm product check overlay button *****************************
***************** Continue by submitton order to erp *****************************
*@
<button type="button" class="btn btn-warning" @onclick="@ShowProductCheckOverlay" disabled="@(_formInvalid || Working)">
<i class="bi-cloud-arrow-up"></i> @ButtonText
</button>
<button type="button" class="btn btn-warning" @onclick="@ShowProductCheckOverlay" disabled="@(_formInvalid || Working)">
<i class="bi-cloud-arrow-up"></i> @ButtonText
</button>
</div>
</div>
</div>
<ProductHistoryOverlay CompanyId="@CompanyId" ItemSku="@_selectedItem.Sku" @ref="ProductOverlay"/>
<CatalogPagedOverlay CountryCode="@_company.CountryCode.ToLower()"
OnSelected="PriceCatalogOverlayCallback" @ref="CatalogOverlay"/>
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@_selectedItem.Sku"
OnSelected="PriceHistoryOverlayCallback" @ref="PriceOverlay"/>
<ConfirmCheckOverlay BodyMessage="" CompanyId="@CompanyId"
Products="_inventoryDrawer.Content"
OnOkClicked="ProductCheckOverlayCallback" @ref="ProductCheckOverlay"/>
<CustomerActivityListOverlay CompanyName="@_company.Name"
Activities="_activityDrawer.Content" @ref="ActivityListOverlay"/>
<CustomerInventoryListOverlay CompanyName="@_company.Name" CompanyId="@CompanyId" CountryCode="@_company.CountryCode"
Inventory="_inventoryDrawer.Content"
OnSelected="InventoryOverlayCallback" @ref="InventoryListOverlay"/>
<CustomerInvoiceListOverlay Company="_company"
Invoices="_invoiceDrawer.Content" @ref="InvoiceListOverlay"/>
}
}
<ConfirmWorkDateOverlay BodyMessage="@PromptDateConfirm"
<ConfirmWorkDateOverlay BodyMessage="@PromptDateConfirm"
OnOkClicked="WorkDateOverlayCallback" @ref="WorkDateOverlay"/>
<ProductHistoryOverlay CompanyId="@CompanyId" ItemSku="@_selectedItem.Sku" @ref="ProductOverlay"/>
<CatalogPagedOverlay CountryCode="@_company.CountryCode.ToLower()"
OnSelected="PriceCatalogOverlayCallback" @ref="CatalogOverlay"/>
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@_selectedItem.Sku"
OnSelected="PriceHistoryOverlayCallback" @ref="PriceOverlay"/>
<ConfirmCheckOverlay BodyMessage="" CompanyId="@CompanyId"
Products="_inventoryDrawer.Content"
OnOkClicked="ProductCheckOverlayCallback" @ref="ProductCheckOverlay"/>
<CustomerActivityListOverlay CompanyName="@_company.Name"
Activities="_activityDrawer.Content" @ref="ActivityListOverlay"/>
<CustomerInventoryListOverlay CompanyName="@_company.Name" CompanyId="@CompanyId" CountryCode="@_company.CountryCode"
Inventory="_inventoryDrawer.Content"
OnSelected="InventoryOverlayCallback" @ref="InventoryListOverlay"/>
<CustomerInvoiceListOverlay Company="_company"
Invoices="_invoiceDrawer.Content" @ref="InvoiceListOverlay"/>

View file

@ -104,6 +104,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
_userPref = await PreferenceService.GetProfile();
_salesRep = await UserInfo.GetUserInfo();
@ -190,14 +191,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
// raise flag if report is closed
ReportClosed = await ReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
// Ask for confirmation of date
// Logger.LogDebug("Preferences.DateConfirmed => {}", _userPref.DateConfirmed);
if (!_userPref.DateConfirmed)
{
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
WorkDateOverlay.Show();
}
// Lines may already have been added from the company inventory page
if (DraftProvider.Draft.DraftType == "order")
{
@ -218,7 +211,14 @@ public partial class AdvisorActivityCreatePage : IDisposable
Working = false;
// StateHasChanged();
// Ask for confirmation of date
Logger.LogDebug("Preferences.DateConfirmed => {}", _userPref.DateConfirmed);
if (!_userPref.DateConfirmed)
{
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
WorkDateOverlay.Show();
}
StateHasChanged();
}

View file

@ -17,20 +17,20 @@
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}"
<PageTitle>Stamkort for @_infoDrawer.Content.Name</PageTitle>
<PageTitle>Stamkort for @_company.Name</PageTitle>
@if (!string.IsNullOrWhiteSpace(_infoDrawer.Content.Account))
@if (!string.IsNullOrWhiteSpace(_company.Account))
{
@if (!string.IsNullOrWhiteSpace(_infoDrawer.Content.Blocked))
@if (!string.IsNullOrWhiteSpace(_company.Blocked))
{
<div class="alert alert-danger">
<h4>Ring til kontoret. Denne konto er spærret med kode '@_infoDrawer.Content.Blocked'</h4>
<h4>Ring til kontoret. Denne konto er spærret med kode '@_company.Blocked'</h4>
</div>
}
<div class="row pt-2 pb-2 mb-2 rounded rounded-2 bg-dark text-white">
<div class="col-sm-6">
<div class="mt-1">
<span class="h3">@_infoDrawer.Content.Name</span> <span>(@_infoDrawer.Content.Account)</span>
<span class="h3">@_company.Name</span> <span>(@_company.Account)</span>
</div>
</div>
<div class="col-sm-6 text-end">
@ -46,75 +46,74 @@
{
<a class="btn btn-secondary btn-sm me-2" href="/advisor/customers/@CompanyId/statistic" disabled="@(_company.Account.StartsWith("NY"))"><i class="bi-activity"></i> Statistik</a>
}
<button class="btn btn-secondary btn-sm me-2" @onclick="@ReloadHistory" disabled="@(_working || _company.Account.StartsWith("NY"))"><i class="bi-repeat"></i> Historik</button>
<button class="btn btn-secondary btn-sm me-2" @onclick="@(() => ReloadHistory(true))" disabled="@(_working || _company.Account.StartsWith("NY"))"><i class="bi-repeat"></i> Historik</button>
<a class="btn btn-primary btn-sm me-2" href="/advisor/customers"><i class="bi-chevron-left"></i> Tilbage</a>
</div>
</div>
// erp context
<EditForm EditContext="_erpContext">
<EditForm EditContext="_erpFormContext">
<DataAnnotationsValidator/>
<div class="row g-1">
@* Company Name *@
<label for="name" class="col-sm-1 col-form-label-sm">Navn</label>
<div class="col-sm-5">
<InputText id="name" class="form-control" @bind-Value="_infoDrawer.Content.Name" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Name)"></ValidationMessage>
<InputText id="name" class="form-control" @bind-Value="_company.Name" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Name)"></ValidationMessage>
</div>
@* Company Attention *@
<label for="attention" class="col-sm-1 col-form-label-sm">Att.</label>
<div class="col-sm-5">
<InputText id="attention" class="form-control" @bind-Value="_infoDrawer.Content.Attention" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Attention)"></ValidationMessage>
<InputText id="attention" class="form-control" @bind-Value="_company.Attention" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Attention)"></ValidationMessage>
</div>
@* Address 1 *@
<label for="address1" class="col-sm-1 col-form-label-sm">Adresse</label>
<div class="col-sm-5">
<InputText id="address1" class="form-control" @bind-Value="_infoDrawer.Content.Address1" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Address1)"></ValidationMessage>
<InputText id="address1" class="form-control" @bind-Value="_company.Address1" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Address1)"></ValidationMessage>
</div>
@* Address 2 *@
<label for="address2" class="col-sm-1 col-form-label-sm">Adresse</label>
<div class="col-sm-5">
<InputText id="address2" class="form-control" @bind-Value="_infoDrawer.Content.Address2" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Address2)"></ValidationMessage>
<InputText id="address2" class="form-control" @bind-Value="_company.Address2" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Address2)"></ValidationMessage>
</div>
@* Post Code *@
<label for="zipCode" class="col-sm-1 col-form-label-sm">PostNr</label>
<div class="col-sm-1">
<InputText id="zipCode" class="form-control" @bind-Value="_infoDrawer.Content.ZipCode" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.ZipCode)"></ValidationMessage>
<InputText id="zipCode" class="form-control" @bind-Value="_company.ZipCode" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.ZipCode)"></ValidationMessage>
</div>
@* City Name *@
<label for="city" class="col-sm-1 col-form-label-sm">Bynavn</label>
<div class="col-sm-3">
<InputText id="city" class="form-control" @bind-Value="_infoDrawer.Content.City" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.City)"></ValidationMessage>
<InputText id="city" class="form-control" @bind-Value="_company.City" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.City)"></ValidationMessage>
</div>
@* Email *@
<label for="email" class="col-sm-1 col-form-label-sm">Epost</label>
<div class="col-sm-5">
<InputText id="email" class="form-control" @bind-Value="_infoDrawer.Content.Email" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Email)"></ValidationMessage>
<InputText id="email" class="form-control" @bind-Value="_company.Email" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Email)"></ValidationMessage>
</div>
@* Phone *@
<label for="phone" class="col-sm-1 col-form-label-sm">Telefon</label>
<div class="col-sm-2">
<InputText id="phone" class="form-control" @bind-Value="_infoDrawer.Content.Phone" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Phone)"></ValidationMessage>
<InputText id="phone" class="form-control" @bind-Value="_company.Phone" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Phone)"></ValidationMessage>
</div>
@* Mobile *@
<label for="mobile" class="col-sm-1 col-form-label-sm">Mobil</label>
<div class="col-sm-2">
<InputText id="mobile" class="form-control" @bind-Value="_infoDrawer.Content.Mobile" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Mobile)"></ValidationMessage>
<InputText id="mobile" class="form-control" @bind-Value="_company.Mobile" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.Mobile)"></ValidationMessage>
</div>
@* Email *@
<label for="eanNumber" class="col-sm-1 col-form-label-sm">EAN</label>
<div class="col-sm-5">
<InputText id="eanNumber" class="form-control" @bind-Value="_infoDrawer.Content.EanNumber" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.EanNumber)"></ValidationMessage>
<InputText id="eanNumber" class="form-control" @bind-Value="_company.EanNumber" readonly="@(_erpEditDisabled)"/>
<ValidationMessage For="@(() => _company.EanNumber)"></ValidationMessage>
</div>
@if (!_kanvas)
@ -125,12 +124,12 @@
<label for="segment" class="col-sm-1 col-form-label-sm">Segment</label>
<div class="col-sm-2">
<InputSelect id="segment" class="form-select bg-warning text-bg-warning"
@bind-Value="@_infoDrawer.Content.Segment" disabled="@(_erpEditDisabled)">
@bind-Value="@_company.Segment" disabled="@(_erpEditDisabled)">
<option value="" disabled>segment</option>
<option value="1">AUTO</option>
<option value="2">INDUSTRI</option>
</InputSelect>
<ValidationMessage For="@(() => _infoDrawer.Content.Segment)"></ValidationMessage>
<ValidationMessage For="@(() => _company.Segment)"></ValidationMessage>
</div>
<div class="col-sm-1">
<div class="led-box @(DateTime.Now < DateTime.Parse("2023-12-31") ? "inno-display" : "inno-hidden")">
@ -154,7 +153,7 @@
</div>
@* Save erp data *@
<div class="col-sm-3 d-grid mx-auto">
<button type="button" class="btn btn-danger d-block" @onclick="@UpdateErpData" disabled="@(_working || _infoDrawer.Content.Name == "ERROR" || _erpEditDisabled)"><i class="bi-cloud-arrow-up"></i> STAM data </button>
<button type="button" class="btn btn-danger d-block" @onclick="@UpdateErpData" disabled="@(_working || _company.Name == "ERROR" || _erpEditDisabled)"><i class="bi-cloud-arrow-up"></i> STAM data </button>
</div>
@* vat number*@
<hr class="mb-3"/>
@ -164,8 +163,8 @@
<span class="input-group-text">
<DisplayStateComponent StateClass="@VatState"/>
</span>
<InputText id="vatNumber" class="form-control" @bind-Value="_infoDrawer.Content.VatNumber" readonly="@(_vatEditDisabled)"/>
<ValidationMessage For="@(() => _infoDrawer.Content.VatNumber)"></ValidationMessage>
<InputText id="vatNumber" class="form-control" @bind-Value="_company.VatNumber" readonly="@(_vatEditDisabled)"/>
<ValidationMessage For="@(() => _company.VatNumber)"></ValidationMessage>
</div>
</div>
@* Enable edit/save vatnumber *@
@ -183,7 +182,7 @@
<a class="btn btn-info" href="https://brreg.no/" target="_blank"><i class="bi-search"></i> brreg.no</a>
break;
case "se":
<a class="btn btn-info" href="https://www.allabolag.se/what/@_infoDrawer.Content.Name" target="_blank"><i class="bi-search"></i> allabolag.se</a>
<a class="btn btn-info" href="https://www.allabolag.se/what/@_company.Name" target="_blank"><i class="bi-search"></i> allabolag.se</a>
break;
}
</div>
@ -241,19 +240,19 @@
<div class="row mb-2">
<label for="note" class="col-sm-1 col-form-label-sm">OBS</label>
<div class="col-sm-8">
@if (string.IsNullOrWhiteSpace(_infoDrawer.Content.Note))
@if (string.IsNullOrWhiteSpace(_company.Note))
{
<InputText name="note" id="note" class="form-control" @bind-Value="_infoDrawer.Content.Note"/>
<InputText name="note" id="note" class="form-control" @bind-Value="_company.Note"/>
}
else
{
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="_infoDrawer.Content.Note"/>
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="_company.Note"/>
}
<ValidationMessage For="@(() => _infoDrawer.Content.Note)"></ValidationMessage>
<ValidationMessage For="@(() => _company.Note)"></ValidationMessage>
</div>
@* Save CRM data button *@
<div class="col-sm-3 d-grid mx-auto">
<button type="button" class="btn btn-warning" disabled="@(_infoDrawer.Content.Name == "ERROR")" @onclick="@PostCrmData"><i class="bi-cloud-arrow-up"></i> CRM data</button>
<button type="button" class="btn btn-warning" disabled="@(_company.Name == "ERROR")" @onclick="@PostCrmData"><i class="bi-cloud-arrow-up"></i> CRM data</button>
</div>
</div>
@* crm context - contacts *@
@ -309,14 +308,14 @@
</div>
<label for="interval" class="col-sm-2 col-form-label-sm">Uge Interval</label>
<div class="col-sm-2">
<InputNumber id="interval" class="form-control" @bind-Value="_infoDrawer.Content.Interval"/>
<ValidationMessage For="@(() => _infoDrawer.Content.Interval)"></ValidationMessage>
<InputNumber id="interval" class="form-control" @bind-Value="_company.Interval"/>
<ValidationMessage For="@(() => _company.Interval)"></ValidationMessage>
</div>
</div>
<div class="row mb-2">
<label for="crmNotes" class="col-sm-1 col-form-label-sm">Noter</label>
<div class="col-sm-11">
<InputTextArea id="crmNotes" class="form-control" @bind-Value="_infoDrawer.Content.CrmNotes"/>
<InputTextArea id="crmNotes" class="form-control" @bind-Value="_company.CrmNotes"/>
</div>
</div>
}
@ -340,8 +339,8 @@
<WorkingThreeDots/>
}
<VatLookupDkModal VatAddress="_companyVatAddress" EntityName="@_infoDrawer.Content.Name" VatNumber="@_infoDrawer.Content.VatNumber"
<VatLookupDkModal VatAddress="_companyVatAddress" EntityName="@_company.Name" VatNumber="@_company.VatNumber"
@ref="_vatLookupPopup" OnSelectedCompany="SelectedCompanyCallback"/>
<ContactViewEditModal SelectedContact="_selectedContact" CompanyName="@_infoDrawer.Content.Name"
<ContactViewEditModal SelectedContact="_selectedContact" CompanyName="@_company.Name"
@ref="_contactViewPopup" OnSaveClicked="WriteContactCallback" OnDeleteClicked="DeleteContactCallback"/>

View file

@ -38,14 +38,14 @@ namespace Wonky.Client.Pages;
public partial class AdvisorCustomerViewEditPage : IDisposable
{
// ###########################################################################
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ILogger<AdvisorCustomerViewEditPage> Logger { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public IAdvisorActivityRepository ActivityRepo { get; set; }
[Inject] public IAdvisorCustomerRepository CustomerRepo { get; set; }
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
[Inject] public IAdvisorCustomerRepository AdvisorCustomerRepo { get; set; }
[Inject] public IAdvisorCustomerHistoryRepository CustomerHistoryRepo { get; set; }
[Inject] public IAdvisorContactRepository ContactRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public VatInfoLookupService VatService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public IUserInfoService UserInfoService { get; set; }
@ -56,7 +56,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
[Parameter] public string CompanyId { get; set; } = "";
// ###########################################################################
private EditContext _erpContext;
private EditContext _erpFormContext;
private DateTime _lastVisit;
private DateTime _nextVisit;
private VatAddress _companyVatAddress = new();
@ -114,23 +114,19 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
/*
* setup form context
*/
_erpContext = new EditContext(_company);
/*
* assign event handlers to context
*/
_erpContext.OnFieldChanged += HandleFieldChanged;
_erpContext.OnValidationStateChanged += ValidationChanged!;
_erpFormContext = new EditContext(_company);
_erpFormContext.OnFieldChanged += HandleFieldChanged;
_erpFormContext.OnValidationStateChanged += ValidationChanged!;
/*
* fetch user info from local storage
*/
_userInfo = await UserInfoService.GetUserInfo();
_countryCode = _userInfo.CountryCode.ToLower();
_countryIsDk = _countryCode == "dk";
/*
* get InfoDrawer.Company from drawer
*/
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId, force:true);
_company = _infoDrawer.Content;
_company = await AdvisorCustomerRepo.GetCompanyById(CompanyId);
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId);
_infoDrawer.Content = _company;
await DrawerService.StoreInfoDrawerAsync(CompanyId, _infoDrawer);
/*
* internal _enableActivity flag
*/
@ -215,6 +211,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
{
_companyVatAddress = PrepareVatAddress(_company);
}
// await GetContacts(CompanyId);
}
/*
* remove loading image
@ -228,39 +225,43 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
if (firstRender)
{
await GetContacts(CompanyId);
_ = await DrawerService.GetActivityDrawerAsync(CompanyId);
_ = await DrawerService.GetActivityDrawerAsync(CompanyId, force:true);
if (!_company.Account.StartsWith("NY"))
{
_ = await HistoryRepo.RequestErpSync(CompanyId, _company.HistorySync, false);
_ = await DrawerService.GetInvoiceDrawerAsync(CompanyId);
_ = await DrawerService.GetInventoryDrawerAsync(CompanyId);
_ = await DrawerService.GetStatisticDrawerAsync(CompanyId);
await ReloadHistory();
}
}
}
private async Task ReloadHistory()
private async Task ReloadHistory(bool force = false)
{
Toaster.ShowInfo("Afventer svar fra tjenester ...");
if (force)
{
Toaster.ShowInfo("Afventer svar fra tjenester ...");
}
_enableLink = 0;
_enableActivity = 0;
_ = await DrawerService.GetActivityDrawerAsync(CompanyId, true);
var newSync = await HistoryRepo.RequestErpSync(CompanyId, _company.HistorySync, true);
var newSync = await CustomerHistoryRepo.RequestErpSync(CompanyId, _company.HistorySync, force);
await Task.Delay(500);
if (!string.IsNullOrWhiteSpace(newSync))
{
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId, true);
_company = _infoDrawer.Content;
_ = await DrawerService.GetInvoiceDrawerAsync(CompanyId, true);
_ = await DrawerService.GetInventoryDrawerAsync(CompanyId, true);
_ = await DrawerService.GetStatisticDrawerAsync(CompanyId, true);
if (!_company.Account.StartsWith("NY"))
{
_ = await DrawerService.GetInvoiceDrawerAsync(CompanyId, force);
_ = await DrawerService.GetInventoryDrawerAsync(CompanyId, force);
_ = await DrawerService.GetStatisticDrawerAsync(CompanyId, force);
}
_ = await DrawerService.GetActivityDrawerAsync(CompanyId, force);
}
_enableLink = 1;
_enableActivity = _company.ValidVat;
// StateHasChanged();
Toaster.ShowSuccess("Alle tjenester har svaret.");
StateHasChanged();
if (force)
{
Toaster.ShowSuccess("Alle tjenester har svaret.");
}
}
@ -286,7 +287,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
/*
* send update reqeust
*/
await CustomerRepo.UpdateCrmData(CompanyId, _company);
await AdvisorCustomerRepo.UpdateCrmData(CompanyId, _company);
}
@ -429,7 +430,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
_company.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
_company.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
_company.IsHidden = 0;
var result = await CustomerRepo.UpdateCrmData(CompanyId, _company);
var result = await AdvisorCustomerRepo.UpdateCrmData(CompanyId, _company);
if (!string.IsNullOrWhiteSpace(result.CompanyId))
{
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId, true);
@ -451,7 +452,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
_erpEditDisabled = true;
_working = true;
Toaster.ShowInfo("Vent venligst ...");
var result = await CustomerRepo.UpdateErpData(CompanyId, _company);
var result = await AdvisorCustomerRepo.UpdateErpData(CompanyId, _company);
if (!string.IsNullOrWhiteSpace(result.CompanyId))
{
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId, true);
@ -486,7 +487,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
_working = true;
_vatEditDisabled = true;
Toaster.ShowInfo("Vent venligst ...");
var result = await CustomerRepo.UpdateCompanyVat(CompanyId, _company.VatNumber);
var result = await AdvisorCustomerRepo.UpdateCompanyVat(CompanyId, _company.VatNumber);
if (!string.IsNullOrWhiteSpace(result.CompanyId))
{
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId, true);
@ -576,13 +577,13 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
*/
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
_erpContext.OnFieldChanged -= HandleFieldChanged;
_erpContext.OnValidationStateChanged -= ValidationChanged!;
_erpFormContext.OnFieldChanged -= HandleFieldChanged;
_erpFormContext.OnValidationStateChanged -= ValidationChanged!;
_erpContext = new EditContext(_company);
_erpFormContext = new EditContext(_company);
_erpContext.OnFieldChanged += HandleFieldChanged;
_erpContext.OnValidationStateChanged += ValidationChanged!;
_erpFormContext.OnFieldChanged += HandleFieldChanged;
_erpFormContext.OnValidationStateChanged += ValidationChanged!;
}
@ -592,7 +593,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
public void Dispose()
{
Interceptor.DisposeEvent();
_erpContext.OnFieldChanged -= HandleFieldChanged;
_erpContext.OnValidationStateChanged -= ValidationChanged!;
_erpFormContext.OnFieldChanged -= HandleFieldChanged;
_erpFormContext.OnValidationStateChanged -= ValidationChanged!;
}
}

View file

@ -1,7 +1,7 @@
{
"appInfo": {
"name": "Wonky Online",
"version": "173.0",
"version": "177.1",
"rc": true,
"sandBox": true,
"image": "grumpy-coder.png",
@ -11,7 +11,7 @@
"LogLevel": {
"Default": "Debug",
"System": "Debug",
"Microsoft": "None"
"Microsoft": "Information"
},
"Debug": {
"LogLevel": {

View file

@ -17,7 +17,7 @@
<link href="/css/20230614.css" rel="stylesheet" >
<link href="/css/print.css" rel="stylesheet" >
<link href="/Wonky.Client.styles.css" rel="stylesheet" >
<link href="/_content/Blazored.Toast/blazored-toast.min.css" rel="stylesheet" >
<link href="/_content/Blazored.Toast/Blazored.Toast.bundle.scp.css" rel="stylesheet" >
</head>
<body>
<div id="app">

View file

@ -10,13 +10,15 @@ FOLDER="alpha-client"
sed -i "s|\"version\".*|\"version\": \"$1\",|g" "${FILE}"
sed -i 's|\"rc\".*|\"rc\": false,|g' "${FILE}"
sed -i 's|\"sandbox\".*|\"sandbox\": true,|g' "${FILE}"
sed -i 's|\"sandBox\".*|\"sandBox\": true,|g' "${FILE}"
sed -i 's|\"Default": \"None\",|\"Default": \"Debug\",|g' "${FILE}"
sed -i 's|\"System": \"None\",|\"System": \"Debug\",|g' "${FILE}"
sed -i 's|\"Microsoft\": \"None\",|\"Microsoft\": \"Information\",|g' "${FILE}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://eta.innotec.dk\",|g' "${FILE}"
dotnet clean
dotnet publish -c release
cp --recursive /a/projects/inno/a/Wonky.Client/Wonky.Client/bin/Release/net7.0/publish/* "/a/projects/inno/version-sync/${FOLDER}"

View file

@ -10,22 +10,25 @@ FOLDER="eta-${1}"
sed -i "s|\"version\".*|\"version\": \"${1}\",|g" "${FILE}"
sed -i 's|\"rc\".*|\"rc\": true,|g' "${FILE}"
sed -i 's|\"sandbox\".*|\"sandbox\": true,|g' "${FILE}"
sed -i 's|\"sandBox\".*|\"sandBox\": true,|g' "${FILE}"
sed -i 's|\"Default": \"Debug\",|\"Default": \"None\",|g' "${FILE}"
sed -i 's|\"System": \"Debug\",|\"System": \"None\",|g' "${FILE}"
sed -i 's|\"Microsoft\": \"Information\",|\"Microsoft\": \"None\",|g' "${FILE}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://eta.innotec.dk\",|g' "${FILE}"
dotnet clean
dotnet publish -c release
cp --recursive "/a/projects/inno/a/Wonky.Client/Wonky.Client/bin/Release/net7.0/publish" "/a/projects/inno/version-sync/client/${FOLDER}"
cp --recursive /a/projects/inno/a/Wonky.Client/Wonky.Client/bin/Release/net7.0/publish/ "/a/projects/inno/version-sync/client/${FOLDER}"
# RESET TO DEVELOPMENT
sed -i 's|\"sandbox\".*|\"sandbox\": true,|g' "${FILE}"
sed -i 's|\"sandBox\".*|\"sandBox\": true,|g' "${FILE}"
sed -i 's|\"Default": \"None\",|\"Default": \"Debug\",|g' "${FILE}"
sed -i 's|\"System": \"None\",|\"System": \"Debug\",|g' "${FILE}"
sed -i 's|\"Microsoft\": \"None\",|\"Microsoft\": \"Information\",|g' "${FILE}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://eta.innotec.dk\",|g' "${FILE}"

View file

@ -10,22 +10,25 @@ FOLDER="zeta-${1}"
sed -i "s|\"version\":.*|\"version\": \"$1\",|g" "${FILE}"
sed -i 's|\"rc\":.*|\"rc\": true,|g' "${FILE}"
sed -i 's|\"sandbox\":.*|\"sandbox\": false,|g' "${FILE}"
sed -i 's|\"sandBox\":.*|\"sandBox\": false,|g' "${FILE}"
sed -i 's|\"Default": \"Debug\",|\"Default": \"None\",|g' "${FILE}"
sed -i 's|\"System": \"Debug\",|\"System": \"None\",|g' "${FILE}"
sed -i 's|\"Microsoft\": \"Information\",|\"Microsoft\": \"None\",|g' "${FILE}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://zeta.innotec.dk\",|g' "${FILE}"
dotnet clean
dotnet publish -c release
cp --recursive "/a/projects/inno/a/Wonky.Client/Wonky.Client/bin/Release/net7.0/publish" "/a/projects/inno/version-sync/client/${FOLDER}"
cp --recursive /a/projects/inno/a/Wonky.Client/Wonky.Client/bin/Release/net7.0/publish/ "/a/projects/inno/version-sync/client/${FOLDER}"
# RESET TO DEVELOPMENT
sed -i 's|\"sandbox\".*|\"sandbox\": true,|g' "${FILE}"
sed -i 's|\"sandBox\".*|\"sandBox\": true,|g' "${FILE}"
sed -i 's|\"Default": \"None\",|\"Default": \"Debug\",|g' "${FILE}"
sed -i 's|\"System": \"None\",|\"System": \"Debug\",|g' "${FILE}"
sed -i 's|\"Microsoft\": \"None\",|\"Microsoft\": \"Information\",|g' "${FILE}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://eta.innotec.dk\",|g' "${FILE}"