Contacts and Commodities

This commit is contained in:
2021-08-05 20:36:06 +01:00
parent afd38cea03
commit f5e0b925fb
33 changed files with 694 additions and 505 deletions
+2 -39
View File
@@ -1,4 +1,5 @@
using Sarand.BusinessMgr.Net.Standard.Base.App; using Newtonsoft.Json;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus; using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Bus;
@@ -26,23 +27,11 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
securityProfile = new SbmSecurityProfile(this, false); securityProfile = new SbmSecurityProfile(this, false);
} }
//-------------------------------------------------------------------
// User Context.
public SbmUserContext UserContext
{
get
{
SbmUserContext userContext = new SbmUserContext_Web(SessionContext);
return userContext;
}
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Security Profile. // Security Profile.
private readonly SbmSecurityProfile securityProfile; private readonly SbmSecurityProfile securityProfile;
public ISbmSecurityProfile SecurityProfile { get { return securityProfile; } } public ISbmSecurityProfile SecurityProfile { get { return securityProfile; } }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// ToDo: Organisation configuration. // ToDo: Organisation configuration.
public String GetOrganisationOption(Sbm.OrganisationOption option, String context) { return null; } public String GetOrganisationOption(Sbm.OrganisationOption option, String context) { return null; }
@@ -61,32 +50,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
public Sbm.CommodityType GetOwnerOption_CommodityType(Sbm.OrgOption_CommodityType commodityTypeContext) { return Sbm.CommodityType.Unknown; } public Sbm.CommodityType GetOwnerOption_CommodityType(Sbm.OrgOption_CommodityType commodityTypeContext) { return Sbm.CommodityType.Unknown; }
public SysId GetOwnerOption_StockLocation(Sbm.OrgOption_StockLocation eLoc) { return null; } public SysId GetOwnerOption_StockLocation(Sbm.OrgOption_StockLocation eLoc) { return null; }
//-------------------------------------------------------------------
// Contacts.
public class ContactsData
{
public class FilterData
{
public uint PageNo { get; set; } = 1;
public ushort PageLength { get; set; } = 16;
}
public FilterData Filter { get; } = new FilterData();
}
public ContactsData Contacts { get; } = new ContactsData();
//-------------------------------------------------------------------
// Commodities.
public class CommoditiesData
{
public class FilterData
{
public uint PageNo { get; set; } = 1;
public ushort PageLength { get; set; } = 16;
}
public FilterData Filter { get; } = new FilterData();
}
public CommoditiesData Commodities { get; } = new CommoditiesData();
//------------------------------------------------------------------- //-------------------------------------------------------------------
} }
//======================================================================= //=======================================================================
+3 -1
View File
@@ -109,7 +109,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
.AddViewLocalization( .AddViewLocalization(
LanguageViewLocationExpanderFormat.Suffix, LanguageViewLocationExpanderFormat.Suffix,
opts => { opts.ResourcesPath = resourcesPath; }) opts => { opts.ResourcesPath = resourcesPath; })
.AddDataAnnotationsLocalization(); .AddDataAnnotationsLocalization()
// Ignore null values during object serisliation.
.AddJsonOptions(options => { options.JsonSerializerOptions.IgnoreNullValues = true; });
// Configure localisation middleware. // Configure localisation middleware.
config.services.Configure<RequestLocalizationOptions> config.services.Configure<RequestLocalizationOptions>
@@ -11,6 +11,7 @@ using Sarand.BusinessMgr.Net.Core.Web.Models;
using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus; using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles; using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Net.Standard.Base.Core;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr; using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.CodeTypes; using Sarand.Net.Standard.Base.CodeTypes;
@@ -69,8 +70,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
public bool DebugMode { get; } = SacsSystem.DebugMode; public bool DebugMode { get; } = SacsSystem.DebugMode;
protected SbmApplication_Web App { get { return SbmGlobals_Web.Application; } } protected SbmApplication_Web App { get { return SbmGlobals_Web.Application; } }
public SbmAppConfig AppConfig { get { return App.AppConfig; } } public SbmAppConfig AppConfig { get { return App.AppConfig; } }
public SbmSessionContext SessionContext { get { return UserContext?.SessionContext ?? null; } } public SbmSessionContext SessionContext { get { return SessionData?.SessionContext ?? null; } }
public SbmUserContext UserContext { get { return SessionData.UserContext; } } public ISbmUserContext UserContext { get { return SessionData; } }
protected SbmLocaliser Localiser { get; } protected SbmLocaliser Localiser { get; }
/// <summary> /// <summary>
/// Indicate whether session data should be stored by action. /// Indicate whether session data should be stored by action.
@@ -386,10 +387,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
public class AjaxResponse_Base public class AjaxResponse_Base
{ {
// Response status. // Response status.
public bool Success { get; set; } = false; public bool? Success { get; set; } = null;
public bool Error { get; set; } = false; public bool? Error { get; set; } = null;
public bool SessionExpired { get; protected set; } = false; public bool? SessionExpired { get; protected set; } = null;
public bool GoHome { get; protected set; } = false; public bool? GoHome { get; protected set; } = null;
public AjaxResponse_Base SetSessionExpired(String title, String text) public AjaxResponse_Base SetSessionExpired(String title, String text)
{ {
SessionExpired = true; SessionExpired = true;
@@ -432,15 +433,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
/// <summary>
/// Common item response data properties.
/// <para>- Null values are ignored by the JSON serialiser.</para>
/// <para>- Return null for false boolean values where possible.</para>
/// <para>- Return null for blank string values where possible.</para>
/// </summary>
public class ItemData public class ItemData
{ {
public String Id { get; set; } public String Id { get; set; }
public String Notes { get; set; } private String notes;
public String Notes { get { return StringUtil.OnEmpty(notes, null); } set { notes = StringUtil.EmptyOnNull(value).Trim(); } }
public String StatusCode { get; set; } public String StatusCode { get; set; }
public String StatusDesc { get; set; } public String StatusDesc { get; set; }
public Boolean Awaiting { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Awaiting)); } } public bool? Awaiting { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Awaiting)) ? true : (bool?)null; } }
public Boolean Active { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)); } } public bool? Active { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)) ? true : (bool?)null; } }
public Boolean Deleted { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Deleted)); } } public bool? Deleted { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Deleted)) ? true : (bool?)null; } }
public String CreatedOn { get; set; } public String CreatedOn { get; set; }
public String CreatedOnFmt { get; set; } public String CreatedOnFmt { get; set; }
public String UpdatedOn { get; set; } public String UpdatedOn { get; set; }
@@ -462,7 +470,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
public String Error { get; set; } public String Error { get; set; }
} }
private readonly Dictionary<String, FormControlValue> controlValues = new Dictionary<String, FormControlValue>(); private readonly Dictionary<String, FormControlValue> controlValues = new Dictionary<String, FormControlValue>();
public List<FormControlValue> ControlValues { get { return controlValues.Values.ToList(); } } public List<FormControlValue> ControlValues { get { return controlValues.Count > 0 ? controlValues.Values.ToList() : null; } }
public void SetControlValue(String controlName, String value, String error = null) public void SetControlValue(String controlName, String value, String error = null)
{ {
if (controlValues.ContainsKey(controlName)) if (controlValues.ContainsKey(controlName))
@@ -509,7 +517,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
public String Message { get; set; } public String Message { get; set; }
} }
public NotificationData Notification { get; private set; } public NotificationData Notification { get; private set; }
public bool HasNotification { get { return Notification != null; } }
public AjaxResponse_Data SetNotification(String title, String message) public AjaxResponse_Data SetNotification(String title, String message)
{ {
Notification = new NotificationData() { Title = title, Message = message }; Notification = new NotificationData() { Title = title, Message = message };
+1 -1
View File
@@ -63,7 +63,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Business components. // Business components.
// NB Keep these accessors protected to avoid them being called by teh model binding logic before the session data is ready. // NB Keep these accessors protected to avoid them being called by teh model binding logic before the session data is ready.
protected SbmInternals Internals { get { if (internals == null) internals = new SbmInternals(SessionData_Web.UserContext); return internals; } } protected SbmInternals Internals { get { if (internals == null) internals = new SbmInternals(SessionData_Web); return internals; } }
// Managers. // Managers.
protected SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } } protected SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
protected SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } } protected SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } }
@@ -86,7 +86,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
KeepLoggedIn = affiliateUser.KeepLoggedIn_Portal; KeepLoggedIn = affiliateUser.KeepLoggedIn_Portal;
else Debugger.Break(); else Debugger.Break();
} }
this.supervisedOrganisations = supervisedOrganisations; this.supervisedOrganisations = supervisedOrganisations ?? new List<SysIdString>();
} }
protected UserData(UserData userData) protected UserData(UserData userData)
{ {
@@ -132,20 +132,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
} }
protected abstract UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations); protected abstract UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations);
[JsonProperty("User")]
protected UserData userData;
[JsonIgnore]
/// <summary>User account details.</summary> /// <summary>User account details.</summary>
private UserData userData;
public ISbmUserContext.IUserData User { get { return userData; } } public ISbmUserContext.IUserData User { get { return userData; } }
public bool ValidUser { get { return SysId.IsValid(userData.SecurityItemId) && SysId.IsValid(userData.AffiliateId); } } public bool ValidUser { get { return SysId.IsValid(userData.SecurityItemId) && SysId.IsValid(userData.AffiliateId); } }
public bool KeepLoggedIn { get { return userData.KeepLoggedIn; } } public bool KeepLoggedIn { get { return userData.KeepLoggedIn; } }
/// <summary>User - JSON deserialisation route.</summary>
protected void SetUser(UserData user)
{
if (this.userData != null && userData.UserAccountSupplied)
throw new NotSupportedException("Session User cannot be replaced.");
this.userData = user;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Organisation. // Organisation.
public class OrganisationData : ISbmUserContext.IOrganisationData public class OrganisationData : ISbmUserContext.IOrganisationData
@@ -165,7 +159,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
public String DisplayName { get; protected set; } public String DisplayName { get; protected set; }
public String InterfaceContext { get; } public String InterfaceContext { get; }
} }
[JsonProperty("Organisation")]
protected OrganisationData organisationData; protected OrganisationData organisationData;
[JsonIgnore]
public ISbmUserContext.IOrganisationData Organisation { get { return organisationData; } } public ISbmUserContext.IOrganisationData Organisation { get { return organisationData; } }
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -1806,8 +1806,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
// Commodity Ids. // Commodity Ids.
public List<SysId> IncludedIds { get; } = new List<SysId>(); public List<SysId> IncludedIds { get; } = new List<SysId>();
public List<SysId> ExcludedIds { get; } = new List<SysId>(); public List<SysId> ExcludedIds { get; } = new List<SysId>();
/// <summary>Organisation - if not available via Session Config. ie. must be populated for Web/Console sessions.</summary>
public SysId AffiliateIdOrganisation {get; set; }
// Commodity. // Commodity.
public Sbm.CommodityType CommodityType { get; set; } public Sbm.CommodityType CommodityType { get; set; }
public bool StockItemsOnly { get; set; } = false; public bool StockItemsOnly { get; set; } = false;
@@ -175,7 +175,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
return false; return false;
} }
// Validate the affiliate names. // Validate the affiliate names.
if (errField.Name != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Name, "name", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_Name), SbmAffiliate.IsIndividual(data.AffiliateType))) if (errField.Name != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Name, "name", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_Name), !SbmAffiliate.IsIndividual(data.AffiliateType)))
{ {
errField.Name = SacsHierarchyItem.ValidValue.Invalid; errField.Name = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
@@ -402,7 +402,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
errField.Code = SacsHierarchyItem.ValidValue.Invalid; errField.Code = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
} }
if (errField.DescBrief != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescBrief, "description brief", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Commodity_DescBrief))) if (errField.DescBrief != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescBrief, "description brief", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Commodity_DescBrief), true))
{ {
errField.DescBrief = SacsHierarchyItem.ValidValue.Invalid; errField.DescBrief = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
@@ -283,7 +283,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
dbAffiliate._Website = affiliate.Website; dbAffiliate._Website = affiliate.Website;
// Ogranisation. // Ogranisation.
dbAffiliate._AffIdParent = affiliate.AffiliateIdParent.ToInt(); dbAffiliate._AffIdParent = affiliate.AffiliateIdParent.ToInt();
if (!affiliate.IsIndividual())
dbAffiliate._Name = affiliate.Name; dbAffiliate._Name = affiliate.Name;
else
dbAffiliate._Name = affiliate.GetDisplayName();
dbAffiliate._Abbrev = affiliate.Abbr; dbAffiliate._Abbrev = affiliate.Abbr;
dbAffiliate._Nature = affiliate.Nature; dbAffiliate._Nature = affiliate.Nature;
dbAffiliate._Contact = affiliate.Contact; dbAffiliate._Contact = affiliate.Contact;
@@ -65,6 +65,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
return new List<StringPair>() return new List<StringPair>()
{ {
new StringPair("Id",SysId.ToString(commodity.Id)), new StringPair("Id",SysId.ToString(commodity.Id)),
new StringPair("Code",commodity.Code),
new StringPair("DescBrief",commodity.DescBrief), new StringPair("DescBrief",commodity.DescBrief),
new StringPair("Status",commodity.StatusCode) new StringPair("Status",commodity.StatusCode)
}; };
@@ -2295,16 +2296,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
//--------------------------------------------------------------- //---------------------------------------------------------------
// Organisation. // Organisation.
if (SysId.IsValid(prm.AffiliateIdOrganisation))
filter.Add(colCommodity_AffIdOwner + "=" + SysId.ToString(prm.AffiliateIdOrganisation));
else
{
// Must filter by organisation if insufficient alternative filetrs. // Must filter by organisation if insufficient alternative filetrs.
if (!prm.IncludedIds.HasValidIds() && !prm.PriceSetIdsIncluded.HasValidIds() && !SysId.IsValid(prm.AssociationIdCustomer) && !SysId.IsValid(prm.AssociationIdCommodityCustomer)) if (!prm.IncludedIds.HasValidIds() && !prm.PriceSetIdsIncluded.HasValidIds() && !SysId.IsValid(prm.AssociationIdCustomer) && !SysId.IsValid(prm.AssociationIdCommodityCustomer))
{ {
if (!SysId.IsValid(AffiliateId_Owner)) throw new NotSupportedException("Commodity query filter - Organisation Id must be specified"); if (!SysId.IsValid(AffiliateId_Owner)) throw new NotSupportedException("Commodity query filter - Organisation Id must be specified");
filter.Add(colCommodity_AffIdOwner + "=" + SysId.ToString(AffiliateId_Owner)); filter.Add(colCommodity_AffIdOwner + "=" + SysId.ToLong(AffiliateId_Owner));
}
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
@@ -58,6 +58,8 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
SbmAffiliate affiliateOrganisation = accountMgr.GetAffiliateById(affiliateIdOrganisation); SbmAffiliate affiliateOrganisation = accountMgr.GetAffiliateById(affiliateIdOrganisation);
Assert.IsNotNull(affiliateOrganisation); Assert.IsNotNull(affiliateOrganisation);
// Profile.
// Populate User Session. // Populate User Session.
SbmSessionData_Portal sessionData = new SbmSessionData_Portal(SessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); SbmSessionData_Portal sessionData = new SbmSessionData_Portal(SessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
@@ -80,6 +82,7 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
Assert.AreEqual(affiliateOrganisation.Id, sessionData.Organisation.AffiliateId); Assert.AreEqual(affiliateOrganisation.Id, sessionData.Organisation.AffiliateId);
Assert.AreEqual(associationOrganisation.Id, sessionData.Organisation.AssociationId); Assert.AreEqual(associationOrganisation.Id, sessionData.Organisation.AssociationId);
// Serialise data. // Serialise data.
String sessionDataJson = JsonConvert.SerializeObject(sessionData); String sessionDataJson = JsonConvert.SerializeObject(sessionData);
Assert.IsNotNull(sessionDataJson); Assert.IsNotNull(sessionDataJson);
@@ -192,9 +192,18 @@
<data name="label.create" xml:space="preserve"> <data name="label.create" xml:space="preserve">
<value>Create</value> <value>Create</value>
</data> </data>
<data name="label.create.individual" xml:space="preserve">
<value>Create Individual</value>
</data>
<data name="label.create.organisation" xml:space="preserve">
<value>Create Organisation</value>
</data>
<data name="label.description" xml:space="preserve"> <data name="label.description" xml:space="preserve">
<value>Description</value> <value>Description</value>
</data> </data>
<data name="label.edit" xml:space="preserve">
<value>Edit</value>
</data>
<data name="label.email" xml:space="preserve"> <data name="label.email" xml:space="preserve">
<value>Email</value> <value>Email</value>
</data> </data>
@@ -216,6 +225,12 @@
<data name="label.name" xml:space="preserve"> <data name="label.name" xml:space="preserve">
<value>Name</value> <value>Name</value>
</data> </data>
<data name="label.name.first" xml:space="preserve">
<value>First name</value>
</data>
<data name="label.name.last" xml:space="preserve">
<value>Last name</value>
</data>
<data name="label.next" xml:space="preserve"> <data name="label.next" xml:space="preserve">
<value>Next</value> <value>Next</value>
</data> </data>
@@ -300,6 +315,18 @@
<data name="msg.error.system" xml:space="preserve"> <data name="msg.error.system" xml:space="preserve">
<value>System error encountered.</value> <value>System error encountered.</value>
</data> </data>
<data name="msg.item.created" xml:space="preserve">
<value>Item created.</value>
</data>
<data name="msg.item.deleted" xml:space="preserve">
<value>Item deleted.</value>
</data>
<data name="msg.item.removed" xml:space="preserve">
<value>Item removed.</value>
</data>
<data name="msg.item.updated" xml:space="preserve">
<value>Item updated.</value>
</data>
<data name="msg.something.gone.wrong" xml:space="preserve"> <data name="msg.something.gone.wrong" xml:space="preserve">
<value>Unfortunately, something has gone wrong.\n\nYou will be returned to the home page.</value> <value>Unfortunately, something has gone wrong.\n\nYou will be returned to the home page.</value>
</data> </data>
@@ -35,12 +35,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Contact details. // Contact details.
private class UserData_Online : UserData private class UserData_Portal : UserData
{ {
public UserData_Online(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) : public UserData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) :
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations) base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations)
{ } { }
public UserData_Online(UserData userData) : public UserData_Portal(UserData userData) :
base(userData) base(userData)
{ } { }
public new bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) public new bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
@@ -50,10 +50,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
} }
protected override UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) protected override UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
{ {
return new UserData_Online(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations); return new UserData_Portal(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations);
} }
/// <summary>User - JSON deserialisation route.</summary> /// <summary>User - JSON deserialisation route.</summary>
//public new UserData User { get { return base.User; } set { SetUser(new UserData_Online(value)); } } //public new UserData User { get { return base.User; } set { SetUser(new UserData_Portal(value)); } }
/// <summary> /// <summary>
/// Update the user's contact details against the session. /// Update the user's contact details against the session.
@@ -61,7 +61,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
/// </summary> /// </summary>
public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
{ {
UserData_Online user = User as UserData_Online; UserData_Portal user = User as UserData_Portal;
if (user != null) if (user != null)
return user.Refresh(securityItemUser, affiliateUser, supervisedOrganisations); return user.Refresh(securityItemUser, affiliateUser, supervisedOrganisations);
organisationData = new OrganisationData(associationOrganisation, affiliateOrganisation); organisationData = new OrganisationData(associationOrganisation, affiliateOrganisation);
@@ -69,66 +69,62 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// User Profile. /// <summary>
// Protected constructors & setters for JSON deserialisation. /// User Profile.
/// <para>- Filter settings.</para>
/// </summary>
public class UserProfileData public class UserProfileData
{ {
public UserProfileData() { } public UserProfileData() { }
// Sports.
public class SportData
{
[JsonConstructor]
public SportData(SysId sportId, SaStatus status)
{
SportId = sportId;
Status = status;
}
public SysId SportId { get; protected set; }
public SaStatus Status { get; protected set; }
}
private class SportData_Online : SportData
{
// Internal class to allow values to be updated.
public SportData_Online(SysId sportId, SaStatus status) : base(sportId, status) { }
public SportData_Online(SportData sportData) : base(sportData.SportId, sportData.Status) { }
public void SetSportId(SysId sportId) { SportId = sportId; }
public void SetStatus(SaStatus status) { Status = status; }
}
[JsonIgnore]
private readonly List<SportData_Online> sports = new List<SportData_Online>();
[JsonIgnore]
public int SportCount { get { return sports.Count; } }
public List<SportData> Sports { get { return new List<SportData>(sports); } protected set { sports.Clear(); sports.AddRange(value.Select(item => new SportData_Online(item))); } }
public void AddSport(SysId sportId, SaStatus status)
{
if (!SysId.IsValid(sportId)) throw new NotSupportedException("Session Profile Sport must have a valid Id");
SportData_Online sport = this.sports.Find(item => item.SportId == sportId);
if (sport != null)
{
sport.SetStatus(status);
}
else
this.sports.Add(new SportData_Online(sportId, status));
}
public void ClearSports()
{
this.sports.Clear();
}
}
public UserProfileData Profile { get; protected set; } = new UserProfileData();
//------------------------------------------------------------------- // Common filter.
// Filter properties.
public class FilterData public class FilterData
{ {
/// <summary>Id for currently selected Association.</summary> /// <summary>Id for currently selected Association.</summary>
public SysId AssociationId { get; set; } public SysId AssociationId { get; set; }
} }
/// <summary>
/// Common filter properties.
/// </summary>
public FilterData Filter { get; private set; } = new FilterData(); public FilterData Filter { get; private set; } = new FilterData();
// Contacts filter.
public class ContactsData
{
public class FilterData
{
public uint PageNo { get; set; } = 1;
public ushort PageLength { get; set; } = 16;
}
public FilterData Filter { get; } = new FilterData();
}
/// <summary>
/// Contacts filter properties.
/// </summary>
public ContactsData Contacts { get; } = new ContactsData();
// Commodities filter.
public class CommoditiesData
{
public class FilterData
{
public uint PageNo { get; set; } = 1;
public ushort PageLength { get; set; } = 16;
}
public FilterData Filter { get; } = new FilterData();
}
/// <summary>
/// Commodities filter properties.
/// </summary>
public CommoditiesData Commodities { get; } = new CommoditiesData();
}
public UserProfileData Profile { get; protected set; } = new UserProfileData();
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Online application encryption IV value - for consistent encryption during session.
public String Base64IV_OnlineApp { get; private set; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(SbmController_Portal.Base64Key_OnlineApp); //-------------------------------------------------------------------
// Portal application encryption IV value - for consistent encryption during session.
public String Base64IV_PortalApp { get; private set; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(SbmController_Portal.Base64Key_OnlineApp);
//------------------------------------------------------------------- //-------------------------------------------------------------------
} }
@@ -97,7 +97,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Item filter. // Item filter.
SbmCommodity.Params prmCommodity = new SbmCommodity.Params(); SbmCommodity.Params prmCommodity = new SbmCommodity.Params();
prmCommodity.AffiliateIdOrganisation = SessionData.Organisation.AffiliateId;
prmCommodity.Search = model.Filter.CommoditySearch; prmCommodity.Search = model.Filter.CommoditySearch;
prmCommodity.CommodityType = model.GetFilterCommodityType(); prmCommodity.CommodityType = model.GetFilterCommodityType();
prmCommodity.StatusCat = SbmCommodity.StatusCat.NotDeleted; prmCommodity.StatusCat = SbmCommodity.StatusCat.NotDeleted;
@@ -150,8 +149,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Refresh paging info. // Refresh paging info.
if (model.Paging.IsPaged) if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Commodities.Count; model.Paging.ItemCount = (ushort)responseData.Commodities.Count;
SessionData.Commodities.Filter.PageNo = model.Paging.PageNo; SessionData_Portal.Profile.Commodities.Filter.PageNo = model.Paging.PageNo;
SessionData.Commodities.Filter.PageLength = model.Paging.PageLength; SessionData_Portal.Profile.Commodities.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model); responseData.SetPaging(model);
// Complete response. // Complete response.
@@ -179,9 +178,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
String messageTitle = Localiser["commodity.caption.commodity"]; String messageTitle = Localiser["commodity.caption.commodity"];
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model); AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
// Validate session. // Validate session and referrer.
if (!ValidUserSession) if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
return GetAjaxResult_InvalidSession(responseData); if (!ValidReferer) return Forbid();
RefreshModel(model);
// Identify item. // Identify item.
SysId commodityId = model.CommodityId.ToSysId(); SysId commodityId = model.CommodityId.ToSysId();
@@ -217,17 +217,31 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
String messageTitle = Localiser["commodity.caption.commodity"]; String messageTitle = Localiser["commodity.caption.commodity"];
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model); AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
// Validate session. // Validate session and referrer.
if (!ValidUserSession) if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
return GetAjaxResult_InvalidSession(responseData); if (!ValidReferer) return Forbid();
RefreshModel(model);
// Validate item properties. // Validate item properties.
model.ValidateCommodityData(responseData); model.ValidateCommodityData(responseData);
if (responseData.HasControlErrors()) if (responseData.HasControlErrors())
return Json(responseData); return Json(responseData);
// Retrieve existing item. // Validate item Id against 'Exists' flag.
SysId commodityId = model.CommodityId.ToSysId(); SysId commodityId = model.CommodityId.ToSysId();
bool commodityExists = StringUtil.ToBool(model.CommodityExists);
if (commodityExists && !SysId.IsValid(commodityId))
{
SaLogger.Warn(fn + " Id not specified for existing Commodity.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
if (!commodityExists && SysId.IsValid(commodityId))
{
SaLogger.Warn(fn + " Id specified for new Commodity: '" + model.CommodityId + "'");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Retrieve existing item.
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId); SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
if (commodity == null && SysId.IsValid(commodityId)) if (commodity == null && SysId.IsValid(commodityId))
{ {
@@ -244,13 +258,17 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
} }
// Populate item properties. // Populate item properties.
if (model.CommodityType != null)
commodity.CommodityType = model.GetCommodityType();
if (model.CommodityCode != null) if (model.CommodityCode != null)
commodity.Code = model.CommodityCode; commodity.Code = model.CommodityCode;
if (model.CommodityDesc != null)
commodity.DescBrief = model.CommodityDesc;
// Common properties. // Common properties.
if (model.CommodityNotes != null) if (model.CommodityNotes != null)
commodity.Notes = model.CommodityNotes; commodity.Notes = model.CommodityNotes;
if (model.CommodityStatus != null) if (model.CommodityStatusCode != null)
commodity.Status = model.GetCommodityStatus(); commodity.Status = model.CommodityStatus;
// Store item. // Store item.
if (!SysId.IsValid(commodity.Id)) if (!SysId.IsValid(commodity.Id))
@@ -260,6 +278,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
SaLogger.Warn(fn + " Failed to insert commodity: " + CommodityMgr.ErrorStateMessage); SaLogger.Warn(fn + " Failed to insert commodity: " + CommodityMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage));
} }
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
} }
else else
{ {
@@ -268,6 +287,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
SaLogger.Warn(fn + " Failed to update commodity [Id:" + SysId.ToString(commodity.Id) + "]: " + CommodityMgr.ErrorStateMessage); SaLogger.Warn(fn + " Failed to update commodity [Id:" + SysId.ToString(commodity.Id) + "]: " + CommodityMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage));
} }
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
} }
// Construct response. // Construct response.
@@ -42,8 +42,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Commodity page. // Commodity page.
Model_Commodity model = new Model_Commodity(Localiser); Model_Commodity model = new Model_Commodity(Localiser);
model.Paging.PageNo = SessionData.Commodities.Filter.PageNo; model.Paging.PageNo = SessionData_Portal.Profile.Commodities.Filter.PageNo;
model.Paging.PageLength = SessionData.Commodities.Filter.PageLength; model.Paging.PageLength = SessionData_Portal.Profile.Commodities.Filter.PageLength;
return View(model); return View(model);
} }
@@ -36,6 +36,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
public String DisplayName { get; set; } public String DisplayName { get; set; }
public String TypeCode { get; set; } public String TypeCode { get; set; }
public String TypeDesc { get; set; } public String TypeDesc { get; set; }
public bool? Individual { get; set; }
// Address. // Address.
public String AddressSummary { get; set; } public String AddressSummary { get; set; }
} }
@@ -78,6 +79,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
data.DisplayName = affiliate.GetDisplayName(); data.DisplayName = affiliate.GetDisplayName();
data.TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliate.AffiliateType); data.TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliate.AffiliateType);
data.TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliate.AffiliateType); data.TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliate.AffiliateType);
data.Individual = affiliate.AffiliateType == Sbm.AffiliateType.Individual ? true : (bool?)null;
// Common properties. // Common properties.
data.Notes = affiliate.Notes; data.Notes = affiliate.Notes;
data.StatusCode = affiliate.StatusCode; data.StatusCode = affiliate.StatusCode;
@@ -153,8 +155,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Item filter. // Item filter.
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.Search = model.Filter.AffiliateSearch; prmAffiliate.Search = model.Filter.ContactSearch;
prmAffiliate.AffiliateType = model.GetFilterAffiliateType(); prmAffiliate.AffiliateType = model.GetFilterContactType();
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted; prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name)); prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name));
prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.LastName)); prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.LastName));
@@ -193,6 +195,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
DisplayName = values.GetString(colName.DataName), DisplayName = values.GetString(colName.DataName),
TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliateType), TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliateType),
TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliateType), TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliateType),
Individual = affiliateType == Sbm.AffiliateType.Individual ? true : (bool?)null,
AddressSummary = AccountMgr.GetAffiliateDataValue(colAddress, values).AsString(), AddressSummary = AccountMgr.GetAffiliateDataValue(colAddress, values).AsString(),
Notes = values.GetString(colNotes.DataName), Notes = values.GetString(colNotes.DataName),
StatusCode = values.GetString(colStatus.DataName), StatusCode = values.GetString(colStatus.DataName),
@@ -209,8 +212,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Refresh paging info. // Refresh paging info.
if (model.Paging.IsPaged) if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Affiliates.Count; model.Paging.ItemCount = (ushort)responseData.Affiliates.Count;
SessionData.Contacts.Filter.PageNo = model.Paging.PageNo; SessionData_Portal.Profile.Contacts.Filter.PageNo = model.Paging.PageNo;
SessionData.Contacts.Filter.PageLength = model.Paging.PageLength; SessionData_Portal.Profile.Contacts.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model); responseData.SetPaging(model);
// Complete response. // Complete response.
@@ -235,12 +238,13 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
public IActionResult Ajax_GetItem(Model_Contact model) public IActionResult Ajax_GetItem(Model_Contact model)
{ {
String fn = GetType().Name + ".Ajax_GetItem"; String fn = GetType().Name + ".Ajax_GetItem";
String messageTitle = Localiser["affiliate.caption.affiliate"]; String messageTitle = Localiser["contact.caption.contact"];
AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model); AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model);
// Validate session. // Validate session and referrer.
if (!ValidUserSession) if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
return GetAjaxResult_InvalidSession(responseData); if (!ValidReferer) return Forbid();
RefreshModel(model);
// Identify item. // Identify item.
SysId affiliateId = model.AffiliateId.ToSysId(); SysId affiliateId = model.AffiliateId.ToSysId();
@@ -273,20 +277,34 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
public IActionResult Ajax_StoreItem(Model_Contact model) public IActionResult Ajax_StoreItem(Model_Contact model)
{ {
String fn = GetType().Name + ".Ajax_StoreItem"; String fn = GetType().Name + ".Ajax_StoreItem";
String messageTitle = Localiser["affiliate.caption.affiliate"]; String messageTitle = Localiser["contact.caption.contact"];
AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model); AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model);
// Validate session. // Validate session and referrer.
if (!ValidUserSession) if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
return GetAjaxResult_InvalidSession(responseData); if (!ValidReferer) return Forbid();
RefreshModel(model);
// Validate item properties. // Validate item properties.
model.ValidateAffiliateData(responseData); model.ValidateAffiliateData(responseData);
if (responseData.HasControlErrors()) if (responseData.HasControlErrors())
return Json(responseData); return Json(responseData);
// Retrieve existing item. // Validate item Id against 'Exists' flag.
SysId affiliateId = model.AffiliateId.ToSysId(); SysId affiliateId = model.AffiliateId.ToSysId();
bool contactExists = StringUtil.ToBool(model.ContactExists);
if (contactExists && !SysId.IsValid(affiliateId))
{
SaLogger.Warn(fn + " Id not specified for existing Affiliate.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
if (!contactExists && SysId.IsValid(affiliateId))
{
SaLogger.Warn(fn + " Id specified for new Affiliate: '" + model.AffiliateId + "'");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Retrieve existing item.
SbmAffiliate affiliate = AccountMgr.GetAffiliateById(affiliateId); SbmAffiliate affiliate = AccountMgr.GetAffiliateById(affiliateId);
if (affiliate == null && SysId.IsValid(affiliateId)) if (affiliate == null && SysId.IsValid(affiliateId))
{ {
@@ -296,16 +314,33 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Create new item if required. // Create new item if required.
if (affiliate == null) if (affiliate == null)
affiliate = AccountMgr.CreateAffiliate(model.GetAffiliateType()); {
affiliate = AccountMgr.CreateAffiliate(model.GetContactType());
}
else
{
if (model.ContactType != null)
affiliate.AffiliateType = model.GetContactType();
}
// Populate item properties. // Populate item properties.
if (model.AffiliateName != null) if (affiliate.IsIndividual())
affiliate.Name = model.AffiliateName; {
if (model.ContactFirstName != null)
affiliate.FirstName = model.ContactFirstName;
if (model.ContactLastName != null)
affiliate.LastName = model.ContactLastName;
}
else
{
if (model.ContactName != null)
affiliate.Name = model.ContactName;
}
// Common properties. // Common properties.
if (model.AffiliateNotes != null) if (model.ContactNotes != null)
affiliate.Notes = model.AffiliateNotes; affiliate.Notes = model.ContactNotes;
if (model.AffiliateStatus != null) if (model.ContactStatusCode != null)
affiliate.Status = model.GetAffiliateStatus(); affiliate.Status = model.ContactStatus;
// Store item. // Store item.
if (!SysId.IsValid(affiliate.Id)) if (!SysId.IsValid(affiliate.Id))
@@ -315,6 +350,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
SaLogger.Warn(fn + " Failed to insert affiliate: " + AccountMgr.ErrorStateMessage); SaLogger.Warn(fn + " Failed to insert affiliate: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
} }
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
} }
else else
{ {
@@ -323,6 +359,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
SaLogger.Warn(fn + " Failed to update affiliate [Id:" + SysId.ToString(affiliate.Id) + "]: " + AccountMgr.ErrorStateMessage); SaLogger.Warn(fn + " Failed to update affiliate [Id:" + SysId.ToString(affiliate.Id) + "]: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
} }
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
} }
// Construct response. // Construct response.
@@ -42,8 +42,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
// Contact page. // Contact page.
Model_Contact model = new Model_Contact(Localiser); Model_Contact model = new Model_Contact(Localiser);
model.Paging.PageNo = SessionData.Contacts.Filter.PageNo; model.Paging.PageNo = SessionData_Portal.Profile.Contacts.Filter.PageNo;
model.Paging.PageLength = SessionData.Contacts.Filter.PageLength; model.Paging.PageLength = SessionData_Portal.Profile.Contacts.Filter.PageLength;
return View(model); return View(model);
} }
@@ -272,7 +272,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
public static String Base64Key_OnlineApp { get; } = SacsEncryptionHelper.EncodePlainKey("{SaBusMgr=Portal-App#Encryption}", SacsEncryptionHelper.KeyLength); public static String Base64Key_OnlineApp { get; } = SacsEncryptionHelper.EncodePlainKey("{SaBusMgr=Portal-App#Encryption}", SacsEncryptionHelper.KeyLength);
protected String EncryptOnlineParams(NameValueCollection parameters) protected String EncryptOnlineParams(NameValueCollection parameters)
{ {
return HttpUtility.UrlEncode(EncryptParameters(parameters, SessionData_Portal.Base64IV_OnlineApp, Base64Key_OnlineApp)); return HttpUtility.UrlEncode(EncryptParameters(parameters, SessionData_Portal.Base64IV_PortalApp, Base64Key_OnlineApp));
} }
public static String EncryptOnlineParams(SbmController_Portal controller, NameValueCollection parameters) public static String EncryptOnlineParams(SbmController_Portal controller, NameValueCollection parameters)
{ {
@@ -280,7 +280,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
} }
protected NameValueCollection ExtractOnlineParams(String encryptedParams) protected NameValueCollection ExtractOnlineParams(String encryptedParams)
{ {
return DecryptParameters(encryptedParams, SessionData_Portal.Base64IV_OnlineApp, Base64Key_OnlineApp); return DecryptParameters(encryptedParams, SessionData_Portal.Base64IV_PortalApp, Base64Key_OnlineApp);
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -41,6 +41,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Commodity properties. // Commodity properties.
public String CommodityId { get; set; } public String CommodityId { get; set; }
public String CommodityExists { get; set; }
public String CommodityType{ get; set; } public String CommodityType{ get; set; }
public Sbm.CommodityType GetCommodityType() public Sbm.CommodityType GetCommodityType()
{ {
@@ -50,11 +51,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
public String CommodityDesc { get; set; } public String CommodityDesc { get; set; }
// Common properties. // Common properties.
public String CommodityNotes { get; set; } public String CommodityNotes { get; set; }
public String CommodityStatus { get; set; } public String CommodityStatusCode { get; set; }
public SaStatus GetCommodityStatus() public SaStatus CommodityStatus { get { return SacsSystem.GetStatusForCode(CommodityStatusCode); } }
{
return SacsSystem.GetStatusForCode(CommodityStatus);
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Validation. // Validation.
@@ -98,12 +96,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
} }
// Commodity status. // Commodity status.
if (CommodityStatus != null) if (CommodityStatusCode != null)
{ {
if (StringUtil.IsEmpty(CommodityStatus)) if (StringUtil.IsEmpty(CommodityStatusCode))
responseData.SetControlError(nameof(CommodityStatus), Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(nameof(CommodityStatusCode), Localiser["msg.validation.mandatory.value"]);
else if (!SbmCommodity.ValidStatuses.Contains(GetCommodityStatus())) else if (!SbmCommodity.ValidStatuses.Contains(CommodityStatus))
responseData.SetControlError(nameof(CommodityStatus), Localiser["msg.validation.invalid.value"]); responseData.SetControlError(nameof(CommodityStatusCode), Localiser["msg.validation.invalid.value"]);
} }
return !responseData.HasControlErrors(); return !responseData.HasControlErrors();
@@ -29,31 +29,38 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
// Filter properties. // Filter properties.
public class FilterData public class FilterData
{ {
public String AffiliateSearch { get; set; } public String ContactSearch { get; set; }
public String AffiliateType { get; set; } public String ContactType { get; set; }
} }
public FilterData Filter { get; } = new FilterData(); public FilterData Filter { get; } = new FilterData();
public Sbm.AffiliateType GetFilterAffiliateType() public Sbm.AffiliateType GetFilterContactType()
{ {
return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(Filter.AffiliateType); return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(Filter.ContactType);
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Affiliate properties. // Contact properties.
public String AffiliateId { get; set; } public String AffiliateId { get; set; }
public String AffiliateType{ get; set; } public String ContactExists { get; set; }
public Sbm.AffiliateType GetAffiliateType() public String ContactType { get; set; }
public String ContactIndividual { get; set; }
public Sbm.AffiliateType GetContactType()
{ {
return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(AffiliateType); if (ContactType != null)
return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(ContactType);
if (StringUtil.ToBool(ContactIndividual))
return Sbm.AffiliateType.Individual;
return Sbm.AffiliateType.Unknown;
} }
public String AffiliateName { get; set; } // Organisation.
public String ContactName { get; set; }
// Individual.
public String ContactFirstName { get; set; }
public String ContactLastName { get; set; }
// Common properties. // Common properties.
public String AffiliateNotes { get; set; } public String ContactNotes { get; set; }
public String AffiliateStatus { get; set; } public String ContactStatusCode { get; set; }
public SaStatus GetAffiliateStatus() public SaStatus ContactStatus { get { return SacsSystem.GetStatusForCode(ContactStatusCode); } }
{
return SacsSystem.GetStatusForCode(AffiliateStatus);
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Validation. // Validation.
@@ -62,37 +69,58 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
public bool ValidateAffiliateData(SbmController_Base.AjaxResponse_Data responseData) public bool ValidateAffiliateData(SbmController_Base.AjaxResponse_Data responseData)
{ {
// Affiliate Type. // Affiliate Type.
if (AffiliateType != null) if (ContactType != null)
{ {
if (StringUtil.IsEmpty(AffiliateType)) if (StringUtil.IsEmpty(ContactType))
responseData.SetControlError(nameof(AffiliateType), Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(nameof(ContactType), Localiser["msg.validation.mandatory.value"]);
}
bool individual = GetContactType() == Sbm.AffiliateType.Individual;
// Organisation Name.
if (ContactName != null)
{
responseData.SetControlValue(nameof(ContactName), ContactName);
if (StringUtil.IsEmpty(ContactName) && !individual)
responseData.SetControlError(nameof(ContactName), Localiser["msg.validation.mandatory.value"]);
if (StringUtil.GetLength(ContactName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name))
responseData.SetControlError(nameof(ContactName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name)]);
} }
// Affiliate Name. // Individual First Name.
if (AffiliateName != null) if (ContactFirstName != null)
{ {
responseData.SetControlValue(nameof(AffiliateName), AffiliateName); responseData.SetControlValue(nameof(ContactFirstName), ContactFirstName);
if (StringUtil.IsEmpty(AffiliateName)) if (StringUtil.IsEmpty(ContactFirstName) && individual)
responseData.SetControlError(nameof(AffiliateName), Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(nameof(ContactFirstName), Localiser["msg.validation.mandatory.value"]);
if (StringUtil.GetLength(AffiliateName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name)) if (StringUtil.GetLength(ContactFirstName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName))
responseData.SetControlError(nameof(AffiliateName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name)]); responseData.SetControlError(nameof(ContactFirstName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName)]);
}
// Individual Last Name.
if (ContactLastName != null)
{
responseData.SetControlValue(nameof(ContactLastName), ContactLastName);
if (StringUtil.IsEmpty(ContactLastName) && individual)
responseData.SetControlError(nameof(ContactLastName), Localiser["msg.validation.mandatory.value"]);
if (StringUtil.GetLength(ContactLastName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName))
responseData.SetControlError(nameof(ContactLastName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName)]);
} }
// Affiliate Notes. // Affiliate Notes.
if (AffiliateNotes != null) if (ContactNotes != null)
{ {
responseData.SetControlValue(nameof(AffiliateNotes), AffiliateNotes); responseData.SetControlValue(nameof(ContactNotes), ContactNotes);
if (!StringUtil.IsEmpty(AffiliateNotes) && StringUtil.GetLength(AffiliateNotes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes)) if (!StringUtil.IsEmpty(ContactNotes) && StringUtil.GetLength(ContactNotes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes))
responseData.SetControlError(nameof(AffiliateNotes), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes)]); responseData.SetControlError(nameof(ContactNotes), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes)]);
} }
// Affiliate status. // Affiliate status.
if (AffiliateStatus != null) if (ContactStatusCode != null)
{ {
if (StringUtil.IsEmpty(AffiliateStatus)) if (StringUtil.IsEmpty(ContactStatusCode))
responseData.SetControlError(nameof(AffiliateStatus), Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(nameof(ContactStatusCode), Localiser["msg.validation.mandatory.value"]);
else if (!SbmAffiliate.ValidStatuses.Contains(GetAffiliateStatus())) else if (!SbmAffiliate.ValidStatuses.Contains(ContactStatus))
responseData.SetControlError(nameof(AffiliateStatus), Localiser["msg.validation.invalid.value"]); responseData.SetControlError(nameof(ContactStatusCode), Localiser["msg.validation.invalid.value"]);
} }
return !responseData.HasControlErrors(); return !responseData.HasControlErrors();
@@ -5,11 +5,12 @@
ViewData["Title"] = "Commodities"; ViewData["Title"] = "Commodities";
} }
<div class="sbm-page-commodities"> <div class="sbm-panel Commodities">
<script type="text/javascript"> <script type="text/javascript">
sbm.lbl.edit = 'Edit'; sbm.lbl.refresh = '@(Localiser.GetJavascriptText("label.refresh"))';
sbm.lbl.activate = 'Activate'; sbm.lbl.create = '@(Localiser.GetJavascriptText("label.create"))';
sbm.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))';
</script> </script>
<div class="row"> <div class="row">
@@ -31,8 +32,13 @@
<partial name="~/Views/Common/ResultsPaging.cshtml" /> <partial name="~/Views/Common/ResultsPaging.cshtml" />
</div> </div>
<div class="fixed row"> <div class="fixed row">
<div class="sbm-action sbm-results-refresh"><img src="~/img/action/refresh24.png" alt="@(Localiser["label.refresh"])" title="@(Localiser["label.refresh"])" /></div> @* Burger menu *@
<div class="sbm-action sbm-item-create"><img src="~/img/action/add24.png" alt="@(Localiser["label.create"])" title="@(Localiser["label.create"])" /></div> <ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div> </div>
</div> </div>
</div> </div>
@@ -53,6 +59,15 @@
</div> </div>
</div> </div>
</div> </div>
@* Filter element templates *@
<div class="sbm-panel-item-template">
@* Burger dropdown item template - ul is ignored *@
<ul class="sbm-dropdown-menu CommodityFilter">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
</div>
</div> </div>
} }
@@ -77,7 +92,7 @@
<div class="sbm-header row"> <div class="sbm-header row">
<div class="col"> <div class="col">
@* Commodity caption *@ @* Commodity caption *@
<div class="sbm-caption"><div class="sbm-action sbm-item-update CommodityName"></div></div> <div class="sbm-caption"><div class="sbm-action sbm-item-update"><span class="CommodityCode"></span> - <span class="CommodityDesc"></span></div></div>
</div> </div>
<div class="fixed sbm-actions"> <div class="fixed sbm-actions">
@* Burger menu *@ @* Burger menu *@
@@ -8,20 +8,23 @@
sbm.dlg.title.createCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.create")'; sbm.dlg.title.createCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.create")';
sbm.dlg.title.updateCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.update")'; sbm.dlg.title.updateCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.update")';
</script> </script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityId", @class = "sbm-form" })) @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityId", @class = "sbm-form" }))
{ {
@Html.HiddenFor(model => model.CommodityId, new { @class = "CommodityId" }) @Html.HiddenFor(model => model.CommodityId, new { @class = "CommodityId" })
} }
<div id="dlgCommodity" class="sbm-dialog" title=""> <div id="dlgCommodity" class="sbm-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodity", @class = "sbm-form", @onSubmit = "return false;" })) @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodity", @class = "sbm-form", @onSubmit = "return false;" }))
{ {
@Html.HiddenFor(model => model.CommodityId, new { @id = "", @class = "CommodityId" }) @Html.HiddenFor(model => model.CommodityId, new { @id = "", @class = "CommodityId" })
@Html.HiddenFor(model => model.CommodityExists, new { @id = "", @class = "CommodityExists" });
@* Commodity Type *@ @* Commodity Type *@
<div class="sbm-form-control CommodityType"> <div class="sbm-form-control CommodityType">
<div class="sbm-label"> <div class="sbm-label">
<label for="cbCommodityType"><span><span class="required">*</span> @Localiser["label.type"]</span></label> <label for="cbCommodityType"><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.DropDownListFor(model => model.CommodityType, Model.GetCommodityTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" }) @Html.DropDownListFor(model => model.CommodityType, Model.GetCommodityTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" })
@@ -29,10 +32,10 @@
<div class="sbm-message"></div> <div class="sbm-message"></div>
</div> </div>
@* Commodity Codeription *@ @* Commodity Code *@
<div class="sbm-form-control CommodityCode"> <div class="sbm-form-control CommodityCode">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifCommodityCode"><span><span class="required">*</span> @Localiser["label.code"]</span></label> <label for="ifCommodityCode"><span>@Localiser["label.code"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.TextBoxFor(model => model.CommodityCode, new { @id = "ifCommodityCode", @class = "CommodityCode sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Code) }) @Html.TextBoxFor(model => model.CommodityCode, new { @id = "ifCommodityCode", @class = "CommodityCode sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Code) })
@@ -43,7 +46,7 @@
@* Commodity Description *@ @* Commodity Description *@
<div class="sbm-form-control CommodityDesc"> <div class="sbm-form-control CommodityDesc">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifCommodityDesc"><span><span class="required">*</span> @Localiser["label.description"]</span></label> <label for="ifCommodityDesc"><span>@Localiser["label.description"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.TextBoxFor(model => model.CommodityDesc, new { @id = "ifCommodityDesc", @class = "CommodityDesc sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_DescBrief) }) @Html.TextBoxFor(model => model.CommodityDesc, new { @id = "ifCommodityDesc", @class = "CommodityDesc sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_DescBrief) })
@@ -51,13 +54,24 @@
<div class="sbm-message"></div> <div class="sbm-message"></div>
</div> </div>
@* Commodity status *@
<div class="sbm-form-control CommodityStatus">
<div class="sbm-label">
<label for="cbCommodityStatus"><span>@Localiser["label.status"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sbm-control">
<select id="cbCommodityStatus" class="sbm-select CommodityStatus" name="CommodityStatusCode"></select>
</div>
<div class="sbm-message"></div>
</div>
@* Commodity Notes *@ @* Commodity Notes *@
<div class="sbm-form-control CommodityNotes"> <div class="sbm-form-control CommodityNotes">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifCommodityNotes"><span><span class="required">*</span> @Localiser["label.notes"]</span></label> <label for="ifCommodityNotes"><span>@Localiser["label.notes"]</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.TextAreaFor(model => model.CommodityNotes, new { @id = "ifCommodityNotes", @class = "CommodityNotes sbm-textarea", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Notes) }) @Html.TextAreaFor(model => model.CommodityNotes, new { @id = "ifCommodityNotes", @class = "CommodityNotes sbm-textarea", @rows = "3", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Notes) })
</div> </div>
<div class="sbm-message"></div> <div class="sbm-message"></div>
</div> </div>
@@ -1,15 +1,18 @@
@model Model_Contact @model Model_Contact
@inject SbmLocaliser Localiser @inject SbmLocaliser Localiser
@{ @{
/* Affiliates - Index */ /* Contacts - Index */
ViewData["Title"] = "Affiliates"; ViewData["Title"] = "Contacts";
} }
<div class="sbm-page-affiliates"> <div class="sbm-panel Contacts">
<script type="text/javascript"> <script type="text/javascript">
sbm.lbl.edit = 'Edit'; sbm.lbl.refresh = '@(Localiser.GetJavascriptText("label.refresh"))';
sbm.lbl.activate = 'Activate'; sbm.lbl.create = '@(Localiser.GetJavascriptText("label.create"))';
sbm.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))';
sbm.lbl.createOrg = '@(Localiser.GetJavascriptText("label.create.organisation"))';
sbm.lbl.createInd = '@(Localiser.GetJavascriptText("label.create.individual"))';
</script> </script>
<div class="row"> <div class="row">
@@ -19,7 +22,7 @@
<div class="col"> <div class="col">
@* Filter Panel *@ @* Filter Panel *@
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAffiliateFilter", @class = "sbm-form", @onSubmit = "return false;" })) @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmContactFilter", @class = "sbm-form", @onSubmit = "return false;" }))
{ {
<div class="sbm-panel-filter"> <div class="sbm-panel-filter">
@* Header - Page caption, paging controls, actions. *@ @* Header - Page caption, paging controls, actions. *@
@@ -31,28 +34,42 @@
<partial name="~/Views/Common/ResultsPaging.cshtml" /> <partial name="~/Views/Common/ResultsPaging.cshtml" />
</div> </div>
<div class="fixed row"> <div class="fixed row">
<div class="sbm-action sbm-results-refresh"><img src="~/img/action/refresh24.png" alt="@(Localiser["label.refresh"])" title="@(Localiser["label.refresh"])" /></div> @* Burger menu *@
<div class="sbm-action sbm-item-create"><img src="~/img/action/add24.png" alt="@(Localiser["label.create"])" title="@(Localiser["label.create"])" /></div> <ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="sbm-content"> <div class="sbm-content">
@* Affiliate filter - name etc. *@ @* Contact filter - name etc. *@
<div class="row pb4"> <div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div> <div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7"> <div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.AffiliateSearch, new { @id = "", @class = "FilterAffiliate", @maxlength = "32" }) @Html.TextBoxFor(model => model.Filter.ContactSearch, new { @id = "", @class = "FilterContact", @maxlength = "32" })
</div> </div>
</div> </div>
@* Affiliate Category *@ @* Contact type *@
<div class="row pb4"> <div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.type"]</div> <div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
<div class="col-sm-7"> <div class="col-sm-7">
@Html.DropDownListFor(model => model.Filter.AffiliateType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterAffiliateType sbm-select" }) @Html.DropDownListFor(model => model.Filter.ContactType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
</div> </div>
</div> </div>
</div> </div>
@* Filter element templates *@
<div class="sbm-panel-item-template">
@* Burger dropdown item template - ul is ignored *@
<ul class="sbm-dropdown-menu ContactFilter">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
</div>
</div> </div>
} }
@@ -72,12 +89,12 @@
@* element templates *@ @* element templates *@
<div class="sbm-panel-item-template"> <div class="sbm-panel-item-template">
@* Affiliate item template *@ @* Contact item template *@
<div class="sbm-panel-item Affiliate"> <div class="sbm-panel-item Contact">
<div class="sbm-header row"> <div class="sbm-header row">
<div class="col"> <div class="col">
@* Affiliate caption *@ @* Contact caption *@
<div class="sbm-caption"><div class="sbm-action sbm-item-update AffiliateName"></div></div> <div class="sbm-caption"><div class="sbm-action sbm-item-update ContactName"></div></div>
</div> </div>
<div class="fixed sbm-actions"> <div class="fixed sbm-actions">
@* Burger menu *@ @* Burger menu *@
@@ -91,27 +108,27 @@
</div> </div>
<div class="sbm-content"> <div class="sbm-content">
<div class="row"> <div class="row">
<div class="col-sm-4"><div class="AffiliateType"></div></div> <div class="col-sm-4"><div class="ContactType"></div></div>
<div class="col-sm-4"><div class="AffiliateAssociationCount sbm-action-text">@Localiser["label.associations"]:&nbsp;<span class="AssociationCount"></span></div></div> <div class="col-sm-4"><div class="ContactAssociationCount sbm-action-text">@Localiser["label.associations"]:&nbsp;<span class="AssociationCount"></span></div></div>
<div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div> <div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div>
</div> </div>
<div class="row"> <div class="row">
<div class=""><div class="AffiliateAddress"></div></div> <div class=""><div class="ContactAddress sbm-note"></div></div>
</div> </div>
<div class="row"> <div class="row">
<div class=""><div class="AffiliateNotes sbm-note"></div></div> <div class=""><div class="ContactNotes sbm-note"></div></div>
</div> </div>
</div> </div>
</div> </div>
@* Burger dropdown item template - ul is ignored *@ @* Burger dropdown item template - ul is ignored *@
<ul class="sbm-dropdown-menu Affiliate"> <ul class="sbm-dropdown-menu Contact">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li> <li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul> </ul>
</div> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
<partial name="Panel-AffiliateDialog.cshtml" /> <partial name="Panel-ContactDialog.cshtml" />
@@ -1,56 +0,0 @@
@model Model_Contact
@inject SbmLocaliser Localiser
@{
/* Affiliates - Affiliate dialog panel */
}
<script type="text/javascript">
sbm.dlg.title.createAffiliate = '@Localiser.GetJavascriptText("contact.caption.contact.create")';
sbm.dlg.title.updateAffiliate = '@Localiser.GetJavascriptText("contact.caption.contact.update")';
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAffiliateId", @class = "sbm-form" }))
{
@Html.HiddenFor(model => model.AffiliateId, new { @class = "AffiliateId" })
}
<div id="dlgAffiliate" class="sbm-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAffiliate", @class = "sbm-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.AffiliateId, new { @id = "", @class = "AffiliateId" })
@* Affiliate Type *@
<div class="sbm-form-control AffiliateType">
<div class="sbm-label">
<label for="cbAffiliateType"><span><span class="required">*</span> @Localiser["label.type"]</span></label>
</div>
<div class="sbm-control">
@Html.DropDownListFor(model => model.AffiliateType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbAffiliateType", @class = "AffiliateType sbm-select" })
</div>
<div class="sbm-message"></div>
</div>
@* Affiliate Organisation Name *@
<div class="sbm-form-control AffiliateName">
<div class="sbm-label">
<label for="ifAffiliateName"><span><span class="required">*</span> @Localiser["label.name"]</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.AffiliateName, new { @id = "ifAffiliateName", @class = "AffiliateName sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name) })
</div>
<div class="sbm-message"></div>
</div>
@* Affiliate Notes *@
<div class="sbm-form-control AffiliateNotes">
<div class="sbm-label">
<label for="ifAffiliateNotes"><span><span class="required">*</span> @Localiser["label.notes"]</span></label>
</div>
<div class="sbm-control">
@Html.TextAreaFor(model => model.AffiliateNotes, new { @id = "ifAffiliateNotes", @class = "AffiliateNotes sbm-textarea", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes) })
</div>
<div class="sbm-message"></div>
</div>
}
</div>
@@ -0,0 +1,80 @@
@model Model_Contact
@inject SbmLocaliser Localiser
@{
/* Contacts - Contactdialog panel */
}
<script type="text/javascript">
sbm.dlg.title.createContact = '@Localiser.GetJavascriptText("contact.caption.contact.create")';
sbm.dlg.title.updateContact = '@Localiser.GetJavascriptText("contact.caption.contact.update")';
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmContactId", @class = "sbm-form" }))
{
@Html.HiddenFor(model => model.AffiliateId, new { @class = "AffiliateId" })
}
<div id="dlgContact" class="sbm-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmContact", @class = "sbm-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.AffiliateId, new { @id = "", @class = "AffiliateId" });
@Html.HiddenFor(model => model.ContactExists, new { @id = "", @class = "ContactExists" });
@Html.HiddenFor(model => model.ContactIndividual, new { @id = "", @class = "ContactIndividual" });
@* Contact Type *@
<div class="sbm-form-control ContactType">
<div class="sbm-label">
<label for="cbContactType"><span>@Localiser["label.type"]</span><span class="required"> *</span></label>
</div>
<div class="sbm-control">
@Html.DropDownListFor(model => model.ContactType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbContactType", @class = "ContactType sbm-select" })
</div>
<div class="sbm-message"></div>
</div>
@* Contact Organisation Name *@
<div class="sbm-form-control ContactName">
<div class="sbm-label">
<label for="ifContactName"><span>@Localiser["label.name"]</span><span class="required"> *</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.ContactName, new { @id = "ifContactName", @class = "ContactName sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name) })
</div>
<div class="sbm-message"></div>
</div>
@* Contact Individual First Name *@
<div class="sbm-form-control ContactFirstName">
<div class="sbm-label">
<label for="ifContactFirstName"><span>@Localiser["label.name.first"]</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.ContactFirstName, new { @id = "ifContactFirstName", @class = "ContactFirstName sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName) })
</div>
<div class="sbm-message"></div>
</div>
@* Contact Individual Last Name *@
<div class="sbm-form-control ContactLastName">
<div class="sbm-label">
<label for="ifContactLastName"><span>@Localiser["label.name.last"]</span><span class="required"> *</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.ContactLastName, new { @id = "ifContactLastName", @class = "ContactLastName sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName) })
</div>
<div class="sbm-message"></div>
</div>
@* Contact Notes *@
<div class="sbm-form-control ContactNotes">
<div class="sbm-label">
<label for="ifContactNotes"><span>@Localiser["label.notes"]</span></label>
</div>
<div class="sbm-control">
@Html.TextAreaFor(model => model.ContactNotes, new { @id = "ifContactNotes", @class = "ContactNotes sbm-textarea", @rows = "3", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes) })
</div>
<div class="sbm-message"></div>
</div>
}
</div>
@@ -20,7 +20,7 @@
/* Current password - required when setting password within user session. */ /* Current password - required when setting password within user session. */
<div class="spacer4"></div> <div class="spacer4"></div>
<div class="sbm-form-control PasswordCurrent"> <div class="sbm-form-control PasswordCurrent">
<div class="sbm-label"><label for="ifPasswordCurrent"><span><span class="required">*</span> @Localiser["label.password.current"]</span></label></div> <div class="sbm-label"><label for="ifPasswordCurrent"><span>@Localiser["label.password.current"]</span><span class="required">&nbsp;*</span></label></div>
<div class="sbm-control"> <div class="sbm-control">
@Html.PasswordFor(model => model.PasswordCurrent, new { @id = "ifPasswordCurrent", @class = "sbm-input", @maxlength = Model.PasswordMaxLength }) @Html.PasswordFor(model => model.PasswordCurrent, new { @id = "ifPasswordCurrent", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div> </div>
@@ -35,7 +35,7 @@
<div class="spacer4"></div> <div class="spacer4"></div>
<div class="sbm-form-control Password"> <div class="sbm-form-control Password">
<div class="sbm-label"><label for="ifPassword"><span><span class="required">*</span> @Localiser["label.password"]</span></label></div> <div class="sbm-label"><label for="ifPassword"><span>@Localiser["label.password"]</span><span class="required">&nbsp;*</span></label></div>
<div class="sbm-control"> <div class="sbm-control">
@Html.PasswordFor(model => model.Password, new { @id = "ifPassword", @class = "sbm-input", @maxlength = Model.PasswordMaxLength }) @Html.PasswordFor(model => model.Password, new { @id = "ifPassword", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div> </div>
@@ -48,7 +48,7 @@
<div class="spacer4"></div> <div class="spacer4"></div>
<div class="sbm-form-control PasswordConfirm"> <div class="sbm-form-control PasswordConfirm">
<div class="sbm-label"><label for="ifPasswordConfirm"><span><span class="required">*</span> @Localiser["label.password.confirm"]</span></label></div> <div class="sbm-label"><label for="ifPasswordConfirm"><span>@Localiser["label.password.confirm"]</span><span class="required">&nbsp;*</span></label></div>
<div class="sbm-control"> <div class="sbm-control">
@Html.PasswordFor(model => model.PasswordConfirm, new { @id = "ifPasswordConfirm", @class = "sbm-input", @maxlength = Model.PasswordMaxLength }) @Html.PasswordFor(model => model.PasswordConfirm, new { @id = "ifPasswordConfirm", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div> </div>
@@ -17,7 +17,7 @@
<div class="spacer4"></div> <div class="spacer4"></div>
<div class="sbm-form-control EmailAddress"> <div class="sbm-form-control EmailAddress">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email"]</span></label> <label for="ifEmailAddress"><span>@Localiser["label.email"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = "128" }) @Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = "128" })
@@ -20,7 +20,7 @@
<div class="spacer4"></div> <div class="spacer4"></div>
<div class="sbm-form-control EmailAddress"> <div class="sbm-form-control EmailAddress">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email"]</span></label> <label for="ifEmailAddress"><span>@Localiser["label.email"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
<div class="sbm-control"> <div class="sbm-control">
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = @emailAddressLen }) @Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = @emailAddressLen })
@@ -33,7 +33,7 @@
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<div class="sbm-label"> <div class="sbm-label">
<label for="ifPassword"><span><span class="required">*</span> @Localiser["label.password"]</span></label> <label for="ifPassword"><span>@Localiser["label.password"]</span><span class="required">&nbsp;*</span></label>
</div> </div>
</div> </div>
</div> </div>
@@ -38,14 +38,15 @@
.sbm-panel-filter .sbm-header .sbm-action .sbm-panel-filter .sbm-header .sbm-action
{ {
margin: 2px 0 0 8px; margin: 2px 4px 0 8px;
border-radius: 4px; padding: 2px 4px;
border-radius: 3px;
} }
.sbm-panel-filter .sbm-header .sbm-action:hover .sbm-panel-filter .sbm-header .sbm-action:hover
{ {
background-color: #b0b0b0; background-color: #e0e0e0;
box-shadow: 0 0 4px 2px #80808080; /*box-shadow: 0 0 4px 2px #80808080;*/
} }
.sbm-panel-filter .sbm-content .sbm-panel-filter .sbm-content
@@ -85,7 +86,7 @@
.sbm-results-paging .sbm-paging-info .sbm-results-paging .sbm-paging-info
{ {
font-size: .8rem; font-size: .67rem;
} }
.sbm-panel-filter .sbm-header .sbm-results-paging .sbm-action .sbm-panel-filter .sbm-header .sbm-results-paging .sbm-action
@@ -157,7 +158,7 @@
.sbm-panel-item > .sbm-header .sbm-action .sbm-panel-item > .sbm-header .sbm-action
{ {
border-radius: 4px; border-radius: 3px;
} }
.sbm-panel-item > .sbm-header .sbm-caption .sbm-action:hover .sbm-panel-item > .sbm-header .sbm-caption .sbm-action:hover
@@ -167,13 +168,14 @@
.sbm-panel-item > .sbm-header .sbm-actions .sbm-action .sbm-panel-item > .sbm-header .sbm-actions .sbm-action
{ {
margin: 2px 0 0 8px; margin: 2px 4px 0 8px;
padding: 2px 4px;
} }
.sbm-panel-item > .sbm-header .sbm-actions .sbm-action:hover .sbm-panel-item > .sbm-header .sbm-actions .sbm-action:hover
{ {
background-color: #c0c0c0; background-color: #e0e0e0;
box-shadow: 0 0 4px 2px #c0c0c080; /*box-shadow: 0 0 4px 2px #c0c0c080;*/
} }
.sbm-panel-item > .sbm-content .sbm-panel-item > .sbm-content
@@ -94,6 +94,10 @@ body
/* Header */ /* Header */
#sbm-page-header
{
}
a.navbar-brand a.navbar-brand
{ {
white-space: normal; white-space: normal;
@@ -122,7 +126,15 @@ button.accept-policy
line-height: inherit; line-height: inherit;
} }
/* Footer */
#sbm-page-footer, #sbm-page-footer div
{
font-size: .8rem;
}
/* Page caption */ /* Page caption */
.sbm-page-caption .sbm-page-caption
{ {
margin: 0; margin: 0;
@@ -6,122 +6,136 @@
{ {
"use strict"; "use strict";
sbm.itemIdPrefix = 'Itm_'; sbm.itemIdPrefix = 'Itm_';
var $results; let $pnl = sbm.$pnl;
let $frm = sbm.$frm;
let $dlg = sbm.$dlg;
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.refreshResults = function (delay) sbm.refreshResults = function (delay)
{ {
if (!sbm.awaitingRefreshResponse) if (!sbm.awaitingRefreshResponse)
{ {
var $items = $('.sbm-panel-item-list', $results).fadeOut(200).empty(); $('.sbm-burger', $pnl.filter).hide();
var $msgs = $('.sbm-panel-messages', $results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200); $('.sbm-panel-item-list', $pnl.results).fadeOut(200).empty();
$('.sbm-panel-messages', $pnl.results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
} }
sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Commodity/Ajax/List', formId: 'frmCommodityFilter', callbackFn: sbm.doRefreshResults }; sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Commodity/Ajax/List', formId: 'frmCommodityFilter', callbackFn: sbm.doRefreshResults };
sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50); sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50);
sbm.awaitingRefreshResponse = true; sbm.awaitingRefreshResponse = true;
} }
sbm.getFilterDropdownTemplate = function ()
{
return $('.sbm-panel-item-template .sbm-dropdown-menu.CommodityFilter li.sbm-dropdown-item', $pnl.filter).clone();
}
sbm.getItemTemplate = function () sbm.getItemTemplate = function ()
{ {
return $('.sbm-panel-item-template .sbm-panel-item.Commodity', $results); return $('.sbm-panel-item-template .sbm-panel-item.Commodity', $pnl.results).clone();
} }
sbm.getDropdownItemTemplate = function () sbm.getItemDropdownTemplate = function ()
{ {
return $('.sbm-panel-item-template .sbm-dropdown-menu.Commodity li.sbm-dropdown-item', $results); return $('.sbm-panel-item-template .sbm-dropdown-menu.Commodity li.sbm-dropdown-item', $pnl.results).clone();
} }
sbm.doRefreshResults = function (response) sbm.doRefreshResults = function (response)
{ {
sbm.debug('doRefreshResults', response); //sbm.debug('doRefreshResults', response);
delete sbm.awaitingRefreshResponse; delete sbm.awaitingRefreshResponse;
sbm.refreshControlValues(response.controlValues); sbm.refreshControlValues(response.controlValues);
var $msgs = $('.sbm-panel-messages', $results).hide().empty(); var $msgs = $('.sbm-panel-messages', $pnl.results).hide().empty();
var $items = $('.sbm-panel-item-list', $results).hide().empty(); var $items = $('.sbm-panel-item-list', $pnl.results).hide().empty();
var $tmpl = sbm.getItemTemplate();
sbm.refreshPaging(response, '#frmCommodityFilter', sbm.refreshResults); sbm.refreshPaging(response, '#frmCommodityFilter', sbm.refreshResults);
if (!response.success) return; if (!response.success) return;
// Reference data - Statuses. // Reference data - Statuses.
if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode; if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode;
if (response.statuses) if (response.statuses)
sbm.populateSelectCodeDesc('#cbCommodityStatus', response.statuses); sbm.populateSelectCodeDesc('#cbCommodityStatus', response.statuses);
// Menu.
var $bgr = $('.sbm-burger', $pnl.filter).hide();
var $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.refresh, function () { sbm.refreshResults(); }));
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.create, function () { sbm.createItem(); }));
$bgr.toggle(!!$('.sbm-dropdown-item', $mnu).length);
// Items. // Items.
var items = response.commodies; var items = response.commodities;
if (!items.length) if (!items.length)
return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500); return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++) for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{ $items.append(sbm.populateItem(sbm.getItemTemplate(), items[itemIdx]));
let item = items[itemIdx];
let $item = $tmpl.clone();
sbm.populateItem($item, item);
$items.append($item);
}
$items.fadeIn(50); $items.fadeIn(50);
} }
sbm.populateItem = function ($item, item) sbm.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return;
$item.prop('id', sbm.itemIdPrefix + item.id); $item.prop('id', sbm.itemIdPrefix + item.id);
$('.CommodityName', $item).text(item.displayName); $('.CommodityCode', $item).text(item.code);
$('.CommodityDesc', $item).text(item.desc);
$('.CommodityType', $item).text(item.typeDesc); $('.CommodityType', $item).text(item.typeDesc);
$('.CommodityAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount); $('.CommodityAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount);
$('.CommodityAddress', $item).text(item.addressSummary); $('.CommodityAddress', $item).text(item.addressSummary);
$('.CommodityNotes', $item).text(item.notes); $('.CommodityNotes', $item).text(item.notes);
$('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase()); $('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase());
$('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted); $('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted);
let $mnu = $('ul.sbm-dropdown-menu', $item);
if (!item.deleted) if (!item.deleted)
{ {
let $mnu = $('ul.sbm-dropdown-menu', $item); $mnu.append(sbm.getItemMenuOption(sbm.lbl.edit, function () { sbm.updateItem(item.id) }));
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.edit).end().on('click', function () { sbm.updateItem(item.id) }));
if (item.awaiting)
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.activate).end().on('click', function () { sbm.activateItem(item.id) }));
$('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) }); $('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) });
$item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) }); $item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) });
} }
$('.sbm-burger', $item).toggle(!!$('.sbm-burger .sbm-dropdown-menu .sbm-dropdown-item', $item).length); $('.sbm-burger', $item).toggle(!!$('.sbm-dropdown-item', $mnu).length);
$('.sbm-panel-messages', $results).hide().empty(); $('.sbm-panel-messages', $pnl.results).hide().empty();
return $item; return $item;
} }
//--------------------------------------------------------------
sbm.getFilterMenuOption = function (lbl, fn)
{
return sbm.getMenuOption(sbm.getFilterDropdownTemplate(), lbl, fn);
}
sbm.getItemMenuOption = function (lbl, fn)
{
return sbm.getMenuOption(sbm.getItemDropdownTemplate(), lbl, fn);
}
sbm.getMenuOption = function ($opt, lbl, fn)
{
return $opt.find('div.sbm-label').text(lbl).end().on('click', fn);
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.createItem = function () sbm.createItem = function ()
{ {
let $frm = sbm.$frm.commodity; let frm = $frm.commodity;
$('.CommodityId,input[type="text"],textarea,select', $frm).val(''); $('.CommodityId,.CommodityExists,input[type="text"],textarea,select', frm).val('');
$('.CommodityStatus', $frm).val(sbm.data.defaultStatusCode); $('.CommodityStatus', frm).val(sbm.data.defaultStatusCode);
sbm.clearControlErrors(); sbm.clearControlErrors();
sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.createCommodity); sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.createCommodity);
sbm.openDialog(sbm.$dlg.commodity, 600, 600); sbm.openDialog(sbm.$dlg.commodity, 600, 600);
} }
sbm.doCreateItem = function ()
{
sbm.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.updateItem = function (id) sbm.updateItem = function (id)
{ {
$('.CommodityId', sbm.$frm.commodityId).val(id); $('.CommodityId', $frm.commodityId).val(id);
sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Commodity/Ajax/GetItem', formId: 'frmCommodityId', callbackFn: sbm.onUpdateItem }; sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Commodity/Ajax/GetItem', formId: 'frmCommodityId', callbackFn: sbm.onUpdateItem };
sbm.doAjaxRequest(sbm.ajax.updateItem, 50); sbm.doAjaxRequest(sbm.ajax.updateItem, 50);
} }
sbm.onUpdateItem = function (response) sbm.onUpdateItem = function (response)
{ {
//sbm.debug('onUpdateItem', response); sbm.debug('onUpdateItem', response);
let $frm = sbm.$frm.commodity; let frm = $frm.commodity;
$('.CommodityId,input[type="text"],textarea,select', $frm).val(''); $('.CommodityId,input[type="text"],textarea,select', frm).val('');
if (!response.success) return; if (!response.success) return;
let item = response.commodity; let item = response.commodity;
$('.CommodityId', $frm).val(item.id); $('.CommodityId', frm).val(item.id);
$('.CommodityType', $frm).val(item.typeCode); $('.CommodityExists', frm).val(1);
$('.CommodityName', $frm).val(item.name); $('.CommodityType', frm).val(item.typeCode);
$('.CommodityNotes', $frm).val(item.notes); $('.CommodityCode', frm).val(item.code);
$('.CommodityStatus', $frm).val(item.statusCode); $('.CommodityDesc', frm).val(item.desc);
$('.CommodityNotes', frm).val(item.notes);
$('.CommodityStatus', frm).val(item.statusCode);
sbm.clearControlErrors(); sbm.clearControlErrors();
sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.updateCommodity); sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.updateCommodity);
sbm.openDialog(sbm.$dlg.commodity, 600, 600); sbm.openDialog(sbm.$dlg.commodity, 600, 600);
} }
sbm.doUpdateItem = function ()
{
sbm.storeItem();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.storeItem = function () sbm.storeItem = function ()
@@ -140,39 +154,30 @@
var $item = $('#' + sbm.itemIdPrefix + item.id); var $item = $('#' + sbm.itemIdPrefix + item.id);
if (!$item.length) if (!$item.length)
{ {
$item = $('.sbm-panel-item-template .sbm-panel-item.Commodity', $results).clone(); $item = sbm.getItemTemplate();
$('.sbm-panel-item-list', $results).prepend($item).show(); $('.sbm-panel-item-list', $pnl.results).prepend($item).show();
} }
$item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item)); $item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item));
} }
//--------------------------------------------------------------
sbm.onClickAssociationCount = function (id)
{
if (!(id * 1)) return;
sbm.doPleaseWait();
let $frm = $('#frmCommodityId');
$('.CommodityId', $frm).val(id);
$frm.prop('action', sbm.url.base + 'Association').submit();
}
//-------------------------------------------------------------- //--------------------------------------------------------------
$(function () $(function ()
{ {
$('.sbm-panel-filter .sbm-action.sbm-item-create').on('click', function () { sbm.createItem(); }); $pnl.commodities = $('.sbm-panel.Commodities');
$('.sbm-panel-filter .sbm-action.sbm-results-refresh').on('click', function () { sbm.refreshResults(); }); $pnl.filter = $('.sbm-panel-filter', $pnl.commodities);
$pnl.results = $('.sbm-panel-results', $pnl.commodities);
$('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); }); $('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); });
$('.sbm-select').on('change', function () { sbm.clearControlError(this); }); $('.sbm-select').on('change', function () { sbm.clearControlError(this); });
sbm.$frm.filter = $('#frmCommodityFilter'); $frm.filter = $('#frmCommodityFilter');
$('.FilterCommodity', sbm.$frm.filter).on('input', function () { sbm.refreshResults(250); }); $('.FilterCommodity', $frm.filter).on('input', function () { sbm.refreshResults(250); });
$('.FilterCommodityCategory,.FilterCommodityStatusCategory', sbm.$frm.filter).on('change', function () { sbm.refreshResults(50); }); $('.FilterCommodityType,.FilterCommodityStatusCategory', $frm.filter).on('change', function () { sbm.refreshResults(50); });
sbm.$frm.commodityId = $('#frmCommodityId'); $frm.commodityId = $('#frmCommodityId');
sbm.$frm.commodity = $('#frmCommodity'); $frm.commodity = $('#frmCommodity');
$results = $('.sbm-panel-results');
var opt = sbm.dlgOpts(); var opt = sbm.dlgOpts();
opt.buttons[sbm.dlg.btn.ok] = function () { sbm.doCreateItem(); }; opt.buttons[sbm.dlg.btn.ok] = function () { sbm.storeItem(); };
opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sbm.$dlg.commodity = $('#dlgCommodity').dialog(opt); sbm.$dlg.commodity = $('#dlgCommodity').dialog(opt);
@@ -6,127 +6,152 @@
{ {
"use strict"; "use strict";
sbm.itemIdPrefix = 'Itm_'; sbm.itemIdPrefix = 'Itm_';
var $results; let $pnl = sbm.$pnl;
let $frm = sbm.$frm;
let $dlg = sbm.$dlg;
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.refreshResults = function (delay) sbm.refreshResults = function (delay)
{ {
if (!sbm.awaitingRefreshResponse) if (!sbm.awaitingRefreshResponse)
{ {
var $items = $('.sbm-panel-item-list', $results).fadeOut(200).empty(); $('.sbm-burger', $pnl.filter).hide();
var $msgs = $('.sbm-panel-messages', $results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200); $('.sbm-panel-item-list', $pnl.results).fadeOut(200).empty();
$('.sbm-panel-messages', $pnl.results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
} }
sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Contact/Ajax/List', formId: 'frmAffiliateFilter', callbackFn: sbm.doRefreshResults }; sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Contact/Ajax/List', formId: 'frmContactFilter', callbackFn: sbm.doRefreshResults };
sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50); sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50);
sbm.awaitingRefreshResponse = true; sbm.awaitingRefreshResponse = true;
} }
sbm.getFilterDropdownTemplate = function ()
{
return $('.sbm-panel-item-template .sbm-dropdown-menu.ContactFilter li.sbm-dropdown-item', $pnl.filter).clone();
}
sbm.getItemTemplate = function () sbm.getItemTemplate = function ()
{ {
return $('.sbm-panel-item-template .sbm-panel-item.Affiliate', $results); return $('.sbm-panel-item-template .sbm-panel-item.Contact', $pnl.results).clone();
} }
sbm.getDropdownItemTemplate = function () sbm.getItemDropdownTemplate = function ()
{ {
return $('.sbm-panel-item-template .sbm-dropdown-menu.Affiliate li.sbm-dropdown-item', $results); return $('.sbm-panel-item-template .sbm-dropdown-menu.Contact li.sbm-dropdown-item', $pnl.results).clone();
} }
sbm.doRefreshResults = function (response) sbm.doRefreshResults = function (response)
{ {
sbm.debug('doRefreshResults', response); //sbm.debug('doRefreshResults', response);
delete sbm.awaitingRefreshResponse; delete sbm.awaitingRefreshResponse;
sbm.refreshControlValues(response.controlValues); sbm.refreshControlValues(response.controlValues);
var $msgs = $('.sbm-panel-messages', $results).hide().empty(); var $msgs = $('.sbm-panel-messages', $pnl.results).hide().empty();
var $items = $('.sbm-panel-item-list', $results).hide().empty(); var $items = $('.sbm-panel-item-list', $pnl.results).hide().empty();
var $tmpl = sbm.getItemTemplate(); sbm.refreshPaging(response, '#frmContactFilter', sbm.refreshResults);
sbm.refreshPaging(response, '#frmAffiliateFilter', sbm.refreshResults);
if (!response.success) return; if (!response.success) return;
// Reference data - Statuses. // Reference data - Statuses.
if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode; if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode;
if (response.statuses) if (response.statuses)
sbm.populateSelectCodeDesc('#cbAffiliateStatus', response.statuses); sbm.populateSelectCodeDesc('#cbContactStatus', response.statuses);
// Menu.
var $bgr = $('.sbm-burger', $pnl.filter).hide();
var $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.refresh, function () { sbm.refreshResults(); }));
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.createOrg, function () { sbm.createItem(); }));
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.createInd, function () { sbm.createItem(1); }));
$bgr.toggle(!!$('.sbm-dropdown-item', $mnu).length);
// Items. // Items.
var items = response.affiliates; var items = response.affiliates;
if (!items.length) if (!items.length)
return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500); return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++) for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{ $items.append(sbm.populateItem(sbm.getItemTemplate(), items[itemIdx]));
let item = items[itemIdx];
let $item = $tmpl.clone();
sbm.populateItem($item, item);
$items.append($item);
}
$items.fadeIn(50); $items.fadeIn(50);
} }
sbm.populateItem = function ($item, item) sbm.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return;
$item.prop('id', sbm.itemIdPrefix + item.id); $item.prop('id', sbm.itemIdPrefix + item.id);
$('.AffiliateName', $item).text(item.displayName); $('.ContactName', $item).text(item.displayName);
$('.AffiliateType', $item).text(item.typeDesc); $('.ContactType', $item).text(item.typeDesc);
$('.AffiliateAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount); $('.ContactAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount);
$('.AffiliateAddress', $item).text(item.addressSummary); $('.ContactAddress', $item).text(item.addressSummary);
$('.AffiliateNotes', $item).text(item.notes); $('.ContactNotes', $item).text(item.notes);
$('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase()); $('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase());
$('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted); $('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted);
let $mnu = $('ul.sbm-dropdown-menu', $item).empty();
if (!item.deleted) if (!item.deleted)
{ {
let $mnu = $('ul.sbm-dropdown-menu', $item); $mnu.append(sbm.getItemMenuOption(sbm.lbl.edit, function () { sbm.updateItem(item.id) }));
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.edit).end().on('click', function () { sbm.updateItem(item.id) }));
if (item.awaiting)
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.activate).end().on('click', function () { sbm.activateItem(item.id) }));
$('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) }); $('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) });
$item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) }); $item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) });
} }
$('.sbm-burger', $item).toggle(!!$('.sbm-burger .sbm-dropdown-menu .sbm-dropdown-item', $item).length); $('.sbm-burger', $item).toggle(!!$('.sbm-dropdown-item', $mnu).length);
$('.sbm-panel-messages', $results).hide().empty(); $('.sbm-panel-messages', $pnl.results).hide().empty();
return $item; return $item;
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.createItem = function () sbm.getFilterMenuOption = function (lbl, fn)
{ {
let $frm = sbm.$frm.affiliate; return sbm.getMenuOption(sbm.getFilterDropdownTemplate(), lbl, fn);
$('.AffiliateId,input[type="text"],textarea,select', $frm).val('');
$('.AffiliateStatus', $frm).val(sbm.data.defaultStatusCode);
sbm.clearControlErrors();
sbm.$dlg.affiliate.dialog('option', 'title', sbm.dlg.title.createAffiliate);
sbm.openDialog(sbm.$dlg.affiliate, 600, 600);
} }
sbm.doCreateItem = function () sbm.getItemMenuOption = function (lbl, fn)
{ {
sbm.storeItem(); return sbm.getMenuOption(sbm.getItemDropdownTemplate(), lbl, fn);
}
sbm.getMenuOption = function ($opt, lbl, fn)
{
return $opt.find('div.sbm-label').text(lbl).end().on('click', fn);
}
//--------------------------------------------------------------
sbm.createItem = function (ind)
{
let frm = $frm.contact;
sbm.clearControlErrors(frm);
$('.AffiliateId,.ContactExists,input[type="text"],textarea,select', frm).val('');
$('.ContactIndividual', frm).val(!!ind ? 1 : null);
$('.ContactStatus', frm).val(sbm.data.defaultStatusCode);
sbm.toggleContactControls(ind);
$dlg.contact.dialog('option', 'title', sbm.dlg.title.createContact);
sbm.openDialog($dlg.contact, 600, 600);
}
sbm.toggleContactControls = function (ind)
{
let frm = $frm.contact;
$('.sbm-form-control.ContactType,.sbm-form-control.ContactName', frm).toggle(!ind).find('input,select').prop('disabled', !!ind);
$('.sbm-form-control.ContactFirstName,.sbm-form-control.ContactLastName', frm).toggle(!!ind).find('input,select').prop('disabled', !ind);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.updateItem = function (id) sbm.updateItem = function (id)
{ {
$('.AffiliateId', sbm.$frm.affiliateId).val(id); $('.AffiliateId', $frm.contactId).val(id);
sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Contact/Ajax/GetItem', formId: 'frmAffiliateId', callbackFn: sbm.onUpdateItem }; sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Contact/Ajax/GetItem', formId: 'frmContactId', callbackFn: sbm.onUpdateItem };
sbm.doAjaxRequest(sbm.ajax.updateItem, 50); sbm.doAjaxRequest(sbm.ajax.updateItem, 50);
} }
sbm.onUpdateItem = function (response) sbm.onUpdateItem = function (response)
{ {
//sbm.debug('onUpdateItem', response); //sbm.debug('onUpdateItem', response);
let $frm = sbm.$frm.affiliate; let frm = $frm.contact;
$('.AffiliateId,input[type="text"],textarea,select', $frm).val(''); $('.AffiliateId,input[type="text"],textarea,select', frm).val('');
if (!response.success) return; if (!response.success) return;
let item = response.affiliate; let item = response.affiliate;
$('.AffiliateId', $frm).val(item.id); sbm.toggleContactControls(item.individual);
$('.AffiliateType', $frm).val(item.typeCode); $('.AffiliateId', frm).val(item.id);
$('.AffiliateName', $frm).val(item.name); $('.ContactExists', frm).val(1);
$('.AffiliateNotes', $frm).val(item.notes); $('.ContactIndividual', frm).val(!!item.individual ? 1 : null);
$('.AffiliateStatus', $frm).val(item.statusCode); $('.ContactType', frm).val(item.typeCode);
$('.ContactName', frm).val(item.name);
$('.ContactFirstName', frm).val(item.firstName);
$('.ContactLastName', frm).val(item.lastName);
$('.ContactNotes', frm).val(item.notes);
$('.ContactStatus', frm).val(item.statusCode);
sbm.clearControlErrors(); sbm.clearControlErrors();
sbm.$dlg.affiliate.dialog('option', 'title', sbm.dlg.title.updateAffiliate); $dlg.contact.dialog('option', 'title', sbm.dlg.title.updateContact);
sbm.openDialog(sbm.$dlg.affiliate, 600, 600); sbm.openDialog($dlg.contact, 600, 600);
}
sbm.doUpdateItem = function ()
{
sbm.storeItem();
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
sbm.storeItem = function () sbm.storeItem = function ()
{ {
sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Contact/Ajax/StoreItem', formId: 'frmAffiliate', callbackFn: sbm.onStoreItem }; sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Contact/Ajax/StoreItem', formId: 'frmContact', callbackFn: sbm.onStoreItem };
sbm.doAjaxRequest(sbm.ajax.storeItem, 50); sbm.doAjaxRequest(sbm.ajax.storeItem, 50);
} }
sbm.onStoreItem = function (response) sbm.onStoreItem = function (response)
@@ -134,14 +159,14 @@
//sbm.debug('onStoreItem', response); //sbm.debug('onStoreItem', response);
sbm.refreshControlValues(response.controlValues); sbm.refreshControlValues(response.controlValues);
if (!response.success) return; if (!response.success) return;
sbm.$dlg.affiliate.dialog('close'); $dlg.contact.dialog('close');
var item = response.affiliate; var item = response.affiliate;
var $item = $('#' + sbm.itemIdPrefix + item.id); var $item = $('#' + sbm.itemIdPrefix + item.id);
if (!$item.length) if (!$item.length)
{ {
$item = $('.sbm-panel-item-template .sbm-panel-item.Affiliate', $results).clone(); $item = sbm.getItemTemplate();
$('.sbm-panel-item-list', $results).prepend($item).show(); $('.sbm-panel-item-list', $pnl.results).prepend($item).show();
} }
$item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item)); $item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item));
} }
@@ -151,30 +176,31 @@
{ {
if (!(id * 1)) return; if (!(id * 1)) return;
sbm.doPleaseWait(); sbm.doPleaseWait();
let $frm = $('#frmAffiliateId'); let frm = $frm.contactId;
$('.AffiliateId', $frm).val(id); $('.AffiliateId', frm).val(id);
$frm.prop('action', sbm.url.base + 'Association').submit(); frm.prop('action', sbm.url.base + 'Association').submit();
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
$(function () $(function ()
{ {
$('.sbm-panel-filter .sbm-action.sbm-item-create').on('click', function () { sbm.createItem(); }); $pnl.contacts = $('.sbm-panel.Contacts');
$('.sbm-panel-filter .sbm-action.sbm-results-refresh').on('click', function () { sbm.refreshResults(); }); $pnl.filter = $('.sbm-panel-filter', $pnl.contacts);
$pnl.results = $('.sbm-panel-results', $pnl.contacts);
$('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); }); $('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); });
$('.sbm-select').on('change', function () { sbm.clearControlError(this); }); $('.sbm-select').on('change', function () { sbm.clearControlError(this); });
sbm.$frm.filter = $('#frmAffiliateFilter'); $frm.filter = $('#frmContactFilter');
$('.FilterAffiliate', sbm.$frm.filter).on('input', function () { sbm.refreshResults(250); }); $('.FilterContact', $frm.filter).on('input', function () { sbm.refreshResults(250); });
$('.FilterAffiliateCategory,.FilterAffiliateStatusCategory', sbm.$frm.filter).on('change', function () { sbm.refreshResults(50); }); $('.FilterContactType', $frm.filter).on('change', function () { sbm.refreshResults(50); });
sbm.$frm.affiliateId = $('#frmAffiliateId'); $frm.contactId = $('#frmContactId');
sbm.$frm.affiliate = $('#frmAffiliate'); $frm.contact = $('#frmContact');
$results = $('.sbm-panel-results');
var opt = sbm.dlgOpts(); var opt = sbm.dlgOpts();
opt.buttons[sbm.dlg.btn.ok] = function () { sbm.doCreateItem(); }; opt.buttons[sbm.dlg.btn.ok] = function () { sbm.storeItem(); };
opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sbm.$dlg.affiliate = $('#dlgAffiliate').dialog(opt); $dlg.contact = $('#dlgContact').dialog(opt);
setTimeout(sbm.refreshResults, 250); setTimeout(sbm.refreshResults, 250);
}); });
@@ -264,7 +264,7 @@
//sbm.debug(sbm.topMargin($bdy)); //sbm.debug(sbm.topMargin($bdy));
var fbr = $bdy[0].getBoundingClientRect(); var fbr = $bdy[0].getBoundingClientRect();
var fn = function () { $hdr.delay(2000).animate({ backgroundColor: '#f0f0f0' }, 1000); }; var fn = function () { $hdr.delay(2000).animate({ backgroundColor: '#f0f0f0' }, 1000); };
$not.css({ 'top': Math.max(0, fbr.top - sbm.topMargin($bdy)), 'right': $win.width() - fbr.right }).slideDown(500, fn); $not.css({ 'top': Math.max(0, fbr.top /*- sbm.topMargin($bdy)*/), 'right': $win.width() - fbr.right }).slideDown(500, fn);
sbm.toNotification = setTimeout(sbm.hideNotification, 6000); sbm.toNotification = setTimeout(sbm.hideNotification, 6000);
} }
sbm.hideNotification = function () sbm.hideNotification = function ()