Contacts page.
@@ -33,6 +33,19 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// 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();
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|||||||
@@ -380,6 +380,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
return Json(responseData);
|
return Json(responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Base Ajax Response Data.
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public class AjaxResponse_Base
|
public class AjaxResponse_Base
|
||||||
{
|
{
|
||||||
@@ -418,13 +420,30 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Ajax Response Data.
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public class AjaxResponse_Data : AjaxResponse_Base
|
public class AjaxResponse_Data : AjaxResponse_Base
|
||||||
{
|
{
|
||||||
|
//---------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
protected AjaxResponse_Data(SbmModel_Base model)
|
protected AjaxResponse_Data(SbmModel_Base model)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
public class ItemData
|
||||||
|
{
|
||||||
|
public String Id { get; set; }
|
||||||
|
public String Notes { get; set; }
|
||||||
|
public String StatusCode { get; set; }
|
||||||
|
public String StatusDesc { get; set; }
|
||||||
|
public Boolean Awaiting { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Awaiting)); } }
|
||||||
|
public Boolean Active { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)); } }
|
||||||
|
public Boolean Deleted { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Deleted)); } }
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
// Form data.
|
// Form data.
|
||||||
public class FormControlValue
|
public class FormControlValue
|
||||||
{
|
{
|
||||||
@@ -477,6 +496,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
// Notification - briefly displays after response received.
|
// Notification - briefly displays after response received.
|
||||||
public class NotificationData
|
public class NotificationData
|
||||||
{
|
{
|
||||||
@@ -490,6 +511,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
Notification = new NotificationData() { Title = title, Message = message };
|
Notification = new NotificationData() { Title = title, Message = message };
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
// Paged data.
|
// Paged data.
|
||||||
public class PagingData
|
public class PagingData
|
||||||
{
|
{
|
||||||
@@ -515,6 +538,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
{
|
{
|
||||||
Paging = new PagingData(model);
|
Paging = new PagingData(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
|||||||
@@ -111,8 +111,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
|||||||
{
|
{
|
||||||
if (!systemCodeCache.ContainsKey(systemCode))
|
if (!systemCodeCache.ContainsKey(systemCode))
|
||||||
systemCodeCache.Add(systemCode, SbmSystem.GetCodesOfType(UserContext, systemCode));
|
systemCodeCache.Add(systemCode, SbmSystem.GetCodesOfType(UserContext, systemCode));
|
||||||
return systemCodeCache.GetValueOrDefault(systemCode, new List<TypeCodeDesc>());
|
return new List<TypeCodeDesc>(systemCodeCache.GetValueOrDefault(systemCode, new List<TypeCodeDesc>()));
|
||||||
}
|
}
|
||||||
|
public List<TypeCodeDesc> AffiliateTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AffiliateType); } }
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Managers.
|
// Managers.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
using Newtonsoft.Json;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||||
using Sarand.Net.Standard.Base.App;
|
using Sarand.Net.Standard.Base.App;
|
||||||
using Sarand.Net.Standard.Base.Bus;
|
using Sarand.Net.Standard.Base.Bus;
|
||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
@@ -35,6 +36,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Properties.
|
// Properties.
|
||||||
|
[JsonIgnore]
|
||||||
public SbmUserContext UserContext { get; }
|
public SbmUserContext UserContext { get; }
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Sarand.Net.Standard.Base.App;
|
using Newtonsoft.Json;
|
||||||
|
using Sarand.Net.Standard.Base.App;
|
||||||
|
|
||||||
namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||||
{
|
{
|
||||||
@@ -7,6 +8,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
|||||||
{
|
{
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
|
[JsonConstructor]
|
||||||
protected SbmSessionContext(ushort index, Sbm.Application application) : base(index)
|
protected SbmSessionContext(ushort index, Sbm.Application application) : base(index)
|
||||||
{
|
{
|
||||||
Index = index;
|
Index = index;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
|||||||
Pos,
|
Pos,
|
||||||
Id,
|
Id,
|
||||||
// Affiliate.
|
// Affiliate.
|
||||||
|
Type,
|
||||||
|
Type_Code,
|
||||||
Type_Desc,
|
Type_Desc,
|
||||||
Name,
|
Name,
|
||||||
Abbrev,
|
Abbrev,
|
||||||
@@ -734,7 +736,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
|||||||
// List parameters.
|
// List parameters.
|
||||||
public enum StatusCat
|
public enum StatusCat
|
||||||
{
|
{
|
||||||
Any, ActiveOnly,
|
Any,
|
||||||
|
CurrentOnly,
|
||||||
|
OnHoldOnly,
|
||||||
|
NotDeleted,
|
||||||
|
DeletedOnly,
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Item list parameters.
|
/// Item list parameters.
|
||||||
@@ -748,6 +754,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
|||||||
public Sbm.AffiliateType AffiliateType { get; set; } = Sbm.AffiliateType.Any;
|
public Sbm.AffiliateType AffiliateType { get; set; } = Sbm.AffiliateType.Any;
|
||||||
public SysId AffiliateIdParent { get; set; }
|
public SysId AffiliateIdParent { get; set; }
|
||||||
public SysId UserId { get; set; }
|
public SysId UserId { get; set; }
|
||||||
|
/// <summary>Generic search value - name, phone, website, address etc.</summary>
|
||||||
|
public String Search { get; set; }
|
||||||
public String Name { get; set; }
|
public String Name { get; set; }
|
||||||
public String NamePartial { get; set; }
|
public String NamePartial { get; set; }
|
||||||
public String PhonePartial { get; set; }
|
public String PhonePartial { get; set; }
|
||||||
|
|||||||
@@ -378,10 +378,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
|
|||||||
switch ((SbmAffiliate.Column)column.Id)
|
switch ((SbmAffiliate.Column)column.Id)
|
||||||
{
|
{
|
||||||
// Affiliate type description.
|
// Affiliate type description.
|
||||||
|
case SbmAffiliate.Column.Type_Code:
|
||||||
case SbmAffiliate.Column.Type_Desc:
|
case SbmAffiliate.Column.Type_Desc:
|
||||||
{
|
{
|
||||||
Sbm.AffiliateType affiliateType = (Sbm.AffiliateType)values.GetValue(column.DataName).AsLong();
|
Sbm.AffiliateType affiliateType = (Sbm.AffiliateType)values.GetValue(column.DataName).AsLong();
|
||||||
|
if (column.Id == (int)SbmAffiliate.Column.Type_Desc)
|
||||||
value = new DataValue(AffiliateTypes.GetDescForType(affiliateType, affiliateType.ToString()));
|
value = new DataValue(AffiliateTypes.GetDescForType(affiliateType, affiliateType.ToString()));
|
||||||
|
else value = new DataValue(AffiliateTypes.GetCodeForType(affiliateType, affiliateType.ToString()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<div class="sax-email-header">
|
|
||||||
<div class="sax-content">Email Footer</div>
|
|
||||||
</div>
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
<div class="sax-para">Follow <span style="font-weight:bold;"><a href="[#Link.RequestPassword]">this link</a></span> to set a new password against your account.</div>
|
<div class="sax-para">Follow <span style="font-weight:bold;"><a href="[#Link.RequestPassword]">this link</a></span> to set a new password against your account.</div>
|
||||||
<div class="sax-para">This link will expire in [#Link.ExpiresMinutes] minutes.</div>
|
<div class="sax-para">This link will expire in [#Link.ExpiresMinutes] minutes.</div>
|
||||||
<div class="sax-para">Thank you.</div>
|
<div class="sax-para">Thank you.</div>
|
||||||
|
<div class="sax-para">Sarand BusinessMgr team</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
[#Email.Footer]
|
[#Email.Footer]
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="sax-email-footer">
|
||||||
|
<div class="sax-content"></div>
|
||||||
|
</div>
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
body
|
html
|
||||||
|
{
|
||||||
|
font-size:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body
|
||||||
{
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: Verdana, Helvetica, Arial, sans-serif;
|
font-family: Verdana, Helvetica, Arial, sans-serif;
|
||||||
font-size: 16px;
|
font-size: 1.6rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
@@ -32,6 +37,7 @@ td
|
|||||||
|
|
||||||
.sax-email-header .sax-content
|
.sax-email-header .sax-content
|
||||||
{
|
{
|
||||||
|
font-size:2.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sax-email-body
|
.sax-email-body
|
||||||
@@ -41,7 +47,7 @@ td
|
|||||||
.sax-email-panel-caption
|
.sax-email-panel-caption
|
||||||
{
|
{
|
||||||
margin: 12px 0;
|
margin: 12px 0;
|
||||||
font-size: 40px;
|
font-size: 3.2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #000;
|
color: #000;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@@ -60,7 +66,7 @@ td
|
|||||||
td.sax-label
|
td.sax-label
|
||||||
{
|
{
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
font-size: 16px;
|
font-size: 1.6rem;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
color: #808080;
|
color: #808080;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -69,7 +75,7 @@ td.sax-label
|
|||||||
td.sax-value
|
td.sax-value
|
||||||
{
|
{
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
font-size: 16px;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sax-email-footer
|
.sax-email-footer
|
||||||
@@ -81,6 +87,7 @@ td.sax-value
|
|||||||
.sax-email-footer .sax-content
|
.sax-email-footer .sax-content
|
||||||
{
|
{
|
||||||
padding:12px 24px;
|
padding:12px 24px;
|
||||||
|
font-size:1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sax-email-footer .sax-content .sax-footer-lower
|
.sax-email-footer .sax-content .sax-footer-lower
|
||||||
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
|
Before Width: | Height: | Size: 287 B After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 774 B |
@@ -14,4 +14,8 @@
|
|||||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Resources\**\*.*" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -398,12 +398,18 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
columnDfn.ReadOnly = true;
|
columnDfn.ReadOnly = true;
|
||||||
break;
|
break;
|
||||||
// Affiliate Properties.
|
// Affiliate Properties.
|
||||||
|
case SbmAffiliate.Column.Type:
|
||||||
|
SetAffiliateColDfn(columnDfn, "Type", 60, SbmDbDfn.ColumnIdx.Affiliate_Type, ColumnAlignment.Center, DataValue.DataType.Long);
|
||||||
|
break;
|
||||||
|
case SbmAffiliate.Column.Type_Code:
|
||||||
|
SetAffiliateColDfn(columnDfn, "Type", 70, SbmDbDfn.ColumnIdx.Affiliate_Type, ColumnAlignment.Center);
|
||||||
|
break;
|
||||||
case SbmAffiliate.Column.Type_Desc:
|
case SbmAffiliate.Column.Type_Desc:
|
||||||
SetAffiliateColDfn(columnDfn, "Type", 70, SbmDbDfn.ColumnIdx.Affiliate_Type);
|
SetAffiliateColDfn(columnDfn, "Type", 80, SbmDbDfn.ColumnIdx.Affiliate_Type, ColumnAlignment.Center);
|
||||||
break;
|
break;
|
||||||
case SbmAffiliate.Column.Name:
|
case SbmAffiliate.Column.Name:
|
||||||
SetAffiliateColDfn(columnDfn, "Name", 160, SbmDbDfn.ColumnIdx.Affiliate_Name);
|
SetAffiliateColDfn(columnDfn, "Name", 160, SbmDbDfn.ColumnIdx.Affiliate_Name);
|
||||||
break;/*
|
break;
|
||||||
case SbmAffiliate.Column.Abbrev:
|
case SbmAffiliate.Column.Abbrev:
|
||||||
SetAffiliateColDfn(columnDfn, "Abbrev", 90, SbmDbDfn.ColumnIdx.Affiliate_Abbrev);
|
SetAffiliateColDfn(columnDfn, "Abbrev", 90, SbmDbDfn.ColumnIdx.Affiliate_Abbrev);
|
||||||
break;
|
break;
|
||||||
@@ -421,16 +427,16 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
break;
|
break;
|
||||||
case SbmAffiliate.Column.Salutation:
|
case SbmAffiliate.Column.Salutation:
|
||||||
SetAffiliateColDfn(columnDfn, "Salutation", 50, SbmDbDfn.ColumnIdx.Affiliate_Salutation);
|
SetAffiliateColDfn(columnDfn, "Salutation", 50, SbmDbDfn.ColumnIdx.Affiliate_Salutation);
|
||||||
break;*/
|
break;
|
||||||
case SbmAffiliate.Column.Nature:
|
case SbmAffiliate.Column.Nature:
|
||||||
SetAffiliateColDfn(columnDfn, "Nature", 120, SbmDbDfn.ColumnIdx.Affiliate_Nature);
|
SetAffiliateColDfn(columnDfn, "Nature", 120, SbmDbDfn.ColumnIdx.Affiliate_Nature);
|
||||||
break;/*
|
break;
|
||||||
case SbmAffiliate.Column.CompanyNo:
|
case SbmAffiliate.Column.CompanyNo:
|
||||||
SetAffiliateColDfn(columnDfn, "CompanyNo", 50, SbmDbDfn.ColumnIdx.Affiliate_CompanyNo);
|
SetAffiliateColDfn(columnDfn, "CompanyNo", 50, SbmDbDfn.ColumnIdx.Affiliate_CompanyNo);
|
||||||
break;
|
break;
|
||||||
case SbmAffiliate.Column.VatReg:
|
case SbmAffiliate.Column.VatReg:
|
||||||
SetAffiliateColDfn(columnDfn, "VatReg", 80, SbmDbDfn.ColumnIdx.Affiliate_VatReg);
|
SetAffiliateColDfn(columnDfn, "VatReg", 80, SbmDbDfn.ColumnIdx.Affiliate_VatReg);
|
||||||
break;*/
|
break;
|
||||||
case SbmAffiliate.Column.Contact:
|
case SbmAffiliate.Column.Contact:
|
||||||
SetAffiliateColDfn(columnDfn, "Contact", 120, SbmDbDfn.ColumnIdx.Affiliate_Contact);
|
SetAffiliateColDfn(columnDfn, "Contact", 120, SbmDbDfn.ColumnIdx.Affiliate_Contact);
|
||||||
break;
|
break;
|
||||||
@@ -486,12 +492,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
case SbmAffiliate.Column.Address_Postcode:
|
case SbmAffiliate.Column.Address_Postcode:
|
||||||
SetAffiliateColDfn(columnDfn, "Postcode", 65, SbmDbDfn.ColumnIdx.Address_Postcode, ColumnAlignment.Center, DataValue.DataType.String, aliasAffiliate_AddPrim, prefixAffiliate_AddPrim);
|
SetAffiliateColDfn(columnDfn, "Postcode", 65, SbmDbDfn.ColumnIdx.Address_Postcode, ColumnAlignment.Center, DataValue.DataType.String, aliasAffiliate_AddPrim, prefixAffiliate_AddPrim);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
// Derived columns.
|
// Derived columns.
|
||||||
case SbmAffiliate.Column.GroupMembers:
|
case SbmAffiliate.Column.GroupMembers:
|
||||||
SetAffiliateColDfn(columnDfn, "Members", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
SetAffiliateColDfn(columnDfn, "Members", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||||
columnDfn.DataName = colNameAffiliate_GroupMembers;
|
columnDfn.DataName = colNameAffiliate_GroupMembers;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
// Common properties.
|
// Common properties.
|
||||||
case SbmAffiliate.Column.Notes:
|
case SbmAffiliate.Column.Notes:
|
||||||
@@ -556,38 +564,60 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
filter.Add(colAffiliate_AffIdParent + "=" + SysId.ToString(prm.AffiliateIdParent));
|
filter.Add(colAffiliate_AffIdParent + "=" + SysId.ToString(prm.AffiliateIdParent));
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Name.
|
// Common columns.
|
||||||
String colAffiliate_Name = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliate);
|
String colAffiliate_Name = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliate);
|
||||||
|
String colAffiliate_FirstName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_FirstName, aliasAffiliate);
|
||||||
|
String colAffiliate_LastName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_LastName, aliasAffiliate);
|
||||||
|
String colAffiliate_PhoneMain = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneMain, aliasAffiliate);
|
||||||
|
String colAffiliate_PhoneAlt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneAlt, aliasAffiliate);
|
||||||
|
String colAffiliate_PhoneFax = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneFax);
|
||||||
|
String colAffiliate_PhoneMobile = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneMobile);
|
||||||
|
String colAffiliate_PhoneDirect = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneDirect);
|
||||||
|
String colAffiliate_Website = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Website, aliasAffiliate);
|
||||||
|
String colAffiliate_Email = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Email, aliasAffiliate);
|
||||||
|
String colAffiliate_Notes = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Notes, aliasAffiliate);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
// Generic search.
|
||||||
|
if (!StringUtil.IsEmpty(prm.Search))
|
||||||
|
{
|
||||||
|
List<String> searchFilter = new List<string>();
|
||||||
|
foreach (String rawSearchValue in prm.Search.Split(new char[] { ' ', ',', ';' }))
|
||||||
|
{
|
||||||
|
String searchValue = DbQuery.FormatForLike(StringUtil.TrimAll(rawSearchValue));
|
||||||
|
if (StringUtil.IsEmpty(searchValue)) continue;
|
||||||
|
List<String> searchValueFilter = new List<string>();
|
||||||
|
searchValueFilter.Add(colAffiliate_Name + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_FirstName + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_LastName + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_PhoneMain + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_PhoneAlt + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_Website + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_Email + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchValueFilter.Add(colAffiliate_Notes + " LIKE '%" + searchValue + "%'");
|
||||||
|
searchFilter.Add(searchValueFilter.Concat(" OR ", "(", ")"));
|
||||||
|
}
|
||||||
|
filter.AddRange(searchFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
// Name.
|
||||||
if (!StringUtil.IsEmpty(prm.Name))
|
if (!StringUtil.IsEmpty(prm.Name))
|
||||||
filter.Add(colAffiliate_Name + "='" + DbQuery.FormatForCondition(prm.Name) + "'");
|
filter.Add(colAffiliate_Name + "='" + DbQuery.FormatForCondition(prm.Name) + "'");
|
||||||
// Partial Name with FirstName & LastName.
|
// Partial Name with FirstName & LastName.
|
||||||
String colAffiliate_FirstName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_FirstName, aliasAffiliate);
|
|
||||||
String colAffiliate_LastName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_LastName, aliasAffiliate);
|
|
||||||
if (!StringUtil.IsEmpty(prm.NamePartial))
|
if (!StringUtil.IsEmpty(prm.NamePartial))
|
||||||
filter.Add(colAffiliate_Name + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_FirstName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_LastName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%'");
|
filter.Add(colAffiliate_Name + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_FirstName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_LastName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%'");
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
|
||||||
// Partial Email.
|
// Partial Email.
|
||||||
String colAffiliate_Email = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Email, aliasAffiliate);
|
|
||||||
if (!StringUtil.IsEmpty(prm.EmailPartial))
|
if (!StringUtil.IsEmpty(prm.EmailPartial))
|
||||||
filter.Add(colAffiliate_Email + " LIKE '%" + DbQuery.FormatForLike(prm.EmailPartial) + "%'");
|
filter.Add(colAffiliate_Email + " LIKE '%" + DbQuery.FormatForLike(prm.EmailPartial) + "%'");
|
||||||
|
|
||||||
// Partial Notes.
|
|
||||||
String colAffiliate_Notes = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Notes, aliasAffiliate);
|
|
||||||
if (!StringUtil.IsEmpty(prm.EmailPartial))
|
|
||||||
filter.Add(colAffiliate_Notes + " LIKE '%" + DbQuery.FormatForLike(prm.NotesPartial) + "%'");
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Partial Phone - type of phone number held against addresses.
|
// Partial Phone - type of phone number held against addresses.
|
||||||
if (!StringUtil.IsEmpty(prm.PhonePartial))
|
if (!StringUtil.IsEmpty(prm.PhonePartial))
|
||||||
{
|
{
|
||||||
// Search for matches in any of the phone numbers associated with the affiliate.
|
// Search for matches in any of the phone numbers associated with the affiliate.
|
||||||
String aliasAffAddPhone = "aAffAddPhone";
|
String aliasAffAddPhone = "aAffAddPhone";
|
||||||
String colAffiliate_PhoneMain = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneMain);
|
|
||||||
String colAffiliate_PhoneAlt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneAlt);
|
|
||||||
String colAffiliate_PhoneFax = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneFax);
|
|
||||||
String colAffiliate_PhoneMobile = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneMobile);
|
|
||||||
String colAffiliate_PhoneDirect = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_PhoneDirect);
|
|
||||||
String colAddress_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Id, aliasAffAddPhone);
|
String colAddress_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Id, aliasAffAddPhone);
|
||||||
String colAddress_Owner = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_AffIdOwner, aliasAffAddPhone);
|
String colAddress_Owner = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_AffIdOwner, aliasAffAddPhone);
|
||||||
String colAddress_Phone = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Phone, aliasAffAddPhone);
|
String colAddress_Phone = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Phone, aliasAffAddPhone);
|
||||||
@@ -746,9 +776,21 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
// Common properties.
|
||||||
|
|
||||||
|
// Partial Notes.
|
||||||
|
if (!StringUtil.IsEmpty(prm.EmailPartial))
|
||||||
|
filter.Add(colAffiliate_Notes + " LIKE '%" + DbQuery.FormatForLike(prm.NotesPartial) + "%'");
|
||||||
|
|
||||||
// Status.
|
// Status.
|
||||||
if (prm.StatusCat == SbmAffiliate.StatusCat.ActiveOnly)
|
if (prm.StatusCat == SbmAffiliate.StatusCat.CurrentOnly)
|
||||||
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + " = '" + StatusActive + "'");
|
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + StatusCurrent + "'");
|
||||||
|
else if (prm.StatusCat == SbmAffiliate.StatusCat.OnHoldOnly)
|
||||||
|
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + SacsSystem.GetStatusCode(SaStatus.OnHold) + "'");
|
||||||
|
else if (prm.StatusCat == SbmAffiliate.StatusCat.NotDeleted)
|
||||||
|
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "!='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'");
|
||||||
|
else if (prm.StatusCat == SbmAffiliate.StatusCat.DeletedOnly)
|
||||||
|
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'");
|
||||||
|
|
||||||
if (filter.Count < 1 && prm.IncludeDefaultFilter) filter.Add("1=1");
|
if (filter.Count < 1 && prm.IncludeDefaultFilter) filter.Add("1=1");
|
||||||
return filter;
|
return filter;
|
||||||
@@ -868,7 +910,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
// Affiliate Properties - add columns as defined in query list.
|
// Affiliate Properties - add columns as defined in query list.
|
||||||
if (columns.HasId((int)SbmAffiliate.Column.Id))
|
if (columns.HasId((int)SbmAffiliate.Column.Id))
|
||||||
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate));
|
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate));
|
||||||
if (columns.HasId((int)SbmAffiliate.Column.Type_Desc))
|
if (columns.HasId((int)SbmAffiliate.Column.Type) || columns.HasId((int)SbmAffiliate.Column.Type_Code) || columns.HasId((int)SbmAffiliate.Column.Type_Desc))
|
||||||
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Type, aliasAffiliate));
|
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Type, aliasAffiliate));
|
||||||
if (columns.HasId((int)SbmAffiliate.Column.Name))
|
if (columns.HasId((int)SbmAffiliate.Column.Name))
|
||||||
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliate));
|
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliate));
|
||||||
|
|||||||
@@ -117,6 +117,21 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="contact.caption.contact" xml:space="preserve">
|
||||||
|
<value>Contact</value>
|
||||||
|
</data>
|
||||||
|
<data name="contact.caption.contact.create" xml:space="preserve">
|
||||||
|
<value>Add Contact</value>
|
||||||
|
</data>
|
||||||
|
<data name="contact.caption.contact.update" xml:space="preserve">
|
||||||
|
<value>Update Contact</value>
|
||||||
|
</data>
|
||||||
|
<data name="contact.caption.contacts" xml:space="preserve">
|
||||||
|
<value>Contacts</value>
|
||||||
|
</data>
|
||||||
|
<data name="copyright.symbol.year.html" xml:space="preserve">
|
||||||
|
<value>&copy; {0}</value>
|
||||||
|
</data>
|
||||||
<data name="dialog.title.alert" xml:space="preserve">
|
<data name="dialog.title.alert" xml:space="preserve">
|
||||||
<value>Alert</value>
|
<value>Alert</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -126,12 +141,21 @@
|
|||||||
<data name="dialog.title.progress" xml:space="preserve">
|
<data name="dialog.title.progress" xml:space="preserve">
|
||||||
<value>Progress</value>
|
<value>Progress</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.any" xml:space="preserve">
|
||||||
|
<value>Any</value>
|
||||||
|
</data>
|
||||||
|
<data name="label.associations" xml:space="preserve">
|
||||||
|
<value>Associations</value>
|
||||||
|
</data>
|
||||||
<data name="label.calendar" xml:space="preserve">
|
<data name="label.calendar" xml:space="preserve">
|
||||||
<value>Calendar</value>
|
<value>Calendar</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="label.cancel" xml:space="preserve">
|
<data name="label.cancel" xml:space="preserve">
|
||||||
<value>Cancel</value>
|
<value>Cancel</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.category" xml:space="preserve">
|
||||||
|
<value>Category</value>
|
||||||
|
</data>
|
||||||
<data name="label.change.password" xml:space="preserve">
|
<data name="label.change.password" xml:space="preserve">
|
||||||
<value>Change Password</value>
|
<value>Change Password</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -153,9 +177,15 @@
|
|||||||
<data name="label.contacts" xml:space="preserve">
|
<data name="label.contacts" xml:space="preserve">
|
||||||
<value>Contacts</value>
|
<value>Contacts</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.create" xml:space="preserve">
|
||||||
|
<value>Create</value>
|
||||||
|
</data>
|
||||||
<data name="label.email" xml:space="preserve">
|
<data name="label.email" xml:space="preserve">
|
||||||
<value>Email</value>
|
<value>Email</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.first" xml:space="preserve">
|
||||||
|
<value>First</value>
|
||||||
|
</data>
|
||||||
<data name="label.forgotten.password" xml:space="preserve">
|
<data name="label.forgotten.password" xml:space="preserve">
|
||||||
<value>Forgotten password?</value>
|
<value>Forgotten password?</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -165,24 +195,48 @@
|
|||||||
<data name="label.keep.signed.in" xml:space="preserve">
|
<data name="label.keep.signed.in" xml:space="preserve">
|
||||||
<value>Remember Me</value>
|
<value>Remember Me</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.last" xml:space="preserve">
|
||||||
|
<value>Last</value>
|
||||||
|
</data>
|
||||||
<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.next" xml:space="preserve">
|
||||||
|
<value>Next</value>
|
||||||
|
</data>
|
||||||
<data name="label.no" xml:space="preserve">
|
<data name="label.no" xml:space="preserve">
|
||||||
<value>No</value>
|
<value>No</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.notes" xml:space="preserve">
|
||||||
|
<value>Notes</value>
|
||||||
|
</data>
|
||||||
<data name="label.ok" xml:space="preserve">
|
<data name="label.ok" xml:space="preserve">
|
||||||
<value>OK</value>
|
<value>OK</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.page.info" xml:space="preserve">
|
||||||
|
<value>Page {0} of {1}</value>
|
||||||
|
</data>
|
||||||
<data name="label.password" xml:space="preserve">
|
<data name="label.password" xml:space="preserve">
|
||||||
<value>Password</value>
|
<value>Password</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.previous" xml:space="preserve">
|
||||||
|
<value>Previous</value>
|
||||||
|
</data>
|
||||||
<data name="label.reference" xml:space="preserve">
|
<data name="label.reference" xml:space="preserve">
|
||||||
<value>Reference</value>
|
<value>Reference</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.refresh" xml:space="preserve">
|
||||||
|
<value>Refresh</value>
|
||||||
|
</data>
|
||||||
|
<data name="label.search" xml:space="preserve">
|
||||||
|
<value>Search</value>
|
||||||
|
</data>
|
||||||
<data name="label.security" xml:space="preserve">
|
<data name="label.security" xml:space="preserve">
|
||||||
<value>Security</value>
|
<value>Security</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.select" xml:space="preserve">
|
||||||
|
<value>Select</value>
|
||||||
|
</data>
|
||||||
<data name="label.selected.count" xml:space="preserve">
|
<data name="label.selected.count" xml:space="preserve">
|
||||||
<value>{0} selected</value>
|
<value>{0} selected</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -195,6 +249,9 @@
|
|||||||
<data name="label.signout" xml:space="preserve">
|
<data name="label.signout" xml:space="preserve">
|
||||||
<value>Sign-out</value>
|
<value>Sign-out</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="label.type" xml:space="preserve">
|
||||||
|
<value>Type</value>
|
||||||
|
</data>
|
||||||
<data name="label.yes" xml:space="preserve">
|
<data name="label.yes" xml:space="preserve">
|
||||||
<value>Yes</value>
|
<value>Yes</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -264,6 +321,9 @@
|
|||||||
<data name="msg.validation.maximum.length" xml:space="preserve">
|
<data name="msg.validation.maximum.length" xml:space="preserve">
|
||||||
<value>Value must not exceed {0} characters</value>
|
<value>Value must not exceed {0} characters</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="security.caption.change.password" xml:space="preserve">
|
||||||
|
<value>Change Password</value>
|
||||||
|
</data>
|
||||||
<data name="security.caption.request.password" xml:space="preserve">
|
<data name="security.caption.request.password" xml:space="preserve">
|
||||||
<value>Request Password</value>
|
<value>Request Password</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -0,0 +1,332 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||||
|
using Sarand.Net.Standard.Base.App;
|
||||||
|
using Sarand.Net.Standard.Base.Bus;
|
||||||
|
using Sarand.Net.Standard.Base.Core;
|
||||||
|
using Sarand.Net.Standard.Base.Dbas;
|
||||||
|
using Sarand.Net.Standard.Base.Email;
|
||||||
|
using Sarand.Net.Standard.Base.Helpers;
|
||||||
|
using Sarand.Net.Standard.Base.Security;
|
||||||
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||||
|
{
|
||||||
|
//=======================================================================
|
||||||
|
// Portal Contact Controller - Ajax actions.
|
||||||
|
//=======================================================================
|
||||||
|
partial class ContactController
|
||||||
|
{
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Affiliate data.
|
||||||
|
private class AffiliateData_List : AjaxResponse_Data.ItemData
|
||||||
|
{
|
||||||
|
public String DisplayName { get; set; }
|
||||||
|
public String TypeCode { get; set; }
|
||||||
|
public String TypeDesc { get; set; }
|
||||||
|
// Address.
|
||||||
|
public String AddressSummary { get; set; }
|
||||||
|
}
|
||||||
|
private class AffiliateData_Full : AffiliateData_List
|
||||||
|
{
|
||||||
|
// Affiliate properties.
|
||||||
|
public String PhoneMain { get; set; } = "";
|
||||||
|
public String PhoneAlt { get; set; } = "";
|
||||||
|
public String PhoneFax { get; set; } = "";
|
||||||
|
public String Email { get; set; } = "";
|
||||||
|
public String Website { get; set; } = "";
|
||||||
|
// Ogranisation.
|
||||||
|
public SysId AffiliateIdParent { get; set; } = new SysId();
|
||||||
|
public String Name { get; set; } = "";
|
||||||
|
public String Abbr { get; set; } = "";
|
||||||
|
public String Nature { get; set; } = "";
|
||||||
|
public String Contact { get; set; } = "";
|
||||||
|
public String CompanyNo { get; set; } = "";
|
||||||
|
public String VatReg { get; set; } = "";
|
||||||
|
public String PhoneDirect { get; set; } = "";
|
||||||
|
// Individual.
|
||||||
|
public String Title { get; set; } = "";
|
||||||
|
public String Initials { get; set; } = "";
|
||||||
|
public String LastName { get; set; } = "";
|
||||||
|
public String FirstName { get; set; } = "";
|
||||||
|
public String Salutation { get; set; } = "";
|
||||||
|
public String PhoneMobile { get; set; } = "";
|
||||||
|
public byte BirthDay { get; set; } = 0;
|
||||||
|
public byte BirthMonth { get; set; } = 0;
|
||||||
|
public short BirthYear { get; set; } = 0;
|
||||||
|
public String MaritalStatus { get; set; } = "";
|
||||||
|
public String Spouse { get; set; } = "";
|
||||||
|
public String Children { get; set; } = "";
|
||||||
|
public String Hometown { get; set; } = "";
|
||||||
|
public SysId UserId { get; set; } = new SysId();
|
||||||
|
}
|
||||||
|
private void PopulateAffiliateResponseData(SbmAffiliate affiliate, AffiliateData_List data)
|
||||||
|
{
|
||||||
|
data.Id = SysId.ToString(affiliate.Id);
|
||||||
|
data.DisplayName = affiliate.GetDisplayName();
|
||||||
|
data.TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliate.AffiliateType);
|
||||||
|
data.TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliate.AffiliateType);
|
||||||
|
// Common properties.
|
||||||
|
data.Notes = affiliate.Notes;
|
||||||
|
data.StatusCode = affiliate.StatusCode;
|
||||||
|
data.StatusDesc = affiliate.StatusDesc;
|
||||||
|
}
|
||||||
|
private void PopulateAffiliateResponseData(SbmAffiliate affiliate, AffiliateData_Full data)
|
||||||
|
{
|
||||||
|
PopulateAffiliateResponseData(affiliate, data as AffiliateData_List);
|
||||||
|
// Affiliate properties.
|
||||||
|
data.PhoneMain = affiliate.PhoneMain;
|
||||||
|
data.PhoneAlt = affiliate.PhoneAlt;
|
||||||
|
data.PhoneFax = affiliate.PhoneFax;
|
||||||
|
data.Email = affiliate.Email;
|
||||||
|
data.Website = affiliate.Website;
|
||||||
|
// Ogranisation.
|
||||||
|
data.AffiliateIdParent = affiliate.AffiliateIdParent;
|
||||||
|
data.Name = affiliate.Name;
|
||||||
|
data.Abbr = affiliate.Abbr;
|
||||||
|
data.Nature = affiliate.Nature;
|
||||||
|
data.Contact = affiliate.Contact;
|
||||||
|
data.CompanyNo = affiliate.CompanyNo;
|
||||||
|
data.VatReg = affiliate.VatReg;
|
||||||
|
data.PhoneDirect = affiliate.PhoneDirect;
|
||||||
|
// Individual.
|
||||||
|
data.Title = affiliate.Title;
|
||||||
|
data.Initials = affiliate.Initials;
|
||||||
|
data.LastName = affiliate.LastName;
|
||||||
|
data.FirstName = affiliate.FirstName;
|
||||||
|
data.Salutation = affiliate.Salutation;
|
||||||
|
data.PhoneMobile = affiliate.PhoneMobile;
|
||||||
|
data.BirthDay = affiliate.BirthDay;
|
||||||
|
data.BirthMonth = affiliate.BirthMonth;
|
||||||
|
data.BirthYear = affiliate.BirthYear;
|
||||||
|
data.MaritalStatus = affiliate.MaritalStatus;
|
||||||
|
data.Spouse = affiliate.Spouse;
|
||||||
|
data.Children = affiliate.Children;
|
||||||
|
data.Hometown = affiliate.Hometown;
|
||||||
|
data.UserId = affiliate.UserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Contact list.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
private class AjaxResponse_ContactList : AjaxResponse_Data
|
||||||
|
{
|
||||||
|
// Construction.
|
||||||
|
public AjaxResponse_ContactList(SbmModel_Portal model) : base(model) { }
|
||||||
|
// Affiliate list.
|
||||||
|
public List<AffiliateData_List> Affiliates { get; } = new List<AffiliateData_List>();
|
||||||
|
// Reference data.
|
||||||
|
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||||
|
public String DefaultStatusCode { get; set; }
|
||||||
|
}
|
||||||
|
// Ajax request.
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Contact/Ajax/List")]
|
||||||
|
[Route("Contact/Ajax/GetList")]
|
||||||
|
public IActionResult Ajax_ContactList(Model_Contact model)
|
||||||
|
{
|
||||||
|
String fn = GetType().Name + ".Ajax_ContactList";
|
||||||
|
AjaxResponse_ContactList responseData = new AjaxResponse_ContactList(model);
|
||||||
|
String messageTitle = Localiser["contact.caption.contacts"];
|
||||||
|
|
||||||
|
// Validate session and referrer.
|
||||||
|
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||||
|
if (!ValidReferer) return Forbid();
|
||||||
|
RefreshModel(model);
|
||||||
|
|
||||||
|
// Reference data - statuses.
|
||||||
|
foreach (SaStatus status in SbmAffiliate.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
|
||||||
|
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||||
|
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmAffiliate.DefaultStatus);
|
||||||
|
|
||||||
|
// Item filter.
|
||||||
|
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
||||||
|
prmAffiliate.Search = model.Filter.AffiliateSearch;
|
||||||
|
prmAffiliate.AffiliateType = model.GetFilterAffiliateType();
|
||||||
|
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
|
||||||
|
prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name));
|
||||||
|
prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.LastName));
|
||||||
|
model.Paging.ItemTotal = (ulong)AccountMgr.GetAffiliateCount(prmAffiliate);
|
||||||
|
model.PopulatePagingTo(prmAffiliate.ResultsPaging);
|
||||||
|
|
||||||
|
// Item columns.
|
||||||
|
ColumnDfn colId = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Id);
|
||||||
|
ColumnDfn colName = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name);
|
||||||
|
ColumnDfn colAffiliateType = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Type);
|
||||||
|
ColumnDfn colPhoneMain = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneMain);
|
||||||
|
ColumnDfn colPhoneAlt = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneAlt);
|
||||||
|
ColumnDfn colNotes = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Notes);
|
||||||
|
ColumnDfn colStatus = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Status);
|
||||||
|
ColumnDfn colCreatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.CreateOn_Date);
|
||||||
|
ColumnDfn colUpdatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.UpdateOn_Date);
|
||||||
|
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||||
|
{
|
||||||
|
colId,
|
||||||
|
colName,
|
||||||
|
colAffiliateType,
|
||||||
|
colPhoneMain,
|
||||||
|
colPhoneAlt,
|
||||||
|
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||||
|
};
|
||||||
|
|
||||||
|
// Query items.
|
||||||
|
using (DbResultSet resultSet = AccountMgr.ExecuteAffiliateQuery(columns, prmAffiliate))
|
||||||
|
{
|
||||||
|
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
||||||
|
{
|
||||||
|
NamedValue.Map values = resultSet.GetRecordValues();
|
||||||
|
Sbm.AffiliateType affiliateType = (Sbm.AffiliateType)values.GetLong(colAffiliateType.DataName);
|
||||||
|
AffiliateData_List affiliateData = new AffiliateData_List()
|
||||||
|
{
|
||||||
|
Id = values.GetString(colId.DataName),
|
||||||
|
DisplayName = values.GetString(colName.DataName),
|
||||||
|
TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliateType),
|
||||||
|
TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliateType),
|
||||||
|
Notes = values.GetString(colNotes.DataName),
|
||||||
|
StatusCode = values.GetString(colStatus.DataName),
|
||||||
|
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
|
||||||
|
};
|
||||||
|
responseData.Affiliates.Add(affiliateData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (model.Paging.IsPaged)
|
||||||
|
model.Paging.ItemCount = (ushort)responseData.Affiliates.Count;
|
||||||
|
|
||||||
|
// Complete response.
|
||||||
|
responseData.SetPaging(model);
|
||||||
|
responseData.Success = true;
|
||||||
|
return Json(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Get Affiliate ajax request.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
private class AjaxResponse_Affiliate : AjaxResponse_Data
|
||||||
|
{
|
||||||
|
// Construction.
|
||||||
|
public AjaxResponse_Affiliate(SbmModel_Portal model) : base(model) { }
|
||||||
|
// Affiliate details.
|
||||||
|
public AffiliateData_Full affiliate { get; } = new AffiliateData_Full();
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Contact/Ajax/Item")]
|
||||||
|
[Route("Contact/Ajax/GetItem")]
|
||||||
|
public IActionResult Ajax_GetItem(Model_Contact model)
|
||||||
|
{
|
||||||
|
String fn = GetType().Name + ".Ajax_GetItem";
|
||||||
|
String messageTitle = Localiser["affiliate.caption.affiliate"];
|
||||||
|
AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model);
|
||||||
|
|
||||||
|
// Validate session.
|
||||||
|
if (!ValidUserSession)
|
||||||
|
return GetAjaxResult_InvalidSession(responseData);
|
||||||
|
|
||||||
|
// Identify item.
|
||||||
|
SysId affiliateId = model.AffiliateId.ToSysId();
|
||||||
|
if (!SysId.IsValid(affiliateId))
|
||||||
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
|
||||||
|
|
||||||
|
// Retrieve item.
|
||||||
|
SbmAffiliate affiliate = AccountMgr.GetAffiliateById(affiliateId);
|
||||||
|
if (affiliate == null)
|
||||||
|
{
|
||||||
|
SaLogger.Warn(fn + " Failed to retrieve affiliate for Id: '" + model.AffiliateId + "'");
|
||||||
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct response.
|
||||||
|
PopulateAffiliateResponseData(affiliate, responseData.affiliate);
|
||||||
|
|
||||||
|
// Complete response.
|
||||||
|
responseData.Success = true;
|
||||||
|
|
||||||
|
return Json(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Store Affiliate ajax request.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Contact/Ajax/Store")]
|
||||||
|
[Route("Contact/Ajax/StoreItem")]
|
||||||
|
public IActionResult Ajax_StoreItem(Model_Contact model)
|
||||||
|
{
|
||||||
|
String fn = GetType().Name + ".Ajax_StoreItem";
|
||||||
|
String messageTitle = Localiser["affiliate.caption.affiliate"];
|
||||||
|
AjaxResponse_Affiliate responseData = new AjaxResponse_Affiliate(model);
|
||||||
|
|
||||||
|
// Validate session.
|
||||||
|
if (!ValidUserSession)
|
||||||
|
return GetAjaxResult_InvalidSession(responseData);
|
||||||
|
|
||||||
|
// Validate item properties.
|
||||||
|
model.ValidateAffiliateData(responseData);
|
||||||
|
if (responseData.HasControlErrors())
|
||||||
|
return Json(responseData);
|
||||||
|
|
||||||
|
// Retrieve existing item.
|
||||||
|
SysId affiliateId = model.AffiliateId.ToSysId();
|
||||||
|
SbmAffiliate affiliate = AccountMgr.GetAffiliateById(affiliateId);
|
||||||
|
if (affiliate == null && SysId.IsValid(affiliateId))
|
||||||
|
{
|
||||||
|
SaLogger.Warn(fn + " Failed to retrieve affiliate for Id: '" + model.AffiliateId + "'");
|
||||||
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new item if required.
|
||||||
|
if (affiliate == null)
|
||||||
|
affiliate = AccountMgr.CreateAffiliate(model.GetAffiliateType());
|
||||||
|
|
||||||
|
// Populate item properties.
|
||||||
|
if (model.AffiliateName != null)
|
||||||
|
affiliate.Name = model.AffiliateName;
|
||||||
|
// Common properties.
|
||||||
|
if (model.AffiliateNotes != null)
|
||||||
|
affiliate.Notes = model.AffiliateNotes;
|
||||||
|
if (model.AffiliateStatus != null)
|
||||||
|
affiliate.Status = model.GetAffiliateStatus();
|
||||||
|
|
||||||
|
// Store item.
|
||||||
|
if (!SysId.IsValid(affiliate.Id))
|
||||||
|
{
|
||||||
|
if (!AccountMgr.InsertAffiliate(affiliate, DbUpdateInfo))
|
||||||
|
{
|
||||||
|
SaLogger.Warn(fn + " Failed to insert affiliate: " + AccountMgr.ErrorStateMessage);
|
||||||
|
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!AccountMgr.UpdateAffiliate(affiliate, DbUpdateInfo))
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct response.
|
||||||
|
PopulateAffiliateResponseData(affiliate, responseData.affiliate);
|
||||||
|
|
||||||
|
// Complete response.
|
||||||
|
responseData.Success = true;
|
||||||
|
|
||||||
|
return Json(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
//=======================================================================
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||||
|
using Sarand.Net.Standard.Base.App;
|
||||||
|
using Sarand.Net.Standard.Base.Bus;
|
||||||
|
using Sarand.Net.Standard.Base.Security;
|
||||||
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||||
|
{
|
||||||
|
//=======================================================================
|
||||||
|
public partial class ContactController : SbmController_Portal
|
||||||
|
{
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Data members.
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Construction.
|
||||||
|
public ContactController(SbmLocaliser localiser, ILogger<ContactController> logger) :
|
||||||
|
base(localiser, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
String fn = GetType().Name + ".Index";
|
||||||
|
|
||||||
|
if (!ValidUserSession)
|
||||||
|
return RedirectToAction("", "");
|
||||||
|
|
||||||
|
// Contact page.
|
||||||
|
Model_Contact model = new Model_Contact(Localiser);
|
||||||
|
model.Paging.PageNo = SessionData.Contacts.Filter.PageNo;
|
||||||
|
model.Paging.PageLength = SessionData.Contacts.Filter.PageLength;
|
||||||
|
return View(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public IActionResult Error()
|
||||||
|
{
|
||||||
|
return View(new ErrorViewModel(Localiser) { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
//=======================================================================
|
||||||
|
}
|
||||||
@@ -41,62 +41,54 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
// NB Only allowed if there isn't a current user session.
|
// NB Only allowed if there isn't a current user session.
|
||||||
if (!ValidUserSession && AppConfig.Security.SignIn.KeepLoggedIn.Allowed)
|
if (!ValidUserSession && AppConfig.Security.SignIn.KeepLoggedIn.Allowed)
|
||||||
{
|
{
|
||||||
|
// Extract parameters and validate that they are populated.
|
||||||
String encryptedParams = GetRequestCookie(CookieName_KeepLoggedIn);
|
String encryptedParams = GetRequestCookie(CookieName_KeepLoggedIn);
|
||||||
KeepLoggedInParams keepLoggedInParams = ExtractKeepLoggedInParams(encryptedParams);
|
KeepLoggedInParams keepLoggedInParams = ExtractKeepLoggedInParams(encryptedParams);
|
||||||
|
String logPrefix = fn + " 'Keep Logged In' cookie found but ";
|
||||||
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
||||||
|
if (keepLoggedInParams.IsValid())
|
||||||
if (SysId.IsValid(keepLoggedInParams.SecurityItemId) && SysId.IsValid(keepLoggedInParams.AffiliateId))
|
|
||||||
{
|
{
|
||||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(keepLoggedInParams.EmailAddress);
|
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(keepLoggedInParams.EmailAddress);
|
||||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||||
{
|
{
|
||||||
|
// Consoles and Managers must be associated with the specific context.
|
||||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
using (SaSecurityConsole securityConsole = App.CreateSecurityConsole(userContext))
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
{
|
{
|
||||||
SaSecurityItem securityItemUser = securityConsole.GetUserByEmail(keepLoggedInParams.EmailAddress);
|
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||||
if (securityItemUser != null)
|
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateId))
|
||||||
{
|
{
|
||||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId))
|
if (securityItemUser != null && affiliateUser != null)
|
||||||
{
|
{
|
||||||
using (SbmAccountMgr accountMgr = App.System.CreateAccountMgr(userContext))
|
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||||
{
|
{
|
||||||
SbmAffiliate affiliateUser = accountMgr.GetAffiliateById(keepLoggedInParams.AffiliateId);
|
if (affiliateUser.IsStatusCurrent)
|
||||||
if (affiliateUser != null)
|
|
||||||
{
|
|
||||||
if (affiliateUser.Id.Equals(keepLoggedInParams.AffiliateId))
|
|
||||||
{
|
|
||||||
if (affiliateUser.UserId.Equals(securityItemUser.Id))
|
|
||||||
{
|
|
||||||
if (affiliateUser.IsStatusActive)
|
|
||||||
{
|
{
|
||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
if (SignUserIn(sessionContext, securityItemUser, affiliateUser, true, ref errorMessage))
|
if (SignUserIn(userContext, securityItemUser, affiliateUser, true, ref errorMessage))
|
||||||
SaLogger.Info(fn + " Keep Logged In cookie found." + logSuffix);
|
{
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but failed to sign user in: " + errorMessage + "." + logSuffix);
|
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Affiliate is not active." + logSuffix);
|
else SaLogger.Warn(logPrefix + "failed to sign user in: " + errorMessage + "." + logSuffix);
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Affiliate User Id does not match security item." + logSuffix);
|
else SaLogger.Warn(logPrefix + "Affiliate is not active." + logSuffix);
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Affiliate does nto match Id." + logSuffix);
|
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Affiliate not found." + logSuffix);
|
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Security Item does not match Id." + logSuffix);
|
|
||||||
}
|
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Security Item not found by email." + logSuffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValidUserSession)
|
if (ValidUserSession)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " Keep Logged In cookie found but Security Item or Affiliate Ids missing." + logSuffix);
|
else if (!StringUtil.IsEmpty(encryptedParams))
|
||||||
|
SaLogger.Warn(fn + " Keep Logged In cookie found but with incomplete details." + logSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect to sign-in if not signed-in.
|
// Redirect to sign-in if not signed-in.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
|||||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.App;
|
using Sarand.BusinessMgr.Net.Core.Web.Portal.App;
|
||||||
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.Mgr;
|
||||||
using Sarand.Net.Standard.Base.App;
|
using Sarand.Net.Standard.Base.App;
|
||||||
using Sarand.Net.Standard.Base.Bus;
|
using Sarand.Net.Standard.Base.Bus;
|
||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
@@ -27,7 +28,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Protected construction.
|
// Protected construction.
|
||||||
protected SbmController_Portal(SbmLocaliser localiser, Microsoft.Extensions.Logging.ILogger<HomeController> logger) : base(localiser)
|
protected SbmController_Portal(SbmLocaliser localiser, Microsoft.Extensions.Logging.ILogger<SbmController_Portal> logger) : base(localiser)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,42 +51,60 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
/// <para>- Open user session - store details against Sesion Data.</para>
|
/// <para>- Open user session - store details against Sesion Data.</para>
|
||||||
/// <para>- Set 'Keep logged in' cookie if required.</para>
|
/// <para>- Set 'Keep logged in' cookie if required.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool SignUserIn(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, bool keepLoggedIn, ref String errorMessage)
|
protected bool SignUserIn(SbmUserContext userContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, bool keepLoggedIn, ref String errorMessage)
|
||||||
{
|
{
|
||||||
String fn = GetType().Name + ".SignUserIn";
|
String fn = GetType().Name + ".SignUserIn";
|
||||||
|
|
||||||
// Validate User Account, just in case - should have been done before arriving here!
|
// Validate Security Item and Affiliate, just in case - should have been done before arriving here!
|
||||||
if (affiliateUser == null)
|
if (securityItemUser == null)
|
||||||
{
|
{
|
||||||
SaLogger.Error(fn + " Unable to sign account in - null user account.");
|
SaLogger.Error(fn + " Unable to sign account in - null security item.");
|
||||||
errorMessage = Localiser["security.msg.signin.failed"];
|
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!affiliateUser.IsStatusActive)
|
if (affiliateUser == null)
|
||||||
{
|
{
|
||||||
SaLogger.Error(fn + " Unable to sign account in - user account is not active. Email: " + affiliateUser.Email);
|
SaLogger.Error(fn + " Unable to sign account in - null affiliate.");
|
||||||
errorMessage = Localiser["security.msg.signin.failed"];
|
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!affiliateUser.IsStatusCurrent)
|
||||||
|
{
|
||||||
|
SaLogger.Error(fn + " Unable to sign account in - affiliate is not active. Email: " + securityItemUser.EmailAddress);
|
||||||
|
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'Keep logged in' can be switched off by the application configuration.
|
// 'Keep logged in' can be switched off by the application configuration.
|
||||||
keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn;
|
keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn;
|
||||||
|
|
||||||
// Log user in.
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
affiliateUser.KeepLoggedIn_Portal = keepLoggedIn;
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
//affiliateUser.LastLoginAt = DateTime.Now;
|
|
||||||
//affiliateUser.InvalidLoginCount = 0;
|
|
||||||
//affiliateUser.LastInvalidLoginAt = DateTime.MinValue;
|
|
||||||
if (!AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo))
|
|
||||||
{
|
{
|
||||||
SaLogger.Warn(fn + " Failed to update account for " + affiliateUser.Email + ": " + AccountMgr.ErrorStateMessage);
|
// Log user in.
|
||||||
errorMessage = Localiser["security.msg.signin.failed"];
|
securityItemUser.LastLogin = DateTime.Now;
|
||||||
|
securityItemUser.InvalidLoginCount = 0;
|
||||||
|
securityItemUser.LastInvalidLoginAt = DateTime.MinValue;
|
||||||
|
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||||
|
{
|
||||||
|
SaLogger.Warn(fn + " Failed to update security item for " + securityItemUser.EmailAddress + ": " + securityConsoleForUser.ErrorStateMessage);
|
||||||
|
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SaLogger.Info(fn + " User session opened for " + affiliateUser.Email, true);
|
|
||||||
|
// Update affiliate.
|
||||||
|
affiliateUser.KeepLoggedIn_Portal = keepLoggedIn;
|
||||||
|
if (!accountMgrForUser.UpdateAffiliate(affiliateUser, DbUpdateInfo))
|
||||||
|
{
|
||||||
|
SaLogger.Warn(fn + " Failed to update affiliate for " + securityItemUser.EmailAddress + ": " + accountMgrForUser.ErrorStateMessage);
|
||||||
|
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SaLogger.Info(fn + " User session opened for " + securityItemUser.EmailAddress, true);
|
||||||
|
}
|
||||||
|
|
||||||
// Create session.
|
// Create session.
|
||||||
OpenUserSession(sessionContext, securityItemUser, affiliateUser);
|
OpenUserSession(userContext.SessionContext, securityItemUser, affiliateUser);
|
||||||
|
|
||||||
// Send the 'Keep Logged In' cookie if requested.
|
// Send the 'Keep Logged In' cookie if requested.
|
||||||
if (affiliateUser.KeepLoggedIn_Portal)
|
if (affiliateUser.KeepLoggedIn_Portal)
|
||||||
@@ -116,7 +135,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
{
|
{
|
||||||
// Validate user properties.
|
// Validate user properties.
|
||||||
if (!SysId.IsValid(affiliateUser.Id)) return false;
|
if (!SysId.IsValid(affiliateUser.Id)) return false;
|
||||||
if (StringUtil.IsEmpty(affiliateUser.Email)) return false;
|
if (StringUtil.IsEmpty(securityItemUser.EmailAddress)) return false;
|
||||||
|
|
||||||
// Close previous session.
|
// Close previous session.
|
||||||
CloseUserSession();
|
CloseUserSession();
|
||||||
@@ -186,10 +205,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
public List<String> GetValidParams()
|
public List<String> GetValidParams()
|
||||||
{
|
{
|
||||||
List<String> values = new List<String>();
|
List<String> values = new List<String>();
|
||||||
|
if (!StringUtil.IsEmpty(EmailAddress))
|
||||||
|
values.Add("EmailAddress: " + EmailAddress);
|
||||||
|
if (SysId.IsValid(SecurityItemId))
|
||||||
|
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
||||||
if (SysId.IsValid(AffiliateId))
|
if (SysId.IsValid(AffiliateId))
|
||||||
values.Add("UserAccountId: " + SysId.ToString(AffiliateId));
|
values.Add("UserAccountId: " + SysId.ToString(AffiliateId));
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
/// <summary>Verifiy that the email and account Ids are populated and the data hasn't expired.</summary>
|
||||||
|
public bool IsValid()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
!StringUtil.IsEmpty(EmailAddress) &&
|
||||||
|
SysId.IsValid(SecurityItemId) &&
|
||||||
|
SysId.IsValid(AffiliateId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public KeepLoggedInParams ExtractKeepLoggedInParams(String encryptedParams)
|
public KeepLoggedInParams ExtractKeepLoggedInParams(String encryptedParams)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ using System.Web;
|
|||||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// Online Security Controller - Ajax actions.
|
// Portal Security Controller - Ajax actions.
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
partial class SecurityController
|
partial class SecurityController
|
||||||
{
|
{
|
||||||
@@ -72,7 +72,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
return Json(responseData);
|
return Json(responseData);
|
||||||
|
|
||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
if (!SignUserIn(sessionContext, securityItemUser, affiliateUser, model.KeepMeSignedIn, ref errorMessage))
|
if (!SignUserIn(userContext, securityItemUser, affiliateUser, model.KeepMeSignedIn, ref errorMessage))
|
||||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,10 +122,11 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
{
|
{
|
||||||
String fn = GetType().Name + ".GetSecurityItemForSignin";
|
String fn = GetType().Name + ".GetSecurityItemForSignin";
|
||||||
SaSecurityItem securityItemUser = null;
|
SaSecurityItem securityItemUser = null;
|
||||||
using (SaSecurityConsole securityConsole = App.CreateSecurityConsole(userContext))
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
{
|
{
|
||||||
// Retrieve security item by email address.
|
// Retrieve security item by email address.
|
||||||
securityItemUser = securityConsole.GetUserByEmail(model.EmailAddress);
|
using (securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress))
|
||||||
|
{
|
||||||
if (securityItemUser != null)
|
if (securityItemUser != null)
|
||||||
{
|
{
|
||||||
// Validate password.
|
// Validate password.
|
||||||
@@ -134,7 +135,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
// Record invalid login attempt.
|
// Record invalid login attempt.
|
||||||
securityItemUser.InvalidLoginCount++;
|
securityItemUser.InvalidLoginCount++;
|
||||||
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
||||||
if (!securityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||||
SaLogger.Warn(fn + " Failed to store invalid sign-in attempt against User: " + model.EmailAddress + ". " + AccountMgr.ErrorStateMessage, true);
|
SaLogger.Warn(fn + " Failed to store invalid sign-in attempt against User: " + model.EmailAddress + ". " + AccountMgr.ErrorStateMessage, true);
|
||||||
SaLogger.Warn(fn + " Attempt to sign-in to User " + model.EmailAddress + " with invalid password. Attempt: " + securityItemUser.InvalidLoginCount, true);
|
SaLogger.Warn(fn + " Attempt to sign-in to User " + model.EmailAddress + " with invalid password. Attempt: " + securityItemUser.InvalidLoginCount, true);
|
||||||
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
||||||
@@ -142,6 +143,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return securityItemUser;
|
return securityItemUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,19 +152,21 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
{
|
{
|
||||||
String fn = GetType().Name + ".GetAffiliateForSignin";
|
String fn = GetType().Name + ".GetAffiliateForSignin";
|
||||||
SbmAffiliate affiliate = null;
|
SbmAffiliate affiliate = null;
|
||||||
using (SbmAccountMgr accountMgr = App.System.CreateAccountMgr(userContext))
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
{
|
{
|
||||||
// Identify the contact asociated with the security item.
|
// Identify the contact asociated with the security item.
|
||||||
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
||||||
prmAffiliate.UserId = securityItemUser.Id;
|
prmAffiliate.UserId = securityItemUser.Id;
|
||||||
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.ActiveOnly;
|
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.CurrentOnly;
|
||||||
affiliate = accountMgr.GetAffiliate(prmAffiliate);
|
using (affiliate = accountMgrForUser.GetAffiliate(prmAffiliate))
|
||||||
|
{
|
||||||
if (affiliate != null)
|
if (affiliate != null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
if (affiliate == null && !responseData.HasControlErrors())
|
if (affiliate == null && !responseData.HasControlErrors())
|
||||||
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return affiliate;
|
return affiliate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,8 +259,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
String messageTitle = Localiser["security.caption.change.password"];
|
String messageTitle = Localiser["security.caption.change.password"];
|
||||||
|
|
||||||
// Validate referrer.
|
// Validate referrer.
|
||||||
if (!ValidReferer)
|
if (!ValidReferer) return Forbid();
|
||||||
return Forbid();
|
|
||||||
|
// If user is logged in, session Consoles and Managers can be used.
|
||||||
|
// If 'Request Password' parameters are specified, Consoles and Managers must be associated with the specific database for the user.
|
||||||
|
SbmSessionContext sessionContextForUser = null;
|
||||||
|
SbmUserContext_Web userContextForUser = null;
|
||||||
|
|
||||||
// If 'Request Password' encrypted params (from email link) are present,
|
// If 'Request Password' encrypted params (from email link) are present,
|
||||||
// Session is not required and password can be set directly against the user.
|
// Session is not required and password can be set directly against the user.
|
||||||
@@ -266,33 +274,57 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
bool validSessionRequired = true;
|
bool validSessionRequired = true;
|
||||||
RequestPasswordParams requestPasswordParams = ExtractRequestPasswordLinkParams(model.rpe);
|
RequestPasswordParams requestPasswordParams = ExtractRequestPasswordLinkParams(model.rpe);
|
||||||
if (requestPasswordParams.IsValid())
|
if (requestPasswordParams.IsValid())
|
||||||
|
{
|
||||||
|
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||||
|
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||||
|
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(requestPasswordParams.EmailAddress);
|
||||||
|
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||||
|
{
|
||||||
|
// Consoles and Managers must be associated with the specific context.
|
||||||
|
sessionContextForUser = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||||
|
userContextForUser = new SbmUserContext_Web(sessionContextForUser);
|
||||||
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContextForUser))
|
||||||
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContextForUser))
|
||||||
{
|
{
|
||||||
// Retrieve user details and validate email address.
|
// Retrieve user details and validate email address.
|
||||||
securityItemUser = SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, requestPasswordParams.SecurityItemId);
|
securityItemUser = securityConsoleForUser.GetSecurityItemById(SaSecurity.ItemType.User, requestPasswordParams.SecurityItemId);
|
||||||
affiliateUser = AccountMgr.GetAffiliateById(requestPasswordParams.AffiliateId);
|
affiliateUser = accountMgrForUser.GetAffiliateById(requestPasswordParams.AffiliateId);
|
||||||
if (requestPasswordParams.IsValid(securityItemUser, affiliateUser))
|
if (requestPasswordParams.IsValid(securityItemUser, affiliateUser))
|
||||||
{
|
{
|
||||||
validRequestPasswordParams = true;
|
validRequestPasswordParams = true;
|
||||||
validSessionRequired = false;
|
validSessionRequired = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SaLogger.Warn(fn + " 'Request Password' parameters supplied but invalid. SecurityItemId: " + SysId.ToString(requestPasswordParams.SecurityItemId) + ". AffiliateId: " + SysId.ToString(requestPasswordParams.AffiliateId) + ". Email: " + requestPasswordParams.EmailAddress);
|
SaLogger.Warn(fn + " 'Request Password' parameters supplied but invalid. Email: " + requestPasswordParams.EmailAddress + ". SecurityItemId: " + SysId.ToString(requestPasswordParams.SecurityItemId) + ". AffiliateId: " + SysId.ToString(requestPasswordParams.AffiliateId));
|
||||||
affiliateUser = null;
|
if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null;
|
||||||
|
if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null;
|
||||||
|
sessionContextForUser = null;
|
||||||
|
userContextForUser = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// User must have a valid session.
|
// User must have a valid session if security item and affiliate not idenfied via the 'Request Password' paramaters.
|
||||||
if (validSessionRequired && (securityItemUser == null || affiliateUser == null) && !ValidUserSession)
|
if (validSessionRequired && (securityItemUser == null || affiliateUser == null) && !ValidUserSession)
|
||||||
return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"]));
|
return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"]));
|
||||||
|
|
||||||
|
// User specific Consoles and Managers if User Context specified.
|
||||||
|
using (SaSecurityConsole securityConsoleForUser = userContextForUser != null ? App.CreateSecurityConsole(userContextForUser) : null)
|
||||||
|
using (SbmAccountMgr accountMgrForUser = userContextForUser != null ? App.System.CreateAccountMgr(userContextForUser) : null)
|
||||||
|
{
|
||||||
|
SaSecurityConsole securityConsole = (securityConsoleForUser ?? SecurityConsole);
|
||||||
|
SbmAccountMgr accountMgr = (accountMgrForUser ?? AccountMgr);
|
||||||
|
|
||||||
// Retrieve user details if not previously populated.
|
// Retrieve user details if not previously populated.
|
||||||
if (securityItemUser == null && SessionData_Portal != null)
|
if (securityItemUser == null && SessionData_Portal != null)
|
||||||
securityItemUser = SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId);
|
securityItemUser = (securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId));
|
||||||
if (securityItemUser == null)
|
if (securityItemUser == null)
|
||||||
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve security item details."));
|
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve security item details."));
|
||||||
if (affiliateUser == null && SessionData_Portal != null)
|
if (affiliateUser == null && SessionData_Portal != null)
|
||||||
affiliateUser = AccountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId);
|
affiliateUser = accountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId);
|
||||||
if (affiliateUser == null)
|
if (affiliateUser == null)
|
||||||
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve affiliate details."));
|
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve affiliate details."));
|
||||||
|
|
||||||
@@ -323,12 +355,20 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
securityItemUser.PasswordHistory.Add(oldPasswordHashed);
|
securityItemUser.PasswordHistory.Add(oldPasswordHashed);
|
||||||
while (securityItemUser.PasswordHistory.Count > 10)
|
while (securityItemUser.PasswordHistory.Count > 10)
|
||||||
securityItemUser.PasswordHistory.RemoveAt(securityItemUser.PasswordHistory.Count - 1);
|
securityItemUser.PasswordHistory.RemoveAt(securityItemUser.PasswordHistory.Count - 1);
|
||||||
if (!SecurityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
if (!securityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||||
{
|
{
|
||||||
SaLogger.Warn(fn + " Failed to change password for " + securityItemUser.EmailAddress + ": " + AccountMgr.ErrorStateMessage);
|
SaLogger.Warn(fn + " Failed to change password for " + securityItemUser.EmailAddress + ": " + securityConsole.ErrorStateMessage);
|
||||||
return Json(responseData.SetControlError(nameof(model.Password), Localiser["security.msg.change.password.failed"]));
|
return Json(responseData.SetControlError(nameof(model.Password), Localiser["security.msg.change.password.failed"]));
|
||||||
}
|
}
|
||||||
SaLogger.Info(fn + " Password changed for " + securityItemUser.EmailAddress, true);
|
SaLogger.Info(fn + " Password changed for " + securityItemUser.EmailAddress, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup. NB The Security Item and/or Affiliate aren't disposed when the method
|
||||||
|
// returns above but these objects shouldn't be carrying any disposable resources.
|
||||||
|
if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null;
|
||||||
|
if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null;
|
||||||
|
sessionContextForUser = null;
|
||||||
|
userContextForUser = null;
|
||||||
|
|
||||||
// Construct response.
|
// Construct response.
|
||||||
responseData.Success = true;
|
responseData.Success = true;
|
||||||
@@ -350,10 +390,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
}
|
}
|
||||||
// Ajax request.
|
// Ajax request.
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("Security/Ajax/RequestNewPassword")]
|
[Route("Security/Ajax/RequestPassword")]
|
||||||
public ActionResult Ajax_RequestNewPassword(Model_Security model)
|
public ActionResult Ajax_RequestPassword(Model_Security model)
|
||||||
{
|
{
|
||||||
String fn = GetType().Name + ".Ajax_RequestNewPassword";
|
String fn = GetType().Name + ".Ajax_RequestPassword";
|
||||||
AjaxResponse_RequestPassword responseData = new AjaxResponse_RequestPassword(model);
|
AjaxResponse_RequestPassword responseData = new AjaxResponse_RequestPassword(model);
|
||||||
String messageTitle = Localiser["security.caption.request.password"];
|
String messageTitle = Localiser["security.caption.request.password"];
|
||||||
|
|
||||||
@@ -372,15 +412,15 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
|
|
||||||
// Get user security item and affiliate.
|
// Get user security item and affiliate.
|
||||||
using (SaSecurityConsole securityConsole = App.CreateSecurityConsole(userContext))
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
{
|
{
|
||||||
using (SaSecurityItem securityItemUser = securityConsole.GetUserByEmail(model.EmailAddress))
|
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress))
|
||||||
{
|
{
|
||||||
if (securityItemUser != null)
|
if (securityItemUser != null)
|
||||||
{
|
{
|
||||||
using (SbmAccountMgr accountMgr = App.System.CreateAccountMgr(userContext))
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
{
|
{
|
||||||
using (SbmAffiliate affiliateUser = accountMgr.GetAffiliateByUserId(securityItemUser.Id))
|
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateByUserId(securityItemUser.Id))
|
||||||
{
|
{
|
||||||
if (affiliateUser != null)
|
if (affiliateUser != null)
|
||||||
{
|
{
|
||||||
@@ -431,9 +471,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Password request link.
|
// Password request link.
|
||||||
private static String ParamName_RequestPasswordEncrypted { get; } = "rpe";
|
private static String ParamName_RequestPasswordEncrypted { get; } = "rpe";
|
||||||
|
private static String ParamName_EmailAddress { get; } = "ema";
|
||||||
private static String ParamName_SecurityItemId { get; } = "sei";
|
private static String ParamName_SecurityItemId { get; } = "sei";
|
||||||
private static String ParamName_AffiliateId { get; } = "afi";
|
private static String ParamName_AffiliateId { get; } = "afi";
|
||||||
private static String ParamName_EmailAddress { get; } = "ema";
|
|
||||||
private static String ParamName_ExpiresAt { get; } = "exp";
|
private static String ParamName_ExpiresAt { get; } = "exp";
|
||||||
private static String ParamName_Token { get; } = "tok";
|
private static String ParamName_Token { get; } = "tok";
|
||||||
// NB IV value is generated from the key and fixed so that it doesn't change when the application restarts.
|
// NB IV value is generated from the key and fixed so that it doesn't change when the application restarts.
|
||||||
@@ -444,9 +484,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
private String GenerateRequestPasswordLink(SysId securityItemId, SysId affiliateId, String emailAddress, String requestPasswordToken)
|
private String GenerateRequestPasswordLink(SysId securityItemId, SysId affiliateId, String emailAddress, String requestPasswordToken)
|
||||||
{
|
{
|
||||||
NameValueCollection parameters = new NameValueCollection();
|
NameValueCollection parameters = new NameValueCollection();
|
||||||
|
parameters.Add(ParamName_EmailAddress, emailAddress);
|
||||||
parameters.Add(ParamName_SecurityItemId, SysId.ToString(securityItemId));
|
parameters.Add(ParamName_SecurityItemId, SysId.ToString(securityItemId));
|
||||||
parameters.Add(ParamName_AffiliateId, SysId.ToString(affiliateId));
|
parameters.Add(ParamName_AffiliateId, SysId.ToString(affiliateId));
|
||||||
parameters.Add(ParamName_EmailAddress, emailAddress);
|
|
||||||
parameters.Add(ParamName_ExpiresAt, DateUtil.Format(DateTime.Now.AddMinutes(GetRequestPasswordEmailLinkExpiresMinutes()), DateUtil.Format_XmlDateTime));
|
parameters.Add(ParamName_ExpiresAt, DateUtil.Format(DateTime.Now.AddMinutes(GetRequestPasswordEmailLinkExpiresMinutes()), DateUtil.Format_XmlDateTime));
|
||||||
parameters.Add(ParamName_Token, requestPasswordToken);
|
parameters.Add(ParamName_Token, requestPasswordToken);
|
||||||
String link =
|
String link =
|
||||||
@@ -463,34 +503,34 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
}
|
}
|
||||||
private class RequestPasswordParams
|
private class RequestPasswordParams
|
||||||
{
|
{
|
||||||
|
public String EmailAddress { get; set; }
|
||||||
public SysId SecurityItemId { get; set; }
|
public SysId SecurityItemId { get; set; }
|
||||||
public SysId AffiliateId { get; set; }
|
public SysId AffiliateId { get; set; }
|
||||||
public String EmailAddress { get; set; }
|
|
||||||
public DateTime ExpiresAt { get; set; }
|
public DateTime ExpiresAt { get; set; }
|
||||||
public String Token { get; set; }
|
public String Token { get; set; }
|
||||||
/// <summary>Retrieve the list of valid parameters in printable format [Name: Value].</summary>
|
/// <summary>Retrieve the list of valid parameters in printable format [Name: Value].</summary>
|
||||||
public List<String> GetValidParams()
|
public List<String> GetValidParams()
|
||||||
{
|
{
|
||||||
List<String> values = new List<String>();
|
List<String> values = new List<String>();
|
||||||
|
if (!StringUtil.IsEmpty(EmailAddress))
|
||||||
|
values.Add("Email: " + EmailAddress);
|
||||||
if (SysId.IsValid(SecurityItemId))
|
if (SysId.IsValid(SecurityItemId))
|
||||||
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
||||||
if (SysId.IsValid(AffiliateId))
|
if (SysId.IsValid(AffiliateId))
|
||||||
values.Add("AffiliateId: " + SysId.ToString(AffiliateId));
|
values.Add("AffiliateId: " + SysId.ToString(AffiliateId));
|
||||||
if (!StringUtil.IsEmpty(EmailAddress))
|
|
||||||
values.Add("Email: " + EmailAddress);
|
|
||||||
if (DateUtil.IsValid(ExpiresAt))
|
if (DateUtil.IsValid(ExpiresAt))
|
||||||
values.Add("Expires: " + DateUtil.FormatXmlDateTime(ExpiresAt));
|
values.Add("Expires: " + DateUtil.FormatXmlDateTime(ExpiresAt));
|
||||||
if (!StringUtil.IsEmpty(Token))
|
if (!StringUtil.IsEmpty(Token))
|
||||||
values.Add("Token: " + Token);
|
values.Add("Token: " + Token);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
/// <summary>Verifiy that the account Id and email are populated and the data hasn't expired.</summary>
|
/// <summary>Verifiy that the email and account Ids are populated and the data hasn't expired.</summary>
|
||||||
public bool IsValid()
|
public bool IsValid()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
!StringUtil.IsEmpty(EmailAddress) &&
|
||||||
SysId.IsValid(SecurityItemId) &&
|
SysId.IsValid(SecurityItemId) &&
|
||||||
SysId.IsValid(AffiliateId) &&
|
SysId.IsValid(AffiliateId) &&
|
||||||
!StringUtil.IsEmpty(EmailAddress) &&
|
|
||||||
DateUtil.IsValid(ExpiresAt) && ExpiresAt >= DateTime.Now;
|
DateUtil.IsValid(ExpiresAt) && ExpiresAt >= DateTime.Now;
|
||||||
}
|
}
|
||||||
/// <summary>Verify that the data is valid and the account details match.</summary>
|
/// <summary>Verify that the data is valid and the account details match.</summary>
|
||||||
@@ -498,10 +538,11 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
IsValid() &&
|
IsValid() &&
|
||||||
affiliateUser != null &&
|
securityItemUser.EmailAddress.EqualsCI(EmailAddress) &&
|
||||||
|
securityItemUser != null &&
|
||||||
securityItemUser.Id.Equals(SecurityItemId) &&
|
securityItemUser.Id.Equals(SecurityItemId) &&
|
||||||
affiliateUser.Id.Equals(AffiliateId) &&
|
affiliateUser != null &&
|
||||||
securityItemUser.EmailAddress.EqualsCI(EmailAddress);
|
affiliateUser.Id.Equals(AffiliateId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private RequestPasswordParams ExtractRequestPasswordLinkParams(String encryptedParams)
|
private RequestPasswordParams ExtractRequestPasswordLinkParams(String encryptedParams)
|
||||||
@@ -510,9 +551,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
if (!StringUtil.IsEmpty(encryptedParams))
|
if (!StringUtil.IsEmpty(encryptedParams))
|
||||||
{
|
{
|
||||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_RequestPassword, Base64Key_RequestPassword);
|
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_RequestPassword, Base64Key_RequestPassword);
|
||||||
|
requestPasswordParams.EmailAddress = linkParams.Get(ParamName_EmailAddress);
|
||||||
requestPasswordParams.SecurityItemId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_SecurityItemId)));
|
requestPasswordParams.SecurityItemId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_SecurityItemId)));
|
||||||
requestPasswordParams.AffiliateId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_AffiliateId)));
|
requestPasswordParams.AffiliateId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_AffiliateId)));
|
||||||
requestPasswordParams.EmailAddress = linkParams.Get(ParamName_EmailAddress);
|
|
||||||
requestPasswordParams.ExpiresAt = DateUtil.ParseXmlDateTime(linkParams.Get(ParamName_ExpiresAt));
|
requestPasswordParams.ExpiresAt = DateUtil.ParseXmlDateTime(linkParams.Get(ParamName_ExpiresAt));
|
||||||
requestPasswordParams.Token = linkParams.Get(ParamName_Token);
|
requestPasswordParams.Token = linkParams.Get(ParamName_Token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||||
|
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.Mgr;
|
||||||
using Sarand.Net.Standard.Base.App;
|
using Sarand.Net.Standard.Base.App;
|
||||||
using Sarand.Net.Standard.Base.Bus;
|
using Sarand.Net.Standard.Base.Bus;
|
||||||
using Sarand.Net.Standard.Base.Security;
|
using Sarand.Net.Standard.Base.Security;
|
||||||
@@ -71,24 +74,43 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
|||||||
RequestPasswordParams requestPasswordParams = ExtractRequestPasswordLinkParams(encryptedParams);
|
RequestPasswordParams requestPasswordParams = ExtractRequestPasswordLinkParams(encryptedParams);
|
||||||
if (requestPasswordParams.IsValid())
|
if (requestPasswordParams.IsValid())
|
||||||
{
|
{
|
||||||
|
String logPrefix = fn + " 'Request Password' parameters supplied but ";
|
||||||
String logSuffix = requestPasswordParams.GetValidParams().Concat("", " ", ".");
|
String logSuffix = requestPasswordParams.GetValidParams().Concat("", " ", ".");
|
||||||
using (SaSecurityItem securityItemUser = SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, requestPasswordParams.SecurityItemId))
|
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||||
using (SbmAffiliate userAccount = AccountMgr.GetAffiliateById(requestPasswordParams.AffiliateId))
|
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||||
|
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(requestPasswordParams.EmailAddress);
|
||||||
|
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||||
{
|
{
|
||||||
if (securityItemUser != null && userAccount != null)
|
// Consoles and Managers must be associated with the specific context.
|
||||||
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||||
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
{
|
{
|
||||||
if (userAccount.IsStatusActive)
|
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(requestPasswordParams.EmailAddress))
|
||||||
|
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(requestPasswordParams.AffiliateId))
|
||||||
{
|
{
|
||||||
if (requestPasswordParams.IsValid(securityItemUser, userAccount))
|
if (securityItemUser != null && affiliateUser != null)
|
||||||
|
{
|
||||||
|
if (securityItemUser.Id.Equals(requestPasswordParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||||
|
{
|
||||||
|
if (affiliateUser.IsStatusCurrent)
|
||||||
|
{
|
||||||
|
if (requestPasswordParams.IsValid(securityItemUser, affiliateUser))
|
||||||
{
|
{
|
||||||
model.rpe = encryptedParams;
|
model.rpe = encryptedParams;
|
||||||
validSessionRequired = false;
|
validSessionRequired = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " 'Request Password' parameters supplied but invalid. " + logSuffix);
|
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are incompatible with parameters. " + logSuffix);
|
||||||
|
}
|
||||||
|
else SaLogger.Warn(logPrefix + "Affiliate is not active. " + logSuffix);
|
||||||
|
}
|
||||||
|
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||||
|
}
|
||||||
|
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " 'Request Password' parameters supplied but account is not active. " + logSuffix);
|
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(fn + " 'Request Password' parameters supplied but security item or affiliate not found. " + logSuffix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||||
|
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||||
|
using Sarand.Net.Standard.Base.App;
|
||||||
|
using Sarand.Net.Standard.Base.Core;
|
||||||
|
using Sarand.Net.Standard.Base.Helpers;
|
||||||
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||||
|
{
|
||||||
|
//=======================================================================
|
||||||
|
public class Model_Contact : SbmModel_Portal
|
||||||
|
{
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Construction.
|
||||||
|
public Model_Contact(SbmLocaliser localiser) :
|
||||||
|
base(localiser)
|
||||||
|
{
|
||||||
|
AdditionalFiles_JS.Add("js/sbm-contact.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Filter properties.
|
||||||
|
public class FilterData
|
||||||
|
{
|
||||||
|
public String AffiliateSearch { get; set; }
|
||||||
|
public String AffiliateType { get; set; }
|
||||||
|
}
|
||||||
|
public FilterData Filter { get; } = new FilterData();
|
||||||
|
public Sbm.AffiliateType GetFilterAffiliateType()
|
||||||
|
{
|
||||||
|
return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(Filter.AffiliateType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Affiliate properties.
|
||||||
|
public String AffiliateId { get; set; }
|
||||||
|
public String AffiliateType{ get; set; }
|
||||||
|
public Sbm.AffiliateType GetAffiliateType()
|
||||||
|
{
|
||||||
|
return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(AffiliateType);
|
||||||
|
}
|
||||||
|
public String AffiliateName { get; set; }
|
||||||
|
// Common properties.
|
||||||
|
public String AffiliateNotes { get; set; }
|
||||||
|
public String AffiliateStatus { get; set; }
|
||||||
|
public SaStatus GetAffiliateStatus()
|
||||||
|
{
|
||||||
|
return SacsSystem.GetStatusForCode(AffiliateStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Validation.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Affiliate validation.
|
||||||
|
public bool ValidateAffiliateData(SbmController_Base.AjaxResponse_Data responseData)
|
||||||
|
{
|
||||||
|
// Affiliate Type.
|
||||||
|
if (AffiliateType != null)
|
||||||
|
{
|
||||||
|
if (StringUtil.IsEmpty(AffiliateType))
|
||||||
|
responseData.SetControlError(nameof(AffiliateType), Localiser["msg.validation.mandatory.value"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Affiliate Name.
|
||||||
|
if (AffiliateName != null)
|
||||||
|
{
|
||||||
|
responseData.SetControlValue(nameof(AffiliateName), AffiliateName);
|
||||||
|
if (StringUtil.IsEmpty(AffiliateName))
|
||||||
|
responseData.SetControlError(nameof(AffiliateName), Localiser["msg.validation.mandatory.value"]);
|
||||||
|
if (StringUtil.GetLength(AffiliateName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name))
|
||||||
|
responseData.SetControlError(nameof(AffiliateName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Affiliate Notes.
|
||||||
|
if (AffiliateNotes != null)
|
||||||
|
{
|
||||||
|
responseData.SetControlValue(nameof(AffiliateNotes), AffiliateNotes);
|
||||||
|
if (!StringUtil.IsEmpty(AffiliateNotes) && StringUtil.GetLength(AffiliateNotes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes))
|
||||||
|
responseData.SetControlError(nameof(AffiliateNotes), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Notes)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Affiliate status.
|
||||||
|
if (AffiliateStatus != null)
|
||||||
|
{
|
||||||
|
if (StringUtil.IsEmpty(AffiliateStatus))
|
||||||
|
responseData.SetControlError(nameof(AffiliateStatus), Localiser["msg.validation.mandatory.value"]);
|
||||||
|
else if (!SbmAffiliate.ValidStatuses.Contains(GetAffiliateStatus()))
|
||||||
|
responseData.SetControlError(nameof(AffiliateStatus), Localiser["msg.validation.invalid.value"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !responseData.HasControlErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
//=======================================================================
|
||||||
|
}
|
||||||
@@ -36,4 +36,10 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Views\Commodity\" />
|
||||||
|
<Folder Include="Views\Association\" />
|
||||||
|
<Folder Include="Views\Transactions\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
@model SbmModel_Portal
|
||||||
|
@inject SbmLocaliser Localiser
|
||||||
|
|
||||||
|
<script src="~/js/sbm-resultsPaging.js?@Model.HrefVersion"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
sbm.resultsPaging.msg.pageInfo = '@Localiser.GetJavascriptText("label.page.info","{0}","{1}")';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@* Results paging *@
|
||||||
|
<div class="sbm-results-paging hidden">
|
||||||
|
|
||||||
|
@Html.HiddenFor(model => model.Paging.PageNo, new { @id = "", @class = "PagingPageNo" })
|
||||||
|
@Html.HiddenFor(model => model.Paging.PageLength, new { @id = "", @class = "PagingPageLength" })
|
||||||
|
|
||||||
|
<div class="iblock sbm-action sbm-paging-first"><img src="~/img/action/first24.png" alt="@(Localiser["label.first"])" title="@(Localiser["label.first"])" /></div>
|
||||||
|
<div class="iblock sbm-action sbm-paging-prev"><img src="~/img/action/prev24.png" alt="@(Localiser["label.previous"])" title="@(Localiser["label.previous"])" /></div>
|
||||||
|
<div class="iblock sbm-paging-info"></div>
|
||||||
|
<div class="iblock sbm-action sbm-paging-next"><img src="~/img/action/next24.png" alt="@(Localiser["label.next"])" title="@(Localiser["label.next"])" /></div>
|
||||||
|
<div class="iblock sbm-action sbm-paging-last"><img src="~/img/action/last24.png" alt="@(Localiser["label.last"])" title="@(Localiser["label.last"])" /></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
@model Model_Contact
|
||||||
|
@inject SbmLocaliser Localiser
|
||||||
|
@{
|
||||||
|
/* Affiliates - Index */
|
||||||
|
ViewData["Title"] = "Affiliates";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="sbm-page-affiliates">
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
sbm.lbl.edit = 'Edit';
|
||||||
|
sbm.lbl.activate = 'Activate';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-5 row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
@* Filter Panel *@
|
||||||
|
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAffiliateFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||||
|
{
|
||||||
|
<div class="sbm-panel-filter">
|
||||||
|
@* Header - Page caption, paging controls, actions. *@
|
||||||
|
<div class="sbm-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><div class="sbm-caption">@Localiser["contact.caption.contacts"]</div></div>
|
||||||
|
<div class="fixed row">
|
||||||
|
<div class="col">
|
||||||
|
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
|
<div class="sbm-action sbm-item-create"><img src="~/img/action/add24.png" alt="@(Localiser["label.create"])" title="@(Localiser["label.create"])" /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sbm-content">
|
||||||
|
@* Affiliate filter - name etc. *@
|
||||||
|
<div class="row pb4">
|
||||||
|
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||||
|
<div class="col-sm-7">
|
||||||
|
@Html.TextBoxFor(model => model.Filter.AffiliateSearch, new { @id = "", @class = "FilterAffiliate", @maxlength = "32" })
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* Affiliate Category *@
|
||||||
|
<div class="row pb4">
|
||||||
|
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.category"]</div>
|
||||||
|
<div class="col-sm-7">
|
||||||
|
@Html.DropDownListFor(model => model.Filter.AffiliateType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterAffiliateType sbm-select" })
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@* Separate filter from results when alondside each other. *@
|
||||||
|
<div class="fixed"><div class="d-none d-md-block" style="width:8px;"></div></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-7">
|
||||||
|
|
||||||
|
@* Results Panel *@
|
||||||
|
<div class="sbm-panel-results">
|
||||||
|
<div class="sbm-panel-messages"></div>
|
||||||
|
<div class="sbm-panel-item-list"></div>
|
||||||
|
|
||||||
|
@* element templates *@
|
||||||
|
<div class="sbm-panel-item-template">
|
||||||
|
@* Affiliate item template *@
|
||||||
|
<div class="sbm-panel-item Affiliate">
|
||||||
|
<div class="sbm-header row">
|
||||||
|
<div class="col">
|
||||||
|
@* Affiliate caption *@
|
||||||
|
<div class="sbm-caption"><div class="sbm-action sbm-item-update AffiliateName"></div></div>
|
||||||
|
</div>
|
||||||
|
<div class="fixed sbm-actions">
|
||||||
|
@* Burger menu *@
|
||||||
|
<ul class="nav navbar-nav navbar-light 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 class="sbm-content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4"><div class="AffiliateType"></div></div>
|
||||||
|
<div class="col-sm-4"><div class=""></div></div>
|
||||||
|
<div class="col-sm-4 text-left text-sm-right"><div class=""></div></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4"><div class=""></div></div>
|
||||||
|
<div class="col-sm-4"><div class="AffiliateAssociationCount sbm-action-text">@Localiser["label.associations"]: <span class="AssociationCount"></span></div></div>
|
||||||
|
<div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* Burger dropdown item template - ul is ignored *@
|
||||||
|
<ul class="sbm-dropdown-menu Affiliate">
|
||||||
|
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<partial name="Panel-AffiliateDialog.cshtml" />
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
@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>
|
||||||
@@ -120,10 +120,10 @@
|
|||||||
@Localiser["label.reference"]
|
@Localiser["label.reference"]
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contacts');">@Localiser["label.contacts"]</div>
|
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contact');">@Localiser["label.contacts"]</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodities');">@Localiser["label.commodities"]</div>
|
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodity');">@Localiser["label.commodities"]</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"Send": {
|
"Send": {
|
||||||
"Using": 2,
|
"Using": 2,
|
||||||
"UserName": "businessmgr@sarand.com",
|
"UserName": "businessmgr@sarand.com",
|
||||||
"Password": "sarand-busmgr-5apP1re"
|
"Password": "sarand-busmgr-5apPh1re"
|
||||||
},
|
},
|
||||||
"Message": {
|
"Message": {
|
||||||
"AddressFrom": "DoNotReply@SaBusinessMgr.com"
|
"AddressFrom": "DoNotReply@SaBusinessMgr.com"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Base stylesheet.
|
BusMgr Portal - Base stylesheet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
body
|
body
|
||||||
@@ -19,10 +19,9 @@ div, button, input, select, textarea, table, tr, td
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
:focus, input:focus, textarea:focus, select:focus, button:focus
|
:focus, button:focus
|
||||||
{
|
{
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: inherit;
|
|
||||||
box-shadow: 0 0 0 2px #80808040 inset;
|
box-shadow: 0 0 0 2px #80808040 inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +121,15 @@ input
|
|||||||
|
|
||||||
textarea
|
textarea
|
||||||
{
|
{
|
||||||
overflow-y:scroll;
|
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 3px 2px 1px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.bold, b
|
.bold, b
|
||||||
{
|
{
|
||||||
font-weight: bold !important;
|
font-weight: bold !important;
|
||||||
@@ -389,7 +393,9 @@ td.action
|
|||||||
{
|
{
|
||||||
-moz-box-shadow: 2px 2px 3px #ccc;
|
-moz-box-shadow: 2px 2px 3px #ccc;
|
||||||
-webkit-box-shadow: 2px 2px 3px #ccc;
|
-webkit-box-shadow: 2px 2px 3px #ccc;
|
||||||
box-shadow: 2px 2px 3px #ccc;
|
box-shadow: 2px 2px 3px #ccc; /* For IE 8 */
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=3,Direction=135,Color='#cccccc')"; /* For IE 5.5 - 7 */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3,Direction=135,Color='#cccccc');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bootstrap */
|
/* Bootstrap */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Data stylesheet.
|
BusMgr Portal - Data stylesheet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Filter panel */
|
/* Filter panel */
|
||||||
@@ -8,10 +8,9 @@
|
|||||||
{
|
{
|
||||||
margin: 8px auto;
|
margin: 8px auto;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
border: solid 2px var(--color-primary);
|
border: solid 1px #979797;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
-webkit-border-radius: 6px;
|
overflow: hidden;
|
||||||
-moz-border-radius: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 576px)
|
@media (min-width: 576px)
|
||||||
@@ -21,56 +20,60 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-header
|
.sbm-panel-filter .sbm-header
|
||||||
{
|
{
|
||||||
padding: 2px 8px;
|
padding: 1px 8px 2px 8px;
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
color: #f0f0f0;
|
color: #f0f0f0;
|
||||||
background-color: var(--color-primary);
|
background-color: #979797;
|
||||||
border-bottom: solid 1px var(--color-primary);
|
border-bottom: solid 1px #979797;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-header .sbm-caption
|
.sbm-panel-filter .sbm-header .sbm-caption
|
||||||
{
|
{
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-header .sbm-action
|
.sbm-panel-filter .sbm-header .sbm-action
|
||||||
{
|
{
|
||||||
margin: 2px 0 0 8px;
|
margin: 2px 0 0 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-header .sbm-action:hover
|
.sbm-panel-filter .sbm-header .sbm-action:hover
|
||||||
{
|
{
|
||||||
background-color: #b0b0b0;
|
background-color: #b0b0b0;
|
||||||
box-shadow: 0 0 4px 2px #80808080;
|
box-shadow: 0 0 4px 2px #80808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-content
|
.sbm-panel-filter .sbm-content
|
||||||
{
|
{
|
||||||
margin: 4px 8px;
|
margin: 4px 8px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-content .sbm-control
|
.sbm-panel-filter .sbm-content .sbm-label
|
||||||
{
|
{
|
||||||
margin-bottom: 4px;
|
padding-top: 2px;
|
||||||
}
|
padding-right: 12px;
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-content .sbm-label
|
|
||||||
{
|
|
||||||
padding: 2px 12px 2px 0;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-filter > .sbm-content .sbm-button
|
.sbm-panel-filter .sbm-content input[type="text"],
|
||||||
|
.sbm-panel-filter .sbm-content select
|
||||||
|
{
|
||||||
|
min-width: 75%;
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-panel-filter .sbm-content .sbm-button
|
||||||
{
|
{
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
padding: 4px 6px 2px 6px;
|
padding: 4px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paging */
|
/* Paging */
|
||||||
@@ -88,8 +91,7 @@
|
|||||||
.sbm-panel-filter .sbm-header .sbm-results-paging .sbm-action
|
.sbm-panel-filter .sbm-header .sbm-results-paging .sbm-action
|
||||||
{
|
{
|
||||||
margin: 2px 1px 0 1px;
|
margin: 2px 1px 0 1px;
|
||||||
background-color: #a0a0a0;
|
background-color: #b0b0b0;
|
||||||
opacity: 0.8;
|
|
||||||
box-shadow: 0 0 0 1px #40404080 inset;
|
box-shadow: 0 0 0 1px #40404080 inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,8 +133,7 @@
|
|||||||
.sbm-panel-item
|
.sbm-panel-item
|
||||||
{
|
{
|
||||||
margin: 8px auto;
|
margin: 8px auto;
|
||||||
background-color: #f8f8f8;
|
border: solid 1px #979797;
|
||||||
border: solid 2px #979797;
|
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
-webkit-border-radius: 6px;
|
-webkit-border-radius: 6px;
|
||||||
-moz-border-radius: 6px;
|
-moz-border-radius: 6px;
|
||||||
@@ -161,7 +162,7 @@
|
|||||||
|
|
||||||
.sbm-panel-item > .sbm-header .sbm-caption .sbm-action:hover
|
.sbm-panel-item > .sbm-header .sbm-caption .sbm-action:hover
|
||||||
{
|
{
|
||||||
color: var(--color-primary);
|
color: var(--color-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-item > .sbm-header .sbm-actions .sbm-action
|
.sbm-panel-item > .sbm-header .sbm-actions .sbm-action
|
||||||
@@ -177,7 +178,7 @@
|
|||||||
|
|
||||||
.sbm-panel-item > .sbm-content
|
.sbm-panel-item > .sbm-content
|
||||||
{
|
{
|
||||||
margin: 6px 8px;
|
margin: 4px 8px;
|
||||||
padding: 4px 4px;
|
padding: 4px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,46 +187,38 @@
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Profile Sports */
|
@media (min-width: 576px)
|
||||||
|
|
||||||
.sbm-panel-item.ProfileSport,
|
|
||||||
.sbm-panel-item.ProfileSport > .sbm-header
|
|
||||||
{
|
{
|
||||||
border-color: var(--color-alt2);
|
.sbm-panel-filter
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Organisations */
|
/* Item statuses */
|
||||||
|
|
||||||
.sbm-panel-item.Organisation,
|
.sbm-status-awa
|
||||||
.sbm-panel-item.Organisation > .sbm-header
|
|
||||||
{
|
{
|
||||||
border-color: var(--color-alt3);
|
color: darkorange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Articles */
|
.sbm-status-atv
|
||||||
|
|
||||||
.sbm-panel-item.Article,
|
|
||||||
.sbm-panel-item.Article > .sbm-header
|
|
||||||
{
|
{
|
||||||
border-color: var(--color-article);
|
color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-item.Article > .sbm-header
|
.sbm-status-ina
|
||||||
{
|
{
|
||||||
background-color: var(--color-article-pale);
|
color: darkred;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opportunitys */
|
.sbm-status-hld
|
||||||
|
|
||||||
.sbm-panel-item.Opportunity,
|
|
||||||
.sbm-panel-item.Opportunity > .sbm-header
|
|
||||||
{
|
{
|
||||||
border-color: var(--color-opportunity);
|
color: dodgerblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-item.Opportunity > .sbm-header
|
.sbm-status-del
|
||||||
{
|
{
|
||||||
background-color: var(--color-opportunity-pale);
|
color: purple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The End */
|
/* The End */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Form stylesheet.
|
BusMgr Portal - Form stylesheet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Panels */
|
/* Panels */
|
||||||
@@ -7,20 +7,20 @@
|
|||||||
.sbm-panel-info, .sbm-panel-form
|
.sbm-panel-info, .sbm-panel-form
|
||||||
{
|
{
|
||||||
max-width: 720px;
|
max-width: 720px;
|
||||||
margin: 16px auto;
|
margin: 24px auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #f8f8f8;
|
background-color: #fff;
|
||||||
border: solid 2px #606060;
|
border: solid 2px #979797;
|
||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
border-radius: 6px;
|
border-radius: 4px;
|
||||||
-webkit-border-radius: 6px;
|
-webkit-border-radius: 4px;
|
||||||
-moz-border-radius: 6px;
|
-moz-border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-form.security
|
.sbm-panel-form.security
|
||||||
{
|
{
|
||||||
max-width: 560px;
|
max-width: 520px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 576px)
|
@media (min-width: 576px)
|
||||||
@@ -40,24 +40,14 @@
|
|||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-form > .sbm-header
|
|
||||||
{
|
|
||||||
background-color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-header .sbm-caption,
|
.sbm-panel-info > .sbm-header .sbm-caption,
|
||||||
.sbm-panel-form > .sbm-header .sbm-caption
|
.sbm-panel-form > .sbm-header .sbm-caption
|
||||||
{
|
{
|
||||||
font-size: 1.25rem;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--color-primary-dark);
|
color: var(--color-primary-dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-form > .sbm-header .sbm-caption
|
|
||||||
{
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-header .sbm-action img:hover,
|
.sbm-panel-info > .sbm-header .sbm-action img:hover,
|
||||||
.sbm-panel-form > .sbm-header .sbm-action img:hover
|
.sbm-panel-form > .sbm-header .sbm-action img:hover
|
||||||
{
|
{
|
||||||
@@ -66,29 +56,18 @@
|
|||||||
box-shadow: 2px 2px 4px 0 #80808080;
|
box-shadow: 2px 2px 4px 0 #80808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-header .dropdown-menu,
|
|
||||||
.sbm-panel-form > .sbm-header .dropdown-menu
|
|
||||||
{
|
|
||||||
padding: 4px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-header ul.nav,
|
|
||||||
.sbm-panel-form > .sbm-header ul.nav
|
|
||||||
{
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-header .dropdown-menu .sbm-action,
|
|
||||||
.sbm-panel-form > .sbm-header .dropdown-menu .sbm-action
|
|
||||||
{
|
|
||||||
font-size: .8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-panel-info > .sbm-content,
|
.sbm-panel-info > .sbm-content,
|
||||||
.sbm-panel-form > .sbm-content
|
.sbm-panel-form > .sbm-content
|
||||||
{
|
{
|
||||||
|
max-height: 400px;
|
||||||
padding: 12px 12px;
|
padding: 12px 12px;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-panel-info > .sbm-content
|
||||||
|
{
|
||||||
|
padding: 8px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-panel-section.sbm-edit .sbm-panel-info,
|
.sbm-panel-section.sbm-edit .sbm-panel-info,
|
||||||
@@ -128,20 +107,13 @@
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-form .sbm-form-control .sbm-caption,
|
|
||||||
.sbm-form .sbm-form-control .sbm-label
|
.sbm-form .sbm-form-control .sbm-label
|
||||||
{
|
{
|
||||||
margin: 0 0 4px 0;
|
margin: 0 0 8px 0;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-form .sbm-form-control .sbm-caption
|
|
||||||
{
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sbm-form .sbm-form-control .sbm-label-text
|
.sbm-form .sbm-form-control .sbm-label-text
|
||||||
{
|
{
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -158,19 +130,39 @@
|
|||||||
|
|
||||||
.sbm-form .sbm-form-control
|
.sbm-form .sbm-form-control
|
||||||
{
|
{
|
||||||
margin: 0 0 12px 0;
|
margin: 0 0 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-form .sbm-form-control .sbm-label
|
||||||
|
{
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-form .sbm-form-control .sbm-label-text
|
||||||
|
{
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-form .sbm-form-control .sbm-note
|
||||||
|
{
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-form .sbm-input, .sbm-form .sbm-textarea, .sbm-form .sbm-select
|
.sbm-form .sbm-input, .sbm-form .sbm-textarea, .sbm-form .sbm-select
|
||||||
{
|
{
|
||||||
padding: 3px 8px 0 8px;
|
padding: 3px 8px 4px 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 30px;
|
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.3;
|
line-height: 1.25;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #595959;
|
border: 1px solid #595959;
|
||||||
border-radius: 3px;
|
border-radius: 2px;
|
||||||
|
-webkit-border-radius: 2px;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +173,8 @@
|
|||||||
|
|
||||||
.sbm-form .sbm-textarea, .sbm-form .sbm-select[multiple="multiple"]
|
.sbm-form .sbm-textarea, .sbm-form .sbm-select[multiple="multiple"]
|
||||||
{
|
{
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 2px;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 2px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,10 +185,8 @@
|
|||||||
|
|
||||||
.sbm-form .sbm-form-control.sbm-error .sbm-input, .sbm-form .sbm-form-control.sbm-error .sbm-textarea, .sbm-form .sbm-form-control.sbm-error .sbm-select
|
.sbm-form .sbm-form-control.sbm-error .sbm-input, .sbm-form .sbm-form-control.sbm-error .sbm-textarea, .sbm-form .sbm-form-control.sbm-error .sbm-select
|
||||||
{
|
{
|
||||||
color: #606060;
|
color: #DC143C;
|
||||||
color: var(--color-primary);
|
border-color: #DC143C;
|
||||||
border-color: #606060;
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control messages */
|
/* Control messages */
|
||||||
@@ -206,7 +196,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
font-size: 16px;
|
font-size: 1.00rem;
|
||||||
background-position: left top;
|
background-position: left top;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
@@ -226,16 +216,13 @@
|
|||||||
{
|
{
|
||||||
height: auto;
|
height: auto;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 120px;
|
min-width: 80px;
|
||||||
padding: 4px 8px;
|
padding: 4px 2px;
|
||||||
font-size: 16px;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #606060;
|
color: #fff;
|
||||||
color: var(--color-primary);
|
background-color: #d4af37;
|
||||||
background-color: #DFD2E1;
|
border: 1px solid #d4af37;
|
||||||
border: solid 1px #606060;
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +230,6 @@
|
|||||||
.sbm-form input[type="button"].sbm-button:hover,
|
.sbm-form input[type="button"].sbm-button:hover,
|
||||||
.sbm-form input[type="submit"].sbm-button:hover
|
.sbm-form input[type="submit"].sbm-button:hover
|
||||||
{
|
{
|
||||||
background-color: #EFE8F0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Password strength */
|
/* Password strength */
|
||||||
@@ -254,7 +240,8 @@
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
margin: 6px 24px;
|
margin: 6px 24px;
|
||||||
border-color: #595959;
|
border-color: #595959;
|
||||||
box-shadow: none;
|
-moz-box-shadow: none;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
Main stylesheet.
|
BusMgr Portal - Main stylesheet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
|
|
||||||
:root
|
:root
|
||||||
{
|
{
|
||||||
/*
|
/* Colour analysis: https://www.colorhexa.com/ */
|
||||||
#556B2F Dark Olive Green
|
/* #4b0082 - Indigo. Ref. https://www.crispedge.com/color/4b0082 */
|
||||||
Ref. https://www.crispedge.com/color/556B2F
|
--color-primary: #4b0082;
|
||||||
Darker: #445525, #33401c. Lighter: #768858, #99a682, #a6c275, #b7ce90.
|
--color-light: #9b71b9;
|
||||||
*/
|
--color-pale: #ebe2f1;
|
||||||
--color-primary: #556B2F;
|
|
||||||
--color-primary-dark: #425324;
|
|
||||||
--color-primary-light: #a0ac8b;
|
|
||||||
--color-primary-pale: #eceee7;
|
|
||||||
/* Tetrad/Square colors */
|
/* Tetrad/Square colors */
|
||||||
--color-alt1: #2f6b63;
|
--color-alt1: #820a00;
|
||||||
--color-alt2: #452f6b;
|
--color-alt2: #378200;
|
||||||
--color-alt3: #6b2f37;
|
--color-alt3: #007882;
|
||||||
/* Activity colours */
|
|
||||||
--color-article-dark: #7339ac;
|
|
||||||
--color-article: #9966CC;
|
|
||||||
--color-article-light: #b38cd9;
|
|
||||||
--color-article-pale: #decdee;
|
|
||||||
--color-opportunity-dark: #8f6b24;
|
|
||||||
--color-opportunity: #CC9933;
|
|
||||||
--color-opportunity-light: #dbb870;
|
|
||||||
--color-opportunity-pale: #f3e7d0;
|
|
||||||
/* Specific colours */
|
|
||||||
--color-dialog: var(--color-alt3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Document */
|
/* Document */
|
||||||
@@ -49,13 +34,36 @@ html
|
|||||||
|
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
font-family: Verdana, Helvetica, Arial, Lucida, sans-serif;
|
font-family: Arial, Verdana, Helvetica, Lucida, sans-serif;
|
||||||
background-color: #e9edf6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body > .container
|
body > .container
|
||||||
{
|
{
|
||||||
padding: 0 1%;
|
padding: 0 0.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px)
|
||||||
|
{
|
||||||
|
.container
|
||||||
|
{
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px)
|
||||||
|
{
|
||||||
|
.container
|
||||||
|
{
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576px)
|
||||||
|
{
|
||||||
|
.container
|
||||||
|
{
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sticky footer styles */
|
/* Sticky footer styles */
|
||||||
@@ -69,7 +77,7 @@ html
|
|||||||
body
|
body
|
||||||
{
|
{
|
||||||
/* Margin bottom by footer height */
|
/* Margin bottom by footer height */
|
||||||
/*margin-bottom: 60px;*/
|
margin-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
@@ -77,6 +85,7 @@ body
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 0 2%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* Set the fixed height of the footer here */
|
/* Set the fixed height of the footer here */
|
||||||
height: 60px;
|
height: 60px;
|
||||||
@@ -113,11 +122,14 @@ button.accept-policy
|
|||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Information */
|
/* Page caption */
|
||||||
|
.sbm-page-caption
|
||||||
.sbm-para
|
|
||||||
{
|
{
|
||||||
margin: 8px 0;
|
margin: 0;
|
||||||
|
padding: 16px 24px;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
@@ -125,8 +137,7 @@ button.accept-policy
|
|||||||
a, a:hover
|
a, a:hover
|
||||||
{
|
{
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
color: #606060;
|
color: #d4af37;
|
||||||
color: var(--color-primary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a:focus
|
a:focus
|
||||||
@@ -135,11 +146,16 @@ a:focus
|
|||||||
outline-width: thin;
|
outline-width: thin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-action
|
.sbm-action, .sbm-action-text
|
||||||
{
|
{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sbm-action-text:hover
|
||||||
|
{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.sbm-action-link
|
.sbm-action-link
|
||||||
{
|
{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -169,11 +185,11 @@ a:focus
|
|||||||
padding: 12px 12px;
|
padding: 12px 12px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
color: #404040;
|
color: #404040;
|
||||||
background-color: #b7ce90;
|
background-color: #e0e0e0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 12px;
|
border-radius: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .5s ease-in-out;
|
transition: all .5s ease-in-out;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -185,12 +201,18 @@ a:focus
|
|||||||
|
|
||||||
.sbm-button-action:hover
|
.sbm-button-action:hover
|
||||||
{
|
{
|
||||||
background-color: #a6c275;
|
background-color: #b0b0b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbm-button-action:focus
|
||||||
|
{
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 4px 2px #808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sbm-button-cta:hover
|
.sbm-button-cta:hover
|
||||||
{
|
{
|
||||||
background: #a6c275;
|
background: #808080 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Notification --- */
|
/* --- Notification --- */
|
||||||
@@ -254,7 +276,6 @@ a:focus
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --- Modal Please wait --- */
|
/* --- Modal Please wait --- */
|
||||||
|
|
||||||
#sbm-please-wait
|
#sbm-please-wait
|
||||||
{
|
{
|
||||||
display: none;
|
display: none;
|
||||||
@@ -277,7 +298,6 @@ a:focus
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Dialogs */
|
/* Dialogs */
|
||||||
|
|
||||||
.sbm-dialog
|
.sbm-dialog
|
||||||
{
|
{
|
||||||
display: none;
|
display: none;
|
||||||
@@ -287,21 +307,25 @@ a:focus
|
|||||||
{
|
{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #e9edf6;
|
}
|
||||||
|
|
||||||
|
.ui-dialog .ui-dialog-titlebar
|
||||||
|
{
|
||||||
|
padding: 6px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-dialog .ui-dialog-content
|
||||||
|
{
|
||||||
|
padding: 6px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog.ui-widget.ui-widget-content
|
.ui-dialog.ui-widget.ui-widget-content
|
||||||
{
|
{
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
border-color: #606060;
|
border-color: #d4af37;
|
||||||
border-color: var(--color-dialog);
|
-moz-box-shadow: 4px 4px 6px #ccc;
|
||||||
-moz-box-shadow: 4px 4px 6px var(--color-dialog);
|
-webkit-box-shadow: 4px 4px 6px #ccc;
|
||||||
-webkit-box-shadow: 4px 4px 6px var(--color-dialog);
|
overflow: hidden;
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog.ui-widget.sbm-dialog-border-thin.ui-widget-content
|
|
||||||
{
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog.ui-widget.ui-widget-content.ui-corner-all
|
.ui-dialog.ui-widget.ui-widget-content.ui-corner-all
|
||||||
@@ -309,68 +333,41 @@ a:focus
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog.ui-widget.sbm-dialog-rounding-none.ui-widget-content.ui-corner-all
|
|
||||||
{
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog.ui-widget .ui-widget-header
|
.ui-dialog.ui-widget .ui-widget-header
|
||||||
{
|
{
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
color: #f0f0f0;
|
color: #fff;
|
||||||
background-color: #606060;
|
background-color: #d4af37;
|
||||||
border-color: var(--color-dialog);
|
border-color: #d4af37;
|
||||||
background-color: #606060;
|
|
||||||
background-color: var(--color-dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog.ui-widget .ui-widget-header.ui-corner-all
|
.ui-widget-content
|
||||||
{
|
{
|
||||||
border-radius: 0;
|
font-size: 16px;
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog.sbm-dialog-titlebar-hide .ui-dialog-titlebar
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog.dialog-no-close .ui-dialog-titlebar-close
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog.ui-widget .ui-dialog-content.ui-widget-content
|
|
||||||
{
|
|
||||||
padding: 4px 8px 0 8px;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog .ui-dialog-buttonpane.ui-widget-content
|
.ui-dialog .ui-dialog-titlebar.ui-corner-all
|
||||||
{
|
{
|
||||||
margin-top: 0;
|
border-bottom-left-radius: 0;
|
||||||
padding: 4px 16px 4px 16px;
|
border-bottom-right-radius: 0;
|
||||||
background-color: transparent;
|
|
||||||
border-color: #606060;
|
|
||||||
border-color: var(--color-dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset
|
.ui-dialog.no-close .ui-dialog-titlebar-close
|
||||||
{
|
{
|
||||||
float: none;
|
/*display: none;*/
|
||||||
width: 100%;
|
}
|
||||||
text-align: right;
|
|
||||||
|
.ui-dialog .ui-dialog-buttonpane
|
||||||
|
{
|
||||||
|
border-color: #d4af37;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-dialog .ui-dialog-buttonpane button
|
.ui-dialog .ui-dialog-buttonpane button
|
||||||
{
|
{
|
||||||
min-width: 60px;
|
|
||||||
padding: 6px 16px 4px 16px;
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #606060;
|
background-color: #d4af37;
|
||||||
background-color: var(--color-dialog);
|
border-color: #d4af37;
|
||||||
border-color: #606060;
|
|
||||||
border-color: var(--color-dialog);
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +385,7 @@ a:focus
|
|||||||
.ui-datepicker .ui-datepicker-header
|
.ui-datepicker .ui-datepicker-header
|
||||||
{
|
{
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #606060;
|
border: 1px solid #d4af37;
|
||||||
border-color: var(--color-dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The End */
|
/* The End */
|
||||||
|
|||||||
|
After Width: | Height: | Size: 582 B |
|
After Width: | Height: | Size: 923 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 529 B |
|
After Width: | Height: | Size: 765 B |
|
After Width: | Height: | Size: 946 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 829 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 697 B |
|
After Width: | Height: | Size: 1011 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 604 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 594 B |
|
After Width: | Height: | Size: 859 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 479 B |
|
After Width: | Height: | Size: 675 B |
|
After Width: | Height: | Size: 577 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 498 B |
|
After Width: | Height: | Size: 688 B |
|
After Width: | Height: | Size: 605 B |
|
After Width: | Height: | Size: 601 B |
|
After Width: | Height: | Size: 904 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 555 B |