diff --git a/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs b/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs index 9b316ef..55b47e1 100644 --- a/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs +++ b/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs @@ -184,33 +184,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App Financial.FinancialsAccessControl = (sessionConfig != null && !sessionConfig.AllowOption(Sbm.ConfigOption.AllowFinancialsAccessControl)); } - public bool UserCanViewFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) - { - if (!Financial.FinancialsAccessControl) return true; - if (Financial.UpdateFinancials || Financial.ViewFinancials) - { - // If specific type of financial is requested, check that view is not denied. - if (financialType > 0 && IsSecurityRightDenied(Sbm.SecurityRight.Financial_ViewByType, new SysId((int)financialType))) - return false; - return true; - } - return false; - } - - public bool UserCanUpdateFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) - { - if (!Financial.FinancialsAccessControl) return true; - if (Financial.UpdateFinancials) - { - // If specific type of financial is requested, check that update is not denied. - if (financialType > 0 && IsSecurityRightDenied(Sbm.SecurityRight.Financial_UpdateByType, new SysId((int)financialType))) - return false; - return true; - } - return false; - } - - public bool UserCanAccessFinancialViewOfType(Sbm.FinancialType financialType) + private bool UserCanAccessFinancialViewOfType(Sbm.FinancialType financialType) { if ((int)financialType < 1) return false; // If specific type of financial is requested, check that view is not denied. @@ -219,7 +193,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App return true; } - public bool UserCanAccessFinancialUpdateOfType(Sbm.FinancialType financialType) + private bool UserCanAccessFinancialUpdateOfType(Sbm.FinancialType financialType) { if ((int)financialType < 1) return false; // If specific type of financial is requested, check that update is not denied. @@ -228,6 +202,38 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App return true; } + /// Does the user have sufficient rights to view the specified financials. + public bool UserCanViewFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) + { + if (!Financial.FinancialsAccessControl) return true; + if (Financial.UpdateFinancials || Financial.ViewFinancials) + { + // If specific type of financial is requested, check that view access is not denied. + if (financialType == Sbm.FinancialType.CommoditySupply) + return Financial.ViewCommoditySupplyFinancials; + else if (financialType == Sbm.FinancialType.CommoditySales) + return Financial.ViewCommoditySalesFinancials; + else return true; + } + return false; + } + + /// Does the user have sufficient rights to update the specified financials. + public bool UserCanUpdateFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) + { + if (!Financial.FinancialsAccessControl) return true; + if (Financial.UpdateFinancials) + { + // If specific type of financial is requested, check that update access is not denied. + if (financialType == Sbm.FinancialType.CommoditySupply) + return Financial.UpdateCommoditySupplyFinancials; + else if (financialType == Sbm.FinancialType.CommoditySales) + return Financial.UpdateCommoditySalesFinancials; + else return true; + } + return false; + } + //------------------------------------------------------------------- // Security rights - Contacts. public class ContactsProfile @@ -486,7 +492,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //------------------------------------------------------------------- // Security rights. - private bool UserHasSecurityRight(Sbm.SecurityRight securityRight, SysId dataItemId = null) + public bool UserHasSecurityRight(Sbm.SecurityRight securityRight, SysId dataItemId = null) { String rightCode = securityRights.GetCodeForType(securityRight); if (StringUtil.IsEmpty(rightCode)) return false; diff --git a/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs b/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs index 98c2670..60cfcd1 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs @@ -275,7 +275,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public decimal FreeStock { get; set; } = 0.0m; public DateTime StockTakeDate { get; set; } = DateTime.MinValue; public decimal StockTakeQty { get; set; } = 0.0m; - // Projecetd sales. + // Projected sales. public SysId CommodityIdSalesProj { get; set; } = new SysId(); public decimal SalesProjAnnual { get; set; } = 0.0m; public decimal SalesProjMonth01 { get; set; } = 0.0m; @@ -929,7 +929,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus FreeStock = data.FreeStock; StockTakeDate = data.StockTakeDate; StockTakeQty = data.StockTakeQty; - // Projecetd sales. + // Projected sales. CommodityIdSalesProj = data.CommodityIdSalesProj; SalesProjAnnual = data.SalesProjAnnual; SalesProjMonth01 = data.SalesProjMonth01; @@ -1047,7 +1047,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public ValidValue FreeStock { get; set; } = ValidValue.Valid; public ValidValue StockTakeDate { get; set; } = ValidValue.Valid; public ValidValue StockTakeQty { get; set; } = ValidValue.Valid; - // Projecetd sales. + // Projected sales. public ValidValue CommodityIdSalesProj { get; set; } = ValidValue.Valid; public ValidValue SalesProjMonthlyProp { get; set; } = ValidValue.Valid; public ValidValue SalesProjAnnual { get; set; } = ValidValue.Valid; diff --git a/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole.cs b/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole.cs index 7e3f931..fc0cb84 100644 --- a/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole.cs +++ b/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole.cs @@ -405,23 +405,32 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles // Application Configuration. - Display and caption for data attributes. public virtual bool DisplayAttribute(SbmDbDfn.ColumnIdx column) { + // Only need to intercept fields that are partnered with other fields to determine display. switch (column) { - // Fields that are tied to other columns for the purposes of controlling their display. + // Commodity - specification. + case SbmDbDfn.ColumnIdx.Commodity_Weight: case SbmDbDfn.ColumnIdx.Commodity_UomIdWeight: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Weight); + case SbmDbDfn.ColumnIdx.Commodity_Length: case SbmDbDfn.ColumnIdx.Commodity_UomIdLength: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Length); + case SbmDbDfn.ColumnIdx.Commodity_Volume: case SbmDbDfn.ColumnIdx.Commodity_UomIdVolume: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Volume); + case SbmDbDfn.ColumnIdx.Commodity_Density: case SbmDbDfn.ColumnIdx.Commodity_UomIdDensity: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Density); + case SbmDbDfn.ColumnIdx.Commodity_BoxQuantity: case SbmDbDfn.ColumnIdx.Commodity_UomIdBox: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_BoxQuantity); + case SbmDbDfn.ColumnIdx.Commodity_TimeProd: case SbmDbDfn.ColumnIdx.Commodity_UomIdTimeProd: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_TimeProd); + case SbmDbDfn.ColumnIdx.Commodity_MaterialCost: case SbmDbDfn.ColumnIdx.Commodity_CurrencyIdMaterial: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_MaterialCost); + case SbmDbDfn.ColumnIdx.Commodity_ExWorksCost: case SbmDbDfn.ColumnIdx.Commodity_CurrencyIdExWorks: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_ExWorksCost); case SbmDbDfn.ColumnIdx.Commodity_CommodityIdSalesProj: @@ -439,10 +448,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles case SbmDbDfn.ColumnIdx.Commodity_SalesProjMonth11: case SbmDbDfn.ColumnIdx.Commodity_SalesProjMonth12: return UserContext.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_SalesProjAnnual); - default: // Sep-08: Session profile should be able to handle all fields now (rather than just those that are controlled) + default: return UserContext.GetOwnerOption_ShowField(column); } - //return true; } //------------------------------------------------------------------- diff --git a/SaBusMgrStandardBase/Base/Core/ISbmSecurityProfile_Core.cs b/SaBusMgrStandardBase/Base/Core/ISbmSecurityProfile_Core.cs index 81c651c..19f5ef5 100644 --- a/SaBusMgrStandardBase/Base/Core/ISbmSecurityProfile_Core.cs +++ b/SaBusMgrStandardBase/Base/Core/ISbmSecurityProfile_Core.cs @@ -27,8 +27,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Core // Security - Financials. bool UserCanViewFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any); bool UserCanUpdateFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any); - bool UserCanAccessFinancialViewOfType(Sbm.FinancialType financialType = Sbm.FinancialType.Any); - bool UserCanAccessFinancialUpdateOfType(Sbm.FinancialType financialType = Sbm.FinancialType.Any); // Security - Transactions. bool UserCanAccessTransactionsOfType(Sbm.TransactionType transactionType); @@ -39,6 +37,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Core bool UserCanUpdateItemType(Sbm.ItemType itemType); bool UserCanRemoveItemType(Sbm.ItemType itemType); + // Security rights. + public bool UserHasSecurityRight(Sbm.SecurityRight securityRight, SysId dataItemId = null); + //------------------------------------------------------------------- /// Refresh profile. void RefreshProfile(SbmSessionConsole sessionConsole, SaSecurityConsole securityConsole, SysId userId, List securityRights); diff --git a/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs b/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs index ba9378a..02c959d 100644 --- a/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs @@ -28,6 +28,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles base(SbmGlobals.Application.GetBusMgrDatabase(userContext.SessionContext)) { UserContext = userContext; + RegisterSecurityRights(); } protected override void Dispose(bool disposing) { diff --git a/SaBusinessMgrCoreWebPortal/Localisation/SbmPortalProperties.resx b/SaBusinessMgrCoreWebPortal/Localisation/SbmPortalProperties.resx index 5bd4c36..66a0126 100644 --- a/SaBusinessMgrCoreWebPortal/Localisation/SbmPortalProperties.resx +++ b/SaBusinessMgrCoreWebPortal/Localisation/SbmPortalProperties.resx @@ -520,7 +520,7 @@ Cost price - Retail price + RRP Tax code @@ -621,4 +621,61 @@ Select Contact + + Dimensions + + + Catalog ref + + + ICN tariff code + + + Place of origin + + + Material currency + + + Material cost + + + Ex-works currency + + + Ex-works cost + + + Specification + + + Material + + + Finish + + + Planned RRP + + + Indicative carriage cost + + + Units + + + Weight + + + Length + + + Volume + + + Density + + + Box quantity + \ No newline at end of file diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs index e3c92aa..5c0852a 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs @@ -1,27 +1,17 @@ using Microsoft.AspNetCore.Mvc; -using Sarand.BusinessMgr.Net.Core.Web.App; -using Sarand.BusinessMgr.Net.Core.Web.Helpers; -using Sarand.BusinessMgr.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.BusinessMgr.Web.Portal.Models; +using Sarand.BusinessMgr.Web.Portal.Models.Commodities; +using Sarand.BusinessMgr.Web.Portal.Models.Contacts; 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; -using Sarand.BusinessMgr.Web.Portal.Models.Commodities; using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities @@ -32,16 +22,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities partial class CommodityController { //------------------------------------------------------------------- - // Commodity data. + // Item data. private class CommodityListData : AjaxResponse_Data.ItemData_Base { - public String TypeCode { get; set; } - public String TypeDesc { get; set; } + // Item properties with specific handling. public String Code { get; set; } - public String Desc { get; set; } - public String SalesPriceFmt { get; set; } - public String SalesUnit { get; set; } - public String CostPriceFmt { get; set; } + public String Caption { get; set; } + // Fields. + public class FieldData + { + // Item property values keyed to match field name. + public Dictionary Value { get; } = new Dictionary(); + } + public FieldData Field { get; } = new FieldData(); } private enum CommodityDataGroup { @@ -49,48 +42,43 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities } private class CommodityItemData : CommodityListData { - // Commodity properties. - public String DrawingIssue { get; set; } - public String AssocIdCustomer { get; set; } - public String AssocIdSupplier { get; set; } - // Sales. - public String SalesPrice { get; set; } - // Purchasing. - public String CostPrice { get; set; } - // Specification. - // Production. + // Affiliate properties with specific handling. + public String TypeCode { get; set; } + public String TypeDesc { get; set; } } private void PopulateCommodityResponseListData(SbmCommodity commodity, CommodityListData data) { data.Id = SysId.ToString(commodity.Id); - data.TypeCode = Internals.CommodityTypeCodes.GetCodeForType(commodity.CommodityType); - data.TypeDesc = Internals.CommodityTypeCodes.GetDescForType(commodity.CommodityType); - data.Code = commodity.Code; - data.Desc = commodity.DescBrief; - data.SalesPriceFmt = StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.SalesPrice, SbmInternals.CurrencyDecimalsDefault, 0, ',')); - data.SalesUnit = StringUtil.NullOnBlank(Internals.GetUnitOfMeasureCaption(commodity.UomIdSale)); - data.CostPriceFmt = StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.CostPrice, SbmInternals.CurrencyDecimalsDefault, 0, ',')); - // Common properties. - data.Notes = commodity.Notes; - data.StatusCode = commodity.StatusCode; - data.StatusDesc = commodity.StatusDesc; } private void PopulateCommodityResponseItemData(SbmCommodity commodity, CommodityItemData data, HashSet dataGroups = null) { PopulateCommodityResponseListData(commodity, data as CommodityListData); + // Prominent properties for selecting and editing. + data.Code = commodity.Code; + data.Caption = commodity.DescBrief; + // Affiliate type - populate for list ('Type' property populated with desc) and form (Type Code & Desc). + data.TypeCode = Internals.CommodityTypeCodes.GetCodeForType(commodity.CommodityType); + data.TypeDesc = Internals.CommodityTypeCodes.GetDescForType(commodity.CommodityType); + data.Field.Value.Add($"{Model_Commodity.ItemField.Type}", Internals.CommodityTypeCodes.GetDescForType(commodity.CommodityType)); // Commodity properties. - data.DrawingIssue = StringUtil.NullOnBlank(commodity.DrawingIssue); - data.AssocIdCustomer = StringUtil.NullOnBlank(SysId.ToString(commodity.AssociationIdCustomer)); - data.AssocIdSupplier = StringUtil.NullOnBlank(SysId.ToString(commodity.AssociationIdSupplier)); + data.Field.Value.Add($"{Model_Commodity.ItemField.Code}", commodity.Code); + data.Field.Value.Add($"{Model_Commodity.ItemField.DescBrief}", commodity.DescBrief); + data.Field.Value.Add($"{Model_Commodity.ItemField.DrawingIssue}", commodity.DrawingIssue); + data.Field.Value.Add($"{Model_Commodity.ItemField.SalesPriceFmt}", StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.SalesPrice, SbmInternals.CurrencyDecimalsDefault, 0, ','))); + data.Field.Value.Add($"{Model_Commodity.ItemField.SalesUnit}", StringUtil.NullOnBlank(Internals.GetUnitOfMeasureCaption(commodity.UomIdSale))); + data.Field.Value.Add($"{Model_Commodity.ItemField.CostPriceFmt}", StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.CostPrice, SbmInternals.CurrencyDecimalsDefault, 0, ','))); + data.Field.Value.Add($"{Model_Commodity.ItemField.AssocIdCustomer}", StringUtil.NullOnBlank(SysId.ToString(commodity.AssociationIdCustomer))); + data.Field.Value.Add($"{Model_Commodity.ItemField.AssocIdSupplier}", StringUtil.NullOnBlank(SysId.ToString(commodity.AssociationIdSupplier))); if (dataGroups != null && dataGroups.Contains(CommodityDataGroup.Sales)) { // Sales. - data.SalesPrice = StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.SalesPrice, SbmInternals.CurrencyDecimalsDefault)); + data.Field.Value.Add($"{Model_Commodity.ItemField.SalesPrice}", StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.SalesPrice, SbmInternals.CurrencyDecimalsDefault))); + data.Field.Value.Add($"{Model_Commodity.ItemField.UomIdSale}", StringUtil.NullOnBlank(SysId.ToString(commodity.UomIdSale))); } if (dataGroups != null && dataGroups.Contains(CommodityDataGroup.Purchasing)) { // Purchasing. - data.CostPrice = StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.CostPrice, SbmInternals.CurrencyDecimalsDefault)); + data.Field.Value.Add($"{Model_Commodity.ItemField.CostPrice}", StringUtil.NullOnBlank(StringUtil.FormatNumeric(commodity.CostPrice, SbmInternals.CurrencyDecimalsDefault))); } if (dataGroups != null && dataGroups.Contains(CommodityDataGroup.Specification)) { @@ -100,74 +88,87 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities { // Production. } + // Common properties. + data.StatusCode = commodity.StatusCode; + data.StatusDesc = commodity.StatusDesc; + data.Field.Value.Add($"{Model_Contact.ItemField.Status}", commodity.StatusDesc); + // Cleanse field values. + data.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value)); + // Populate item list values that might be cleared during update after removing blank values to ensure that blank values are published. + data.Field.Value.Add($"{Model_Commodity.ItemField.Notes}", commodity.Notes); + data.Field.Value.Add($"{Model_Commodity.ItemField.UpdatedOn}", Localiser.FormatDate(commodity.UpdateStamp.On)); + } + + //------------------------------------------------------------------- + // Commodity configuration. + //------------------------------------------------------------------- + private class AjaxResponse_CommodityConfig : AjaxResponse_Data + { + // Construction. + public AjaxResponse_CommodityConfig(SbmModel_Portal model) : base(model) { } + // Configuration. + public Model_Commodity.ListConfigData Config { get; } = new Model_Commodity.ListConfigData(); + public Model_Commodity.ItemConfigData ConfigCmd { get; } = new Model_Commodity.ItemConfigData(); + // Reference data. + public List CommodityTypes { get; } = new List(); + public List Statuses { get; } = new List(); + public String DefaultStatusCode { get; set; } + } + // Ajax request. + [HttpPost] + [Route("Commodity/Ajax/Config")] + [Route("Commodity/Ajax/GetConfig")] + public IActionResult Ajax_CommodityConfig(Model_Commodity model) + { + AjaxResponse_CommodityConfig responseData = new AjaxResponse_CommodityConfig(model); + String messageTitle = Localiser["caption.commodities"]; + + // Validate session and referrer. + if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); + if (!ValidReferer) return Forbid(); + RefreshModel(model); + + // Populate configuration data. + PopulateCommodityConfig(model, responseData); + + // Complete response. + responseData.Success = true; + return Json(responseData); + } + private void PopulateCommodityConfig(Model_Commodity model, AjaxResponse_CommodityConfig responseData) + { + // Configuration. + model.PopulateListConfig(responseData.Config); + model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.CommodityType.Unknown); + + // Reference data - commodity types. + foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) + responseData.CommodityTypes.Add(commodityType.Code, commodityType.Desc); + + // Reference data - statuses. + foreach (SaStatus status in SbmCommodity.ValidStatuses.FindAll(item => item != SaStatus.Deleted)) + responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); + responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmCommodity.DefaultStatus); } //------------------------------------------------------------------- // Commodity list. //------------------------------------------------------------------- - private class AjaxResponse_CommodityList : AjaxResponse_Data + private class AjaxResponse_CommodityList : AjaxResponse_CommodityConfig { // Construction. public AjaxResponse_CommodityList(SbmModel_Portal model) : base(model) { } + // View mode. + public class ModeData + { + public bool? Search { get; set; } + public bool? Maintain { get; set; } + public bool? StockControl { get; set; } + public bool? StockTake { get; set; } + } + public ModeData Mode { get; set; } // Commodity list. public List Commodities { get; } = new List(); - // Commodity configuration. - public class ConfigData - { - // Optional columns to show. - public class ShowColumnData - { - public bool? CatalogRef { get; set; } - public bool? Weight { get; set; } - public bool? PackQtySale { get; set; } - public bool? StockAllocated { get; set; } - public bool? StockLevelSales { get; set; } - public bool? StockAvailable { get; set; } - } - public ShowColumnData ShowColumn { get; } = new ShowColumnData(); - // Optional fields to show. - public class ShowFieldData - { - public bool? DrawingIssue { get; set; } - public bool? DrawingNo { get; set; } - public bool? Department { get; set; } - public bool? CatalogRef { get; set; } - public bool? Volume { get; set; } - public bool? Density { get; set; } - public bool? BoxQuantity { get; set; } - public bool? ICNTariffCode { get; set; } - public bool? PlaceOfOrigin { get; set; } - public bool? MaterialCost { get; set; } - public bool? ExWorksCost { get; set; } - public bool? RetailPricePlanned { get; set; } - public bool? CarriageCostIndicative { get; set; } - } - public ShowFieldData ShowField { get; } = new ShowFieldData(); - // Configurable field label. - public class FieldLabelData - { - public String CatalogRef { get; set; } - public String Dimensions { get; set; } - public String ICNTariffCode { get; set; } - public String CostPrice { get; set; } - public String PlaceOfOrigin { get; set; } - public String MaterialCost { get; set; } - public String CurrencyIdMaterial { get; set; } - public String ExWorksCost { get; set; } - public String CurrencyIdExWorks { get; set; } - public String SpecSummary { get; set; } - public String MaterialCode { get; set; } - public String FinishCode { get; set; } - public String DescDetail { get; set; } - public String RetailPricePlanned { get; set; } - } - public FieldLabelData FieldLabel { get; } = new FieldLabelData(); - } - public ConfigData Config { get; } = new ConfigData(); - // Reference data. - public List CommodityTypes { get; } = new List(); - public List Statuses { get; } = new List(); - public String DefaultStatusCode { get; set; } } // Ajax request. [HttpPost] @@ -183,17 +184,20 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities if (!ValidReferer) return Forbid(); RefreshModel(model); - // Configuration. - PopulateConfigShow(responseData.Config.ShowField); + // Populate configuration data. + PopulateCommodityConfig(model, responseData); - // Reference data - commodity types. - foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) - responseData.CommodityTypes.Add(commodityType.Code, commodityType.Desc); - - // Reference data - statuses. - foreach (SaStatus status in SbmCommodity.ValidStatuses.FindAll(item => item != SaStatus.Deleted)) - responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); - responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmCommodity.DefaultStatus); + // View mode. + responseData.Mode = new AjaxResponse_CommodityList.ModeData(); + Model_Commodity.CommodityViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_Commodity.CommodityViewMode.Maintain) + responseData.Mode.Maintain = true; + else if (viewMode == Model_Commodity.CommodityViewMode.StockControl) + responseData.Mode.StockControl = true; + else if (viewMode == Model_Commodity.CommodityViewMode.StockTake) + responseData.Mode.StockTake = true; + else + responseData.Mode.Search = true; // Item filter. SbmCommodity.Params prmCommodity = new SbmCommodity.Params(); @@ -220,9 +224,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities List columns = new List() { colId, colCommodityType, colCode, colDescBrief, - colSalesPrice, colSalesUomId,colCostPrice, colNotes, colStatus, colCreatedOn, colUpdatedOn }; + if (model.UserCanViewCommodityFinancials_Sales()) + columns.AddRange(new[] { colSalesPrice, colSalesUomId }); + if (model.UserCanViewCommodityFinancials_Supply()) + columns.AddRange(new[] { colCostPrice }); // Query items. using (DbResultSet resultSet = CommodityMgr.ExecuteCommodityQuery(columns, prmCommodity)) @@ -234,21 +241,26 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities CommodityListData commodityData = new CommodityListData() { Id = values.GetString(colId.DataName), - TypeCode = Internals.CommodityTypeCodes.GetCodeForType(commodityType), - TypeDesc = Internals.CommodityTypeCodes.GetDescForType(commodityType), Code = values.GetString(colCode.DataName), - Desc = values.GetString(colDescBrief.DataName), - SalesPriceFmt = StringUtil.NullOnBlank(StringUtil.FormatNumeric(values.GetValue(colSalesPrice.DataName).ToDecimal(), SbmInternals.CurrencyDecimalsDefault, 0, ',')), - SalesUnit = Internals.GetUnitOfMeasureCaption(new SysId(values.GetLong(colSalesUomId.DataName))), - CostPriceFmt = StringUtil.NullOnBlank(StringUtil.FormatNumeric(values.GetValue(colCostPrice.DataName).ToDecimal(), SbmInternals.CurrencyDecimalsDefault, 0, ',')), - Notes = StringUtil.NullOnBlank(values.GetString(colNotes.DataName)), + Caption = values.GetString(colDescBrief.DataName), StatusCode = values.GetString(colStatus.DataName), - StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)), - CreatedOn = DateUtil.Format(values.GetDate(colCreatedOn.DataName), "yyyyMMdd"), - CreatedOnFmt = Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)), - UpdatedOn = DateUtil.Format(values.GetDate(colUpdatedOn.DataName), "yyyyMMdd"), - UpdatedOnFmt = Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName)) }; + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.Type}", Internals.CommodityTypeCodes.GetDescForType(commodityType)); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.Code}", values.GetString(colCode.DataName)); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.DescBrief}", values.GetString(colDescBrief.DataName)); + if (model.UserCanViewCommodityFinancials_Sales()) + { + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.SalesPriceFmt}", StringUtil.FormatNumeric(values.GetValue(colSalesPrice.DataName).ToDecimal(), SbmInternals.CurrencyDecimalsDefault, 0, ',')); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.SalesUnit}", Internals.GetUnitOfMeasureCaption(new SysId(values.GetLong(colSalesUomId.DataName)))); + } + if (model.UserCanViewCommodityFinancials_Supply()) + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.CostPriceFmt}", StringUtil.FormatNumeric(values.GetValue(colCostPrice.DataName).ToDecimal(), SbmInternals.CurrencyDecimalsDefault, 0, ',')); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.Notes}", CommodityMgr.GetCommodityDataValue(colNotes, values).ToString()); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.Status}", SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.CreatedOn}", Localiser.FormatDate(values.GetDate(colCreatedOn.DataName))); + commodityData.Field.Value.Add($"{Model_Commodity.ItemField.UpdatedOn}", Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName))); + // Cleanse item values. + commodityData.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value)); responseData.Commodities.Add(commodityData); } } @@ -265,27 +277,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities return Json(responseData); } - //------------------------------------------------------------------- - // Populate configuration. - - private void PopulateConfigShow(AjaxResponse_CommodityList.ConfigData.ShowFieldData show) - { - // Ref. Sbm.OrgOption_ShowField. - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_DrawingIssue)) show.DrawingIssue = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_DrawingNo)) show.DrawingNo = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Department)) show.Department = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_CatalogRef)) show.CatalogRef = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Volume)) show.Volume = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_Density)) show.Density = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_BoxQuantity)) show.BoxQuantity = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_ICNTariffCode)) show.ICNTariffCode = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_PlaceOfOrigin)) show.PlaceOfOrigin = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_MaterialCost)) show.MaterialCost = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_ExWorksCost)) show.ExWorksCost = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_RetailPricePlanned)) show.RetailPricePlanned = true; - if (UserContext_Core.GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx.Commodity_CarriageCostIndicative)) show.CarriageCostIndicative = true; - } - //------------------------------------------------------------------- // Get Commodity ajax request. //------------------------------------------------------------------- @@ -293,6 +284,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities { // Construction. public AjaxResponse_Commodity(SbmModel_Portal model) : base(model) { } + // Configuration. + public Model_Commodity.ItemConfigData Config { get; } = new Model_Commodity.ItemConfigData(); // Commodity details. public CommodityItemData commodity { get; } = new CommodityItemData(); } @@ -324,6 +317,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities } // Construct response. + model.PopulateItemConfig(responseData.Config, commodity); PopulateCommodityResponseItemData(commodity, responseData.commodity); // Complete response. @@ -418,6 +412,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities UpdateAssociatedData(commodity); // Construct response. + model.PopulateItemConfig(responseData.Config, commodity); PopulateCommodityResponseItemData(commodity, responseData.commodity); // Complete response. diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController.cs index 2515193..7414738 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController.cs @@ -47,6 +47,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities // Commodity page. RefreshModel(model); + model.PopulateListConfig(); model.Paging.PageNo = SessionData_Portal.Profile.Commodities.Filter.PageNo; model.Paging.PageLength = SessionData_Portal.Profile.Commodities.Filter.PageLength; return View(model); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs index 5890940..aeb78c2 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs @@ -171,8 +171,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts // View mode. public class ModeData { - public bool? Maintain { get; set; } public bool? Search { get; set; } + public bool? Maintain { get; set; } public bool? Relationships { get; set; } public bool? PriceSet { get; set; } } @@ -199,21 +199,15 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts // View mode. responseData.Mode = new AjaxResponse_AssociationList.ModeData(); - switch (model.GetFilterMode()) - { - case Model_Association.AssociationViewMode.Search: - responseData.Mode.Search = true; - break; - case Model_Association.AssociationViewMode.Relationships: - responseData.Mode.Relationships = true; - break; - case Model_Association.AssociationViewMode.PriceSet: - responseData.Mode.PriceSet = true; - break; - default: - responseData.Mode.Maintain = true; - break; - } + Model_Association.AssociationViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_Association.AssociationViewMode.Maintain) + responseData.Mode.Maintain = true; + else if (viewMode == Model_Association.AssociationViewMode.Relationships) + responseData.Mode.Relationships = true; + else if (viewMode == Model_Association.AssociationViewMode.PriceSet) + responseData.Mode.PriceSet = true; + else + responseData.Mode.Search = true; // Item filter. SbmAssociation.Params prmAssociation = new SbmAssociation.Params(); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs index ba3b732..df5a99b 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs @@ -24,10 +24,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts partial class ContactController { //------------------------------------------------------------------- - // Affiliate data. + // Item data. private class AffiliateListData : AjaxResponse_Data.ItemData_Base { - // Affiliate properties with specific handling. + // Item properties with specific handling. public String Name { get; set; } // Affiliate properties for list with specific handling. public long? AssociationCount { get; set; } @@ -52,7 +52,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts private void PopulateAffiliateResponseItemData(Model_Contact model, SbmAffiliate affiliate, AffiliateItemData data) { PopulateAffiliateResponseListData(model, affiliate, data as AffiliateListData); - // Affiliate name - prominent property for selecting and editing. + // Name - prominent property for selecting and editing. data.Name = affiliate.Name; // Affiliate type - populate for list ('Type' property populated with desc) and form (Type Code & Desc). data.TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliate.AffiliateType); @@ -206,10 +206,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts // View mode. responseData.Mode = new AjaxResponse_ContactList.ModeData(); Model_Contact.ContactViewMode viewMode = model.GetFilterMode(); - if (viewMode == Model_Contact.ContactViewMode.Search) - responseData.Mode.Search = true; - else + if (viewMode == Model_Contact.ContactViewMode.Maintain) responseData.Mode.Maintain = true; + else + responseData.Mode.Search = true; // Item filter. SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs index 1209221..b1f88d6 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs @@ -80,7 +80,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers /// - Open user session - store details against Sesion Data. /// - Set 'Keep logged in' cookie if required. /// - protected bool SignUserIn(ISbmUserContext_Core userContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage) + protected bool SignUserIn(ISbmUserContext_Core userContext, String repositoryContext, SaSecurityConsole securityConsoleForUser, SbmAccountMgr accountMgrForUser, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage) { // Validate Security Item and Affiliate, just in case - should have been done before arriving here! if (securityItemUser == null) @@ -125,8 +125,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers // 'Keep logged in' can be switched off by the application configuration. keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn; - using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext)) - using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext)) + using (DisposableCollection disposables = new DisposableCollection()) { // Log user in. securityItemUser.LastLogin = DateTime.Now; @@ -148,14 +147,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers return false; } SaLogger.Info($"{SysUtil.Fn} User session opened for {securityItemUser.EmailAddress}", true); + + // Create session. + OpenUserSession(userContext.SessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); + + // Configure security profile. + SessionData_Portal.SecurityProfile_Core.RefreshProfile(SessionConsole, securityConsoleForUser, securityItemUser.Id, securityConsoleForUser.GetRegisteredRights()); } - // Create session. - OpenUserSession(userContext.SessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); - - // Configure security profile. - SessionData_Portal.SecurityProfile_Core.RefreshProfile(SessionConsole, SecurityConsole, securityItemUser.Id, SecurityConsole.GetRegisteredRights()); - // Send the 'Keep Logged In' cookie if requested. if (affiliateUser.KeepLoggedIn_Portal) SetKeepLoggedInCookie(); @@ -264,7 +263,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers { List supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id); String errorMessage = ""; - if (SignUserIn(userContext, keepLoggedInParams.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage)) + if (SignUserIn(userContext, keepLoggedInParams.RepositoryContext, securityConsoleForUser, accountMgrForUser, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage)) { SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix); return true; diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs index ea63e27..82d4295 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs @@ -175,7 +175,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security } // Initialise user session. - if (SignUserIn(userContext, model.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage)) + if (SignUserIn(userContext, model.RepositoryContext, securityConsoleForUser, accountMgrForUser, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage)) return true; } return false; diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs new file mode 100644 index 0000000..47a72c1 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs @@ -0,0 +1,715 @@ +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Bus; +using System; +using System.Collections.Generic; +using System.Drawing; + +namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities +{ + //======================================================================= + // Commodity model - Configuration. + //======================================================================= + partial class Model_Commodity + { + //------------------------------------------------------------------- + // Commodity fields. + //------------------------------------------------------------------- + + /// Prefix for field names. + public const String FieldNamePrefix = "Commodity"; + + //------------------------------------------------------------------- + // Legacy Commodity dialog tabs and panels. + // - Commodity. + // - Tab 1: + // - Sales. + // - Costs (grid - category cost/labour per unit/job). + // - Orders ('Purchasing'). + // - Specification. + // - Asset Category. + // - Defaults. + // - Machines. + // - Notes. + // - Tab 2: + // - Images. + // - Tab 3: + // - Processes + // - Production + // - Special Instructions. + // - Item Docs + // - Tab 4: + // - Stock + // - Stock Events + // - Sage Stock Transfers + // - Sales Budget + // - Tab 5: + // - Portfolio Items + // - Associated Products + // - Tab 6: + // - Update Log + // - Tab 7: + // - Requirements x 6. + // - Other. + // - Stock Projection + + //------------------------------------------------------------------- + /// Item fields. + public enum ItemField + { + //--------------------------------------------------------------- + // Commodity. + Pos, + Id, + Code, + DrawingNo, + DrawingIssue, + Type, + DescBrief, + //--------------------------------------------------------------- + // Sales. + SalesPrice, + /// Formatted sales price - for list only. + SalesPriceFmt, + RetailPrice, + RetailPricePlanned, + TaxCodeId, + CarriageCostIndicative, + UomIdSale, + /// Unit of sale caption - for list only. + SalesUnit, + PackQtySale, + MinOrderQty, + DescOrder, + AssocIdCustomer, + Customer, + Department, + NominalCode, + Promotion, + //--------------------------------------------------------------- + // Purchasing. + CostPrice, + /// Formatted cost price - for list only. + CostPriceFmt, + PlaceOfOrigin, + MaterialCost, + MaterialCurrency, + ExWorksCost, + ExWorksCurrency, + AssocIdSupplier, + Supplier, + SupplierRef, + NominalCodePurchase, + //--------------------------------------------------------------- + // Specification. + Weight, + WeightUnit, + Length, + LengthUnit, + Volume, + VolumeUnit, + Density, + DensityUnit, + BoxQuantity, + BoxUnit, + Dimensions, + SpecSummary, + //--------------------------------------------------------------- + // Asset. + AssetCategory, + //--------------------------------------------------------------- + // Defaults. + ICNTariffCode, + Category, + Category2, + Category3, + Location, + CatalogRef, + //--------------------------------------------------------------- + // Production. + MaterialCode, + FinishCode, + //--------------------------------------------------------------- + // Special instructions. + DescDetail, + //--------------------------------------------------------------- + // Codes. + RangeCode, + ColourCode, + SourceCode, + SupplyMethodCode, + HandlingCode, + DeliveryCode, + //--------------------------------------------------------------- + // Inages. + ImagePath, + Image, + //--------------------------------------------------------------- + // Production time. + TimeProd, + //--------------------------------------------------------------- + // Stock. + QtyOnOrder, + LastOrderDate, + LastOrderQty, + ReorderLevel, + ReorderQty, + CurrentLevel, + StockAvailable, + StockMonthCurrent, + StockMonth, + StockDueProvisional, + QtyInStock, + QtyAllocated, + FreeStock, + StockTakeDate, + StockTakeQty, + //--------------------------------------------------------------- + // Projected sales. + ProjectedSales, + //--------------------------------------------------------------- + // Common properties. + Notes, + Status, + CreatedOn, + UpdatedOn, + Actions, + } + + /// + /// Identifier used by form fields to show control specific messages generated by model validation etc. + /// - Both page and model should use this method to consistently generate the field name. + /// + public static String GetFieldName(ItemField field) + { + return $"{FieldNamePrefix}{field}"; + } + + //------------------------------------------------------------------- + + // List configuration. + public class ListConfigData + { + // List columns. + public class ColumnData + { + // Column name prefix. + public String Prefix { get; } = Model_Commodity.FieldNamePrefix; + // Hide column. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Column labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public ColumnData Column { get; } = new ColumnData(); + } + public ListConfigData ListConfig { get; private set; } + + //------------------------------------------------------------------- + /// + /// Populate Commodity list configuration data in this model - only required on initial page construction. + /// + public void PopulateListConfig() + { + ListConfig = new ListConfigData(); + PopulateListConfig(ListConfig); + } + /// + /// Populate Commodity list configuration data. + /// + public void PopulateListConfig(ListConfigData config) + { + // View properties. + CommodityViewMode viewMode = GetFilterMode(); + bool modeIsMaintain = viewMode == CommodityViewMode.Maintain; + bool modeIsSearch = viewMode == CommodityViewMode.Search; + bool modeIsStockControl = viewMode == CommodityViewMode.StockControl; + bool modeIsStockTake = viewMode == CommodityViewMode.StockTake; + + Sbm.CommodityType commodityType = GetFilterCommodityType(); + + //--------------------------------------------------------------- + // Commodity list columns. + + // Position. + + // Id + if (!SbmSystem.DebugMode) + config.Column.Hide.Add($"{ItemField.Id}"); + + // Code. + + // Drawing issue. + if (SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_DrawingIssue)) + config.Column.Label.Add($"{ItemField.DrawingIssue}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_DrawingIssue, Localiser["label.issue"])); + else + config.Column.Hide.Add($"{ItemField.DrawingIssue}"); + + // Commodity type. + if (commodityType <= 0) + config.Column.Label.Add($"{ItemField.Type}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Type, Localiser["label.type"])); + else + config.Column.Hide.Add($"{ItemField.Type}"); + + // Description. + + //--------------------------------------------------------------- + // Sales. + + // Sales price. + if (!UserCanViewCommodityFinancials_Sales()) + config.Column.Hide.Add($"{ItemField.SalesPrice}"); + + // Pack qty. + if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_PackQtySale)) + config.Column.Label.Add($"{ItemField.PackQtySale}", Localiser["label.pack.quantity"]); + else + config.Column.Hide.Add($"{ItemField.PackQtySale}"); + + // Customer. + if (modeIsStockControl || !SessionConsole.AllowOption(Sbm.ConfigOption.CommodityExclusiveToCustomer)) + config.Column.Hide.Add($"{ItemField.Customer}"); + + // Promotion. + if (!SessionConsole.AllowOption(Sbm.ConfigOption.CommodityPromotion) || !CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.CommodityPromotion)) || !CommodityMgr.ColumnExists(SbmDbDfn.ColumnIdx.Commodity_PromotionCode)) + config.Column.Hide.Add($"{ItemField.Promotion}"); + + //--------------------------------------------------------------- + // Purchasing. + + // Cost price. + if (!UserCanViewCommodityFinancials_Supply()) + config.Column.Hide.Add($"{ItemField.CostPrice}"); + + // Supplier. + if (!modeIsStockControl) + config.Column.Hide.Add($"{ItemField.Supplier}"); + + //--------------------------------------------------------------- + // Specification. + + // Weight. + if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_Weight)) + config.Column.Label.Add($"{ItemField.Weight}", Localiser["label.weight"]); + else + config.Column.Hide.Add($"{ItemField.Weight}"); + + //--------------------------------------------------------------- + // Defaults. + + // Catalog Reference. + if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_CatalogRef)) + config.Column.Label.Add($"{ItemField.CatalogRef}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CatalogRef, Localiser["label.catalog.ref"])); + else + config.Column.Hide.Add($"{ItemField.CatalogRef}"); + + //--------------------------------------------------------------- + // Stock. + + // Stock - allocated. + if ((modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAllocated)) && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated)) + config.Column.Label.Add($"{ItemField.QtyAllocated}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated, Localiser["label.allocated"])); + else + config.Column.Hide.Add($"{ItemField.QtyAllocated}"); + + // Stock - available. + if (!modeIsStockControl && SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAvailable)) + config.Column.Label.Add($"{ItemField.StockAvailable}", Localiser["label.available"]); + else + config.Column.Hide.Add($"{ItemField.StockAvailable}"); + + // Current Level. + if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockLevelSales)) + config.Column.Label.Add($"{ItemField.CurrentLevel}", Localiser["label.current.level"]); + else + config.Column.Hide.Add($"{ItemField.CurrentLevel}"); + + // Stock - current month. + if (!modeIsStockControl) + config.Column.Hide.Add($"{ItemField.StockMonthCurrent}"); + + // Stock - by month. + if (!modeIsStockControl) + config.Column.Hide.Add($"{ItemField.StockMonth}"); + + // Stock - due provisional. + if (!modeIsStockControl) + config.Column.Hide.Add($"{ItemField.StockDueProvisional}"); + + //--------------------------------------------------------------- + // Common. + + // Status. + if (modeIsSearch) + config.Column.Hide.Add($"{ItemField.Status}"); + + // Actions. + if (!modeIsMaintain) + config.Column.Hide.Add($"{ItemField.Actions}"); + } + + //------------------------------------------------------------------- + // Item configuration. + //------------------------------------------------------------------- + + // Contact item configuration. + public class ItemConfigData + { + // Item type. + public bool? IsOrganisation { get; set; } + public bool? IsIndividual { get; set; } + public bool? IsGroup { get; set; } + // Item fields. + public class FieldData + { + // Field name prefix. + public String Prefix { get; } = Model_Commodity.FieldNamePrefix; + // Hide field. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Read-only field. + public HashSet Readonly { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Field labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public FieldData Field { get; } = new FieldData(); + } + + //------------------------------------------------------------------- + /// + /// Populate item configuration for existing association. + /// + public void PopulateItemConfig(ItemConfigData config, SbmCommodity commodity) + { + PopulateItemConfig(config, commodity.GetItemId(), commodity.CommodityType); + } + + /// + /// Populate item configuration for new or existing association. + /// + public void PopulateItemConfig(ItemConfigData config, ItemId commodityItemId, Sbm.CommodityType commodityType) + { + // Item type. + bool isProduct = commodityType != Sbm.CommodityType.Service; + bool isService = commodityType == Sbm.CommodityType.Service; + + bool importedFromAccounts = Internals.AccountsDfn.ItemIsImportedFromAccounts(commodityItemId); + bool managedByAccounts = Internals.AccountsDfn.IsItemTypeManagedByAccounts(Sbm.ItemType.Commodity); + bool showNotes = true; + + //--------------------------------------------------------------- + // Commodity. + + // Id. + if (SbmSystem.DebugMode) + config.Field.Readonly.Add($"{ItemField.Id}"); + else + config.Field.Hide.Add($"{ItemField.Id}"); + + // Code. + // Read-only if commodity being superceded. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Code}"); + + // Commodity type. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Type}"); + + // Description. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.DescBrief}"); + + //--------------------------------------------------------------- + // Sales. + + // Sales price. + if (!UserCanViewCommodityFinancials_Sales()) + config.Field.Hide.Add($"{ItemField.SalesPrice}"); + else if (managedByAccounts || !UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.SalesPrice}"); + + // Retail price. + if (UserCanViewCommodityFinancials_Sales() && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_RetailPrice)) + { + config.Field.Label.Add($"{ItemField.RetailPrice}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_RetailPrice, Localiser["label.retail.price"])); + if (!UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.RetailPrice}"); + } + else config.Field.Hide.Add($"{ItemField.RetailPrice}"); + + // Retail price - planned. + if (UserCanViewCommodityFinancials_Sales() && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_RetailPricePlanned)) + { + config.Field.Label.Add($"{ItemField.RetailPricePlanned}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_RetailPricePlanned, Localiser["label.retail.price.planned"])); + if (!UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.RetailPricePlanned}"); + } + else config.Field.Hide.Add($"{ItemField.RetailPricePlanned}"); + + // Tax code + if (managedByAccounts || !UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.TaxCodeId}"); + + // Indicative carriage cost. + if (UserCanViewCommodityFinancials_Sales() && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_CarriageCostIndicative) || !CommodityMgr.ColumnExists(SbmDbDfn.ColumnIdx.Commodity_CarriageCostIndicative)) + { + config.Field.Label.Add($"{ItemField.CarriageCostIndicative}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CarriageCostIndicative, Localiser["label.carriage.cost.indicative"])); + if (!UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.CarriageCostIndicative}"); + } + else config.Field.Hide.Add($"{ItemField.CarriageCostIndicative}"); + + // Sales Unit. + if (managedByAccounts || !UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.UomIdSale}"); + + // Sales Pack quantity. + + // Min order quantity. + + // Description - order. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.DescOrder}"); + + // Customer. + if (!SessionConsole.AllowOption(Sbm.ConfigOption.CommodityExclusiveToCustomer)) + config.Field.Hide.Add($"{ItemField.Customer}"); + else if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Customer}"); + + // Department. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Department}"); + + // Nominal code. + if (!managedByAccounts) + config.Field.Hide.Add($"{ItemField.NominalCode}"); + + // Promotion. + if (!SessionConsole.AllowOption(Sbm.ConfigOption.CommodityPromotion) || !CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.CommodityPromotion)) || !CommodityMgr.ColumnExists(SbmDbDfn.ColumnIdx.Commodity_PromotionCode)) + config.Field.Hide.Add($"{ItemField.Promotion}"); + + //--------------------------------------------------------------- + // Purchasing. + + // Cost price. + if (UserCanViewCommodityFinancials_Supply()) + { + config.Field.Label.Add($"{ItemField.CostPrice}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CostPrice, Localiser["label.cost.price"])); + if (!UserCanUpdateFinancials()) + config.Field.Readonly.Add($"{ItemField.CostPrice}"); + } + else config.Field.Hide.Add($"{ItemField.CostPrice}"); + + // Place of origin. + config.Field.Label.Add($"{ItemField.PlaceOfOrigin}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_PlaceOfOrigin, Localiser["label.place.of.origin"])); + + // Material. + if (UserCanViewCommodityFinancials_Supply()) + { + config.Field.Label.Add($"{ItemField.MaterialCost}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_MaterialCost, Localiser["label.material.cost"])); + config.Field.Label.Add($"{ItemField.MaterialCurrency}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CurrencyIdMaterial, Localiser["label.material.currency"])); + if (!UserCanUpdateFinancials()) + { + config.Field.Readonly.Add($"{ItemField.MaterialCost}"); + config.Field.Readonly.Add($"{ItemField.MaterialCurrency}"); + } + } + else + { + config.Field.Hide.Add($"{ItemField.MaterialCost}"); + config.Field.Hide.Add($"{ItemField.MaterialCurrency}"); + } + + // Ex-works cost. + if (UserCanViewCommodityFinancials_Supply()) + { + config.Field.Label.Add($"{ItemField.ExWorksCost}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_ExWorksCost, Localiser["label.ex.works.cost"])); + config.Field.Label.Add($"{ItemField.ExWorksCurrency}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CurrencyIdExWorks, Localiser["label.ex.works.currency"])); + if (!UserCanUpdateFinancials()) + { + config.Field.Readonly.Add($"{ItemField.ExWorksCost}"); + config.Field.Readonly.Add($"{ItemField.ExWorksCurrency}"); + } + } + else + { + config.Field.Hide.Add($"{ItemField.ExWorksCost}"); + config.Field.Hide.Add($"{ItemField.ExWorksCurrency}"); + } + + // Nominal code - purchase. + if (!managedByAccounts) + config.Field.Hide.Add($"{ItemField.NominalCodePurchase}"); + + // Supplier. + if (!managedByAccounts) + config.Field.Hide.Add($"{ItemField.Supplier}"); + + // Supplier reference. + + //--------------------------------------------------------------- + // Specification. + + // Weight. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Weight)) + { + config.Field.Label.Add($"{ItemField.Weight}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Weight, Localiser["label.weight"])); + } + else + { + config.Field.Hide.Add($"{ItemField.Weight}"); + config.Field.Hide.Add($"{ItemField.WeightUnit}"); + } + + // Lenghth. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Length)) + { + config.Field.Label.Add($"{ItemField.Length}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Length, Localiser["label.length"])); + } + else + { + config.Field.Hide.Add($"{ItemField.Length}"); + config.Field.Hide.Add($"{ItemField.LengthUnit}"); + } + + // Volume. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Volume)) + { + config.Field.Label.Add($"{ItemField.Volume}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Volume, Localiser["label.volume"])); + } + else + { + config.Field.Hide.Add($"{ItemField.Volume}"); + config.Field.Hide.Add($"{ItemField.VolumeUnit}"); + } + + // Density. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Density)) + { + config.Field.Label.Add($"{ItemField.Density}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Density, Localiser["label.density"])); + } + else + { + config.Field.Hide.Add($"{ItemField.Density}"); + config.Field.Hide.Add($"{ItemField.DensityUnit}"); + } + + // Box quantity. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Dimensions)) + { + config.Field.Label.Add($"{ItemField.BoxQuantity}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_BoxQuantity, Localiser["label.box.quantity"])); + } + else + { + config.Field.Hide.Add($"{ItemField.BoxQuantity}"); + config.Field.Hide.Add($"{ItemField.BoxUnit}"); + } + + // Dimensions. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_Dimensions)) + config.Field.Label.Add($"{ItemField.Dimensions}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Dimensions, Localiser["label.dimensions"])); + else + config.Field.Hide.Add($"{ItemField.Dimensions}"); + + // Spec summary. + if (isProduct && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_SpecSummary)) + config.Field.Label.Add($"{ItemField.SpecSummary}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_SpecSummary, Localiser["label.specification"])); + else + config.Field.Hide.Add($"{ItemField.SpecSummary}"); + + //--------------------------------------------------------------- + // Asset. + + // Asset category. + if (!SessionConsole.AllowOption(Sbm.ConfigOption.AllowAssets)) + config.Field.Hide.Add($"{ItemField.AssetCategory}"); + + //--------------------------------------------------------------- + // Defaults. + + // ICN Tariff code. + if (managedByAccounts) + { + config.Field.Label.Add($"{ItemField.ICNTariffCode}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_ICNTariffCode, Localiser["label.icn.tariff.code"])); + config.Field.Readonly.Add($"{ItemField.ICNTariffCode}"); + } + else + config.Field.Hide.Add($"{ItemField.ICNTariffCode}"); + + // Category. + if (managedByAccounts) + { + config.Field.Readonly.Add($"{ItemField.Category}"); + config.Field.Readonly.Add($"{ItemField.Category2}"); + config.Field.Readonly.Add($"{ItemField.Category3}"); + } + + // Location. + config.Field.Label.Add($"{ItemField.Location}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_Location, Localiser["label.location"])); + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Location}"); + + // Catalog reference. + config.Field.Label.Add($"{ItemField.CatalogRef}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CatalogRef, Localiser["label.catalog.ref"])); + + //--------------------------------------------------------------- + // Special Instructions. + + // Description - detail. + config.Field.Label.Add($"{ItemField.DescDetail}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_DescDetail, Localiser["label.desc.detail"])); + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.DescDetail}"); + + // Image path. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.ImagePath}"); + + // Weight. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Weight}"); + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.WeightUnit}"); + + //--------------------------------------------------------------- + // Production. + + // Material. + config.Field.Label.Add($"{ItemField.MaterialCode}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_MaterialCode, Localiser["label.material"])); + + // Finish. + config.Field.Label.Add($"{ItemField.FinishCode}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_FinishCode, Localiser["label.finish"])); + + //--------------------------------------------------------------- + // Stock. + + // Reorder level - not currently in use. + config.Field.Hide.Add($"{ItemField.ReorderLevel}"); + + // Reorder quantity - not currently in use. + config.Field.Hide.Add($"{ItemField.ReorderQty}"); + + // Quantity on order. + config.Field.Readonly.Add($"{ItemField.QtyOnOrder}"); + + // Last order date - not currently in use. Otherwise always read-only. + config.Field.Hide.Add($"{ItemField.LastOrderDate}"); + + // Last order quantity - not currently in use. Otherwise always read-only. + config.Field.Hide.Add($"{ItemField.LastOrderQty}"); + + //--------------------------------------------------------------- + // Common. + + // Notes. + if (!showNotes) + config.Field.Hide.Add($"{ItemField.Notes}"); + + // Status. + // Read-only if commodity being superceded. + if (managedByAccounts) + config.Field.Readonly.Add($"{ItemField.Status}"); + + } + + //------------------------------------------------------------------- + } +} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs index 8f5f556..5e97e57 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs @@ -13,12 +13,26 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; +using static Sarand.BusinessMgr.Web.Portal.Models.Contacts.Model_Contact; namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities { //======================================================================= - public class Model_Commodity : SbmModel_Portal + // Commodity model. + //======================================================================= + /// + /// Commodity model - Filter, Form, validation and configuration. + /// + public partial class Model_Commodity : SbmModel_Portal { + //------------------------------------------------------------------- + // Definitions. + public enum CommodityViewMode + { + Search, Maintain, StockControl, StockTake + } + //------------------------------------------------------------------- // Construction. public Model_Commodity(SbmLocaliser localiser) : @@ -30,13 +44,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities // Filter properties. public class FilterData { - public string Search { get; set; } - public string CommodityType { get; set; } + public String Mode { get; set; } + public String CommodityType { get; set; } + public String Search { get; set; } } public FilterData Filter { get; } = new FilterData(); + public CommodityViewMode GetFilterMode() + { + return EnumUtil.ParseEnum(Filter.Mode, CommodityViewMode.Search); + } public Sbm.CommodityType GetFilterCommodityType() { - return (Sbm.CommodityType)Internals.CommodityTypeCodes.GetTypeForCode(Filter.CommodityType); + Sbm.CommodityType commodityType = (Sbm.CommodityType)Internals.CommodityTypeCodes.GetTypeForCode(Filter.CommodityType); + if (commodityType == 0 && !StringUtil.IsBlank(Filter.CommodityType) && StringUtil.IsNumeric(Filter.CommodityType, true)) + commodityType = (Sbm.CommodityType)StringUtil.ToInt(Filter.CommodityType); + return commodityType; } //------------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs index 5e22db1..afa2426 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs @@ -13,9 +13,8 @@ using System.Xml.Serialization; namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { //======================================================================= - /// - /// Association model - Configuration. - /// + // Association model - Configuration. + //======================================================================= partial class Model_Association { //------------------------------------------------------------------- @@ -143,8 +142,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts bool typeIsSupplier = associationType == Sbm.AssociationType.Supplier; bool typeIsMember = associationType == Sbm.AssociationType.Member; - bool userCanViewFinancials = SessionData_Portal.SecurityProfile_Core.UserCanViewFinancials(); - // Actions. if (typeIsCustomer) @@ -180,23 +177,23 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts config.Column.Hide.Add($"{ItemField.Address}"); // Customer financials. - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open)) config.Column.Hide.Add($"{ItemField.TransSalesValueOpen}"); if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_LastSaleRaised)) config.Column.Hide.Add($"{ItemField.TransLastSaleRaised}"); - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget)) config.Column.Hide.Add($"{ItemField.AnnualSalesTarget}"); - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd)) config.Column.Hide.Add($"{ItemField.TransSalesValueCytd}"); - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy)) config.Column.Hide.Add($"{ItemField.TransSalesValueLcy}"); // Customer commodities. if (!modeIsMaintain || !typeIsCustomer || !CommodityMgr.CanManageCommodityCustomers()) config.Column.Hide.Add($"{ItemField.CommodityCount}"); // Customer pricing. - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerDiscount)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerDiscount)) config.Column.Hide.Add($"{ItemField.DiscountRate}"); - if (!modeIsMaintain || !typeIsCustomer || !userCanViewFinancials || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerPriceSet) && PriceMgr.PriceDatabaseIsValid) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerPriceSet) && PriceMgr.PriceDatabaseIsValid) config.Column.Hide.Add($"{ItemField.PriceSet}"); // Association group. if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Group)) @@ -302,8 +299,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts /// public void PopulateItemConfig(ItemConfigData config, ItemId associationItemId, SysId ownerId, Sbm.AssociationType associationType) { - bool canViewFinancials = SessionData_Portal.SecurityProfile_Core.UserCanViewFinancials(); - bool canUpdateFinancials = SessionData_Portal.SecurityProfile_Core.UserCanUpdateFinancials(); bool ownerIsInternal = SessionData_Portal.Organisation.AffiliateId.Equals(ownerId); bool isCustomer = SbmAssociation.IsCustomer(associationType); bool isSupplier = SbmAssociation.IsSupplier(associationType); @@ -384,9 +379,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts // Financials. // Annual Sales Target. - if (!canViewFinancials) + if (!UserCanViewFinancials()) config.Field.Hide.Add($"{ItemField.AnnualSalesTarget}"); - else if (!canUpdateFinancials) + else if (!UserCanUpdateFinancials()) config.Field.Readonly.Add($"{ItemField.AnnualSalesTarget}"); // Default Nominal Code. @@ -396,37 +391,37 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts config.Field.Readonly.Add($"{ItemField.DefaultNominalCode}"); // Credit limit. - if (!canViewFinancials || !managedByAccounts) + if (!UserCanViewFinancials() || !managedByAccounts) config.Field.Hide.Add($"{ItemField.CreditLimit}"); - else if (managedByAccounts || !canUpdateFinancials) + else if (managedByAccounts || !UserCanUpdateFinancials()) config.Field.Readonly.Add($"{ItemField.CreditLimit}"); // Account balance. - if (!canViewFinancials || !managedByAccounts) + if (!UserCanViewFinancials() || !managedByAccounts) config.Field.Hide.Add($"{ItemField.AccountBalance}"); - else if (managedByAccounts || !canUpdateFinancials) + else if (managedByAccounts || !UserCanUpdateFinancials()) config.Field.Readonly.Add($"{ItemField.AccountBalance}"); // Discount. - if (!canViewFinancials || (!managedByAccounts && !SessionConsole.AllowOption(isSupplier ? Sbm.ConfigOption.SupplierDiscount : Sbm.ConfigOption.CustomerDiscount))) + if (!UserCanViewFinancials() || (!managedByAccounts && !SessionConsole.AllowOption(isSupplier ? Sbm.ConfigOption.SupplierDiscount : Sbm.ConfigOption.CustomerDiscount))) { config.Field.Hide.Add($"{ItemField.DiscountType}"); config.Field.Hide.Add($"{ItemField.DiscountRate}"); } - else if (!localPricing || !canUpdateFinancials) + else if (!localPricing || !UserCanUpdateFinancials()) { config.Field.Readonly.Add($"{ItemField.DiscountType}"); config.Field.Readonly.Add($"{ItemField.DiscountRate}"); } // Price set. - if (!canViewFinancials || (!managedByAccounts && !SessionConsole.AllowOption(isSupplier ? Sbm.ConfigOption.SupplierPriceSet : Sbm.ConfigOption.CustomerPriceSet)) || !PriceMgr.PriceDatabaseIsValid) + if (!UserCanViewFinancials() || (!managedByAccounts && !SessionConsole.AllowOption(isSupplier ? Sbm.ConfigOption.SupplierPriceSet : Sbm.ConfigOption.CustomerPriceSet)) || !PriceMgr.PriceDatabaseIsValid) config.Field.Hide.Add($"{ItemField.PriceSet}"); - else if (!localPricing || !canUpdateFinancials) + else if (!localPricing || !UserCanUpdateFinancials()) config.Field.Readonly.Add($"{ItemField.PriceSet}"); // Tax code. - if (managedByAccounts || !canUpdateFinancials) + if (managedByAccounts || !UserCanUpdateFinancials()) config.Field.Readonly.Add($"{ItemField.TaxCode}"); // Default sales commodity. diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs index 725534a..ed0d010 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs @@ -17,9 +17,11 @@ using System.Threading.Tasks; namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { + //======================================================================= + // Association model. //======================================================================= /// - /// Association model - Filter and Form. + /// Association model - Filter, Form, validation and configuration. /// public partial class Model_Association : SbmModel_Portal { @@ -53,7 +55,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts public FilterData Filter { get; } = new FilterData(); public AssociationViewMode GetFilterMode() { - return EnumUtil.ParseEnum(Filter.Mode, AssociationViewMode.Maintain); + return EnumUtil.ParseEnum(Filter.Mode, AssociationViewMode.Search); } public Sbm.AssociationType GetFilterAssociationType() { diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs index 42ba632..1108184 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs @@ -8,9 +8,8 @@ using System.Collections.Generic; namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { //======================================================================= - /// - /// Contact model - Configuration. - /// + // Contact model - Configuration. + //======================================================================= partial class Model_Contact { //------------------------------------------------------------------- @@ -124,29 +123,29 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts // Contact type. if (affiliateType <= 0) - config.Column.Label.Add($"{ItemField.Type}", Localiser["label.type"]); + config.Column.Label.Add($"{ItemField.Type}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Affiliate_Type, Localiser["label.type"])); else config.Column.Hide.Add($"{ItemField.Type}"); // Contact name. - config.Column.Label.Add($"{ItemField.Name}", Localiser["label.name"]); + config.Column.Label.Add($"{ItemField.Name}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Affiliate_Name, Localiser["label.name"])); // Nature. bool showNature = false; if (!contactGroupsOnly && showNature) - config.Column.Label.Add($"{ItemField.Nature}", Localiser["label.nature"]); + config.Column.Label.Add($"{ItemField.Nature}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Affiliate_Nature, Localiser["label.nature"])); else config.Column.Hide.Add($"{ItemField.Nature}"); // Email. if (!contactGroupsOnly && (affiliateType == Sbm.AffiliateType.Individual || !StringUtil.IsBlank(Filter.Email))) - config.Column.Label.Add($"{ItemField.Email}", Localiser["label.email"]); + config.Column.Label.Add($"{ItemField.Email}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Affiliate_Email, Localiser["label.email"])); else config.Column.Hide.Add($"{ItemField.Email}"); // Contact. if (!contactGroupsOnly && (affiliateType != Sbm.AffiliateType.Individual)) - config.Column.Label.Add($"{ItemField.Contact}", Localiser["label.contact"]); + config.Column.Label.Add($"{ItemField.Contact}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Affiliate_Contact, Localiser["label.contact"])); else config.Column.Hide.Add($"{ItemField.Contact}"); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs index 31d69bc..dbce3b3 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs @@ -17,9 +17,11 @@ using System.Threading.Tasks; namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { + //======================================================================= + // Contact model. //======================================================================= /// - /// Contact (Affiliate) model - Configuration. + /// Contact (Affiliate) model - Filter, Form, validation and configuration. /// public partial class Model_Contact : SbmModel_Portal { @@ -42,14 +44,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts public class FilterData { public String Mode { get; set; } - public string ContactType { get; set; } - public string Search { get; set; } - public string Email { get; set; } + public String ContactType { get; set; } + public String Search { get; set; } + public String Email { get; set; } } public FilterData Filter { get; } = new FilterData(); public ContactViewMode GetFilterMode() { - return EnumUtil.ParseEnum(Filter.Mode, ContactViewMode.Maintain); + return EnumUtil.ParseEnum(Filter.Mode, ContactViewMode.Search); } public Sbm.AffiliateType GetFilterContactType() { @@ -63,31 +65,31 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts // Contact properties. public class ContactData { - public string Id { get; set; } - public string Exists { get; set; } - public string Type { get; set; } - public string IsIndividual { get; set; } - public string IsGroup { get; set; } + public String Id { get; set; } + public String Exists { get; set; } + public String Type { get; set; } + public String IsIndividual { get; set; } + public String IsGroup { get; set; } // Organisation. - public string Name { get; set; } - public string Abbreviation { get; set; } - public string Nature { get; set; } - public string Contact { get; set; } - public string PhoneMain { get; set; } - public string PhoneAlt { get; set; } - public string PhoneDirect { get; set; } - public string PhoneFax { get; set; } - public string Email { get; set; } - public string Website { get; set; } - public string CompanyNo { get; set; } - public string VatReg { get; set; } + public String Name { get; set; } + public String Abbreviation { get; set; } + public String Nature { get; set; } + public String Contact { get; set; } + public String PhoneMain { get; set; } + public String PhoneAlt { get; set; } + public String PhoneDirect { get; set; } + public String PhoneFax { get; set; } + public String Email { get; set; } + public String Website { get; set; } + public String CompanyNo { get; set; } + public String VatReg { get; set; } // Individual. - public string Title { get; set; } - public string Salutation { get; set; } - public string FirstName { get; set; } - public string Initials { get; set; } - public string LastName { get; set; } - public string PhoneMobile { get; set; } + public String Title { get; set; } + public String Salutation { get; set; } + public String FirstName { get; set; } + public String Initials { get; set; } + public String LastName { get; set; } + public String PhoneMobile { get; set; } // Flags. // NB Have to use bool with checkbox and then cannot tell whether // false is unchecked or not submitted (ie. excluded from form, disabled etc). @@ -95,12 +97,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts private bool? prospectValue { get; set; } public bool Prospect { get { return prospectValue ?? false; } set { prospectValue = value; } } // Common properties. - public string Notes { get; set; } - public string StatusCode { get; set; } + public String Notes { get; set; } + public String StatusCode { get; set; } } - public SysId GetAffiliateId() { return StringUtil.ToSysId(Contact.Id); } - public SaStatus GetAffiliateStatus() { return SacsSystem.GetStatusForCode(Contact.StatusCode); } public ContactData Contact { get; } = new ContactData(); + public SysId GetAffiliateId() { return StringUtil.ToSysId(Contact.Id); } public Sbm.AffiliateType GetAffiliateType() { if (StringUtil.ToBool(Contact.IsIndividual)) @@ -111,6 +112,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts return (Sbm.AffiliateType)Internals.AffiliateTypeCodes.GetTypeForCode(Contact.Type); return Sbm.AffiliateType.Unknown; } + public SaStatus GetAffiliateStatus() { return SacsSystem.GetStatusForCode(Contact.StatusCode); } //------------------------------------------------------------------- // Validation. diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs index a5c70df..6f87ad0 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; namespace Sarand.BusinessMgr.Web.Portal.Models { @@ -29,6 +30,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Models public override ISbmUserContext_Core UserContext_Core { get { return SessionData_Portal; } } public String OrganisationName { get { return SessionData_Portal?.Organisation?.DisplayName ?? ""; } } + //------------------------------------------------------------------- + // Security profile. + public bool UserCanViewFinancials() { return SessionData_Portal.SecurityProfile_Core.UserCanViewFinancials(); } + public bool UserCanViewCommodityFinancials_Supply() { return SessionData_Portal.SecurityProfile_Core.UserCanViewFinancials(FinancialType.CommoditySupply); } + public bool UserCanViewCommodityFinancials_Sales() { return SessionData_Portal.SecurityProfile_Core.UserCanViewFinancials(FinancialType.CommoditySales); } + public bool UserCanUpdateFinancials() { return SessionData_Portal.SecurityProfile_Core.UserCanUpdateFinancials(); } + public bool UserCanStockTake() { return SessionData_Portal.SecurityProfile_Core.UserHasSecurityRight(SecurityRight.StockTake); } + public bool UserCanCreateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(itemType); } + public bool UserCanUpdateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(itemType); } + //------------------------------------------------------------------- // View reference data. diff --git a/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj b/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj index 9f3a7e9..1f171e0 100644 --- a/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj +++ b/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj @@ -44,6 +44,10 @@ true PreserveNewest + + true + PreserveNewest + diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationList.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationList.cshtml index a85e933..5258bc5 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationList.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationList.cshtml @@ -3,7 +3,7 @@ @inject SbmLocaliser Localiser @{ /* Association list panel */ - /* NB Can potentially appear more than once on a page? */ + /* NB Can potentially appear more than once on a page. */ } @* Item list *@ diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml index 5c88e3e..554ee9b 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml @@ -20,6 +20,8 @@ @* Filter form - wrap header to include paging controls. *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" })) { + @Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Maintain, new { @id = "" }) + @* Header - Page caption, paging controls, actions. *@
diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml index 3f0dc57..a21a553 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml @@ -15,7 +15,7 @@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", "Search", new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Search, new { @id = "" }) @Html.Hidden("Filter.OwnerId", "", new { @id = "", @class = "FilterOwnerId" }) @Html.Hidden("Filter.TargetId", "", new { @id = "", @class = "FilterTargetId" }) diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Index.cshtml index 8523cb8..8ddd2a9 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Index.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Index.cshtml @@ -1,121 +1,8 @@ @model Model_Commodity @inject SbmLocaliser Localiser @{ - /* Commodities - Index */ + /* Commodity page. */ ViewData["Title"] = "Commodities"; - Model.AdditionalFiles_JS.Add("js/sbm-commodity.js"); } -
- - - -
- - @* Filter form - wrap header to include paging controls. *@ - @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityFilter", @class = "sbm-form", @onSubmit = "return false;" })) - { - @* Header - Page caption, paging controls, actions. *@ -
-
-
-
@Localiser["caption.commodities"]
-
- @* Burger menu *@ - -
-
-
- - @* Filter Panel *@ -
-
-
- @* Commodity filter - code, description etc *@ -
@Localiser["label.search"]
-
- @Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterCommodity sbm-input", @maxlength = "32" }) -
-
-
- @* Commodity Category *@ -
@Localiser["label.type"]
-
- @Html.DropDownListFor(model => model.Filter.CommodityType, Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" }) -
-
-
-
-
-
- } - - @* Item list *@ -
- - - - - - - - - - - - - - - -
@Localiser["label.code"]@Localiser["label.description"]@Localiser["label.type"]@Localiser["label.sales.price"]@Localiser["label.unit.of.sale"]@Localiser["label.notes"]@Localiser["label.status"]
-
- - @* Element templates *@ -
- - @* List burger dropdown template - ul is ignored *@ -
    -
  • XXX
  • -
- - @* Item row template - table is ignored. *@ - - - - - - - - - - - -
-
- @* Burger menu *@ - -
-
- - @* Item burger dropdown template - ul is ignored *@ -
    -
  • XXX
  • -
- -
-
- -
- - + diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml index 2af19de..6d3f87c 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml @@ -1,7 +1,10 @@ -@model Model_Commodity +@* View is decoupled from Commodity model as it may be included in other views, eg. Transactions. *@ +@model SbmModel_Portal @inject SbmLocaliser Localiser @{ - /* Commodities - Commodity dialog panel */ + /* Commodity dialog panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Commodity/Panel-CommodityDialog")) return; } + +
+ + @* Filter form - wrap header to include paging controls. *@ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityFilter", @class = "sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Maintain, new { @id = "" }) + + @* Header - Page caption, paging controls, actions. *@ +
+
+
+
@Localiser["caption.commodities"]
+
+ @* Burger menu *@ + +
+
+
+ + @* Filter Panel *@ +
+
+
+ @* Commodity filter - code, description etc *@ +
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterCommodity sbm-input", @maxlength = "32" }) +
+
+
+ @* Commodity Category *@ +
@Localiser["label.type"]
+
+ @Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" }) +
+
+
+
+
+
+ } + + + +
+
+ +
+ + diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml new file mode 100644 index 0000000..87c1fde --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml @@ -0,0 +1,43 @@ +@* View is decoupled from Commodity model as it may be included in other views, eg. Transactions. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Commodity select panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Commodity/Panel-CommoditySelect")) return; + Model.AdditionalFiles_JS.Add("js/sbm-commodity.js"); +} + + + +
+ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmCommodityFilter sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Search, new { @id = "" }) + + @* Filter Panel *@ +
+
+
+ @* Commodity type *@ +
@Localiser["label.type"]
+
+ @Html.DropDownList("Filter.CommodityType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" }) +
+
+
+ @* Commodity filter - name etc. *@ +
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) +
+
+
+
+ } + + + +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Contact/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Contact/Index.cshtml index 330a2c6..029442d 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Contact/Index.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Contact/Index.cshtml @@ -1,7 +1,7 @@ @model Model_Contact @inject SbmLocaliser Localiser @{ - /* Contact page */ + /* Contact page. */ ViewData["Title"] = "Contacts"; } diff --git a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactDialog.cshtml b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactDialog.cshtml index d25bb77..5e4a29f 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactDialog.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactDialog.cshtml @@ -11,9 +11,10 @@ sbm.dlg.title.createContact = '@Localiser.GetJavascriptText("caption.contact.create")'; sbm.dlg.title.updateContact = '@Localiser.GetJavascriptText("caption.contact.update")'; + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmContactId", @class = "sbm-form" })) { - + @Html.Hidden("Contact.Id", "", new { @id = "", @class = "ContactId" }) }
@@ -59,7 +60,7 @@
- + @Html.TextBox("Contact.Abbreviation", "", new { @id = "ifContactAbbreviation", @class = "ContactAbbreviation sbm-input sbm-auto-val upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Abbrev) })
@@ -79,7 +80,7 @@
- + @Html.TextBox("Contact.Name", "", new { @id = "ifContactName", @class = "ContactName sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name) })
@@ -99,7 +100,7 @@
- + @Html.TextBox("Contact.Nature", "", new { @id = "ifContactNature", @class = "ContactNature sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Nature) })
@@ -120,7 +121,7 @@
- + @Html.TextBox("Contact.Contact", "", new { @id = "ifContactContact", @class = "ContactContact sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Contact) })
@@ -169,7 +170,7 @@
- + @Html.TextBox("Contact.Salutation", "", new { @id = "ifContactSalutation", @class = "ContactSalutation sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Salutation) })
@@ -192,7 +193,7 @@
- + @Html.TextBox("Contact.FirstName", "", new { @id = "ifContactFirstName", @class = "ContactFirstName sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName) })
@@ -213,7 +214,7 @@
- + @Html.TextBox("Contact.Initials", "", new { @id = "ifContactInitials", @class = "ContactInitials sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Initials) })
@@ -233,7 +234,7 @@
- + @Html.TextBox("Contact.LastName", "", new { @id = "ifContactLastName", @class = "ContactLastName sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName) })
@@ -253,7 +254,7 @@
- + @Html.TextBox("Contact.PhoneMain", "", new { @id = "ifContactPhoneMain", @class = "ContactPhoneMain sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_PhoneMain) })
@@ -274,7 +275,7 @@
- + @Html.TextBox("Contact.PhoneAlt", "", new { @id = "ifContactPhoneAlt", @class = "ContactPhoneAlt sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_PhoneAlt) })
@@ -291,7 +292,7 @@
- + @Html.TextBox("Contact.PhoneMobile", "", new { @id = "ifContactPhoneMobile", @class = "ContactPhoneMobile sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_PhoneMobile) })
@@ -314,7 +315,7 @@
- + @Html.TextBox("Contact.PhoneDirect", "", new { @id = "ifContactPhoneDirect", @class = "ContactPhoneDirect sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_PhoneDirect) })
@@ -335,7 +336,7 @@
- + @Html.TextBox("Contact.PhoneFax", "", new { @id = "ifContactPhoneFax", @class = "ContactPhoneFax sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_PhoneFax) })
@@ -355,7 +356,7 @@
- + @Html.TextBox("Contact.Email", "", new { @id = "ifContactEmail", @class = "ContactEmail sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Email) })
@@ -372,7 +373,7 @@
- + @Html.TextBox("Contact.Website", "", new { @id = "ifContactWebsite", @class = "ContactWebsite sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Website) })
@@ -392,7 +393,7 @@
- + @Html.TextBox("Contact.CompanyNo", "", new { @id = "ifContactCompanyNo", @class = "ContactCompanyNo sbm-input upper sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_CompanyNo) })
@@ -413,7 +414,7 @@
- + @Html.TextBox("Contact.VatReg", "", new { @id = "ifContactVatReg", @class = "ContactVatReg sbm-input upper sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_VatReg) })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactList.cshtml b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactList.cshtml index b851c3d..c1366e3 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactList.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactList.cshtml @@ -3,7 +3,7 @@ @inject SbmLocaliser Localiser @{ /* Contact list panel */ - /* NB Can potentially appear more than once on a page? */ + /* NB Can potentially appear more than once on a page. */ }