335 lines
14 KiB
C#
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, 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;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|