Files
BusinessMgr-2019/SaBusMgrStandardDbas/Dbas/Bus/SbmRequirement_Dbas.cs
T
2024-11-19 09:47:00 +00:00

335 lines
14 KiB
C#

using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
namespace Sarand.BusinessMgr.Net.Standard.Dbas.Bus
{
//=======================================================================
class SbmRequirement_Dbas : SbmRequirement
{
//-------------------------------------------------------------------
// Data members.
private readonly SbmInternals internals;
private readonly String statusCancelled = SacsSystem.GetStatusCode(SaStatus.Cancelled);
//-------------------------------------------------------------------
// Construction.
public SbmRequirement_Dbas(SbmInternals internals, SysId id, SysId affIdOwner, SysId assocId, SysId transId, Sbm.RequirementType requirementType, ushort flags) :
base(internals.UserContext, id, affIdOwner, assocId, transId, requirementType)
{
this.internals = internals;
Flags = flags;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
// NB Do not dispose the Internals - owned by manager.
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
private SbmTransactionMgr TransactionMgr { get { return internals.TransactionMgr; } }
private SbmDataItemMgr DataItemMgr { get { return internals.DataItemMgr; } }
private SbmProcessMgr ProcessMgr { get { return internals.ProcessMgr; } }
private SbmStockMgr StockMgr { get { return internals.StockMgr; } }
//-------------------------------------------------------------------
// Associated data.
public override bool HasRequirements()
{
ClearErrorState();
bool hasRequirements = TransactionMgr.RequirementHasAssociatedRequirements(Id);
SetErrorState(TransactionMgr.ErrorStateMessage);
return hasRequirements;
}
public override bool HasConstituents(Sbm.ConstituentType constituentType)
{
ClearErrorState();
bool hasConstituents = TransactionMgr.RequirementHasConstituents(Id, constituentType);
SetErrorState(TransactionMgr.ErrorStateMessage);
return hasConstituents;
}
public override bool HasStockMovments()
{
ClearErrorState();
bool hasMovements = false;
/* ToDo need to have StockMgr for RequirementDbas>HasStockMovments
if (SysId.IsValid(Id) && InitStockMgr())
{
hasMovements = stockMgr.SourceItemHasMovements(Sbm.ItemType.Requirement, Id);
}*/
return hasMovements;
}
public override bool HasItemLinks()
{
ClearErrorState();
if (SysId.IsValid(Id))
DataItemMgr.HasItemLinks(Sbm.ItemType.Requirement, Id);
return false;
}
//-------------------------------------------------------------------
public override bool CommitAssociatedData()
{
ClearErrorState();
if (this == null || !SysId.IsValid(Id)) return false;
if (!HasErrorState()) CommitCostEstimates();
if (!HasErrorState()) CommitProcesses();
return !HasErrorState();
}
//-------------------------------------------------------------------
public override bool ClearDependentData()
{
ClearErrorState();
TransactionMgr.ClearRequirementDependentData(Id, CommodityId);
SetErrorState(TransactionMgr.ErrorStateMessage);
return !HasErrorState();
}
public override bool ClearAssociatedRequirements()
{
ClearErrorState();
TransactionMgr.ClearRequirementAssociatedRequirements(Id);
SetErrorState(TransactionMgr.ErrorStateMessage);
return !HasErrorState();
}
public override decimal GetQuantityDispatched(SysId transIdExclude)
{
ISacsDatabase db = internals.BusMgrDatabase;
if (SysId.IsValid(Id))
{
// Build query to sum associated dispatch item quantities.
List<String> filters = new List<String>
{
SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_ReqntIdSource) + "=" + Id.ToString(),
SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Status) + "<>'" + statusCancelled + "'"
};
// Requirement must belong to a transaction of type 'Dispatch Note'.
DbQuery qryTrans = new DbQuery(db.DbmsType);
qryTrans.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction));
qryTrans.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id));
if (SysId.IsValid(transIdExclude))
qryTrans.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id) + "<>" + transIdExclude.ToString());
qryTrans.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId));
qryTrans.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Type) + "=" + Sbm.TransactionType.SalesDispatch.ToString());
qryTrans.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Status) + "<>'" + statusCancelled + "'");
filters.Add("EXISTS (" + qryTrans.BuildQuery() + ")");
// Retrieve database and perform query.
if (db != null)
db.GetRowValue(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Requirement), SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Quantity), filters.Concat(" AND ", "(", ")"), DbGetValueType.eDbValueSum);
SetErrorState("Database query failed");
}
return 0.0m;
}
//-------------------------------------------------------------------
public override decimal GetQuantityInvoiced(SysId transIdExclude)
{
ISacsDatabase db = internals.BusMgrDatabase;
if (SysId.IsValid(Id))
{
// Build query to sum associated dispatch item quantities.
List<String> filter = new List<String>
{
SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_ReqntIdSource) + "=" + Id.ToString(),
SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Status) + "<>'" + statusCancelled + "'"
};
// Requirement must belong to a transaction of type 'Invoice' (Sales or Purchase).
DbQuery qryTrans = new DbQuery(db.DbmsType);
String colTransaction_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id);
String colRequirement_TransId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId);
String colTransaction_Type = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Type);
String colTransaction_Status = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Status);
qryTrans.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction));
qryTrans.Columns.Add(colTransaction_Id);
if (SysId.IsValid(transIdExclude))
qryTrans.Filters.Add(colTransaction_Id + "<>" + transIdExclude.ToString());
qryTrans.Filters.Add(colTransaction_Id + "=" + colRequirement_TransId);
qryTrans.Filters.Add("(" + colTransaction_Type + "=" + Sbm.TransactionType.SalesInvoice.ToString() + "OR" + colTransaction_Type + "=" + Sbm.TransactionType.PurchaseInvoice + ")".ToString());
qryTrans.Filters.Add(colTransaction_Status + "<>'" + statusCancelled + "'");
filter.Add("EXISTS (" + qryTrans.BuildQuery() + ")");
// Retrieve database and perform query.
if (db != null)
db.GetRowValue(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Requirement), SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Quantity), filter.Concat(" AND ", "(", ")"), DbGetValueType.eDbValueSum);
SetErrorState("Database query failed");
}
return 0.0m;
}
//-------------------------------------------------------------------
// C o s t E s t i m a t e s
//-------------------------------------------------------------------
public override bool HasCostEstimates()
{
if (data.CostEstimates != null) return data.CostEstimates.Count > 0;
if (!SysId.IsValid(Id)) return false;
SbmItemLink.Params prmItemLink = new SbmItemLink.Params
{
ItemLinkType = Sbm.ItemLinkType.Requirement_CostEstimate,
ItemTypeFrom = Sbm.ItemType.Requirement,
ItemIdFrom = Id
};
return DataItemMgr.GetItemLinkCount(prmItemLink) > 0;
}
public override List<SbmCostEstimate> GetCostEstimates()
{
List<SbmCostEstimate> costEstimatesCopy = null;
if (data.CostEstimates == null)
data.CostEstimates = TransactionMgr.GetRequirementCostEstimates(GetData());
// Clone and sort the list.
costEstimatesCopy = data.CostEstimates.Clone();
costEstimatesCopy.Sort();
return costEstimatesCopy;
}
public override bool SetCostEstimates(List<SbmCostEstimate> costEstimatesNew)
{
data.CostEstimates = costEstimatesNew?.Clone() ?? new List<SbmCostEstimate>();
return true;
}
public override bool CommitCostEstimates()
{
ClearErrorState();
// Do not attempt any updates unless the list has been populated.
if (data.CostEstimates != null && SysId.IsValid(Id) && DataItemMgr != null)
{
// Build an item link list corresponding to the list of cost estimates:
List<SbmItemLink> itemLinks = new List<SbmItemLink>();
foreach (SbmCostEstimate costEstimate in data.CostEstimates)
{
if (costEstimate == null) continue;
SbmItemLink itemLink = DataItemMgr.CreateItemLink(Sbm.ItemLinkType.Requirement_CostEstimate, Sbm.ItemType.Requirement, Id, Sbm.ItemType.Unknown, new SysId(0));
if (itemLink != null)
{
itemLink.Seq = (short)costEstimate.CodeSeq;
itemLink.DataContent = costEstimate.ToString();
itemLink.Notes = costEstimate.Notes;
itemLinks.Add(itemLink);
itemLink = null; // Now owned by the list.
}
}
// Store these details.
if (!DataItemMgr.StoreFromItemLinks(Sbm.ItemLinkType.Requirement_CostEstimate, new ItemId((short)Sbm.ItemType.Requirement, Id), itemLinks, internals.DbUpdateInfo))
SetErrorState("Failed to save cost estimate item links - " + DataItemMgr.ErrorState);
if (itemLinks != null)
itemLinks.Clear();
}
return false;
}
//-------------------------------------------------------------------
// P r o c e s s e s
//-------------------------------------------------------------------
public override bool HasProcess()
{
if (data.Processes != null) return data.Processes.Count > 0;
if (!SysId.IsValid(Id)) return false;
SbmConstituent.Params prmConstituent = new SbmConstituent.Params
{
ConstituentType = Sbm.ConstituentType.Process,
ReqntId = Id
};
return TransactionMgr.GetConstituentCount(prmConstituent) > 0;
}
public override List<SbmItemProcess> GetProcesses()
{
if (data.Processes == null && SysId.IsValid(Id))
data.Processes = TransactionMgr.GetRequirementItemProcesses(GetData());
// Clone the list:
return data.Processes.Clone();
}
public override bool SetProcesses(List<SbmItemProcess> itemProcessesNew)
{
data.Processes = itemProcessesNew?.Clone() ?? new List<SbmItemProcess>();
return true;
}
public override bool CommitProcesses()
{
ClearErrorState();
// Do not attempt any updates unless the list has been populated.
if (data.Processes == null || !SysId.IsValid(Id)) return true;
// Make a copy of the process list so that we can track those that have been updated.
List<SbmItemProcess> itemProcessesLocal = new List<SbmItemProcess>(data.Processes);
// Retrieve the existing processes for this requirement.
SbmConstituent.Params prmConstituent = new SbmConstituent.Params();
prmConstituent.ConstituentType = Sbm.ConstituentType.Process;
prmConstituent.ReqntId = Id;
foreach (SbmConstituent constituent in TransactionMgr.GetConstituentList(prmConstituent))
{
// Does this process still exist in the list.
SbmItemProcess itemProcessLocal = itemProcessesLocal.Find(item => item.ProcessId.Equals(constituent.ProcessId));
if (itemProcessLocal != null)
{
if (itemProcessLocal.Changed)
{
// Update the details.
CopyFrom(itemProcessLocal, constituent);
if (TransactionMgr.UpdateConstituent(constituent, internals.DbUpdateInfo))
itemProcessLocal.Changed = false;
else SetErrorState("failed to update process constituent");
}
// Remove this process from the local copy of the list (without deleting it).
itemProcessesLocal.Remove(itemProcessLocal);
}
else
{
// Process no longer required.
constituent.Status = SaStatus.Cancelled;
if (!TransactionMgr.DeleteConstituent(constituent, internals.DbUpdateInfo))
SetErrorState("failed to delete process constituent");
}
}
// Any item processes left in the local list need to be created.
foreach (SbmItemProcess itemprocess in itemProcessesLocal)
{
if (itemprocess == null) continue;
// Create a constituent to represent this process:
SbmConstituent constituent = TransactionMgr.CreateConstituent(AssociationId, Sbm.ConstituentType.Process);
if (constituent != null)
{
// Update the constituent to belong to this requirement.
constituent.TransactionId = TransactionId;
constituent.RequirementId = Id;
CopyFrom(itemprocess, constituent);
// Add it to the database:
if (TransactionMgr.InsertConstituent(constituent, internals.DbUpdateInfo))
itemprocess.Changed = false;
else SetErrorState("failed to add constituent - " + TransactionMgr.ErrorState);
}
else SetErrorState("failed to create constituent - " + TransactionMgr.ErrorState);
}
return !HasErrorState();
}
//-------------------------------------------------------------------
// Item Process - Constituent Interface.
public void CopyFrom(SbmItemProcess itemProcess, SbmConstituent constituent)
{
if (itemProcess == null || constituent != null) return;
constituent.Seq = itemProcess.Seq;
constituent.Notes = itemProcess.Notes;
constituent.ProcessId = itemProcess.ProcessId;
constituent.AssociationIdContractor = itemProcess.AssocIdContractor;
constituent.AmountNet = itemProcess.AmountNet;
constituent.Completed = itemProcess.Completed;
constituent.Notes = itemProcess.Notes;
constituent.Status = itemProcess.Status;
}
//-------------------------------------------------------------------
}
//=======================================================================
}