misc cosmetic changes
office customer list office customer list added isHidden = 1 to custom page filter office create order added salesRep name draft - added property to use for enabling disabling submit button B2B page work
This commit is contained in:
parent
a03d23192a
commit
eb518b3429
19 changed files with 302 additions and 126 deletions
|
@ -44,6 +44,8 @@
|
|||
}
|
||||
<div class="card-body mx-0">
|
||||
<table class="m-0 table table-sm table-striped table-light">
|
||||
<thead></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" class="text-sm-start align-middle">Konto</th>
|
||||
<td class="text-sm-start align-middle">@company.Account</td>
|
||||
|
@ -64,7 +66,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="text-sm-start align-middle">
|
||||
Sælgernr.
|
||||
Sælger Nr.
|
||||
</th>
|
||||
<td colspan="3" class="text-sm-start align-middle">
|
||||
@company.SalesRep
|
||||
|
@ -72,9 +74,10 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="text-sm-start align-middle">Sidst besøgt</th>
|
||||
<td colspan="3" class="text-sm-start align-middle">
|
||||
<td class="text-sm-start align-middle">
|
||||
@(Mapper.MapVisitState(company.LastVisit) == "the-draw" ? "?" : company.LastVisit)
|
||||
</td>
|
||||
<td colspan="2" class="text-sm-end fw-bold align-middle">@(company.IsHidden == 1 ? "Skjult af sælger." : "")</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" class="text-sm-start align-middle">Næste besøg</th>
|
||||
|
@ -86,12 +89,13 @@
|
|||
<button class="btn btn-sm btn-secondary w-100" @onclick="() => RequestBusinessCentralData(company.CompanyId, true)"><i class="bi-arrow-repeat"></i> BC</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<div class="px-1 col-sm-3">
|
||||
<button class="btn btn-sm btn-danger w-100" @onclick="@(() => ShowInvoiceList(company.CompanyId))"> Salg</button>
|
||||
<button class="btn btn-sm btn-danger w-100" @onclick="@(() => ShowInvoiceList(company.CompanyId))"> Salg</button>
|
||||
</div>
|
||||
<div class="px-1 col-sm-3">
|
||||
<button class="btn btn-sm btn-warning w-100" @onclick="@(() => ShowActivityList(company.CompanyId))">Aktivitet</button>
|
||||
|
|
12
Wonky.Client/Extensions/JsInteropExtenstions.cs
Normal file
12
Wonky.Client/Extensions/JsInteropExtenstions.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Wonky.Client.Extensions;
|
||||
|
||||
public static class JsInteropExtensions
|
||||
{
|
||||
public static ValueTask SetFocusAsync(this IJSRuntime jsRuntime, ElementReference elementReference)
|
||||
{
|
||||
return jsRuntime.InvokeVoidAsync("FormFocusElement", elementReference);
|
||||
}
|
||||
}
|
|
@ -22,12 +22,13 @@ public class Draft
|
|||
{
|
||||
public string DraftId { get; set; } = "";
|
||||
public string DraftType { get; set; } = "noSale";
|
||||
public bool Invalid => Items.Count == 0;
|
||||
public List<DraftItem> Items { get; set; } = new ();
|
||||
public decimal Total
|
||||
{
|
||||
get
|
||||
{
|
||||
return Items.Sum(item => item.LineTotal);
|
||||
return Items.Sum(item => item.LineSum);
|
||||
}
|
||||
}
|
||||
public DateTime LastAccessed { get; set; }
|
||||
|
|
|
@ -22,10 +22,10 @@ namespace Wonky.Client.Models;
|
|||
/// </summary>
|
||||
public class DraftItem
|
||||
{
|
||||
public int Quantity { get; set; }
|
||||
public SalesItemView Item { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public decimal Discount { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
public decimal LineSum => (Price - Price * Discount / 100) * Quantity;
|
||||
public bool Sas { get; set; }
|
||||
public decimal LineTotal => (Price - Price * Discount / 100) * Quantity;
|
||||
public SalesItemView Item { get; set; } = new();
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Faktura @Invoice.DocumentNumber</h3>
|
||||
<h3 class="modal-title">Salgsinfo @Invoice.DocumentNumber</h3>
|
||||
<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">
|
||||
|
@ -98,7 +98,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<span>Ingen data</span>
|
||||
<div class="alert alert-info">Ingen data</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -287,7 +287,7 @@ else
|
|||
<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-end">@($"{cartItem.LineSum:N2}")</td>
|
||||
<td class="align-middle text-center">
|
||||
<input type="checkbox" checked="@cartItem.Sas" disabled/>
|
||||
</td>
|
||||
|
|
|
@ -474,7 +474,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
{
|
||||
Price = item.Price,
|
||||
Discount = item.Discount,
|
||||
LineAmount = item.LineTotal,
|
||||
LineAmount = item.LineSum,
|
||||
Qty = item.Quantity,
|
||||
Sku = item.Item.Sku,
|
||||
Text = item.Item.Name,
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
<a class="btn btn-primary" href="@Workplace.ShortUrl" target="_blank"><i class="bi-list-ul"></i> Vis QR-koder</a>
|
||||
</div>
|
||||
<div class="col-sm-3 text-end">
|
||||
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces/@WorkplaceId/documents/new"><i class="bi-pencil-square"></i> Revision</a>
|
||||
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces/@WorkplaceId/documents/new"><i class="bi-pencil-square"></i> Tilføj Produkt(er)</a>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="input-group">
|
||||
|
@ -174,7 +174,7 @@
|
|||
@docView.DocumentDate
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<img class="img-fluid img-thumbnail" src="@(docView.PictureLink)?height=100"
|
||||
<img class="img-fluid img-thumbnail" src="@(docView.PictureLink)?height=100" alt="produkt-billede"
|
||||
onerror="this.onerror=null;this.src='@(_config.AssetUrl)/images/no-image.png?height=100'"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -182,6 +182,10 @@
|
|||
</li>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="alert alert-info"><h3>Ingen dokumenter oprettet.</h3></div>
|
||||
}
|
||||
</ol>
|
||||
|
||||
<div class="row mb-5">
|
||||
|
|
|
@ -16,3 +16,59 @@
|
|||
@attribute [Authorize(Roles = "EShop")]
|
||||
@page "/b2b/{countryCode}/{companyId}/order/new"
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Bestilling
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text">
|
||||
<div class="row">
|
||||
<div class="col h5">
|
||||
@_businessInfo.Name
|
||||
</div>
|
||||
<div class="col">
|
||||
<i class="bi-card-heading"></i> @_businessInfo.Account
|
||||
</div>
|
||||
<div class="col">
|
||||
<i class="bi-phone"></i> @_businessInfo.Phone
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text">
|
||||
@Activity.DlvAddress1, @Activity.DlvAddress2
|
||||
</div>
|
||||
<div class="card-text">
|
||||
@CountryCode.ToUpper()-@Activity.DlvZipCode @Activity.DlvCity
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Vare No.
|
||||
</div>
|
||||
<div class="col">
|
||||
Beskrivelse
|
||||
</div>
|
||||
<div class="col">
|
||||
Antal
|
||||
</div>
|
||||
</div>
|
||||
@foreach (var item in DraftProvider.Draft.Items)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@item.Item.Sku
|
||||
</div>
|
||||
<div class="col">
|
||||
@item.Item.Name
|
||||
</div>
|
||||
<div class="col">
|
||||
@item.Quantity
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,6 @@
|
|||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using Blazored.Toast.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -25,6 +26,7 @@ public partial class BusinessOrderViewPage
|
|||
[Inject] public ICountryPriceCatalogRepository PriceCatalog { get; set; }
|
||||
[Inject] public IOptions<ApiConfig> Config { get; set; }
|
||||
[Inject] public IUserInfoService UserInfoService { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
|
||||
// ##############################################################
|
||||
[CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new();
|
||||
|
@ -34,12 +36,7 @@ public partial class BusinessOrderViewPage
|
|||
// ##############################################################
|
||||
private UserManagerEditView UserInfo { get; set; } = new();
|
||||
private B2BBusinessInfo _businessInfo = new();
|
||||
private B2BAdvisorInfo _advisorInfo = new();
|
||||
private List<ProductHistoryView> _productHistory = new();
|
||||
private List<ProductInventoryItemView> _productInventory = new();
|
||||
private ApiConfig _config = new();
|
||||
private B2BProductPriceHistoryOverlay PriceHistoryOverlay { get; set; }
|
||||
private ItemSelect _selectedItem = new();
|
||||
private ActivityDto Activity { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
||||
private bool Working { get; set; } = true;
|
||||
|
@ -52,6 +49,7 @@ public partial class BusinessOrderViewPage
|
|||
|
||||
// get info for logged in user
|
||||
UserInfo = await UserInfoService.GetUserInfo();
|
||||
_businessInfo = await B2BRepo.GetBusinessInfo(CompanyId);
|
||||
|
||||
SelectedDate = DateTime.Now;
|
||||
var today = $"{SelectedDate:yyyy-MM-dd}";
|
||||
|
@ -62,34 +60,147 @@ public partial class BusinessOrderViewPage
|
|||
Activity.ActivityStatusEnum = "order";
|
||||
Activity.Express = true;
|
||||
Activity.OurRef = $"WEB:{UserInfo.FirstName}";
|
||||
// get sales rep info
|
||||
// SalesRep = await UserRepo.GetUserInfo(Company.SalesRepId);
|
||||
// Logger.LogDebug("OfficeOrderCreate => SalesRep => {}", JsonSerializer.Serialize(SalesRep));
|
||||
// assign salesRep and countryCode to activity
|
||||
// Activity.SalesRep = _advisorInfo.SalesRep;
|
||||
// Activity.CountryCode = SalesRep.CountryCode;
|
||||
// Activity.SalesRepId = Company.SalesRepId;
|
||||
Activity.SalesRep = _businessInfo.SalesRep;
|
||||
Activity.CountryCode = _businessInfo.CountryCode;
|
||||
Activity.SalesRepId = _businessInfo.AdvisorId;
|
||||
// assign customer info into activity properties
|
||||
// Activity.Account = Company.Account;
|
||||
// Activity.VatNumber = Company.VatNumber;
|
||||
// Activity.Email = Company.Email;
|
||||
// Activity.Phone = Company.Phone;
|
||||
// Activity.Mobile = Company.Mobile;
|
||||
// Activity.Name = Company.Name;
|
||||
// Activity.Address1 = Company.Address1;
|
||||
// Activity.Address2 = Company.Address2;
|
||||
// Activity.ZipCode = Company.ZipCode;
|
||||
// Activity.City = Company.City;
|
||||
// Activity.DlvName = Company.Name;
|
||||
// Activity.DlvAddress1 = Company.Address1;
|
||||
// Activity.DlvAddress2 = Company.Address2;
|
||||
// Activity.DlvZipCode = Company.ZipCode;
|
||||
// Activity.DlvCity = Company.City;
|
||||
// Activity.BcId = Company.BcId;
|
||||
// Activity.CompanyId = Company.CompanyId;
|
||||
Activity.Account = _businessInfo.Account;
|
||||
Activity.VatNumber = _businessInfo.VatNumber;
|
||||
Activity.Email = _businessInfo.Email;
|
||||
Activity.Phone = _businessInfo.Phone;
|
||||
Activity.Mobile = _businessInfo.Mobile;
|
||||
Activity.Name = _businessInfo.Name;
|
||||
Activity.Address1 = _businessInfo.Address1;
|
||||
Activity.Address2 = _businessInfo.Address2;
|
||||
Activity.ZipCode = _businessInfo.ZipCode;
|
||||
Activity.City = _businessInfo.City;
|
||||
Activity.DlvName = _businessInfo.Name;
|
||||
Activity.DlvAddress1 = _businessInfo.Address1;
|
||||
Activity.DlvAddress2 = _businessInfo.Address2;
|
||||
Activity.DlvZipCode = _businessInfo.ZipCode;
|
||||
Activity.DlvCity = _businessInfo.City;
|
||||
Activity.BcId = _businessInfo.BcId;
|
||||
Activity.CompanyId = _businessInfo.CompanyId;
|
||||
// assign activity properties
|
||||
|
||||
// var lineNo = 0;
|
||||
// foreach (var item in DraftProvider.Draft.Items)
|
||||
// {
|
||||
// lineNo += 1;
|
||||
// Activity.Lines.Add(new ActivityLineDto()
|
||||
// {
|
||||
// Discount = item.Discount,
|
||||
// Price = item.Price,
|
||||
// Qty = item.Quantity,
|
||||
// LineAmount = item.LineSum,
|
||||
// LineNumber = lineNo,
|
||||
// ShortName = item.Item.ShortName,
|
||||
// Sku = item.Item.Sku,
|
||||
// Text = item.Item.Name,
|
||||
// Location = item.Item.Location,
|
||||
// Sas = item.Sas
|
||||
// });
|
||||
// }
|
||||
|
||||
Working = false;
|
||||
}
|
||||
|
||||
private async Task CreateActivity()
|
||||
{
|
||||
// avoid duplication
|
||||
if (Working)
|
||||
return;
|
||||
// validate customer address1
|
||||
// - this is a required input
|
||||
// --- exclude for office orders
|
||||
// if (string.IsNullOrWhiteSpace(Activity.Address1))
|
||||
// {
|
||||
// Toaster.ShowError("Kunde adresse er ufuldstændig.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// validate org number
|
||||
// - this is a required input
|
||||
// - must validate according to country rules.
|
||||
// --- exclude for office orders
|
||||
// if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
|
||||
// {
|
||||
// Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // validate input according to status
|
||||
// switch (Activity.ActivityStatusEnum)
|
||||
// {
|
||||
// // don't accept order with no lines
|
||||
// case "order" when DraftProvider.Draft.Items.Count == 0:
|
||||
// Toaster.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
|
||||
// return;
|
||||
// // phone number is required if first time customer
|
||||
// case "order" when Company.Account.StartsWith("NY") && string.IsNullOrWhiteSpace(Activity.Phone):
|
||||
// Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
|
||||
// return;
|
||||
// // verify email address is a valid address
|
||||
// // --- exclude for office orders
|
||||
// // case "quote" when !Utils.IsValidEmail(Activity.Email):
|
||||
// // Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
|
||||
// // return;
|
||||
// }
|
||||
|
||||
// raise working flag
|
||||
Working = true;
|
||||
|
||||
// reset selected item
|
||||
// SelectedItem = new SalesItemView();
|
||||
|
||||
// begin assembling activity
|
||||
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
||||
if (Activity.Express)
|
||||
Activity.OurRef = $"E{Activity.OurRef}";
|
||||
// begin lines
|
||||
Activity.Lines = new List<ActivityLineDto>();
|
||||
var lineNo = 0;
|
||||
if (DraftProvider.Draft.Items.Count != 0)
|
||||
{
|
||||
var lines = DraftProvider.Draft.Items.Select(item => new ActivityLineDto
|
||||
{
|
||||
// sales properties
|
||||
Discount = item.Discount,
|
||||
Price = item.Price,
|
||||
Qty = item.Quantity,
|
||||
LineAmount = item.LineSum,
|
||||
LineNumber = ++lineNo,
|
||||
Sas = item.Sas,
|
||||
// item properties
|
||||
Location = item.Item.Location,
|
||||
ShortName = item.Item.ShortName,
|
||||
Sku = item.Item.Sku,
|
||||
Text = item.Item.Name,
|
||||
})
|
||||
.ToList();
|
||||
Activity.Lines = lines;
|
||||
}
|
||||
|
||||
// // debug logging
|
||||
// Logger.LogDebug("CrmNewActivityPage => \n {}", JsonSerializer.Serialize(Activity));
|
||||
// // post to api
|
||||
// var result = await CountryActivityRepo.PostPhoneOrder(Company.CompanyId, Activity);
|
||||
// // debug logging
|
||||
// Logger.LogDebug("ApiResponseView => \n {}", JsonSerializer.Serialize(result));
|
||||
// // show result message
|
||||
// if (result.IsSuccess)
|
||||
// {
|
||||
// Toaster.ShowSuccess($"{result.Message}");
|
||||
// await DeleteDraft();
|
||||
// Navigator.NavigateTo($"/office/customers/{CompanyId}/orders/{result.Id}");
|
||||
// Working = false;
|
||||
// return;
|
||||
// }
|
||||
// lower working flag
|
||||
Working = false;
|
||||
// show error message
|
||||
// Toaster.ShowError(result.Message);
|
||||
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@ public partial class OfficeAdvisorCustomerPagedListPage : IDisposable
|
|||
Paging.OrderBy = UserPreference.CompanySort;
|
||||
Paging.SearchColumn = UserPreference.CompanySearch;
|
||||
Paging.PageSize = Convert.ToInt32(UserPreference.PageSize);
|
||||
Paging.IsHidden = 1;
|
||||
Paging.HasFolded = IncludeFolded ? 1 : 0;
|
||||
|
||||
// load saved search
|
||||
|
|
|
@ -67,6 +67,7 @@ public partial class OfficeCustomerCountryPagedListPage : IDisposable
|
|||
Paging.OrderBy = Preference.CompanySort;
|
||||
Paging.SearchColumn = Preference.CompanySearch;
|
||||
Paging.PageSize = Convert.ToInt32(Preference.PageSize);
|
||||
Paging.IsHidden = 1;
|
||||
Paging.HasFolded = ShowFolded ? 1 : 0;
|
||||
|
||||
// load saved search
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
@page "/office/customers/{CountryCode}/{CompanyId}/order"
|
||||
|
||||
<PageTitle>Telefon Ordre - @Company.Name - @Company.Account</PageTitle>
|
||||
<PageTitle>@Company.Name - @Company.Account - Telefon Bestilling</PageTitle>
|
||||
|
||||
<div class="row bg-light border-2 border-dark rounded-3 p-3">
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-8">
|
||||
<h3>@Company.Name - @Company.Account</h3>
|
||||
</div>
|
||||
|
@ -36,6 +36,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">Sælger</div>
|
||||
<div class="col-sm-10">@SalesRep.FirstName @SalesRep.LastName</div>
|
||||
</div>
|
||||
|
||||
<EditForm EditContext="ActivityContext">
|
||||
|
@ -76,6 +78,7 @@
|
|||
<ValidationMessage For="@(() => Activity.DlvCity)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<hr style="height: 2px;" />
|
||||
<label for="yourRef" class="col-sm-2 col-md-2 col-form-label">Indkøber</label>
|
||||
<div class="col-sm-10 col-md-4">
|
||||
<InputText id="yourRef" class="form-control"
|
||||
|
@ -165,7 +168,7 @@
|
|||
<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-end">@($"{cartItem.LineSum:N2}")</td>
|
||||
<td class="align-middle text-center">
|
||||
<input type="checkbox" checked="@cartItem.Sas" disabled/>
|
||||
</td>
|
||||
|
|
|
@ -19,6 +19,8 @@ using System.Text.Json;
|
|||
using Blazored.Toast.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.JSInterop;
|
||||
using Wonky.Client.Extensions;
|
||||
using Wonky.Client.Helpers;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
|
@ -47,6 +49,7 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
[Inject] public ICountryUserInfoRepository UserRepo { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public IUserInfoService UserInfoService { get; set; }
|
||||
[Inject] public IJSRuntime JsRuntime { get; set; }
|
||||
|
||||
// #############################################################
|
||||
// parameters
|
||||
|
@ -88,56 +91,53 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
private List<ProductInventoryItemView> CompanyInventory { get; set; } = new();
|
||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||
private List<ReportItemView> CompanyActivities { get; set; } = new();
|
||||
|
||||
private readonly ElementReference _yourRef = new ("yourRef");
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JsRuntime.SetFocusAsync(_yourRef);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
// get info for logged in user
|
||||
|
||||
UserInfo = await UserInfoService.GetUserInfo();
|
||||
// setup edit context
|
||||
|
||||
ActivityContext = new EditContext(Activity);
|
||||
ActivityContext.OnFieldChanged += HandleFieldChanged;
|
||||
ActivityContext.OnValidationStateChanged += ValidationChanged;
|
||||
// fetch customer
|
||||
|
||||
Company = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
|
||||
Logger.LogDebug("OfficeOrderCreate => Customer => {}", JsonSerializer.Serialize(Company));
|
||||
// construct today's workdate
|
||||
// Initialize date variable
|
||||
|
||||
SelectedDate = DateTime.Now;
|
||||
var today = $"{SelectedDate:yyyy-MM-dd}";
|
||||
// assign activity properties
|
||||
|
||||
Activity.ActivityVisitEnum = "office";
|
||||
Activity.ActivityTypeEnum = "phone";
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
Activity.Express = true;
|
||||
Activity.OurRef = $"INNOTEC:{UserInfo.FirstName}";
|
||||
Activity.ActivityDate = today;
|
||||
// initiate a sync to ensure up-to-date product history
|
||||
|
||||
if (Company.HistorySync != today)
|
||||
{
|
||||
Company.HistorySync = await HistoryRepo.RequestErpToCrmSync(CompanyId, Company.HistorySync, false);
|
||||
Logger.LogDebug("OfficeOrderCreate => RequestErpToCrmSync <= {}", Company.HistorySync);
|
||||
}
|
||||
// fetch invoices
|
||||
CompanyInvoices = await HistoryRepo.GetInvoiceList(CountryCode, CompanyId);
|
||||
Logger.LogDebug("OfficeOrderCreate => Invoices => {}", JsonSerializer.Serialize(CompanyInvoices));
|
||||
// fetch activities
|
||||
CompanyActivities = await CountryActivityRepo.GetActivityList(CompanyId);
|
||||
Logger.LogDebug("OfficeOrderCreate => Activities => {}", JsonSerializer.Serialize(CompanyActivities));
|
||||
// fetch inventory
|
||||
CompanyInventory = await HistoryRepo.GetInventory(CountryCode, CompanyId);
|
||||
CompanyInventory = CompanyInventory.OrderBy(x => x.Description).ToList();
|
||||
Logger.LogDebug("OfficeOrderCreate => Inventory => {}", JsonSerializer.Serialize(CompanyInventory));
|
||||
// get sales rep info
|
||||
|
||||
SalesRep = await UserRepo.GetUserInfo(Company.SalesRepId);
|
||||
Logger.LogDebug("OfficeOrderCreate => SalesRep => {}", JsonSerializer.Serialize(SalesRep));
|
||||
// assign salesRep and countryCode to activity
|
||||
Activity.SalesRep = SalesRep.SalesRep;
|
||||
Activity.CountryCode = SalesRep.CountryCode;
|
||||
Activity.SalesRepId = Company.SalesRepId;
|
||||
// assign customer info into activity properties
|
||||
|
||||
Activity.Account = Company.Account;
|
||||
Activity.VatNumber = Company.VatNumber;
|
||||
Activity.Email = Company.Email;
|
||||
|
@ -156,6 +156,9 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
Activity.BcId = Company.BcId;
|
||||
Activity.CompanyId = Company.CompanyId;
|
||||
|
||||
DraftProvider.Draft.DraftType = "order";
|
||||
PoFormInvalid = DraftProvider.Draft.Invalid;
|
||||
|
||||
Working = false;
|
||||
}
|
||||
|
||||
|
@ -163,22 +166,23 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
private async Task DeleteDraft()
|
||||
{
|
||||
await DraftProvider.DeleteDraftAsync();
|
||||
PoFormInvalid = DraftProvider.Draft.Invalid;
|
||||
}
|
||||
|
||||
|
||||
private async Task RemoveItem(DraftItem item)
|
||||
{
|
||||
// remove item
|
||||
DraftProvider.Draft.Items.Remove(item);
|
||||
// save the remaining draft
|
||||
|
||||
await DraftProvider.SaveChangesAsync();
|
||||
PoFormInvalid = DraftProvider.Draft.Invalid;
|
||||
}
|
||||
|
||||
|
||||
private async Task AddItem(SalesItemView salesItem)
|
||||
{
|
||||
ShowItem = false;
|
||||
// create a new cart item
|
||||
|
||||
var item = new DraftItem
|
||||
{
|
||||
Item = salesItem,
|
||||
|
@ -187,30 +191,30 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
Discount = Convert.ToDecimal(Discount, CultureInfo.InvariantCulture),
|
||||
Sas = Sas
|
||||
};
|
||||
// reset internals to initial state
|
||||
|
||||
Sas = false;
|
||||
Quantity = "1";
|
||||
Price = "0";
|
||||
Discount = "0";
|
||||
// add it to the cart
|
||||
|
||||
SelectedItem = new SalesItemView();
|
||||
DraftProvider.Draft.Items.Add(item);
|
||||
if(Activity.ActivityStatusEnum != "quote")
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
// save the item using the CartStateProvider's save method
|
||||
PoFormInvalid = DraftProvider.Draft.Invalid;
|
||||
|
||||
await DraftProvider.SaveChangesAsync();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async Task PriceListCallback(ItemSelect selectedItem)
|
||||
{
|
||||
// get selected item
|
||||
SelectedItem = new SalesItemView();
|
||||
if (string.IsNullOrWhiteSpace(selectedItem.ItemNo))
|
||||
return;
|
||||
SelectedItem = await PriceCatalog.GetSalesItemSku(CountryCode, selectedItem.ItemNo);
|
||||
ShowItem = true;
|
||||
Price = selectedItem.Rate;
|
||||
Quantity = selectedItem.Quantity;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,71 +244,40 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
|
||||
private async Task CreateActivity()
|
||||
{
|
||||
// avoid duplication
|
||||
if (Working)
|
||||
return;
|
||||
// validate customer address1
|
||||
// - this is a required input
|
||||
// --- exclude for office orders
|
||||
// if (string.IsNullOrWhiteSpace(Activity.Address1))
|
||||
// {
|
||||
// Toaster.ShowError("Kunde adresse er ufuldstændig.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// validate org number
|
||||
// - this is a required input
|
||||
// - must validate according to country rules.
|
||||
// --- exclude for office orders
|
||||
// if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
|
||||
// {
|
||||
// Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// validate input according to status
|
||||
switch (Activity.ActivityStatusEnum)
|
||||
{
|
||||
// don't accept order with no lines
|
||||
case "order" when DraftProvider.Draft.Items.Count == 0:
|
||||
case "order" when DraftProvider.Draft.Invalid:
|
||||
Toaster.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
|
||||
return;
|
||||
// phone number is required if first time customer
|
||||
|
||||
case "order" when Company.Account.StartsWith("NY") && string.IsNullOrWhiteSpace(Activity.Phone):
|
||||
Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
|
||||
return;
|
||||
// verify email address is a valid address
|
||||
// --- exclude for office orders
|
||||
// case "quote" when !Utils.IsValidEmail(Activity.Email):
|
||||
// Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
|
||||
// return;
|
||||
}
|
||||
|
||||
// raise working flag
|
||||
Working = true;
|
||||
|
||||
// reset selected item
|
||||
SelectedItem = new SalesItemView();
|
||||
|
||||
// begin assembling activity
|
||||
|
||||
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
||||
if (Activity.Express)
|
||||
Activity.OurRef = $"E{Activity.OurRef}";
|
||||
// begin lines
|
||||
|
||||
Activity.Lines = new List<ActivityLineDto>();
|
||||
var ln = 0;
|
||||
if (DraftProvider.Draft.Items.Count != 0)
|
||||
{
|
||||
var lines = DraftProvider.Draft.Items.Select(item => new ActivityLineDto
|
||||
{
|
||||
// sales properties
|
||||
|
||||
Discount = item.Discount,
|
||||
Price = item.Price,
|
||||
Qty = item.Quantity,
|
||||
LineAmount = item.LineTotal,
|
||||
LineAmount = item.LineSum,
|
||||
LineNumber = ++ln,
|
||||
Sas = item.Sas,
|
||||
// item properties
|
||||
|
||||
Location = item.Item.Location,
|
||||
ShortName = item.Item.ShortName,
|
||||
Sku = item.Item.Sku,
|
||||
|
@ -314,13 +287,8 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
Activity.Lines = lines;
|
||||
}
|
||||
|
||||
// debug logging
|
||||
Logger.LogDebug("CrmNewActivityPage => \n {}", JsonSerializer.Serialize(Activity));
|
||||
// post to api
|
||||
var result = await CountryActivityRepo.PostPhoneOrder(Company.CompanyId, Activity);
|
||||
// debug logging
|
||||
Logger.LogDebug("ApiResponseView => \n {}", JsonSerializer.Serialize(result));
|
||||
// show result message
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Toaster.ShowSuccess($"{result.Message}");
|
||||
|
@ -329,9 +297,9 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
|
|||
Working = false;
|
||||
return;
|
||||
}
|
||||
// lower working flag
|
||||
|
||||
Working = false;
|
||||
// show error message
|
||||
|
||||
Toaster.ShowError(result.Message);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"appInfo": {
|
||||
"name": "Wonky Online",
|
||||
"version": "315.0",
|
||||
"version": "316.0",
|
||||
"rc": false,
|
||||
"sandBox": true,
|
||||
"image": "grumpy-coder.png",
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<script src="/bootstrap/js/bootstrap.bundle.js"></script>
|
||||
<script src="/_framework/blazor.webassembly.js"></script>
|
||||
<script type="module" src="/scripts/print-invoke.js"></script>
|
||||
<script src="/scripts/focus-element.js"></script>
|
||||
<script src="/_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
5
Wonky.Client/wwwroot/scripts/focus-element.js
Normal file
5
Wonky.Client/wwwroot/scripts/focus-element.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
function FormFocusElement(element) {
|
||||
if (element instanceof HTMLElement) {
|
||||
element.focus();
|
||||
}
|
||||
}
|
|
@ -2,7 +2,10 @@ namespace Wonky.Entity.DTO;
|
|||
|
||||
public class B2BAdvisorInfo
|
||||
{
|
||||
public string AdvisorId { get; set; } = "";
|
||||
public string CountryCode { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string Name { get; set; } = "";
|
||||
public string Phone { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string SalesRep { get; set; } = "";
|
||||
}
|
|
@ -5,10 +5,16 @@ public class B2BBusinessInfo
|
|||
public string Account { get; set; } = "";
|
||||
public string Address1 { get; set; } = "";
|
||||
public string Address2 { get; set; } = "";
|
||||
public string AdvisorId { get; set; } = "";
|
||||
public string BcId { get; set; } = "";
|
||||
public string City { get; set; } = "";
|
||||
public string CompanyId { get; set; } = "";
|
||||
public string CountryCode { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string Mobile { get; set; } = "";
|
||||
public string Name { get; set; } = "";
|
||||
public string ZipCode { get; set; } = "";
|
||||
public string Phone { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string SalesRep { get; set; } = "";
|
||||
public string VatNumber { get; set; } = "";
|
||||
public string ZipCode { get; set; } = "";
|
||||
}
|
Loading…
Reference in a new issue