This commit is contained in:
Frede Hundewadt 2022-06-14 19:00:21 +02:00
parent f05548a075
commit 1fab58610e
41 changed files with 884 additions and 564 deletions

View file

@ -14,5 +14,5 @@
// 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> *@<div>
<img class="spinner pe-3" src="loader.gif" alt="Afventer svar fra netværk ..."/>Afventer netværk svar ... <img class="spinner pe-3" src="loader.gif" alt="Afventer svar fra netværk ..."/> Venter ...
</div> </div>

View file

@ -25,6 +25,8 @@
<div class="col-md-4"> <div class="col-md-4">
<WorkDateComponent OnChanged="FetchActivities"></WorkDateComponent> <WorkDateComponent OnChanged="FetchActivities"></WorkDateComponent>
</div> </div>
<div class="col">
</div>
</div> </div>

View file

@ -15,6 +15,7 @@
// //
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
using Microsoft.VisualBasic; using Microsoft.VisualBasic;
@ -32,8 +33,9 @@ public partial class Home : IDisposable
[Inject] public UserPreferenceService UserPrefs { get; set; } [Inject] public UserPreferenceService UserPrefs { get; set; }
[Inject] public ILogger<Home> Logger { get; set; } [Inject] public ILogger<Home> Logger { get; set; }
[Inject] private HttpInterceptorService Interceptor { get; set; } [Inject] private HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; } [Inject] private NavigationManager Navigator { get; set; }
[Inject] public IActivityHttpRepository ActivityRepo { get; set; } [Inject] private IActivityHttpRepository ActivityRepo { get; set; }
[Inject] private IToastService _toast { get; set; }
private List<ReportActivityDto> Activities { get; set; } private List<ReportActivityDto> Activities { get; set; }
private Preferences _prefs { get; set; } = new(); private Preferences _prefs { get; set; } = new();
private string _workDate { get; set; } = $"{DateTime.Now:yyyy-MM-dd}"; private string _workDate { get; set; } = $"{DateTime.Now:yyyy-MM-dd}";
@ -47,12 +49,12 @@ public partial class Home : IDisposable
Interceptor.RegisterEvent(); Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent(); Interceptor.RegisterBeforeSendEvent();
await FetchActivities(_workDate); await FetchActivities(_workDate);
} }
private async Task FetchActivities(string workDate) private async Task FetchActivities(string workDate)
{ {
_toast.ShowInfo("Vent nogle sekunder for data");
_workDate = workDate; _workDate = workDate;
Activities = new List<ReportActivityDto>(); Activities = new List<ReportActivityDto>();
Activities = await ActivityRepo.GetActivities(workDate); Activities = await ActivityRepo.GetActivities(workDate);

View file

@ -89,12 +89,12 @@ public class ActivityHttpRepository : IActivityHttpRepository
return pagingResponse; return pagingResponse;
} }
public async Task<ActivityResponseView> CreateActivity(ActivityDto model) public async Task<ApiResponse> CreateActivity(ActivityDto model)
{ {
Console.WriteLine(JsonSerializer.Serialize(model, _options)); Console.WriteLine(JsonSerializer.Serialize(model, _options));
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}", model, _options); var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}", model, _options);
var content = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ActivityResponseView>(content); var result = JsonSerializer.Deserialize<ApiResponse>(content);
return result!; return result!;
} }
@ -105,12 +105,12 @@ public class ActivityHttpRepository : IActivityHttpRepository
return salesItem ?? new ActivityDto(); return salesItem ?? new ActivityDto();
} }
public async Task<ActivityResponseView> AcceptOffer(string id) public async Task<ApiResponse> AcceptOffer(string id)
{ {
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}/{id}/accept", id) var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}/{id}/accept", id)
; ;
var content = await response.Content.ReadAsStringAsync(); var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ActivityResponseView>(content); var result = JsonSerializer.Deserialize<ApiResponse>(content);
return result!; return result!;
} }
} }

View file

@ -26,7 +26,7 @@ public interface IActivityHttpRepository
{ {
Task<PagingResponse<ActivityDto>> GetActivityPaged(ActivityPagingParams pagingParameters); Task<PagingResponse<ActivityDto>> GetActivityPaged(ActivityPagingParams pagingParameters);
Task<ActivityDto> GetActivity(string id); Task<ActivityDto> GetActivity(string id);
Task<ActivityResponseView> CreateActivity(ActivityDto model); Task<ApiResponse> CreateActivity(ActivityDto model);
Task<ActivityResponseView> AcceptOffer(string id); Task<ApiResponse> AcceptOffer(string id);
Task<List<ReportActivityDto>?> GetActivities(string activityDate); Task<List<ReportActivityDto>?> GetActivities(string activityDate);
} }

View file

@ -1,9 +1,12 @@
using Wonky.Client.Pages; using Wonky.Client.Pages;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository; namespace Wonky.Client.HttpRepository;
public interface IReportHttpRepository public interface IReportHttpRepository
{ {
Task<NgSalesReportInitDto> FetchReportInit(string workDate); Task<NgSalesReportView> GetReport(string workDate);
Task<ReportInitDto> InitializeReportData(string workDate);
Task<ApiResponse> PostReport(string workDate, ReportDto reportDto);
} }

View file

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository; namespace Wonky.Client.HttpRepository;
@ -29,10 +30,32 @@ public class ReportHttpRepository :IReportHttpRepository
_apiConfig = configuration.Value; _apiConfig = configuration.Value;
} }
public async Task<NgSalesReportInitDto> FetchReportInit(string workDate) public async Task<NgSalesReportView> GetReport(string workDate)
{
return await _client.GetFromJsonAsync<NgSalesReportView>($"{_apiConfig.ReportEndpoint}/{workDate}");
}
public async Task<ReportInitDto> InitializeReportData(string workDate)
{ {
var initData = await _client var initData = await _client
.GetFromJsonAsync<NgSalesReportInitDto>($"{_apiConfig.ReportEndpoint}/init/{workDate}"); .GetFromJsonAsync<ReportInitDto>($"{_apiConfig.ReportEndpoint}/init/{workDate}");
return initData ?? new NgSalesReportInitDto(); return initData ?? new ReportInitDto();
}
public async Task<ApiResponse> PostReport(string workDate, ReportDto reportDto)
{
var response = await _client
.PostAsJsonAsync($"{_apiConfig.ReportEndpoint}/{workDate}", reportDto);
var jsonDate = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(jsonDate);
return new ApiResponse
{
Code = result.Code,
Id = result.Id,
Message = result.Message,
IsSuccess = result.IsSuccess
};
} }
} }

View file

@ -47,36 +47,35 @@
<div class="row mb-1"> <div class="row mb-1">
<label for="activityType" class="col-md-2 col-form-label">Ordre Type</label> <label for="activityType" class="col-md-2 col-form-label">Ordre Type</label>
<div class="col-md-4"> <div class="col-md-4">
<select id="activityType" class="form-select" <InputSelect id="activityType" class="form-select"
@bind-Value="@_poDraft.ActivityTypeEnum" @bind-Value:event="oninput" @bind-Value="@_poDraft.ActivityTypeEnum">
@onchange="CheckActivity">
<option value="">ORDRE TYPE</option> <option value="">ORDRE TYPE</option>
<option value="onSite">Besøg</option> <option value="onSite">Besøg</option>
<option value="phone">Telefon</option> <option value="phone">Telefon</option>
</select> </InputSelect>
<ValidationMessage For="@(() => _poDraft.ActivityTypeEnum)"></ValidationMessage> <ValidationMessage For="@(() => _poDraft.ActivityTypeEnum)"></ValidationMessage>
</div> </div>
<label for="statusType" class="col-md-2 col-form-label">Status</label> <label for="statusType" class="col-md-2 col-form-label">Status</label>
<div class="col-md-4"> <div class="col-md-4">
<select id="statusType" class="form-select" <InputSelect id="statusType" class="form-select"
@bind-Value="@_poDraft.ActivityStatusEnum" @bind-Value:event="oninput"> @bind-Value="@_poDraft.ActivityStatusEnum">
<option value="noSale" selected>Ingen salg</option> <option value="noSale" selected>Ingen salg</option>
<option value="order">Bestilling</option> <option value="order">Bestilling</option>
<option value="quote">Tilbud</option> <option value="quote">Tilbud</option>
</select> </InputSelect>
<ValidationMessage For="@(() => _poDraft.ActivityStatusEnum)"></ValidationMessage>
</div> </div>
</div> </div>
<div class="row mb-1"> <div class="row mb-1">
<label for="demo" class="col-md-2 col-form-label">Demo</label> <label for="demo" class="col-md-2 col-form-label">Demo</label>
<div class="col-md-4"> <div class="col-md-4">
<InputText id="demo" class="form-control" <InputText id="demo" class="form-control" @bind-Value="_poDraft.Demo"/>
@bind-Value="_poDraft.Demo"/> <ValidationMessage For="@(() => _poDraft.Demo)"></ValidationMessage>
</div> </div>
<label for="email" class="col-md-2 col-form-label">Epost</label> <label for="email" class="col-md-2 col-form-label">Epost</label>
<div class="col-md-4"> <div class="col-md-4">
<InputText id="email" class="form-control" <InputText id="email" class="form-control" @bind-Value="_poDraft.EMail"/>
@bind-Value="_poDraft.EMail"/>
<ValidationMessage For="@(() => _poDraft.EMail)"></ValidationMessage> <ValidationMessage For="@(() => _poDraft.EMail)"></ValidationMessage>
</div> </div>
</div> </div>
@ -179,7 +178,8 @@
<li class="list-group-item d-flex justify-content-between align-items-end"> <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-start px-2">@rate.Quantity</div>
<div class="text-sm-end">@rate.Rate</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> <button type="button" class="btn btn-primary btn-sm"
@onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">Vælg</button>
</li> </li>
} }
</ul> </ul>
@ -361,13 +361,13 @@
</div> </div>
</div> </div>
<div class="row mt-2 mb-2"> <div class="row mt-2 mb-2">
<div class="col-md-2"> <div class="col">
<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-md-2"> <div class="col">
<a class="btn btn-primary" href="/company/@NgCompany.CompanyId">Tilbage</a> <a class="btn btn-primary" href="/company/@NgCompany.CompanyId">Tilbage</a>
</div> </div>
<div class="col-md-2"> <div class="col">
@* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@ @* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@
<button type="button" class="btn btn-success" @onclick="CreateActivity">Opret besøg</button> <button type="button" class="btn btn-success" @onclick="CreateActivity">Opret besøg</button>
</div> </div>

View file

@ -30,9 +30,9 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
public partial class CrmActivityCreate : IDisposable public partial class ActivityCreate : IDisposable
{ {
[Inject] public ILogger<CrmActivityCreate> _logger { get; set; } [Inject] public ILogger<ActivityCreate> _logger { get; set; }
[Inject] public IToastService ToastService { get; set; } [Inject] public IToastService ToastService { get; set; }
[Inject] public NavigationManager NavigationManager { get; set; } [Inject] public NavigationManager NavigationManager { get; set; }
[Inject] public ILocalStorageService StorageService { get; set; } [Inject] public ILocalStorageService StorageService { get; set; }
@ -163,6 +163,7 @@ public partial class CrmActivityCreate : IDisposable
_poDraft.Lines = lines; _poDraft.Lines = lines;
await StorageService.SetItemAsync(CompanyId, _poDraft); await StorageService.SetItemAsync(CompanyId, _poDraft);
Console.WriteLine(JsonSerializer.Serialize(_poDraft));
var result = await ActivityRepo.CreateActivity(_poDraft); var result = await ActivityRepo.CreateActivity(_poDraft);
ToastService.ShowSuccess($"{result.Message}."); ToastService.ShowSuccess($"{result.Message}.");
NavigationManager.NavigateTo($"/companies"); NavigationManager.NavigateTo($"/companies");

View file

@ -104,8 +104,8 @@ namespace Wonky.Client.Pages
_virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First(); _virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First();
RegState = _virkRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly"; RegState = _virkRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly";
_createDto.Name = _virkRegInfo.Name; _createDto.Name = _virkRegInfo.Name;
_createDto.Address1 = _virkRegInfo.CoName; _createDto.Address1 = _virkRegInfo.Address;
_createDto.Address2 = _virkRegInfo.Address; _createDto.Address2 = _virkRegInfo.CoName;
_createDto.ZipCode = _virkRegInfo.ZipCode; _createDto.ZipCode = _virkRegInfo.ZipCode;
_createDto.City = _virkRegInfo.City; _createDto.City = _virkRegInfo.City;
_createDto.VatNumber = _virkRegInfo.VatNumber; _createDto.VatNumber = _virkRegInfo.VatNumber;

View file

@ -0,0 +1,213 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components
@using Wonky.Client.Components
@using Wonky.Client.Helpers
@attribute [Authorize(Roles = "Adviser")]
@page "/company/{CompanyId}/update"
@if (!string.IsNullOrWhiteSpace(_companyView.Name))
{
<div class="card">
<div class="card-header">
<h5>@_companyView.Account - @_companyView.Name</h5>
</div>
<div class="card-body">
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
</div>
@if (_vInfos.Any())
{
<table class="table">
<thead>
<tr>
<th scope="col">CVR ORG</th>
<th scope="col">Navn</th>
<th scope="col">Status</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var info in _vInfos)
{
<tr>
<td class="align-middle">@info.VatNumber</td>
<td class="align-middle">@info.Name</td>
<td class="align-middle">@info.States[^1].State</td>
<td class="align-middle">
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, true))">OVERRØR</button>
</td>
<td class="align-middle">
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, false))">CVR/VAT</button>
</td>
</tr>
}
</tbody>
</table>
}
<EditForm EditContext="_updateCompany" OnValidSubmit="SubmitUpdate">
<DataAnnotationsValidator/>
<div class="card-body">
<table class="table">
<tbody>
<tr class="align-middle">
<th>
CVR/ORG
</th>
<td class="state"><DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent></td>
<td>
<InputText id="vatNumber" class="form-control" @bind-Value="_companyView.VatNumber"/>
<ValidationMessage For="@(() => _companyView.VatNumber)"></ValidationMessage>
</td>
<th>
Telefon
</th>
<td>
<InputText id="phone" class="form-control" @bind-Value="_companyView.Phone"/>
<ValidationMessage For="@(() => _companyView.Phone)"></ValidationMessage>
</td>
</tr>
<tr class="align-middle">
<th>
Firmanavn
</th>
<td></td>
<td>
<InputText id="name" class="form-control" @bind-Value="_companyView.Name"/>
<ValidationMessage For="@(() => _companyView.Name)"></ValidationMessage>
</td>
<th>
Attention
</th>
<td>
<InputText id="attention" class="form-control" @bind-Value="_companyView.Attention"/>
<ValidationMessage For="@(() => _companyView.Attention)"></ValidationMessage>
</td>
</tr>
<tr class="align-middle">
<th>
Adresse1
</th>
<td></td>
<td>
<InputText id="address1" class="form-control" @bind-Value="_companyView.Address1"/>
<ValidationMessage For="@(() => _companyView.Address1)"></ValidationMessage>
</td>
<th>
Adresse2
</th>
<td>
<InputText id="address2" class="form-control" @bind-Value="_companyView.Address2"/>
<ValidationMessage For="@(() => _companyView.Address2)"></ValidationMessage>
</td>
</tr>
<tr class="align-middle">
<th>
Postnr
</th>
<td></td>
<td>
<InputText id="zipCode" class="form-control" @bind-Value="_companyView.ZipCode"/>
<ValidationMessage For="@(() => _companyView.ZipCode)"></ValidationMessage>
</td>
<th>
Bynavn
</th>
<td>
<InputText id="city" class="form-control" @bind-Value="_companyView.City"/>
<ValidationMessage For="@(() => _companyView.City)"></ValidationMessage>
</td>
</tr>
<tr class="align-middle">
<th>
Epost
</th>
<td></td>
<td>
<InputText id="email" class="form-control" @bind-Value="_companyView.Email"/>
<ValidationMessage For="@(() => _companyView.Email)"></ValidationMessage>
</td>
<th>
Mobil
</th>
<td>
<InputText id="mobile" class="form-control" @bind-Value="_companyView.Mobile"/>
<ValidationMessage For="@(() => _companyView.Mobile)"></ValidationMessage>
</td>
</tr>
<tr class="align-middle">
<th>
Næste besøg
</th>
<td class="state"><DisplayStateComponent StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState($"{_companyView.NextVisit}"))"> </DisplayStateComponent></td>
<td>
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
<ValidationMessage For="@(() => _companyView.NextVisit)">Dato kan ikke vær før sidste besøg</ValidationMessage>
</td>
<th>
Besøgt
</th>
<td>
<InputDate id="lastVisit" class="form-control" @bind-Value="@_lastVisit"/>
</td>
</tr>
<tr class="align-middle">
<th>
Inteval (uger)
</th>
<td></td>
<td>
<InputNumber id="interval" class="form-control" @bind-Value="_companyView.Interval"/>
<ValidationMessage For="@(() => _companyView.Interval)"></ValidationMessage>
</td>
<th scope="row">
</th>
<td>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer">
<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">
<button type="submit" class="btn btn-success">Gem</button>
</div>
<div class="col">
<a class="btn btn-primary" href="/company/@CompanyId">Til Oversigt</a>
</div>
<div class="col">
<a class="btn btn-primary" href="/company/@CompanyId">Tilbage</a>
</div>
</div>
</div>
</EditForm>
</div>
}
else
{
<AppSpinner/>
}

View file

@ -32,7 +32,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
public partial class CompanyUpdate : IDisposable public partial class CompanyEdit : IDisposable
{ {
[Inject] public IToastService ToastService { get; set; } [Inject] public IToastService ToastService { get; set; }
[Inject] public ILogger<CompanyCreate> Logger { get; set; } [Inject] public ILogger<CompanyCreate> Logger { get; set; }
@ -175,8 +175,8 @@ public partial class CompanyUpdate : IDisposable
{ {
_companyView.VatNumber = _virkRegInfo.VatNumber; _companyView.VatNumber = _virkRegInfo.VatNumber;
_companyView.Name = _virkRegInfo.Name; _companyView.Name = _virkRegInfo.Name;
_companyView.Address1 = _virkRegInfo.CoName; _companyView.Address1 = _virkRegInfo.Address;
_companyView.Address2 = _virkRegInfo.Address; _companyView.Address2 = _virkRegInfo.CoName;
_companyView.ZipCode = _virkRegInfo.ZipCode; _companyView.ZipCode = _virkRegInfo.ZipCode;
_companyView.City = _virkRegInfo.City; _companyView.City = _virkRegInfo.City;
} }

View file

@ -1,187 +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]
//
*@
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components
@using Wonky.Client.Components
@using Wonky.Client.Helpers
@attribute [Authorize(Roles = "Adviser")]
@page "/company/{CompanyId}/update"
@if (!string.IsNullOrWhiteSpace(_companyView.Name))
{
<div class="card">
<div class="card-header">
<h5>@_companyView.Account - @_companyView.Name</h5>
</div>
<div class="card-body">
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
</div>
@if (_vInfos.Any())
{
<table class="table">
<thead>
<tr>
<th scope="col">CVR ORG</th>
<th scope="col">Navn</th>
<th scope="col">Status</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var info in _vInfos)
{
<tr>
<td class="align-middle">@info.VatNumber</td>
<td class="align-middle">@info.Name</td>
<td class="align-middle">@info.States[^1].State</td>
<td class="align-middle">
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, true))">OVERRØR</button>
</td>
<td class="align-middle">
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, false))">CVR/VAT</button>
</td>
</tr>
}
</tbody>
</table>
}
<EditForm EditContext="_updateCompany" OnValidSubmit="SubmitUpdate">
<DataAnnotationsValidator/>
<div class="card-body">
<div class="form-group row mb-1">
<label for="vatNumber" class="col-md-2 col-form-label">
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
CVR/ORG
</label>
<div class="col-md-10">
<InputText id="vatNumber" class="form-control" @bind-Value="_companyView.VatNumber"/>
<ValidationMessage For="@(() => _companyView.VatNumber)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="name" class="col-md-2 col-form-label">Firmanavn</label>
<div class="col-md-10">
<InputText id="name" class="form-control" @bind-Value="_companyView.Name"/>
<ValidationMessage For="@(() => _companyView.Name)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="address1" class="col-md-2 col-form-label">Adresse</label>
<div class="col-md-10">
<InputText id="address1" class="form-control" @bind-Value="_companyView.Address1"/>
<ValidationMessage For="@(() => _companyView.Address1)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="address2" class="col-md-2 col-form-label">Adresse</label>
<div class="col-md-10">
<InputText id="address2" class="form-control" @bind-Value="_companyView.Address2"/>
</div>
</div>
<div class="form-group row mb-1">
<label for="zipCode" class="col-md-2 col-form-label">Postnr</label>
<div class="col-md-10">
<InputText id="zipCode" class="form-control" @bind-Value="_companyView.ZipCode"/>
<ValidationMessage For="@(() => _companyView.ZipCode)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="city" class="col-md-2 col-form-label">Bynavn</label>
<div class="col-md-10">
<InputText id="city" class="form-control" @bind-Value="_companyView.City"/>
<ValidationMessage For="@(() => _companyView.City)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="phone" class="col-md-2 col-form-label">Telefon</label>
<div class="col-md-10">
<InputText id="phone" class="form-control" @bind-Value="_companyView.Phone"/>
<ValidationMessage For="@(() => _companyView.Phone)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="mobile" class="col-md-2 col-form-label">Mobil</label>
<div class="col-md-10">
<InputText id="mobile" class="form-control" @bind-Value="_companyView.Mobile"/>
<ValidationMessage For="@(() => _companyView.Mobile)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="email" class="col-md-2 col-form-label">Email</label>
<div class="col-md-10">
<InputText id="email" class="form-control" @bind-Value="_companyView.Email"/>
<ValidationMessage For="@(() => _companyView.Email)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="attention" class="col-md-2 col-form-label">Attention</label>
<div class="col-md-10">
<InputText id="attention" class="form-control" @bind-Value="_companyView.Attention"/>
<ValidationMessage For="@(() => _companyView.Attention)"></ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="lastVisit" class="col-form-label col-md-2">
<DisplayStateComponent
StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState($"{_companyView.NextVisit}"))">
</DisplayStateComponent>
Besøgt
</label>
<div class="col-md-4">
<InputDate id="lastVisit" class="form-control" @bind-Value="@_lastVisit"/>
</div>
<label for="nextVisit" class="col-form-label col-md-2">Næste besøg</label>
<div class="col-md-4">
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
<ValidationMessage For="@(() => _companyView.NextVisit)">Dato kan ikke vær før sidste besøg</ValidationMessage>
</div>
</div>
<div class="form-group row mb-1">
<label for="interval" class="col-form-label col-md-2">Interval (uger)</label>
<div class="col-md-4">
<InputNumber id="interval" class="form-control" @bind-Value="_companyView.Interval"/>
<ValidationMessage For="@(() => _companyView.Interval)"></ValidationMessage>
</div>
</div>
</div>
<div class="card-footer">
<div class="row">
<div class="col col-md-2">
<button type="button" class="btn btn-warning">Fjern</button>
</div>
<div class="col col-md-2">
<button type="button" class="btn btn-danger">Slet</button>
</div>
<div class="col col-md-2">
<button type="submit" class="btn btn-success">Gem</button>
</div>
<div class="col col-md-2">
<a class="btn btn-primary" href="/company/@CompanyId">Til Oversigt</a>
</div>
<div class="col col-md-2">
<a class="btn btn-primary" href="/company/@CompanyId">Tilbage</a>
</div>
</div>
</div>
</EditForm>
</div>
}
else
{
<AppSpinner/>
}

View file

@ -32,56 +32,37 @@
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-sm table-striped table-bordered"> <table class="table">
<tbody> <tbody>
<tr> <tr>
<th scope="row">Konto</th> <th scope="row">Konto</th>
<td colspan="2">@_companyDto.Account</td> <td>@_companyDto.Account</td>
<th scope="row">Telefon</th>
<td >@_companyDto.Phone</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Conavn</th> <th scope="row">Adresse1</th>
<td colspan="2">@_companyDto.Address1</td> <td>@_companyDto.Address1</td>
</tr> <th scope="row">Adresse2</th>
<tr> <td>@_companyDto.Address2</td>
<th scope="row">Adresse</th>
<td colspan="2">@_companyDto.Address2</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Postnummer</th> <th scope="row">Postnummer</th>
<td colspan="2">@_companyDto.ZipCode</td> <td >@_companyDto.ZipCode</td>
</tr>
<tr>
<th scope="row">Bynavn</th> <th scope="row">Bynavn</th>
<td colspan="2">@_companyDto.City</td> <td >@_companyDto.City</td>
</tr> </tr>
<tr> <tr>
<th scope="row">CVR</th> <th scope="row"><DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>CVR</th>
<td class="state">
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
</td>
<td>@_companyDto.VatNumber</td> <td>@_companyDto.VatNumber</td>
</tr>
<tr>
<th scope="row">Telefon</th>
<td colspan="2">@_companyDto.Phone</td>
</tr>
<tr>
<th scope="row">Email</th> <th scope="row">Email</th>
<td colspan="2">@_companyDto.Email</td> <td >@_companyDto.Email</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Sidste besøg</th> <th scope="row"><DisplayStateComponent StateClass="@(_companyDto.HasFolded == 1 ? "the-dead" : Utils.GetVisitState(_companyDto.NextVisit))"> </DisplayStateComponent>Næste besøg</th>
<td colspan="2">@_companyDto.LastVisit</td>
</tr>
<tr>
<th scope="row">Næste besøg</th>
<td class="state">
<DisplayStateComponent
StateClass="@(_companyDto.HasFolded == 1
? "the-dead" : Utils.GetVisitState(_companyDto.NextVisit))">
</DisplayStateComponent>
</td>
<td>@_companyDto.NextVisit</td> <td>@_companyDto.NextVisit</td>
<th scope="row">Sidste besøg</th>
<td>@_companyDto.LastVisit</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View file

@ -42,17 +42,22 @@ public partial class CompanyView : IDisposable
private string _vatState = "the-dead"; private string _vatState = "the-dead";
private bool _vatInvalid = true; private bool _vatInvalid = true;
protected override async Task OnParametersSetAsync()
{
_companyDto = await CompanyRepo.GetCompanyById(CompanyId);
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
Interceptor.RegisterEvent(); Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent(); Interceptor.RegisterBeforeSendEvent();
var xu = await Storage.GetItemAsync<UserInfoView>("_xu"); var xu = await Storage.GetItemAsync<UserInfoView>("_xu");
_companyDto = await CompanyRepo.GetCompanyById(CompanyId);
_companyDto.CountryCode = xu.CountryCode; _companyDto.CountryCode = xu.CountryCode;
if (_companyDto.HasFolded == 0) if (_companyDto.HasFolded == 0)
{ {
_vatInvalid = !VatUtils.ValidateFormat(_companyDto.CountryCode, _companyDto.VatNumber); _vatInvalid = !VatUtils.ValidateFormat(_companyDto.CountryCode, _companyDto.VatNumber);
_vatState = _vatInvalid ? "the-draw" : "the-good"; _vatState = !_vatInvalid ? "the-draw" : "the-good";
} }
} }

View file

@ -17,7 +17,7 @@ using Microsoft.AspNetCore.Components;
namespace Wonky.Client.Pages namespace Wonky.Client.Pages
{ {
public partial class ReportError public partial class ErrorReport
{ {
[Parameter] [Parameter]
public int ErrorCode { get; set; } public int ErrorCode { get; set; }

View file

@ -28,7 +28,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
public partial class SalesItemCatalog : IDisposable public partial class ItemCatalog : IDisposable
{ {
[Inject] public ILocalStorageService LocalStorage { get; set; } [Inject] public ILocalStorageService LocalStorage { get; set; }
[Inject] public ISalesItemHttpRepository SalesItemRepo { get; set; } [Inject] public ISalesItemHttpRepository SalesItemRepo { get; set; }

View file

@ -23,7 +23,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
public partial class SalesItemView : IDisposable public partial class ItemView : IDisposable
{ {
private NgSalesItemView Item { get; set; } = new (); private NgSalesItemView Item { get; set; } = new ();

View file

@ -0,0 +1,252 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Adviser")]
@page "/sales-report"
<EditForm EditContext="_editContext">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<div class="h5" style="font-variant: small-caps">Dagsrapport @(_workDate.ToLongDateString())</div>
</div>
<div class="col">
<WorkDateComponent OnChanged="SetWorkDate"></WorkDateComponent>
</div>
<div class="col">
@if (_fetching)
{
<AppSpinner></AppSpinner>
}
</div>
</div>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th scope="col">Dagen</th>
<th scope="col">Begyndt</th>
<th scope="col">Afsluttet</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select id="dayType" class="col-md-3 form-select"
@bind-Value="_report.DayTypeEnum" @bind-Value:event="oninput">
<option value="">-UDFYLD MIG-</option>
<option value="sales">Salgsdag</option>
<option value="meeting">Salgsmøde</option>
<option value="office">Kontordag</option>
<option value="supervisor">Supervisor</option>
<option value="sickLeave">Sygdom</option>
<option value="leave">Ferie</option>
</select>
<ValidationMessage For="@(() => _report.DayTypeEnum)" />
</td>
@if (_report.DayTypeEnum.ToLower().Contains("leave"))
{
<td>
<InputDate class="form-control"
@bind-Value="_leaveBegin" @bind-Value:event="oninput" @onchange="OnLeaveChanged"/>
</td>
<td>
<InputDate class="form-control"
@bind-Value="_leaveEnd" @bind-Value:event="oninput" @onchange="OnLeaveChanged"/>
</td>
}
else
{
<td>
<input type="time" id="checkIn" class="form-control"
@bind-Value="_timestampIn" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
</td>
<td>
<input type="time" id="checkOut" class="form-control"
@bind-Value="_timestampOut" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
</td>
}
<th>
<button type="button" class="btn btn-info"
@onclick="InitializeReport" disabled="@(!_noFigures)">Nøgletal</button>
</th>
<td>
<button type="button" class="btn btn-info"
@onclick="SubmitReport" disabled="@(_noFigures)">Gem Rapport</button>
</td>
</tr>
</tbody>
</table>
@if (!_report.DayTypeEnum.ToLower().Contains("leave"))
{
<table class="table">
<thead>
<tr>
<th scope="col" style="width:60%">Tekst</th>
<th scope="col">Medkørende Supervisor</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<InputTextArea id="description" class="form-control" @bind-Value="_report.Description"/>
<ValidationMessage For="@(() => _report.Description)" />
</td>
<td>
<InputText id="supervisedBy" class="form-control" @bind-Value="_report.SupervisedBy"/>
<ValidationMessage For="@(() => _report.SupervisedBy)" />
</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th scope="col">Km aften</th>
<th scope="col">Km morgen</th>
<th scope="col">Km privat</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<InputNumber class="form-control" @bind-Value="@_report.Figures.KmEvening"
disabled="@(_noFigures)" />
</td>
<td>
<InputNumber class="form-control" @bind-Value="@_report.Figures.KmMorning"
disabled="@(_noFigures)" />
</td>
<td>
<InputNumber class="form-control" @bind-Value="@_report.Figures.DistancePrivate"
disabled="@(_noFigures)" />
</td>
</tr>
</tbody>
</table>
@if (_activities != null)
{
<table class="table">
<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 _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>
<td></td>
<td></td>
<td>Total</td>
<td class="align-content-end">@_report.Figures.TotalTurnover</td>
</tr>
</tbody>
</table>
}
<table class="table">
<thead>
<tr>
<th></th>
<th colspan="2" scope="col">Demo @(_report.Figures.NewDemoCount + _report.Figures.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.Figures.NewVisitCount</td>
<td>@_report.Figures.NewDemoCount</td>
<td>@_report.Figures.NewSaleCount</td>
<td>@_report.Figures.NewTurnover</td>
<td>@_report.Figures.NewVisitCountMonth</td>
<td>@_report.Figures.NewDemoCountMonth</td>
<td>@_report.Figures.NewSaleCountMonth</td>
<td>@_report.Figures.NewTurnoverMonth</td>
</tr>
<tr>
<th scope="row">R</th>
<td>@_report.Figures.RecallVisitCount</td>
<td>@_report.Figures.RecallDemoCount</td>
<td>@_report.Figures.RecallSaleCount</td>
<td>@_report.Figures.RecallTurnover</td>
<td>@_report.Figures.RecallVisitCountMonth</td>
<td>@_report.Figures.RecallDemoCountMonth</td>
<td>@_report.Figures.RecallSaleCountMonth</td>
<td>@_report.Figures.RecallTurnoverMonth</td>
</tr>
<tr>
<th scope="row">SAS</th>
<td></td>
<td></td>
<td>@_report.Figures.SasCount</td>
<td>@_report.Figures.SasTurnover</td>
<td></td>
<td></td>
<td>@_report.Figures.SasCountMonth</td>
<td>@_report.Figures.SasTurnoverMonth</td>
</tr>
<tr>
<th scope="row">TOTAL</th>
<td>@(_report.Figures.TotalVisitCount)</td>
<td>@(_report.Figures.TotalDemoCount)</td>
<td>@(_report.Figures.TotalSaleCount)</td>
<td>@(_report.Figures.TotalTurnover)</td>
<td>@(_report.Figures.TotalVisitCountMonth)</td>
<td>@(_report.Figures.TotalDemoCountMonth)</td>
<td>@(_report.Figures.TotalSaleCountMonth)</td>
<td>@(_report.Figures.TotalTurnoverMonth)</td>
</tr>
</tbody>
</table>
}
</div>
</div>
</EditForm>

View file

@ -15,6 +15,7 @@
using System.Runtime.Intrinsics; using System.Runtime.Intrinsics;
using System.Text.Json; using System.Text.Json;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
@ -22,31 +23,38 @@ using Wonky.Client.HttpRepository;
using Wonky.Client.Services; using Wonky.Client.Services;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;
using Wonky.Entity.Models; using Wonky.Entity.Models;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages; namespace Wonky.Client.Pages;
public partial class SalesReport public partial class ReportCreate
{ {
[Inject] private HttpInterceptorService Interceptor { get; set; } [Inject] private HttpInterceptorService Interceptor { get; set; }
[Inject] private UserPreferenceService UserPrefs { get; set; } [Inject] private UserPreferenceService UserPrefs { get; set; }
[Inject] private IActivityHttpRepository ActivityRepo { get; set; } [Inject] private IActivityHttpRepository ActivityRepo { get; set; }
[Inject] private IReportHttpRepository ReportRepo { get; set; } [Inject] private IReportHttpRepository ReportRepo { get; set; }
[Inject] private NavigationManager Navigator { get; set; }
[Inject] private ILogger<ReportCreate> _logger { get; set; }
[Inject] private IToastService _toast { get; set; }
private EditContext _editContext { get; set; } private EditContext _editContext { get; set; }
private ReportDto _reportDto { get; set; } = new(); private ReportDto _report { get; set; } = new();
private NgSalesReportInitDto _reportInit { get; set; } = new(); private List<ReportActivityDto> _activities { get; set; } = new();
private ReportFiguresDto _init { get; set; }
private Preferences _prefs { get; set; } = new(); private Preferences _prefs { get; set; } = new();
private bool _formInvalid = true; private bool _formInvalid = true;
private bool _noFigures = true; private bool _noFigures = true;
private bool _fetching = false;
private DateTime _workDate { get; set; } = DateTime.Now; private DateTime _workDate { get; set; } = DateTime.Now;
private TimeOnly _timestampIn { get; set; } = new(12, 0); private TimeOnly _timestampIn { get; set; } = new(12, 0);
private TimeOnly _timestampOut { get; set; } = new(12, 0); private TimeOnly _timestampOut { get; set; } = new(12, 0);
private DateOnly _leaveBegin { get; set; } = DateOnly.FromDateTime(DateTime.Now); private DateOnly _leaveBegin { get; set; } = DateOnly.FromDateTime(DateTime.Now);
private DateOnly _leaveEnd { get; set; } = DateOnly.FromDateTime(DateTime.Now); private DateOnly _leaveEnd { get; set; } = DateOnly.FromDateTime(DateTime.Now);
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
Interceptor.RegisterEvent(); Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent(); Interceptor.RegisterBeforeSendEvent();
_editContext = new EditContext(_reportDto); _editContext = new EditContext(_report);
_editContext.OnFieldChanged += HandleFieldChanged; _editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged; _editContext.OnValidationStateChanged += ValidationChanged;
@ -54,14 +62,16 @@ public partial class SalesReport
if (!string.IsNullOrWhiteSpace(_prefs.WorkDate)) if (!string.IsNullOrWhiteSpace(_prefs.WorkDate))
_workDate = DateTime.Parse(_prefs.WorkDate); _workDate = DateTime.Parse(_prefs.WorkDate);
_leaveBegin = DateOnly.FromDateTime(_workDate); _leaveBegin = DateOnly.FromDateTime(_workDate);
_reportDto.CheckIn = _workDate.AddHours(12);
_reportDto.CheckOut = _workDate.AddHours(12);
_report.FromDateTime = $"{_workDate:yyyy-MM-dd 12:00}";
_report.ToDateTime = $"{_workDate:yyyy-MM-dd 12:00}";
_report.Figures.Distance = 0;
_report.Figures.DistancePrivateMonth = 0;
} }
private void HandleFieldChanged(object sender, FieldChangedEventArgs e) private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{ {
_reportDto.Figures.Distance = (int) (_reportDto.Figures.KmEvening - _reportDto.Figures.KmMorning);
_formInvalid = !_editContext.Validate(); _formInvalid = !_editContext.Validate();
StateHasChanged(); StateHasChanged();
} }
@ -70,23 +80,40 @@ public partial class SalesReport
{ {
_formInvalid = false; _formInvalid = false;
_editContext.OnFieldChanged -= HandleFieldChanged; _editContext.OnFieldChanged -= HandleFieldChanged;
_editContext = new EditContext(_reportDto); _editContext = new EditContext(_report);
_editContext.OnFieldChanged += HandleFieldChanged; _editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged; _editContext.OnValidationStateChanged += ValidationChanged;
} }
private async Task SubmitReport() private async Task SubmitReport()
{ {
if (_reportDto.DayTypeEnum.ToLower().Contains("leave")) if (string.IsNullOrWhiteSpace(_report.DayTypeEnum))
{ {
_reportDto.CheckIn = new DateTime(_leaveBegin.Year, _leaveBegin.Month, _leaveBegin.Day, 0, 0, 0); _toast.ShowError("Dagtype skal vælges");
_reportDto.CheckOut = new DateTime(_leaveEnd.Year, _leaveEnd.Month, _leaveEnd.Day, 0, 0, 0); return;
}
DateTime checkIn;
DateTime checkOut;
if (_report.DayTypeEnum.ToLower().Contains("leave"))
{
checkIn = new DateTime(_leaveBegin.Year, _leaveBegin.Month, _leaveBegin.Day, 0, 0, 0);
checkOut = new DateTime(_leaveEnd.Year, _leaveEnd.Month, _leaveEnd.Day, 0, 0, 0);
} }
else else
{ {
_reportDto.CheckIn = _workDate.AddHours(_timestampIn.Hour).AddMinutes(_timestampIn.Minute); checkIn = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampIn.Hour, _timestampIn.Minute, 0);
_reportDto.CheckOut = _workDate.AddHours(_timestampOut.Hour).AddMinutes(_timestampOut.Minute); checkOut = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampOut.Hour, _timestampOut.Minute, 0);
} }
_report.FromDateTime = $"{checkIn:yyyy-MM-dd hh:mm}";
_report.ToDateTime = $"{checkOut:yyyy-MM-dd hh:mm}";
_fetching = true;
var result = await ReportRepo.PostReport($"{_workDate:yyyy-MM-dd}", _report);
_fetching = false;
Navigator.NavigateTo("/home");
} }
private void OnLeaveChanged() private void OnLeaveChanged()
@ -96,26 +123,40 @@ public partial class SalesReport
private void OnTimeChanged() private void OnTimeChanged()
{ {
_reportDto.CheckIn = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampIn.Hour, _timestampIn.Minute,0); var x = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampIn.Hour, _timestampIn.Minute,0);
_reportDto.CheckOut = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampOut.Hour, _timestampOut.Minute,0); _report.FromDateTime = $"{x:yyyy-MM-dd hh:mm}";
x = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _timestampOut.Hour, _timestampOut.Minute,0);
_report.ToDateTime = $"{x:yyyy-MM-dd hh:mm}";
} }
private void SetWorkDate(string workDate) private void SetWorkDate(string workDate)
{ {
_workDate = DateTime.Parse(workDate); _workDate = DateTime.Parse(workDate);
_reportDto.CheckIn = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, 12, 0,0); _noFigures = true;
_reportDto.CheckOut = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, 12, 0,0); _report.Figures = new ReportFiguresDto();
_init = new ReportFiguresDto();
_activities = new List<ReportActivityDto>();
_report.Figures.KmEvening = 0;
_report.Figures.KmMorning = 0;
_report.Figures.Distance = 0;
_report.Figures.DistanceMonth = 0;
_report.Figures.DistancePrivate = 0;
_report.Figures.DistancePrivateMonth = 0;
_report.FromDateTime = $"{_workDate:yyyy-MM-dd 12:00}";
_report.ToDateTime = $"{_workDate:yyyy-MM-dd 12:00}";
} }
private async Task GetActivities() private async Task InitializeReport()
{ {
_fetching = true;
var data = await ReportRepo.InitializeReportData($"{_workDate:yyyy-MM-dd}");
if(data.Closed)
Navigator.NavigateTo($"/sales-report/view/{_workDate:yyyy-MM-dd}");
_noFigures = false; _noFigures = false;
_prefs = await UserPrefs.GetPreferences(); _report.Figures = data.Figures;
_reportInit = await ReportRepo.FetchReportInit(_prefs.WorkDate); _init = data.Figures;
_activities = data.Activities;
_reportDto.Figures = _reportInit.Figures; _fetching = false;
_reportDto.Figures.DistanceMonth = _reportInit.Figures.DistanceMonth + _reportDto.Figures.Distance;
_reportDto.Figures.DistancePrivateMonth = _reportInit.Figures.DistancePrivateMonth + _reportDto.Figures.DistancePrivate;
} }
public void Dispose() public void Dispose()

View file

@ -0,0 +1,107 @@
@using Wonky.Client.Components
@page "/sales-report/view/{reportDate}"
<WorkDateComponent OnChanged="GetReport"></WorkDateComponent>
<div>
@if (_report.Activities != null)
{
<table class="table">
<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>
<td></td>
<td></td>
<td>Total</td>
<td class="align-content-end">@_report.Report.TotalTurnover</td>
</tr>
</tbody>
</table>
}
<table class="table">
<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>

View file

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpRepository;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class ReportView
{
[Inject] private IReportHttpRepository ReportRepo { get; set; }
[Parameter] public string ReportDate { get; set; }
private NgSalesReportView _report { get; set; }
protected override async Task OnInitializedAsync()
{
if(!string.IsNullOrWhiteSpace(ReportDate))
await GetReport(ReportDate);
}
private async Task GetReport(string workDate)
{
_report = await ReportRepo.GetReport(workDate);
}
}

View file

@ -1,250 +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]
//
*@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Adviser")]
@page "/sales-report"
<EditForm EditContext="_editContext">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col">
<div class="h5" style="font-variant: small-caps">Dagsrapport @(_reportDto.CheckIn.ToLongDateString())</div>
</div>
<div class="col">
<WorkDateComponent OnChanged="SetWorkDate"></WorkDateComponent>
</div>
</div>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th scope="col">Aktivitet</th>
<th scope="col">Begyndt</th>
<th scope="col">Afsluttet</th>
@if (!_reportDto.DayTypeEnum.ToLower().Contains("leave"))
{
<th></th>
}
</tr>
</thead>
<tbody>
<tr>
<td>
<select id="dayType" class="col-md-3 form-select"
@bind-Value="_reportDto.DayTypeEnum" @bind-Value:event="oninput">
<option value="sales" selected>Salgsdag</option>
<option value="meeting">Salgsmøde</option>
<option value="office">Kontordag</option>
<option value="supervisor">Supervisor</option>
<option value="sickLeave">Sygdom</option>
<option value="leave">Ferie</option>
</select>
<ValidationMessage For="@(() => _reportDto.DayTypeEnum)" />
</td>
@if (_reportDto.DayTypeEnum.ToLower().Contains("leave"))
{
<td>
<InputDate class="form-control"
@bind-Value="_leaveBegin" @bind-Value:event="oninput" @onchange="OnLeaveChanged"/>
</td>
<td>
<InputDate class="form-control"
@bind-Value="_leaveEnd" @bind-Value:event="oninput" @onchange="OnLeaveChanged"/>
</td>
}
else
{
<td>
<input type="time" id="checkIn" class="form-control"
@bind-Value="_timestampIn" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
</td>
<td>
<input type="time" id="checkOut" class="form-control"
@bind-Value="_timestampOut" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
</td>
<th>
<button type="button" class="btn btn-info" @onclick="GetActivities">Hent Besøg</button>
</th>
}
</tr>
</tbody>
</table>
@if (!_reportDto.DayTypeEnum.ToLower().Contains("leave"))
{
<table class="table">
<thead>
<tr>
<th scope="col" style="width:60%">Tekst</th>
<th scope="col">Medkørende Supervisor</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<InputTextArea id="description" class="form-control" @bind-Value="_reportDto.Description"/>
<ValidationMessage For="@(() => _reportDto.Description)" />
</td>
<td>
<InputText id="supervisedBy" class="form-control" @bind-Value="_reportDto.SupervisedBy"/>
<ValidationMessage For="@(() => _reportDto.SupervisedBy)" />
</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th scope="col">Km morgen</th>
<th scope="col">Km aften</th>
<th scope="col">Km kørt</th>
<th scope="col">Km privat</th>
<th scope="col">Md privat</th>
<th scope="col">Md total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.KmMorning" disabled="@_noFigures" />
</td>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.KmEvening" disabled="@_noFigures" />
</td>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.Distance" readonly />
</td>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.DistancePrivate" disabled="@_noFigures"/>
</td>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.DistancePrivateMonth" readonly/>
</td>
<td>
<InputNumber class="form-control" @bind-Value="_reportDto.Figures.DistanceMonth" readonly/>
</td>
</tr>
</tbody>
</table>
@if (_reportInit.Activities != null)
{
<table class="table">
<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 _reportInit.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>
<td></td>
<td></td>
<td>Total</td>
<td class="align-content-end">@_reportDto.Figures.TotalTurnover</td>
</tr>
</tbody>
</table>
}
<table class="table">
<thead>
<tr>
<th></th>
<th colspan="2" scope="col">Demo @(_reportDto.Figures.NewDemoCount + _reportDto.Figures.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>@_reportDto.Figures.NewVisitCount</td>
<td>@_reportDto.Figures.NewDemoCount</td>
<td>@_reportDto.Figures.NewSaleCount</td>
<td>@_reportDto.Figures.NewTurnover</td>
<td>@_reportDto.Figures.NewVisitCountMonth</td>
<td>@_reportDto.Figures.NewDemoCountMonth</td>
<td>@_reportDto.Figures.NewSaleCountMonth</td>
<td>@_reportDto.Figures.NewTurnoverMonth</td>
</tr>
<tr>
<th scope="row">R</th>
<td>@_reportDto.Figures.RecallVisitCount</td>
<td>@_reportDto.Figures.RecallDemoCount</td>
<td>@_reportDto.Figures.RecallSaleCount</td>
<td>@_reportDto.Figures.RecallTurnover</td>
<td>@_reportDto.Figures.RecallVisitCountMonth</td>
<td>@_reportDto.Figures.RecallDemoCountMonth</td>
<td>@_reportDto.Figures.RecallSaleCountMonth</td>
<td>@_reportDto.Figures.RecallTurnoverMonth</td>
</tr>
<tr>
<th scope="row">SAS</th>
<td></td>
<td></td>
<td>@_reportDto.Figures.SasCount</td>
<td>@_reportDto.Figures.SasTurnover</td>
<td></td>
<td></td>
<td>@_reportDto.Figures.SasCountMonth</td>
<td>@_reportDto.Figures.SasTurnoverMonth</td>
</tr>
<tr>
<th scope="row">TOTAL</th>
<td>@(_reportDto.Figures.NewVisitCount + _reportDto.Figures.RecallVisitCount)</td>
<td>@(_reportDto.Figures.NewDemoCount + _reportDto.Figures.RecallDemoCount)</td>
<td>@(_reportDto.Figures.NewSaleCount + _reportDto.Figures.RecallSaleCount + _reportDto.Figures. SasCount)</td>
<td>@(_reportDto.Figures.NewTurnover + _reportDto.Figures.RecallTurnover + _reportDto.Figures.SasTurnover)</td>
<td>@(_reportDto.Figures.NewVisitCountMonth + _reportDto.Figures.RecallVisitCountMonth)</td>
<td>@(_reportDto.Figures.NewDemoCountMonth + _reportDto.Figures.RecallDemoCountMonth)</td>
<td>@(_reportDto.Figures.NewSaleCountMonth + _reportDto.Figures.RecallSaleCountMonth + _reportDto.Figures. SasCountMonth)</td>
<td>@(_reportDto.Figures.NewTurnoverMonth + _reportDto.Figures.RecallTurnoverMonth + _reportDto.Figures.SasTurnoverMonth)</td>
</tr>
</tbody>
</table>
}
</div>
</div>
</EditForm>

View file

@ -105,7 +105,10 @@ namespace Wonky.Client.Services
{ {
((AuthStateProvider)_authStateProvider).NotifyUserLogout(); ((AuthStateProvider)_authStateProvider).NotifyUserLogout();
_client.DefaultRequestHeaders.Authorization = null; _client.DefaultRequestHeaders.Authorization = null;
await _localStorage.ClearAsync(); await _localStorage.RemoveItemAsync("_xa");
await _localStorage.RemoveItemAsync("_xr");
await _localStorage.RemoveItemAsync("_xe");
await _localStorage.RemoveItemAsync("_xu");
} }
public async Task<UserInfoView> UserInfo(bool write = false) public async Task<UserInfoView> UserInfo(bool write = false)

View file

@ -18,12 +18,12 @@
}, },
"appInfo": { "appInfo": {
"name": "Wonky Client", "name": "Wonky Client",
"version": "0.7", "version": "0.7.5",
"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",

View file

@ -7,7 +7,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
<link rel="manifest" href="site.webmanifest" crossorigin="use-credentials"> <link rel="manifest" href="site.webmanifest">
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#5bbad5"> <link rel="mask-icon" href="safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#ffaa00"> <meta name="msapplication-TileColor" content="#ffaa00">
<meta name="theme-color" content="#000"> <meta name="theme-color" content="#000">

View file

@ -1,10 +0,0 @@
using Wonky.Entity.Models;
namespace Wonky.Entity.DTO;
public class NgSalesReportInitDto
{
public ReportFiguresDto Figures { get; set; } = new();
public List<ReportActivityDto> Activities { get; set; } = new();
}

View file

@ -2,7 +2,7 @@ namespace Wonky.Entity.DTO;
public class ReportActivityDto public class ReportActivityDto
{ {
public ReportVisitDto Company { get; set; } = new(); public VisitCompanyDto Company { get; set; } = new();
public string SalesHeadId { get; set; } = ""; public string SalesHeadId { get; set; } = "";
public bool Closed { get; set; } public bool Closed { get; set; }
public string OrderDate { get; set; } = ""; public string OrderDate { get; set; } = "";

View file

@ -4,11 +4,12 @@ namespace Wonky.Entity.DTO;
public class ReportDto public class ReportDto
{ {
[Required(ErrorMessage = "Dagtype skal angives")] public string DayTypeEnum { get; set; } = ""; public string Name { get; set; } = "";
[MaxLength(1000, ErrorMessage = "Du kan højst bruge 1000 tegn")] public string Description { 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(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 DateTime CheckIn { get; set; } public string FromDateTime { get; set; } = "";
public DateTime CheckOut { get; set; } public string ToDateTime { get; set; } = "";
public ReportFiguresDto Figures { get; set; } = new(); public ReportFiguresDto Figures { get; set; } = new();
} }

View file

@ -3,32 +3,41 @@ namespace Wonky.Entity.DTO;
public class ReportFiguresDto public class ReportFiguresDto
{ {
public int SalesDayNumber { get; set; } public int SalesDayNumber { get; set; }
public long KmMorning { get; set; }
public long KmEvening { get; set; }
public int Distance { get; set; } public int Distance { get; set; }
public int DistancePrivate { get; set; } public int DistancePrivate { get; set; }
public int KmEvening { get; set; }
public int KmMorning { get; set; }
public int NewVisitCount { get; set; } public int NewVisitCount { get; set; }
public int NewDemoCount { get; set; } public int NewDemoCount { get; set; }
public int NewSaleCount { get; set; }
public int RecallVisitCount { get; set; } public int RecallVisitCount { get; set; }
public int RecallDemoCount { get; set; } public int RecallDemoCount { get; set; }
public int NewSaleCount { get; set; }
public int RecallSaleCount { get; set; } public int RecallSaleCount { get; set; }
public int TotalVisitCount { get; set; }
public int TotalDemoCount { get; set; }
public int TotalSaleCount { get; set; }
public int SasCount { get; set; } public int SasCount { get; set; }
// turnover day // turnover day
public decimal NewTurnover { get; set; } public decimal NewTurnover { get; set; }
public decimal RecallTurnover { get; set; } public decimal RecallTurnover { get; set; }
public decimal SasTurnover { get; set; } public decimal SasTurnover { get; set; }
public decimal TotalTurnover { get; set; } public decimal TotalTurnover { get; set; }
// month summaries // month distance
public int DistanceMonth { get; set; } public int DistanceMonth { get; set; }
public int DistancePrivateMonth { get; set; } public int DistancePrivateMonth { get; set; }
// mont counters
public int NewVisitCountMonth { get; set; } public int NewVisitCountMonth { get; set; }
public int NewDemoCountMonth { get; set; } public int NewDemoCountMonth { get; set; }
public int NewSaleCountMonth { get; set; } public int NewSaleCountMonth { get; set; }
public int RecallVisitCountMonth { get; set; } public int RecallVisitCountMonth { get; set; }
public int RecallDemoCountMonth { get; set; } public int RecallDemoCountMonth { get; set; }
public int RecallSaleCountMonth { get; set; } public int RecallSaleCountMonth { get; set; }
// month total counter
public int TotalVisitCountMonth { get; set; }
public int TotalDemoCountMonth { get; set; }
public int TotalSaleCountMonth { get; set; }
public int SasCountMonth { get; set; } public int SasCountMonth { get; set; }
// month turnover // month turnover
public decimal NewTurnoverMonth { get; set; } public decimal NewTurnoverMonth { get; set; }

View file

@ -0,0 +1,11 @@
using Wonky.Entity.Models;
namespace Wonky.Entity.DTO;
public class ReportInitDto
{
public bool Closed { get; set; }
public ReportFiguresDto Figures { get; set; }
public List<ReportActivityDto> Activities { get; set; }
}

View file

@ -1,6 +1,6 @@
namespace Wonky.Entity.DTO; namespace Wonky.Entity.DTO;
public class ReportVisitDto public class VisitCompanyDto
{ {
public string CompanyId { get; set; } = ""; public string CompanyId { get; set; } = "";
public string Account { get; set; } = ""; public string Account { get; set; } = "";

View file

@ -0,0 +1,11 @@
namespace Wonky.Entity.Views;
public class ActivityCompanyView
{
public string CompanyId { get; set; } = "";
public string Account { get; set; } = "";
public string Name { get; set; } = "";
public string ZipCity { get; set; } = "";
public string Phone { get; set; } = "";
public string VatNumber { get; set; } = "";
}

View file

@ -17,9 +17,9 @@ using System.Net;
namespace Wonky.Entity.Views; namespace Wonky.Entity.Views;
public class ActivityResponseView public class ApiResponse
{ {
public bool IsSuccessStatusCode { get; set; } public bool IsSuccess { get; set; }
public HttpStatusCode Code { get; set; } public HttpStatusCode Code { get; set; }
public string Message { get; set; } = ""; public string Message { get; set; } = "";
public string Id { get; set; } = ""; public string Id { get; set; } = "";

View file

@ -0,0 +1,16 @@
namespace Wonky.Entity.Views;
public class NgReportActivityView
{
public ActivityCompanyView Company { get; set; } = new();
public string SalesHeadId { get; set; } = "";
public bool Closed { get; set; }
public string OrderDate { get; set; } = "";
public string ReferenceNumber { get; set; } = "";
public string YourRef { get; set; } = "";
public decimal OrderAmount { get; set; }
public string VisitTypeEnum { get; set; } = "";
public string Demo { get; set; } = "";
public string SalesResume { get; set; } = "";
}

View file

@ -0,0 +1,55 @@
namespace Wonky.Entity.Views;
public class NgSalesReport
{
public string ReportId { get; set; } = "";
public string ErpUserId { get; set; } = "";
public string Name { get; set; } = "";
public string SupervisedBy { get; set; } = "";
public string Description { get; set; } = "";
public string DayTypeEnum { get; set; } = "";
public long ReportDate { get; set; }
public long FromDateTime { get; set; }
public long ToDateTime { get; set; }
public bool Closed { get; set; }
// workday
public int NewVisitCount { get; set; }
public int RecallVisitCount { get; set; }
public int NewDemoCount { get; set; }
public int RecallDemoCount { get; set; }
public int NewSaleCount { get; set; }
public int RecallSaleCount { get; set; }
public int TotalVisitCount { get; set; }
public int TotalDemoCount { get; set; }
public int TotalSaleCount { get; set; }
public int SasCount { get; set; }
// workday turnover
public decimal NewTurnover { get; set; }
public decimal RecallTurnover { get; set; }
public decimal SasTurnover { get; set; }
public decimal TotalTurnover { get; set; }
// workday distance ledger
public int KmEvening { get; set; }
public int KmMorning { get; set; }
public int Distance { get; set; }
public int DistancePrivate { get; set; }
// month summaries
public int DistanceMonth { get; set; }
public int DistancePrivateMonth { get; set; }
public int NewVisitCountMonth { get; set; }
public int NewDemoCountMonth { get; set; }
public int NewSaleCountMonth { get; set; }
public int RecallVisitCountMonth { get; set; }
public int RecallDemoCountMonth { get; set; }
public int RecallSaleCountMonth { get; set; }
public int TotalVisitCountMonth { get; set; }
public int TotalDemoCountMonth { get; set; }
public int TotalSaleCountMonth { get; set; }
public int SasCountMonth { get; set; }
// month turnover
public decimal NewTurnoverMonth { get; set; }
public decimal RecallTurnoverMonth { get; set; }
public decimal SasTurnoverMonth { get; set; }
public decimal TotalTurnoverMonth { get; set; }
}

View file

@ -0,0 +1,7 @@
namespace Wonky.Entity.Views;
public class NgSalesReportView
{
public NgSalesReport Report { get; set; } = new();
public List<NgReportActivityView> Activities { get; set; } = new ();
}