3.0.0.7 Transactions

This commit is contained in:
Andy Howard
2025-02-17 17:44:30 +00:00
parent 797ad08e5d
commit fa01e0799a
87 changed files with 1865 additions and 549 deletions
@@ -129,9 +129,6 @@
<data name="label.associations" xml:space="preserve">
<value>Associations</value>
</data>
<data name="caption.commodities" xml:space="preserve">
<value>Commodities</value>
</data>
<data name="caption.commodity" xml:space="preserve">
<value>Commodity</value>
</data>
@@ -339,9 +336,6 @@
<data name="msg.item.updated" xml:space="preserve">
<value>Item updated.</value>
</data>
<data name="msg.item.updated" xml:space="preserve">
<value>Item updated.</value>
</data>
<data name="msg.something.gone.wrong" xml:space="preserve">
<value>Unfortunately, something has gone wrong.\n\nYou will be returned to the home page.</value>
</data>
@@ -753,4 +747,85 @@
<data name="label.tax" xml:space="preserve">
<value>Tax</value>
</data>
<data name="label.sales.orders" xml:space="preserve">
<value>Sales orders</value>
</data>
<data name="label.raised" xml:space="preserve">
<value>Raised</value>
</data>
<data name="label.in.progress" xml:space="preserve">
<value>In progress</value>
</data>
<data name="label.required" xml:space="preserve">
<value>Required</value>
</data>
<data name="label.closed" xml:space="preserve">
<value>Closed</value>
</data>
<data name="label.amount.net" xml:space="preserve">
<value>Amount net</value>
</data>
<data name="label.amount.tax" xml:space="preserve">
<value>Amount tax</value>
</data>
<data name="label.customer" xml:space="preserve">
<value>Customer</value>
</data>
<data name="label.supplier" xml:space="preserve">
<value>Supplier</value>
</data>
<data name="caption.projects" xml:space="preserve">
<value>Projects</value>
</data>
<data name="caption.sales.leads" xml:space="preserve">
<value>Sales Leads</value>
</data>
<data name="caption.sales.quotes" xml:space="preserve">
<value>Sales Quotes</value>
</data>
<data name="caption.proforma.sales.orders" xml:space="preserve">
<value>Proforma Sales Orders</value>
</data>
<data name="caption.sales.purchase.orders" xml:space="preserve">
<value>SalesPurchaseOrders</value>
</data>
<data name="caption.sales.orders" xml:space="preserve">
<value>Sales Orders</value>
</data>
<data name="caption.sales.dispatches" xml:space="preserve">
<value>Sales Dispatches</value>
</data>
<data name="caption.proforma.sales.invoices" xml:space="preserve">
<value>Proforma Sales Invoices</value>
</data>
<data name="caption.sales.invoices" xml:space="preserve">
<value>Sales Invoices</value>
</data>
<data name="caption.purchase.quotes" xml:space="preserve">
<value>Purchase Quotes</value>
</data>
<data name="caption.purchase.sales.orders" xml:space="preserve">
<value>Purchase Sales Orders</value>
</data>
<data name="caption.purchase.orders" xml:space="preserve">
<value>Purchase Orders</value>
</data>
<data name="caption.purchase.deliveries" xml:space="preserve">
<value>Purchase Deliveries</value>
</data>
<data name="caption.proforma.purchase.invoices" xml:space="preserve">
<value>Proforma Purchase Invoices</value>
</data>
<data name="caption.purchase.invoices" xml:space="preserve">
<value>Purchase Invoices</value>
</data>
<data name="caption.proforma.purchase.orders" xml:space="preserve">
<value>Proforma Purchase Orders</value>
</data>
<data name="label.items" xml:space="preserve">
<value>Items</value>
</data>
<data name="label.raised.by" xml:space="preserve">
<value>Raised by</value>
</data>
</root>
@@ -204,6 +204,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Components
if (keepLoggedInParams.IsValid())
{
// Instance Repository configured on Control database identified by Context.
bool demoContext = keepLoggedInParams.RepositoryContext.EqualsCI(Sbm.RepositoryContext_Demo);
SbmSessionContext sessionContext = SbmCoreInstanceHelper_Portal.GetSessionContextByRepositoryContext(keepLoggedInParams.RepositoryContext);
if (sessionContext != null)
{
@@ -237,7 +238,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Components
}
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
}
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
else if (!demoContext)
SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
}
}
}
@@ -175,6 +175,15 @@ namespace Sarand.BusinessMgr.Web.Portal.Components
if (commoditiesItem.Options.Any())
Menu.Items.Add(commoditiesItem);
// Transactions.
if (SessionConsole.AllowOption(Sbm.ConfigOption.Transactions))
{
MenuItemData transactionsItem = new MenuItemData() { Caption = @Localiser["label.transactions"] };
transactionsItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.sales.orders"], Page = "Transactions/SalesOrder" });
if (transactionsItem.Options.Any())
Menu.Items.Add(transactionsItem);
}
// Reference.
MenuItemData referenceItem = new MenuItemData() { Caption = @Localiser["label.reference"] };
referenceItem.Options.Add(new MenuOptionData() { Caption = @Localiser["caption.code.types"], Page = "Codes/CodeType" });
@@ -4,11 +4,14 @@ using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Net.Standard.Base.Core;
using Sarand.BusinessMgr.Net.Standard.Base.Data;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
using Sarand.BusinessMgr.Web.Portal.App;
using Sarand.BusinessMgr.Web.Portal.Components;
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.Helpers;
using Sarand.Net.Standard.Base.ReferenceData;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
@@ -16,6 +19,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Transactions;
namespace Sarand.BusinessMgr.Web.Portal.Consoles
{
@@ -87,37 +91,29 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
data.InitData.User.Password = "ap@www.boardgameoutlet.co.uk";
// Contacts - Organisations.
SbmRepositoryPopulationData.OrganisationData organisation01 = new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Online Board Games" };
organisation01.SetCustomer("CUST123");
SbmRepositoryPopulationData.OrganisationData organisation02 = new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Traditional Pastimes Ltd" };
organisation02.SetCustomer("CUST017");
SbmRepositoryPopulationData.OrganisationData organisation03 = new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Surplus Stock Ltd" };
organisation02.SetSupplier("SUPP012");
SbmRepositoryPopulationData.OrganisationData organisation04 = new SbmRepositoryPopulationData.CharityOrganisationData() { Name = "Ethical Game Redistribution" };
organisation04.SetCustomer("CUST1234");
organisation04.SetSupplier("SUPP018");
data.Organisations.AddRange(new List<SbmRepositoryPopulationData.OrganisationData>() { organisation01, organisation02, organisation03, organisation04 });
data.Organisations.Add(new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Online Board Games", CustomerCode = "CUST123" });
data.Organisations.Add(new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Traditional Pastimes Ltd", CustomerCode = "CUST017" });
data.Organisations.Add(new SbmRepositoryPopulationData.CommercialOrganisationData() { Name = "Surplus Stock Ltd", SupplierCode = "SUPP012" });
data.Organisations.Add(new SbmRepositoryPopulationData.CharityOrganisationData() { Name = "Ethical Game Redistribution", CustomerCode = "CUST124", SupplierCode = "SUPP018" });
data.Organisations.Add(new SbmRepositoryPopulationData.CharityOrganisationData() { Name = "The Games Emporium", CustomerCode = "CUST004" });
data.Organisations.Add(new SbmRepositoryPopulationData.CharityOrganisationData() { Name = "Spare Time Cafe", CustomerCode = "CUST016" });
data.Organisations.Add(new SbmRepositoryPopulationData.CharityOrganisationData() { Name = "Take a Break Coffee Shop", CustomerCode = "CUST102" });
// Contact - Individuals.
SbmRepositoryPopulationData.IndividualData individual01 = new SbmRepositoryPopulationData.IndividualData() { FirstName = "Billy", LastName = "Sparks", Email = "bs@www.boardgameoutlet.co.uk" };
individual01.SetMember("OBG110", "Dice Cleaner");
SbmRepositoryPopulationData.IndividualData individual02 = new SbmRepositoryPopulationData.IndividualData() { FirstName = "Sally", LastName = "Sparks", Email = "ss@www.boardgameoutlet.co.uk" };
individual02.SetMember("OBG120", "Banker");
data.Individuals.AddRange(new List<SbmRepositoryPopulationData.IndividualData>() { individual01, individual02 });
data.Individuals.Add(new SbmRepositoryPopulationData.IndividualData() { FirstName = "Billy", LastName = "Sparks", Email = "bs@www.boardgameoutlet.co.uk", MemberCode = "OBG110", MemberRole = "Dice Cleaner" });
data.Individuals.Add(new SbmRepositoryPopulationData.IndividualData() { FirstName = "Sally", LastName = "Sparks", Email = "ss@www.boardgameoutlet.co.uk", MemberCode = "OBG120", MemberRole = "Banker" });
// Commodities.
SbmRepositoryPopulationData.CommodityData commodity01 = new SbmRepositoryPopulationData.StockCommodityData() { Code = "MONOPOLY-STD", Caption = "Monopoly", SalePrice = 24.75m };
SbmRepositoryPopulationData.CommodityData commodity02 = new SbmRepositoryPopulationData.StockCommodityData() { Code = "MONOPOLY-DEL", Caption = "Monopoly Deluxe", SalePrice = 32.45m };
SbmRepositoryPopulationData.CommodityData commodity03 = new SbmRepositoryPopulationData.StockCommodityData() { Code = "CLUEDO-STD", Caption = "Cluedo", SalePrice = 18.25m };
SbmRepositoryPopulationData.CommodityData commodity04 = new SbmRepositoryPopulationData.StockCommodityData() { Code = "RISK-STD", Caption = "Risk", SalePrice = 21.50m };
SbmRepositoryPopulationData.CommodityData commodity90 = new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-EXP", Caption = "Expert Tuition", SalePrice = 45.00m };
SbmRepositoryPopulationData.CommodityData commodity91 = new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-STD", Caption = "Standard Tuition", SalePrice = 38.75m };
SbmRepositoryPopulationData.CommodityData commodity92 = new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-BAS", Caption = "Basic Tuition", SalePrice = 32.50m };
data.Commodities.AddRange(new List<SbmRepositoryPopulationData.CommodityData>()
{
commodity01, commodity02, commodity03, commodity04,
commodity90, commodity91, commodity92
});
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "MONOPOLY-STD", Caption = "Monopoly", SalePrice = 24.75m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "MONOPOLY-DEL", Caption = "Monopoly Deluxe", SalePrice = 32.45m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "CLUEDO-STD", Caption = "Cluedo", SalePrice = 18.25m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "RISK-STD", Caption = "Risk", SalePrice = 21.50m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "JIGS-1000", Caption = "1000 piece jigsaw", SalePrice = 12.25m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "JIGS-2500", Caption = "2500 piece jigsaw", SalePrice = 16.75m });
data.Commodities.Add(new SbmRepositoryPopulationData.StockCommodityData() { Code = "JIGS-5000", Caption = "5000 piece jigsaw", SalePrice = 18.50m });
data.Commodities.Add(new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-EXP", Caption = "Expert Tuition", SalePrice = 45.00m });
data.Commodities.Add(new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-STD", Caption = "Standard Tuition", SalePrice = 38.75m });
data.Commodities.Add(new SbmRepositoryPopulationData.ServiceCommodityData() { Code = "TUITION-BAS", Caption = "Basic Tuition", SalePrice = 32.50m });
return data;
}
@@ -164,8 +160,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
if (!ConfigureSecurityComponents()) return false;
// Populate demo data.
if (!PopulateCommodities(data)) return false;
if (!PopulateContacts(data)) return false;
// NB Log any errors but continue with population to ensure at least some data results.
PopulateCommodities(data);
PopulateContacts(data);
PopulateTransactions(data);
return OK;
}
@@ -239,11 +237,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
commodity.DescBrief = commodityData.Caption;
commodity.SalesPrice = commodityData.SalePrice;
commodity.UomIdSale = uomTypes.GetValueOrDefault(commodityData.SaleUnitType)?.Id;
if (!Internals.CommodityMgr.InsertCommodity(commodity, DbUpdateInfo))
commodity.Notes = commodityData.Notes;
if (Internals.CommodityMgr.InsertCommodity(commodity, DbUpdateInfo))
{
commodityData.Id = commodity.Id;
}
else
{
string msg = "Repository population failed (Commodity).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.CommodityMgr.ErrorStateMessage.TrimEnd('.')}.");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
}
return OK;
@@ -274,8 +277,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
affiliate.CompanyNo = organisation.CompanyNo;
affiliate.VatReg = organisation.VatReg;
affiliate.Website = organisation.Website;
affiliate.Notes = organisation.Notes;
if (Internals.AccountMgr.InsertAffiliate(affiliate, DbUpdateInfo))
{
organisation.Id = affiliate.Id;
if (!PopulateAffiliate(data.AffiliateIdOrganisation, affiliate, organisation))
return false;
}
@@ -283,7 +288,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
{
string msg = "Repository population failed (Individual).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.AccountMgr.ErrorStateMessage.TrimEnd('.')}.");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
}
@@ -296,8 +301,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
affiliate.Email = individual.Email;
affiliate.PhoneMain = individual.PhoneMain;
affiliate.PhoneMobile = individual.PhoneMobile;
affiliate.Notes = individual.Notes;
if (Internals.AccountMgr.InsertAffiliate(affiliate, DbUpdateInfo))
{
individual.Id = affiliate.Id;
if (!PopulateAffiliate(data.AffiliateIdOrganisation, affiliate, individual))
return false;
}
@@ -305,10 +312,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
{
string msg = "Repository population failed (Individual).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.AccountMgr.ErrorStateMessage.TrimEnd('.')}.");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
}
return OK;
}
@@ -327,33 +333,38 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
address.Province = address.Province;
address.Postcode = address.Postcode;
address.Country = address.Country;
if (!Internals.AccountMgr.InsertAddress(address, DbUpdateInfo))
address.Notes = address.Notes;
if (Internals.AccountMgr.InsertAddress(address, DbUpdateInfo))
{
addressData.Id = address.Id;
}
else
{
string msg = "Repository population failed (Address).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.AccountMgr.ErrorStateMessage.TrimEnd('.')}.");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
}
// Associations.
if (!PopulateAssociation(affilliateIdOwner, affiliate, affiliateData.Customer))
{
string msg = "Repository population failed (Customer).";
SaLogger.Warn($"{SysUtil.Fn} {msg}");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
if (!PopulateAssociation(affilliateIdOwner, affiliate, affiliateData.Supplier))
{
string msg = "Repository population failed (Supplier).";
SaLogger.Warn($"{SysUtil.Fn} {msg}");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
if (!PopulateAssociation(affilliateIdOwner, affiliate, affiliateData.Member))
{
string msg = "Repository population failed (Member).";
SaLogger.Warn($"{SysUtil.Fn} {msg}");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
return OK;
}
@@ -362,23 +373,173 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
{
if (HasErrorState()) return false;
if (associationData == null) return true;
SbmAssociation association = Internals.AccountMgr.CreateAssociation(affilliateIdOwner, associationData.Type, affiliate.Id);
association.Code = associationData.Code;
association.Location = associationData.Location;
association.Role = associationData.Role;
association.PhoneMain = associationData.PhoneMain;
association.Notes = associationData.Notes;
if (Internals.AccountMgr.InsertAssociation(association, DbUpdateInfo))
{
// ToDo Populate Transactions.
associationData.Id = association.Id;
}
else
{
string msg = $"Repository population failed ({associationData.Type}).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.AccountMgr.ErrorStateMessage.TrimEnd('.')}.");
return SetErrorState($"{msg}");
//return SetErrorState($"{msg}");
}
return OK;
}
//-------------------------------------------------------------------
private class TransactionData
{
public TransactionData(SbmTransaction transaction)
{
this.Transaction = transaction;
}
public SbmTransaction Transaction { get; }
public List<SbmRequirement> Requirements { get; } = new List<SbmRequirement>();
}
// Populate demo transactions.
private bool PopulateTransactions(SbmRepositoryPopulationData data)
{
if (HasErrorState()) return false;
SysId affilliateIdOwner = data.AffiliateIdOrganisation;
Dictionary<String, SaTaxCode> taxCodes = Internals.GetTaxCodesEffectiveOn(DateTime.Today).ToDictionary(item => item.Code, item => item);
SaTaxCode taxCodeDefault = taxCodes.Values.FirstOrDefault(item => item.Code.EqualsCI(Internals.GetDefaultTaxCode()));
//---------------------------------------------------------------
// Sales Orders.
// Customers.
List<SbmRepositoryPopulationData.CustomerData> customers =
data.Organisations.Concat<SbmRepositoryPopulationData.AffiliateData>(data.Individuals)
.Where(item => item.Customer != null && SysId.IsValid(item.Customer.Id))
.Select(item => item.Customer)
.ToList();
// Compile transactions and requirements.
List<TransactionData> transactions = new List<TransactionData>();
// Sales Orders for Customers.
foreach (var customerData in customers)
{
int transactionCount = 0;
DateTime raisedOn = DateTime.Today;
for (int i = 0; i < SacsRandomHelper.GetInt32(6, 24); i++)
{
// Prepare transaction data.
transactionCount++;
raisedOn = DateUtil.IncrementDate(raisedOn, -SacsRandomHelper.GetInt32(2, transactionCount == 1 ? 5 : 18));
// Create transaction.
SbmTransaction salesOrder = Internals.TransactionMgr.CreateTransaction(customerData.Id, Sbm.TransactionType.SalesOrder);
salesOrder.DescBrief = "";
salesOrder.Status = SaStatus.InProgress;
salesOrder.Raised = raisedOn;
salesOrder.InProgress = DateUtil.IncrementDate(salesOrder.Raised, SacsRandomHelper.GetInt32(0, 2));
if (transactionCount > SacsRandomHelper.GetInt32(1, 3))
{
salesOrder.Status = SaStatus.Completed;
salesOrder.Closed = DateUtil.IncrementDate(salesOrder.InProgress, SacsRandomHelper.GetInt32(2, 5));
}
salesOrder.RaisedBy = "";
salesOrder.ContactName = "";
salesOrder.Notes = "";
TransactionData transactionData = new TransactionData(salesOrder);
transactions.Add(transactionData);
}
}
// Store transactions in 'Raised' order before adding requirements.
foreach (var transactionData in transactions.OrderBy(item => item.Transaction.Raised))
{
// Transaction must exist before requirements are created.
if (Internals.TransactionMgr.InsertTransaction(transactionData.Transaction, DbUpdateInfo))
{
}
else
{
string msg = "Repository population failed (Transaction).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.TransactionMgr.ErrorStateMessage.TrimEnd('.')}.");
//return SetErrorState($"{msg}");
}
}
// Add requirements.
foreach (var transactionData in transactions)
{
if (!SysId.IsValid(transactionData.Transaction.Id)) continue;
// Add requirements.
int serviceCommodityCount = 0;
foreach (var commodityData in data.Commodities)
{
// Only include 1 in 3 items.
if (SacsRandomHelper.GetInt32(0, 3) < 1) continue;
if (commodityData.Type == Sbm.CommodityType.Service)
{
serviceCommodityCount++;
if (serviceCommodityCount > 1) continue;
}
SbmRequirement requirement = Internals.TransactionMgr.CreateRequirement(transactionData.Transaction.AssociationId, transactionData.Transaction.Id, Sbm.RequirementType.Detail);
requirement.CommodityId = commodityData.Id;
requirement.DescBrief = commodityData.Caption;
requirement.Quantity = (decimal)(commodityData.Type == Sbm.CommodityType.Service ? 0.25 * SacsRandomHelper.GetInt32(2, 12) : SacsRandomHelper.GetInt32(1, 6));
requirement.AmountUnit = commodityData.SalePrice;
requirement.AmountNet = requirement.AmountUnit * requirement.Quantity;
requirement.TaxCodeId = taxCodeDefault?.Id;
Internals.TransactionMgr.SetTaxCode(requirement, transactionData.Transaction.InProgress);
Internals.TransactionMgr.CalculateTotal(requirement);
transactionData.Requirements.Add(requirement);
}
// Assign requirement sequence in random order.
short sequence = 0;
foreach (SbmRequirement requirement in transactionData.Requirements.OrderBy(x => Guid.NewGuid()))
requirement.Seq = ++sequence;
}
//---------------------------------------------------------------
StoreTransactions(transactions);
return OK;
}
private bool StoreTransactions(List<TransactionData> transactions)
{
// Store transactions and requirements.
// Sort so from oldest to newest to mimc real-world.
foreach (TransactionData transactionData in transactions.OrderBy(item => item.Transaction.Raised))
{
if (SysId.IsValid(transactionData.Transaction.Id) || Internals.TransactionMgr.InsertTransaction(transactionData.Transaction, DbUpdateInfo))
{
List<SbmRequirement> requirements = transactionData.Requirements;
foreach (var requirement in requirements.OrderBy(item => item.Seq))
{
if (!Internals.TransactionMgr.InsertRequirement(requirement, DbUpdateInfo))
{
string msg = "Repository population failed (Requirement).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.TransactionMgr.ErrorStateMessage.TrimEnd('.')}.");
//return SetErrorState($"{msg}");
}
}
// Update transaction totals.
Internals.TransactionMgr.RefreshTransactionTotals(transactionData.Transaction, requirements.Where(item => SysId.IsValid(item.Id)));
if (!Internals.TransactionMgr.UpdateTransaction(transactionData.Transaction, DbUpdateInfo))
SaLogger.Warn($"{SysUtil.Fn} Faield to update transaction. {Internals.TransactionMgr.ErrorStateMessage.TrimEnd('.')}.");
}
else
{
string msg = "Repository population failed (Transaction).";
SaLogger.Warn($"{SysUtil.Fn} {msg} {Internals.TransactionMgr.ErrorStateMessage.TrimEnd('.')}.");
//return SetErrorState($"{msg}");
}
}
return OK;
}
@@ -111,12 +111,13 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
{
// Construction.
public AjaxResponse_CommodityConfig(SbmModel_Portal model) : base(model) { }
// Configuration.
public Model_Commodity.ListConfigData Config { get; } = new Model_Commodity.ListConfigData();
public Model_Commodity.ItemConfigData ConfigItemNew { get; } = new Model_Commodity.ItemConfigData();
// Reference data - object copied directly to env.datain script.
public class ReferenceData
// Configuration data - object copied directly to env.datain script.
public class ConfigData
{
// Configurations.
public Model_Commodity.ListConfigData CfgList { get; } = new Model_Commodity.ListConfigData();
public Model_Commodity.ItemConfigData CfgItemNew { get; } = new Model_Commodity.ItemConfigData();
// Reference data.
public List<ItemCodeDesc> CommodityTypes { get; } = new List<ItemCodeDesc>();
public String CommodityTypeDefault { get; set; }
public List<TaxCode> TaxCodes { get; } = new List<TaxCode>();
@@ -128,7 +129,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
public List<ItemCodeDesc> Statuses { get; } = new List<ItemCodeDesc>();
public String DefaultStatusCode { get; set; }
}
public ReferenceData Data { get; set; } = new ReferenceData();
public ConfigData Data { get; set; } = new ConfigData();
}
// Ajax request.
[HttpPost]
@@ -137,7 +138,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
public IActionResult Ajax_CommodityConfig(Model_Commodity model)
{
AjaxResponse_CommodityConfig responseData = new AjaxResponse_CommodityConfig(model);
String messageTitle = Localiser["caption.commodities"];
String messageTitle = Localiser["label.commodities"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
@@ -154,8 +155,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
private void PopulateCommodityConfig(Model_Commodity model, AjaxResponse_CommodityConfig responseData)
{
// Configuration.
model.PopulateListConfig(responseData.Config);
model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.CommodityType.Unknown);
model.PopulateListConfig(responseData.Data.CfgList);
model.PopulateItemConfig(responseData.Data.CfgItemNew, null, Sbm.CommodityType.Unknown);
// Commodity types.
List<TypeCodeDesc> commodityTypes = GetSystemCodes(Sbm.SystemCode.CommodityType);
@@ -183,7 +184,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
Id = $"{SysId.ToLong(uom.Id)}",
Category = uomCategories.GetCodeForType(uom.Category),
Type = uomTypes.GetCodeForType(uom.UnitType),
Caption = uom.Multiple,
Caption = uom.GetCaption()
});
}
responseData.Data.uomTypeDefault = uomTypes.GetCodeForType(Internals.GetDefaultUomType());
@@ -220,7 +221,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
public IActionResult Ajax_CommodityList(Model_Commodity model)
{
AjaxResponse_CommodityList responseData = new AjaxResponse_CommodityList(model);
String messageTitle = Localiser["caption.commodities"];
String messageTitle = Localiser["label.commodities"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
@@ -338,7 +339,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
[Route("Commodity/Ajax/GetItem")]
public IActionResult Ajax_GetItem(Model_Commodity model)
{
String messageTitle = Localiser["caption.commodity"];
String messageTitle = Localiser["label.commodity"];
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
// Validate session and referrer.
@@ -380,7 +381,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
[Route("Commodity/Ajax/StoreItem")]
public IActionResult Ajax_StoreItem(Model_Commodity model)
{
String messageTitle = Localiser["caption.commodity"];
String messageTitle = Localiser["label.commodity"];
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
// Validate session and referrer.
@@ -94,16 +94,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
{
// Construction.
public AjaxResponse_AssociationConfig(SbmModel_Portal model) : base(model) { }
// Page caption.
public String Caption { get; set; }
// Configuration.
public Model_Association.ListConfigData Config { get; } = new Model_Association.ListConfigData();
public Model_Association.ItemConfigData ConfigCust { get; } = new Model_Association.ItemConfigData();
public Model_Association.ItemConfigData ConfigSupp { get; } = new Model_Association.ItemConfigData();
// Reference data.
public List<ItemCodeDesc> AssociationTypes { get; } = new List<ItemCodeDesc>();
public List<ItemCodeDesc> Statuses { get; } = new List<ItemCodeDesc>();
public String DefaultStatusCode { get; set; }
// Configuration data - object copied directly to env.datain script.
public class ConfigData
{
// Configuration.
public Model_Association.ListConfigData CfgList { get; } = new Model_Association.ListConfigData();
public Model_Association.ItemConfigData CfgCust { get; } = new Model_Association.ItemConfigData();
public Model_Association.ItemConfigData CfgSupp { get; } = new Model_Association.ItemConfigData();
// Reference data.
public List<ItemCodeDesc> AssociationTypes { get; } = new List<ItemCodeDesc>();
public List<ItemCodeDesc> Statuses { get; } = new List<ItemCodeDesc>();
public String DefaultStatusCode { get; set; }
}
public ConfigData Data { get; set; } = new ConfigData();
}
// Ajax request.
[HttpPost]
@@ -128,18 +131,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
}
private void PopulateAssociationConfig(Model_Association model, AjaxResponse_AssociationConfig responseData)
{
// Page caption.
Sbm.AssociationType associationType = model.GetFilterAssociationType();
if (associationType == Sbm.AssociationType.Customer)
responseData.Caption = Localiser["label.customers"];
else if (associationType == Sbm.AssociationType.Supplier)
responseData.Caption = Localiser["label.suppliers"];
responseData.Caption = StringUtil.OnBlank(responseData.Caption, Localiser["label.associations"]);
// Configuration.
model.PopulateListConfig(responseData.Config);
model.PopulateItemConfig(responseData.ConfigCust, null, SessionData_Portal.Organisation.AffiliateId, Sbm.AssociationType.Customer);
model.PopulateItemConfig(responseData.ConfigSupp, null, SessionData_Portal.Organisation.AffiliateId, Sbm.AssociationType.Supplier);
model.PopulateListConfig(responseData.Data.CfgList);
model.PopulateItemConfig(responseData.Data.CfgCust, null, SessionData_Portal.Organisation.AffiliateId, Sbm.AssociationType.Customer);
model.PopulateItemConfig(responseData.Data.CfgSupp, null, SessionData_Portal.Organisation.AffiliateId, Sbm.AssociationType.Supplier);
// Reference data - types.
List<TypeCodeDesc> associationTypes = Internals.AssociationTypeCodes;
@@ -147,13 +142,13 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
{
if (type <= 0 || type == Sbm.AssociationType.Internal) continue;
if (!SessionConsole.AllowAssociationType(type)) continue;
responseData.AssociationTypes.Add(new AjaxResponse_Data.ItemCodeDesc(associationTypes.GetCodeForType(type), Localiser.GetAssociationTypeCaption(type)));
responseData.Data.AssociationTypes.Add(new AjaxResponse_Data.ItemCodeDesc(associationTypes.GetCodeForType(type), Localiser.GetAssociationTypeCaption(type)));
}
// Reference data - statuses.
foreach (SaStatus status in SbmAssociation.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
responseData.Statuses.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)));
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmAssociation.DefaultStatus);
responseData.Data.Statuses.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)));
responseData.Data.DefaultStatusCode = SacsSystem.GetStatusCode(SbmAssociation.DefaultStatus);
}
//-------------------------------------------------------------------
@@ -20,7 +20,6 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using static Sarand.BusinessMgr.Net.Standard.Base.Data.SbmRepositoryPopulationData;
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Home
{
@@ -190,7 +189,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Home
// Check that User Account doesn't already exist.
SbmRepositoryPopulationData.UserAccount userAccount = new UserAccount()
SbmRepositoryPopulationData.UserAccount userAccount = new SbmRepositoryPopulationData.UserAccount()
{
AffiliateIdOwner = demoData.AffiliateIdOrganisation,
FirstName = model.FirstName,
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using DocumentFormat.OpenXml.EMMA;
using Microsoft.AspNetCore.Mvc;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Web.Portal.Components;
@@ -40,24 +41,40 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
public String TypeCode { get; set; }
public String TypeDesc { get; set; }
}
private void PopulateTransactionResponseListData(SbmTransaction transaction, TransactionListData data)
private void PopulateTransactionResponseListData(SbmModel_Portal model, SbmTransaction transaction, TransactionListData data)
{
data.Id = SysId.ToString(transaction.Id);
// Derived values for list refresh.
long itemCount = TransactionMgr.GetTransactionRequirementCount(transaction.Id);
if (itemCount > 0)
data.Field.Value.Add($"{Model_Transaction.ItemField.ItemCount}", $"{itemCount}");
// Status dates for list refresh.
data.Field.Value.Add($"{Model_Transaction.ItemField.RaisedFmt}", model.FormatDateForDisplay(transaction.Raised));
data.Field.Value.Add($"{Model_Transaction.ItemField.InProgressFmt}", model.FormatDateForDisplay(transaction.InProgress));
data.Field.Value.Add($"{Model_Transaction.ItemField.ClosedFmt}", model.FormatDateForDisplay(transaction.Closed));
}
private void PopulateTransactionResponseItemData(SbmTransaction transaction, TransactionItemData data, HashSet<TransactionDataGroup> dataGroups = null)
private void PopulateTransactionResponseItemData(SbmModel_Portal model, SbmTransaction transaction, TransactionItemData data, HashSet<TransactionDataGroup> dataGroups = null)
{
PopulateTransactionResponseListData(transaction, data as TransactionListData);
PopulateTransactionResponseListData(model, transaction, data as TransactionListData);
// Prominent properties for selecting and editing.
data.Reference = transaction.Ref;
data.Narrative = transaction.DescBrief;
// Affiliate type - populate for list ('Type' property populated with desc) and form (Type Code & Desc).
data.TypeCode = Internals.TransactionTypeCodes.GetCodeForType(transaction.TransactionType);
data.TypeDesc = Internals.TransactionTypeCodes.GetDescForType(transaction.TransactionType);
data.Field.Value.Add($"{Model_Transaction.ItemField.Type}", Internals.TransactionTypeCodes.GetDescForType(transaction.TransactionType));
// Transaction properties.
data.Field.Value.Add($"{Model_Transaction.ItemField.Type}", Internals.TransactionTypeCodes.GetDescForType(transaction.TransactionType));
data.Field.Value.Add($"{Model_Transaction.ItemField.AssociationId}", $"{SysId.ToInt(transaction.AssociationId)}");
data.Field.Value.Add($"{Model_Transaction.ItemField.AssociationName}", AccountMgr.GetAssociationTargetName(transaction.AssociationId));
data.Field.Value.Add($"{Model_Transaction.ItemField.Reference}", transaction.Ref);
data.Field.Value.Add($"{Model_Transaction.ItemField.ReferenceExt}", transaction.RefExt);
data.Field.Value.Add($"{Model_Transaction.ItemField.DescBrief}", transaction.DescBrief);
data.Field.Value.Add($"{Model_Transaction.ItemField.ContactName}", transaction.ContactName);
data.Field.Value.Add($"{Model_Transaction.ItemField.RaisedBy}", transaction.RaisedBy);
// Status dates.
data.Field.Value.Add($"{Model_Transaction.ItemField.Raised}", model.FormatDateForForm(transaction.Raised));
data.Field.Value.Add($"{Model_Transaction.ItemField.InProgress}", model.FormatDateForForm(transaction.InProgress));
data.Field.Value.Add($"{Model_Transaction.ItemField.Closed}", model.FormatDateForForm(transaction.Closed));
if (dataGroups != null && dataGroups.Contains(TransactionDataGroup.Core))
{
// Core.
@@ -88,13 +105,18 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
{
// Construction.
public AjaxResponse_TransactionConfig(SbmModel_Portal model) : base(model) { }
// Configuration.
public Model_Transaction.ListConfigData Config { get; } = new Model_Transaction.ListConfigData();
public Model_Transaction.ItemConfigData ConfigItemNew { get; } = new Model_Transaction.ItemConfigData();
// Reference data.
public List<ItemCodeDesc> TransactionTypes { get; } = new List<ItemCodeDesc>();
public List<ItemCodeDesc> Statuses { get; } = new List<ItemCodeDesc>();
public String DefaultStatusCode { get; set; }
// Configuration data - object copied directly to env.datain script.
public class ConfigData
{
// Configurations.
public Model_Transaction.ListConfigData CfgList { get; } = new Model_Transaction.ListConfigData();
public Model_Transaction.ItemConfigData CfgItemNew { get; } = new Model_Transaction.ItemConfigData();
// Reference data.
public List<ItemCodeDesc> TransactionTypes { get; } = new List<ItemCodeDesc>();
public List<ItemCodeDesc> Statuses { get; } = new List<ItemCodeDesc>();
public String DefaultStatusCode { get; set; }
}
public ConfigData Data { get; set; } = new ConfigData();
}
// Ajax request.
[HttpPost]
@@ -103,7 +125,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
public IActionResult Ajax_TransactionConfig(Model_Transaction model)
{
AjaxResponse_TransactionConfig responseData = new AjaxResponse_TransactionConfig(model);
String messageTitle = Localiser["caption.transactions"];
String messageTitle = Localiser["label.transactions"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
@@ -120,17 +142,17 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
private void PopulateTransactionConfig(Model_Transaction model, AjaxResponse_TransactionConfig responseData)
{
// Configuration.
model.PopulateListConfig(responseData.Config);
model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.TransactionType.Unknown);
model.PopulateListConfig(responseData.Data.CfgList);
model.PopulateItemConfig(responseData.Data.CfgItemNew, null, Sbm.TransactionType.Unknown);
// Reference data - transaction types.
foreach (TypeCodeDesc transactionType in GetSystemCodes(Sbm.SystemCode.TransactionType))
responseData.TransactionTypes.Add(new AjaxResponse_Data.ItemCodeDesc(transactionType.Code, transactionType.Desc));
responseData.Data.TransactionTypes.Add(new AjaxResponse_Data.ItemCodeDesc(transactionType.Code, transactionType.Desc));
// Reference data - statuses.
foreach (SaStatus status in SbmTransaction.ValidStatuses().FindAll(item => item != SaStatus.Deleted))
responseData.Statuses.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)));
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmTransaction.DefaultStatus);
responseData.Data.Statuses.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)));
responseData.Data.DefaultStatusCode = SacsSystem.GetStatusCode(SbmTransaction.DefaultStatus);
}
//-------------------------------------------------------------------
@@ -161,7 +183,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
public IActionResult Ajax_TransactionList(Model_Transaction model)
{
AjaxResponse_TransactionList responseData = new AjaxResponse_TransactionList(model);
String messageTitle = Localiser["caption.transactions"];
String messageTitle = Localiser["label.transactions"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
@@ -173,16 +195,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
// View mode.
responseData.Mode = new AjaxResponse_TransactionList.ModeData();
Model_Transaction.TransactionViewMode viewMode = model.GetFilterMode();
if (viewMode == Model_Transaction.TransactionViewMode.Maintain)
Model_Transaction.ViewMode viewMode = model.GetFilterMode();
if (viewMode == Model_Transaction.ViewMode.Maintain)
responseData.Mode.Maintain = true;
else if (viewMode == Model_Transaction.TransactionViewMode.SearchRequirement)
else if (viewMode == Model_Transaction.ViewMode.SearchRequirement)
responseData.Mode.SearchRequirement = true;
else if (viewMode == Model_Transaction.TransactionViewMode.DeliveryPlanning)
else if (viewMode == Model_Transaction.ViewMode.DeliveryPlanning)
responseData.Mode.DeliveryPlanning = true;
else if (viewMode == Model_Transaction.TransactionViewMode.TransactionsForSourceTrans)
else if (viewMode == Model_Transaction.ViewMode.TransactionsForSourceTrans)
responseData.Mode.TransactionsForSourceTrans = true;
else if (viewMode == Model_Transaction.TransactionViewMode.TransactionsForAssociation)
else if (viewMode == Model_Transaction.ViewMode.TransactionsForAssociation)
responseData.Mode.TransactionsForAssociation = true;
else
responseData.Mode.Search = true;
@@ -191,7 +213,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
SbmTransaction.Params prmTransaction = new SbmTransaction.Params();
prmTransaction.Search = model.Filter.Search;
prmTransaction.TransactionType = model.GetFilterTransactionType();
prmTransaction.StatusCat = SbmTransaction.StatusCat.NotDeleted;
if (model.GetFilterTransactionStatusCat() > 0)
prmTransaction.StatusCat = model.GetFilterTransactionStatusCat();
else prmTransaction.StatusCat = SbmTransaction.StatusCat.NotDeleted;
if (model.GetFilterTransactionType() <= 0)
prmTransaction.SortColumns.Add(TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Type_Desc));
prmTransaction.SortColumns.Add(TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Ref));
@@ -200,10 +224,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
// Item columns.
ColumnDfn colId = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Id);
ColumnDfn colTargetName = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AssocTarget_Name);
ColumnDfn colType = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Type_Desc);
ColumnDfn colRef = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Ref);
ColumnDfn colRefExt = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.RefExt);
ColumnDfn colDescBrief = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.DescBrief);
ColumnDfn colItemCount = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.ReqntCount);
ColumnDfn colRaisedOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.RaisedOn);
ColumnDfn colRequiredOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.RequiredOn);
ColumnDfn colInProgressOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.InProgressOn);
ColumnDfn colClosedOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.ClosedOn);
ColumnDfn colAmountNet = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountNet);
ColumnDfn colAmountTax = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountTax);
ColumnDfn colAmountTot = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountTot);
@@ -213,7 +243,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
ColumnDfn colUpdatedOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.UpdateOn_Date);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
colId, colType, colRef, colRefExt, colDescBrief,
colId, colTargetName, colType, colRef, colRefExt, colDescBrief, colItemCount,
colRaisedOn, colRequiredOn, colInProgressOn, colClosedOn,
colNotes, colStatus, colCreatedOn, colUpdatedOn
};
if (model.UserCanViewFinancials())
@@ -233,10 +264,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
Narrative = values.GetString(colDescBrief.DataName),
StatusCode = values.GetString(colStatus.DataName),
};
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.AssociationName}", values.GetString(colTargetName.DataName));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Type}", Internals.TransactionTypeCodes.GetDescForType(transactionType));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Reference}", values.GetString(colRef.DataName));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.ReferenceExt}", values.GetString(colRefExt.DataName));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.DescBrief}", values.GetString(colDescBrief.DataName));
long itemCount = values.GetLong(colItemCount.DataName);
if (itemCount > 0)
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.ItemCount}", $"{itemCount}");
// Status dates.
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.RaisedFmt}", model.FormatDateForDisplay(values.GetDate(colRaisedOn.DataName)));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.RequiredFmt}", model.FormatDateForDisplay(values.GetDate(colRequiredOn.DataName)));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.InProgressFmt}", model.FormatDateForDisplay(values.GetDate(colInProgressOn.DataName)));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.ClosedFmt}", model.FormatDateForDisplay(values.GetDate(colClosedOn.DataName)));
if (model.UserCanViewFinancials())
{
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.AmountNet}", colAmountNet.FormatValue(values));
@@ -283,7 +323,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
[Route("Transaction/Ajax/GetItem")]
public IActionResult Ajax_GetItem(Model_Transaction model)
{
String messageTitle = Localiser["caption.transaction"];
String messageTitle = Localiser["label.transaction"];
AjaxResponse_Transaction responseData = new AjaxResponse_Transaction(model);
// Validate session and referrer.
@@ -306,7 +346,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
// Construct response.
model.PopulateItemConfig(responseData.Config, transaction);
PopulateTransactionResponseItemData(transaction, responseData.transaction);
PopulateTransactionResponseItemData(model, transaction, responseData.transaction);
// Complete response.
responseData.Success = true;
@@ -322,7 +362,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
[Route("Transaction/Ajax/StoreItem")]
public IActionResult Ajax_StoreItem(Model_Transaction model)
{
String messageTitle = Localiser["caption.transaction"];
String messageTitle = Localiser["label.transaction"];
AjaxResponse_Transaction responseData = new AjaxResponse_Transaction(model);
// Validate session and referrer.
@@ -405,7 +445,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
// Construct response.
model.PopulateItemConfig(responseData.Config, transaction);
PopulateTransactionResponseItemData(transaction, responseData.transaction);
PopulateTransactionResponseItemData(model, transaction, responseData.transaction);
// Complete response.
responseData.Success = true;
@@ -16,6 +16,7 @@ using System.Linq;
using System.Threading.Tasks;
using Sarand.BusinessMgr.Web.Portal.Models.Transactions;
using Sarand.BusinessMgr.Web.Portal.Components;
using Sarand.Net.Standard.Base.Core;
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
{
@@ -34,7 +35,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
//-------------------------------------------------------------------
[HttpGet]
public IActionResult Index(Model_Transaction model)
[Route("Transactions/{transactionTypeName=}")]
public IActionResult Index(String transactionTypeName)
{
if (!ValidUserSession)
AutoLoginUser();
@@ -46,11 +48,17 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
return RedirectToAction("", "Security");
}
// Interpret transaction type, default to 'Sales Order'.
List<TypeCodeDesc> transactionTypes = GetSystemCodes(Sbm.SystemCode.TransactionType);
Sbm.TransactionType transactionType = EnumUtil.ParseEnum(transactionTypeName, Sbm.TransactionType.SalesOrder);
// Transaction page.
Model_Transaction model = new Model_Transaction(Localiser);
RefreshModel(model);
model.PopulateListConfig();
model.Filter.TransactionType = transactionTypes.GetCodeForType(transactionType);
model.Paging.PageNo = SessionData_Portal.Profile.Transaction.Filter.PageNo;
model.Paging.PageLength = SessionData_Portal.Profile.Transaction.Filter.PageLength;
model.PopulateListConfig();
return View(model);
}
@@ -228,7 +228,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
commodity = CommodityMgr.GetCommodityById(SysId.ToSysId(Commodity.Id));
disposables.Add(commodity);
if (commodity == null)
responseData.SetMessage(Localiser["caption.commodity"], Localiser["msg.something.gone.wrong"]);
responseData.SetMessage(Localiser["label.commodity"], Localiser["msg.something.gone.wrong"]);
}
if (!responseData.HasControlErrors())
@@ -285,7 +285,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
if (CommodityMgr.GetCommodityCount(prmCommodity) > 0)
{
String msg = "There are no other Commodities for this code\nwith a status of 'Current'.\n\nAre you sure that this commodity should be set to 'Superseded'?";
responseData.SetConfirmMessage(Localiser["caption.commodity"], msg);
responseData.SetConfirmMessage(Localiser["label.commodity"], msg);
}
}
}
@@ -96,6 +96,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
// List configuration.
public class ListConfigData
{
// List caption.
public String Caption { get; set; }
// Actions.
public class ActionData
{
@@ -137,11 +139,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
ViewMode pageMode = GetFilterMode();
bool modeIsRelationships = pageMode == ViewMode.Relationships;
bool modeIsMaintain = pageMode == ViewMode.Maintain;
Sbm.AssociationType associationType = GetFilterAssociationType();
bool typeIsCustomer = associationType == Sbm.AssociationType.Customer;
bool typeIsSupplier = associationType == Sbm.AssociationType.Supplier;
bool typeIsMember = associationType == Sbm.AssociationType.Member;
// Page caption.
if (associationType == Sbm.AssociationType.Customer)
config.Caption = Localiser["label.customers"];
else if (associationType == Sbm.AssociationType.Supplier)
config.Caption = Localiser["label.suppliers"];
config.Caption = StringUtil.OnBlank(config.Caption, Localiser["label.associations"]);
// Actions.
if (typeIsCustomer)
@@ -337,7 +347,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
// Item Fields.
// Type.
config.Field.Readonly.Add($"{ItemField.Type}");
// Disabled for existing associations.
// Dropdown should only include a single item if Association type is preselecedt (in the list filter).
if (ItemId.IsValid(associationItemId))
config.Field.Readonly.Add($"{ItemField.Type}");
// Owner.
if (!ItemId.IsValid(associationItemId) || ownerIsInternal)
@@ -19,8 +19,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Home
//-------------------------------------------------------------------
// Home page statictics.
// Contacts.
public long GetContactCount()
{
if (!ValidUserSession) return 0;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
return AccountMgr.GetAffiliateCount(prmAffiliate);
@@ -28,6 +31,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Home
public long GetCustomerCount()
{
if (!ValidUserSession) return 0;
SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
prmAssociation.AssociationType = Sbm.AssociationType.Customer;
prmAssociation.StatusCat = SbmAssociation.StatusCat.NotDeleted;
@@ -36,14 +40,18 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Home
public long GetSupplierCount()
{
if (!ValidUserSession) return 0;
SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
prmAssociation.AssociationType = Sbm.AssociationType.Supplier;
prmAssociation.StatusCat = SbmAssociation.StatusCat.NotDeleted;
return AccountMgr.GetAssociationCount(prmAssociation);
}
// Commodities.
public long GetCommodityCount()
{
if (!ValidUserSession) return 0;
SbmCommodity.Params prmCommodity = new SbmCommodity.Params();
prmCommodity.StatusCat = SbmCommodity.StatusCat.NotDeleted;
return CommodityMgr.GetCommodityCount(prmCommodity);
@@ -51,6 +59,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Home
public long GetAssetCount()
{
if (!ValidUserSession) return 0;
SbmAsset.Params prmAsset = new SbmAsset.Params();
prmAsset.StatusCat = SbmAsset.StatusCat.NotDeleted;
return AssetMgr.GetAssetCount(prmAsset);
@@ -58,11 +67,23 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Home
public long GetVehicleCount()
{
if (!ValidUserSession) return 0;
SbmVehicle.Params prmVehicle = new SbmVehicle.Params();
prmVehicle.StatusCat = SbmVehicle.StatusCat.NotDeleted;
return AssetMgr.GetVehicleCount(prmVehicle);
}
// Transactions.
public long GetSalesOrderCount()
{
if (!ValidUserSession) return 0;
SbmTransaction.Params prmTransaction = new SbmTransaction.Params();
prmTransaction.TransactionType = Sbm.TransactionType.SalesOrder;
prmTransaction.StatusCat = SbmTransaction.StatusCat.NotDeleted;
return TransactionMgr.GetTransactionCount(prmTransaction);
}
//-------------------------------------------------------------------
}
//=======================================================================
@@ -1,6 +1,7 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -19,18 +20,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
/// <summary>Prefix for field names.</summary>
public const String FieldNamePrefix = "Transaction";
//-------------------------------------------------------------------
// Legacy Transaction dialog tabs and panels.
// - Transaction.
// - Tab 1:
// - Tab 2:
// - Tab 3:
// - Tab 4:
// - Tab 5:
// - Tab 6:
// - Tab 7:
// - Other.
//-------------------------------------------------------------------
/// <summary>Item fields.</summary>
public enum ItemField
@@ -39,8 +28,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
// Transaction.
Pos,
Id,
AssociationTarget,
AssociationIdTarget,
AssociationName,
AssociationId,
Type,
Reference,
ReferenceExt,
@@ -68,11 +57,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
//---------------------------------------------------------------
// Status dates.
Raised,
RaisedFmt,
Required,
RequiredFmt,
InProgress,
InProgressFmt,
DeliveredEst,
DeliveredAct,
Closed,
ClosedFmt,
//---------------------------------------------------------------
Department,
DescBrief,
DescIntro,
@@ -161,6 +155,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
// List configuration.
public class ListConfigData
{
// List caption.
public String Caption { get; set; }
// Actions.
public class ActionData
{
public class AllowData
{
public bool? Create { get; set; }
public bool? Update { get; set; }
}
public AllowData Allow { get; } = new AllowData();
}
public ActionData Action { get; } = new ActionData();
// List columns.
public class ColumnData
{
@@ -190,13 +197,13 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
public void PopulateListConfig(ListConfigData config)
{
// View properties.
TransactionViewMode viewMode = GetFilterMode();
bool modeIsSearch = viewMode == TransactionViewMode.Search;
bool modeIsMaintain = viewMode == TransactionViewMode.Maintain;
bool modeIsRequirementSearch = viewMode == TransactionViewMode.SearchRequirement;
bool modeIsDeliveryPlanning = viewMode == TransactionViewMode.DeliveryPlanning;
bool modeIsTransactionsForSourceTrans = viewMode == TransactionViewMode.TransactionsForSourceTrans;
bool modeIsTransactionsForAssociation = viewMode == TransactionViewMode.TransactionsForAssociation;
ViewMode viewMode = GetFilterMode();
bool modeIsSearch = viewMode == ViewMode.Search;
bool modeIsMaintain = viewMode == ViewMode.Maintain;
bool modeIsRequirementSearch = viewMode == ViewMode.SearchRequirement;
bool modeIsDeliveryPlanning = viewMode == ViewMode.DeliveryPlanning;
bool modeIsTransactionsForSourceTrans = viewMode == ViewMode.TransactionsForSourceTrans;
bool modeIsTransactionsForAssociation = viewMode == ViewMode.TransactionsForAssociation;
// Item type.
Sbm.TransactionType transactionType = GetFilterTransactionType();
@@ -219,9 +226,23 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
SbmTransaction.StatusCat transactionStatusCat = GetFilterTransactionStatusCat();
// Options.
bool userCanCreateTransactions = SessionData_Portal.SecurityProfile.UserCanCreateItemType(Sbm.ItemType.Transaction);
bool userCanUpdateTransactions = SessionData_Portal.SecurityProfile.UserCanUpdateItemType(Sbm.ItemType.Transaction);
bool allowTimeRecording = SessionConsole.AllowOption(Sbm.ConfigOption.TimeRecording);
bool allowJobCosting = SessionConsole.GetRequirementCostingConfig().AllowRequirementCosting(transactionType) && TransactionMgr.CostColumnsAreAvailable() && UserCanViewFinancials();
//---------------------------------------------------------------
// List Caption.
config.Caption = StringUtil.OnBlank(GetListCaptionByTransactionType(transactionType),Localiser["label.transactions"]);
//---------------------------------------------------------------
// Actions.
if (userCanCreateTransactions)
config.Action.Allow.Create = true;
if (userCanUpdateTransactions)
config.Action.Allow.Update = true;
//---------------------------------------------------------------
// Transaction list columns.
@@ -254,9 +275,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
String associationLabel = Localiser["label.target"];
if (isSales) associationLabel = Localiser["label.customer"];
else if (isPurchase) associationLabel = Localiser["label.supplier"];
config.Column.Label.Add($"{ItemField.AssociationTarget}", associationLabel);
config.Column.Label.Add($"{ItemField.AssociationName}", associationLabel);
}
config.Column.Hide.Add($"{ItemField.AssociationTarget}");
else config.Column.Hide.Add($"{ItemField.AssociationName}");
// Narrative.
config.Column.Label.Add($"{ItemField.DescBrief}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DescBrief, Localiser["label.narrative"]));
@@ -313,18 +334,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
// Raised date.
if (!modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.Raised}", Localiser["label.raised"]);
//config.Column.Label.Add($"{ItemField.Raised}", Localiser["label.raised"]);
}
else
{
config.Column.Hide.Add($"{ItemField.Raised}");
config.Column.Hide.Add($"{ItemField.RaisedFmt}");
}
// In Progress date.
if (!modeIsDeliveryPlanning && !isSalesLead && !isSalesDispatch && transactionStatusCat != SbmTransaction.StatusCat.Pending)
{
config.Column.Label.Add($"{ItemField.InProgress}", Localiser["label.in.progress"]);
//config.Column.Label.Add($"{ItemField.InProgress}", Localiser["label.in.progress"]);
}
else
{
config.Column.Hide.Add($"{ItemField.InProgress}");
config.Column.Hide.Add($"{ItemField.InProgressFmt}");
}
// Required date.
if (modeIsDeliveryPlanning && !isSalesLead && !isSalesDispatch || transactionStatusCat != SbmTransaction.StatusCat.Closed)
@@ -334,15 +361,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
config.Column.Label.Add($"{ItemField.Required}", requiredLabel);
}
else
{
config.Column.Hide.Add($"{ItemField.Required}");
config.Column.Hide.Add($"{ItemField.RequiredFmt}");
}
// Closed date.
if (modeIsDeliveryPlanning || transactionStatusCat != SbmTransaction.StatusCat.Open)
{
config.Column.Label.Add($"{ItemField.Closed}", Localiser["label.closed"]);
//config.Column.Label.Add($"{ItemField.Closed}", Localiser["label.closed"]);
}
else
{
config.Column.Hide.Add($"{ItemField.Closed}");
config.Column.Hide.Add($"{ItemField.ClosedFmt}");
}
//---------------------------------------------------------------
// Amounts.
@@ -502,6 +535,31 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
config.Column.Hide.Add($"{ItemField.Actions}");
}
//-------------------------------------------------------------------
private String GetListCaptionByTransactionType(Sbm.TransactionType transactionType)
{
switch (transactionType)
{
case Sbm.TransactionType.Project: return Localiser["caption.projects"];
case Sbm.TransactionType.SalesLead: return Localiser["caption.sales.leads"];
case Sbm.TransactionType.SalesQuote: return Localiser["caption.sales.quotes"];
case Sbm.TransactionType.ProformaSalesOrder: return Localiser["caption.proforma.sales.orders"];
case Sbm.TransactionType.SalesPO: return Localiser["caption.sales.purchase.orders"];
case Sbm.TransactionType.SalesOrder: return Localiser["caption.sales.orders"];
case Sbm.TransactionType.SalesDispatch: return Localiser["caption.sales.dispatches"];
case Sbm.TransactionType.ProformaSalesInvoice: return Localiser["caption.proforma.sales.invoices"];
case Sbm.TransactionType.SalesInvoice: return Localiser["caption.sales.invoices"];
case Sbm.TransactionType.PurchaseQuote: return Localiser["caption.purchase.quotes"];
case Sbm.TransactionType.ProformaPurchaseOrder: return Localiser["caption.proforma.purchase.orders"];
case Sbm.TransactionType.PurchaseSO: return Localiser["caption.purchase.sales.orders"];
case Sbm.TransactionType.PurchaseOrder: return Localiser["caption.purchase.orders"];
case Sbm.TransactionType.PurchaseDelivery: return Localiser["caption.purchase.deliveries"];
case Sbm.TransactionType.ProformaPurchaseInvoice: return Localiser["caption.proforma.purchase.invoices"];
case Sbm.TransactionType.PurchaseInvoice: return Localiser["caption.purchase.invoices"];
}
return Localiser["label.transactions"];
}
//-------------------------------------------------------------------
// Item configuration.
//-------------------------------------------------------------------
@@ -563,8 +621,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
config.Field.Label.Add($"{ItemField.Type}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Type, Localiser["label.type"]));
config.Field.Readonly.Add($"{ItemField.Type}");
// Association.
config.Field.Readonly.Add($"{ItemField.AssociationName}");
// Reference.
config.Field.Label.Add($"{ItemField.Reference}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Ref, Localiser["label.reference"]));
config.Field.Readonly.Add($"{ItemField.Reference}");
// External Reference.
if (transactionType != Sbm.TransactionType.SalesLead)
@@ -1,4 +1,5 @@
using Sarand.BusinessMgr.Net.Core.Web.App;
using Microsoft.AspNetCore.Mvc.Rendering;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Web.Portal.Components;
@@ -7,6 +8,8 @@ using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
{
@@ -20,7 +23,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
{
//-------------------------------------------------------------------
// Definitions.
public enum TransactionViewMode
public enum ViewMode
{
Search, Maintain, SearchRequirement, DeliveryPlanning, TransactionsForSourceTrans, TransactionsForAssociation
}
@@ -42,9 +45,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
public String StatusCat { get; set; }
}
public FilterData Filter { get; } = new FilterData();
public TransactionViewMode GetFilterMode()
public ViewMode GetFilterMode()
{
return EnumUtil.ParseEnum(Filter.Mode, TransactionViewMode.Search);
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
}
public Sbm.TransactionType GetFilterTransactionType()
{
@@ -53,11 +56,25 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
transactionType = (Sbm.TransactionType)StringUtil.ToInt(Filter.TransactionType);
return transactionType;
}
public String GetFilterAssociationTypeCode()
{
List<TypeCodeDesc> associationTypes = Internals.GetSystemCodes(Sbm.SystemCode.AssociationType);
return SbmTransaction.GetAssociationTypes(GetFilterTransactionType())
.Select(item => associationTypes.GetCodeForType(item))
.Where(item => !StringUtil.IsBlank(item))
.FirstOrDefault();
}
public SbmTransaction.StatusCat GetFilterTransactionStatusCat()
{
return (SbmTransaction.StatusCat)StringUtil.ToInt(Filter.StatusCat);
}
/// <summary>Transaction Status Cats for filter dropdown.</summary>
public IEnumerable<SelectListItem> GetTransactionStatusCatsForFilterDropdown()
{
return new SelectList(SbmTransaction.GetTransactionStatusCats(GetFilterTransactionType()), "Code", "Desc");
}
//-------------------------------------------------------------------
// Transaction properties.
public class TransactionData
@@ -83,6 +100,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
public String Raised { get; set; }
public String Required { get; set; }
public String InProgress { get; set; }
// Delivery.
public String DeliveredEst { get; set; }
public String DeliveredAct { get; set; }
public String Closed { get; set; }
@@ -160,7 +178,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
// Association.
if (Transaction.AssociationId != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationTarget);
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationName);
SysId associationId = SysId.ToSysId(Transaction.AssociationId);
if (!SysId.IsValid(associationId))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
@@ -52,10 +52,26 @@
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="Views\Transaction\" />
<Content Update="Views\Transaction\Index.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Views\Transaction\Panel-TransactionDialog.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Views\Transaction\Panel-TransactionList.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Views\Transaction\Panel-TransactionMaintain.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Views\Transaction\Panel-TransactionSelect.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
@@ -62,7 +62,7 @@
<div class="col-sm-4 row pb4">
<div class="col-5 sbm-label text-right">@Localiser["label.search"]</div>
<div class="col-7">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -31,7 +31,7 @@
@* Asset filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -53,7 +53,7 @@
<div class="col-sm-4 row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -31,7 +31,7 @@
@* AssetCategory filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -55,7 +55,7 @@
@* Association filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-7 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -6,6 +6,7 @@
// Ensure view is only included once in page.
if (!Model.RegisterView("Views/Association/Panel-AssociationSelect")) return;
Model.AdditionalFiles_JS.Add("js/sbm-assoc.js");
Model_Association ModelAssociation = Model as Model_Association;
}
<script type="text/javascript">
@@ -26,14 +27,15 @@
@* Association type *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
<div class="col-8 col-sm-8">
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
@Html.Hidden("Filter.AssociationType", ModelAssociation?.Filter.AssociationType, new { @id = "", @class = "FilterAssociationType sbm-input" })
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), null, new { @id = "", @class = "FilterAssociationType sbm-select" })
</div>
</div>
<div class="col-sm-4 row pb4">
@* Association filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -49,7 +49,7 @@
<div class="col-md-6 row">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -42,7 +42,7 @@
<div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -5,7 +5,7 @@
/* Commodity - Maintain panel */
// Ensure view is only included once in page.
if (!Model.RegisterView("Views/Commodity/Panel-CommodityMaintain")) return;
Model.AdditionalFiles_JS.Add("js/sbm-commodity.js");
Model.AdditionalFiles_JS.Add("js/sbm-cmd.js");
}
<div class="sbm-panel Commodities fullheight">
@@ -24,7 +24,7 @@
<div class="sbm-panel-header">
<div class="row">
<div class="col"><partial name="~/Views/Common/ResultsPaging.cshtml" /></div>
<div class="fixed center"><div class="sbm-panel-caption">@Localiser["caption.commodities"]</div></div>
<div class="fixed center"><div class="sbm-panel-caption">@Localiser["label.commodities"]</div></div>
<div class="col right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
@@ -51,7 +51,7 @@
@* Commodity filter - code, description etc *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-7 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
<div class="col-sm-4 row pb4">
@@ -5,7 +5,7 @@
/* 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");
Model.AdditionalFiles_JS.Add("js/sbm-cmd.js");
}
<script type="text/javascript">
@@ -31,7 +31,7 @@
@* Commodity filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -54,7 +54,7 @@
@* Contact filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-7 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -31,7 +31,7 @@
@* Contact filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
@@ -136,6 +136,10 @@ else
<td class="">@Localiser["label.commodities"]</td>
<td class="center">@Model.GetCommodityCount()</td>
</tr>
<tr class="sbm-action-text" onclick="sbm.goToPage('Transactions/SalesOrder')">
<td class="">@Localiser["label.sales.orders"]</td>
<td class="center">@Model.GetSalesOrderCount()</td>
</tr>
@if (Model.GetInternals().SessionConsole.AllowOption(Sbm.ConfigOption.Assets))
{
<tr class="sbm-action-text" onclick="sbm.goToPage('Assets/Asset')">
@@ -0,0 +1,8 @@
@model Model_Transaction
@inject SbmLocaliser Localiser
@{
/* Transaction page. */
ViewData["Title"] = "Transactions";
}
<partial name="Panel-TransactionMaintain.cshtml" />
@@ -0,0 +1,265 @@
@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@
@model SbmModel_Portal
@inject SbmLocaliser Localiser
@{
/* Transaction - Dialog panel */
// Ensure view is only included once in page.
if (!Model.RegisterView("Views/Transaction/Panel-TransactionDialog")) return;
}
<script type="text/javascript">
sbm.dlg.title.createTransaction = '@Localiser.GetJavascriptText("caption.transaction.create")';
sbm.dlg.title.updateTransaction = '@Localiser.GetJavascriptText("caption.transaction.update")';
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmTransactionId", @class = "sbm-form" }))
{
@Html.Hidden("Transaction.Id", "", new { @id = "", @class = "TransactionId" })
@Html.Hidden("Transaction.DataGroups", "", new { @id = "", @class = "TransactionDataGroups" })
}
<div id="dlgTransaction" class="sbm-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmTransaction", @class = "sbm-form", @onSubmit = "return false;" }))
{
@Html.Hidden("Transaction.Id", "", new { @id = "", @class = "TransactionId sbm-input" })
@Html.Hidden("Transaction.Exists", "", new { @id = "", @class = "TransactionExists sbm-input" })
<div class="spacer2"></div>
@* Association *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationName)">
<div class="row">
<div class="col-sm-2">
<div class="sbm-label">
<label for="ifTransactionAssociationTarget"><span>@Localiser["label.association"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control row">
<div class="col">
@Html.Hidden("Transaction.AssociationId", "", new { @id = "", @class = "TransactionAssociationId sbm-input" })
<input type="text" name="Transaction.Association" id="ifTransactionAssociation" readonly="readonly" class="TransactionAssociation sbm-input sbm-auto-val" maxlength=@Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name) />
</div>
<div class="fixed">
<div class="sbm-action AssociationTargetSearch"><img src="~/img/action/search24.png" alt="" title="" /></div>
</div>
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
@* Reference *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.Reference)">
<div class="row">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionReference"><span>@Localiser["label.reference"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.Reference", "", new { @id = "ifTransactionReference", @class = "TransactionReference sbm-input upper sbm-auto-val", @readonly = true, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Ref) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
<div class="col-6">
@* External Reference *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.ReferenceExt)">
<div class="row pl-3">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionReferenceExt"><span>@Localiser["label.reference.external"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.TransactionReferenceExt", "", new { @id = "ifTransactionReferenceExt", @class = "TransactionReferenceExt sbm-input upper sbm-auto-val" })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
</div>
@* Narrative *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescBrief)">
<div class="row">
<div class="col-sm-2">
<div class="sbm-label">
<label for="ifTransactionDesc"><span>@Localiser["label.narrative"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.DescBrief", "", new { @id = "ifTransactionDesc", @class = "TransactionDesc sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescBrief) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
@* Transaction status *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.Status)">
<div class="row">
<div class="col-sm-4">
<div class="sbm-label">
<label for="cbTransactionStatus"><span>@Localiser["label.status"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
<select id="cbTransactionStatus" class="TransactionStatus sbm-select sbm-auto-val" name="Transaction.StatusCode"></select>
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
<div class="col-6">
@* Contact *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.ContactName)">
<div class="row pl-3">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionContactName"><span>@Localiser["label.contact"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.ContactName", "", new { @id = "ifTransactionContactName", @class = "TransactionContactName sbm-input sbm-auto-val", @maxlen = Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactName) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
@* Raiased date *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.Raised)">
<div class="row">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionRaised"><span>@Localiser["label.raised"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.Raised", "", new { @id = "ifTransactionRaised", @class = "TransactionRaised sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
<div class="col-6">
@* Raised by *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.RaisedBy)">
<div class="row pl-3">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionRaisedBy"><span>@Localiser["label.raised.by"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.RaisedBy", "", new { @id = "ifTransactionRaisedBy", @class = "TransactionRaisedBy sbm-input sbm-auto-val", @maxlen = Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_RaisedBy) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
@* In Progress date *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.InProgress)">
<div class="row">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionInProgress"><span>@Localiser["label.in.progress"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.InProgress", "", new { @id = "ifTransactionInProgress", @class = "TransactionInProgress sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
<div class="col-6">
@* Raised by *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.Closed)">
<div class="row pl-3">
<div class="col-sm-4">
<div class="sbm-label">
<label for="ifTransactionClosed"><span>@Localiser["label.closed"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextBox("Transaction.Closed", "", new { @id = "ifTransactionClosed", @class = "TransactionClosed sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
</div>
</div>
@* Transaction Notes *@
<div class="sbm-form-control @Model_Transaction.GetFieldName(Model_Transaction.ItemField.Notes)">
<div class="row">
<div class="col-sm-2">
<div class="sbm-label">
<label for="ifTransactionNotes"><span>@Localiser["label.notes"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextArea("Transaction.Notes", "", new { @id = "ifTransactionNotes", @class = "TransactionNotes sbm-textarea sbm-auto-val", @rows = "3", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Notes) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
}
</div>
@* Association panels. *@
<partial name="~/Views/Association/Panel-AssociationSelect.cshtml" />
<partial name="~/Views/Association/Panel-AssociationDialog.cshtml" />
@@ -0,0 +1,86 @@
@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@
@model SbmModel_Portal
@inject SbmLocaliser Localiser
@{
/* Transaction - List panel */
/* NB Can potentially appear more than once on a page. */
}
@* Item list *@
<div class="sbm-panel-item-table sbm-flex">
<table class="sbm-item-list">
<thead>
<tr>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Reference) width5pc center">@Localiser["label.reference"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Type) width5pc center">@Localiser["label.type"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationName) width15pc">@Localiser["label.association"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescBrief) width10pc d-none d-lg-table-cell">@Localiser["label.narrative"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.RaisedFmt) width5pc center nowrap">@Localiser["label.items"]</th>
@* Status dates. *@
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.RaisedFmt) width5pc center nowrap">@Localiser["label.raised"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.RequiredFmt) width5pc center nowrap">@Localiser["label.required"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.InProgressFmt) width5pc center nowrap">@Localiser["label.in.progress"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.ClosedFmt) width5pc center nowrap">@Localiser["label.closed"]</th>
@if (Model.UserCanViewFinancials())
{
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AmountNet) width5pc right">@Localiser["label.amount.net"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AmountTax) width5pc right">@Localiser["label.amount.tax"]</th>
}
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Notes) width15pc d-none d-lg-table-cell">@Localiser["label.notes"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Status) width5pc center">@Localiser["label.status"]</th>
<th class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Actions) width5pc right" style="width:2%;"></th>
</tr>
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
</thead>
<tbody></tbody>
</table>
</div>
@* Element templates *@
<div class="sbm-panel-item-template">
@* List burger dropdown template - ul is ignored *@
<ul class="sbm-dropdown-menu TransactionList">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
@* Item row template - table is ignored. *@
<table>
<tr class="sbm-row-item Transaction">
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Reference) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Type) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationName)"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescBrief) d-none d-lg-table-cell"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.ItemCount) center nowrap"></td>
@* Status dates. *@
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.RaisedFmt) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.RequiredFmt) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.InProgressFmt) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.ClosedFmt) center nowrap"></td>
@if (Model.UserCanViewFinancials())
{
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AmountNet) right nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.AmountTax) right nowrap"></td>
}
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Notes) d-none d-lg-table-cell"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Status) center nowrap"></td>
<td class="@Model_Transaction.GetFieldName(Model_Transaction.ItemField.Actions)">
<div class="right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</td>
</tr>
</table>
@* Item burger dropdown template - ul is ignored *@
<ul class="sbm-dropdown-menu Transaction">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
</div>
@@ -0,0 +1,85 @@
@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@
@model SbmModel_Portal
@inject SbmLocaliser Localiser
@{
/* Transaction - Maintain panel */
// Ensure view is only included once in page.
if (!Model.RegisterView("Views/Transaction/Panel-TransactionMaintain")) return;
Model.AdditionalFiles_JS.Add("js/sbm-trn.js");
Model_Transaction ModelTransaction = Model as Model_Transaction;
}
<div class="sbm-panel Transactions fullheight">
<script type="text/javascript">
</script>
<div class="sbm-panel-data sbm-flex">
@* Filter form - wrap header to include paging controls. *@
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmTransactionFilter sbm-form", @onSubmit = "return false;" }))
{
@Html.Hidden("Filter.Mode", Model_Transaction.ViewMode.Maintain, new { @id = "" })
@* Header - Page caption, paging controls, actions. *@
<div class="sbm-panel-header">
<div class="row">
<div class="col"><partial name="~/Views/Common/ResultsPaging.cshtml" /></div>
<div class="fixed center"><div class="sbm-panel-caption">@Localiser["label.transactions"]</div></div>
<div class="col right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</div>
</div>
@* Filter Panel *@
<div class="sbm-panel-filter">
<div class="row">
@if (ModelTransaction?.GetFilterTransactionType() > 0)
{
@Html.Hidden("Filter.TransactionType", ModelTransaction.Filter.TransactionType, new { @id = "", @class = "FilterTransactionType" })
<input type="hidden" class="FilterAssociationType" value="@ModelTransaction.GetFilterAssociationTypeCode()" />
}
else
{
<div class="col-sm-4 row pb4">
@* Transaction Category *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
<div class="col-7 col-sm-8">
@Html.DropDownList("Filter.TransactionType", Model.GetTransactionTypeCodesForFilterDropdown(), null, new { @id = "", @class = "FilterTransactionType sbm-select" })
</div>
</div>
}
<div class="col-sm-4 row pb4">
@* Transaction Status *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.status"]</div>
<div class="col-7 col-sm-8">
@Html.DropDownList("Filter.TransactionStatusCat", ModelTransaction?.GetTransactionStatusCatsForFilterDropdown() ?? Model.GetEmptyListForSelect(), null, new { @id = "", @class = "FilterTransactionStatusCat sbm-select" })
</div>
</div>
<div class="col-sm-4 row pb4">
@* Transaction filter - code, description etc *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-7 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
<div class="col-sm-4 row pb4">
</div>
</div>
</div>
}
<partial name="Panel-TransactionList.cshtml" />
</div>
<partial name="Panel-TransactionDialog.cshtml" />
</div>
@@ -0,0 +1,43 @@
@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@
@model SbmModel_Portal
@inject SbmLocaliser Localiser
@{
/* Transaction - Select panel */
// Ensure view is only included once in page.
if (!Model.RegisterView("Views/Transaction/Panel-TransactionSelect")) return;
Model.AdditionalFiles_JS.Add("js/sbm-trn.js");
}
<script type="text/javascript">
</script>
<div id="dlgTransactionSelect" class="sbm-dialog sbm-flex sbm-no-padding" title="@Localiser["caption.contact.select"]">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmTransactionFilter sbm-form", @onSubmit = "return false;" }))
{
@Html.Hidden("Filter.Mode", Model_Transaction.ViewMode.Search, new { @id = "" })
@* Filter Panel *@
<div class="sbm-panel-filter">
<div class="row">
<div class="col-sm-4 row pb4">
@* Transaction type *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
<div class="col-8 col-sm-8">
@Html.DropDownList("Filter.TransactionType", Model.GetTransactionTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterTransactionType sbm-select" })
</div>
</div>
<div class="col-sm-4 row pb4">
@* Transaction filter - name etc. *@
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-8 col-sm-8">
@Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
</div>
</div>
</div>
</div>
}
<partial name="Panel-TransactionList.cshtml" />
</div>
@@ -43,7 +43,7 @@
<div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -42,7 +42,7 @@
<div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
@Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
@@ -6,6 +6,7 @@
@using Sarand.BusinessMgr.Web.Portal.Models.Security
@using Sarand.BusinessMgr.Web.Portal.Models.Contacts
@using Sarand.BusinessMgr.Web.Portal.Models.Commodities
@using Sarand.BusinessMgr.Web.Portal.Models.Transactions
@using Sarand.BusinessMgr.Web.Portal.Models.Assets
@using Sarand.BusinessMgr.Web.Portal.Models.Vehicles
@using Sarand.BusinessMgr.Web.Portal.Models.Codes
@@ -33,12 +33,12 @@
.Contacts .sbm-panel-data
{
--color-panel-data: var(--color-ForestGreen);
--color-panel-data: var(--color-KellyGreen);
}
.Associations .sbm-panel-data
{
--color-panel-data: var(--color-Iris);
--color-panel-data: var(--color-ForestGreen);
}
.Commodities .sbm-panel-data
@@ -56,6 +56,11 @@
--color-panel-data: var(--color-Iris);
}
.Transactions .sbm-panel-data
{
--color-panel-data: var(--color-RoyalBlue);
}
/* Dialogs */
:root
@@ -70,12 +75,12 @@
.ui-dialog.sbm-Contact
{
--color-dialog: var(--color-ForestGreen);
--color-dialog: var(--color-KellyGreen);
}
.ui-dialog.sbm-Association
{
--color-dialog: var(--color-Iris);
--color-dialog: var(--color-ForestGreen);
}
.ui-dialog.sbm-Commodity
@@ -93,4 +98,9 @@
--color-dialog: var(--color-Iris);
}
.ui-dialog.sbm-Transaction
{
--color-dialog: var(--color-RoyalBlue);
}
/* The End */
@@ -72,6 +72,8 @@
}
.sbm-panel-filter input[type="text"],
.sbm-panel-filter input[type="email"],
.sbm-panel-filter input[type="search"],
.sbm-panel-filter textarea,
.sbm-panel-filter select
{
@@ -100,6 +102,8 @@
}
.sbm-panel-data .sbm-content input[type="text"],
.sbm-panel-data .sbm-content input[type="email"],
.sbm-panel-data .sbm-content input[type="search"],
.sbm-panel-data .sbm-content select
{
min-width: 75%;
@@ -412,13 +412,13 @@ a:focus
{
border-color: var(--color-dialog);
margin-top: 0;
padding: .2em 1em .2em .5em;
padding: .25em .5em .25em .5em;
}
.ui-dialog .ui-dialog-buttonpane button
{
min-width: 80px;
margin: .5em .25em .5em .5em;
margin: .2em .25em .2em 1em;
color: #fff;
background-color: var(--color-dialog);
border-color: var(--color-dialog);
@@ -211,8 +211,9 @@
$item = ac.getItemTemplate(env);
$('table tbody', env.$pnl.table).prepend($item).show();
}
ac.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
ac.populateItem(env, $item, item);
}
//--------------------------------------------------------------
@@ -231,8 +231,9 @@
$item = as.getItemTemplate(env);
$('table tbody', env.$pnl.table).prepend($item).show();
}
as.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
as.populateItem(env, $item, item);
}
//--------------------------------------------------------------
@@ -10,21 +10,11 @@
//--------------------------------------------------------------
as.refreshConfig = function (env, delay)
{
env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Association/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshConfig(env, response); } };
sbm.doAjaxRequest(env.ajax.refreshConfig, delay || 50);
sbm.doAjaxRequest(env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Association/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { as.storeConfig(env, response); } }, delay || 50);
}
as.doRefreshConfig = function (env, response)
as.storeConfig = function (env, response)
{
//sbm.debug('doRefreshConfig', env, response);
if (!response.success) return;
// Config.
env.mode = response.mode;
env.config = response.config;
env.configCust = response.configCust;
env.configSupp = response.configSupp;
env.data.associationTypes = response.associationTypes;
env.data.statuses = response.statuses;
env.data.defaultStatusCode = response.defaultStatusCode;
Object.assign(env.data, response.data);
}
//--------------------------------------------------------------
@@ -36,8 +26,7 @@
env.$pnl.table.find('tbody tr').remove();
env.$pnl.msgs.hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
}
env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Association/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshResults(env, response); } };
sbm.doAjaxRequest(env.ajax.refreshResults, delay || 50);
sbm.doAjaxRequest(env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Association/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshResults(env, response); } }, delay || 50);
as.awaitingRefreshResponse = true;
}
as.doRefreshResults = function (env, response)
@@ -48,8 +37,10 @@
let $table = $('table', env.$pnl.table).find('tbody tr').remove().end();
sbm.refreshPaging(response, env.$frm.filter, function () { as.refreshResults(env); });
if (!response.success) return;
as.doRefreshConfig(env, response);
if (response.caption) env.$pnl.items.find('.sbm-panel-caption').text(response.caption);
as.storeConfig(env, response);
let cfg = env.data.cfgList;
env.mode = response.mode;
if (cfg.caption) env.$pnl.items.find('.sbm-panel-caption').text(cfg.caption);
// Menu.
if (env.$pnl.bgr.length)
@@ -57,10 +48,10 @@
env.$pnl.bgr.invisible();
env.$pnl.mnu.empty();
env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.refresh, function () { as.refreshResults(env); }, 'sbm-refresh'));
if (env.config.action.allow.createCust)
env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createCust, function () { as.createItem(env, env.configCust, sbm.lbl.createCust); }, 'sbm-add'));
if (env.config.action.allow.createSupp)
env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createSupp, function () { as.createItem(env, env.configSupp, sbm.lbl.createSupp); }, 'sbm-add'));
if (env.data.cfgList.action.allow.createCust)
env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createCust, function () { as.createItem(env, env.data.cfgCust, sbm.lbl.createCust); }, 'sbm-add'));
if (env.data.cfgList.action.allow.createSupp)
env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createSupp, function () { as.createItem(env, env.data.cfgSupp, sbm.lbl.createSupp); }, 'sbm-add'));
env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length);
}
@@ -68,15 +59,15 @@
var items = response.associations || [];
if (!items.length)
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
$table.append(as.populateItem(env, as.getItemTemplate(env), items[itemIdx]));
sbm.configureItemTable(env.config, $table);
for (const item of items)
$table.append(as.populateItem(env, as.getItemTemplate(env), item));
sbm.configureItemTable(env.data.cfgList, $table);
}
as.populateItem = function (env, $item, item)
{
if (!item) return $item;
$item.prop('id', as.getItemId(item));
let cfg = env.config;
let cfg = env.data.cfgList;
sbm.populateItemValues(cfg, $item, item.field.value);
let prefix = cfg.column.prefix;
if (!env.mode.search)
@@ -140,7 +131,7 @@
as.clearItem(env, cfg);
let prefix = cfg.field.prefix;
let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', env.$frm.item);
if (cfg.type) sbm.selectOrAdd($ctrls.filter('.AssociationType'), cfg.type.code, cfg.type.desc)
if (cfg.type) sbm.populateSelectCodeDesc('#cbAssociationType', [{ code: cfg.type.code, desc: cfg.type.desc }])
env.$ctrl.targetActions.filter('.AssocTargetSearch').show();
$ctrls.filter('.AssociationTarget').off('dblclick').on('dblclick', function () { as.selectTarget(env); });
$ctrls.filter('.AssociationStatus').val(env.data.defaultStatusCode);
@@ -178,7 +169,7 @@
//sbm.debug('onSelectTarget', env, item);
let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', env.$frm.item);
$ctrls.filter('.AssociationTargetId').val(item.id);
$ctrls.filter('.AssociationTarget').val(item.Name);
$ctrls.filter('.AssociationTarget').val(item.name);
}
as.editTarget = function (env)
{
@@ -200,8 +191,7 @@
{
let $frm = env.$frm.itemId;
$('.AssociationId', $frm).val(id);
env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Association/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { as.onUpdateItem(env, response); } };
sbm.doAjaxRequest(env.ajax.updateItem, 50);
sbm.doAjaxRequest(env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Association/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { as.onUpdateItem(env, response); } }, 50);
}
as.onUpdateItem = function (env, response)
{
@@ -228,8 +218,7 @@
//--------------------------------------------------------------
as.storeItem = function (env)
{
env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Association/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { as.onStoreItem(env, response); } };
sbm.doAjaxRequest(env.ajax.storeItem, 50);
sbm.doAjaxRequest(env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Association/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { as.onStoreItem(env, response); } }, 50);
}
as.onStoreItem = function (env, response)
{
@@ -252,6 +241,7 @@
$('table tbody', env.$pnl.table).prepend($item).show();
}
as.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
}
@@ -280,11 +270,12 @@
sbm.fn.selectAssociation = function (prm)
{
let env = as.env.select;
//sbm.debug('listAssociations', env, prm);
//sbm.debug('selectAssociation', env, prm);
env.prmSelect = prm;
let $frm = env.$frm.filter;
$frm.find('.FilterOwnerId,.FilterTargetId').val('');
$frm.find('.FilterContactType').val(prm.type || '');
env.$frm.filter.find('.sbm-input.FilterAssociationType').val(prm.type);
env.$ctrl.filterAssocType.val(prm.type || '').prop('disabled', env.$ctrl.filterAssocType.val());
$frm.find('.FilterSearch').val(prm.search || '');
env.$pnl.table.find('tbody tr').remove();
let $dlg = env.$dlg.select;
@@ -300,7 +291,7 @@
//sbm.debug('selectItemRow', env, $item, item);
env.$pnl.table.find('tr').removeClass('sbm-sel');
$item.addClass('sbm-sel');
env.prmSelect.item = item;
env.prmSelect.item = { id: item.id, name: item.field.value.Target };
}
as.selectItem = function (env)
{
@@ -324,7 +315,8 @@
env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template');
env.$frm.filter = env.$pnl.items.find('.frmAssociationFilter');
env.$frm.filter.on('input', '.FilterSearch', function () { as.refreshResults(env, 250); }).on('change', '.FilterAssociationType', function () { as.refreshResults(env, 50); });
env.$frm.filter.on('input', '.FilterSearch', function () { as.refreshResults(env, 250); });
env.$ctrl.filterAssocType = env.$frm.filter.find('.sbm-select.FilterAssociationType').on('change', function () { env.$frm.filter.find('.sbm-input.FilterAssociationType').val(env.$frm.filter.find('.sbm-select.FilterAssociationType').val()); as.refreshResults(env, 50); });
var opt = sbm.dlgOpts();
opt.dialogClass += " sbm-Association";
env.$dlg.item = $('#dlgAssociation').dialog(opt);
@@ -17,9 +17,6 @@
{
//sbm.debug('doRefreshConfig', env, response);
if (!response.success) return;
// Config.
env.config = response.config;
env.configItemNew = response.configItemNew;
Object.assign(env.data, response.data);
}
@@ -53,7 +50,7 @@
env.$pnl.bgr.invisible();
env.$pnl.mnu.empty();
env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.refresh, function () { co.refreshResults(env); }, 'sbm-refresh'));
if (env.config.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configItemNew); }, 'sbm-add'));
if (env.data.cfgList.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.data.cfgItemNew); }, 'sbm-add'));
env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length);
}
@@ -63,12 +60,13 @@
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (const item of items)
$table.append(co.populateItem(env, co.getItemTemplate(env), item));
sbm.configureItemTable(env.data.cfgList, $table);
}
co.populateItem = function (env, $item, item)
{
if (!item) return $item;
$item.prop('id', co.getItemId(item));
let cfg = env.config;
let cfg = env.data.cfgList;
if (cfg) sbm.populateItemValues(cfg, $item, item.field.value);
let prefix = cfg.column.prefix;
$('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
@@ -253,6 +251,7 @@
$('table tbody', env.$pnl.table).prepend($item).show();
}
co.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
}
@@ -340,7 +339,7 @@
co.env.maint = co.initEnv('.sbm-panel.Commodities');
if (co.env.maint.$pnl.items.length)
{
$('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.config.action.allow.create) co.createItem(env, env.configItemNew); });
$('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.data.cfgList.action.allow.create) co.createItem(env, env.data.cfgItemNew); });
setTimeout(function () { co.refreshResults(co.env.maint); }, 250);
}
co.env.select = co.initEnv('#dlgCommoditySelect');
@@ -69,8 +69,8 @@
var items = response.contacts || [];
if (!items.length)
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
$table.append(co.populateItem(env, co.getItemTemplate(env), items[itemIdx]));
for (const item of items)
$table.append(co.populateItem(env, co.getItemTemplate(env), item));
sbm.configureItemTable(env.config, $table);
}
co.populateItem = function (env, $item, item)
@@ -223,6 +223,7 @@
$('table tbody', env.$pnl.table).prepend($item).show();
}
co.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
}
@@ -252,7 +253,7 @@
//sbm.debug('selectItemRow', env, $item, item);
env.$pnl.table.find('tr').removeClass('sbm-sel');
$item.addClass('sbm-sel');
env.prmSelect.item = item;
env.prmSelect.item = { id: item.id, name: item.name };
}
co.selectItem = function (env)
{
@@ -170,8 +170,8 @@
sbm.clearItemForm = function ($frm)
{
sbm.clearControlErrors($frm);
$('.sbm-input,.sbm-textarea,.sbm-select', $frm).val('').prop('readonly', false).prop('disabled', false);
$('.sbm-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked');
$frm.find('.sbm-input,.sbm-textarea,.sbm-select').val('').prop('readonly', false).prop('disabled', false);
$frm.find('.sbm-checkbox').prop('readonly', false).prop('disabled', false).removeAttr('checked');
}
sbm.configureItemControls = function (cfg, $frm)
{
@@ -179,8 +179,8 @@
let fld = cfg.field || {};
let $ctrl = $('.sbm-form-control', $frm).show();
for (var name in fld.label || {}) { /* ... */ };
(fld.hide || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).hide().find('.sbm-input,.sbm-textarea,.sbm-select,.sbm-checkbox').prop('disabled', true); });
(fld.readonly || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).find('.sbm-input,.sbm.textarea,.sbm-select,.sbm-checkbox').prop('readonly', true).prop('disabled', true); });
(fld.hide || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).hide().find('.sbm-input,.sbm-textarea,.sbm-select,.sbm-checkbox').filter('.sbm-auto-val').prop('disabled', true); });
(fld.readonly || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).find('.sbm-input,.sbm.textarea,.sbm-select,.sbm-checkbox').filter('.sbm-auto-val').prop('readonly', true).prop('disabled', true); });
}
sbm.populateFormValues = function (cfg, $frm, val)
{
@@ -0,0 +1,321 @@
/*
* Transaction page scripts.
*/
(function (win, doc, undef)
{
"use strict";
let co = sbm.mdl.Transactions = { env: {} };
//--------------------------------------------------------------
co.refreshConfig = function (env, delay)
{
sbm.doAjaxRequest(env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Transaction/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { co.storeConfig(env, response); } }, delay || 50);
}
co.storeConfig = function (env, response)
{
Object.assign(env.data, response.data);
}
//--------------------------------------------------------------
co.refreshItems = function (env, delay)
{
if (!co.awaitingRefreshResponse)
{
env.$pnl.bgr.invisible();
env.$pnl.table.find('tbody tr').remove();
env.$pnl.msgs.hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
}
sbm.doAjaxRequest(env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Transaction/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { co.displayItems(env, response); } }, delay || 50);
co.awaitingRefreshResponse = true;
}
co.displayItems = function (env, response)
{
//sbm.debug('doRefreshResults', env, response);
delete co.awaitingRefreshResponse;
env.$pnl.msgs.hide().empty();
let $table = $('table', env.$pnl.table).find('tbody tr').remove().end();
sbm.refreshPaging(response, env.$frm.filter, function () { co.refreshItems(env); });
if (!response.success) return;
co.storeConfig(env, response);
let cfg = env.data.cfgList;
env.mode = response.mode;
if (cfg.caption) env.$pnl.items.find('.sbm-panel-caption').text(cfg.caption);
// Menu.
if (env.$pnl.bgr.length)
{
env.$pnl.bgr.invisible();
env.$pnl.mnu.empty();
env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.refresh, function () { co.refreshItems(env); }, 'sbm-refresh'));
if (cfg.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.data.cfgItemNew); }, 'sbm-add'));
env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length);
}
// Items.
var items = response.transactions || [];
if (!items.length)
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
for (const item of items)
$table.append(co.populateItem(env, co.getItemTemplate(env), item));
sbm.configureItemTable(cfg, $table);
}
co.populateItem = function (env, $item, item)
{
if (!item) return $item;
$item.prop('id', co.getItemId(item));
let cfg = env.data.cfgList;
if (cfg) sbm.populateItemValues(cfg, $item, item.field.value);
let prefix = cfg.column.prefix;
$('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
if (!env.mode.search)
{
// Actions.
var $bgr = $('.sbm-burger', $item).hide();
let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
if (!item.deleted)
{
let fnUpd = function () { co.updateItem(env, item.id) };
$mnu.append(co.getItemMenuOption(env, sbm.lbl.edit, fnUpd, 'sbm-edit'));
$('.TransactionCode,.TransactionDesc', $item).off('click').on('click', fnUpd).addClass('sbm-action-text');
$item.off('dblclick').on('dblclick', fnUpd);
}
$bgr.toggle(!!$('.sbm-dropdown-item', $mnu).length);
}
else
{
$item.off('click').on('click', function () { co.selectItemRow(env, $item, item); });
$item.off('dblclick').on('dblclick', function () { co.selectItem(env); });
}
return $item;
}
co.getItemId = function (item)
{
return 'Cmd_' + (item || {}).id;
}
//--------------------------------------------------------------
co.getFilterDropdownTemplate = function (env)
{
return $('.sbm-dropdown-menu.TransactionList li.sbm-dropdown-item', env.$pnl.tmpl).clone();
}
co.getItemTemplate = function (env)
{
return $('table tr.sbm-row-item.Transaction', env.$pnl.tmpl).clone();
}
co.getItemDropdownTemplate = function (env)
{
return $('.sbm-dropdown-menu.Transaction li.sbm-dropdown-item', env.$pnl.tmpl).clone();
}
//--------------------------------------------------------------
co.getFilterMenuOption = function (env, lbl, fn, cls)
{
return co.getMenuOption(co.getFilterDropdownTemplate(env), lbl, fn, cls);
}
co.getItemMenuOption = function (env, lbl, fn, cls)
{
return co.getMenuOption(co.getItemDropdownTemplate(env), lbl, fn, cls);
}
co.getMenuOption = function ($opt, lbl, fn, cls)
{
return $opt.find('div.sbm-label').text(lbl).end().on('click', fn).addClass(cls);
}
//--------------------------------------------------------------
co.createItem = function (env, cfg)
{
co.clearItem(env, cfg);
let $frm = env.$frm.item;
$frm.find('.TransactionType').val(env.data.transactionTypeDefault);
env.$ctrl.searchTgtAssoc.show();
$frm.find('.TransactionStatus').val(env.data.defaultStatusCode);
co.openItemDlg(env, cfg, sbm.dlg.title.createTransaction);
}
co.clearItem = function (env, cfg)
{
sbm.clearItemForm(env.$frm.item);
sbm.populateSelectCodeDesc('#cbTransactionStatus', env.data.statuses);
}
co.openItemDlg = function (env, cfg, title)
{
let $dlg = env.$dlg.item;
let $frm = env.$frm.item;
sbm.configureItemControls(cfg, $frm);
var btns = {};
btns[sbm.lbl.ok] = function () { co.storeItem(env); };
btns[sbm.lbl.cancel] = function () { delete env.prmEdit; $(this).dialog('close'); };
$dlg.dialog('option', 'buttons', btns);
if (title) $dlg.dialog('option', 'title', title);
sbm.openDialog($dlg, 720, 640);
}
//--------------------------------------------------------------
co.updateItem = function (env, id)
{
let $frm = env.$frm.itemId;
$('.TransactionId', $frm).val(id);
$('.TransactionDataGroups', $frm).val('Sales');
env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Transaction/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { co.onUpdateItem(env, response); } };
sbm.doAjaxRequest(env.ajax.updateItem, 50);
}
co.onUpdateItem = function (env, response)
{
sbm.debug('onUpdateItem', env, response);
if (!response.success) return;
let cfg = response.config || {};
co.clearItem(env, cfg);
let item = response.transaction;
let $frm = env.$frm.item;
sbm.populateFormValues(cfg, $frm, item.field.value);
let $ctrls = $frm.find('.sbm-input,.sbm-textarea,.sbm-select');
$ctrls.filter('.TransactionId').val(item.id);
$ctrls.filter('.TransactionExists').val(1);
sbm.debug(item.field.value.AssociationId);
$ctrls.filter('.TransactionAssociationId').val(item.field.value.AssociationId);
env.$ctrl.searchTgtAssoc.hide();
sbm.selectOrAdd($ctrls.filter('.TransactionType'), item.typeCode, item.typeDesc);
sbm.selectOrAdd($ctrls.filter('.TransactionStatus'), item.statusCode, item.field.value.Status);
co.openItemDlg(env, cfg, sbm.dlg.title.updateTransaction);
}
//--------------------------------------------------------------
co.selectAssocTarget = function (env)
{
if (!!env.$frm.item.find('.sbm-input.TransactionId').val()) return;
sbm.fn.selectAssociation({ type: env.$frm.filter.find('.FilterAssociationType').val(), fnSuccess: function (item) { co.onSelectAssocTarget(env, item); } });
}
co.onSelectAssocTarget = function (env, item)
{
sbm.debug('onSelectAssocTarget', env, item);
env.$frm.item.find('.TransactionAssociationId').val(item.id);
env.$frm.item.find('.TransactionAssociation').val(item.name);
}
//--------------------------------------------------------------
co.storeItem = function (env)
{
env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Transaction/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); } };
sbm.doAjaxRequest(env.ajax.storeItem, 50);
}
co.onStoreItem = function (env, response)
{
//sbm.debug('onStoreItem', env, response);
sbm.refreshControlValues(response.controlValues);
if (!response.success) return;
env.$dlg.item.dialog('close');
var item = response.transaction;
if (env.prmEdit)
{
co.onItemEdited(env, item);
}
else if (env.$pnl.table.length)
{
env.$pnl.msgs.hide().empty();
var $item = $('#' + co.getItemId(item), env.$pnl.table);
if (!$item.length)
{
$item = co.getItemTemplate(env);
$('table tbody', env.$pnl.table).prepend($item).show();
}
co.populateItem(env, $item, item);
sbm.configureItemTable(env.data.cfgList, env.$pnl.table);
}
}
//--------------------------------------------------------------
/* Params: type, search, fnSuccess. */
sbm.fn.selectTransaction = function (prm)
{
//sbm.debug('selectTransaction', prm);
let env = co.env.select;
env.prmSelect = prm;
env.$frm.filter.find('.FilterTransactionType').val('');
env.$frm.filter.find('.FilterSearch').val(prm.search || '');
env.$pnl.table.find('tbody tr').remove();
sbm.openDialog(env.$dlg.select, 1000, 800);
if (env.$pnl.items.length) setTimeout(function () { co.refreshItems(env); }, 250);
}
co.selectItemRow = function (env, $item, item)
{
//sbm.debug('selectItemRow', env, $item, item);
env.$pnl.table.find('tr').removeClass('sbm-sel');
$item.addClass('sbm-sel');
env.prmSelect.item = item;
}
co.selectItem = function (env)
{
//sbm.debug('selectItem', env, env.prmSelect.item);
env.$dlg.select.dialog('close');
env.prmSelect.fnSuccess(env.prmSelect.item);
delete env.prmSelect;
}
/* Params: id, fnSuccess. */
sbm.fn.editTransaction = function (prm)
{
//sbm.debug('editTransaction', prm);
let env = co.env.select;
env.prmEdit = prm;
//sbm.debug(env, prm);
co.updateItem(env, prm.id);
}
co.onItemEdited = function (env, item)
{
//sbm.debug('co.onItemEdited', env, item);
env.prmEdit.fnSuccess(item);
delete env.prmEdit;
}
//--------------------------------------------------------------
co.initEnv = function ($pnlItems)
{
let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} };
let $items = env.$pnl.items = $($pnlItems);
env.$pnl.header = $items.find('.sbm-panel-header');
env.$pnl.bgr = env.$pnl.header.find('.sbm-burger');
env.$pnl.mnu = env.$pnl.bgr.find('ul.sbm-dropdown-menu');
env.$pnl.table = $items.find('.sbm-panel-item-table');
env.$pnl.msgs = env.$pnl.table.find('.sbm-panel-messages');
env.$pnl.tmpl = $items.find('.sbm-panel-item-template');
env.$frm.filter = $items.find('.frmTransactionFilter');
if (env.$frm.filter.length)
env.$frm.filter.on('input', '.FilterSearch', function () { co.refreshItems(env, 250); }).on('change', '.FilterTransactionType,.FilterTransactionStatusCat', function () { co.refreshItems(env, 50); });
env.$frm.itemId = $items.find('#frmTransactionId');
var opt = sbm.dlgOpts();
opt.dialogClass += " sbm-Transaction";
env.$dlg.item = $items.find('#dlgTransaction').dialog(opt);
env.$frm.item = env.$dlg.item.find('#frmTransaction').on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); });
sbm.initCalendars(env.$dlg.item.find('.sbm-input.sbm-calendar'), {});
env.$frm.item.on('blur', '.sbm-input.sbm-format-integer', function () { sbm.formatInteger($(this)); }).on('blur', '.sbm-input.sbm-format-currency', function () { sbm.formatCurrency($(this)); });
env.$frm.item.find('.TransactionAssociation').on('dblclick', function () { co.selectAssocTarget(env); });
env.$ctrl.searchTgtAssoc = env.$frm.item.find('.AssociationTargetSearch').on('click', function () { co.selectAssocTarget(env); });
var opt = sbm.dlgOpts();
opt.dialogClass += " sbm-Transaction";
opt.buttons[sbm.lbl.ok] = function () { co.selectItem(env); };
opt.buttons[sbm.lbl.cancel] = function () { delete env.prmSelect; $(this).dialog('close'); };
env.$dlg.select = $('#dlgTransactionSelect').dialog(opt);
return env;
}
//--------------------------------------------------------------
$(function ()
{
co.env.maint = co.initEnv('.sbm-panel.Transactions');
if (co.env.maint.$pnl.items.length)
{
$('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.data.cfgList.action.allow.create) co.createItem(env, env.data.cfgItemNew); });
setTimeout(function () { co.refreshItems(co.env.maint); }, 250);
}
co.env.select = co.initEnv('#dlgTransactionSelect');
if (co.env.select.$pnl.items.length) setTimeout(function () { co.refreshConfig(co.env.select); }, 250);
});
//--------------------------------------------------------------
}(window, window.document));
/* The End */