wip - refactor and adding functionality
This commit is contained in:
parent
b0651d2ea6
commit
f731bc4b58
38 changed files with 1076 additions and 783 deletions
|
@ -1,6 +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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
@if (Enabled == 1)
|
@if (Enabled == 1)
|
||||||
{
|
{
|
||||||
<a type="button" class="btn btn-success" href="/company/@CompanyId/activity">Besøg</a>
|
<a type="button" class="btn btn-success" href="/companies/@CompanyId/activities/new">Besøg</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
45
Wonky.Client/Components/ActivityTableComponent.razor
Normal file
45
Wonky.Client/Components/ActivityTableComponent.razor
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
@*
|
||||||
|
// 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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
|
@if (Activities.Any())
|
||||||
|
{
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<th scope="col">Besøg</th>
|
||||||
|
<th scope="col">Demo</th>
|
||||||
|
<th scope="col">Salg</th>
|
||||||
|
<th class="text-end" scope="col">Beløb</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var activity in Activities)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@activity.Company.Name, @activity.Company.ZipCity</td>
|
||||||
|
<td>@activity.Demo</td>
|
||||||
|
<td>@activity.SalesResume</td>
|
||||||
|
<td class="text-end">@activity.OrderAmount</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<AppSpinner/>
|
||||||
|
}
|
9
Wonky.Client/Components/ActivityTableComponent.razor.cs
Normal file
9
Wonky.Client/Components/ActivityTableComponent.razor.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
|
namespace Wonky.Client.Components;
|
||||||
|
|
||||||
|
public partial class ActivityTableComponent
|
||||||
|
{
|
||||||
|
[Parameter] public List<NgReportActivityView> Activities { get; set; }
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@<div>
|
*@
|
||||||
<img class="spinner pe-3" src="loader.gif" alt="Afventer svar fra netværk ..."/> Venter ...
|
<div>
|
||||||
|
<img class="spinner pe-3" src="loader.gif" alt="Venter på svar ..."/> Afventer server ...
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
|
|
||||||
<span class="version">@_app?.Version</span>@if(_app!.IsBeta){<span class="version">-beta</span>}
|
<span class="version">@_app?.Version</span>@if(_app!.IsBeta){<span class="version">-beta</span>}
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -20,42 +20,32 @@
|
||||||
|
|
||||||
@if (Companies.Any())
|
@if (Companies.Any())
|
||||||
{
|
{
|
||||||
<table class="table">
|
<div class="list-group list-group-flush">
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col"></th>
|
|
||||||
<th scope="col">Navn</th>
|
|
||||||
<th scope="col">Konto</th>
|
|
||||||
<th scope="col">Bynavn</th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var company in Companies)
|
@foreach (var company in Companies)
|
||||||
{
|
{
|
||||||
<tr>
|
<a class="list-group-item list-group-item-action" href="/companies/@company.CompanyId">
|
||||||
<td class="align-middle">
|
<div class="row align-items-center">
|
||||||
<DisplayStateComponent StateClass="@(company.HasFolded == 1
|
<div class="col-sm-1">
|
||||||
? "the-dead" : Utils.GetVisitState(company.NextVisit))">
|
<DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.GetVisitState(company.NextVisit))">
|
||||||
</DisplayStateComponent>
|
</DisplayStateComponent>
|
||||||
</td>
|
</div>
|
||||||
<td class="align-middle">
|
<div class="col">
|
||||||
@company.Name
|
@company.Name
|
||||||
</td>
|
</div>
|
||||||
<td class="align-middle">
|
<div class="col">
|
||||||
@company.Account
|
@company.Account
|
||||||
</td>
|
</div>
|
||||||
<td class="align-middle">
|
<div class="col">
|
||||||
@company.City
|
@company.City
|
||||||
</td>
|
</div>
|
||||||
<td class="align-middle">
|
<div class="col">
|
||||||
<a class="btn btn-edit" href="/company/@company.CompanyId/update">Rediger</a>
|
|
||||||
<ActivityButton CompanyId="@company.CompanyId" Enabled="@company.ValidVat"></ActivityButton>
|
<ActivityButton CompanyId="@company.CompanyId" Enabled="@company.ValidVat"></ActivityButton>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
}
|
}
|
||||||
</tbody>
|
</div>
|
||||||
</table>
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,5 @@
|
||||||
<WorkDateComponent OnChanged="GetCalender"></WorkDateComponent>
|
<WorkDateComponent OnChanged="GetCalender"></WorkDateComponent>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
135
Wonky.Client/Components/ReportSummaryComponent.razor
Normal file
135
Wonky.Client/Components/ReportSummaryComponent.razor
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
@*
|
||||||
|
// 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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<th></th>
|
||||||
|
<th class="text-center" colspan="2" scope="col">Dagens Demo @(Report.NewDemoCount + Report.RecallDemoCount)</th>
|
||||||
|
<th class="text-center border-end" colspan="2" scope="col">Dagens Resultat</th>
|
||||||
|
<th class="text-center" colspan="4" scope="col">Måneds Resultat</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="bg-dark bg-opacity-50">
|
||||||
|
<td></td>
|
||||||
|
<th class="text-end text-white" scope="col">Besøg</th>
|
||||||
|
<th class="text-end text-white" scope="col">Demo</th>
|
||||||
|
<th class="text-end text-white" scope="col">Salg</th>
|
||||||
|
<th class="text-end text-white border-end" scope="col">Beløb</th>
|
||||||
|
<th class="text-end text-white" scope="col">Besøg</th>
|
||||||
|
<th class="text-end text-white" scope="col">Demo</th>
|
||||||
|
<th class="text-end text-white" scope="col">Salg</th>
|
||||||
|
<th class="text-end text-white" scope="col">Beløb</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">N</th>
|
||||||
|
<td class="text-end">@Report.NewVisitCount</td>
|
||||||
|
<td class="text-end">@Report.NewDemoCount</td>
|
||||||
|
<td class="text-end">@Report.NewSaleCount</td>
|
||||||
|
<td class="text-end border-end">@Report.NewTurnover</td>
|
||||||
|
<td class="text-end">@Report.NewVisitCountMonth</td>
|
||||||
|
<td class="text-end">@Report.NewDemoCountMonth</td>
|
||||||
|
<td class="text-end">@Report.NewSaleCountMonth</td>
|
||||||
|
<td class="text-end">@Report.NewTurnoverMonth</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">R</th>
|
||||||
|
<td class="text-end">@Report.RecallVisitCount</td>
|
||||||
|
<td class="text-end">@Report.RecallDemoCount</td>
|
||||||
|
<td class="text-end">@Report.RecallSaleCount</td>
|
||||||
|
<td class="text-end border-end">@Report.RecallTurnover</td>
|
||||||
|
<td class="text-end">@Report.RecallVisitCountMonth</td>
|
||||||
|
<td class="text-end">@Report.RecallDemoCountMonth</td>
|
||||||
|
<td class="text-end">@Report.RecallSaleCountMonth</td>
|
||||||
|
<td class="text-end">@Report.RecallTurnoverMonth</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">SAS</th>
|
||||||
|
<td class="bg-light"></td>
|
||||||
|
<td class="bg-light"></td>
|
||||||
|
<td class="text-end">@Report.SasCount</td>
|
||||||
|
<td class="text-end border-end">@Report.SasTurnover</td>
|
||||||
|
<td class="bg-light"></td>
|
||||||
|
<td class="bg-light"></td>
|
||||||
|
<td class="text-end">@Report.SasCountMonth</td>
|
||||||
|
<td class="text-end">@Report.SasTurnoverMonth</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">TOTAL</th>
|
||||||
|
<td class="text-end">@Report.TotalVisitCount</td>
|
||||||
|
<td class="text-end">@Report.TotalDemoCount</td>
|
||||||
|
<td class="text-end">@Report.TotalSaleCount</td>
|
||||||
|
<td class="text-end border-end">@Report.TotalTurnover</td>
|
||||||
|
<td class="text-end">@Report.TotalVisitCountMonth</td>
|
||||||
|
<td class="text-end">@Report.TotalDemoCountMonth</td>
|
||||||
|
<td class="text-end">@Report.TotalSaleCountMonth</td>
|
||||||
|
<td class="text-end">@Report.TotalTurnoverMonth</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<th scope="col">
|
||||||
|
Km Aften
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
Km Morgen
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
Km Kørt Dag
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
Km Kørt Md.
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
Km Privat
|
||||||
|
</th>
|
||||||
|
<th scope="col">
|
||||||
|
Km Privat Md.
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>@Report.KmEvening</td>
|
||||||
|
<td>@Report.KmMorning</td>
|
||||||
|
<td>@Report.Distance</td>
|
||||||
|
<td>@Report.DistanceMonth</td>
|
||||||
|
<td>@Report.DistancePrivate</td>
|
||||||
|
<td>@Report.DistancePrivateMonth</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
@if (!string.IsNullOrWhiteSpace(Report.Description) || !string.IsNullOrWhiteSpace(Report.SupervisedBy))
|
||||||
|
{
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<th class="w-50" scope="col">Tekst</th>
|
||||||
|
<th class="w-50" scope="col">Medkørende Supervisor</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>@Report.Description</td>
|
||||||
|
<td>@Report.SupervisedBy</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
11
Wonky.Client/Components/ReportSummaryComponent.razor.cs
Normal file
11
Wonky.Client/Components/ReportSummaryComponent.razor.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Wonky.Client.Components;
|
||||||
|
|
||||||
|
public partial class ReportSummaryComponent
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public NgSalesReport Report { get; set; }
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
@using System.Security.Claims
|
@using System.Security.Claims
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
<a class="btn btn-outline-light" href="logout">Log af</a>
|
<a class="btn btn-outline-light" href="logout">LOG AF</a>
|
||||||
<a class="btn btn-outline-light" href="info">INFO</a>
|
<a class="btn btn-outline-light" href="info">HJÆLP</a>
|
||||||
</Authorized>
|
</Authorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
|
@ -91,13 +91,17 @@ public class CompanyHttpRepository : ICompanyHttpRepository
|
||||||
return company ?? new CompanyDto();
|
return company ?? new CompanyDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create company from model
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model"></param>
|
||||||
|
/// <returns>company id</returns>
|
||||||
public async Task<string> CreateCompany(CompanyDto model)
|
public async Task<string> CreateCompany(CompanyDto model)
|
||||||
{
|
{
|
||||||
var response = await _client.PostAsJsonAsync($"{_apiConfig.CustomerEndpoint}", model);
|
var response = await _client.PostAsJsonAsync($"{_apiConfig.CustomerEndpoint}", model);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
Console.WriteLine(content);
|
var result = JsonSerializer.Deserialize<CompanyDto>(content, _options);
|
||||||
var result = JsonSerializer.Deserialize<CompanyDto>(content);
|
return result.CompanyId;
|
||||||
return result == null ? "" : result.CompanyId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateCompany(string companyId, CompanyDto model)
|
public async Task<bool> UpdateCompany(string companyId, CompanyDto model)
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Wonky.Client.HttpRepository;
|
||||||
public interface IReportHttpRepository
|
public interface IReportHttpRepository
|
||||||
{
|
{
|
||||||
Task<bool> ReportExist(string workDate);
|
Task<bool> ReportExist(string workDate);
|
||||||
|
Task<List<NgSalesReport>> GetReports();
|
||||||
Task<NgSalesReportView> GetReport(string workDate);
|
Task<NgSalesReportView> GetReport(string workDate);
|
||||||
Task<ReportInitDto> InitializeReportData(string workDate);
|
Task<ReportInitDto> InitializeReportData(string workDate);
|
||||||
Task<ApiResponse> PostReport(string workDate, ReportDto reportDto);
|
Task<ApiResponse> PostReport(string workDate, ReportDto reportDto);
|
||||||
|
|
|
@ -30,6 +30,14 @@ public class ReportHttpRepository :IReportHttpRepository
|
||||||
_apiConfig = configuration.Value;
|
_apiConfig = configuration.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<NgSalesReport>> GetReports()
|
||||||
|
{
|
||||||
|
var response = await _client.GetStringAsync($"{_apiConfig.ReportEndpoint}");
|
||||||
|
Console.WriteLine(response);
|
||||||
|
|
||||||
|
return new List<NgSalesReport>();
|
||||||
|
|
||||||
|
}
|
||||||
public async Task<bool> ReportExist(string workDate)
|
public async Task<bool> ReportExist(string workDate)
|
||||||
{
|
{
|
||||||
var result =
|
var result =
|
||||||
|
|
374
Wonky.Client/Pages/ActivityCompanyCreate.razor
Normal file
374
Wonky.Client/Pages/ActivityCompanyCreate.razor
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
@*
|
||||||
|
// 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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
|
@page "/companies/{companyId}/activities/new"
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
|
@using Wonky.Client.Components
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row align-items-md-center">
|
||||||
|
<div class="col">
|
||||||
|
<h3 class="workDate">@_workDate.ToLongDateString()</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<WorkDateComponent OnChanged="SetWorkDate"></WorkDateComponent>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<EditForm EditContext="_editContext">
|
||||||
|
<DataAnnotationsValidator/>
|
||||||
|
<div class="accordion-flush" id="crmActivity">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="activityHeader">
|
||||||
|
<button class="accordion-button bg-light" type="button"
|
||||||
|
data-bs-toggle="collapse" data-bs-target="#activityBody"
|
||||||
|
aria-expanded="true" aria-controls="activityBody">
|
||||||
|
@_draft.Name - @_draft.Account
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="activityBody" class="accordion-collapse collapse show"
|
||||||
|
aria-labelledby="activityHeader" data-bs-parent="#crmActivity">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="activityType" class="col-md-2 col-form-label">Ordre Type</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputSelect id="activityType" class="form-select" @bind-Value="@_draft.ActivityTypeEnum">
|
||||||
|
<option value="">ORDRE TYPE</option>
|
||||||
|
<option value="onSite">Besøg</option>
|
||||||
|
<option value="phone">Telefon</option>
|
||||||
|
</InputSelect>
|
||||||
|
<ValidationMessage For="@(() => _draft.ActivityTypeEnum)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
<label for="statusType" class="col-md-2 col-form-label">Status</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputSelect id="statusType" class="form-select" @bind-Value="@_draft.ActivityStatusEnum">
|
||||||
|
<option value="noSale" selected>Ingen salg</option>
|
||||||
|
<option value="order">Bestilling</option>
|
||||||
|
<option value="quote">Tilbud</option>
|
||||||
|
</InputSelect>
|
||||||
|
<ValidationMessage For="@(() => _draft.ActivityStatusEnum)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="demo" class="col-md-2 col-form-label">Demo</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputText id="demo" class="form-control" @bind-Value="_draft.Demo"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.Demo)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
<label for="email" class="col-md-2 col-form-label">Epost</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputText id="email" class="form-control" @bind-Value="_draft.EMail"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.EMail)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputText id="referenceNumber" class="form-control"
|
||||||
|
@bind-Value="_draft.ReferenceNumber"v/>
|
||||||
|
<ValidationMessage For="@(() => _draft.ReferenceNumber)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputText id="yourRef" class="form-control"
|
||||||
|
@bind-Value="_draft.YourRef"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.YourRef)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="orderMessage" class="col-md-2 col-form-label">Note /Kontor</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputTextArea id="orderMessage" class="form-control"
|
||||||
|
@bind-Value="_draft.OrderMessage"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.OrderMessage)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
<label for="crmNote" class="col-md-2 col-form-label">Note /Mig</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputTextArea id="crmNote" class="form-control"
|
||||||
|
@bind-Value="_draft.CrmNote"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.CrmNote)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="attention" class="col-md-2 col-form-label">Att.</label>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<InputText id="attention" class="form-control"
|
||||||
|
@bind-Value="_draft.Attention"/>
|
||||||
|
<ValidationMessage For="@(() => _draft.Attention)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* Order lines *@
|
||||||
|
<div class="accordion-item" style="@(_draft.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
|
||||||
|
<h2 class="accordion-header" id="catalogHeader">
|
||||||
|
<button class="accordion-button collapsed bg-light" type="button"
|
||||||
|
data-bs-toggle="collapse" data-bs-target="#catalogBody"
|
||||||
|
aria-expanded="false" aria-controls="catalogBody">
|
||||||
|
Varelinjer
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="catalogBody" class="accordion-collapse collapse"
|
||||||
|
aria-labelledby="catalogHeader" data-bs-parent="#crmActivity">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row mb-1">
|
||||||
|
<div class="col">
|
||||||
|
<ItemGroupComponent OnChanged="SetItemGroup"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<ItemSearchComponent OnChanged="SetSearchCol"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<SearchPhrase OnChanged="SetSearchPhrase"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<ItemSortComponent OnChanged="SetSortCol"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<PageSizeComponent OnChanged="SetPageSize"></PageSizeComponent>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<PaginationComponent MetaData="_metaData" Spread="2" SelectedPage="SelectedPage"></PaginationComponent>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (_caltalog.Any())
|
||||||
|
{
|
||||||
|
<table class="table table-hover table-striped justify-content-center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Navn</th>
|
||||||
|
<th scope="col" class="text-nowrap">Varenr</th>
|
||||||
|
<th scope="col" class="text-nowrap">Fork</th>
|
||||||
|
<th scope="col">Stk / Pris</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var item in _caltalog)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@item.Name</td>
|
||||||
|
<td>@item.Sku</td>
|
||||||
|
<td>@item.ShortName</td>
|
||||||
|
<td>
|
||||||
|
<ul class="list-group">
|
||||||
|
@foreach (var rate in item.Rates)
|
||||||
|
{
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-end">
|
||||||
|
<div class="text-sm-start px-2">@rate.Quantity</div>
|
||||||
|
<div class="text-sm-end">@rate.Rate</div>
|
||||||
|
<button type="button" class="btn btn-primary btn-sm"
|
||||||
|
@onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">
|
||||||
|
Vælg
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<AppSpinner/>
|
||||||
|
}
|
||||||
|
@if (_selectedItem != null && ShowItem)
|
||||||
|
{
|
||||||
|
<div class="card mb-3 mt-3">
|
||||||
|
<div class="card-header bg-dark fw-bold text-white">Kladdelinje</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-4 fw-bold">
|
||||||
|
Varenavn
|
||||||
|
</div>
|
||||||
|
<div class="col fw-bold">
|
||||||
|
Varenr
|
||||||
|
</div>
|
||||||
|
<div class="col fw-bold">
|
||||||
|
Antal
|
||||||
|
</div>
|
||||||
|
<div class="col fw-bold">
|
||||||
|
Pris
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
Rabat
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
SAS
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-4">
|
||||||
|
@_selectedItem.Name
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
@_selectedItem.Sku
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input type="number" class="form-control" @bind-value="@Quantity"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input type="number" class="form-control" @bind-value="@Price"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input type="number" class="form-control" @bind-value="@Discount"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button type="button" class="btn btn-info" @onclick="@(() => AddItem(_selectedItem))">Læg til</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@* Order draft lines *@
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
Kladdelinjer <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftStateProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover table-striped justify-content-center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<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-end">Linjesum</th>
|
||||||
|
<th scope="col"> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if (DraftStateProvider != null && DraftStateProvider.Draft.Items.Count > 0)
|
||||||
|
{
|
||||||
|
@foreach (var cItem in DraftStateProvider.Draft.Items)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@cItem.Item.Name</td>
|
||||||
|
<td>@cItem.Item.Sku</td>
|
||||||
|
<td class="text-end">@cItem.Quantity</td>
|
||||||
|
<td class="text-end">@cItem.Price</td>
|
||||||
|
<td class="text-end">@cItem.LineTotal</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" checked="@cItem.Sas" disabled/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-warning" @onclick="@(() => RemoveItem(@cItem))">Slet</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="text-black text-end fw-bold">Total</td>
|
||||||
|
<td class="text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<button type="button" class="btn btn-danger"
|
||||||
|
@onclick="@DeleteDraft"
|
||||||
|
disabled="@(DraftStateProvider.Draft.Items.Count == 0)">
|
||||||
|
Slet kladde
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* Delivery address *@
|
||||||
|
<div class="accordion-item" style="@(_draft.ActivityStatusEnum == "order" ? "display: block" : "display:none")">
|
||||||
|
<h2 class="accordion-header" id="deliveryHeader">
|
||||||
|
<button class="accordion-button collapsed bg-light" type="button"
|
||||||
|
data-bs-toggle="collapse" data-bs-target="#deliveryBody"
|
||||||
|
aria-expanded="false" aria-controls="deliveryBody">
|
||||||
|
Leveringsadresse
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="deliveryBody" class="accordion-collapse collapse"
|
||||||
|
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="dlvName" class="col-md-2 col-form-label">Lev. Navn</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<InputText id="dlvName" class="form-control" @bind-Value="_draft.DlvName"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="dlvAddress1" class="col-md-2 col-form-label">Lev. Adresse</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<InputText id="dlvAddress1" class="form-control" @bind-Value="_draft.DlvAddress1"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="dlvAddress2" class="col-md-2 col-form-label">Lev. Adresse</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<InputText id="dlvAddress2" class="form-control" @bind-Value="_draft.DlvAddress2"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="dlvZipCode" class="col-md-2 col-form-label">Lev. Postnr</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<InputText id="dlvZipCode" class="form-control" @bind-Value="_draft.DlvZipCode"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1">
|
||||||
|
<label for="dlvCity" class="col-md-2 col-form-label">Lev. Bynavn</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<InputText id="dlvCity" class="form-control" @bind-Value="_draft.DlvCity"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2 mb-2">
|
||||||
|
<div class="col">
|
||||||
|
<a class="btn btn-primary" href="/companies">Til Oversigt</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a class="btn btn-primary" href="/company/@_company.CompanyId">Tilbage</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
@* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@
|
||||||
|
<button type="button" class="btn btn-success" @onclick="CreateActivity">Opret besøg</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -30,10 +30,10 @@ using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.Pages;
|
namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
public partial class ActivityCreate : IDisposable
|
public partial class ActivityCompanyCreate : IDisposable
|
||||||
{
|
{
|
||||||
// todo: prevent creating activity for workDate with closed report
|
// todo: prevent creating activity for workDate with closed report
|
||||||
[Inject] private ILogger<ActivityCreate> _logger { get; set; }
|
[Inject] private ILogger<ActivityCompanyCreate> _logger { get; set; }
|
||||||
[Inject] private IToastService _toast { get; set; }
|
[Inject] private IToastService _toast { get; set; }
|
||||||
[Inject] private NavigationManager _navigator { get; set; }
|
[Inject] private NavigationManager _navigator { get; set; }
|
||||||
[Inject] private ILocalStorageService _storage { get; set; }
|
[Inject] private ILocalStorageService _storage { get; set; }
|
||||||
|
@ -50,13 +50,13 @@ public partial class ActivityCreate : IDisposable
|
||||||
PropertyNameCaseInsensitive = true
|
PropertyNameCaseInsensitive = true
|
||||||
};
|
};
|
||||||
private NgSalesItemView _selectedItem { get; set; } = new();
|
private NgSalesItemView _selectedItem { get; set; } = new();
|
||||||
private List<NgSalesItemView> SalesItems { get; set; } = new();
|
private List<NgSalesItemView> _caltalog { get; set; } = new();
|
||||||
private MetaData MetaData { get; set; } = new();
|
private MetaData _metaData { get; set; } = new();
|
||||||
private Preferences _prefs { get; set; } = new();
|
private Preferences _prefs { get; set; } = new();
|
||||||
private ActivityDto _poDraft { get; set; } = new();
|
private ActivityDto _draft { get; set; } = new();
|
||||||
private CompanyDto NgCompany = new();
|
private CompanyDto _company = new();
|
||||||
private CatalogPagingParams _paging = new();
|
private CatalogPagingParams _paging = new();
|
||||||
private EditContext DraftContext { get; set; }
|
private EditContext _editContext { get; set; }
|
||||||
private bool _poFormInvalid { get; set; } = true;
|
private bool _poFormInvalid { get; set; } = true;
|
||||||
private bool ShowItem { get; set; }
|
private bool ShowItem { get; set; }
|
||||||
private bool HideButtons { get; set; }
|
private bool HideButtons { get; set; }
|
||||||
|
@ -72,61 +72,67 @@ public partial class ActivityCreate : IDisposable
|
||||||
private UserInfoView Ux { get; set; } = new();
|
private UserInfoView Ux { get; set; } = new();
|
||||||
private DateTime _workDate { get; set; } = DateTime.Now;
|
private DateTime _workDate { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
_interceptor.RegisterEvent();
|
|
||||||
_interceptor.RegisterBeforeSendEvent();
|
|
||||||
|
|
||||||
_prefs = await _userPrefs.GetPreferences();
|
_prefs = await _userPrefs.GetPreferences();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(_prefs.WorkDate))
|
if (!string.IsNullOrWhiteSpace(_prefs.WorkDate))
|
||||||
_workDate = DateTime.Parse(_prefs.WorkDate);
|
_workDate = DateTime.Parse(_prefs.WorkDate);
|
||||||
|
|
||||||
_poDraft.ActivityDate = $"{_workDate:yyyy-MM-dd}" ;
|
// raise flag if report is closed
|
||||||
|
_reportClosdd = await _reportRepo.ReportExist($"{_workDate:yyyy-MM-dd}");
|
||||||
|
if(_reportClosdd)
|
||||||
|
_navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
|
||||||
|
|
||||||
// check if report is closed
|
}
|
||||||
|
|
||||||
_reportClosdd = await _reportRepo.ReportExist(_poDraft.ActivityDate);
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_editContext = new EditContext(_draft);
|
||||||
|
_editContext.OnFieldChanged += HandleFieldChanged;
|
||||||
|
_editContext.OnValidationStateChanged += ValidationChanged;
|
||||||
|
|
||||||
|
_interceptor.RegisterEvent();
|
||||||
|
_interceptor.RegisterBeforeSendEvent();
|
||||||
|
|
||||||
|
_draft.ActivityDate = $"{_workDate:yyyy-MM-dd}" ;
|
||||||
|
|
||||||
|
// todo - does it make sense to continue if _reportClosed is true?
|
||||||
_paging.SearchColumn = _prefs.ItemSearch ?? "name";
|
_paging.SearchColumn = _prefs.ItemSearch ?? "name";
|
||||||
_paging.PageSize = Convert.ToInt32(_prefs.PageSize);
|
_paging.PageSize = Convert.ToInt32(_prefs.PageSize);
|
||||||
|
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
|
|
||||||
Ux = await _storage.GetItemAsync<UserInfoView>("_xu");
|
Ux = await _storage.GetItemAsync<UserInfoView>("_xu");
|
||||||
NgCompany = await _companyRepo.GetCompanyById(CompanyId);
|
_company = await _companyRepo.GetCompanyById(CompanyId);
|
||||||
|
|
||||||
DraftContext = new EditContext(_poDraft);
|
|
||||||
DraftContext.OnFieldChanged += HandleFieldChanged;
|
|
||||||
DraftContext.OnValidationStateChanged += ValidationChanged;
|
|
||||||
|
|
||||||
// set up identification
|
// set up identification
|
||||||
_poDraft.CompanyId = NgCompany.CompanyId;
|
_draft.CompanyId = _company.CompanyId;
|
||||||
_poDraft.BcId = NgCompany.BcId;
|
_draft.BcId = _company.BcId;
|
||||||
_poDraft.SalesRepId = Ux.Id;
|
_draft.SalesRepId = Ux.Id;
|
||||||
|
|
||||||
_poDraft.ActivityStatusEnum = "noSale";
|
_draft.ActivityStatusEnum = "noSale";
|
||||||
_poDraft.VisitTypeEnum = NgCompany.Account is "" or "NY" ? "new" : "recall";
|
_draft.VisitTypeEnum = _company.Account is "" or "NY" ? "new" : "recall";
|
||||||
|
|
||||||
// permanent identifications
|
// permanent identifications
|
||||||
_poDraft.SalesRep = Ux.Adviser;
|
_draft.SalesRep = Ux.Adviser;
|
||||||
_poDraft.Account = NgCompany.Account;
|
_draft.Account = _company.Account;
|
||||||
_poDraft.VatNumber = NgCompany.VatNumber;
|
_draft.VatNumber = _company.VatNumber;
|
||||||
_poDraft.EMail = NgCompany.Email;
|
_draft.EMail = _company.Email;
|
||||||
_poDraft.Phone = NgCompany.Phone;
|
_draft.Phone = _company.Phone;
|
||||||
_poDraft.Mobile = NgCompany.Mobile;
|
_draft.Mobile = _company.Mobile;
|
||||||
|
|
||||||
_poDraft.Name = NgCompany.Name;
|
_draft.Name = _company.Name;
|
||||||
_poDraft.Address1 = NgCompany.Address1;
|
_draft.Address1 = _company.Address1;
|
||||||
_poDraft.Address2 = NgCompany.Address2;
|
_draft.Address2 = _company.Address2;
|
||||||
_poDraft.ZipCode = NgCompany.ZipCode;
|
_draft.ZipCode = _company.ZipCode;
|
||||||
_poDraft.City = NgCompany.City;
|
_draft.City = _company.City;
|
||||||
|
|
||||||
_poDraft.DlvName = NgCompany.Name;
|
_draft.DlvName = _company.Name;
|
||||||
_poDraft.DlvAddress1 = NgCompany.Address1;
|
_draft.DlvAddress1 = _company.Address1;
|
||||||
_poDraft.DlvAddress2 = NgCompany.Address2;
|
_draft.DlvAddress2 = _company.Address2;
|
||||||
_poDraft.DlvZipCode = NgCompany.ZipCode;
|
_draft.DlvZipCode = _company.ZipCode;
|
||||||
_poDraft.DlvCity = NgCompany.City;
|
_draft.DlvCity = _company.City;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,21 +140,21 @@ public partial class ActivityCreate : IDisposable
|
||||||
{
|
{
|
||||||
_logger.LogInformation("WorkDateComponent.OnChanged(SetWorkDate(workDate)) => {workDate}", workDate);
|
_logger.LogInformation("WorkDateComponent.OnChanged(SetWorkDate(workDate)) => {workDate}", workDate);
|
||||||
_workDate = DateTime.Parse(workDate);
|
_workDate = DateTime.Parse(workDate);
|
||||||
_poDraft.ActivityDate = workDate;
|
_draft.ActivityDate = workDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateActivity()
|
private async Task CreateActivity()
|
||||||
{
|
{
|
||||||
HideButtons = true;
|
HideButtons = true;
|
||||||
_poDraft.ActivityDate = _prefs.WorkDate;
|
_draft.ActivityDate = _prefs.WorkDate;
|
||||||
|
|
||||||
var activityType = _poDraft.ActivityTypeEnum switch
|
var activityType = _draft.ActivityTypeEnum switch
|
||||||
{
|
{
|
||||||
"phone" => "T",
|
"phone" => "T",
|
||||||
"onSite" => "B",
|
"onSite" => "B",
|
||||||
_ => ""
|
_ => ""
|
||||||
};
|
};
|
||||||
_poDraft.OurRef = $"{activityType}:{Ux.FullName.Split(" ")[0]}";
|
_draft.OurRef = $"{activityType}:{Ux.FullName.Split(" ")[0]}";
|
||||||
var ln = 0;
|
var ln = 0;
|
||||||
|
|
||||||
// post to create activity endpoint
|
// post to create activity endpoint
|
||||||
|
@ -168,18 +174,18 @@ public partial class ActivityCreate : IDisposable
|
||||||
};
|
};
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
}
|
}
|
||||||
_poDraft.Lines = lines;
|
_draft.Lines = lines;
|
||||||
|
|
||||||
await _storage.SetItemAsync(CompanyId, _poDraft);
|
await _storage.SetItemAsync(CompanyId, _draft);
|
||||||
Console.WriteLine(JsonSerializer.Serialize(_poDraft));
|
Console.WriteLine(JsonSerializer.Serialize(_draft));
|
||||||
var result = await _activityRepo.CreateActivity(_poDraft);
|
var result = await _activityRepo.CreateActivity(_draft);
|
||||||
_toast.ShowSuccess($"{result.Message}.");
|
_toast.ShowSuccess($"{result.Message}.");
|
||||||
_navigator.NavigateTo($"/companies");
|
_navigator.NavigateTo($"/companies");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckActivity()
|
private void CheckActivity()
|
||||||
{
|
{
|
||||||
InvalidActivityType = string.IsNullOrWhiteSpace(_poDraft.ActivityTypeEnum);
|
InvalidActivityType = string.IsNullOrWhiteSpace(_draft.ActivityTypeEnum);
|
||||||
}
|
}
|
||||||
private async Task DeleteDraft()
|
private async Task DeleteDraft()
|
||||||
{
|
{
|
||||||
|
@ -189,7 +195,7 @@ public partial class ActivityCreate : IDisposable
|
||||||
private void SelectItem(string itemId, string quantity, string price)
|
private void SelectItem(string itemId, string quantity, string price)
|
||||||
{
|
{
|
||||||
ShowItem = true;
|
ShowItem = true;
|
||||||
_selectedItem = (from x in SalesItems where x.ItemId == itemId select x).First();
|
_selectedItem = (from x in _caltalog where x.ItemId == itemId select x).First();
|
||||||
Price = price;
|
Price = price;
|
||||||
Quantity = quantity;
|
Quantity = quantity;
|
||||||
}
|
}
|
||||||
|
@ -225,14 +231,14 @@ public partial class ActivityCreate : IDisposable
|
||||||
}
|
}
|
||||||
private async Task SetItemGroup(string groupFilter)
|
private async Task SetItemGroup(string groupFilter)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.PageNumber = 1;
|
_paging.PageNumber = 1;
|
||||||
_paging.SelectGroup = groupFilter;
|
_paging.SelectGroup = groupFilter;
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
}
|
}
|
||||||
private async Task SetSearchCol(string columnName)
|
private async Task SetSearchCol(string columnName)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.PageNumber = 1;
|
_paging.PageNumber = 1;
|
||||||
_paging.SearchTerm = "";
|
_paging.SearchTerm = "";
|
||||||
_paging.SearchColumn = columnName;
|
_paging.SearchColumn = columnName;
|
||||||
|
@ -240,27 +246,27 @@ public partial class ActivityCreate : IDisposable
|
||||||
}
|
}
|
||||||
private async Task SetSortCol(string orderBy)
|
private async Task SetSortCol(string orderBy)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.OrderBy = orderBy;
|
_paging.OrderBy = orderBy;
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
}
|
}
|
||||||
private async Task SetSearchPhrase(string searchTerm)
|
private async Task SetSearchPhrase(string searchTerm)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.PageNumber = 1;
|
_paging.PageNumber = 1;
|
||||||
_paging.SearchTerm = searchTerm;
|
_paging.SearchTerm = searchTerm;
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
}
|
}
|
||||||
private async Task SelectedPage(int page)
|
private async Task SelectedPage(int page)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.PageNumber = page;
|
_paging.PageNumber = page;
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetPageSize(string pageSize)
|
private async Task SetPageSize(string pageSize)
|
||||||
{
|
{
|
||||||
SalesItems = new List<NgSalesItemView>();
|
_caltalog = new List<NgSalesItemView>();
|
||||||
_paging.PageSize = Convert.ToInt32(pageSize);
|
_paging.PageSize = Convert.ToInt32(pageSize);
|
||||||
_paging.PageNumber = 1;
|
_paging.PageNumber = 1;
|
||||||
await GetSalesItems();
|
await GetSalesItems();
|
||||||
|
@ -269,8 +275,8 @@ public partial class ActivityCreate : IDisposable
|
||||||
private async Task GetSalesItems()
|
private async Task GetSalesItems()
|
||||||
{
|
{
|
||||||
var response = await _itemRepo.GetSalesItemsPaged(_paging);
|
var response = await _itemRepo.GetSalesItemsPaged(_paging);
|
||||||
SalesItems = response.Items!;
|
_caltalog = response.Items!;
|
||||||
MetaData = response.MetaData;
|
_metaData = response.MetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
|
@ -287,27 +293,27 @@ public partial class ActivityCreate : IDisposable
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
_poFormInvalid = !DraftContext.Validate();
|
_poFormInvalid = !_editContext.Validate();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_poDraft.ActivityTypeEnum))
|
if (string.IsNullOrEmpty(_draft.ActivityTypeEnum))
|
||||||
_toast.ShowWarning("Aktivitet type kan ikke være tom");
|
_toast.ShowWarning("Aktivitet type kan ikke være tom");
|
||||||
|
|
||||||
_poFormInvalid = false;
|
_poFormInvalid = false;
|
||||||
|
|
||||||
DraftContext.OnFieldChanged -= HandleFieldChanged;
|
_editContext.OnFieldChanged -= HandleFieldChanged;
|
||||||
DraftContext = new EditContext(_poDraft);
|
_editContext = new EditContext(_draft);
|
||||||
DraftContext.OnFieldChanged += HandleFieldChanged;
|
_editContext.OnFieldChanged += HandleFieldChanged;
|
||||||
DraftContext.OnValidationStateChanged -= ValidationChanged;
|
_editContext.OnValidationStateChanged -= ValidationChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_interceptor.DisposeEvent();
|
_interceptor.DisposeEvent();
|
||||||
DraftContext.OnFieldChanged -= HandleFieldChanged;
|
_editContext.OnFieldChanged -= HandleFieldChanged;
|
||||||
DraftContext.OnValidationStateChanged -= ValidationChanged;
|
_editContext.OnValidationStateChanged -= ValidationChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,386 +0,0 @@
|
||||||
@*
|
|
||||||
// Copyright (C) 2022 FCS Frede's Computer Services.
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
|
||||||
//
|
|
||||||
*@
|
|
||||||
|
|
||||||
@page "/company/{companyId}/activity"
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
|
||||||
@using Wonky.Client.Components
|
|
||||||
|
|
||||||
<div class="row mb-2 align-items-center">
|
|
||||||
<div class="col">
|
|
||||||
<h5 style="font-variant: small-caps">@_workDate.ToLongDateString()</h5>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<WorkDateComponent OnChanged="SetWorkDate"></WorkDateComponent>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (_reportClosdd)
|
|
||||||
{
|
|
||||||
<div class="row align-items-md-center">
|
|
||||||
<div class="col">
|
|
||||||
<h5>Rapport for @($"{_workDate:yyyy-MM-dd}") er fundet.</h5>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a class="btn btn-info" href="/sales-report/view/@($"{_workDate:yyyy-MM-dd}")">Vis rapport</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@if (DraftContext != null)
|
|
||||||
{
|
|
||||||
<EditForm EditContext="DraftContext">
|
|
||||||
<DataAnnotationsValidator/>
|
|
||||||
<div class="accordion-flush" id="crmActivity">
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header" id="activityHeader">
|
|
||||||
<button class="accordion-button bg-light" type="button"
|
|
||||||
data-bs-toggle="collapse" data-bs-target="#activityBody"
|
|
||||||
aria-expanded="true" aria-controls="activityBody">
|
|
||||||
@_poDraft.Name - @_poDraft.Account
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="activityBody" class="accordion-collapse collapse show"
|
|
||||||
aria-labelledby="activityHeader" data-bs-parent="#crmActivity">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="activityType" class="col-md-2 col-form-label">Ordre Type</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputSelect id="activityType" class="form-select" @bind-Value="@_poDraft.ActivityTypeEnum">
|
|
||||||
<option value="">ORDRE TYPE</option>
|
|
||||||
<option value="onSite">Besøg</option>
|
|
||||||
<option value="phone">Telefon</option>
|
|
||||||
</InputSelect>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.ActivityTypeEnum)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<label for="statusType" class="col-md-2 col-form-label">Status</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputSelect id="statusType" class="form-select" @bind-Value="@_poDraft.ActivityStatusEnum">
|
|
||||||
<option value="noSale" selected>Ingen salg</option>
|
|
||||||
<option value="order">Bestilling</option>
|
|
||||||
<option value="quote">Tilbud</option>
|
|
||||||
</InputSelect>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.ActivityStatusEnum)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="demo" class="col-md-2 col-form-label">Demo</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputText id="demo" class="form-control" @bind-Value="_poDraft.Demo"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.Demo)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<label for="email" class="col-md-2 col-form-label">Epost</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputText id="email" class="form-control" @bind-Value="_poDraft.EMail"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.EMail)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputText id="referenceNumber" class="form-control"
|
|
||||||
@bind-Value="_poDraft.ReferenceNumber"v/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.ReferenceNumber)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputText id="yourRef" class="form-control"
|
|
||||||
@bind-Value="_poDraft.YourRef"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.YourRef)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="orderMessage" class="col-md-2 col-form-label">Note /Kontor</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputTextArea id="orderMessage" class="form-control"
|
|
||||||
@bind-Value="_poDraft.OrderMessage"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.OrderMessage)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<label for="crmNote" class="col-md-2 col-form-label">Note /Mig</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputTextArea id="crmNote" class="form-control"
|
|
||||||
@bind-Value="_poDraft.CrmNote"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.CrmNote)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="attention" class="col-md-2 col-form-label">Att.</label>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<InputText id="attention" class="form-control"
|
|
||||||
@bind-Value="_poDraft.Attention"/>
|
|
||||||
<ValidationMessage For="@(() => _poDraft.Attention)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@* Order lines *@
|
|
||||||
<div class="accordion-item" style="@(_poDraft.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
|
|
||||||
<h2 class="accordion-header" id="catalogHeader">
|
|
||||||
<button class="accordion-button collapsed bg-light" type="button"
|
|
||||||
data-bs-toggle="collapse" data-bs-target="#catalogBody"
|
|
||||||
aria-expanded="false" aria-controls="catalogBody">
|
|
||||||
Varelinjer
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="catalogBody" class="accordion-collapse collapse"
|
|
||||||
aria-labelledby="catalogHeader" data-bs-parent="#crmActivity">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<div class="row mb-1">
|
|
||||||
<div class="col">
|
|
||||||
<ItemGroupComponent OnChanged="SetItemGroup"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<ItemSearchComponent OnChanged="SetSearchCol"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<SearchPhrase OnChanged="SetSearchPhrase"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<ItemSortComponent OnChanged="SetSortCol"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<PageSizeComponent OnChanged="SetPageSize"></PageSizeComponent>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<PaginationComponent MetaData="MetaData" Spread="2" SelectedPage="SelectedPage"></PaginationComponent>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (SalesItems.Any())
|
|
||||||
{
|
|
||||||
<table class="table table-hover table-striped justify-content-center">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">Navn</th>
|
|
||||||
<th scope="col" class="text-nowrap">Varenr</th>
|
|
||||||
<th scope="col" class="text-nowrap">Fork</th>
|
|
||||||
<th scope="col">Stk / Pris</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var item in SalesItems)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@item.Name</td>
|
|
||||||
<td>@item.Sku</td>
|
|
||||||
<td>@item.ShortName</td>
|
|
||||||
<td>
|
|
||||||
<ul class="list-group">
|
|
||||||
@foreach (var rate in item.Rates)
|
|
||||||
{
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-end">
|
|
||||||
<div class="text-sm-start px-2">@rate.Quantity</div>
|
|
||||||
<div class="text-sm-end">@rate.Rate</div>
|
|
||||||
<button type="button" class="btn btn-primary btn-sm"
|
|
||||||
@onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">
|
|
||||||
Vælg
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<AppSpinner/>
|
|
||||||
}
|
|
||||||
@if (_selectedItem != null && ShowItem)
|
|
||||||
{
|
|
||||||
<div class="card mb-3 mt-3">
|
|
||||||
<div class="card-header bg-dark fw-bold text-white">Kladdelinje</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-4 fw-bold">
|
|
||||||
Varenavn
|
|
||||||
</div>
|
|
||||||
<div class="col fw-bold">
|
|
||||||
Varenr
|
|
||||||
</div>
|
|
||||||
<div class="col fw-bold">
|
|
||||||
Antal
|
|
||||||
</div>
|
|
||||||
<div class="col fw-bold">
|
|
||||||
Pris
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
Rabat
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
SAS
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-4">
|
|
||||||
@_selectedItem.Name
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
@_selectedItem.Sku
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<input type="number" class="form-control" @bind-value="@Quantity"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<input type="number" class="form-control" @bind-value="@Price"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<input type="number" class="form-control" @bind-value="@Discount"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<button type="button" class="btn btn-info" @onclick="@(() => AddItem(_selectedItem))">Læg til</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@* Order draft lines *@
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
Kladdelinjer <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftStateProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<table class="table table-hover table-striped justify-content-center">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<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-end">Linjesum</th>
|
|
||||||
<th scope="col"> </th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@if (DraftStateProvider != null && DraftStateProvider.Draft.Items.Count > 0)
|
|
||||||
{
|
|
||||||
@foreach (var cItem in DraftStateProvider.Draft.Items)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@cItem.Item.Name</td>
|
|
||||||
<td>@cItem.Item.Sku</td>
|
|
||||||
<td class="text-end">@cItem.Quantity</td>
|
|
||||||
<td class="text-end">@cItem.Price</td>
|
|
||||||
<td class="text-end">@cItem.LineTotal</td>
|
|
||||||
<td>
|
|
||||||
<input type="checkbox" checked="@cItem.Sas" disabled/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button type="button" class="btn btn-warning" @onclick="@(() => RemoveItem(@cItem))">Slet</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td class="text-black text-end fw-bold">Total</td>
|
|
||||||
<td class="text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<button type="button" class="btn btn-danger"
|
|
||||||
@onclick="@DeleteDraft"
|
|
||||||
disabled="@(DraftStateProvider.Draft.Items.Count == 0)">
|
|
||||||
Slet kladde
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@* Delivery address *@
|
|
||||||
<div class="accordion-item" style="@(_poDraft.ActivityStatusEnum == "order" ? "display: block" : "display:none")">
|
|
||||||
<h2 class="accordion-header" id="deliveryHeader">
|
|
||||||
<button class="accordion-button collapsed bg-light" type="button"
|
|
||||||
data-bs-toggle="collapse" data-bs-target="#deliveryBody"
|
|
||||||
aria-expanded="false" aria-controls="deliveryBody">
|
|
||||||
Leveringsadresse
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="deliveryBody" class="accordion-collapse collapse"
|
|
||||||
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="dlvName" class="col-md-2 col-form-label">Lev. Navn</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<InputText id="dlvName" class="form-control" @bind-Value="_poDraft.DlvName"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="dlvAddress1" class="col-md-2 col-form-label">Lev. Adresse</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<InputText id="dlvAddress1" class="form-control" @bind-Value="_poDraft.DlvAddress1"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="dlvAddress2" class="col-md-2 col-form-label">Lev. Adresse</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<InputText id="dlvAddress2" class="form-control" @bind-Value="_poDraft.DlvAddress2"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="dlvZipCode" class="col-md-2 col-form-label">Lev. Postnr</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<InputText id="dlvZipCode" class="form-control" @bind-Value="_poDraft.DlvZipCode"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1">
|
|
||||||
<label for="dlvCity" class="col-md-2 col-form-label">Lev. Bynavn</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<InputText id="dlvCity" class="form-control" @bind-Value="_poDraft.DlvCity"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mt-2 mb-2">
|
|
||||||
<div class="col">
|
|
||||||
<a class="btn btn-primary" href="/companies">Til Oversigt</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a class="btn btn-primary" href="/company/@NgCompany.CompanyId">Tilbage</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
@* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@
|
|
||||||
<button type="button" class="btn btn-success" @onclick="CreateActivity">Opret besøg</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
}
|
|
||||||
}
|
|
19
Wonky.Client/Pages/ActivityList.razor
Normal file
19
Wonky.Client/Pages/ActivityList.razor
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
@*
|
||||||
|
// 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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
|
@page "/ActivityList"
|
||||||
|
<h3>ActivityList</h3>
|
14
Wonky.Client/Pages/ActivityList.razor.cs
Normal file
14
Wonky.Client/Pages/ActivityList.razor.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Toolbelt.Blazor;
|
||||||
|
using Wonky.Client.HttpRepository;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
|
namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
|
public partial class ActivityList
|
||||||
|
{
|
||||||
|
[Inject] public IActivityHttpRepository ActivityRepo { get; set; }
|
||||||
|
[Inject] public IHttpClientInterceptor Interceptor { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -14,53 +14,24 @@
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Wonky.Client.Components
|
@using Wonky.Client.Components
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
@page "/activity-today"
|
@page "/activity-today"
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<div class="col-md-4">
|
<div class="col">
|
||||||
<span class="workDate">@(string.IsNullOrWhiteSpace(_workDate) ? "" : $"{DateTime.Parse(_workDate).ToLongDateString()}")</span>
|
<h3 class="workDate">@(string.IsNullOrWhiteSpace(_workDate) ? "" : $"{DateTime.Parse(_workDate).ToLongDateString()}")</h3>
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<WorkDateComponent OnChanged="GetActivities"></WorkDateComponent>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
<WorkDateComponent OnChanged="GetActivities"></WorkDateComponent>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<hr/>
|
</div>
|
||||||
<h5>Dagens aktivitet</h5>
|
<div class="card-body">
|
||||||
<table class="table">
|
<ActivityTableComponent Activities="_view.Activities"></ActivityTableComponent>
|
||||||
<thead>
|
</div>
|
||||||
<tr class="align-items-center">
|
|
||||||
<th scope="col">Kunde</th>
|
|
||||||
<th scope="col">Demo</th>
|
|
||||||
<th scope="col">Salg</th>
|
|
||||||
<th scope="col">Sum</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@if (_view != null)
|
|
||||||
{
|
|
||||||
foreach (var activity in _view.Activities)
|
|
||||||
{
|
|
||||||
<tr class="align-items-center">
|
|
||||||
<td>
|
|
||||||
@activity.Company.Name
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
@activity.Demo
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
@activity.SalesResume
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
@activity.OrderAmount
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
|
|
||||||
@page "/company/create"
|
@page "/companies/new"
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Wonky.Client.Components
|
@using Wonky.Client.Components
|
||||||
@using System.Xml
|
@using System.Xml
|
||||||
|
|
|
@ -124,10 +124,11 @@ namespace Wonky.Client.Pages
|
||||||
private async Task SubmitCompanyForm()
|
private async Task SubmitCompanyForm()
|
||||||
{
|
{
|
||||||
var newId = await CompanyRepo.CreateCompany(_companyObject);
|
var newId = await CompanyRepo.CreateCompany(_companyObject);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(newId))
|
if (!string.IsNullOrWhiteSpace(newId))
|
||||||
{
|
{
|
||||||
ToastService.ShowSuccess($"'{_companyObject.Name}' er oprettet i CRM.");
|
ToastService.ShowSuccess($"'{_companyObject.Name}' er oprettet i CRM.");
|
||||||
Navigation.NavigateTo($"/company/id/{newId}");
|
Navigation.NavigateTo($"/companies/{newId}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<a class="btn btn-success" href="/company/create">Opret kunde</a>
|
<a class="btn btn-success" href="/companies/new">Opret kunde</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -14,19 +14,22 @@
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Microsoft.AspNetCore.Components
|
@using Microsoft.AspNetCore.Components
|
||||||
@using Wonky.Client.Components
|
@using Wonky.Client.Components
|
||||||
@using Wonky.Client.Helpers
|
@using Wonky.Client.Helpers
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
@page "/company/{CompanyId}/update"
|
@page "/companies/{CompanyId}"
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(_companyView.Name))
|
@if (!string.IsNullOrWhiteSpace(_company.Name))
|
||||||
{
|
{
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h5>@_companyView.Account - @_companyView.Name</h5>
|
<h3>@_company.Account - @_company.Name</h3>
|
||||||
</div>
|
</div>
|
||||||
|
@if (countryCode == "dk" && _company.ValidVat == 0)
|
||||||
|
{
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
|
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,7 +63,8 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
}
|
}
|
||||||
<EditForm EditContext="_updateCompany" OnValidSubmit="SubmitUpdate">
|
}
|
||||||
|
<EditForm EditContext="_editContext" OnValidSubmit="SubmitUpdate">
|
||||||
<DataAnnotationsValidator/>
|
<DataAnnotationsValidator/>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -73,15 +77,15 @@
|
||||||
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
|
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="vatNumber" class="form-control" @bind-Value="_companyView.VatNumber"/>
|
<InputText id="vatNumber" class="form-control" @bind-Value="_company.VatNumber"/>
|
||||||
<ValidationMessage For="@(() => _companyView.VatNumber)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.VatNumber)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Telefon
|
Telefon
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="phone" class="form-control" @bind-Value="_companyView.Phone"/>
|
<InputText id="phone" class="form-control" @bind-Value="_company.Phone"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Phone)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Phone)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
|
@ -90,15 +94,15 @@
|
||||||
</th>
|
</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="name" class="form-control" @bind-Value="_companyView.Name"/>
|
<InputText id="name" class="form-control" @bind-Value="_company.Name"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Name)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Name)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Attention
|
Attention
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="attention" class="form-control" @bind-Value="_companyView.Attention"/>
|
<InputText id="attention" class="form-control" @bind-Value="_company.Attention"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Attention)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Attention)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
|
@ -107,15 +111,15 @@
|
||||||
</th>
|
</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="address1" class="form-control" @bind-Value="_companyView.Address1"/>
|
<InputText id="address1" class="form-control" @bind-Value="_company.Address1"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Address1)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Address1)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Adresse2
|
Adresse2
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="address2" class="form-control" @bind-Value="_companyView.Address2"/>
|
<InputText id="address2" class="form-control" @bind-Value="_company.Address2"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Address2)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Address2)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
|
@ -124,15 +128,15 @@
|
||||||
</th>
|
</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="zipCode" class="form-control" @bind-Value="_companyView.ZipCode"/>
|
<InputText id="zipCode" class="form-control" @bind-Value="_company.ZipCode"/>
|
||||||
<ValidationMessage For="@(() => _companyView.ZipCode)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.ZipCode)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Bynavn
|
Bynavn
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="city" class="form-control" @bind-Value="_companyView.City"/>
|
<InputText id="city" class="form-control" @bind-Value="_company.City"/>
|
||||||
<ValidationMessage For="@(() => _companyView.City)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.City)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
|
@ -141,15 +145,15 @@
|
||||||
</th>
|
</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="email" class="form-control" @bind-Value="_companyView.Email"/>
|
<InputText id="email" class="form-control" @bind-Value="_company.Email"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Email)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Email)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Mobil
|
Mobil
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<InputText id="mobile" class="form-control" @bind-Value="_companyView.Mobile"/>
|
<InputText id="mobile" class="form-control" @bind-Value="_company.Mobile"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Mobile)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Mobile)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
|
@ -157,11 +161,12 @@
|
||||||
Næste besøg
|
Næste besøg
|
||||||
</th>
|
</th>
|
||||||
<td class="state">
|
<td class="state">
|
||||||
<DisplayStateComponent StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState($"{_companyView.NextVisit}"))"> </DisplayStateComponent>
|
<DisplayStateComponent StateClass="@_visitState">
|
||||||
|
</DisplayStateComponent>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
|
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
|
||||||
<ValidationMessage For="@(() => _companyView.NextVisit)">Dato kan ikke vær før sidste besøg</ValidationMessage>
|
<ValidationMessage For="@(() => _company.NextVisit)">Dato kan ikke vær før sidste besøg</ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th>
|
<th>
|
||||||
Besøgt
|
Besøgt
|
||||||
|
@ -176,8 +181,8 @@
|
||||||
</th>
|
</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<InputNumber id="interval" class="form-control" @bind-Value="_companyView.Interval"/>
|
<InputNumber id="interval" class="form-control" @bind-Value="_company.Interval"/>
|
||||||
<ValidationMessage For="@(() => _companyView.Interval)"></ValidationMessage>
|
<ValidationMessage For="@(() => _company.Interval)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
<th scope="row">
|
<th scope="row">
|
||||||
|
|
||||||
|
@ -191,14 +196,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@*
|
|
||||||
<div class="col">
|
|
||||||
<button type="button" class="btn btn-warning">Fjern</button>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<button type="button" class="btn btn-danger">Slet</button>
|
|
||||||
</div>
|
|
||||||
*@
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<button type="submit" class="btn btn-success">Gem</button>
|
<button type="submit" class="btn btn-success">Gem</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -206,7 +203,7 @@
|
||||||
<a class="btn btn-primary" href="/companies">Til Oversigt</a>
|
<a class="btn btn-primary" href="/companies">Til Oversigt</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<a class="btn btn-primary" href="/company/@CompanyId">Tilbage</a>
|
<ActivityButton CompanyId="@_company.CompanyId"></ActivityButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -32,19 +32,18 @@ using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.Pages;
|
namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
public partial class CompanyEdit : IDisposable
|
public partial class CompanyView : IDisposable
|
||||||
{
|
{
|
||||||
[Inject] public IToastService ToastService { get; set; }
|
[Inject] public IToastService ToastService { get; set; }
|
||||||
[Inject] public ILogger<CompanyEdit> Logger { get; set; }
|
[Inject] public ILogger<CompanyView> Logger { get; set; }
|
||||||
[Inject] public NavigationManager Navigation { get; set; }
|
[Inject] public NavigationManager Navigation { get; set; }
|
||||||
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public VatInfoLookupService VatInfoLookupService { get; set; }
|
[Inject] public VatInfoLookupService VatInfoLookupService { get; set; }
|
||||||
[Inject] public ILocalStorageService StorageService { get; set; }
|
[Inject] public ILocalStorageService StorageService { get; set; }
|
||||||
[Parameter] public string Account { get; set; } = "";
|
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
private CompanyDto _companyView { get; set; } = new();
|
private CompanyDto _company { get; set; } = new();
|
||||||
private EditContext _updateCompany { get; set; }
|
private EditContext _editContext { get; set; }
|
||||||
private List<VirkRegInfo> _vInfos { get; set; } = new();
|
private List<VirkRegInfo> _vInfos { get; set; } = new();
|
||||||
private VirkRegInfo _virkRegInfo { get; set; } = new();
|
private VirkRegInfo _virkRegInfo { get; set; } = new();
|
||||||
private DateTime _lastVisit { get; set; }
|
private DateTime _lastVisit { get; set; }
|
||||||
|
@ -55,6 +54,8 @@ public partial class CompanyEdit : IDisposable
|
||||||
private bool _hasFolded;
|
private bool _hasFolded;
|
||||||
private bool _formInvalid = true;
|
private bool _formInvalid = true;
|
||||||
private string _orgVat;
|
private string _orgVat;
|
||||||
|
private string countryCode = "dk";
|
||||||
|
private string _visitState = "the-ugly";
|
||||||
|
|
||||||
private readonly JsonSerializerOptions _options = new ()
|
private readonly JsonSerializerOptions _options = new ()
|
||||||
{
|
{
|
||||||
|
@ -64,93 +65,94 @@ public partial class CompanyEdit : IDisposable
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
||||||
|
countryCode = ux.CountryCode;
|
||||||
Interceptor.RegisterEvent();
|
Interceptor.RegisterEvent();
|
||||||
Interceptor.RegisterBeforeSendEvent();
|
Interceptor.RegisterBeforeSendEvent();
|
||||||
|
|
||||||
_companyView = await CompanyRepo.GetCompanyById(CompanyId);
|
_company = await CompanyRepo.GetCompanyById(CompanyId);
|
||||||
_orgVat = _companyView.VatNumber;
|
_orgVat = _company.VatNumber;
|
||||||
_companyView.CountryCode = ux.CountryCode.ToLower();
|
_company.CountryCode = ux.CountryCode.ToLower();
|
||||||
|
|
||||||
vatAddress = PrepareVatAddress(_companyView);
|
vatAddress = PrepareVatAddress(_company);
|
||||||
|
|
||||||
if (_companyView.Interval == 0)
|
if (_company.Interval == 0)
|
||||||
_companyView.Interval = 8;
|
_company.Interval = 8;
|
||||||
|
|
||||||
_lastVisit = DateTime.Parse(_companyView.LastVisit);
|
_lastVisit = DateTime.Parse(_company.LastVisit);
|
||||||
_nextVisit = DateTime.Parse(_companyView.NextVisit);
|
_nextVisit = DateTime.Parse(_company.NextVisit);
|
||||||
|
|
||||||
if (!_companyView.ValidDateSpan())
|
if (!_company.ValidDateSpan())
|
||||||
_nextVisit = _lastVisit.AddDays(_companyView.Interval * 7);
|
_nextVisit = _lastVisit.AddDays(_company.Interval * 7);
|
||||||
|
if(_company.HasFolded == 1)
|
||||||
if(_companyView.HasFolded == 1)
|
|
||||||
{
|
{
|
||||||
_hasFolded = true;
|
_hasFolded = true;
|
||||||
_vatState = "the-dead";
|
_vatState = "the-dead";
|
||||||
|
_visitState = "the-dead";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_companyView.ValidVat == 0 && !string.IsNullOrWhiteSpace(_companyView.VatNumber))
|
if (_company.ValidVat == 0 && !string.IsNullOrWhiteSpace(_company.VatNumber))
|
||||||
_companyView.ValidVat = VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber) ? 1 : 0;
|
_company.ValidVat = VatUtils.ValidateFormat(_company.CountryCode, _company.VatNumber) ? 1 : 0;
|
||||||
_validVat = _companyView.ValidVat == 1;
|
_validVat = _company.ValidVat == 1;
|
||||||
_vatState = _companyView.ValidVat == 1 ? "the-good" : "the-draw";
|
_vatState = _company.ValidVat == 1 ? "the-good" : "the-draw";
|
||||||
|
_visitState = Utils.GetVisitState($"{_nextVisit:yyyy-HH-mm}");
|
||||||
}
|
}
|
||||||
_updateCompany = new EditContext(_companyView);
|
_editContext = new EditContext(_company);
|
||||||
_updateCompany.OnFieldChanged += HandleFieldChanged;
|
_editContext.OnFieldChanged += HandleFieldChanged;
|
||||||
_updateCompany.OnValidationStateChanged += ValidationChanged;
|
_editContext.OnValidationStateChanged += ValidationChanged;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_nextVisit = _lastVisit.AddDays(_companyView.Interval * 7);
|
_nextVisit = _lastVisit.AddDays(_company.Interval * 7);
|
||||||
|
|
||||||
_companyView.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
_company.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
_companyView.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
_company.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
|
|
||||||
if (!VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber) ||
|
if (!VatUtils.ValidateFormat(_company.CountryCode, _company.VatNumber) ||
|
||||||
!_companyView.ValidDateSpan())
|
!_company.ValidDateSpan())
|
||||||
{
|
{
|
||||||
_formInvalid = true;
|
_formInvalid = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_formInvalid = !_updateCompany.Validate();
|
_formInvalid = !_editContext.Validate();
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_formInvalid = true;
|
_formInvalid = true;
|
||||||
_updateCompany.OnFieldChanged -= HandleFieldChanged;
|
_editContext.OnFieldChanged -= HandleFieldChanged;
|
||||||
|
|
||||||
_updateCompany = new EditContext(_companyView);
|
_editContext = new EditContext(_company);
|
||||||
|
|
||||||
_updateCompany.OnFieldChanged += HandleFieldChanged;
|
_editContext.OnFieldChanged += HandleFieldChanged;
|
||||||
_updateCompany.OnValidationStateChanged -= ValidationChanged;
|
_editContext.OnValidationStateChanged -= ValidationChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SubmitUpdate()
|
private async Task SubmitUpdate()
|
||||||
{
|
{
|
||||||
if (!VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber))
|
if (!VatUtils.ValidateFormat(_company.CountryCode, _company.VatNumber))
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"CVR/VAT/ORG nummer er ugyldig.");
|
ToastService.ShowError($"CVR/VAT/ORG nummer er ugyldig.");
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_companyView.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
_company.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
_companyView.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
_company.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
_companyView.IsHidden = 0;
|
_company.IsHidden = 0;
|
||||||
if (_companyView.VatNumber != _orgVat)
|
if (_company.VatNumber != _orgVat)
|
||||||
_companyView.UpdateErpVat = 1;
|
_company.UpdateErpVat = 1;
|
||||||
|
|
||||||
var x = JsonSerializer.Serialize(_companyView, _options);
|
var x = JsonSerializer.Serialize(_company, _options);
|
||||||
Logger.LogInformation(x);
|
Logger.LogInformation(x);
|
||||||
var success = await CompanyRepo.UpdateCompany(CompanyId, _companyView );
|
var success = await CompanyRepo.UpdateCompany(CompanyId, _company );
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
ToastService.ShowSuccess("Check");
|
ToastService.ShowSuccess("Check");
|
||||||
Navigation.NavigateTo($"/company/{CompanyId}");
|
Navigation.NavigateTo($"/companies/{CompanyId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,16 +175,16 @@ public partial class CompanyEdit : IDisposable
|
||||||
_virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First();
|
_virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First();
|
||||||
if (syncAll)
|
if (syncAll)
|
||||||
{
|
{
|
||||||
_companyView.VatNumber = _virkRegInfo.VatNumber;
|
_company.VatNumber = _virkRegInfo.VatNumber;
|
||||||
_companyView.Name = _virkRegInfo.Name;
|
_company.Name = _virkRegInfo.Name;
|
||||||
_companyView.Address1 = _virkRegInfo.Address;
|
_company.Address1 = _virkRegInfo.Address;
|
||||||
_companyView.Address2 = _virkRegInfo.CoName;
|
_company.Address2 = _virkRegInfo.CoName;
|
||||||
_companyView.ZipCode = _virkRegInfo.ZipCode;
|
_company.ZipCode = _virkRegInfo.ZipCode;
|
||||||
_companyView.City = _virkRegInfo.City;
|
_company.City = _virkRegInfo.City;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_companyView.VatNumber = _virkRegInfo.VatNumber;
|
_company.VatNumber = _virkRegInfo.VatNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
_vInfos = new List<VirkRegInfo>();
|
_vInfos = new List<VirkRegInfo>();
|
||||||
|
@ -192,8 +194,8 @@ public partial class CompanyEdit : IDisposable
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Interceptor.DisposeEvent();
|
Interceptor.DisposeEvent();
|
||||||
_updateCompany.OnFieldChanged -= HandleFieldChanged;
|
_editContext.OnFieldChanged -= HandleFieldChanged;
|
||||||
_updateCompany.OnValidationStateChanged -= ValidationChanged;
|
_editContext.OnValidationStateChanged -= ValidationChanged;
|
||||||
}
|
}
|
||||||
private static VatAddress PrepareVatAddress(CompanyDto model)
|
private static VatAddress PrepareVatAddress(CompanyDto model)
|
||||||
{
|
{
|
|
@ -14,10 +14,11 @@
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Wonky.Client.Components
|
@using Wonky.Client.Components
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
@page "/sales-report"
|
@page "/sales-reports/new"
|
||||||
|
|
||||||
<EditForm EditContext="_editContext">
|
<EditForm EditContext="_editContext">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
|
@ -1,105 +1,41 @@
|
||||||
|
@*
|
||||||
|
// 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.Components
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@page "/sales-report/view/{reportDate}"
|
@page "/sales-reports/view/{ReportDate}"
|
||||||
@attribute [Authorize(Roles = "Adviser,Admin,Supervisor")]
|
@attribute [Authorize(Roles = "Adviser,Admin,Supervisor")]
|
||||||
|
|
||||||
<WorkDateComponent OnChanged="GetReport"></WorkDateComponent>
|
<div class="card">
|
||||||
<div>
|
<div class="card-header">
|
||||||
@if (_report.Activities.Any())
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
@if (!string.IsNullOrWhiteSpace(ReportDate))
|
||||||
{
|
{
|
||||||
<table class="table">
|
<h3 class="workDate">Dagsrapport @DateTime.Parse(ReportDate).ToLongDateString()</h3>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">Besøg</th>
|
|
||||||
<th scope="col">Demo</th>
|
|
||||||
<th scope="col">Salg</th>
|
|
||||||
<th scope="col">Beløb</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var activity in _report.Activities)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@activity.Company.Name - @activity.Company.ZipCity</td>
|
|
||||||
<td>@activity.Demo</td>
|
|
||||||
<td>@activity.SalesResume</td>
|
|
||||||
<td class="align-content-end">@activity.OrderAmount</td>
|
|
||||||
</tr>
|
|
||||||
}
|
}
|
||||||
<tr>
|
</div>
|
||||||
<td></td>
|
<div class="col">
|
||||||
<td></td>
|
<WorkDateComponent OnChanged="GetReport"></WorkDateComponent>
|
||||||
<td>Total</td>
|
</div>
|
||||||
<td class="align-content-end">@_report.Report.TotalTurnover</td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
</tbody>
|
<div class="card-body">
|
||||||
</table>
|
<ReportSummaryComponent Report="_report.Report"></ReportSummaryComponent>
|
||||||
}
|
<ActivityTableComponent Activities="_report.Activities"></ActivityTableComponent>
|
||||||
<table class="table">
|
</div>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th colspan="2" scope="col">Demo @(_report.Report.NewDemoCount + _report.Report.RecallDemoCount)</th>
|
|
||||||
<th colspan="2" scope="col">Resultat</th>
|
|
||||||
<th colspan="4" scope="col">Resultat Måned</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<th scope="col">Besøg</th>
|
|
||||||
<th scope="col">Demo</th>
|
|
||||||
<th scope="col">Salg</th>
|
|
||||||
<th scope="col">Beløb</th>
|
|
||||||
<th scope="col">Besøg</th>
|
|
||||||
<th scope="col">Demo</th>
|
|
||||||
<th scope="col">Salg</th>
|
|
||||||
<th scope="col">Beløb</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">N</th>
|
|
||||||
<td>@_report.Report.NewVisitCount</td>
|
|
||||||
<td>@_report.Report.NewDemoCount</td>
|
|
||||||
<td>@_report.Report.NewSaleCount</td>
|
|
||||||
<td>@_report.Report.NewTurnover</td>
|
|
||||||
<td>@_report.Report.NewVisitCountMonth</td>
|
|
||||||
<td>@_report.Report.NewDemoCountMonth</td>
|
|
||||||
<td>@_report.Report.NewSaleCountMonth</td>
|
|
||||||
<td>@_report.Report.NewTurnoverMonth</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">R</th>
|
|
||||||
<td>@_report.Report.RecallVisitCount</td>
|
|
||||||
<td>@_report.Report.RecallDemoCount</td>
|
|
||||||
<td>@_report.Report.RecallSaleCount</td>
|
|
||||||
<td>@_report.Report.RecallTurnover</td>
|
|
||||||
<td>@_report.Report.RecallVisitCountMonth</td>
|
|
||||||
<td>@_report.Report.RecallDemoCountMonth</td>
|
|
||||||
<td>@_report.Report.RecallSaleCountMonth</td>
|
|
||||||
<td>@_report.Report.RecallTurnoverMonth</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">SAS</th>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>@_report.Report.SasCount</td>
|
|
||||||
<td>@_report.Report.SasTurnover</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>@_report.Report.SasCountMonth</td>
|
|
||||||
<td>@_report.Report.SasTurnoverMonth</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">TOTAL</th>
|
|
||||||
<td>@(_report.Report.TotalVisitCount)</td>
|
|
||||||
<td>@(_report.Report.TotalDemoCount)</td>
|
|
||||||
<td>@(_report.Report.TotalSaleCount)</td>
|
|
||||||
<td>@(_report.Report.TotalTurnover)</td>
|
|
||||||
<td>@(_report.Report.TotalVisitCountMonth)</td>
|
|
||||||
<td>@(_report.Report.TotalDemoCountMonth)</td>
|
|
||||||
<td>@(_report.Report.TotalSaleCountMonth)</td>
|
|
||||||
<td>@(_report.Report.TotalTurnoverMonth)</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
|
@ -21,6 +21,7 @@ public partial class ReportView
|
||||||
|
|
||||||
private async Task GetReport(string workDate)
|
private async Task GetReport(string workDate)
|
||||||
{
|
{
|
||||||
|
_report = new NgSalesReportView();
|
||||||
_report = await ReportRepo.GetReport(workDate);
|
_report = await ReportRepo.GetReport(workDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
30
Wonky.Client/Pages/SalesReportList.razor
Normal file
30
Wonky.Client/Pages/SalesReportList.razor
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
@*
|
||||||
|
// 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]
|
||||||
|
//
|
||||||
|
*@
|
||||||
|
|
||||||
|
@page "/sales-reports"
|
||||||
|
<h3>SalesReportList</h3>
|
||||||
|
@if (_reports != null)
|
||||||
|
{
|
||||||
|
foreach (var report in _reports)
|
||||||
|
{
|
||||||
|
<span>@report.Name</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<AppSpinner />
|
||||||
|
}
|
19
Wonky.Client/Pages/SalesReportList.razor.cs
Normal file
19
Wonky.Client/Pages/SalesReportList.razor.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Toolbelt.Blazor;
|
||||||
|
using Wonky.Client.HttpRepository;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
|
namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
|
public partial class SalesReportList
|
||||||
|
{
|
||||||
|
[Inject] public IReportHttpRepository ReportRepo { get; set; }
|
||||||
|
[Inject] public IHttpClientInterceptor Interceport { get; set; }
|
||||||
|
|
||||||
|
private List<NgSalesReport> _reports { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_reports = await ReportRepo.GetReports();
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace Wonky.Client.Pages
|
namespace Wonky.Client.Pages
|
||||||
{
|
{
|
||||||
public partial class ErrorReport
|
public partial class SiteErrorReport
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public int ErrorCode { get; set; }
|
public int ErrorCode { get; set; }
|
|
@ -63,8 +63,8 @@
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
<NavLink class="nav-link ps-2" href="sales-report">
|
<NavLink class="nav-link ps-2" href="sales-reports">
|
||||||
<span class="oi oi-document" aria-hidden="true"></span> Dagsrapport
|
<span class="oi oi-document" aria-hidden="true"></span> Dagsrapporter
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
},
|
},
|
||||||
"appInfo": {
|
"appInfo": {
|
||||||
"name": "Wonky Client",
|
"name": "Wonky Client",
|
||||||
"version": "0.8.7",
|
"version": "0.8.10",
|
||||||
"isBeta": true,
|
"isBeta": true,
|
||||||
"image": "grumpy-coder.png"
|
"image": "grumpy-coder.png"
|
||||||
},
|
},
|
||||||
"apiConfig": {
|
"apiConfig": {
|
||||||
"baseAddress": "https://staging.innotec.dk",
|
"baseAddress": "https://dev.innotec.dk",
|
||||||
"tokenPath": "token",
|
"tokenPath": "token",
|
||||||
"userInfo": "api/auth/userinfo",
|
"userInfo": "api/auth/userinfo",
|
||||||
"customerEndpoint": "api/v2/crm/companies",
|
"customerEndpoint": "api/v2/crm/companies",
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
.spinner {
|
.spinner {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
.workDate {
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
/* visit / vat state classes */
|
/* visit / vat state classes */
|
||||||
.state {
|
.state {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
|
|
|
@ -21,34 +21,65 @@ namespace Wonky.Entity.DTO;
|
||||||
|
|
||||||
public class CompanyDto
|
public class CompanyDto
|
||||||
{
|
{
|
||||||
[Required(ErrorMessage = "Navn skal udfyldes")] [MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[Required(ErrorMessage = "Navn skal udfyldes")]
|
||||||
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
[Required(ErrorMessage = "Postnummer skal udfyldes")] [MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
|
||||||
|
[Required(ErrorMessage = "Postnummer skal udfyldes")]
|
||||||
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string ZipCode { get; set; }
|
public string ZipCode { get; set; }
|
||||||
[Required(ErrorMessage = "Bynavn skal udfyldes")] [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
|
||||||
|
[Required(ErrorMessage = "Bynavn skal udfyldes")]
|
||||||
|
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
||||||
public string City { get; set; }
|
public string City { get; set; }
|
||||||
|
|
||||||
[Required(ErrorMessage = "ORG/VAT/CVR er ikke et gyldigt nummer")]
|
[Required(ErrorMessage = "ORG/VAT/CVR er ikke et gyldigt nummer")]
|
||||||
public string VatNumber { get; set; } = "";
|
public string VatNumber { get; set; } = "";
|
||||||
|
|
||||||
public string CompanyId { get; set; } = "";
|
public string CompanyId { get; set; } = "";
|
||||||
|
|
||||||
public string SalesRepId { get; set; } = "";
|
public string SalesRepId { get; set; } = "";
|
||||||
|
|
||||||
public string BcId { get; set; } = "";
|
public string BcId { get; set; } = "";
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Address1 { get; set; } = "";
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")] public string Address2 { get; set; } = "";
|
public string Address1 { get; set; } = "";
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string Account { get; set; } = "";
|
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string Phone { get; set; } = "";
|
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string Mobile { get; set; } = "";
|
public string Address2 { get; set; } = "";
|
||||||
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")] public string Email { get; set; } = "";
|
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Attention { get; set; } = "";
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
|
public string Account { get; set; } = "";
|
||||||
|
|
||||||
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
|
public string Phone { get; set; } = "";
|
||||||
|
|
||||||
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
|
public string Mobile { get; set; } = "";
|
||||||
|
|
||||||
|
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")]
|
||||||
|
public string Email { get; set; } = "";
|
||||||
|
|
||||||
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
|
public string Attention { get; set; } = "";
|
||||||
|
|
||||||
public string CountryCode { get; set; } = "";
|
public string CountryCode { get; set; } = "";
|
||||||
|
|
||||||
public string LastVisit { get; set; } = "";
|
public string LastVisit { get; set; } = "";
|
||||||
|
|
||||||
public string NextVisit { get; set; } = "";
|
public string NextVisit { get; set; } = "";
|
||||||
|
|
||||||
[Range(1, 52, ErrorMessage = "Angiv interval mellem 1 og 52 uger")]
|
[Range(1, 52, ErrorMessage = "Angiv interval mellem 1 og 52 uger")]
|
||||||
public int Interval { get; set; } = 8;
|
public int Interval { get; set; } = 8;
|
||||||
|
|
||||||
public int HasFolded { get; set; }
|
public int HasFolded { get; set; }
|
||||||
|
|
||||||
public int IsHidden { get; set; }
|
public int IsHidden { get; set; }
|
||||||
|
|
||||||
public int ValidVat { get; set; }
|
public int ValidVat { get; set; }
|
||||||
|
|
||||||
public int UpdateErpVat { get; set; }
|
public int UpdateErpVat { get; set; }
|
||||||
public bool ValidDateSpan()
|
|
||||||
|
public virtual bool ValidDateSpan()
|
||||||
{
|
{
|
||||||
var notAllowed = new List<string> {"1970-01-01", "0001-01-01"};
|
var notAllowed = new List<string> {"1970-01-01", "0001-01-01"};
|
||||||
if (notAllowed.Contains(LastVisit) || notAllowed.Contains(NextVisit))
|
if (notAllowed.Contains(LastVisit) || notAllowed.Contains(NextVisit))
|
||||||
|
|
|
@ -5,9 +5,16 @@ namespace Wonky.Entity.DTO;
|
||||||
public class ReportDto
|
public class ReportDto
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
[MaxLength(1000, ErrorMessage = "Du kan højst bruge 1000 tegn")] public string Description { get; set; } = "";
|
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string SupervisedBy { get; set; } = "";
|
[MaxLength(1000, ErrorMessage = "Du kan højst bruge 1000 tegn")]
|
||||||
[Required(ErrorMessage = "Dagtype skal angives")] public string DayTypeEnum { get; set; } = "";
|
public string Description { get; set; } = "";
|
||||||
|
|
||||||
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
|
public string SupervisedBy { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Dagtype skal angives")]
|
||||||
|
public string DayTypeEnum { get; set; } = "";
|
||||||
|
|
||||||
// Date interval (used for leave, sickLeave and work hours
|
// Date interval (used for leave, sickLeave and work hours
|
||||||
public string FromDateTime { get; set; } = "";
|
public string FromDateTime { get; set; } = "";
|
||||||
public string ToDateTime { get; set; } = "";
|
public string ToDateTime { get; set; } = "";
|
||||||
|
|
30
Wonky.Entity/Requests/ReportPagingParams.cs
Normal file
30
Wonky.Entity/Requests/ReportPagingParams.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// 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.Entity.Requests;
|
||||||
|
|
||||||
|
public class ReportPagingParams
|
||||||
|
{
|
||||||
|
private int _pageSize = 5;
|
||||||
|
private const int MaxPageSize = 50;
|
||||||
|
public int PageNumber { get; set; } = 1;
|
||||||
|
public int PageSize
|
||||||
|
{
|
||||||
|
get => _pageSize;
|
||||||
|
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
|
||||||
|
}
|
||||||
|
public string SearchTerm { get; set; } = "";
|
||||||
|
public string SearchColumn { get; set; } = "name";
|
||||||
|
public string OrderBy { get; set; } = "name";
|
||||||
|
}
|
Loading…
Reference in a new issue