WIP: web shop - adding image to list views

This commit is contained in:
Frede Hundewadt 2023-07-22 17:39:35 +02:00
parent 7adc5b2b49
commit e2e528430b
39 changed files with 506 additions and 72 deletions

View file

@ -0,0 +1,17 @@
@* 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]
*@
<h2>B2B</h2>

View file

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Components;
using Wonky.Client.Local.Services;
#pragma warning disable CS8618
namespace Wonky.Client.Components;
public partial class B2BLandingComponent
{
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public IUserInfoService UserInfo { get; set; }
protected override async Task OnInitializedAsync()
{
var userInfo = await UserInfo.GetUserInfo();
Navigator.NavigateTo($"/b2b/{userInfo.CountryCode.ToLower()}/{userInfo.CompanyId}");
}
}

View file

@ -12,6 +12,7 @@
// 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.OverlayCustomer
<div class="list-group">
<div class="list-group-item">

View file

@ -26,7 +26,9 @@
<div class="col-sm-7 text-end">
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="sortOrder" checked @onclick="@SetSortOrder"/>
<label class="form-check-label" for="sortOrder"><i class="@(Descending ? "bi-sort-up" : "bi-sort-down-alt") "></i></label>
<label class="form-check-label" for="sortOrder">
<i class="@(Descending ? "bi-sort-up" : "bi-sort-down-alt") "></i>
</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sortCol" id="description" value="description"
@ -53,6 +55,20 @@
{
<div class="list-group-item">
<div class="row align-items-center">
<div class="col-sm-2">
<div class="position-relative">
<div class="product-image">
<img class="img-fluid img-thumbnail" src="@product.PictureLink?height=100" alt="@product.Description"/>
</div>
@if (product.Discontinued)
{
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
Udgået
<span class="visually-hidden">Produktet er udgået</span>
</span>
}
</div>
</div>
<div class="col-sm-2">
<div class="position-relative">
@product.LastInvoiceDate
@ -65,17 +81,8 @@
}
</div>
</div>
<div class="col-sm-4">
<div class="position-relative">
<div class="col-sm-2">
@product.Description
@if (product.Discontinued)
{
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
Udgået
<span class="visually-hidden">Produktet er udgået</span>
</span>
}
</div>
</div>
<div class="col-sm-2 text-sm-start">
@product.Sku

View file

@ -48,7 +48,6 @@ public partial class CustomerInventoryListComponent
// initialize FilteredList
ApplyInventoryFilter(DisplayFilter);
}
private void SetSortOrder()
{

View file

@ -0,0 +1,4 @@
.product-image {
width: 100px;
height: auto;
}

View file

@ -0,0 +1,105 @@
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using Wonky.Entity.Configuration;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class B2BRepository : IB2BRepository
{
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<B2BRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public B2BRepository(HttpClient client, ILogger<B2BRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
_logger = logger;
_navigation = navigation;
_api = configuration.Value;
}
public async Task<List<ESalesHeadListView>> GetWebShopOrderList(string companyId)
{
var result = await _client.GetFromJsonAsync<List<ESalesHeadListView>>(
$"{_api.B2BCustomer}/{companyId}/sales");
return result ?? new List<ESalesHeadListView>();
}
public async Task<ESalesHeadView> GetWebShopOrder(string companyId, string orderId)
{
var result = await _client.GetFromJsonAsync<ESalesHeadView>(
$"{_api.B2BCustomer}/{companyId}/sales/{orderId}");
return result ?? new ESalesHeadView();
}
public async Task<ESalesHeadView> PostWebShopOrder(string companyId, ESalesHeadCreateDto model)
{
var result = await _client.PostAsJsonAsync(
$"{_api.B2BCustomer}/{companyId}/sales", model, _options);
var content = await result.Content.ReadAsStringAsync();
if (!result.IsSuccessStatusCode || string.IsNullOrWhiteSpace(content))
{
return new ESalesHeadView();
}
return JsonSerializer.Deserialize<ESalesHeadView>(content) ?? new ESalesHeadView();
}
public async Task PutWebShopOrder(string companyId, string orderId, ESalesHeadView model)
{
await _client.PutAsJsonAsync($"{_api.B2BCustomer}/{companyId}/sales/{orderId}", model, _options);
}
public async Task DeleteWebShopOrder(string companyId, string orderId)
{
await _client.DeleteAsync($"{_api.B2BCustomer}/{companyId}/sales/{orderId}");
}
public async Task<B2BAdvisorInfo> GetAdvisorInfo(string companyId)
{
var result = await _client.GetFromJsonAsync<B2BAdvisorInfo>(
$"{_api.B2BCustomer}/{companyId}/info/advisor");
return result ?? new B2BAdvisorInfo();
}
public async Task<B2BBusinessInfo> GetBusinessInfo(string companyId)
{
var result = await _client.GetFromJsonAsync<B2BBusinessInfo>(
$"{_api.B2BCustomer}/{companyId}/info/business");
return result ?? new B2BBusinessInfo();
}
public async Task<List<ProductInventoryItemView>> GetCustomerInventory(string companyId)
{
var result = await _client.GetFromJsonAsync<List<ProductInventoryItemView>>(
$"{_api.B2BCustomer}/{companyId}/info/inventory");
return result ?? new List<ProductInventoryItemView>();
}
public async Task<List<ProductHistoryView>> GetCustomerProductHistory(string companyId, string sku)
{
var result = await _client.GetFromJsonAsync<List<ProductHistoryView>>(
$"{_api.B2BCustomer}/{companyId}/info/inventory/{sku}");
return result ?? new List<ProductHistoryView>();
}
}

View file

@ -0,0 +1,20 @@
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public interface IB2BRepository
{
// sale
Task<List<ESalesHeadListView>> GetWebShopOrderList(string companyId);
Task<ESalesHeadView> GetWebShopOrder(string companyId, string orderId);
Task<ESalesHeadView> PostWebShopOrder(string companyId, ESalesHeadCreateDto model);
Task PutWebShopOrder(string companyId, string orderId, ESalesHeadView model);
Task DeleteWebShopOrder(string companyId, string orderId);
// info
Task<B2BAdvisorInfo> GetAdvisorInfo(string companyId);
Task<B2BBusinessInfo> GetBusinessInfo(string companyId);
Task<List<ProductInventoryItemView>> GetCustomerInventory(string companyId);
Task<List<ProductHistoryView>> GetCustomerProductHistory(string companyId, string sku);
}

View file

@ -52,7 +52,7 @@ public class SystemSendMailService : ISystemSendMailService
/// <returns></returns>
public async Task<ApiResponseView> SendMail(string messageType, EmailMessage message)
{
var response = await _client.PostAsJsonAsync($"{_api.ServicesMail}/{messageType}", message, _options);
var response = await _client.PostAsJsonAsync($"{_api.ServiceMail}/{messageType}", message, _options);
if (!response.IsSuccessStatusCode)
return new ApiResponseView
{

View file

@ -51,7 +51,7 @@ public class SystemSendSmsService : ISystemSendSmsService
/// <returns></returns>
public async Task<ApiResponseView> SendSms(ShortMessage message)
{
var response = await _client.PostAsJsonAsync($"{_api.ServicesSms}", message, _options);
var response = await _client.PostAsJsonAsync($"{_api.ServiceSms}", message, _options);
if (!response.IsSuccessStatusCode)
return new ApiResponseView
{

View file

@ -65,7 +65,7 @@ public class AuthenticationService : IAuthenticationService
};
var response = await _client
.PostAsync(_apiConfig.Value.ServicesAuth, new FormUrlEncodedContent(credForm));
.PostAsync(_apiConfig.Value.ServiceAuth, new FormUrlEncodedContent(credForm));
var resContent = await response.Content.ReadAsStringAsync();
@ -114,7 +114,7 @@ public class AuthenticationService : IAuthenticationService
["refresh_token"] = refreshToken
};
var response = await _client.PostAsync(_apiConfig.Value.ServicesAuth, new FormUrlEncodedContent(credentials));
var response = await _client.PostAsync(_apiConfig.Value.ServiceAuth, new FormUrlEncodedContent(credentials));
var content = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode || string.IsNullOrWhiteSpace(content))

View file

@ -31,7 +31,7 @@ public class SwedishPersonalOrgService : ISwedishPersonalOrgService
PersonalId = ""
};
var response = await _client.GetAsync($"{_api.ServicesVatSe}?companyName={companyName}");
var response = await _client.GetAsync($"{_api.ServiceVatSe}?companyName={companyName}");
var content = await response.Content.ReadAsStringAsync();

View file

@ -54,7 +54,7 @@ public class VatInfoLookupService
["zipCode"] = $"{query.ZipCode}",
["entityName"] = $"{query.EntityName}"
};
var endpoint = WebUtils.QueryHelper($"{_api.ServicesVatDk}", queryDictionary);
var endpoint = WebUtils.QueryHelper($"{_api.ServiceVatDk}", queryDictionary);
var response = await _client.GetAsync(endpoint.ToString());
var content = await response.Content.ReadAsStringAsync();
@ -83,7 +83,7 @@ public class VatInfoLookupService
{
["vatNumber"] = $"{vatNumber}"
};
var endpoint = WebUtils.QueryHelper($"{_api.ServicesVatNo}", queryDictionary);
var endpoint = WebUtils.QueryHelper($"{_api.ServiceVatNo}", queryDictionary);
var response = await _client.GetAsync(endpoint.ToString());
var content = await response.Content.ReadAsStringAsync();
@ -106,7 +106,7 @@ public class VatInfoLookupService
{
["vatNumber"] = $"{vatNumber}"
};
var endpoint = WebUtils.QueryHelper($"{_api.ServicesVatEu}", queryDictionary);
var endpoint = WebUtils.QueryHelper($"{_api.ServiceVatEu}", queryDictionary);
var response = await _client.GetAsync(endpoint.ToString());

View file

@ -52,7 +52,10 @@ else
<span class="h3">@_activity.Name</span> <span>(@_activity.Account)</span>
</div>
<div class="col-sm-3 text-end">
<button type="button" class="btn btn-sm btn-secondary" disabled="@(_company.Account.StartsWith("NY") || _disableButtons)" @onclick="@(() => ReloadHistory(true))"><i class="bi-repeat"></i> Historik</button>
<button type="button" class="btn btn-sm btn-secondary"
disabled="@(_company.Account.StartsWith("NY") || _disableButtons)" @onclick="@(() => ReloadHistory(true))">
<i class="bi-repeat"></i> Historik
</button>
</div>
</div>
@ -86,7 +89,6 @@ else
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)
{
@if (DraftProvider.Draft.DraftType == "order")
@ -207,19 +209,28 @@ else
@*
***************** Invoice history overlay *****************************
*@
<button class="btn btn-danger" disabled="@(string.IsNullOrWhiteSpace(_activity.ActivityTypeEnum) || _disableButtons)" @onclick="@ShowInvoiceOverlay">Faktura</button>
<button class="btn btn-danger" @onclick="@ShowInvoiceOverlay"
disabled="@(string.IsNullOrWhiteSpace(_activity.ActivityTypeEnum) || _disableButtons)">
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) || _disableButtons)" @onclick="@ShowActivitiesOverlay">Tidl. besøg</button>
<button class="btn btn-warning" @onclick="@ShowActivitiesOverlay"
disabled="@(string.IsNullOrWhiteSpace(_activity.ActivityTypeEnum) || _disableButtons)">
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) || _disableButtons)" @onclick="@ShowInventoryOverlay">Produkter</button>
<button class="btn btn-success" @onclick="@ShowInventoryOverlay"
disabled="@(string.IsNullOrWhiteSpace(_activity.ActivityTypeEnum) || _disableButtons)">
Produkter
</button>
</div>
</div>
@ -231,13 +242,18 @@ else
<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>
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>
<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">
@ -270,7 +286,9 @@ else
@*
***************** Remove item *****************************
*@
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))"><i class="bi-trash2"></i> Slet Linje</button>
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))">
<i class="bi-trash2"></i> Slet Linje
</button>
</td>
</tr>
}
@ -339,7 +357,10 @@ else
@*
***************** Add item button *****************************
*@
<button type="button" class="btn btn-primary d-block text-sm-center" @onclick="@(() => AddItem(_selectedItem))">@Quantity stk. @_selectedItem.Name</button>
<button type="button" class="btn btn-primary d-block text-sm-center"
@onclick="@(() => AddItem(_selectedItem))">
@Quantity stk. @_selectedItem.Name
</button>
</td>
</tr>
</tbody>
@ -397,14 +418,17 @@ else
<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>
<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)">
<button type="button" class="btn btn-warning" @onclick="@ShowProductCheckOverlay"
disabled="@(_formInvalid || Working)">
<i class="bi-cloud-arrow-up"></i> @ButtonText
</button>
</div>

View file

@ -164,7 +164,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
_activity.ZipCode = _company.ZipCode;
/*
* debug loggin
* debug logging
*/
// Logger.LogDebug("company.segment = {}", _company.Segment);
// Logger.LogDebug("activity.segment = {}", _activity.Segment);

View file

@ -0,0 +1,39 @@
@* Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@
@using Microsoft.AspNetCore.Authorization
@using System.Text.Json
@attribute [Authorize(Roles = "EShop")]
@page "/b2b/{countryCode}/{companyId}"
<div>
@if (!string.IsNullOrWhiteSpace(_businessInfo.Name))
{
@JsonSerializer.Serialize(_businessInfo)
}
</div>
<div>
@if (!string.IsNullOrWhiteSpace(_advisorInfo.Name))
{
@JsonSerializer.Serialize(_advisorInfo)
}
</div>
<div>
@if (_productInventory.Any())
{
@JsonSerializer.Serialize(_productInventory)
}
</div>

View file

@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.Pages;
public partial class BusinessCustomerLandingPage : IDisposable
{
// ##############################################################
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IB2BRepository B2BRepo { get; set; }
// ##############################################################
[Parameter] public string CountryCode { get; set; } = "";
[Parameter] public string CompanyId { get; set; } = "";
// ##############################################################
private B2BBusinessInfo _businessInfo = new();
private B2BAdvisorInfo _advisorInfo = new();
private List<ProductHistoryView> _productHistory = new();
private List<ProductInventoryItemView> _productInventory = new();
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
_businessInfo = await B2BRepo.GetBusinessInfo(CompanyId);
_advisorInfo = await B2BRepo.GetAdvisorInfo(CompanyId);
_productInventory = await B2BRepo.GetCustomerInventory(CompanyId);
}
public void Dispose()
{
Interceptor.DisposeEvent();
}
}

View file

@ -0,0 +1,23 @@
// 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]
//
namespace Wonky.Client.Pages;
#pragma warning disable CS8618
public partial class BusinessCustomerWebShopPage
{
}

View file

@ -0,0 +1,20 @@
@* Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "EShop")]
@page "/b2b/{countryCode}/{companyId}/webshop"
<h3>BusinessCustomerWebshopPage</h3>

View file

@ -16,26 +16,37 @@
@using Wonky.Client.Components;
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Advisor,Management,Office,Supervisor,Warehouse")]
@attribute [Authorize(Roles = "Admin,Advisor,Management,Office,Supervisor,Warehouse,EShop")]
@page "/"
@page "/index"
@page "/home"
<PageTitle>Innotec Danmark A/S</PageTitle>
<AuthorizeView Roles="Advisor">
<AdvisorLandingComponent />
<AdvisorLandingComponent/>
</AuthorizeView>
<AuthorizeView Roles="Admin,Management,Office,Warehouse">
<OfficeLandingComponent />
<PageTitle>Innotec Danmark A/S</PageTitle>
<OfficeLandingComponent/>
</AuthorizeView>
<AuthorizeView Roles="Supervisor">
<PageTitle>Innotec Danmark A/S</PageTitle>
@* TODO Supervisor landing page *@
</AuthorizeView>
<AuthorizeView Roles="Management">
<PageTitle>Innotec Danmark A/S</PageTitle>
@* TODO Supervisor landing page *@
</AuthorizeView>
<AuthorizeView Roles="EShop">
<PageTitle>Innotec Danmark A/S</PageTitle>
<B2BLandingComponent></B2BLandingComponent>
</AuthorizeView>
@code{
}

View file

@ -140,6 +140,7 @@
<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>
@ -155,6 +156,9 @@
<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 draft line *****************************
@ -195,6 +199,7 @@
<th scope="col">Antal</th>
<th scope="col">Pris</th>
<th 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>
@ -217,6 +222,9 @@
<td class="align-middle">
<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">
@*

View file

@ -71,6 +71,7 @@ public partial class OfficeOrderCreatePage : IDisposable
private string Quantity { get; set; } = "1";
private string Price { get; set; } = "0";
private string Discount { get; set; } = "0";
private bool Sas { get; set; }
// private bool ReportClosed { get; set; }
private bool PoFormInvalid { get; set; } = true;
private bool Working { get; set; } = true;
@ -188,8 +189,10 @@ public partial class OfficeOrderCreatePage : IDisposable
Quantity = Convert.ToInt32(Quantity),
Price = Convert.ToDecimal(Price, CultureInfo.InvariantCulture),
Discount = Convert.ToDecimal(Discount, CultureInfo.InvariantCulture),
Sas = Sas
};
// reset internals to initial state
Sas = false;
Quantity = "1";
Price = "0";
Discount = "0";

View file

@ -35,7 +35,7 @@
<div class="row mb-3 ps-3">
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="eshop" class="form-check-input" @bind-Value="AssignedRoles.EShop"/>
<label for="eshop" class="form-check-label">WebShop Kunde</label>
<label for="eshop" class="form-check-label">B2B Kunde</label>
</div>
<div class="col-sm-3 form-check form-switch">
<InputCheckbox id="supervisor" class="form-check-input" @bind-Value="AssignedRoles.Supervisor"/>

View file

@ -116,7 +116,7 @@
<div class="row">
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="eshop" class="form-check-input" @bind-Value="AssignedRoles.EShop"/>
<label for="eshop" class="form-check-label">WebShop Kunde</label>
<label for="eshop" class="form-check-label">B2B Kunde</label>
</div>
<div class="ms-2 col-sm-2 form-check form-switch">
<InputCheckbox id="supervisor" class="form-check-input" @bind-Value="AssignedRoles.Supervisor"/>
@ -150,16 +150,16 @@
</div>
</div>
<div class="row">
<div class="col">
<div class="col-sm-3">
<button type="button" class="btn btn-danger" disabled="@ReadOnly" @onclick="@SendDeleteRequest"><i class="bi-trash"></i> SLET</button>
</div>
<div class="col">
<div class="col-sm-3">
<button type="button" class="btn btn-warning" @onclick="@(() => ReadOnly = !ReadOnly)"><i class="bi-pencil"></i> Rediger</button>
</div>
<div class="col">
<div class="col-sm-3">
<button type="submit" class="btn btn-primary" disabled="@ReadOnly"><i class="bi-cloud-arrow-up"></i> Gem</button>
</div>
<div class="col">
<div class="col-sm-3">
<a class="btn btn-primary" href="/system/users"><i class="bi-back-lg"></i> Tilbage</a>
</div>
</div>

View file

@ -33,6 +33,7 @@ public partial class SystemUserViewEditPage : IDisposable
// #############################################################
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ISystemUserRepository UserRepo { get; set; }
[Inject] public ICountryCustomerRepository CustomerRepo { get; set; }
[Inject] public ILogger<SystemUserViewEditPage> Logger { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
@ -49,6 +50,7 @@ public partial class SystemUserViewEditPage : IDisposable
private bool PwInvalid { get; set; } = true;
private bool Working { get; set; } = true;
private bool ReadOnly { get; set; } = true;
private CompanyDto _customer = new();
private RoleAssignment AssignedRoles { get; set; } = new();
@ -65,6 +67,11 @@ public partial class SystemUserViewEditPage : IDisposable
UserInfo = await UserRepo.GetUserInfo(UserId);
if (!string.IsNullOrWhiteSpace(UserInfo.CompanyId))
{
_customer = await CustomerRepo.GetByCustomerId(CountryCode, UserInfo.CompanyId);
}
AssignedRoles = Mapper.MapEditAssignedRoles(UserInfo);
UserEditContext = new EditContext(UserInfo);

View file

@ -28,6 +28,7 @@ using Wonky.Client.HttpRepository;
using Wonky.Client.Local.Services;
using Wonky.Client.Shared;
using Wonky.Entity.Configuration;
using Wonky.Entity.DTO;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
@ -105,6 +106,8 @@ builder.Services.AddScoped<ICabinetDrawerService, CabinetDrawerService>();
builder.Services.AddBlazoredLocalStorage();
// Swedisd Personal Company OrgNo Search
builder.Services.AddScoped<ISwedishPersonalOrgService, SwedishPersonalOrgService>();
// b2b service
builder.Services.AddScoped<IB2BRepository, B2BRepository>();
// ---------------------------------------

View file

@ -11,11 +11,11 @@
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.Toast" Version="4.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.7" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.9" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="7.0.0" />
@ -27,13 +27,13 @@
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Remove="wwwroot\icons\**" />
<Content Remove="Pages\AdvisorCustomerOrderViewPage.razor" />
<Content Remove="Pages\OfficeUserAdvisorViewEditPage.razor" />
<Content Remove="Shared\NavMenu-backup.razor" />
<Content Update="wwwroot\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>

View file

@ -1,7 +1,7 @@
{
"appInfo": {
"name": "Wonky Online",
"version": "181.0",
"version": "183.0",
"rc": true,
"sandBox": true,
"image": "grumpy-coder.png",
@ -20,7 +20,7 @@
}
},
"apiConfig": {
"baseUrl": "https://eta.innotec.dk",
"baseUrl": "https://dev.innotec.dk",
"catalog": "api/v2/catalog/country",
"crmCustomers": "api/v2/crm/companies",
"crmInventoryExt": "history/inventory",
@ -36,15 +36,15 @@
"officeReports": "api/v2/office/reports",
"officeUsers": "api/v2/office/users/admin",
"publicProducts": "api/v2/public/products",
"servicesGlsId": "",
"servicesGlsTrackUrl": "https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DK01/DA/5004.htm?txtAction=71000&txtRefNo=",
"servicesMail": "api/v2/services/sendmail",
"servicesSms": "api/v2/services/sms",
"servicesVatDk": "api/v2/services/virk",
"serviceAuth": "v2/token",
"serviceGlsId": "",
"serviceGlsTrack": "https://gls-group.eu/track/",
"serviceMail": "api/v2/services/sendmail",
"serviceSms": "api/v2/services/sms",
"serviceVatDk": "api/v2/services/virk",
"serviceVatEu": "api/v2/services/vies",
"servicesVatNo": "api/v2/services/brReg",
"servicesVatSe": "api/v2/services/allabolag",
"servicesAuth": "v2/token",
"serviceVatNo": "api/v2/services/brReg",
"serviceVatSe": "api/v2/services/allabolag",
"sync": "api/v2/sync",
"syncInvoice": "api/v2/sync/invoices",
"systemDocStringUrl": "api/v2/admin/doc",
@ -56,6 +56,7 @@
"userManagerSetPasswd": "api/v2/app/manage/passwd",
"userRoles": "api/v2/app/manage/roles",
"userSupport": "/api/v2/app/manage/support",
"warehouse": "api/v2/warehouse/packages"
"warehouse": "api/v2/warehouse/packages",
"b2bCustomer": "api/v2/b2b"
}
}

View file

@ -101,46 +101,46 @@ public class ApiConfig
/// <summary>
/// Application uri for token request
/// </summary>
public string ServicesAuth { get; set; } = "";
public string ServiceAuth { get; set; } = "";
/// <summary>
/// GLS tracking url
/// </summary>
public string ServicesGlsTrackUrl { get; set; } = "";
public string ServiceGlsTrack { get; set; } = "";
/// <summary>
/// GLS customer entity
/// </summary>
public string ServicesGlsId { get; set; } = "";
public string ServiceGlsId { get; set; } = "";
/// <summary>
/// url for sending mail message
/// </summary>
public string ServicesMail { get; set; } = "";
public string ServiceMail { get; set; } = "";
/// <summary>
/// url for sending Short Message
/// </summary>
public string ServicesSms { get; set; } = "";
public string ServiceSms { get; set; } = "";
/// <summary>
/// VAT registrar url Denmark
/// </summary>
public string ServicesVatDk { get; set; } = "";
public string ServiceVatDk { get; set; } = "";
/// <summary>
/// VAT registrar url Norway
/// </summary>
public string ServicesVatNo { get; set; } = "";
public string ServiceVatNo { get; set; } = "";
/// <summary>
/// VAT registrar url EU
/// </summary>
public string ServicesVatSe { get; set; } = "";
public string ServiceVatSe { get; set; } = "";
/// <summary>
/// VAT registrar url EU
/// </summary>
public string ServicesVatEu { get; set; } = "";
public string ServiceVatEu { get; set; } = "";
/// <summary>
/// Base sync url
@ -201,4 +201,8 @@ public class ApiConfig
/// </summary>
public string Warehouse { get; set; } = "";
}
/// <summary>
/// Uri for B2BCustomer
/// </summary>
public string B2BCustomer { get; set; } = "";
}

View file

@ -0,0 +1,8 @@
namespace Wonky.Entity.DTO;
public class B2BAdvisorInfo
{
public string Name { get; set; } = "";
public string Phone { get; set; } = "";
public string Email { get; set; } = "";
}

View file

@ -0,0 +1,13 @@
namespace Wonky.Entity.DTO;
public class B2BBusinessInfo
{
public string Address1 { get; set; } = "";
public string Address2 { get; set; } = "";
public string City { get; set; } = "";
public string CompanyId { get; set; } = "";
public string Name { get; set; } = "";
public string ZipCode { get; set; } = "";
public string Phone { get; set; } = "";
public string Email { get; set; } = "";
}

View file

@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Wonky.Entity.DTO;
public class ESalesHeadCreateDto
{
[MaxLength(20)] public string ReferenceNumber { get; set; } = "";
[MaxLength(255)] public string OrderNote { get; set; } = "";
[Required] public bool ConditionsAccepted { get; set; }
[Required] public List<ESalesLineCreateDto> Lines { get; set; } = new();
}

View file

@ -0,0 +1,10 @@
namespace Wonky.Entity.DTO;
public class ESalesHeadListView
{
public string SalesHeadId { get; set; } = "";
public string ReferenceNumber { get; set; } = "";
public string YourRef { get; set; } = "";
public bool Closed { get; set; }
public string OrderDate { get; set; } = "";
}

View file

@ -0,0 +1,13 @@
namespace Wonky.Entity.DTO;
public class ESalesHeadView
{
public string SalesHeadId { get; set; } = "";
public string OurRef { get; set; } = "";
public string ReferenceNumber { get; set; } = "";
public string YourRef { get; set; } = "";
public string OrderNote { get; set; } = "";
public bool Closed { get; set; }
public string OrderDate { get; set; } = "";
public List<ESalesLineView> Lines { get; set; } = new();
}

View file

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace Wonky.Entity.DTO;
public class ESalesLineCreateDto
{
[Required] [MaxLength(20)] public string Sku { get; set; } = "";
[Required] public int Qty { get; set; }
[Required] [MaxLength(40)] public string Text { get; set; } = "";
}

View file

@ -0,0 +1,9 @@
namespace Wonky.Entity.DTO;
public class ESalesLineView
{
public string SalesLineId { get; set; } = "";
public string Sku { get; set; } = "";
public int Qty { get; set; }
public string Text { get; set; } = "";
}

View file

@ -23,6 +23,7 @@ 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}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://dev.innotec.dk\",|g' "${FILE}"
sed -i 's|\"rc\".*|\"rc\": true,|g' "${FILE}"
printf "\n==> done building: ${FOLDER} ${1}\n"

View file

@ -30,6 +30,6 @@ 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}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://dev.innotec.dk\",|g' "${FILE}"
printf "\n==> done building: ${FOLDER} EDU SANDBOX\n"

View file

@ -30,6 +30,6 @@ 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}"
sed -i 's|\"baseUrl\".*|\"baseUrl\": \"https://dev.innotec.dk\",|g' "${FILE}"
printf "\n==> done building: ${FOLDER} RC\n"