WIP: EAN
This commit is contained in:
parent
1389f99b81
commit
4357c2484a
7 changed files with 234 additions and 11 deletions
57
Wonky.Client/Models/Ean13Validator.cs
Normal file
57
Wonky.Client/Models/Ean13Validator.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
namespace Wonky.Client.Models;
|
||||
|
||||
public class Ean13Validator
|
||||
{
|
||||
private const int Size = 12;
|
||||
|
||||
public static bool Validate(string number)
|
||||
{
|
||||
if (number.Length != Size + 1)
|
||||
return false;
|
||||
return number == ParsedNumber(number[..12]);
|
||||
}
|
||||
|
||||
private static string Ean13(int[]? firstDigits)
|
||||
{
|
||||
var summedProduct = 0;
|
||||
var randomDigits = new Random();
|
||||
bool isNull;
|
||||
if (firstDigits == null)
|
||||
{
|
||||
firstDigits = new int[Size];
|
||||
isNull = true;
|
||||
}
|
||||
else
|
||||
isNull = false;
|
||||
for (var idx = 0; idx < Size; idx++)
|
||||
{
|
||||
var alt = idx % 2 == 0 ? 1 : 3;
|
||||
int digit;
|
||||
if (isNull)
|
||||
{
|
||||
digit = randomDigits.Next(10);
|
||||
firstDigits[idx] = digit;
|
||||
}
|
||||
else
|
||||
digit = firstDigits[idx];
|
||||
summedProduct += digit * alt;
|
||||
}
|
||||
var checkDigit = 10 - summedProduct % 10;
|
||||
if (checkDigit == 10)
|
||||
checkDigit = 0;
|
||||
return string.Join("", firstDigits) + checkDigit;
|
||||
}
|
||||
|
||||
private static string ParsedNumber(string number)
|
||||
{
|
||||
var firstDigits = new int[Size];
|
||||
if (number.Length != Size | !long.TryParse(number, out _))
|
||||
return null;
|
||||
for (var idx = 0; idx < Size; idx++)
|
||||
{
|
||||
var digit = int.Parse(number[idx].ToString());
|
||||
firstDigits[idx] = digit;
|
||||
}
|
||||
return Ean13(firstDigits);
|
||||
}
|
||||
}
|
|
@ -163,13 +163,16 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
Activity.DlvAddress2 = Company.Address2;
|
||||
Activity.DlvZipCode = Company.ZipCode;
|
||||
Activity.DlvCity = Company.City;
|
||||
|
||||
// Initialize date variable
|
||||
Logger.LogDebug("AdvisorActivityCreatePage => DateTime parser => {}", UserPreference.WorkDate);
|
||||
SelectedDate = string.IsNullOrWhiteSpace(UserPreference.WorkDate)
|
||||
? DateTime.Now
|
||||
: DateTime.Parse(UserPreference.WorkDate);
|
||||
|
||||
// raise flag if report is closed
|
||||
ReportClosed = await ReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
|
||||
|
||||
// Ask for confirmation of date
|
||||
Logger.LogDebug("Preferences.DateConfirmed => {}", UserPreference.DateConfirmed);
|
||||
if (!UserPreference.DateConfirmed)
|
||||
|
@ -299,6 +302,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
|
||||
// #############################################################
|
||||
// callbacks
|
||||
// pricelist callback
|
||||
private async Task PriceListCallback(SelectedSku sku)
|
||||
{
|
||||
// get selected item
|
||||
|
@ -311,7 +315,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
// price history callback
|
||||
private void PriceHistoryCallback(decimal price)
|
||||
{
|
||||
if (price == 0)
|
||||
|
@ -320,7 +324,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
// inventory callback
|
||||
private void OnInventoryCallback(DraftItem item)
|
||||
{
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
|
@ -329,7 +333,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
// confirm product check callback
|
||||
private async Task ConfirmProductCheckCallback()
|
||||
{
|
||||
ConfirmationCheckOverlay.Hide();
|
||||
|
@ -338,11 +342,10 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
{
|
||||
item.Check = false;
|
||||
}
|
||||
|
||||
await Storage.SetItemAsync($"{CompanyId}-products", CheckList);
|
||||
}
|
||||
|
||||
|
||||
// workdate confirm callback
|
||||
private async Task WorkDateConfirmCallback()
|
||||
{
|
||||
await PreferenceService.SetDateConfirmed(true);
|
||||
|
@ -351,7 +354,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
// workdate changed callback
|
||||
private async Task WorkDateChangedCallback(string workDate)
|
||||
{
|
||||
ReportClosed = await ReportRepo.ReportExist(workDate);
|
||||
|
@ -362,6 +365,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
|
||||
// ################################################################################################
|
||||
// fetch invoices for customer
|
||||
// save invoices to storage
|
||||
private async Task<InvoiceListView> FetchCompanyInvoices()
|
||||
{
|
||||
// no need to do for kanvas entry
|
||||
|
|
|
@ -21,6 +21,27 @@
|
|||
@page "/advisor/customers/{CompanyId}"
|
||||
<PageTitle>Kundekort for @Company.Name</PageTitle>
|
||||
|
||||
@*
|
||||
<div class="led-container">
|
||||
<div class="led-box">
|
||||
<div class="led-green"></div>
|
||||
<p>Green LED</p>
|
||||
</div>
|
||||
<div class="led-box">
|
||||
<div class="led-yellow"></div>
|
||||
<p>Yellow LED</p>
|
||||
</div>
|
||||
<div class="led-box">
|
||||
<div class="led-red"></div>
|
||||
<p>Red LED</p>
|
||||
</div>
|
||||
<div class="led-box">
|
||||
<div class="led-blue"></div>
|
||||
<p>Blue LED</p>
|
||||
</div>
|
||||
</div>
|
||||
*@
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Account))
|
||||
{
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Blocked))
|
||||
|
@ -95,7 +116,29 @@
|
|||
|
||||
@if (!Kanvas)
|
||||
{
|
||||
<div class="col-sm-4">@* ---- placeholder --- *@</div>
|
||||
@if (AppInfo.Value.Rc)
|
||||
{
|
||||
<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="@Company.Segment">
|
||||
<option value="" disabled>segment</option>
|
||||
<option value="1">AUTO</option>
|
||||
<option value="2">INDUSTRI</option>
|
||||
</InputSelect>
|
||||
@* <ValidationMessage For="@(() => )"></ValidationMessage> *@
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<div class="led-box" style="display:@(DateTime.Now < DateTime.Parse("2023-10-01") ? "block" : "none")">
|
||||
<div class="led-red"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-sm-4">
|
||||
@* placeholder *@
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Enable edit/save *@
|
||||
<div class="col-sm-2 d-grid mx-auto">
|
||||
|
@ -110,7 +153,7 @@
|
|||
<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*@
|
||||
<label for="vatNumber" class="col-sm-1 col-form-label-sm">CVR/Org nr.</label>
|
||||
<label for="vatNumber" class="col-sm-1 col-form-label-sm">ORG nr.</label>
|
||||
<div class="col-sm-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">
|
||||
|
@ -122,7 +165,7 @@
|
|||
</div>
|
||||
@* Enable edit/save vatnumber *@
|
||||
<div class="col-sm-2 d-grid mx-auto">
|
||||
<button type="button" class="btn btn-edit" @onclick="ToggleVatEdit"><i class="bi-pencil"></i> Moms/Org Nr.</button>
|
||||
<button type="button" class="btn btn-edit" @onclick="ToggleVatEdit"><i class="bi-pencil"></i> ORG Nr.</button>
|
||||
</div>
|
||||
@* vat lookup *@
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"appInfo": {
|
||||
"name": "Wonky Online",
|
||||
"version": "0.135.1",
|
||||
"version": "0.135.4",
|
||||
"rc": true,
|
||||
"sandBox": false,
|
||||
"image": "grumpy-coder.png"
|
||||
|
|
|
@ -103,6 +103,114 @@ a, .btn-link {
|
|||
|
||||
/* end state elements */
|
||||
|
||||
/* led elements */
|
||||
.led-box {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: auto;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.led-red {
|
||||
margin: 5px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: #F00;
|
||||
border-radius: 50%;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 12px;
|
||||
-webkit-animation: blinkRed 0.5s infinite;
|
||||
-moz-animation: blinkRed 0.5s infinite;
|
||||
-ms-animation: blinkRed 0.5s infinite;
|
||||
-o-animation: blinkRed 0.5s infinite;
|
||||
animation: blinkRed 0.5s infinite;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes blinkRed {
|
||||
from { background-color: #F00; }
|
||||
50% { background-color: #A00; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 0;}
|
||||
to { background-color: #F00; }
|
||||
}
|
||||
@-moz-keyframes blinkRed {
|
||||
from { background-color: #F00; }
|
||||
50% { background-color: #A00; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 0;}
|
||||
to { background-color: #F00; }
|
||||
}
|
||||
@-ms-keyframes blinkRed {
|
||||
from { background-color: #F00; }
|
||||
50% { background-color: #A00; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 0;}
|
||||
to { background-color: #F00; }
|
||||
}
|
||||
@-o-keyframes blinkRed {
|
||||
from { background-color: #F00; }
|
||||
50% { background-color: #A00; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 0;}
|
||||
to { background-color: #F00; }
|
||||
}
|
||||
@keyframes blinkRed {
|
||||
from { background-color: #F00; }
|
||||
50% { background-color: #A00; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 0;}
|
||||
to { background-color: #F00; }
|
||||
}
|
||||
|
||||
.led-yellow {
|
||||
margin: 0 auto;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: #FF0;
|
||||
border-radius: 50%;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 12px;
|
||||
-webkit-animation: blinkYellow 1s infinite;
|
||||
-moz-animation: blinkYellow 1s infinite;
|
||||
-ms-animation: blinkYellow 1s infinite;
|
||||
-o-animation: blinkYellow 1s infinite;
|
||||
animation: blinkYellow 1s infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes blinkYellow {
|
||||
from { background-color: #FF0; }
|
||||
50% { background-color: #AA0; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 0; }
|
||||
to { background-color: #FF0; }
|
||||
}
|
||||
@-moz-keyframes blinkYellow {
|
||||
from { background-color: #FF0; }
|
||||
50% { background-color: #AA0; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 0; }
|
||||
to { background-color: #FF0; }
|
||||
}
|
||||
@-ms-keyframes blinkYellow {
|
||||
from { background-color: #FF0; }
|
||||
50% { background-color: #AA0; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 0; }
|
||||
to { background-color: #FF0; }
|
||||
}
|
||||
@-o-keyframes blinkYellow {
|
||||
from { background-color: #FF0; }
|
||||
50% { background-color: #AA0; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 0; }
|
||||
to { background-color: #FF0; }
|
||||
}
|
||||
@keyframes blinkYellow {
|
||||
from { background-color: #FF0; }
|
||||
50% { background-color: #AA0; box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 0; }
|
||||
to { background-color: #FF0; }
|
||||
}
|
||||
|
||||
.led-green {
|
||||
margin: 0 auto;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: #ABFF00;
|
||||
border-radius: 50%;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #89FF00 0 2px 12px;
|
||||
}
|
||||
|
||||
.led-blue {
|
||||
margin: 0 auto;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: #24E0FF;
|
||||
border-radius: 50%;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #006 0 -1px 9px, #3F8CFF 0 2px 14px;
|
||||
}
|
||||
|
||||
/* end led elements */
|
||||
|
||||
/*#blazor-error-ui {*/
|
||||
/* background: lightyellow;*/
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<link href="/bootstrap/css/bootstrap-icons.css" rel="stylesheet" />
|
||||
<link href="/flag-icons/flag-icons.css" rel="stylesheet" />
|
||||
<link href="/css/app.css" rel="stylesheet" />
|
||||
<link href="/css/led.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" />
|
||||
|
|
|
@ -61,6 +61,11 @@ public class CompanyDto
|
|||
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
||||
public string City { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Customer Group
|
||||
/// </summary>
|
||||
public string Segment { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Company Id
|
||||
/// </summary>
|
||||
|
@ -76,6 +81,11 @@ public class CompanyDto
|
|||
/// </summary>
|
||||
public string CrmNotes { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Ean number
|
||||
/// </summary>
|
||||
public string EanNumber { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Office email
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in a new issue