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
@@ -1,22 +1,14 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Dbas.Bus;
using Sarand.BusinessMgr.Net.Standard.Dbas.Internal;
using Sarand.BusinessMgr.Net.Standard.Dbas.UpdateLog;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.CodeTypes;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Interfaces;
using Sarand.Net.Standard.Base.ItemDocs;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Data;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
{
@@ -67,7 +59,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
HashSet<SysId> affiliateIdsOwner = new HashSet<SysId>();
String colAffIdOwner = SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Association_AffIdOwner);
SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
prmAssociation.AssociationType = AssociationType.Internal;
prmAssociation.AssociationType = Sbm.AssociationType.Internal;
prmAssociation.StatusCat = SbmAssociation.StatusCat.Active;
// Construct the query.
DbQuery qry = new DbQuery(Database.DbmsType);
@@ -8,15 +8,12 @@ using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.CodeTypes;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Interfaces;
using Sarand.Net.Standard.Base.ItemDocs;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Data;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
{
@@ -1,4 +1,5 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Org.BouncyCastle.Bcpg;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Dbas.Bus;
using Sarand.BusinessMgr.Net.Standard.Dbas.Internal;
@@ -254,7 +255,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
}
//-------------------------------------------------------------------
public override bool CalculateTotal(SbmRequirement.Data requirement)
public override bool CalculateTotal(SbmRequirement requirement)
{
ClearErrorState();
if (requirement == null) return SetErrorState(Msg_ItemNotSpecified);
@@ -546,11 +547,25 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
public override SbmRequirement CreateRequirement(SysId assocId, SysId transId, Sbm.RequirementType requirementType)
{
ClearErrorState();
SbmRequirement requirement = null;
if (SysId.IsValid(assocId) && SysId.IsValid(transId) && requirementType > 0)
requirement = new SbmRequirement_Dbas(new SysId(), AffiliateId_Owner, assocId, transId, requirementType, 0);
else SetErrorState("Asset type not identified");
return requirement;
if (!SysId.IsValid(assocId))
{
SetErrorState("Association not identified");
SaLogger.Warn($"{SysUtil.Fn} Failed to create Requirement - {ErrorStateMessage}.");
return null;
}
if (!SysId.IsValid(transId))
{
SetErrorState("Transaction not identified");
SaLogger.Warn($"{SysUtil.Fn} Failed to create Requirement - {ErrorStateMessage}.");
return null;
}
if (requirementType <= 0)
{
SetErrorState("Requirement type not identified");
SaLogger.Warn($"{SysUtil.Fn} Failed to create Requirement - {ErrorStateMessage}.");
return null;
}
return new SbmRequirement_Dbas(new SysId(), AffiliateId_Owner, assocId, transId, requirementType, 0);
}
private SbmRequirement_Dbas CreateRequirement(Requirement_Db dbRequirement)
{
@@ -679,13 +694,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
dbRequirement._TransId = requirement.TransactionId.ToInt();
dbRequirement._Type = (short)requirement.RequirementType;
dbRequirement._Seq = requirement.Seq;
dbRequirement._ReqntIdSource = requirement.RequirementIdSource.ToInt();
dbRequirement._ReqntIdSource = SysId.ToInt(requirement.RequirementIdSource);
dbRequirement._Required = requirement.Required;
dbRequirement._Started = requirement.Started;
dbRequirement._Completed = requirement.Completed;
dbRequirement._JobNumber = requirement.JobNumber;
dbRequirement._AssIdSubcontract = requirement.AssociationIdSubContract.ToInt();
dbRequirement._CommodityId = requirement.CommodityId.ToInt();
dbRequirement._AssIdSubcontract = SysId.ToInt(requirement.AssociationIdSubContract);
dbRequirement._CommodityId = SysId.ToInt(requirement.CommodityId);
dbRequirement._ProductCode = requirement.ProductCode;
dbRequirement._AssetId = requirement.AssetId.ToInt();
dbRequirement._DescBrief = requirement.DescBrief;
@@ -709,7 +724,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
dbRequirement._TimeEst = requirement.TimeEst;
dbRequirement._TimeAct = requirement.TimeAct;
dbRequirement._TimeTot = requirement.TimeTot;
dbRequirement._LocationIdStock = requirement.LocationIdStock.ToInt();
dbRequirement._LocationIdStock = SysId.ToInt(requirement.LocationIdStock);
dbRequirement._CostLabourHours = requirement.CostLabourHours;
dbRequirement._CostLabourRateHour = requirement.CostLabourRateHour;
dbRequirement._CostLabour = requirement.CostLabour;
@@ -7,6 +7,7 @@ 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.ReferenceData;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Base;
using Sarand.Net.Standard.Dbas.Data;
@@ -68,6 +69,41 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
return detailsAreReadOnly;
}
//-------------------------------------------------------------------
public override bool RefreshTransactionTotals(SbmTransaction transaction, IEnumerable<SbmRequirement> requirements)
{
ClearErrorState();
if (transaction == null) return SetErrorState(Msg_ItemNotSpecified);
if (requirements == null) requirements = new List<SbmRequirement>();
// Total weight.
decimal totalWeight = requirements.GetTotalWeight(Internals.GetDefaultUnitOfMeasureByCategory(SaUomCategory.Weight)?.Id);
transaction.Weight = totalWeight;
// Set the allocation status:
transaction.ClearAllocationStatus();
if (requirements.IsFullAllocation()) transaction.FullAllocation = true;
else if (requirements.IsPartialAllocation()) transaction.PartialAllocation = true;
// Calculate the totals from the list of requirements:
decimal totalAmountNet = 0.0m, totalAmountTax = 0.0m, totalAmountTot = 0.0m, totalTimeEst = 0.0m, totalTimeAct = 0.0m;
requirements.CalculateTotals(ref totalAmountNet, ref totalAmountTax, ref totalAmountTot, ref totalTimeEst, ref totalTimeAct);
// Include delivery amounts:
totalAmountNet += transaction.DeliveryAmountNet;
totalAmountTax += transaction.DeliveryAmountTax;
totalAmountTot += transaction.DeliveryAmountTot;
// Store amounts:
transaction.AmountNet = totalAmountNet;
transaction.AmountTax = totalAmountTax;
transaction.AmountTot = totalAmountTot;
transaction.TimeEst = totalTimeEst;
transaction.TimeAct = totalTimeAct;
return OK;
}
//-------------------------------------------------------------------
// Labour Cost.
public override decimal GetTransCostLabourRateHourDefault()
@@ -1,5 +1,6 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Net.Standard.Dbas.Bus;
using Sarand.BusinessMgr.Net.Standard.Dbas.Internal;
using Sarand.BusinessMgr.Net.Standard.Dbas.UpdateLog;
@@ -551,11 +552,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
if (!SysId.IsValid(assocId))
{
SetErrorState("Association not supplied");
SaLogger.Warn($"{SysUtil.Fn} Failed to create Requirement - {ErrorStateMessage}.");
return null;
}
if ((int)transactionType < 1)
if (transactionType <= 0)
{
SetErrorState("Transaction type not identified");
SetErrorState("Transaction type not supplied");
SaLogger.Warn($"{SysUtil.Fn} Failed to create Requirement - {ErrorStateMessage}.");
return null;
}
return new SbmTransaction_Dbas(new SysId(), AffiliateId_Owner, assocId, transactionType, 0);
@@ -584,6 +587,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
ClearErrorState();
if (!IsValidTransaction(transaction)) return false;
if (SysId.IsValid(transaction.Id)) return SetErrorState(ErrorMessage.ValiditemId);
if (StringUtil.IsBlank(transaction.Ref))
{
if (!AssignTransactionReference(transaction))
return false;
if (!IsValidValue(transaction.Ref, "Ref", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Ref), true))
return false;
}
using (var dbConnection = Database.CreateConnection())
using (var dbCommand = dbConnection.CreateCommand())
{
@@ -607,6 +617,29 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
return OK;
}
private bool AssignTransactionReference(SbmTransaction transaction)
{
if (HasErrorState()) return false;
// Populate reference if not already done.
if (StringUtil.IsBlank(transaction.Ref) && SessionConsole.TransactionAssignRefMethod(transaction.TransactionType) != SbmSessionConsole.AssignTransRefMethod.Manual)
{
// Retrieve the next available transaction reference.
String sRef = SessionConsole.GetTransactionCreateRef(transaction.AffiliateIdOwner, transaction.AssociationId, transaction.TransactionType);
// Check that another transaction doesn't already exist with this reference.
SbmTransaction transRef = GetTransactionByOwnerTypeRef(transaction.AffiliateIdOwner, transaction.TransactionType, sRef);
if (transRef == null)
transaction.Ref = sRef;
else
{
String tranTypeDesc = TransactionTypes.GetDescForType(transaction.TransactionType);
if (StringUtil.IsEmpty(tranTypeDesc)) tranTypeDesc = "Transaction";
SetErrorState("Another " + tranTypeDesc + " already exists with this reference.");
}
if (HasErrorState()) return false;
}
return OK;
}
//-------------------------------------------------------------------
// Update Transaction.
public override bool UpdateTransaction(SbmTransaction transaction, DbUpdateInfo dbUpdateInfo)
@@ -792,7 +825,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
transaction.AssociationId = new SysId(dbTransaction._AssocId);
transaction.TransactionType = (Sbm.TransactionType)(dbTransaction._Type ?? 0);
transaction.Ref = dbTransaction._Ref;
transaction.RefInt = dbTransaction._RefInt ?? 0;
transaction.RefExt = dbTransaction._RefExt;
transaction.RaisedBy = dbTransaction._RaisedBy;
transaction.AffiliateIdRaise = new SysId(dbTransaction._AffIdRaise ?? 0);
@@ -2046,6 +2078,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
}
}
}
//---------------------------------------------------------------------
// Delivery Address.
bool hasColDeliveryAddress = columns.HasId(SbmTransaction.Column.DeliveryAddress);
@@ -2077,6 +2110,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
foreach (SbmDbDfn.ColumnIdx dbColumn in addressDeliveryCols)
query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasTransaction_DeliveryAddress), prefixTransaction_DeliveryAddress + SbmDbDfn.GetColumnName(dbColumn, false));
}
//---------------------------------------------------------------------
// Delivery tax code.
bool bHasColDeliveryTaxCode = false;
@@ -2096,6 +2130,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
foreach (SbmDbDfn.ColumnIdx dbColumn in taxcodeDeliveryCols)
query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasTransaction_DeliveryTaxcode), prefixTransaction_DeliveryTaxcode + SbmDbDfn.GetColumnName(dbColumn, false));
}
//---------------------------------------------------------------------
// Currency.
bool hasColCurrency = false;
@@ -2115,6 +2150,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
foreach (SbmDbDfn.ColumnIdx dbColumn in currencyCols)
query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasTransaction_Currency), prefixTransaction_Currency + SbmDbDfn.GetColumnName(dbColumn, false));
}
//---------------------------------------------------------------------
// Source Transaction.
bool hasColSourceTrans = columns.HasId(SbmTransaction.Column.SourceTrans_Ref);
@@ -2132,8 +2168,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
foreach (SbmDbDfn.ColumnIdx dbColumn in transactionSourceCols)
query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasTransaction_SourceTransaction), prefixTransaction_SourceTransaction + SbmDbDfn.GetColumnName(dbColumn, false));
}
//---------------------------------------------------------------------
// If subordinate records are being counted, other columns must be grouped. //if (bCountRequirements || bCountTimeRecords || bCountActions) //qry.lGroupBy = qry.lColumn.Values(); Slows down query immensely.
//---------------------------------------------------------------------
// Total transaction cost.
bool includeCostTotal = (columns.HasId(SbmTransaction.Column.CostTotal) || columns.HasId(SbmTransaction.Column.CostTotal_Fmt));
@@ -2150,40 +2185,41 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
qryReqntCount.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId, aliasTransaction_RequirementCost, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, aliasTransaction));
query.Columns.Add("(" + qryReqntCount.BuildQuery() + ")", colNameCostTotal);
}
//---------------------------------------------------------------------
bool countRequirements = columns.HasId(SbmTransaction.Column.ReqntCount);
if (countRequirements)
// Requirements.
if (columns.HasId(SbmTransaction.Column.ReqntCount))
{
// Build sub query to directly return the number of associated requirements.
String aliasTransaction_CountRequirement = "aTrnReqCnt";
String colNameCountReqnts = "CountReqnts";
DbQuery qryReqntCount = new DbQuery(Database.DbmsType);
qryReqntCount.Tables.Add(new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Requirement), aliasTransaction_CountRequirement));
qryReqntCount.Columns.Add("Count(" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Id, aliasTransaction_CountRequirement, false) + ")");
qryReqntCount.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId, aliasTransaction_CountRequirement, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, aliasTransaction));
qryReqntCount.Columns.Add("Count(*)");
qryReqntCount.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId, aliasTransaction_CountRequirement, false)}={SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, aliasTransaction)}");
qryReqntCount.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Status, aliasTransaction_CountRequirement, false)} Not In ('{StatusCancelled}','{StatusDeleted}')");
query.Columns.Add("(" + qryReqntCount.BuildQuery() + ")", colNameCountReqnts);
}
//---------------------------------------------------------------------
bool bCountTimeRecords = columns.HasId(SbmTransaction.Column.TimeCount);
if (bCountTimeRecords)
// Time records.
if (columns.HasId(SbmTransaction.Column.TimeCount))
{
// Build sub query to directly return the number of associated constituents of type 'Time'.
String aliasTransaction_CountTimes = "ConTim";
String colNameCountTimeRecs = "CountTimeRecs";
DbQuery qryConstTimeCount = new DbQuery(Database.DbmsType);
qryConstTimeCount.Tables.Add(new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Constituent), aliasTransaction_CountTimes));
qryConstTimeCount.Columns.Add("Count(" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Constituent_Id, aliasTransaction_CountTimes, false) + ")");
qryConstTimeCount.Columns.Add("Count(*)");
qryConstTimeCount.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Constituent_TransId, aliasTransaction_CountTimes, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, aliasTransaction));
qryConstTimeCount.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Constituent_Type, aliasTransaction_CountTimes, false) + "=" + Sbm.ConstituentType.TimeRecord.ToString());
qryConstTimeCount.Columns.Add("(" + qryConstTimeCount.BuildQuery() + ")", colNameCountTimeRecs);
}
//---------------------------------------------------------------------
bool bCountActions = columns.HasId(SbmTransaction.Column.TaskCount);
if (bCountActions)
// Tasks.
if (columns.HasId(SbmTransaction.Column.TaskCount))
{
// Build sub query to directly return the number of associated constituents of type 'Action'.
String aliasTransaction_CountActions = "ConAct";
String colNameCountActions = "CountActions";
DbQuery qryConstActionCount = new DbQuery(Database.DbmsType);
qryConstActionCount.Tables.Add(new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Constituent), aliasTransaction_CountActions));
qryConstActionCount.Columns.Add("Count(" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Constituent_Id, aliasTransaction_CountActions, false) + ")");
@@ -2193,8 +2229,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
}
//---------------------------------------------------------------------
// Whether transaction has associated invoices.
bool checkForInvoices = columns.HasId(SbmTransaction.Column.HasInvoice);
if (checkForInvoices)
if (columns.HasId(SbmTransaction.Column.HasInvoice))
{
// Check which types of transaction are allowed.
bool invoicesAllowed = SessionConsole != null && (AllowTransactionType(Sbm.TransactionType.ProformaSalesInvoice) || AllowTransactionType(Sbm.TransactionType.SalesInvoice) ||
@@ -2205,7 +2240,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Aliases & Columns.
String aliasTransaction_TransactionInvoice = "TraInv";
String aliasTransaction_TransactionSource = "TraSrc";
String colNameHasInvoice = "HasInvoice";
// Supported invoice transaction types.
List<String> transTypeInvoices = new List<String>();
@@ -2235,8 +2269,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
}
}
//---------------------------------------------------------------------
bool bAccountInvoiceRef = columns.HasId(SbmTransaction.Column.AccountsInvoiceRef);
if (bAccountInvoiceRef)
if (columns.HasId(SbmTransaction.Column.AccountsInvoiceRef))
{
// Identify the accounts interface.
HashSet<SysId> accountsIdsInterface = AccountsDfn.GetInterfaceIds(true);