reworked documentation preparing for office order creation and country price lookup

This commit is contained in:
Frede Hundewadt 2022-12-31 03:18:16 +01:00
parent d9ca65b96b
commit c6625f08a2
86 changed files with 1813 additions and 1155 deletions

View file

@ -30,7 +30,7 @@ public partial class CustomerProductTableComponent
[CascadingParameter] public DraftStateProvider DraftStateProvider { get; set; } = new();
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public ICatalogHttpRepository Catalog { get; set; }
[Inject] public ICatalogCrmHttpRepository CatalogCrm { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
// private variables
private SalesItemView SalesItem { get; set; } = new();
@ -89,7 +89,7 @@ public partial class CustomerProductTableComponent
private async Task CallShowReorderModal(string sku)
{
// fetch item from http repo
SalesItem = await Catalog.GetSalesItemSku(sku);
SalesItem = await CatalogCrm.GetSalesItemSku(sku);
ReorderModal.Show();
}

View file

@ -36,7 +36,7 @@ public partial class LandingComponentAdmin : IDisposable
[Inject] public ILogger<LandingComponentAdmin> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ICrmTaskItemHttpRepository CrmTaskItemRepo { get; set; }
[Inject] public ITaskItemCrmHttpRepository TaskRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
private readonly JsonSerializerOptions _options = new JsonSerializerOptions

View file

@ -36,7 +36,7 @@ public partial class LandingComponentAdvisor : IDisposable
[Inject] public ILogger<LandingComponentAdvisor> Logger { get; set; }
[Inject] public HttpInterceptorService Inteceptor { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ICrmTaskItemHttpRepository TaskItemRepo { get; set; }
[Inject] public ITaskItemCrmHttpRepository TaskRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
private readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
@ -63,7 +63,7 @@ public partial class LandingComponentAdvisor : IDisposable
private async Task GetAllTasks()
{
TaskItems = await TaskItemRepo.GetTaskList();
TaskItems = await TaskRepo.GetTaskList();
}
private async Task OnCompleteTask(string taskItemId)
@ -77,14 +77,14 @@ public partial class LandingComponentAdvisor : IDisposable
{
SelectedDate = DateTime.Parse(workDate);
TaskItems = new List<TaskItemDto>();
TaskItems = await TaskItemRepo.GetTaskList($"{SelectedDate:yyyy-MM-dd}");
TaskItems = await TaskRepo.GetTaskList($"{SelectedDate:yyyy-MM-dd}");
}
private async Task OnTaskCompleted(string taskItemId)
{
var item = TaskItems.Find(x => x.TaskItemId == taskItemId);
item.IsCompleted = true;
await TaskItemRepo.UpdateTaskItem(taskItemId, item);
await TaskRepo.UpdateTaskItem(taskItemId, item);
TaskItems.Remove(item);
Toaster.ShowInfo("Opgaven er markeret som udført.");
}
@ -93,7 +93,7 @@ public partial class LandingComponentAdvisor : IDisposable
{
var item = TaskItems.First(x => x.TaskItemId == taskItemId);
TaskItems.Remove(item);
await TaskItemRepo.DeleteTaskItem(taskItemId);
await TaskRepo.DeleteTaskItem(taskItemId);
Toaster.ShowInfo("Opgaven er slettet.");
}

View file

@ -14,14 +14,34 @@
//
namespace Wonky.Client.Features;
/// <summary>
/// PagingLink class
/// </summary>
public class PagingLink
{
/// <summary>
/// Text
/// </summary>
public string Text { get; set; }
/// <summary>
/// Page
/// </summary>
public int Page { get; set; }
/// <summary>
/// Enabled
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Active
/// </summary>
public bool Active { get; set; }
/// <summary>
/// The paging link
/// </summary>
/// <param name="page"></param>
/// <param name="enabled"></param>
/// <param name="text"></param>
public PagingLink(int page, bool enabled, string text)
{
Page = page;

View file

@ -18,8 +18,18 @@ using Wonky.Entity.Requests;
namespace Wonky.Client.Features;
/// <summary>
/// PagingResponse T class
/// </summary>
/// <typeparam name="T"></typeparam>
public class PagingResponse<T> where T : class
{
/// <summary>
/// Items
/// </summary>
public List<T>? Items { get; set; }
/// <summary>
/// Meta DAta
/// </summary>
public MetaData? MetaData { get; set; }
}

View file

@ -21,73 +21,99 @@ using Microsoft.AspNetCore.Components.Rendering;
namespace Wonky.Client.Helpers;
/// <summary>
/// InputDateTime Component
/// </summary>
/// <typeparam name="TValue"></typeparam>
public class InputDateTime<TValue> : InputDate<TValue>
{
private const string DateFormat = "yyyy-MM-ddTHH:mm";
/// <inheritdoc />
protected override void BuildRenderTree ( RenderTreeBuilder builder )
/// <summary>
/// BuildTender
/// </summary>
/// <param name="builder"></param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement( 0, "input" );
builder.AddMultipleAttributes( 1, AdditionalAttributes );
builder.AddAttribute( 2, "type", "datetime-local" );
builder.AddAttribute( 3, "class", CssClass );
builder.AddAttribute( 4, "value", BindConverter.FormatValue( CurrentValueAsString ) );
builder.AddAttribute( 5, "onchange", EventCallback.Factory.CreateBinder<string>( this, __value => CurrentValueAsString = __value, CurrentValueAsString ) );
builder.OpenElement(0, "input");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "type", "datetime-local");
builder.AddAttribute(3, "class", CssClass);
builder.AddAttribute(4, "value", BindConverter.FormatValue(CurrentValueAsString));
builder.AddAttribute(5, "onchange",
EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value,
CurrentValueAsString));
builder.CloseElement();
}
/// <inheritdoc />
protected override string FormatValueAsString ( TValue value )
/// <summary>
/// Format value as string
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
protected override string FormatValueAsString(TValue value)
{
switch ( value )
return value switch
{
case DateTime dateTimeValue:
return BindConverter.FormatValue( dateTimeValue, DateFormat, CultureInfo.InvariantCulture );
case DateTimeOffset dateTimeOffsetValue:
return BindConverter.FormatValue( dateTimeOffsetValue, DateFormat, CultureInfo.InvariantCulture );
default:
return string.Empty; // Handles null for Nullable<DateTime>, etc.
}
DateTime dateTimeValue =>
BindConverter.FormatValue(dateTimeValue, DateFormat, CultureInfo.InvariantCulture),
DateTimeOffset dateTimeOffsetValue => BindConverter.FormatValue(dateTimeOffsetValue, DateFormat,
CultureInfo.InvariantCulture),
_ => string.Empty
};
}
/// <inheritdoc />
protected override bool TryParseValueFromString ( string value, out TValue result, out string validationErrorMessage )
/// <summary>
/// TryParseValueFromString
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <param name="validationErrorMessage"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)
{
// Unwrap nullable types. We don't have to deal with receiving empty values for nullable
// types here, because the underlying InputBase already covers that.
var targetType = Nullable.GetUnderlyingType( typeof( TValue ) ) ?? typeof( TValue );
var targetType = Nullable.GetUnderlyingType(typeof(TValue)) ?? typeof(TValue);
bool success;
if ( targetType == typeof( DateTime ) )
if (targetType == typeof(DateTime))
{
success = TryParseDateTime( value, out result );
success = TryParseDateTime(value, out result);
}
else if ( targetType == typeof( DateTimeOffset ) )
else if (targetType == typeof(DateTimeOffset))
{
success = TryParseDateTimeOffset( value, out result );
success = TryParseDateTimeOffset(value, out result);
}
else
{
throw new InvalidOperationException( $"The type '{targetType}' is not a supported date type." );
throw new InvalidOperationException($"The type '{targetType}' is not a supported date type.");
}
if ( success )
if (success)
{
validationErrorMessage = null;
return true;
}
else
{
validationErrorMessage = string.Format( ParsingErrorMessage, FieldIdentifier.FieldName );
validationErrorMessage = string.Format(ParsingErrorMessage, FieldIdentifier.FieldName);
return false;
}
}
static bool TryParseDateTime ( string value, out TValue result )
/// <summary>
/// TrypParseDateTime
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
private static bool TryParseDateTime(string value, out TValue result)
{
var success = BindConverter.TryConvertToDateTime( value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue );
if ( success )
var success =
BindConverter.TryConvertToDateTime(value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue);
if (success)
{
result = (TValue)(object)parsedValue;
return true;
@ -99,10 +125,18 @@ public class InputDateTime<TValue> : InputDate<TValue>
}
}
static bool TryParseDateTimeOffset ( string value, out TValue result )
/// <summary>
/// TryParseDateTimeOffset
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
private static bool TryParseDateTimeOffset(string value, out TValue result)
{
var success = BindConverter.TryConvertToDateTimeOffset( value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue );
if ( success )
var success =
BindConverter.TryConvertToDateTimeOffset(value, CultureInfo.InvariantCulture, DateFormat,
out var parsedValue);
if (success)
{
result = (TValue)(object)parsedValue;
return true;

View file

@ -28,36 +28,79 @@ using System.Diagnostics;
namespace Wonky.Client.Helpers
{
/// <summary>
/// Squid is guid string shortened and url safe
/// </summary>
[DebuggerDisplay("{" + nameof(Value) + "}")]
public readonly struct Squid : IEquatable<Squid>
{
{
/// <summary>
/// Return Empty value
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public static readonly Squid Empty = new(Guid.Empty);
/// <summary>
/// Decode Squid to Guid
/// </summary>
/// <param name="value"></param>
public Squid(string value)
{
Value = value;
Guid = DecodeSquid(value);
}
/// <summary>
/// Generate Squid from Guid object
/// </summary>
/// <param name="obj"></param>
public Squid(Guid obj)
{
Value = EncodeGuid(obj);
Guid = obj;
}
#pragma warning disable CA1720 // Identifier contains type name
/// <summary>
/// Guid
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public Guid Guid { get; }
#pragma warning restore CA1720 // Identifier contains type name
public string Value { get; }
/// <summary>
/// ToString() function
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Value;
}
public override bool Equals(object obj)
/// <summary>
/// Equality
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object? obj)
{
return obj is Squid other && Equals(other);
}
/// <summary>
/// EQuality
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public bool Equals(Squid obj)
{
return Guid.Equals(obj.Guid) && Value == obj.Value;
}
/// <summary>
/// Get hashcode
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
unchecked
@ -65,15 +108,33 @@ namespace Wonky.Client.Helpers
return (Guid.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0);
}
}
/// <summary>
/// Create Squid from new Guid
/// </summary>
/// <returns></returns>
public static Squid NewGuid()
{
return new(Guid.NewGuid());
return new Squid(Guid.NewGuid());
}
/// <summary>
/// Encode string
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string EncodeString(string value)
{
var guid = new Guid(value);
return EncodeGuid(guid);
}
/// <summary>
/// Encode Guid
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
// ReSharper disable once MemberCanBePrivate.Global
public static string EncodeGuid(Guid obj)
{
var encoded = Convert.ToBase64String(obj.ToByteArray());
@ -82,25 +143,52 @@ namespace Wonky.Client.Helpers
.Replace("+", "-");
return encoded.Substring(0, 22);
}
/// <summary>
/// Decode Squid
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
// ReSharper disable once MemberCanBePrivate.Global
public static Guid DecodeSquid(string value)
{
if (value == null) return Empty;
if (!value.Any()) return Empty;
value = value
.Replace("_", "/")
.Replace("-", "+");
var blob = Convert.FromBase64String(value + "==");
return new Guid(blob);
}
/// <summary>
/// Guid From Squid
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static Guid FromSquid(Squid obj)
{
return obj.Guid;
}
/// <summary>
/// Squid From String
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static Squid FromString(string value)
{
if (string.IsNullOrEmpty(value))
return Empty;
return TryParse(value, out Squid obj) ? obj : Empty;
}
/// <summary>
/// TryDecode
/// </summary>
/// <param name="value"></param>
/// <param name="obj"></param>
/// <returns></returns>
// ReSharper disable once MemberCanBePrivate.Global
public static bool TryDecode(string value, out Guid obj)
{
try
@ -109,15 +197,21 @@ namespace Wonky.Client.Helpers
obj = DecodeSquid(value);
return true;
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception)
#pragma warning restore CA1031 // Do not catch general exception types
{
// Return empty Guid
obj = Guid.Empty;
return false;
}
}
/// <summary>
/// TryParse
/// </summary>
/// <param name="value"></param>
/// <param name="obj"></param>
/// <returns></returns>
// ReSharper disable once MemberCanBePrivate.Global
public static bool TryParse(string value, out Squid obj)
{
// Parse as Squid string.
@ -126,15 +220,24 @@ namespace Wonky.Client.Helpers
obj = oGuid;
return true;
}
// Parse as Guid string.
if (Guid.TryParse(value, out oGuid))
{
obj = oGuid;
return true;
}
obj = Empty;
return false;
}
/// <summary>
/// TryParse
/// </summary>
/// <param name="value"></param>
/// <param name="obj"></param>
/// <returns></returns>
public static bool TryParse(string value, out Guid obj)
{
// Try a Squid string.
@ -146,38 +249,98 @@ namespace Wonky.Client.Helpers
obj = Guid.Empty;
return false;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator ==(Squid x, Squid y)
{
return x.Guid == y.Guid;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator ==(Squid x, Guid y)
{
return x.Guid == y;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator ==(Guid x, Squid y)
{
return y == x; // NB: order of arguments
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator !=(Squid x, Squid y)
{
return !(x == y);
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator !=(Squid x, Guid y)
{
return !(x == y);
}
/// <summary>
/// Operator
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static bool operator !=(Guid x, Squid y)
{
return !(x == y);
}
/// <summary>
/// Operator
/// </summary>
/// <param name="oSquid"></param>
/// <returns></returns>
public static implicit operator string(Squid oSquid)
{
return oSquid.Value;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="oSquid"></param>
/// <returns></returns>
public static implicit operator Guid(Squid oSquid)
{
return oSquid.Guid;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static implicit operator Squid(string value)
{
if (string.IsNullOrEmpty(value))
@ -185,6 +348,12 @@ namespace Wonky.Client.Helpers
return TryParse(value, out Squid oSquid) ? oSquid : Empty;
}
/// <summary>
/// Operator
/// </summary>
/// <param name="oGuid"></param>
/// <returns></returns>
public static implicit operator Squid(Guid oGuid)
{
return oGuid == Guid.Empty ? Empty : new Squid(oGuid);

View file

@ -17,7 +17,13 @@ namespace Wonky.Client.Helpers;
public static class StringExtensions
{
public static string Left(this string value, int maxLength)
/// <summary>
/// Left Pad a string with spaces until maxlength
/// </summary>
/// <param name="value"></param>
/// <param name="maxLength"></param>
/// <returns></returns>
public static string PadLeft(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value)) return value;
maxLength = Math.Abs(maxLength);

View file

@ -21,60 +21,95 @@ namespace Wonky.Client.Helpers;
public static class Utils
{
/// <summary>
/// Helper to parse querystring
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public static Dictionary<string, string> ParseQuery(string query)
{
if (string.IsNullOrWhiteSpace(query) || query.Contains("://"))
return new Dictionary<string, string>();
// remove the question mark
query = query.Replace("?", "");
// split into pairs
var elements = query.Split("&");
// return elements as list
return elements.Select(
data
=> data.Split("="))
data
=> data.Split("="))
.ToDictionary(element => element[0], element => element[1]);
}
/// <summary>
/// Validate email format
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public static bool IsValidEmail(string email)
{
var trimmedEmail = email.Trim();
if (trimmedEmail.EndsWith(".")) {
if (trimmedEmail.EndsWith("."))
{
return false; // suggested by @TK-421
}
try {
try
{
var addr = new MailAddress(email);
return addr.Address == trimmedEmail;
}
catch {
catch
{
return false;
}
}
/// <summary>
/// return enum as the string value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string EnumToString(Enum value)
{
return value.ToString();
}
/// <summary>
/// Generate unique hashcode from time
/// </summary>
/// <returns></returns>
public static int GetHashFromNow()
{
return DateTime.Now.ToFileTimeUtc().GetHashCode();
}
/// <summary>
/// Get visit state as colored icon
/// </summary>
/// <param name="dtNextVisit"></param>
/// <returns></returns>
public static string GetVisitState(string dtNextVisit)
{
if (dtNextVisit is "0001-01-01" or "1970-01-01")
return "the-draw";
if (!DateTime.TryParse(dtNextVisit, out _))
return "the-draw";
var dtNow = DateTime.Now;
var dtNext = DateTime.Parse(dtNextVisit);
if (dtNow > dtNext)
return "the-ugly";
return dtNow > dtNext.AddDays(-14) ? "the-bad" : "the-good";
}
/// <summary>
/// Translate process status to icon
/// </summary>
/// <param name="processStatus"></param>
/// <returns></returns>
public static string GetProcessStatus(string processStatus)
{
return processStatus.ToLower() switch
@ -86,5 +121,5 @@ public static class Utils
"shipped" => "the-dead",
_ => "question-square"
};
}
}
}

View file

@ -21,14 +21,19 @@ public class VatUtils
{
// https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11
// https://ec.europa.eu/taxation_customs/vies/
/// <summary>
/// Entrypoint for validating vat number
/// </summary>
/// <param name="countryCode"></param>
/// <param name="vatNumber"></param>
/// <returns></returns>
public static bool ValidateFormat(string countryCode, string vatNumber)
{
if (string.IsNullOrWhiteSpace(vatNumber) || string.IsNullOrWhiteSpace(countryCode) || !IsDigitsOnly(vatNumber))
return false;
var sanitisedVat = SanitizeVatNumber(vatNumber);
return countryCode.ToUpperInvariant() switch
{
"DK" => ValidateFormatDk(sanitisedVat),
@ -38,10 +43,21 @@ public class VatUtils
};
}
/// <summary>
/// Validate string is only numbers
/// </summary>
/// <param name="check"></param>
/// <returns></returns>
private static bool IsDigitsOnly(string check)
{
return check.All(c => c is >= '0' and <= '9');
}
/// <summary>
/// Validate Danish Vat number format
/// </summary>
/// <param name="vatNumber"></param>
/// <returns></returns>
private static bool ValidateFormatDk(string vatNumber)
{
// https://wiki.scn.sap.com/wiki/display/CRM/Denmark
@ -57,6 +73,11 @@ public class VatUtils
return ValidateMod11(vatNumber);
}
/// <summary>
/// Validate Norwegian Vat number format
/// </summary>
/// <param name="vatNumber"></param>
/// <returns></returns>
private static bool ValidateFormatNo(string vatNumber)
{
// https://wiki.scn.sap.com/wiki/display/CRM/Norway
@ -69,6 +90,11 @@ public class VatUtils
return long.Parse(vatNumber) != 0 && ValidateMod11(vatNumber);
}
/// <summary>
/// Validate Swedish Vat number format
/// </summary>
/// <param name="vatNumber"></param>
/// <returns></returns>
private static bool ValidateFormatSe(string vatNumber)
{
// https://wiki.scn.sap.com/wiki/display/CRM/Sweden
@ -81,7 +107,7 @@ public class VatUtils
var vatToCheck = vatNumber;
if (vatToCheck.Length < 10 || long.Parse(vatToCheck) == 0)
return false;
var r = new[] { 0, 2, 4, 6, 8 }
.Sum(m => (int)char.GetNumericValue(vatToCheck[m]) / 5 +
(int)char.GetNumericValue(vatToCheck[m]) * 2 % 10);
@ -89,11 +115,17 @@ public class VatUtils
var c10 = (10 - (r + c1) % 10) % 10;
if (vatToCheck.Length == 10)
{
return $"{vatToCheck[..9]}{c10}" == vatNumber;
return $"{vatToCheck[..9]}{c10}" == vatNumber;
}
return $"{vatToCheck[..9]}{c10}01" == vatNumber;
}
/// <summary>
/// Modulus11 validator
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
private static bool ValidateMod11(string number)
{
if (long.Parse(number) == 0)
@ -108,14 +140,18 @@ public class VatUtils
return sum % 11 == 0;
}
/// <summary>
/// Sanitize Vat number to it's raw numbers
/// </summary>
/// <param name="vatNumber"></param>
/// <returns></returns>
private static string SanitizeVatNumber(string vatNumber)
{
return vatNumber.ToUpperInvariant()
.Replace(" ", "")
return vatNumber.Replace(" ", "")
.Replace("-", "")
.Replace("DK", "")
.Replace("NO", "")
.Replace("SE","")
.Replace("SE", "")
.Replace("MVA", "");
}
}

View file

@ -18,7 +18,10 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmActivityHttpRepository
/// <summary>
/// Interface Activity CRM Http repository
/// </summary>
public interface IActivityCrmHttpRepository
{
/// <summary>
/// Get a list of open quotes
@ -33,13 +36,6 @@ public interface ICrmActivityHttpRepository
/// <returns></returns>
Task<ApiResponseView> UpdateQuoteStatus(ReportItemView activity);
/// <summary>
/// Get activities by date
/// </summary>
/// <param name="activityDate"></param>
/// <returns></returns>
Task<ReportStatusView> GetActivities(string activityDate);
/// <summary>
/// Create new activity
/// </summary>
@ -47,12 +43,26 @@ public interface ICrmActivityHttpRepository
/// <returns></returns>
Task<ApiResponseView> CreateActivity(ActivityDto model);
/// <summary>
/// Get activities by date
/// </summary>
/// <param name="activityDate"></param>
/// <returns></returns>
Task<ReportStatusView> GetActivities(string activityDate);
/// <summary>
/// Get activity data by id
/// </summary>
/// <param name="activityId"></param>
/// <returns></returns>
Task<ActivityDto> GetActivity(string activityId);
/// <summary>
/// Get activities for customer Id
/// </summary>
/// <param name="customerId"></param>
/// <returns></returns>
Task<List<ReportItemView>> GetCustomerActivities(string customerId);
/// <summary>
/// Get activity by id formatted for report
@ -61,20 +71,13 @@ public interface ICrmActivityHttpRepository
/// <returns></returns>
Task<ReportItemView> GetReportItem(string activityId);
/// <summary>
/// Get activities for customer Id
/// </summary>
/// <param name="customerId"></param>
/// <returns></returns>
Task<List<ReportItemView>> GetCustomerActivities(string customerId);
/// <summary>
/// Set backend process state to express
/// </summary>
/// <param name="activityId"></param>
/// <returns>ApiResponseView</returns>
Task<ApiResponseView> GetExpressState(string activityId);
/// <summary>
/// Update office note for activity
/// </summary>

View file

@ -19,7 +19,10 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface ICatalogHttpRepository
/// <summary>
/// Interface Catalog Http repository
/// </summary>
public interface ICatalogCrmHttpRepository
{
/// <summary>
/// Get a paged sales item list
@ -28,6 +31,14 @@ public interface ICatalogHttpRepository
/// <returns></returns>
Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPagingParams pagingParameters);
/// <summary>
/// Get a paged sales item list for country
/// </summary>
/// <param name="pagingParameters"></param>
/// <param name="countryCode"></param>
/// <returns></returns>
Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPagingParams pagingParameters, string countryCode);
/// <summary>
/// Get sales item by id
/// </summary>
@ -43,7 +54,7 @@ public interface ICatalogHttpRepository
Task<SalesItemView> GetSalesItemSku(string sku);
/// <summary>
/// Overload Get sales item by id and country code
/// Overload Get sales item by sku and country code
/// </summary>
/// <param name="sku"></param>
/// <param name="countryCode"></param>
@ -57,5 +68,16 @@ public interface ICatalogHttpRepository
/// <returns></returns>
Task<SalesItemView> GetSalesVariantId(string variantId);
/// <summary>
/// Complete catalog for print
/// </summary>
/// <returns></returns>
Task<List<SalesItemView>> GetPriceList();
/// <summary>
/// Complete catalog for print country
/// </summary>
/// <param name="countryCode"></param>
/// <returns></returns>
Task<List<SalesItemView>> GetPriceList(string countryCode);
}

View file

@ -0,0 +1,47 @@
using Wonky.Entity.DTO;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for Contacts CRM Http repository
/// </summary>
/// <returns></returns>
public interface IContactCrmHttpRepository
{
/// <summary>
/// Create Contact
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<string> CreateContact(ContactDto model);
/// <summary>
/// Get Contact
/// </summary>
/// <param name="companyId"></param>
/// <param name="contactId"></param>
/// <returns></returns>
Task<ContactDto> GetContact(string companyId, string contactId);
/// <summary>
/// Get Contacts
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<List<ContactDto>> GetContacts(string companyId);
/// <summary>
/// Delete Contact
/// </summary>
/// <param name="companyId"></param>
/// <param name="contactId"></param>
/// <returns></returns>
Task DeleteContact(string companyId, string contactId);
/// <summary>
/// Update Contact
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task UpdateContact(ContactDto model);
}

View file

@ -1,12 +0,0 @@
using Wonky.Entity.DTO;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmContactHttpRepository
{
Task<string> CreateContact(ContactDto model);
Task<ContactDto> GetContact(string companyId, string contactId);
Task<List<ContactDto>> GetContacts(string companyId);
Task DeleteContact(string companyId, string contactId);
Task UpdateContact(ContactDto model);
}

View file

@ -1,28 +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 Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmReportHttpRepository
{
Task<bool> ReportExist(string workDate);
Task<List<SalesReportListView>> GetReports();
Task<ReportView> GetReport(string workDate);
Task<ReportInitDto> InitializeReportData(string workDate);
Task<ApiResponseView> PostReport(string workDate, ReportDto reportDto);
}

View file

@ -1,29 +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 Wonky.Entity.DTO;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmTaskItemHttpRepository
{
Task<List<TaskItemDto>?> GetTaskList();
Task<List<TaskItemDto>?> GetTaskList(string workDate);
Task<TaskItemDto?> GetTaskItem(string taskItemId);
Task CreateTaskItem(TaskItemDto taskItem);
Task UpdateTaskItem(string taskItemId, TaskItemDto taskItem);
Task DeleteTaskItem(string taskItemId);
}

View file

@ -19,48 +19,57 @@ using Wonky.Entity.Requests;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmCompanyHttpRepository
/// <summary>
/// Interface Customer CRM Http repository
/// </summary>
public interface ICustomerCrmHttpRepository
{
/// <summary>
/// Get a list of CRM entities
/// Get a list of CRM customers (SalesRep)
/// </summary>
/// <param name="pagingParameters"></param>
/// <returns>A paged response defined by pagingParameters</returns>
Task<PagingResponse<CompanyDto>> GetCompanies(CompanyPagingParams pagingParameters);
Task<PagingResponse<CompanyDto>> GetCompanies(CustomerPaging pagingParameters);
/// <summary>
/// Get CRM entity by Id
/// Get CRM customer by Id (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <returns>A CRM Company entity</returns>
Task<CompanyDto> GetCompanyById(string companyId);
/// <summary>
/// Create new CRM entity
/// Create Customer (SalesRep)
/// </summary>
/// <param name="model"></param>
/// <returns>The Id of the entity</returns>
Task<string> CreateCompany(CompanyDto model);
/// <summary>
/// Delete the CRM entity
/// Delete the CRM customer (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <returns>true/false to define success</returns>
Task<bool> DeleteCompany(string companyId);
/// <summary>
/// Update CRM entity properties
/// Update CRM customer properties (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
/// <returns>A CRM Company entity</returns>
Task<CompanyDto> UpdateCrmData(string companyId, CompanyDto model);
/// <summary>
/// Update ERP entity properties
/// Update ERP customer properties (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
/// <returns>A CRM Company entity</returns>
Task<CompanyDto> UpdateErpData(string companyId, CompanyDto model);
/// <summary>
/// Update Entity Vat Number
/// Update customer Vat Number (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="vatNumber"></param>

View file

@ -0,0 +1,70 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface Customer History CRM Http repository
/// </summary>
public interface ICustomerHistoryCrmHttpRepository
{
/// <summary>
/// Fetch Invoice LIst
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<InvoiceListView> FetchInvoiceList(string companyId);
/// <summary>
/// Fetch given invoice for given customer
/// </summary>
/// <param name="companyId"></param>
/// <param name="invoiceId"></param>
/// <returns></returns>
Task<InvoiceView> FetchInvoice(string companyId, string invoiceId);
/// <summary>
/// Fetch inventory from given customer
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<List<ProductInventoryView>> FetchInventory(string companyId);
/// <summary>
/// Fetch History for given customer
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<List<ProductHistoryView>> FetchHistory(string companyId);
/// <summary>
/// Fetch history for given customer and a given product
/// </summary>
/// <param name="companyId"></param>
/// <param name="sku"></param>
/// <returns></returns>
Task<List<ProductHistoryView>> FetchHistory(string companyId, string sku);
/// <summary>
/// RPC call to initiate remote server sync for given customer
/// </summary>
/// <param name="companyId"></param>
/// <param name="syncDate"></param>
/// <returns></returns>
Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate);
}

View file

@ -0,0 +1,57 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Client.Features;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for Customer Office Http repository
/// </summary>
public interface ICustomerOfficeHttpRepository
{
/// <summary>
/// Get customers paged for given country
/// </summary>
/// <param name="pagingParameters"></param>
/// <param name="countryCode"></param>
/// <returns></returns>
Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CustomerPaging pagingParameters, string countryCode);
/// <summary>
/// Get customers paged for given sales rep
/// </summary>
/// <param name="salesRepId"></param>
/// <param name="pagingParameters"></param>
/// <returns></returns>
Task<PagingResponse<CompanyDto>> GetCompaniesPagedSalesRep(string salesRepId, CustomerPaging pagingParameters);
/// <summary>
/// Get customer by Id
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<CompanyDto> GetByCustomerId(string companyId);
/// <summary>
/// Update Company data
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
/// <returns></returns>
Task<bool> UpdateCompany(string companyId, CompanyDto model);
}

View file

@ -1,27 +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 Wonky.Client.Features;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.HttpInterfaces;
public interface IOfficeCustomerHttpRepository
{
Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CompanyPagingParams pagingParameters);
Task<PagingResponse<CompanyDto>> GetCompaniesPagedSalesRep(string salesRepId, CompanyPagingParams pagingParameters);
Task<CompanyDto> GetByCustomerId(string companyId);
}

View file

@ -0,0 +1,75 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface Report Http repository
/// </summary>
public interface IReportHttpRepository
{
/// <summary>
/// Report Exist for given data (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
Task<bool> ReportExist(string workDate);
/// <summary>
/// Get Reports for (SalesRep)
/// </summary>
/// <returns></returns>
Task<List<SalesReportListView>> GetReports();
/// <summary>
/// Get Report for given date (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
Task<ReportView> GetReport(string workDate);
/// <summary>
/// Initialize Report for given data (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
Task<ReportInitDto> InitializeReportData(string workDate);
/// <summary>
/// Create Report for given data - using reportData
/// </summary>
/// <param name="workDate"></param>
/// <param name="reportDto"></param>
/// <returns></returns>
Task<ApiResponseView> CreateReport(string workDate, ReportDto reportDto);
/// <summary>
/// Get Reports for given userId (Office)
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<List<SalesReportListView>> GetCountryReports(string userId);
/// <summary>
/// Get Report for given userId and workDate (Office)
/// </summary>
/// <param name="userId"></param>
/// <param name="workDate"></param>
/// <returns></returns>
Task<ReportView> GetCountryReport(string userId, string workDate);
}

View file

@ -18,12 +18,24 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmHistoryHttpRepository
/// <summary>
/// Interface for Report http repository
/// </summary>
/// <remarks>Possibly duplicated in IReportHttpRepository</remarks>
public interface IReportOfficeHttpRepository
{
Task<InvoiceListView> FetchInvoiceList(string companyId);
Task<InvoiceView> FetchInvoice(string companyId, string invoiceId);
Task<List<ProductInventoryView>> FetchInventory(string companyId);
Task<List<ProductHistoryView>> FetchHistory(string companyId);
Task<List<ProductHistoryView>> FetchHistory(string companyId, string sku);
Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate);
/// <summary>
/// Get reports for given userId
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<List<SalesReportListView>> GetReports(string userId);
/// <summary>
/// Get report for given userId and workDate
/// </summary>
/// <param name="userId"></param>
/// <param name="workDate"></param>
/// <returns></returns>
Task<ReportView> GetReport(string userId, string workDate);
}

View file

@ -3,7 +3,16 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for sending emai
/// </summary>
public interface ISendMailService
{
/// <summary>
/// Send Mail
/// </summary>
/// <param name="messageType"></param>
/// <param name="message"></param>
/// <returns></returns>
Task<ApiResponseView> SendMail(string messageType, EmailMessage message);
}

View file

@ -0,0 +1,66 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using Wonky.Entity.DTO;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for handling CRM Tasks http repository
/// </summary>
public interface ITaskItemCrmHttpRepository
{
/// <summary>
/// Get Task List (SalesRep)
/// </summary>
/// <returns></returns>
Task<List<TaskItemDto>> GetTaskList();
/// <summary>
/// Get Task List for given workDate (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
Task<List<TaskItemDto>> GetTaskList(string workDate);
/// <summary>
/// Get Task Item by id (SalesRep)
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
Task<TaskItemDto> GetTaskItem(string taskItemId);
/// <summary>
/// Create task using taskItem (SalesRep)
/// </summary>
/// <param name="taskItem"></param>
/// <returns></returns>
Task CreateTaskItem(TaskItemDto taskItem);
/// <summary>
/// Delete Task Item (SalesRep
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
Task UpdateTaskItem(string taskItemId, TaskItemDto taskItem);
/// <summary>
/// Delete Task Item (SalesRep
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
Task DeleteTaskItem(string taskItemId);
}

View file

@ -18,13 +18,59 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for User handling over http
/// </summary>
public interface IUserHttpRepository
{
/// <summary>
/// Get Advisors (Office)
/// </summary>
/// <returns></returns>
Task<List<UserListAdminView>> GetAdvisors();
/// <summary>
/// Get Advisor Info for given userId
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<WebUserInfoView> GetAdvisorInfo(string userId);
/// <summary>
/// Update Advisor using userId and updated data
/// </summary>
/// <param name="userId"></param>
/// <param name="model"></param>
/// <returns></returns>
Task UpdateAdvisor(string userId, UserUpdateDto model);
/// <summary>
/// Get Administrative Users
/// </summary>
/// <returns></returns>
Task<List<UserListAdminView>> GetAdminUsers();
/// <summary>
/// Get Admin Info for giver userId
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<UserInfoDto> GetAdminUserInfo(string userId);
/// <summary>
/// Update Admin user using userId and updated data
/// </summary>
/// <param name="userId"></param>
/// <param name="model"></param>
/// <returns></returns>
Task UpdateAdminUser(string userId, UserUpdateDto model);
/// <summary>
/// Set new user password
/// </summary>
/// <param name="userId"></param>
/// <param name="newPasswd"></param>
/// <param name="confirmPasswd"></param>
/// <returns></returns>
Task ResetUserPassword(string userId, string newPasswd, string confirmPasswd);
}

View file

@ -17,9 +17,37 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
/// <summary>
/// Interface for processing orders in warehouse
/// </summary>
public interface IWarehouseHttpRepository
{
/// <summary>
/// Get warehouse order list by date
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
Task<List<WarehouseOrderView>> GetWarehouseOrderListByDate(string date);
/// <summary>
/// Get orders by status
/// </summary>
/// <param name="status"></param>
/// <param name="express"></param>
/// <returns></returns>
Task<List<WarehouseOrderView>> GetWarehouseOrderListByStatus(string status, string express = "");
/// <summary>
/// Get order with orderId
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
Task<WarehouseOrderView> GetWarehouseOrder(string orderId);
/// <summary>
/// Update Order status setting new process status
/// </summary>
/// <param name="process"></param>
/// <returns></returns>
Task UpdateWarehouseOrderStatus(WarehouseProcess process);
}

View file

@ -18,11 +18,47 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface ICrmWorkplaceHttpRepository
/// <summary>
/// Interface for handling Customer Workplaces (chemical document service)
/// </summary>
public interface IWorkplaceCrmHttpRepository
{
/// <summary>
/// Get Workplaces for given customer id
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
Task<List<WorkplaceListView>> GetWorkplaces(string companyId);
/// <summary>
/// Get specific workplace using customer id and workplace id
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplaceId"></param>
/// <returns></returns>
Task<WorkplaceDto> GetWorkplace(string companyId, string workplaceId);
/// <summary>
/// Create new workplace given the customer id and workplace data
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplace"></param>
/// <returns></returns>
Task CreateWorkplace(string companyId, WorkplaceDto workplace);
/// <summary>
/// Update workplace given the customer id and updated data
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplace"></param>
/// <returns></returns>
Task UpdateWorkplace(string companyId, WorkplaceDto workplace);
/// <summary>
/// Delete workplace given customer id and workplace id
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplaceId"></param>
/// <returns></returns>
Task DeleteWorkplace(string companyId, string workplaceId);
}

View file

@ -25,7 +25,10 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmActivityHttpRepository : ICrmActivityHttpRepository
/// <summary>
/// Implementing Interface Activity CRM Http repository
/// </summary>
public class ActivityCrmHttpRepository : IActivityCrmHttpRepository
{
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
{
@ -33,12 +36,12 @@ public class CrmActivityHttpRepository : ICrmActivityHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CrmActivityHttpRepository> _logger;
private ILogger<ActivityCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public CrmActivityHttpRepository(HttpClient client,
ILogger<CrmActivityHttpRepository> logger,
public ActivityCrmHttpRepository(HttpClient client,
ILogger<ActivityCrmHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -48,9 +51,9 @@ public class CrmActivityHttpRepository : ICrmActivityHttpRepository
}
/// <summary>
/// Get a list of quotes
/// Get a list of open quotes
/// </summary>
/// <returns>List of activities with Quote status </returns>
/// <returns>List of Activities with ActivityStatus == Quote</returns>
public async Task<List<ReportItemView>> GetQuotes()
{
return await _client.GetFromJsonAsync<List<ReportItemView>>($"{_api.CrmActivities}/quotes", _options);
@ -63,7 +66,7 @@ public class CrmActivityHttpRepository : ICrmActivityHttpRepository
/// <returns></returns>
public async Task<ApiResponseView> UpdateQuoteStatus(ReportItemView activity)
{
var response = await _client.PutAsJsonAsync(
var response = await _client.PutAsJsonAsync(
$"{_api.CrmActivities}/quote/{activity.ActivityId}", activity, _options);
var content = await response.Content.ReadAsStringAsync();
_logger.LogDebug("UpdateQuote Response Content <= {}", content);

View file

@ -31,7 +31,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CatalogHttpRepository : ICatalogHttpRepository
public class CatalogCrmHttpRepository : ICatalogCrmHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
@ -39,12 +39,12 @@ public class CatalogHttpRepository : ICatalogHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CatalogHttpRepository> _logger;
private ILogger<CatalogCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public CatalogHttpRepository(HttpClient client,
ILogger<CatalogHttpRepository> logger,
public CatalogCrmHttpRepository(HttpClient client,
ILogger<CatalogCrmHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -91,6 +91,45 @@ public class CatalogHttpRepository : ICatalogHttpRepository
return pagingResponse;
}
/// <summary>
/// Get a paged sales item list for country
/// </summary>
/// <param name="pagingParameters"></param>
/// <param name="countryCode"></param>
/// <returns></returns>
public async Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPagingParams pagingParameters, string countryCode)
{
var queryString = new Dictionary<string, string>
{
["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(),
["orderBy"] = pagingParameters.OrderBy,
["searchColumn"] = pagingParameters.SearchColumn,
["searchTerm"] = pagingParameters.SearchTerm,
["selectGroup"] = pagingParameters.SelectGroup == "0" ? "" : pagingParameters.SelectGroup,
};
var response = await _client
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.Catalog}/{countryCode}/page", queryString));
if (!response.IsSuccessStatusCode)
{
return new PagingResponse<SalesItemView>
{
Items = new List<SalesItemView>(),
MetaData = new MetaData()
};
}
var content = await response.Content.ReadAsStringAsync();
var pagingResponse = new PagingResponse<SalesItemView>
{
Items = JsonSerializer.Deserialize<List<SalesItemView>>(content, _options),
MetaData = JsonSerializer.Deserialize<MetaData>(
response.Headers.GetValues("X-Pagination").First(), _options)
};
return pagingResponse;
}
/// <summary>
/// Get sales item by id
/// </summary>
@ -115,7 +154,7 @@ public class CatalogHttpRepository : ICatalogHttpRepository
}
/// <summary>
/// Overload Get sales item by id and country code
/// Overload Get sales item by sku and country code
/// </summary>
/// <param name="sku"></param>
/// <param name="countryCode"></param>
@ -137,9 +176,24 @@ public class CatalogHttpRepository : ICatalogHttpRepository
.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/variant/{variantId}");
return salesItem ?? new SalesItemView();
}
/// <summary>
/// Complete catalog for print
/// </summary>
/// <returns></returns>
public async Task<List<SalesItemView>> GetPriceList()
{
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_apiConfig.Catalog}", _options);
}
/// <summary>
/// Complete catalog for print country
/// </summary>
/// <param name="countryCode"></param>
/// <returns></returns>
public async Task<List<SalesItemView>> GetPriceList(string countryCode)
{
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_apiConfig.Catalog}/{countryCode}", _options);
}
}

View file

@ -8,7 +8,7 @@ using Wonky.Entity.DTO;
namespace Wonky.Client.HttpRepository;
public class CrmContactHttpRepository : ICrmContactHttpRepository
public class ContactCrmHttpRepository : IContactCrmHttpRepository
{
private readonly JsonSerializerOptions _options = new ()
{
@ -16,12 +16,12 @@ public class CrmContactHttpRepository : ICrmContactHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CrmContactHttpRepository> _logger;
private ILogger<ContactCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _conf;
public CrmContactHttpRepository(HttpClient client,
ILogger<CrmContactHttpRepository> logger,
public ContactCrmHttpRepository(HttpClient client,
ILogger<ContactCrmHttpRepository> logger,
NavigationManager navigation,
IOptions<ApiConfig> apiConfig)
{
@ -32,9 +32,10 @@ public class CrmContactHttpRepository : ICrmContactHttpRepository
}
/// <summary>
/// Create contact
/// Create Contact
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<string> CreateContact(ContactDto model)
{
var response = await _client.PostAsJsonAsync(
@ -42,13 +43,23 @@ public class CrmContactHttpRepository : ICrmContactHttpRepository
return await response.Content.ReadAsStringAsync();
}
/// <summary>
/// Get Contact
/// </summary>
/// <param name="companyId"></param>
/// <param name="contactId"></param>
/// <returns></returns>
public async Task<ContactDto> GetContact(string companyId, string contactId)
{
return await _client.GetFromJsonAsync<ContactDto>(
$"{_conf.CrmCustomers}/{companyId}/contacts/{contactId}");
}
/// <summary>
/// Get Contacts
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
public async Task<List<ContactDto>> GetContacts(string companyId)
{
var response = await _client.GetAsync(
@ -58,13 +69,23 @@ public class CrmContactHttpRepository : ICrmContactHttpRepository
? new List<ContactDto>()
: JsonSerializer.Deserialize<List<ContactDto>>(content, _options);
}
/// <summary>
/// Delete Contact
/// </summary>
/// <param name="companyId"></param>
/// <param name="contactId"></param>
/// <returns></returns>
public async Task DeleteContact(string companyId, string contactId)
{
await _client.DeleteAsync(
$"{_conf.CrmCustomers}/{companyId}/contacts/{contactId}");
}
/// <summary>
/// Update Contact
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task UpdateContact(ContactDto model)
{
await _client.PutAsJsonAsync(

View file

@ -34,7 +34,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
public class CustomerCrmCrmHttpRepository : ICustomerCrmHttpRepository
{
private readonly JsonSerializerOptions _options = new ()
{
@ -42,12 +42,12 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CrmCompanyHttpRepository> _logger;
private ILogger<CustomerCrmCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _conf;
public CrmCompanyHttpRepository(HttpClient client,
ILogger<CrmCompanyHttpRepository> logger,
public CustomerCrmCrmHttpRepository(HttpClient client,
ILogger<CustomerCrmCrmHttpRepository> logger,
NavigationManager navigation,
IOptions<ApiConfig> apiConfig)
{
@ -58,11 +58,11 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
}
/// <summary>
/// Get from crm endpoint
/// Get a list of CRM customers (SalesRep)
/// </summary>
/// <param name="pagingParameters"></param>
/// <returns>Paged response</returns>
public async Task<PagingResponse<CompanyDto>> GetCompanies(CompanyPagingParams pagingParameters)
/// <returns>A paged response defined by pagingParameters</returns>
public async Task<PagingResponse<CompanyDto>> GetCompanies(CustomerPaging pagingParameters)
{
var queryString = new Dictionary<string, string>
{
@ -93,17 +93,21 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
};
return pagingResponse;
}
/// <summary>
/// Get CRM customer by Id (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <returns>A CRM Company entity</returns>
public async Task<CompanyDto> GetCompanyById(string companyId)
{
return await _client.GetFromJsonAsync<CompanyDto>($"{_conf.CrmCustomers}/{companyId}", _options);
}
/// <summary>
/// Create company from model
/// Create Customer (SalesRep)
/// </summary>
/// <param name="model"></param>
/// <returns>company id</returns>
/// <returns>The Id of the entity</returns>
public async Task<string> CreateCompany(CompanyDto model)
{
var response = await _client.PostAsJsonAsync($"{_conf.CrmCustomers}", model, _options);
@ -113,10 +117,10 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
}
/// <summary>
/// Delete company
/// Delete the CRM customer (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
/// <returns>true/false to define success</returns>
public async Task<bool> DeleteCompany(string companyId)
{
var response = await _client.DeleteAsync($"{_conf.CrmCustomers}/{companyId}");
@ -124,11 +128,11 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
}
/// <summary>
/// Update Company CRM properties
/// Update CRM customer properties (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
/// <returns></returns>
/// <returns>A CRM Company entity</returns>
public async Task<CompanyDto> UpdateCrmData(string companyId, CompanyDto model)
{
var updateModel = new UpdateCrmDto
@ -146,11 +150,11 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
}
/// <summary>
/// Update Company ERP properties
/// Update ERP customer properties (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
/// <returns></returns>
/// <returns>A CRM Company entity</returns>
public async Task<CompanyDto> UpdateErpData(string companyId, CompanyDto model)
{
var updateModel = new UpdateErpDto
@ -172,11 +176,11 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository
}
/// <summary>
/// Update company VAT number
/// Update customer Vat Number (SalesRep)
/// </summary>
/// <param name="companyId"></param>
/// <param name="vatNumber"></param>
/// <returns></returns>
/// <returns>A CRM Company entity</returns>
public async Task<CompanyDto> UpdateCompanyVat(string companyId, string vatNumber)
{
var model = new Dictionary<string, string>

View file

@ -25,7 +25,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
public class CustomerHistoryCrmHttpRepository : ICustomerHistoryCrmHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
@ -33,12 +33,12 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CrmHistoryHttpRepository> _logger;
private ILogger<CustomerHistoryCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public CrmHistoryHttpRepository(
HttpClient client, ILogger<CrmHistoryHttpRepository> logger,
public CustomerHistoryCrmHttpRepository(
HttpClient client, ILogger<CustomerHistoryCrmHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -48,7 +48,7 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// fetch a list of invoices for CompanyId
/// Fetch Invoice LIst
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
@ -62,7 +62,7 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// Fetch invoice from archiveHeadId
/// Fetch given invoice for given customer
/// </summary>
/// <param name="companyId"></param>
/// <param name="invoiceId"></param>
@ -74,10 +74,10 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// fetch inventory - summarized list of products
/// Fetch inventory from given customer
/// </summary>
/// <param name="companyId"></param>
/// <returns>List of products</returns>
/// <returns></returns>
public async Task<List<ProductInventoryView>> FetchInventory(string companyId)
{
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmInventoryExt}");
@ -90,10 +90,10 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// Fetch history for all products
/// Fetch History for given customer
/// </summary>
/// <param name="companyId"></param>
/// <returns>List of products</returns>
/// <returns></returns>
public async Task<List<ProductHistoryView>> FetchHistory(string companyId)
{
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmProductExt}");
@ -106,11 +106,11 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// Fetch history for single product
/// Fetch history for given customer and a given product
/// </summary>
/// <param name="companyId"></param>
/// <param name="sku"></param>
/// <returns>list of products</returns>
/// <returns></returns>
public async Task<List<ProductHistoryView>> FetchHistory(string companyId, string sku)
{
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmProductExt}/{sku}");
@ -123,11 +123,11 @@ public class CrmHistoryHttpRepository : ICrmHistoryHttpRepository
}
/// <summary>
/// execute a remote procedure designed to update crm database from erp system based on a date string
/// RPC call to initiate remote server sync for given customer
/// </summary>
/// <param name="companyId"></param>
/// <param name="syncDate"></param>
/// <returns>date string</returns>
/// <returns></returns>
public async Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate)
{
var x = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}");

View file

@ -34,66 +34,36 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class OfficeCustomerHttpRepository : IOfficeCustomerHttpRepository
public class CustomerOfficeHttpRepository : ICustomerOfficeHttpRepository
{
private readonly JsonSerializerOptions _options = new ()
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<OfficeCustomerHttpRepository> _logger;
private readonly NavigationManager _navigator;
private ILogger<CustomerOfficeHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public OfficeCustomerHttpRepository(HttpClient client,
ILogger<OfficeCustomerHttpRepository> logger,
NavigationManager navigation,
public CustomerOfficeHttpRepository(HttpClient client,
ILogger<CustomerOfficeHttpRepository> logger,
NavigationManager navigator,
IOptions<ApiConfig> apiConfig)
{
_client = client;
_logger = logger;
_navigation = navigation;
_navigator = navigator;
_api = apiConfig.Value;
}
/// <summary>
/// Get paged list of customer entities by sales rep id
/// </summary>
/// <param name="salesRepId"></param>
/// <param name="pagingParameters"></param>
/// <returns></returns>
public async Task<PagingResponse<CompanyDto>> GetCompaniesPagedSalesRep(string salesRepId, CompanyPagingParams pagingParameters)
{
var queryString = new Dictionary<string, string>
{
["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = pagingParameters.SearchTerm,
["searchColumn"] = pagingParameters.SearchColumn,
["orderBy"] = pagingParameters.OrderBy,
["isHidden"] = pagingParameters.IsHidden.ToString(),
["hasFolded"] = pagingParameters.HasFolded.ToString(),
["countryCode"] = pagingParameters.CountryCode
};
var response = await _client.GetAsync(QueryHelpers.AddQueryString($"{_api.OfficeCustomers}/salesRep/{salesRepId}/", queryString));
var content = await response.Content.ReadAsStringAsync();
var pagingResponse = new PagingResponse<CompanyDto>
{
Items = JsonSerializer.Deserialize<List<CompanyDto>>(content, _options),
MetaData = JsonSerializer.Deserialize<MetaData>(response.Headers.GetValues("X-Pagination").First(), _options)
};
return pagingResponse;
}
/// <summary>
/// Get paged list of customer companies by country code
/// Get customers paged for given sales rep
/// </summary>
/// <param name="pagingParameters"></param>
/// <param name="countryCode"></param>
/// <returns></returns>
public async Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CompanyPagingParams pagingParameters)
public async Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CustomerPaging pagingParameters, string countryCode)
{
var queryString = new Dictionary<string, string>
{
@ -118,6 +88,36 @@ public class OfficeCustomerHttpRepository : IOfficeCustomerHttpRepository
return pagingResponse;
}
/// <summary>
/// Get customers paged for given sales rep
/// </summary>
/// <param name="salesRepId"></param>
/// <param name="pagingParameters"></param>
/// <returns></returns>
public async Task<PagingResponse<CompanyDto>> GetCompaniesPagedSalesRep(string salesRepId, CustomerPaging pagingParameters)
{
var queryString = new Dictionary<string, string>
{
["pageNumber"] = pagingParameters.PageNumber.ToString(),
["pageSize"] = pagingParameters.PageSize.ToString(),
["searchTerm"] = pagingParameters.SearchTerm,
["searchColumn"] = pagingParameters.SearchColumn,
["orderBy"] = pagingParameters.OrderBy,
["isHidden"] = pagingParameters.IsHidden.ToString(),
["hasFolded"] = pagingParameters.HasFolded.ToString(),
["countryCode"] = pagingParameters.CountryCode
};
var response = await _client.GetAsync(QueryHelpers.AddQueryString($"{_api.OfficeCustomers}/salesRep/{salesRepId}/", queryString));
var content = await response.Content.ReadAsStringAsync();
var pagingResponse = new PagingResponse<CompanyDto>
{
Items = JsonSerializer.Deserialize<List<CompanyDto>>(content, _options),
MetaData = JsonSerializer.Deserialize<MetaData>(response.Headers.GetValues("X-Pagination").First(), _options)
};
return pagingResponse;
}
/// <summary>
/// Get customer entity by id
/// </summary>
@ -128,22 +128,9 @@ public class OfficeCustomerHttpRepository : IOfficeCustomerHttpRepository
var company = await _client.GetFromJsonAsync<CompanyDto>($"{_api.OfficeCustomers}/id/{companyId}");
return company ?? new CompanyDto();
}
/// <summary>
/// Create company from model
/// </summary>
/// <param name="model"></param>
/// <returns>company id</returns>
public async Task<string> CreateCompany(CompanyDto model)
{
var response = await _client.PostAsJsonAsync($"{_api.OfficeCustomers}", model);
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<CompanyDto>(content, _options);
return result.CompanyId;
}
/// <summary>
/// Update company card
/// Update Company data
/// </summary>
/// <param name="companyId"></param>
/// <param name="model"></param>
@ -156,14 +143,4 @@ public class OfficeCustomerHttpRepository : IOfficeCustomerHttpRepository
return response.IsSuccessStatusCode;
}
/// <summary>
/// Delete company
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
public async Task<bool> DeleteCompany(string companyId)
{
var response = await _client.DeleteAsync($"{_api.OfficeCustomers}/{companyId}");
return response.IsSuccessStatusCode;
}
}

View file

@ -1,59 +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 System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using Wonky.Client.HttpInterfaces;
using Wonky.Entity.Configuration;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class OfficeReportHttpRepository : IOfficeReportHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<OfficeReportHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public OfficeReportHttpRepository(HttpClient client,
ILogger<OfficeReportHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
_logger = logger;
_navigation = navigation;
_apiConfig = configuration.Value;
}
public async Task<List<SalesReportListView>> GetReports(string userId)
{
return await _client.GetFromJsonAsync<List<SalesReportListView>>($"{_apiConfig.OfficeReports}/{userId}");
}
public async Task<ReportView> GetReport(string userId, string workDate)
{
return await _client.GetFromJsonAsync<ReportView>($"{_apiConfig.OfficeReports}/{userId}/{workDate}");
}
}

View file

@ -25,7 +25,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmReportHttpRepository :ICrmReportHttpRepository
public class ReportHttpRepository : IReportHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
@ -33,12 +33,12 @@ public class CrmReportHttpRepository :ICrmReportHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<CrmReportHttpRepository> _logger;
private ILogger<ReportHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public CrmReportHttpRepository(HttpClient client,
ILogger<CrmReportHttpRepository> logger,
public ReportHttpRepository(HttpClient client,
ILogger<ReportHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -47,22 +47,42 @@ public class CrmReportHttpRepository :ICrmReportHttpRepository
_apiConfig = configuration.Value;
}
public async Task<List<SalesReportListView>> GetReports()
{
return await _client.GetFromJsonAsync<List<SalesReportListView>>($"{_apiConfig.CrmReports}");
}
/// <summary>
/// Report Exist for given data (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
public async Task<bool> ReportExist(string workDate)
{
var result = await _client.GetFromJsonAsync<SalesReportClosedView>(
$"{_apiConfig.CrmReports}/exist/{workDate}");
return result.ReportClosed;
}
/// <summary>
/// Get Reports for (SalesRep)
/// </summary>
/// <returns></returns>
public async Task<List<SalesReportListView>> GetReports()
{
return await _client.GetFromJsonAsync<List<SalesReportListView>>($"{_apiConfig.CrmReports}");
}
/// <summary>
/// Get Report for given date (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
public async Task<ReportView> GetReport(string workDate)
{
return await _client.GetFromJsonAsync<ReportView>($"{_apiConfig.CrmReports}/{workDate}");
}
/// <summary>
/// Initialize Report for given data (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
public async Task<ReportInitDto> InitializeReportData(string workDate)
{
var initData = await _client
@ -70,13 +90,19 @@ public class CrmReportHttpRepository :ICrmReportHttpRepository
return initData ?? new ReportInitDto();
}
public async Task<ApiResponseView> PostReport(string workDate, ReportDto reportDto)
/// <summary>
/// Create Report for given data - using reportData
/// </summary>
/// <param name="workDate"></param>
/// <param name="reportDto"></param>
/// <returns></returns>
public async Task<ApiResponseView> CreateReport(string workDate, ReportDto reportDto)
{
var response = await _client
.PostAsJsonAsync($"{_apiConfig.CrmReports}/{workDate}", reportDto, _options);
var jsonDate = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponseView>(jsonDate);
var result = JsonSerializer.Deserialize<ApiResponseView>(jsonDate);
return new ApiResponseView
{
Code = result.Code,
@ -85,4 +111,25 @@ public class CrmReportHttpRepository :ICrmReportHttpRepository
IsSuccess = result.IsSuccess
};
}
/// <summary>
/// Get Reports for given userId (Office)
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<List<SalesReportListView>> GetCountryReports(string userId)
{
return await _client.GetFromJsonAsync<List<SalesReportListView>>($"{_apiConfig.OfficeReports}/{userId}");
}
/// <summary>
/// Get Report for given userId and workDate (Office)
/// </summary>
/// <param name="userId"></param>
/// <param name="workDate"></param>
/// <returns></returns>
public async Task<ReportView> GetCountryReport(string userId, string workDate)
{
return await _client.GetFromJsonAsync<ReportView>($"{_apiConfig.OfficeReports}/{userId}/{workDate}");
}
}

View file

@ -16,13 +16,13 @@ public class SendMailService : ISendMailService
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<SendMailService> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public SendMailService(HttpClient client, ILogger<SendMailService> logger,
public SendMailService(HttpClient client, ILogger<SendMailService> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -30,14 +30,20 @@ public class SendMailService : ISendMailService
_navigation = navigation;
_api = configuration.Value;
}
/// <summary>
/// Send Mail
/// </summary>
/// <param name="messageType"></param>
/// <param name="message"></param>
/// <returns></returns>
public async Task<ApiResponseView> SendMail(string messageType, EmailMessage message)
{
var response = await _client.PostAsJsonAsync($"{_api.ServicesMail}/{messageType}", message, _options);
if (!response.IsSuccessStatusCode)
return new ApiResponseView
{
Code = (int) response.StatusCode,
Code = (int)response.StatusCode,
Message = $"{response.ReasonPhrase}: {await response.Content.ReadAsStringAsync()}",
IsSuccess = false,
Id = ""

View file

@ -26,21 +26,21 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmTaskItemHttpRepository : ICrmTaskItemHttpRepository
public class TaskItemCrmHttpRepository : ITaskItemCrmHttpRepository
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
private readonly NavigationManager _navigation;
private ILogger<CrmTaskItemHttpRepository> _logger;
private ILogger<TaskItemCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _apiConfig;
public CrmTaskItemHttpRepository(HttpClient client,
ILogger<CrmTaskItemHttpRepository> logger,
public TaskItemCrmHttpRepository(HttpClient client,
ILogger<TaskItemCrmHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -49,32 +49,60 @@ public class CrmTaskItemHttpRepository : ICrmTaskItemHttpRepository
_apiConfig = configuration.Value;
}
/// <summary>
/// Get Task List (SalesRep)
/// </summary>
/// <returns></returns>
public async Task<List<TaskItemDto>?> GetTaskList()
{
return await _client.GetFromJsonAsync<List<TaskItemDto>>($"{_apiConfig.CrmTasks}", _options);
}
/// <summary>
/// Get Task List for given workDate (SalesRep)
/// </summary>
/// <param name="workDate"></param>
/// <returns></returns>
public async Task<List<TaskItemDto>?> GetTaskList(string workDate)
{
return await _client.GetFromJsonAsync<List<TaskItemDto>>($"{_apiConfig.CrmTasks}/date/{workDate}", _options);
}
/// <summary>
/// Get Task Item by id (SalesRep)
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
public async Task<TaskItemDto?> GetTaskItem(string taskItemId)
{
return await _client.GetFromJsonAsync<TaskItemDto>($"{_apiConfig.CrmTasks}/{taskItemId}", _options);
}
/// <summary>
/// Create task using taskItem (SalesRep)
/// </summary>
/// <param name="taskItem"></param>
/// <returns></returns>
public async Task CreateTaskItem(TaskItemDto taskItem)
{
await _client.PostAsJsonAsync($"{_apiConfig.CrmTasks}", taskItem, _options);
}
/// <summary>
/// Delete Task Item (SalesRep
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
public async Task UpdateTaskItem(string taskItemId, TaskItemDto taskItem)
{
await _client.PutAsJsonAsync($"{_apiConfig.CrmTasks}/{taskItemId}", taskItem, _options);
}
/// <summary>
/// Delete Task Item (SalesRep
/// </summary>
/// <param name="taskItemId"></param>
/// <returns></returns>
public async Task DeleteTaskItem(string taskItemId)
{
await _client.DeleteAsync($"{_apiConfig.CrmTasks}/{taskItemId}");

View file

@ -31,13 +31,13 @@ public class UserHttpRepository : IUserHttpRepository
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<UserHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public UserHttpRepository(HttpClient client, ILogger<UserHttpRepository> logger,
public UserHttpRepository(HttpClient client, ILogger<UserHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;
@ -45,40 +45,78 @@ public class UserHttpRepository : IUserHttpRepository
_navigation = navigation;
_api = configuration.Value;
}
/// <summary>
/// Get Advisors (Office)
/// </summary>
/// <returns></returns>
public async Task<List<UserListAdminView>> GetAdvisors()
{
return await _client.GetFromJsonAsync<List<UserListAdminView>>(_api.OfficeAdvisors);
}
/// <summary>
/// Get Advisor Info for given userId
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<WebUserInfoView> GetAdvisorInfo(string userId)
{
return await _client.GetFromJsonAsync<WebUserInfoView>($"{_api.OfficeAdvisors}/{userId}");
}
/// <summary>
/// Update Advisor using userId and updated data
/// </summary>
/// <param name="userId"></param>
/// <param name="model"></param>
/// <returns></returns>
public async Task UpdateAdvisor(string userId, UserUpdateDto model)
{
await _client.PutAsJsonAsync($"{_api.OfficeAdvisors}/{userId}", model, _options);
}
/// <summary>
/// Get Administrative Users
/// </summary>
/// <returns></returns>
public async Task<List<UserListAdminView>> GetAdminUsers()
{
return await _client.GetFromJsonAsync<List<UserListAdminView>>(_api.OfficeUsers);
}
/// <summary>
/// Get Admin Info for giver userId
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<UserInfoDto> GetAdminUserInfo(string userId)
{
return await _client.GetFromJsonAsync<UserInfoDto>($"{_api.OfficeUsers}/{userId}");
}
/// <summary>
/// Update Admin user using userId and updated data
/// </summary>
/// <param name="userId"></param>
/// <param name="model"></param>
/// <returns></returns>
public async Task UpdateAdminUser(string userId, UserUpdateDto model)
{
await _client.PutAsJsonAsync($"{_api.OfficeUsers}/{userId}", model, _options);
}
/// <summary>
/// Set new user password
/// </summary>
/// <param name="userId"></param>
/// <param name="newPasswd"></param>
/// <param name="confirmPasswd"></param>
/// <returns></returns>
public async Task ResetUserPassword(string userId, string newPasswd, string confirmPasswd)
{
var passwd = new Dictionary<string, string> {{"newPassword", newPasswd}, {"confirmPassword", confirmPasswd}};
var passwd = new Dictionary<string, string>
{ { "newPassword", newPasswd }, { "confirmPassword", confirmPasswd } };
await _client.PostAsJsonAsync($"{_api.OfficeUserPasswd}/{userId}", passwd, _options);
}
}

View file

@ -29,7 +29,7 @@ public class WarehouseHttpRepository : IWarehouseHttpRepository
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<WarehouseHttpRepository> _logger;
private readonly HttpClient _client;
@ -37,7 +37,7 @@ public class WarehouseHttpRepository : IWarehouseHttpRepository
public WarehouseHttpRepository(HttpClient client,
ILogger<WarehouseHttpRepository> logger,
NavigationManager navigation,
NavigationManager navigation,
IOptions<ApiConfig> configuration)
{
_client = client;
@ -46,20 +46,43 @@ public class WarehouseHttpRepository : IWarehouseHttpRepository
_api = configuration.Value;
}
/// <summary>
/// Get warehouse order list by date
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public async Task<List<WarehouseOrderView>> GetWarehouseOrderListByDate(string date)
{
return await _client.GetFromJsonAsync<List<WarehouseOrderView>>($"{_api.Warehouse}?date={date}", _options);
}
/// <summary>
/// Get orders by status
/// </summary>
/// <param name="status"></param>
/// <param name="express"></param>
/// <returns></returns>
public async Task<List<WarehouseOrderView>> GetWarehouseOrderListByStatus(string status, string express = "")
{
return await _client.GetFromJsonAsync<List<WarehouseOrderView>>($"{_api.Warehouse}?status={status}&express={express}", _options);
return await _client.GetFromJsonAsync<List<WarehouseOrderView>>(
$"{_api.Warehouse}?status={status}&express={express}", _options);
}
/// <summary>
/// Get order with orderId
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
public async Task<WarehouseOrderView> GetWarehouseOrder(string orderId)
{
return await _client.GetFromJsonAsync<WarehouseOrderView>($"{_api.Warehouse}/{orderId}", _options);
}
/// <summary>
/// Update Order status setting new process status
/// </summary>
/// <param name="process"></param>
/// <returns></returns>
public async Task UpdateWarehouseOrderStatus(WarehouseProcess process)
{
_logger.LogDebug("process => {}", JsonSerializer.Serialize(process, _options));

View file

@ -24,21 +24,21 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class CrmWorkplaceHttpRepository : ICrmWorkplaceHttpRepository
public class WorkplaceCrmHttpRepository : IWorkplaceCrmHttpRepository
{
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
private readonly NavigationManager _navigation;
private ILogger<CrmWorkplaceHttpRepository> _logger;
private ILogger<WorkplaceCrmHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public CrmWorkplaceHttpRepository(HttpClient client,
ILogger<CrmWorkplaceHttpRepository> logger,
NavigationManager navigation,
public WorkplaceCrmHttpRepository(HttpClient client,
ILogger<WorkplaceCrmHttpRepository> logger,
NavigationManager navigation,
IOptions<ApiConfig> configuration)
{
_client = client;
@ -46,7 +46,12 @@ public class CrmWorkplaceHttpRepository : ICrmWorkplaceHttpRepository
_navigation = navigation;
_api = configuration.Value;
}
/// <summary>
/// Get Workplaces for given customer id
/// </summary>
/// <param name="companyId"></param>
/// <returns></returns>
public async Task<List<WorkplaceListView>> GetWorkplaces(string companyId)
{
var result = await _client.GetFromJsonAsync<List<WorkplaceListView>>(
@ -54,6 +59,12 @@ public class CrmWorkplaceHttpRepository : ICrmWorkplaceHttpRepository
return result ?? new List<WorkplaceListView>();
}
/// <summary>
/// Get specific workplace using customer id and workplace id
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplaceId"></param>
/// <returns></returns>
public async Task<WorkplaceDto> GetWorkplace(string companyId, string workplaceId)
{
var result = await _client.GetFromJsonAsync<WorkplaceDto>(
@ -61,18 +72,36 @@ public class CrmWorkplaceHttpRepository : ICrmWorkplaceHttpRepository
return result ?? new WorkplaceDto();
}
/// <summary>
/// Create new workplace given the customer id and workplace data
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplace"></param>
/// <returns></returns>
public async Task CreateWorkplace(string companyId, WorkplaceDto workplace)
{
await _client.PostAsJsonAsync(
$"{_api.CrmCustomers}/{companyId}/{_api.CrmWorkplaceExt}", workplace, _options);
}
/// <summary>
/// Update workplace given the customer id and updated data
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplace"></param>
/// <returns></returns>
public async Task UpdateWorkplace(string companyId, WorkplaceDto workplace)
{
await _client.PutAsJsonAsync(
$"{_api.CrmCustomers}/{companyId}/{_api.CrmWorkplaceExt}/{workplace.WorkplaceId}", workplace, _options);
}
/// <summary>
/// Delete workplace given customer id and workplace id
/// </summary>
/// <param name="companyId"></param>
/// <param name="workplaceId"></param>
/// <returns></returns>
public async Task DeleteWorkplace(string companyId, string workplaceId)
{
await _client.DeleteAsync(

View file

@ -43,11 +43,11 @@ public partial class ActivityCreateCrmPage : IDisposable
[Inject] public IToastService Toast { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogHttpRepository Catalog { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICrmActivityHttpRepository ActivityRepo { get; set; }
[Inject] public ICrmReportHttpRepository ReportRepo { get; set; }
[Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; }
[Inject] public ICatalogCrmHttpRepository CatalogCrm { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository HistoryRepo { get; set; }
// variables
private readonly JsonSerializerOptions? _options = new() {PropertyNameCaseInsensitive = true};
private SalesItemView SelectedItem { get; set; } = new();
@ -258,7 +258,7 @@ public partial class ActivityCreateCrmPage : IDisposable
// get selected item
if (string.IsNullOrWhiteSpace(sku.ItemId))
return;
SelectedItem = await Catalog.GetSalesItemId(sku.ItemId);
SelectedItem = await CatalogCrm.GetSalesItemId(sku.ItemId);
ShowItem = true;
Price = sku.Rate;
Quantity = sku.Quantity;

View file

@ -29,8 +29,8 @@ public partial class ActivityListCustomerPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
private List<ReportItemView> Activities { get; set; } = new();
private CompanyDto Company { get; set; } = new();
private bool Working { get; set; } = true;
@ -48,7 +48,7 @@ public partial class ActivityListCustomerPage : IDisposable
private async Task GetActivities()
{
Working = true;
Activities = await CrmActivityRepo.GetCustomerActivities(CompanyId);
Activities = await ActivityRepo.GetCustomerActivities(CompanyId);
if(Activities.Any())
Activities = Activities.OrderByDescending(x => x.OrderDate).ToList();
Working = false;

View file

@ -31,8 +31,8 @@ public partial class ActivityListTodayCrmPage : IDisposable
[Inject] public ILogger<ActivityListTodayCrmPage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ICrmReportHttpRepository CrmReportRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public IToastService Toaster { get; set; }
private ReportStatusView? ReportStatusView { get; set; } = new();
private UserPref UserPref { get; set; } = new();
@ -46,7 +46,7 @@ public partial class ActivityListTodayCrmPage : IDisposable
Interceptor.RegisterBeforeSendEvent();
UserPref = await UserProfileService.GetPreferences();
SelectedDate = string.IsNullOrWhiteSpace(UserPref.WorkDate) ? DateTime.Now : DateTime.Parse(UserPref.WorkDate);
ReportExist = await CrmReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
ReportExist = await ReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
await GetActivities($"{SelectedDate:yyyy-MM-dd}");
Working = false;
}
@ -57,8 +57,8 @@ public partial class ActivityListTodayCrmPage : IDisposable
Toaster.ShowInfo("Vent nogle sekunder for data", "HENTER DATA");
SelectedDate = DateTime.Parse(workDate);
ReportStatusView = new ReportStatusView();
ReportExist = await CrmReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
ReportStatusView = await CrmActivityRepo.GetActivities($"{SelectedDate:yyyy-MM-dd}");
ReportExist = await ReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
ReportStatusView = await ActivityRepo.GetActivities($"{SelectedDate:yyyy-MM-dd}");
Logger.LogDebug("Activities => {}", JsonSerializer.Serialize(ReportStatusView));
Working = false;
Toaster.ClearAll();

View file

@ -34,7 +34,7 @@ public partial class ActivityViewCrmPage : IDisposable
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string OrderId { get; set; } = "";
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICrmActivityHttpRepository ActivityRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public ILogger<ActivityViewCrmPage> Logger { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public NavigationManager Navigator { get; set; }

View file

@ -0,0 +1,53 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@page "/price-catalog/{CountryCode}"
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
<div class="sticky-top bg-dark rounded-2 px-3">
<div class="row g-3 mb-3">
<div class="col-sm-2">
<CatalogGroupComponent OnChanged="SetGroupCol"/>
</div>
<div class="col-sm-2">
<CatalogSearchComponent OnChanged="SetSearchCol"/>
</div>
<div class="col-sm-4">
<CatalogSearchPhraseComponent OnChanged="SetSearchPhrase"/>
</div>
<div class="col-sm-2">
<CatalogSortComponent OnChanged="SetSortCol"/>
</div>
<div class="col-sm-2">
<PageSizeComponent OnChanged="SetPageSize"/>
</div>
<div class="col-sm-10">
<PaginationComponent MetaData="MetaInfo" Spread="2" SelectedPage="SetSelectedPage"/>
</div>
<div class="col-sm-2 text-end">
<a class="btn btn-secondary" href="/print/catalog"><i class="bi-printer"></i> Udskriv</a>
</div>
</div>
</div>
<CatalogTableComponent ItemList="Items"/>
@if (Working)
{
<WorkingThreeDots />
}

View file

@ -0,0 +1,121 @@
// 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 System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Blazored.LocalStorage;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Client.Components;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CatalogCountryPage : IDisposable
{
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogCrmHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserProfileService ProfileService { 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 OnParametersSetAsync()
{
Prefs = await ProfileService.GetPreferences();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
PageParams.CountryCode = UserInfo.CountryCode;
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>();
PageParams.PageNumber = 1;
PageParams.SearchTerm = searchTerm;
await FetchSalesItems();
}
private async Task SetPageSize(string pageSize)
{
Items = new List<SalesItemView>();
PageParams.PageSize = Convert.ToInt32(pageSize);
PageParams.PageNumber = 1;
await FetchSalesItems();
}
private async Task SetSearchCol(string columnName)
{
Items = new List<SalesItemView>();
PageParams.PageNumber = 1;
PageParams.SearchColumn = columnName;
await FetchSalesItems();
}
private async Task SetSortCol(string orderBy)
{
Items = new List<SalesItemView>();
PageParams.OrderBy = orderBy;
await FetchSalesItems();
}
private async Task SetSelectedPage(int page)
{
Items = new List<SalesItemView>();
PageParams.PageNumber = page;
await FetchSalesItems();
}
private async Task SetGroupCol(string groupFilter)
{
Items = new List<SalesItemView>();
PageParams.PageNumber = 1;
PageParams.SelectGroup = groupFilter;
await FetchSalesItems();
}
private async Task FetchSalesItems()
{
Working = true;
var pagingResponse = await ItemRepo.GetSalesItemsPaged(PageParams, CountryCode);
Working = false;
Items = pagingResponse.Items!;
MetaInfo = pagingResponse.MetaData;
}
public void Dispose() => Interceptor.DisposeEvent();
}

View file

@ -29,10 +29,10 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CatalogPage : IDisposable
public partial class CatalogCrmPage : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogHttpRepository ItemRepo { get; set; }
[Inject] public ICatalogCrmHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }
private List<SalesItemView> Items { get; set; } = new();

View file

@ -43,7 +43,7 @@ namespace Wonky.Client.Pages
[Inject] public ILogger<CustomerCreateCrmPage> Logger { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public VatInfoLookupService VatService { get; set; }
private EditContext CompanyContext { get; set; }

View file

@ -14,9 +14,9 @@ namespace Wonky.Client.Pages;
public partial class CustomerInvoiceListCrmPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository HistoryRepo { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ILogger<CustomerInvoiceListCrmPage> Logger { get; set; }

View file

@ -0,0 +1,59 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@page "/office/{countryCode}/customers"
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Office")]
<div class="sticky-top bg-dark text-light rounded-2 px-3">
<div class="row g-3">
<div class="col-sm-2">
<CompanySearchColumnComponent OnChanged="SetSearchCol" />
</div>
<div class="col-sm-6">
<CompanySearchPhraseComponent OnChanged="SetSearchPhrase" />
</div>
<div class="col-sm-2">
<CompanySortComponent OnChanged="SetSortCol" />
</div>
<div class="col-sm-2">
<PageSizeComponent OnChanged="SetPageSize" />
</div>
<div class="col-sm-2">
<div class="form-check">
<input type="checkbox" id="folded" class="form-check-input" checked="@IncludeFolded" @onclick="OnFoldedClick" >
<label for="folded" class="form-check-label">Ophørte</label>
</div>
</div>
<div class="col-sm-8">
<PaginationComponent MetaData="PageData" Spread="2" SelectedPage="SelectedPage"/>
</div>
<div class="col-sm-2 text-end">
<a class="btn btn-success text-nowrap" href="/companies/new">Opret kunde <i class="bi-plus"></i></a>
</div>
</div>
</div>
<AdvisorCompanyTableComponent CompanyList="Companies" OnDelete="DeleteCompany" />
@if (Working)
{
<WorkingThreeDots />
}

View file

@ -0,0 +1,151 @@
// 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 System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Blazored.LocalStorage;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages
{
public partial class CustomerListCountryPage : IDisposable
{
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
private List<CompanyDto> Companies { get; set; } = 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 CustomerPaging Paging { get; set; } = new();
protected override async Task OnParametersSetAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// set preferences
Prefs = await ProfileService.GetPreferences();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
Paging.OrderBy = Prefs.CompanySort;
Paging.SearchColumn = Prefs.CompanySearch;
Paging.PageSize = Convert.ToInt32(Prefs.PageSize);
Paging.HasFolded = IncludeFolded ? 1 : 0;
Paging.CountryCode = UserInfo.CountryCode;
// load saved search
SavedSearch = string.IsNullOrWhiteSpace(Prefs.CompanyFilterPhrase) ? "" : Prefs.CompanyFilterPhrase;
Paging.SearchTerm = SavedSearch;
// get companies
await FetchCustomers();
Working = false;
}
private async Task OnFoldedClick()
{
IncludeFolded = !IncludeFolded;
Companies = new List<CompanyDto>();
Paging.PageNumber = 1;
Paging.HasFolded = IncludeFolded ? 1 : 0;
await FetchCustomers();
}
private async Task SelectedPage(int page)
{
Companies = new List<CompanyDto>();
Paging.PageNumber = page;
await FetchCustomers();
}
private async Task SetSearchCol(string searchColumn)
{
Companies = new List<CompanyDto>();
Paging.SearchColumn = searchColumn;
Paging.PageNumber = 1;
await FetchCustomers();
}
private async Task SetPageSize(string pageSize)
{
Companies = new List<CompanyDto>();
Paging.PageSize = Convert.ToInt32(pageSize);
Paging.PageNumber = 1;
await FetchCustomers();
}
private async Task SetSearchPhrase(string searchTerm)
{
Companies = new List<CompanyDto>();
Paging.PageNumber = 1;
Paging.SearchTerm = searchTerm;
await FetchCustomers();
}
private async Task SetSortCol(string orderBy)
{
Companies = new List<CompanyDto>();
Paging.OrderBy = orderBy;
await FetchCustomers();
}
/// <summary>
/// Removes a company from CRM
/// </summary>
/// <param name="companyId"></param>
private async Task DeleteCompany(string companyId)
{
Companies = new List<CompanyDto>();
await CompanyRepo.DeleteCompany(companyId);
if (Paging.PageNumber > 1 && Companies.Count == 1)
Paging.PageNumber--;
await FetchCustomers();
}
private async Task FetchCustomers()
{
Working = true;
var pageRes = await CompanyRepo.GetCompanies(Paging);
Working = false;
if (pageRes.Items.Any())
{
Companies = pageRes.Items;
PageData = pageRes.MetaData;
}
else
{
Companies = new List<CompanyDto>();
PageData = new MetaData();
}
}
public void Dispose() => Interceptor.DisposeEvent();
}
}

View file

@ -32,7 +32,7 @@ namespace Wonky.Client.Pages
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
private List<CompanyDto> Companies { get; set; } = new();
@ -42,7 +42,7 @@ namespace Wonky.Client.Pages
private bool IncludeFolded { get; set; }
private bool Working { get; set; } = true;
private MetaData PageData { get; set; } = new();
private CompanyPagingParams PageParams { get; set; } = new();
private CustomerPaging Paging { get; set; } = new();
protected override void OnParametersSet()
{
@ -56,15 +56,15 @@ namespace Wonky.Client.Pages
// set preferences
Prefs = await ProfileService.GetPreferences();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
PageParams.OrderBy = Prefs.CompanySort;
PageParams.SearchColumn = Prefs.CompanySearch;
PageParams.PageSize = Convert.ToInt32(Prefs.PageSize);
PageParams.HasFolded = IncludeFolded ? 1 : 0;
PageParams.CountryCode = UserInfo.CountryCode;
Paging.OrderBy = Prefs.CompanySort;
Paging.SearchColumn = Prefs.CompanySearch;
Paging.PageSize = Convert.ToInt32(Prefs.PageSize);
Paging.HasFolded = IncludeFolded ? 1 : 0;
Paging.CountryCode = UserInfo.CountryCode;
// load saved search
SavedSearch = string.IsNullOrWhiteSpace(Prefs.CompanyFilterPhrase) ? "" : Prefs.CompanyFilterPhrase;
PageParams.SearchTerm = SavedSearch;
Paging.SearchTerm = SavedSearch;
// get companies
await FetchCompanies();
@ -75,45 +75,45 @@ namespace Wonky.Client.Pages
{
IncludeFolded = !IncludeFolded;
Companies = new List<CompanyDto>();
PageParams.PageNumber = 1;
PageParams.HasFolded = IncludeFolded ? 1 : 0;
Paging.PageNumber = 1;
Paging.HasFolded = IncludeFolded ? 1 : 0;
await FetchCompanies();
}
private async Task SelectedPage(int page)
{
Companies = new List<CompanyDto>();
PageParams.PageNumber = page;
Paging.PageNumber = page;
await FetchCompanies();
}
private async Task SetSearchCol(string searchColumn)
{
Companies = new List<CompanyDto>();
PageParams.SearchColumn = searchColumn;
PageParams.PageNumber = 1;
Paging.SearchColumn = searchColumn;
Paging.PageNumber = 1;
await FetchCompanies();
}
private async Task SetPageSize(string pageSize)
{
Companies = new List<CompanyDto>();
PageParams.PageSize = Convert.ToInt32(pageSize);
PageParams.PageNumber = 1;
Paging.PageSize = Convert.ToInt32(pageSize);
Paging.PageNumber = 1;
await FetchCompanies();
}
private async Task SetSearchPhrase(string searchTerm)
{
Companies = new List<CompanyDto>();
PageParams.PageNumber = 1;
PageParams.SearchTerm = searchTerm;
Paging.PageNumber = 1;
Paging.SearchTerm = searchTerm;
await FetchCompanies();
}
private async Task SetSortCol(string orderBy)
{
Companies = new List<CompanyDto>();
PageParams.OrderBy = orderBy;
Paging.OrderBy = orderBy;
await FetchCompanies();
}
@ -125,15 +125,15 @@ namespace Wonky.Client.Pages
{
Companies = new List<CompanyDto>();
await CompanyRepo.DeleteCompany(companyId);
if (PageParams.PageNumber > 1 && Companies.Count == 1)
PageParams.PageNumber--;
if (Paging.PageNumber > 1 && Companies.Count == 1)
Paging.PageNumber--;
await FetchCompanies();
}
private async Task FetchCompanies()
{
Working = true;
var pageRes = await CompanyRepo.GetCompanies(PageParams);
var pageRes = await CompanyRepo.GetCompanies(Paging);
Working = false;
if (pageRes.Items.Any())
{

View file

@ -1,61 +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 Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/companies/{CountryCode}"
<div class="sticky-top bg-dark text-light rounded-2 px-3">
<div class="container-fluid pt-3">
<div class="row mb-2">
<div class="col-md-3">
<CompanySearchColumnComponent OnChanged="SetSearchCol" />
</div>
<div class="col-md-3">
<CompanySearchPhraseComponent OnChanged="SetSearchPhrase" />
</div>
<div class="col-md-3">
<CompanySortComponent OnChanged="SetSortCol" />
</div>
<div class="col-md-3">
<PageSizeComponent OnChanged="SetPageSize" />
</div>
</div>
<div class="row mb-2">
<div class="col-3">
<div class="form-check">
<input type="checkbox" id="folded" class="form-check-input" checked="@_includeFolded" @onclick="OnFoldedClick" >
<label for="folded" class="form-check-label">Ophørte</label>
</div>
</div>
<div class="col-6">
<PaginationComponent MetaData="_metaData" Spread="2" SelectedPage="SelectedPage"/>
</div>
<div class="col-3 justify-content-end">
<a class="btn btn-success text-nowrap" href="/companies/new">Opret kunde</a>
</div>
</div>
</div>
</div>
<AdvisorCompanyTableComponent CompanyList="_companyList" />
@if (Working)
{
<WorkingThreeDots/>
}

View file

@ -1,131 +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.Components;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
namespace Wonky.Client.Pages;
public partial class CustomerListOfficePage : IDisposable
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "dk";
[Inject] public ILogger<CustomerListOfficePage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IOfficeCustomerHttpRepository CustomerRepo { get; set; }
[Inject] public UserProfileService UserProfileService { get; set; }
private List<CompanyDto> _companyList { get; set; } = new();
private MetaData _metaData { get; set; } = new();
private CompanyPagingParams _paging = new();
private UserPref UserPref { get; set; } = new();
private string _savedSearch { get; set; } = "";
private bool _includeFolded { get; set; }
private bool Working { get; set; } = true;
protected override async Task OnParametersSetAsync()
{
Interceptor.DisposeEvent();
Interceptor.RegisterBeforeSendEvent();
// set preferences
UserPref = await UserProfileService.GetPreferences();
_paging.CountryCode = CountryCode;
_paging.OrderBy = UserPref.CompanySort;
_paging.SearchColumn = UserPref.CompanySearch;
_paging.PageSize = Convert.ToInt32(UserPref.PageSize);
_paging.HasFolded = _includeFolded ? 1 : 0;
// load saved search
_savedSearch = UserPref.CompanyFilterPhrase;
_paging.SearchTerm = _savedSearch;
await FetchCompanies();
Working = false;
}
private async Task OnFoldedClick()
{
_includeFolded = !_includeFolded;
_companyList = new List<CompanyDto>();
_paging.PageNumber = 1;
_paging.HasFolded = _includeFolded ? 1 : 0;
await FetchCompanies();
}
private async Task SelectedPage(int page)
{
_companyList = new List<CompanyDto>();
_paging.PageNumber = page;
await FetchCompanies();
}
private async Task SetSearchCol(string searchColumn)
{
_companyList = new List<CompanyDto>();
_paging.SearchColumn = searchColumn;
_paging.PageNumber = 1;
await FetchCompanies();
}
private async Task SetPageSize(string pageSize)
{
_companyList = new List<CompanyDto>();
_paging.PageSize = Convert.ToInt32(pageSize);
_paging.PageNumber = 1;
await FetchCompanies();
}
private async Task SetSearchPhrase(string searchTerm)
{
// if (!string.IsNullOrWhiteSpace(searchTerm) && searchTerm.Length < 3) return;
_companyList = new List<CompanyDto>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
await FetchCompanies();
if (!string.IsNullOrWhiteSpace(searchTerm) && searchTerm.TrimEnd().Length > 2)
{
_savedSearch = searchTerm;
await UserProfileService.SetCompanyFilterPhrase(searchTerm.Trim());
}
}
private async Task SetSortCol(string orderBy)
{
_companyList = new List<CompanyDto>();
_paging.OrderBy = orderBy;
await FetchCompanies();
}
private async Task FetchCompanies()
{
Working = true;
var pagingResponse = await CustomerRepo.GetCompaniesPagedSalesRep(UserId, _paging);
_companyList = pagingResponse.Items;
_metaData = pagingResponse.MetaData;
Working = false;
}
public void Dispose()
{
Interceptor.DisposeEvent();
}
}

View file

@ -30,8 +30,8 @@ namespace Wonky.Client.Pages;
public partial class CustomerProductListCrmPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository HistoryRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ILogger<CustomerProductListCrmPage> Logger { get; set; }

View file

@ -37,9 +37,9 @@ public partial class CustomerViewCrmPage : IDisposable
[Inject] public IToastService Toaster { get; set; }
[Inject] public ILogger<CustomerViewCrmPage> Logger { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
[Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; }
[Inject] public ICrmContactHttpRepository ContactRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository CompanyRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository HistoryRepo { get; set; }
[Inject] public IContactCrmHttpRepository ContactRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public VatInfoLookupService VatService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }

View file

@ -28,7 +28,7 @@ public partial class KrvItemViewAdminPage : IDisposable
{
[Parameter] public string SalesItemId { get; set; } = "";
private SalesItemView _item { get; set; } = new ();
[Inject] public ICatalogHttpRepository _itemRepo { get; set; }
[Inject] public ICatalogCrmHttpRepository _itemRepo { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }

View file

@ -1,3 +1,4 @@
@*
// 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
@ -12,14 +13,18 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin")]
@page "/office/{CountryCode}"
using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface IOfficeReportHttpRepository
{
Task<List<SalesReportListView>> GetReports(string userId);
Task<ReportView> GetReport(string userId, string workDate);
@code {
[Parameter]
public string CountryCode { get; set; } = "";
}

View file

@ -17,19 +17,12 @@
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin")]
@page "/office/users/office"
@page "/office/{countryCode}/salesreps"
<div class="card">
<div class="card-header bg-dark text-white">
<div class="card-title">
<h3>Administrative brugere</h3>
</div>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
<a class="list-group-item list-group-item-action" href="/office/users/office/dk">Danmark</a>
</div>
</div>
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm-4"></div>
<div class="col-sm-4"></div>
</div>
@code {

View file

@ -1,198 +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 = "Admin,Office,Warehouse")]
@page "/office/customers/{CompanyId}/orders/new"
<EditForm EditContext="_editContext">
<DataAnnotationsValidator/>
<div class="row mb-1">
<label for="name" class="col-md-1 col-form-label">Navn</label>
<div class="col-md-5">
<InputText id="name" class="form-control" @bind-Value="_activity.Name" readonly/>
</div>
<label for="account" class="col-md-1 col-form-label">Konto</label>
<div class="col-md-2">
<InputText id="account" class="form-control" @bind-Value="_activity.Account" readonly/>
</div>
<label for="phone" class="col-md-1 col-form-label">Tlf</label>
<div class="col-md-2">
<InputText id="phone" class="form-control" @bind-Value="_activity.Phone"/>
</div>
</div>
<div class="row mb-1">
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
<div class="col-md-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="_activity.ReferenceNumber"/>
<ValidationMessage For="@(() => _activity.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
<div class="col-md-4">
<InputText id="yourRef" class="form-control" @bind-Value="_activity.YourRef"/>
<ValidationMessage For="@(() => _activity.YourRef)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="orderMessage" class="col-md-2 col-form-label">Ordre notat</label>
<div class="col-md-10">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_activity.OrderMessage"/>
<ValidationMessage For="@(() => _activity.OrderMessage)"></ValidationMessage>
</div>
</div>
<div class="row">
<div class="col">
<table class="sticky-top table table-hover table-striped table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftStateProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
<button type="button" class="btn btn-danger btn-sm" @onclick="@DeleteDraft" disabled="@(DraftStateProvider.Draft.Items.Count == 0)">Slet kladde</button>
</th>
</tr>
<tr class="bg-dark opacity-75 text-white">
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col" class="text-end">Antal</th>
<th scope="col" class="text-end">Enhedspris</th>
<th scope="col" class="text-end">Linjesum</th>
<th scope="col" class="text-end">SAS</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@if (DraftStateProvider != null && DraftStateProvider.Draft.Items.Count > 0)
{
@foreach (var cartItem in DraftStateProvider.Draft.Items)
{
<tr>
<td class="align-middle">@cartItem.Item.Name</td>
<td class="align-middle">@cartItem.Item.Sku</td>
<td class="align-middle text-end">@cartItem.Quantity</td>
<td class="align-middle text-end">@cartItem.Price</td>
<td class="align-middle text-end">@cartItem.LineTotal</td>
<td class="align-middle text-center">
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="align-middle text-end">
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))">Slet Linje</button>
</td>
</tr>
}
}
<tr>
<td colspan="3"></td>
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
<td></td>
<td class="align-middle text-end">
<button class="btn btn-primary" type="button" @onclick="CallPriceListModal">
<i class="oi oi-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col">
@* draft line *@
@if (_selectedItem != null && ShowItem)
{
<table id="draft-line" class="table table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">Kladdelinje</th>
</tr>
<tr>
<th scope="col">Antal</th>
<th scope="col">Pris</th>
<th scope="col">Rabat</th>
<th class="align-content-center justify-content-center" scope="col">SAS</th>
<th scope="col">Varenr.</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Quantity"/>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Price"/>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Discount"/>
</td>
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
</td>
<td class="align-middle">@_selectedItem.Sku</td>
<td class="align-middle">
<button type="button" class="btn btn-warning text-nowrap d-block" @onclick="@(() => AddItem(_selectedItem))">bestil @Quantity stk @_selectedItem.Name</button>
</td>
</tr>
</tbody>
</table>
}
</div>
</div>
<div id="dlvAddress">
<div class="row mb-1">
<div class="col-md-4">
<InputText id="dlvName" class="form-control" @bind-Value="_activity.DlvName"/>
</div>
<div class="col-md-4">
<InputText id="dlvAddress1" class="form-control" @bind-Value="_activity.DlvAddress1"/>
</div>
<div class="col-md-4">
<InputText id="dlvAddress2" class="form-control" @bind-Value="_activity.DlvAddress2"/>
</div>
</div>
<div class="row mb-1">
<div class="col-md-4">
<InputText id="dlvZipCode" class="form-control" @bind-Value="_activity.DlvZipCode"/>
</div>
<div class="col-md-4">
<InputText id="dlvCity" class="form-control" @bind-Value="_activity.DlvCity"/>
</div>
</div>
</div>
</EditForm>
<div class="card-footer">
<div class="row mt-2 mb-2">
<div class="col text-end">
<button type="button" class="btn btn-primary" @onclick="CreateOrder" disabled="@FormInvalid">Opret ordre</button>
</div>
</div>
</div>
@if (Working)
{
<WorkingThreeDots/>
}

View file

@ -1,196 +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 System.Globalization;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Client.Shared;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class OrderCreateOfficePage : IDisposable
{
[CascadingParameter] DraftStateProvider DraftStateProvider { get; set; }
[Parameter] public string CompanyId { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IOfficeCustomerHttpRepository OfficeCustomerRepo { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
[Inject] public ICatalogHttpRepository CatalogRepo { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ILogger<OrderCreateOfficePage> Logger { get; set; }
private ActivityDto _activity { get; set; } = new();
private EditContext _editContext { get; set; }
private PriceListModal _priceList { get; set; } = new();
private CompanyDto _company { get; set; } = new();
private WebUserInfoView _userInfo { get; set; } = new();
private SalesItemView _selectedItem { get; set; } = new();
private string Rate { get; set; } = "0";
private string Quantity { get; set; } = "1";
private string Price { get; set; } = "0";
private string Discount { get; set; } = "0";
private bool ShowItem { get; set; }
private bool Sas { get; set; }
private bool FormInvalid { get; set; } = true;
private bool HideButton { get; set; }
private bool Working { get; set; } = true;
protected override async Task OnParametersSetAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
_company = await OfficeCustomerRepo.GetByCustomerId(CompanyId);
}
protected override async Task OnInitializedAsync()
{
_editContext = new EditContext(_activity);
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged;
_userInfo = await UserRepo.GetAdvisorInfo(_company.SalesRepId);
_activity.ActivityDate = $"{DateTime.Now:yyyy-MM-dd}" ;
// variable to validate if customer needs phone number update
// _phone = _company.Phone;
if (string.IsNullOrWhiteSpace(_company.Phone)
&& !string.IsNullOrWhiteSpace(_company.Account)
&& _company.Account != "NY" && _company.Account.Length > 7)
{
_company.Phone = _company.Account[..8];
}
_activity.ActivityStatusEnum = "order";
_activity.ActivityTypeEnum = "phone";
// set up identification
_activity.CompanyId = _company.CompanyId;
_activity.BcId = _company.BcId;
_activity.SalesRepId = _company.SalesRepId;
_activity.SalesRep = _company.SalesRep;
_activity.Account = _company.Account;
_activity.VatNumber = _company.VatNumber;
_activity.Email = _company.Email;
_activity.Phone = _company.Phone;
_activity.Mobile = _company.Mobile;
_activity.Name = _company.Name;
_activity.Address1 = _company.Address1;
_activity.Address2 = _company.Address2;
_activity.ZipCode = _company.ZipCode;
_activity.City = _company.City;
_activity.DlvName = _company.Name;
_activity.DlvAddress1 = _company.Address1;
_activity.DlvAddress2 = _company.Address2;
_activity.DlvZipCode = _company.ZipCode;
_activity.DlvCity = _company.City;
Working = false;
}
private void CallPriceListModal()
{
_priceList.Show();
}
private async Task SelectSku(SelectedSku sku)
{
ShowItem = true;
_selectedItem = await CatalogRepo.GetSalesVariantId(sku.ItemId);
Price = sku.Rate;
Quantity = sku.Quantity;
}
private async Task DeleteDraft()
{
await DraftStateProvider.DeleteDraftAsync();
}
private async Task CreateOrder()
{
Working = true;
await CrmActivityRepo.CreateActivity(_activity);
Working = false;
}
private async Task AddItem(SalesItemView salesItem)
{
ShowItem = false;
// create a new cart item
var item = new DraftItem
{
Item = salesItem,
Quantity = Convert.ToInt32(Quantity),
Price = Convert.ToDecimal(Price, CultureInfo.InvariantCulture),
Discount = Convert.ToDecimal(Discount, CultureInfo.InvariantCulture),
Sas = Sas
};
// reset internals to initial state
Sas = false;
Quantity = "1";
Price = "0";
Discount = "0";
// add it to the cart
DraftStateProvider.Draft.Items.Add(item);
// save the item using the CartStateProvider's save method
await DraftStateProvider.SaveChangesAsync();
}
private async Task RemoveItem(DraftItem item)
{
// remove item
DraftStateProvider.Draft.Items.Remove(item);
// save the remaining draft
await DraftStateProvider.SaveChangesAsync();
}
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
if (DraftStateProvider.Draft.Items.Count == 0)
{
FormInvalid = true;
return;
}
FormInvalid = !_editContext.Validate();
StateHasChanged();
}
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
FormInvalid = false;
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
_editContext = new EditContext(_activity);
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged;
}
public void Dispose()
{
Interceptor.DisposeEvent();
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
}
}

View file

@ -35,7 +35,7 @@ public partial class OrderViewOfficePage : IDisposable
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string OrderId { get; set; } = "";
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICrmActivityHttpRepository ActivityRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public ISendMailService MailService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }

View file

@ -32,7 +32,7 @@ namespace Wonky.Client.Pages;
public partial class PrintCatalogPage : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICatalogHttpRepository ItemRepo { get; set; }
[Inject] public ICatalogCrmHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
private List<SalesItemView> Items { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();

View file

@ -15,7 +15,7 @@ namespace Wonky.Client.Pages;
public partial class QuoteListCrmPage : IDisposable
{
[Inject] public ICrmActivityHttpRepository ActivityRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ILogger<QuoteListCrmPage> Logger { get; set; }
[Inject] public IToastService Toaster { get; set; }

View file

@ -31,8 +31,8 @@ public partial class ReportCreateCrmPage : IDisposable
{
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ICrmReportHttpRepository CrmReportRepo { get; set; }
[Inject] public IActivityCrmHttpRepository ActivityRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILogger<ReportCreateCrmPage> Logger { get; set; }
[Inject] public IToastService Toaster { get; set; }
@ -130,7 +130,7 @@ public partial class ReportCreateCrmPage : IDisposable
return;
Working = true;
var result = await CrmReportRepo.PostReport($"{_workDate:yyyy-MM-dd}", Report);
var result = await ReportRepo.CreateReport($"{_workDate:yyyy-MM-dd}", Report);
Toaster.ShowInfo($"{result.Message}", $"HTTP Status");
// reset km and date confirmation
@ -250,7 +250,7 @@ public partial class ReportCreateCrmPage : IDisposable
InitialValues = new ReportFiguresDto();
Activities = new List<ReportItemView>();
var data = await CrmReportRepo.InitializeReportData($"{_workDate:yyyy-MM-dd}");
var data = await ReportRepo.InitializeReportData($"{_workDate:yyyy-MM-dd}");
if(data.ReportClosed)
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");

View file

@ -24,7 +24,7 @@ namespace Wonky.Client.Pages;
public partial class ReportListCrmPage : IDisposable
{
[Inject] public ICrmReportHttpRepository ReportRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILogger<ReportListCrmPage> Logger { get; set; }

View file

@ -27,7 +27,7 @@ public partial class ReportListOfficePage : IDisposable
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public IOfficeReportHttpRepository ReportRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
@ -35,6 +35,9 @@ public partial class ReportListOfficePage : IDisposable
private bool Working { get; set; } = true;
private WebUserInfoView UserInfo { get; set; } = new();
/// <summary>
/// override OnParametersSeAsync
/// </summary>
protected override async Task OnParametersSetAsync()
{
Interceptor.RegisterEvent();
@ -42,13 +45,17 @@ public partial class ReportListOfficePage : IDisposable
UserInfo = await UserRepo.GetAdvisorInfo(UserId);
var reports = await ReportRepo.GetReports(UserId);
var reports = await ReportRepo.GetCountryReports(UserId);
if (reports.Any())
ActivityReports = reports.OrderByDescending(x => x.ReportDate).ToList();
Working = false;
}
/// <summary>
/// Callback to shoe the report
/// </summary>
/// <param name="reportDate"></param>
private void ShowThisReport(string reportDate)
{
var uri = new Uri(Navigator.Uri);

View file

@ -26,7 +26,7 @@ namespace Wonky.Client.Pages;
public partial class ReportViewCrmPage : IDisposable
{
[Parameter] public string ReportDate { get; set; }
[Inject] public ICrmReportHttpRepository ReportRepo { get; set; }
[Inject] public IReportHttpRepository ReportRepo { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }

View file

@ -40,8 +40,9 @@ public partial class ReportViewOfficePage : IDisposable
/// <summary>
/// Report Date
/// </summary>
[Parameter]
[Parameter]
public string ReportDate { get; set; } = "";
/// <summary>
/// Injected interceptor service
/// </summary>
@ -52,7 +53,7 @@ public partial class ReportViewOfficePage : IDisposable
/// Injected administrative report http repo
/// </summary>
[Inject]
public IOfficeReportHttpRepository ReportRepo { get; set; }
public IReportHttpRepository ReportRepo { get; set; }
/// <summary>
/// Navigation Manager
@ -89,10 +90,10 @@ public partial class ReportViewOfficePage : IDisposable
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
ProfileService.OnChange += ProfileServiceOnOnChange;
await ProfileService.SetWorkDate(DateTime.Parse(ReportDate));
await FetchUserReport(ReportDate);
}
@ -129,35 +130,35 @@ public partial class ReportViewOfficePage : IDisposable
}
ReportDate = workDate;
// ensure the browser address bar contains the correct link
Navigator.NavigateTo($"/office/users/advisors/{CountryCode}/{UserId}/reports/{workDate}", false, true);
// return if we are already at it
if (Working)
{
return;
}
// reset variables
Report = new ReportView();
Activities = new List<ReportItemView>();
// set busy signal
Working = true;
// fetch report
Report = await ReportRepo.GetReport(UserId, workDate);
Report = await ReportRepo.GetCountryReport(UserId, workDate);
// extract activities
Activities = Report.ReportItems.Where(x => x.Lines.Any()).ToList();
// store locally
if (!string.IsNullOrWhiteSpace(Report.ReportData.ReportDate))
{
await Storage.SetItemAsync($"{UserId}-{workDate}", Report);
}
// remove busy signal
Working = false;
}
@ -168,7 +169,7 @@ public partial class ReportViewOfficePage : IDisposable
Prefs = userPref;
Logger.LogDebug("OfficeReportViewPage => ProfileServiceOnOnChange => Prefs.WorkDate <= {}", Prefs.WorkDate);
ReportDate = Prefs.WorkDate;
StateHasChanged();
}

View file

@ -31,7 +31,7 @@ public partial class TaskItemListCrmPage : IDisposable
[Inject] public ILogger<TaskItemListCrmPage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ICrmTaskItemHttpRepository TaskItemRepo { get; set; }
[Inject] public ITaskItemCrmHttpRepository TaskRepo { get; set; }
[Inject] public IToastService Toaster { get; set; }
private UserPref Prefs { get; set; } = new();
private string WorkDate { get; set; } = $"{DateTime.Now:yyyy-MM-dd}";
@ -55,7 +55,7 @@ public partial class TaskItemListCrmPage : IDisposable
{
Working = true;
Toaster.ShowInfo("Vent nogle sekunder for data");
TaskItems = await TaskItemRepo.GetTaskList(workDate);
TaskItems = await TaskRepo.GetTaskList(workDate);
Toaster.ClearAll();
Working = false;

View file

@ -28,7 +28,7 @@ public partial class TaskItemViewCrmPage : IDisposable
{
[Parameter] public string TaskItemId { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public ICrmTaskItemHttpRepository CrmTaskItemRepo { get; set; }
[Inject] public ITaskItemCrmHttpRepository TaskRepo { get; set; }
private TaskItemDto _taskItem = new ();
private EditContext _editContext { get; set; }
private bool Working { get; set; } = true;
@ -39,7 +39,7 @@ public partial class TaskItemViewCrmPage : IDisposable
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_taskItem = await CrmTaskItemRepo.GetTaskItem(TaskItemId);
_taskItem = await TaskRepo.GetTaskItem(TaskItemId);
Console.WriteLine(JsonSerializer.Serialize(_taskItem));
Working = false;
}

View file

@ -29,11 +29,11 @@ public partial class UserListSalesRepPage : IDisposable
[Inject] public ILogger<UserListSalesRepPage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IOfficeCustomerHttpRepository CustomerRepo { get; set; }
[Inject] public ICustomerOfficeHttpRepository CustomerRepo { get; set; }
[Inject] public UserProfileService UserProfileService { get; set; }
private List<CompanyDto> _companyList { get; set; } = new();
private MetaData _metaData { get; set; } = new();
private CompanyPagingParams _paging = new();
private CustomerPaging _paging = new();
private UserPref UserPref { get; set; } = new();
private string _savedSearch { get; set; } = "";
private bool _includeFolded { get; set; }

View file

@ -27,7 +27,7 @@ public partial class WorkplaceDocumentListPage
[Parameter] public string WorkplaceId { get; set; } = "";
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public ICrmWorkplaceHttpRepository CrmWorkplaceRepo { get; set; }
[Inject] public IWorkplaceCrmHttpRepository WorkplaceCrmRepo { get; set; }
private bool Working { get; set; } = true;
}

View file

@ -27,8 +27,8 @@ namespace Wonky.Client.Pages;
public partial class WorkplaceListPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public ICrmWorkplaceHttpRepository CrmWorkplaceRepo { get; set; }
[Inject] public ICrmCompanyHttpRepository _companyRepo { get; set; }
[Inject] public IWorkplaceCrmHttpRepository WorkplaceCrmRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository _companyRepo { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }
private List<WorkplaceListView> _workplaces { get; set; } = new();
private CompanyDto _company { get; set; } = new();
@ -45,7 +45,7 @@ public partial class WorkplaceListPage : IDisposable
protected override async Task OnInitializedAsync()
{
Working = true;
_workplaces = await CrmWorkplaceRepo.GetWorkplaces(CompanyId);
_workplaces = await WorkplaceCrmRepo.GetWorkplaces(CompanyId);
Working = false;
}

View file

@ -29,8 +29,8 @@ public partial class WorkplaceViewPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string WorkplaceId { get; set; } = "";
[Inject] public ICrmWorkplaceHttpRepository CrmWorkplaceRepo { get; set; }
[Inject] public ICrmCompanyHttpRepository _companyRepo { get; set; }
[Inject] public IWorkplaceCrmHttpRepository WorkplaceCrmRepo { get; set; }
[Inject] public ICustomerCrmHttpRepository _companyRepo { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public NavigationManager _navigator { get; set; }
private WorkplaceDto _workplace { get; set; } = new();
@ -42,7 +42,7 @@ public partial class WorkplaceViewPage : IDisposable
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_workplace = await CrmWorkplaceRepo.GetWorkplace(CompanyId, WorkplaceId);
_workplace = await WorkplaceCrmRepo.GetWorkplace(CompanyId, WorkplaceId);
Working = false;
}
@ -54,14 +54,14 @@ public partial class WorkplaceViewPage : IDisposable
private async Task SubmitUpdate()
{
Working = true;
await CrmWorkplaceRepo.UpdateWorkplace(CompanyId, _workplace);
await WorkplaceCrmRepo.UpdateWorkplace(CompanyId, _workplace);
Working = false;
}
private async Task DeleteWorkplace()
{
Working = true;
await CrmWorkplaceRepo.DeleteWorkplace(CompanyId, _workplace.WorkplaceId);
await WorkplaceCrmRepo.DeleteWorkplace(CompanyId, _workplace.WorkplaceId);
_navigator.NavigateTo($"/companies/{CompanyId}/workplaces");
}

View file

@ -54,21 +54,21 @@ builder.Services.Configure<ApiConfig>(builder.Configuration.GetSection("ApiConfi
// app info object
builder.Services.Configure<AppInfo>(builder.Configuration.GetSection("AppInfo"));
// crm repositories
builder.Services.AddScoped<ICrmActivityHttpRepository, CrmActivityHttpRepository>();
builder.Services.AddScoped<ICrmCompanyHttpRepository, CrmCompanyHttpRepository>();
builder.Services.AddScoped<ICrmContactHttpRepository, CrmContactHttpRepository>();
builder.Services.AddScoped<ICrmHistoryHttpRepository, CrmHistoryHttpRepository>();
builder.Services.AddScoped<ICrmReportHttpRepository, CrmReportHttpRepository>();
builder.Services.AddScoped<ICrmTaskItemHttpRepository, CrmTaskItemHttpRepository>();
builder.Services.AddScoped<ICrmWorkplaceHttpRepository, CrmWorkplaceHttpRepository>();
builder.Services.AddScoped<IActivityCrmHttpRepository, ActivityCrmHttpRepository>();
builder.Services.AddScoped<ICustomerCrmHttpRepository, CustomerCrmCrmHttpRepository>();
builder.Services.AddScoped<IContactCrmHttpRepository, ContactCrmHttpRepository>();
builder.Services.AddScoped<ICustomerHistoryCrmHttpRepository, CustomerHistoryCrmHttpRepository>();
builder.Services.AddScoped<IReportHttpRepository, ReportHttpRepository>();
builder.Services.AddScoped<ITaskItemCrmHttpRepository, TaskItemCrmHttpRepository>();
builder.Services.AddScoped<IWorkplaceCrmHttpRepository, WorkplaceCrmHttpRepository>();
// administrative repositories
builder.Services.AddScoped<IUserHttpRepository, UserHttpRepository>();
builder.Services.AddScoped<IOfficeReportHttpRepository, OfficeReportHttpRepository>();
builder.Services.AddScoped<IOfficeCustomerHttpRepository, OfficeCustomerHttpRepository>();
builder.Services.AddScoped<IReportOfficeHttpRepository, ReportOfficeHttpRepository>();
builder.Services.AddScoped<ICustomerOfficeHttpRepository, CustomerOfficeHttpRepository>();
// warehouse repository
builder.Services.AddScoped<IWarehouseHttpRepository, WarehouseHttpRepository>();
// catalog repository
builder.Services.AddScoped<ICatalogHttpRepository, CatalogHttpRepository>();
builder.Services.AddScoped<ICatalogCrmHttpRepository, CatalogCrmHttpRepository>();
// mail service
builder.Services.AddScoped<ISendMailService, SendMailService>();
// interceptor

View file

@ -31,7 +31,7 @@ public partial class ContactModal
{
[Parameter] public ContactDto ParamContact { get; set; } = new();
[Parameter] public string CompanyName { get; set; } = "";
[Parameter] public ICrmContactHttpRepository ContactRepo { get; set; }
[Parameter] public IContactCrmHttpRepository ContactRepo { get; set; }
[Parameter] public HttpInterceptorService Interceptor { get; set; }
[Parameter] public EventCallback<ContactDto> OnSaveClicked { get; set; }
[Parameter] public EventCallback<string> OnDeleteClicked { get; set; }

View file

@ -29,7 +29,7 @@ public partial class InventoryReorderModal
{
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public SalesItemView SalesItem { get; set; } = new();
[Inject] public ICrmHistoryHttpRepository CrmHistoryRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository CustomerHistoryCrmRepo { get; set; }
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
private List<ProductHistoryView>? History { get; set; } = new();
private DraftItem SelectedItem { get; set; } = new();
@ -43,7 +43,7 @@ public partial class InventoryReorderModal
if (string.IsNullOrWhiteSpace(SalesItem.Sku))
return;
History = await CrmHistoryRepo.FetchHistory(CompanyId, SalesItem.Sku);
History = await CustomerHistoryCrmRepo.FetchHistory(CompanyId, SalesItem.Sku);
if (!History.Any())
await Task.Delay(1000);
SelectedItem.Item = SalesItem;

View file

@ -30,7 +30,7 @@ public partial class InvoiceViewModal : IDisposable
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string InvoiceId { get; set; } = "";
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository HistoryRepo { get; set; }
private string _modalDisplay = "";
private bool _showBackdrop;
private InvoiceView Invoice { get; set; } = new();

View file

@ -44,33 +44,22 @@
</NotAuthorized>
</AuthorizeView>
<AuthorizeView Roles="Admin">
<AuthorizeView Roles="Admin,Office,Warehouse">
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/office/users/advisors">
<i class="bi-people pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Sælgere
<NavLink class="nav-link ps-2" href="/office/dk">
<i class="bi-people pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Danmark
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/price-catalog">
<i class="bi-file-spreadsheet pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Priskatalog
</NavLink>
</div>
</AuthorizeView>
<AuthorizeView Roles="Office">
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/office/users/advisors">
<i class="bi-people pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Sælgere
<NavLink class="nav-link ps-2" href="/office/no">
<i class="bi-file-spreadsheet pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Sverige
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/price-catalog">
<i class="bi-file-spreadsheet pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Priskatalog
<NavLink class="nav-link ps-2" href="/office/se">
<i class="bi-file-spreadsheet pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Norge
</NavLink>
</div>
</AuthorizeView>
<AuthorizeView Roles="Warehouse,Admin,Office">
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/warehouse/orders/none">
<i class="bi-box pe-2" style="font-size:1.3em;" aria-hidden="true"></i> Forsendelse

View file

@ -28,7 +28,7 @@ public partial class PriceListModal : IDisposable
{
[Parameter] public string CountryCode { get; set; } = "dk";
[Parameter] public EventCallback<SelectedSku> OnSelected { get; set; }
[Inject] public ICatalogHttpRepository ItemRepo { get; set; }
[Inject] public ICatalogCrmHttpRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserProfileService UserProfileService { get; set; }

View file

@ -29,7 +29,7 @@ public partial class ProductHistoryModal
// [Parameter] public EventCallback<decimal> OnSelected { get; set; }
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string ItemSku { get; set; } = "";
[Inject] public ICrmHistoryHttpRepository CrmHistoryRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository CustomerHistoryCrmRepo { get; set; }
private List<ProductHistoryView>? History { get; set; }
private string ProductName { get; set; } = "";
private string _modalDisplay = "";
@ -37,7 +37,7 @@ public partial class ProductHistoryModal
protected override async Task OnParametersSetAsync()
{
History = await CrmHistoryRepo.FetchHistory(CompanyId, ItemSku);
History = await CustomerHistoryCrmRepo.FetchHistory(CompanyId, ItemSku);
if (History.Any())
{
ProductName = History[0].Description;

View file

@ -29,7 +29,7 @@ public partial class ProductPriceHistoryModal
[Parameter] public EventCallback<decimal> OnSelected { get; set; }
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string Sku { get; set; } = "";
[Inject] public ICrmHistoryHttpRepository CrmHistoryRepo { get; set; }
[Inject] public ICustomerHistoryCrmHttpRepository CustomerHistoryCrmRepo { get; set; }
private List<ProductHistoryView>? History { get; set; }
private string ProductName { get; set; } = "";
private string _modalDisplay = "";
@ -40,7 +40,7 @@ public partial class ProductPriceHistoryModal
if (string.IsNullOrWhiteSpace(Sku))
return;
History = await CrmHistoryRepo.FetchHistory(CompanyId, Sku);
History = await CustomerHistoryCrmRepo.FetchHistory(CompanyId, Sku);
if (History.Any())
{
ProductName = History[0].Description;

View file

@ -7,7 +7,7 @@
"image": "grumpy-coder.png"
},
"apiConfig": {
"baseUrl": "https://zeta.innotec.dk",
"baseUrl": "https://dev.innotec.dk",
"catalog": "api/v2/catalog",
"crmCustomers": "api/v2/crm/companies",
"crmInventoryExt": "history/inventory",

View file

@ -15,7 +15,7 @@
namespace Wonky.Entity.Requests;
public class CompanyPagingParams
public class CustomerPaging
{
/// <summary>
/// internal default page size