price list

This commit is contained in:
Frede Hundewadt 2022-12-07 14:58:03 +01:00
parent 88039cd8f5
commit ecd1b61c88
15 changed files with 232 additions and 220 deletions

View file

@ -23,7 +23,7 @@
<th colspan="4">
<div class="row">
<div class="col">
<h2>Innotec Prisliste</h2>
<h2>Innotec Prisliste - @CountryName</h2>
</div>
<div class="col-sm-2 text-end">
<button type="button" class="d-print-none btn btn-primary mx-3" onclick="window.print();"><i class="bi-printer"></i> Udskriv</button>

View file

@ -24,4 +24,5 @@ namespace Wonky.Client.Components;
public partial class CatalogTablePrintComponent
{
[Parameter] public List<SalesItemView> ItemList { get; set; } = new();
[Parameter] public string CountryName { get; set; } = "";
}

View file

@ -25,5 +25,5 @@ public interface ICrmHistoryHttpRepository
Task<List<ProductInventoryView>> FetchInventory(string companyId);
Task<List<ProductHistoryView>> FetchHistory(string companyId);
Task<List<ProductHistoryView>> FetchHistory(string companyId, string sku);
Task<string> RpcSyncErpToCrm(string companyId, string syncDate, string etag);
Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate);
}

View file

@ -96,7 +96,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
public async Task<CompanyDto> GetCompanyById(string companyId)
{
return await _client.GetFromJsonAsync<CompanyDto>($"{_conf.CrmCustomers}/{companyId}");
return await _client.GetFromJsonAsync<CompanyDto>($"{_conf.CrmCustomers}/{companyId}", _options);
}
/// <summary>
@ -106,7 +106,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
/// <returns>company id</returns>
public async Task<string> CreateCompany(CompanyDto model)
{
var response = await _client.PostAsJsonAsync($"{_conf.CrmCustomers}", model);
var response = await _client.PostAsJsonAsync($"{_conf.CrmCustomers}", model, _options);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<CompanyDto>(content, _options);
return result.CompanyId;

View file

@ -114,10 +114,13 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
/// </summary>
/// <param name="companyId"></param>
/// <param name="syncDate"></param>
/// <param name="etag"></param>
/// <returns>date string</returns>
public async Task<string> RpcSyncErpToCrm(string companyId, string syncDate, string etag)
public async Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate)
{
return await _client.GetStringAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}?etag={etag}");
var x =await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}");
if (!x.IsSuccessStatusCode)
return "";
var content = await x.Content.ReadAsStringAsync();
return content;
}
}

View file

@ -39,14 +39,14 @@
<PageSizeComponent OnChanged="SetPageSize"/>
</div>
<div class="col-sm-10">
<PaginationComponent MetaData="_metaData" Spread="2" SelectedPage="SetSelectedPage"/>
<PaginationComponent MetaData="MetaInfo" Spread="2" SelectedPage="SetSelectedPage"/>
</div>
<div class="col-sm-2 text-end">
<a class="btn btn-secondary" href="/price-catalog/print"><i class="bi-printer"></i> Udskriv</a>
</div>
</div>
</div>
<CatalogTableComponent ItemList="_items"/>
<CatalogTableComponent ItemList="Items"/>
@if (Working)
{
<WorkingThreeDots />

View file

@ -34,83 +34,84 @@ public partial class CatalogPage : IDisposable
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserPrefService UserPrefService { get; set; }
private List<SalesItemView> _items { get; set; } = new();
private MetaData _metaData { get; set; } = new();
private CatalogPagingParams _paging = new();
private UserPref _userPref = new();
private UserInfoView _user { get; set; } = new();
[Inject] public UserPrefService PrefService { get; set; }
private List<SalesItemView> Items { get; set; } = new();
private MetaData MetaInfo { get; set; } = new();
private CatalogPagingParams PageParams = new();
private UserPref Prefs = new();
private UserInfoView UserInfo { get; set; } = new();
private bool Working { get; set; } = true;
protected override async Task OnInitializedAsync()
{
_userPref = await UserPrefService.GetPreferences();
_user = await Storage.GetItemAsync<UserInfoView>("_xu");
Prefs = await PrefService.GetPreferences();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
_paging.CountryCode = _user.CountryCode;
PageParams.CountryCode = UserInfo.CountryCode;
_paging.OrderBy = _userPref.ItemSort;
_paging.SearchColumn = _userPref.ItemSearch;
_paging.PageSize = Convert.ToInt32(_userPref.PageSize);
PageParams.OrderBy = Prefs.ItemSort;
PageParams.SearchColumn = Prefs.ItemSearch;
PageParams.PageSize = Convert.ToInt32(Prefs.PageSize);
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
await FetchSalesItems();
}
private async Task SetSearchPhrase(string searchTerm)
{
_items = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
Items = new List<SalesItemView>();
PageParams.PageNumber = 1;
PageParams.SearchTerm = searchTerm;
await FetchSalesItems();
}
private async Task SetPageSize(string pageSize)
{
_items = new List<SalesItemView>();
_paging.PageSize = Convert.ToInt32(pageSize);
_paging.PageNumber = 1;
Items = new List<SalesItemView>();
PageParams.PageSize = Convert.ToInt32(pageSize);
PageParams.PageNumber = 1;
await FetchSalesItems();
}
private async Task SetSearchCol(string columnName)
{
_items = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SearchColumn = columnName;
Items = new List<SalesItemView>();
PageParams.PageNumber = 1;
PageParams.SearchColumn = columnName;
await FetchSalesItems();
}
private async Task SetSortCol(string orderBy)
{
_items = new List<SalesItemView>();
_paging.OrderBy = orderBy;
Items = new List<SalesItemView>();
PageParams.OrderBy = orderBy;
await FetchSalesItems();
}
private async Task SetSelectedPage(int page)
{
_items = new List<SalesItemView>();
_paging.PageNumber = page;
Items = new List<SalesItemView>();
PageParams.PageNumber = page;
await FetchSalesItems();
}
private async Task SetGroupCol(string groupFilter)
{
_items = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SelectGroup = groupFilter;
Items = new List<SalesItemView>();
PageParams.PageNumber = 1;
PageParams.SelectGroup = groupFilter;
await FetchSalesItems();
}
private async Task FetchSalesItems()
{
Working = true;
var pagingResponse = await ItemRepo.GetSalesItemsPaged(_paging);
var pagingResponse = await ItemRepo.GetSalesItemsPaged(PageParams);
Working = false;
_items = pagingResponse.Items!;
_metaData = pagingResponse.MetaData;
Items = pagingResponse.Items!;
MetaInfo = pagingResponse.MetaData;
}

View file

@ -21,7 +21,7 @@
@attribute [Authorize(Roles = "Admin,Advisor,Office,Warehouse")]
<CatalogTablePrintComponent ItemList="Items" />
<CatalogTablePrintComponent ItemList="Items" CountryName="@UserInfo.CountryName" />
@if (Working)
{
<WorkingThreeDots/>

View file

@ -34,19 +34,16 @@ public partial class CatalogPrintPage : IDisposable
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserPrefService UserPrefService { get; set; }
private List<SalesItemView> Items { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();
private bool Working { get; set; } = true;
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
await GetSalesItems();
}
private async Task GetSalesItems()
{
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
Items = await ItemRepo.GetPriceList();
Working = false;
}

View file

@ -36,13 +36,20 @@ namespace Wonky.Client.Pages
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
private List<CompanyDto> Companies { get; set; } = new();
private MetaData PageData { get; set; } = new();
private CompanyPagingParams PageParams = new();
private UserPref Prefs { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();
private string SavedSearch { get; set; } = "";
private bool IncludeFolded { get; set; }
private bool Working { get; set; } = true;
private MetaData PageData { get; set; } = new();
private CompanyPagingParams PageParams { get; set; } = new();
protected override void OnParametersSet()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
}
protected override async Task OnInitializedAsync()
{
@ -59,9 +66,6 @@ namespace Wonky.Client.Pages
SavedSearch = string.IsNullOrWhiteSpace(Prefs.CompanyFilterPhrase) ? "" : Prefs.CompanyFilterPhrase;
PageParams.SearchTerm = SavedSearch;
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// get companies
await FetchCompanies();
Working = false;
@ -129,12 +133,12 @@ namespace Wonky.Client.Pages
private async Task FetchCompanies()
{
Working = true;
var pagingResponse = await CompanyRepo.GetCompanies(PageParams);
var pageRes = await CompanyRepo.GetCompanies(PageParams);
Working = false;
if (pagingResponse.Items.Any())
if (pageRes.Items.Any())
{
Companies = pagingResponse.Items;
PageData = pagingResponse.MetaData;
Companies = pageRes.Items;
PageData = pageRes.MetaData;
}
else
{

View file

@ -13,7 +13,6 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.RegularExpressions;
using Blazored.LocalStorage;
@ -66,48 +65,35 @@ public partial class CrmCompanyViewPage : IDisposable
private ContactDto DefaultContact { get; set; } = new();
private ContactModal ContactPopup { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();
private string Etag { get; set; } = "";
private string _getServerData { get; set; } = "";
[Parameter]
public string RpcDone
{
get => _getServerData;
set
{
if (_getServerData == value)
return;
_getServerData = value;
var x = PrepareCompanyDate().Result;
}
}
private async Task<string> PrepareCompanyDate()
{
// call background task to fetch contacts
await FetchContacts(CompanyId);
return await HistoryRepo.RpcSyncErpToCrm(Company.CompanyId, Company.HistorySync, Etag);
}
protected override async Task OnInitializedAsync()
{
// setup interceptor
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// initialize default contact
DefaultContact = new ContactDto { CompanyId = CompanyId, ContactId = "", FirstName = ""};
// setup form context
ErpContext = new EditContext(Company);
// assign event handlers to context
ErpContext.OnFieldChanged += HandleFieldChanged;
ErpContext.OnValidationStateChanged += ValidationChanged;
// fetch user info from local storage
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
CountryCode = UserInfo.CountryCode.ToLower();
CountryIsDk = CountryCode == "dk";
// setup interceptor
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
Company = await CompanyRepo.GetCompanyById(CompanyId);
Etag = Company.Etag;
Company.Etag = Guid.NewGuid().ToString();
Logger.LogDebug("companyId => {}", CompanyId);
if (!string.IsNullOrWhiteSpace(CompanyId))
RpcDone = CompanyId;
Company = await CompanyRepo.GetCompanyById(CompanyId);
Logger.LogDebug("company => {}", JsonSerializer.Serialize(Company));
CurrentVat = Company.VatNumber;
Company.CountryCode = UserInfo.CountryCode.ToLower();
// internal flag
EnableActivity = Company.ValidVat;
@ -151,14 +137,9 @@ public partial class CrmCompanyViewPage : IDisposable
if (CountryIsDk)
CompanyVatAddress = PrepareVatAddress(Company);
// initialize default contact
DefaultContact = new ContactDto { CompanyId = CompanyId, ContactId = "", FirstName = ""};
// setup form context
ErpContext = new EditContext(Company);
// assign event handlers to context
ErpContext.OnFieldChanged += HandleFieldChanged;
ErpContext.OnValidationStateChanged += ValidationChanged;
await FetchContacts(CompanyId);
// remove loading image
Working = false;
}
@ -171,7 +152,8 @@ public partial class CrmCompanyViewPage : IDisposable
{
// load contacts
Contacts = await ContactRepo.GetContacts(companyId);
Contacts = Contacts.OrderBy(x => x.FirstName).ToList();
if(Contacts.Any() && Contacts.Count > 1)
Contacts = Contacts.OrderBy(x => x.FirstName).ToList();
}
/// <summary>
@ -228,18 +210,19 @@ public partial class CrmCompanyViewPage : IDisposable
{
Working = true;
// write contact to debug log
Logger.LogDebug("CompanyView => SaveContactCallback <= {}", JsonSerializer.Serialize(contact));
var jsonContact = JsonSerializer.Serialize(contact);
Logger.LogDebug("CompanyView => SaveContactCallback <= {}", jsonContact);
if (string.IsNullOrWhiteSpace(contact.ContactId))
{
// new contact created
Logger.LogDebug("create");
Logger.LogDebug("create => {}", jsonContact);
// send post request to backend
await ContactRepo.CreateContact(contact);
}
else
{
// contact modified
Logger.LogDebug("update");
Logger.LogDebug("update => {}", jsonContact);
// send put request to backend
await ContactRepo.UpdateContact(contact);
}
@ -326,6 +309,7 @@ public partial class CrmCompanyViewPage : IDisposable
if (!string.IsNullOrWhiteSpace(result.Name))
{
Company = result;
StateHasChanged();
}
Working = false;
}

View file

@ -26,7 +26,7 @@
<WorkDateComponent OnChangedCallback="SetWorkDateCallback"/>
</div>
<div class="col-sm-4 text-end">
<AdvisorActivityKmStartComponent/>
<AdvisorActivityKmStartComponent disabled/>
</div>
</div>
@ -71,7 +71,7 @@
}
else
{
Report.Figures.KmMorning = UserPref.KmMorning;
Report.Figures.KmMorning = Prefs.KmMorning;
<td>
<input type="time" id="checkIn" class="form-control"
@bind-Value="_checkIn" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>

View file

@ -35,7 +35,7 @@ namespace Wonky.Client.Pages;
public partial class CrmReportNewPage : IDisposable
{
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserPrefService UserPrefService { get; set; }
[Inject] public UserPrefService PrefService { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ICrmReportHttpRepository CrmReportRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
@ -45,7 +45,7 @@ public partial class CrmReportNewPage : IDisposable
private ReportDto Report { get; set; } = new();
private List<ReportItemView> Activities { get; set; } = new();
private ReportFiguresDto InitialValues { get; set; }
private UserPref UserPref { get; set; } = new();
private UserPref Prefs { get; set; } = new();
private bool FormInvalid { get; set; } = true;
private bool NoFigures { get; set; } = true;
private bool Working { get; set; } = true;
@ -64,23 +64,26 @@ public partial class CrmReportNewPage : IDisposable
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
ReportContext = new EditContext(Report);
ReportContext.OnFieldChanged += HandleFieldChanged;
ReportContext.OnValidationStateChanged += ValidationChanged;
UserPref = await UserPrefService.GetPreferences();
if (!string.IsNullOrWhiteSpace(UserPref.WorkDate))
_workDate = DateTime.Parse(UserPref.WorkDate);
Prefs = await PrefService.GetPreferences();
if (!string.IsNullOrWhiteSpace(Prefs.WorkDate))
_workDate = DateTime.Parse(Prefs.WorkDate);
if(await CrmReportRepo.ReportExist(UserPref.WorkDate))
Navigator.NavigateTo($"/sales-reports/view/{UserPref.WorkDate}");
if(await CrmReportRepo.ReportExist(Prefs.WorkDate))
Navigator.NavigateTo($"/sales-reports/view/{Prefs.WorkDate}");
BeginLeave = _workDate;
EndLeave = _workDate;
Report.FromDateTime = $"{_workDate:yyyy-MM-dd'T'12:00:00}";
Report.ToDateTime = $"{_workDate:yyyy-MM-dd'T'12:00:00}";
Report.Figures.KmMorning = 0;
Report.Figures.KmEvening = 0;
Report.Figures.Distance = 0;
Report.Figures.DistancePrivateMonth = 0;
await GetKeyFigures();
@ -125,10 +128,17 @@ public partial class CrmReportNewPage : IDisposable
Working = true;
var result = await CrmReportRepo.PostReport($"{_workDate:yyyy-MM-dd}", Report);
if (!result.IsSuccess)
{
Working = false;
Toaster.ShowError($"{result.Message}", $"HTTP Status {result.Code}");
return;
}
// reset km and date confirmation
// await PreferenceService.SetKmMorning(0);
await PrefService.SetKmMorning(0);
// reset date confirmed
await UserPrefService.SetDateConfirmed(false);
await PrefService.SetDateConfirmed(false);
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
}
/// <summary>
@ -170,16 +180,27 @@ public partial class CrmReportNewPage : IDisposable
// format report date time input
Report.FromDateTime = checkIn.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture);
Report.ToDateTime = checkOut.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture);
// assign final distance numbers
if (Report.DayTypeEnum.ToLower().Contains("leave"))
{
Report.Figures.KmEvening = 0;
Report.Figures.KmMorning = 0;
}
// calculate distance
Report.Figures.Distance = Report.Figures.KmEvening - Report.Figures.KmMorning;
// add distance to distance month
Report.Figures.DistanceMonth += Report.Figures.Distance;
// add private distance to month
Report.Figures.DistancePrivateMonth += Report.Figures.DistancePrivate;
Logger.LogDebug("_workDate => {workDate}", $"{_workDate:yyyy-MM-dd}");
Logger.LogDebug("_report => {report}", JsonSerializer.Serialize(Report));
// create a prompt
Prompt = Report.Figures.Distance > 1000 ? $"'{Report.Figures.Distance}'KM tal er meget højt. Er du sikker på at det er rigtigt? Gem rapport for {_workDate.ToLongDateString()}?" : $"Gem Rapport for {_workDate.ToLongDateString()}?";
// pop confirmation
// create a prompt for popup confirmation
Prompt = Report.Figures.Distance > 1000 ? $"'{Report.Figures.Distance}'KM tal er meget højt. Er du sikker på at det er rigtigt? Gem rapport for {_workDate.ToLongDateString()}?" : $"Gem Rapport for {_workDate.ToLongDateString()}?";
ConfirmReportModal.Show();
}
@ -234,9 +255,16 @@ public partial class CrmReportNewPage : IDisposable
Report.Figures = data.ReportData;
InitialValues = data.ReportData;
Activities = data.ReportItems;
if(!Report.DayTypeEnum.ToLower().Contains("leave"))
Report.Figures.KmMorning = UserPref.KmMorning;
if (Report.DayTypeEnum.ToLower().Contains("leave"))
{
Report.Figures.KmMorning = 0;
Report.Figures.KmEvening = 0;
}
else
{
Report.Figures.KmMorning = Prefs.KmMorning;
}
NoFigures = false;
Working = false;

View file

@ -1,7 +1,7 @@
{
"appInfo": {
"name": "Wonky Client",
"version": "0.77.1",
"version": "0.79.1",
"rc": true,
"sandBox": false,
"image": "grumpy-coder.png"
@ -14,7 +14,7 @@
"crmProductExt": "history/products",
"crmReports": "api/v2/crm/advisors/reports",
"crmActivities": "api/v2/crm/advisors/activities",
"crmRpcSyncExt": "invoices/sync",
"crmRpcSyncExt": "invoices/rpc",
"crmTasks": "api/v2/crm/advisors/tasks",
"crmWorkplaceExt": "workplaces",
"officeAdvisors": "api/v2/office/users/advisors",

View file

@ -22,60 +22,10 @@ namespace Wonky.Entity.DTO;
public class CompanyDto
{
/// <summary>
/// Name
/// Account number
/// </summary>
[Required(ErrorMessage = "Navn skal udfyldes")]
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Name { get; set; } = "";
/// <summary>
/// Alert
/// </summary>
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Note { get; set; } = "";
/// <summary>
/// Crm note
/// </summary>
public string CrmNotes { get; set; } = "";
/// <summary>
/// Postal code
/// </summary>
[Required(ErrorMessage = "Postnummer skal udfyldes")]
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string ZipCode { get; set; } = "";
/// <summary>
/// City name
/// </summary>
[Required(ErrorMessage = "Bynavn skal udfyldes")]
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
public string City { get; set; } = "";
/// <summary>
/// VAT number
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string VatNumber { get; set; } = "";
/// <summary>
/// Company Id
/// </summary>
public string CompanyId { get; set; } = "";
/// <summary>
/// Sales representative entity Id
/// </summary>
public string SalesRepId { get; set; } = "";
/// <summary>
/// SalesRep ERP identifier
/// </summary>
public string SalesRep { get; set; } = "";
/// <summary>
/// Business Central entity Id
/// </summary>
public string BcId { get; set; } = "";
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Account { get; set; } = "";
/// <summary>
/// Office address 1
@ -90,22 +40,43 @@ public class CompanyDto
public string Address2 { get; set; } = "";
/// <summary>
/// Account number
/// Attention
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Account { get; set; } = "";
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Attention { get; set; } = "";
/// <summary>
/// Phone number
/// Business Central entity Id
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Phone { get; set; } = "";
public string BcId { get; set; } = "";
/// <summary>
/// ERP block state
/// </summary>
/// <remarks>Empty string - Customer not blocked</remarks>
public string Blocked { get; set; } = "";
/// <summary>
/// Mobile phone number
/// City name
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Mobile { get; set; } = "";
[Required(ErrorMessage = "Bynavn skal udfyldes")]
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
public string City { get; set; } = "";
/// <summary>
/// Company Id
/// </summary>
public string CompanyId { get; set; } = "";
/// <summary>
/// Country code ISO
/// </summary>
public string CountryCode { get; set; } = "";
/// <summary>
/// Crm note
/// </summary>
public string CrmNotes { get; set; } = "";
/// <summary>
/// Office email
@ -114,32 +85,16 @@ public class CompanyDto
public string Email { get; set; } = "";
/// <summary>
/// Attention
/// Value indication if company has shutdown
/// </summary>
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Attention { get; set; } = "";
/// <value>0 or 1</value>
public int HasFolded { get; set; }
/// <summary>
/// ERP block state
/// Date for last sync of product history
/// </summary>
/// <remarks>Empty string - Customer not blocked</remarks>
public string Blocked { get; set; } = "";
/// <summary>
/// Country code ISO
/// </summary>
public string CountryCode { get; set; } = "";
/// <summary>
/// Last visit
/// </summary>
public string LastVisit { get; set; } = "2010-01-01";
/// <summary>
/// Next visit
/// </summary>
public string NextVisit { get; set; } = "2010-01-01";
public string HistorySync { get; set; } = "";
/// <summary>
/// Interval between visits
/// </summary>
@ -147,37 +102,76 @@ public class CompanyDto
[Range(1, 52, ErrorMessage = "Angiv interval mellem 1 og 52 uger")]
public int Interval { get; set; } = 8;
/// <summary>
/// Value indication if company has shutdown
/// </summary>
/// <value>0 or 1</value>
public int HasFolded { get; set; }
/// <summary>
/// User value for hiding the company is out of business
/// </summary>
/// <value>0 or 1</value>
public int IsHidden { get; set; }
/// <summary>
/// Last visit
/// </summary>
public string LastVisit { get; set; } = "2010-01-01";
/// <summary>
/// Mobile phone number
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Mobile { get; set; } = "";
/// <summary>
/// Name
/// </summary>
[Required(ErrorMessage = "Navn skal udfyldes")]
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Name { get; set; } = "";
/// <summary>
/// Next visit
/// </summary>
public string NextVisit { get; set; } = "2010-01-01";
/// <summary>
/// Alert
/// </summary>
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string Note { get; set; } = "";
/// <summary>
/// Phone number
/// </summary>
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string Phone { get; set; } = "";
/// <summary>
/// SalesRep ERP identifier
/// </summary>
public string SalesRep { get; set; } = "";
/// <summary>
/// Sales representative entity Id
/// </summary>
public string SalesRepId { get; set; } = "";
/// <summary>
/// Value indicating the VAT number is valid
/// </summary>
/// <value>0 or 1</value>
public int ValidVat { get; set; }
/// <summary>
/// Value indicating if VAT number has changed and should be written to ERP record
/// </summary>
/// <value>0 or 1</value>
public int UpdateErpVat { get; set; }
/// <summary>
/// Date for last sync of product history
/// VAT number
/// </summary>
public string HistorySync { get; set; } = "";
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string VatNumber { get; set; } = "";
/// <summary>
/// Postal code
/// </summary>
[Required(ErrorMessage = "Postnummer skal udfyldes")]
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
public string ZipCode { get; set; } = "";
public int IsDirty { get; set; } = 0;
public string Etag { get; set; } = "";
/// <summary>
/// Virtual property indicating if timespan is within the defined interval
/// </summary>