290 lines
13 KiB
C#
290 lines
13 KiB
C#
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.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;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Transactions;
|
|
|
|
namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|
{
|
|
//=======================================================================
|
|
// Transaction manager - Transactions - Utils.
|
|
//=======================================================================
|
|
partial class SbmTransactionMgr_Dbas
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Read only.
|
|
public override bool TransactionIsReadOnly(SbmTransaction transaction)
|
|
{
|
|
if (!SysId.IsValid(transaction.Id)) return false;
|
|
bool bReadOnly = false;
|
|
|
|
// Transaction can't be updated after it has been exporetd to an accounts system.
|
|
if (!bReadOnly)
|
|
{
|
|
if (AccountsDfn.IsTransactionTypeManagedByAccounts(transaction.TransactionType))
|
|
bReadOnly = true;
|
|
}
|
|
return bReadOnly;
|
|
}
|
|
public override bool TransactionDetailsAreReadOnly(SbmTransaction transaction)
|
|
{
|
|
if (!SysId.IsValid(transaction.Id)) return false;
|
|
if (TransactionIsReadOnly(transaction)) return true; // If transaction is read only then details must be.
|
|
bool detailsAreReadOnly = false;
|
|
|
|
// User must be allowed to update transactions:
|
|
if (!detailsAreReadOnly)
|
|
{
|
|
// ToDo UserCanUpdateItemType
|
|
/*if (!pSys->UserCanUpdateItemType(eSapItemTypeTransaction))
|
|
bDetailsAreReadOnly = true;*/
|
|
}
|
|
|
|
// Closed transactions.
|
|
if (!detailsAreReadOnly)
|
|
{
|
|
if (transaction.TransactionStatusCat == SbmTransaction.StatusCat.Closed)
|
|
{
|
|
// Once the 'grace' period has passed, only the status can be modified.
|
|
int graceDaysUpdateClosedTrans = Math.Max(0, Internals.GetOwnerOption_UpdateLimit(Sbm.OrgOption_PeriodDays.UpdateClosedTransaction, 0));
|
|
DateTime closed = transaction.Closed;
|
|
detailsAreReadOnly = (DateUtil.IsValid(closed) && closed <= DateTime.Today.AddDays(-graceDaysUpdateClosedTrans));
|
|
}
|
|
}
|
|
|
|
return detailsAreReadOnly;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
public override bool RefreshTransactionTotals(SbmTransaction transaction, IEnumerable<SbmRequirement> requirements)
|
|
{
|
|
ClearErrorState();
|
|
if (transaction == null) return SetErrorState(ErrorMessage.InvalidStatus);
|
|
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()
|
|
{
|
|
String costLabourRateHour = Internals.GetOwnerOption_Value(Sbm.OrgOption_Value.CostLabourRateDefault);
|
|
return costLabourRateHour.ToDecimal();
|
|
}
|
|
// ToDo GetTransCostLabourRateHourDefault & GetTransCostLabourRateHour for conversion datatype double to decimal!
|
|
public override decimal GetTransCostLabourRateHour(SysId transactionId)
|
|
{
|
|
string colCostLabourRateHour = "CostLabourRateHour";
|
|
decimal labourRate = 0.0m;
|
|
if (SysId.IsValid(transactionId))
|
|
{
|
|
labourRate = GetTransCostLabourRateHourDefault();
|
|
if (ColumnExists(SbmDbDfn.ColumnIdx.Transaction_CostLabourRateHour))
|
|
{
|
|
// Construct the query.
|
|
DbQuery qry = new DbQuery(Database.DbmsType);
|
|
qry.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction));
|
|
qry.Columns.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_CostLabourRateHour), colCostLabourRateHour);
|
|
qry.Filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_Id) + "=" + transactionId.ToString());
|
|
qry.Filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_CostLabourRateHour) + " IS NOT null");
|
|
|
|
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(Database, qry.ToString()))
|
|
{
|
|
if (dbResultSet != null && dbResultSet.NextRecord())
|
|
{
|
|
NamedValue.Map values = dbResultSet.GetRecordValues();
|
|
return (decimal)values.GetValue(colCostLabourRateHour).ToNumeric();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return labourRate;
|
|
}
|
|
public override bool DeliveryFinancialsAreAvailable()
|
|
{
|
|
// Are the fields defined on the database?
|
|
if (ColumnExists(SbmDbDfn.ColumnIdx.Transaction_DeliveryAmountNet)) return false;
|
|
if (ColumnExists(SbmDbDfn.ColumnIdx.Transaction_DeliveryAmountTax)) return false;
|
|
if (!ColumnExists(SbmDbDfn.ColumnIdx.Transaction_DeliveryAmountTot)) return false;
|
|
if (!ColumnExists(SbmDbDfn.ColumnIdx.Transaction_TaxCodeIdDelivery)) return false;
|
|
if (!ColumnExists(SbmDbDfn.ColumnIdx.Transaction_DeliveryDepartment)) return false;
|
|
if (!ColumnExists(SbmDbDfn.ColumnIdx.Transaction_DeliveryNominalCode)) return false;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Change association against transaction and dependent data.
|
|
/// </summary>
|
|
public override bool ChangeTransactionsAssociation(SbmTransaction transaction, SysId assocId)
|
|
{
|
|
ClearErrorState();
|
|
List<String> filters = new List<String>();
|
|
List<StringPair> values = new List<StringPair>();
|
|
String errorStatePrefix = "Failed to change transaction's association - ";
|
|
|
|
// Database connection.
|
|
if (!HasErrorState() && Database == null) SetErrorState(errorStatePrefix + ErrorMessage.DatabaseNotAvailable);
|
|
|
|
// Validate the transaction.
|
|
if (!HasErrorState() && (transaction == null || !SysId.IsValid(transaction.Id)))
|
|
SetErrorState(errorStatePrefix + "invalid transaction specified");
|
|
|
|
///<summary>### Apr2012 Don't bother checking that the transaction's assocition is different ###</summary>
|
|
/* Check that the association is not the same as the current association.
|
|
if (!HasErrorState() && transaction.AssocId == assocId)
|
|
SetErrorState(errorStatePrefix+"a different association must be specified");*/
|
|
|
|
// Check that the specified association exists.
|
|
if (!HasErrorState() && AccountMgr != null && !AccountMgr.AssociationExistsById(assocId))
|
|
SetErrorState(errorStatePrefix + "specified association doesn't exist");
|
|
|
|
// Replace the association against subordinate data items.
|
|
if (!HasErrorState() && TransactionHasConstituents(transaction.Id, SbmConstituent.StatusCat.NotDeleted))
|
|
{
|
|
SacsDatabase.AddValuePair(values, SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Constituent_AssocId), assocId.ToString(), false);
|
|
filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Constituent_TransId) + "=" + transaction.Id.ToString());
|
|
Database.ExecuteUpdate(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Constituent), values, filters.Concat(" AND ", "(", ")"));
|
|
if (Database.HasErrorState())
|
|
{
|
|
SetErrorState(errorStatePrefix + "transaction updates failed");
|
|
ChangeTransactionsAssociation(transaction, transaction.AssociationId); // To reset changes.
|
|
}
|
|
}
|
|
if (!HasErrorState() && TransactionHasRequirements(transaction.Id, SbmRequirement.StatusCat.NotDeleted))
|
|
{
|
|
SacsDatabase.AddValuePair(values, SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Requirement_AssocId), assocId.ToString(), false);
|
|
filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Requirement_TransId) + "=" + transaction.Id.ToString());
|
|
Database.ExecuteUpdate(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Requirement), values, filters.Concat(" AND ", "(", ")"));
|
|
if (Database.HasErrorState())
|
|
{
|
|
SetErrorState(errorStatePrefix + "requirement updates failed");
|
|
ChangeTransactionsAssociation(transaction, transaction.AssociationId); // To reset changes.
|
|
}
|
|
}// Replace the association against the transaction itself.
|
|
if (!HasErrorState() && transaction.AssociationId != assocId)
|
|
{
|
|
filters.Clear(); values.Clear();
|
|
SacsDatabase.AddValuePair(values, SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_AssocId), assocId.ToString(), false);
|
|
filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_Id) + "=" + transaction.Id.ToString());
|
|
Database.ExecuteUpdate(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction), values, filters.Concat(" AND ", "(", ")"));
|
|
if (Database.HasErrorState())
|
|
{
|
|
SetErrorState(errorStatePrefix + "transaction update failed");
|
|
ChangeTransactionsAssociation(transaction, transaction.AssociationId); // To reset changes.
|
|
}
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Transaction Subordinate data.
|
|
|
|
/// <summary>Commit Subordinate data - Payments.</summary>
|
|
public override bool CommitTransactionSubordinateData(SbmTransaction transaction, DbUpdateInfo dbUpdateInfo)
|
|
{
|
|
ClearErrorState();
|
|
if (transaction == null || !SysId.IsValid(transaction.Id)) return false;
|
|
if (!HasErrorState()) CommitTransactionPayments(transaction, dbUpdateInfo);
|
|
return OK;
|
|
}
|
|
public override bool TransactionHasPayments(SysId transactionId)
|
|
{
|
|
if (!SysId.IsValid(transactionId)) return false;
|
|
SbmItemLink.Params prmItemLink = new SbmItemLink.Params();
|
|
prmItemLink.ItemLinkType = Sbm.ItemLinkType.Transaction_Payment;
|
|
prmItemLink.ItemTypeFrom = Sbm.ItemType.Transaction;
|
|
prmItemLink.ItemIdFrom = transactionId;
|
|
return DataItemMgr.GetItemLinkCount(prmItemLink) > 0;
|
|
}
|
|
public override List<SbmTransactionPayment> GetTransactionPayments(SysId transactionId)
|
|
{
|
|
List<SbmTransactionPayment> transactionPayments = new List<SbmTransactionPayment>();
|
|
if (!SysId.IsValid(transactionId)) return transactionPayments;
|
|
SbmItemLink.Params prm = new SbmItemLink.Params();
|
|
prm.ItemLinkType = Sbm.ItemLinkType.Transaction_Payment;
|
|
prm.ItemTypeFrom = Sbm.ItemType.Transaction;
|
|
prm.ItemIdFrom = transactionId;
|
|
foreach (SbmItemLink itemLink in DataItemMgr.GetItemLinkList(prm))
|
|
{
|
|
SbmTransactionPayment transactionPayment = new SbmTransactionPayment(itemLink.DataContent);
|
|
transactionPayment.Notes = itemLink.Notes;
|
|
transactionPayment.Changed = false;
|
|
if (transactionPayments == null) transactionPayments = new List<SbmTransactionPayment>();
|
|
transactionPayments.Add(transactionPayment);
|
|
}
|
|
transactionPayments.Sort();
|
|
return transactionPayments;
|
|
}
|
|
public override bool CommitTransactionPayments(SbmTransaction transaction, DbUpdateInfo dbUpdateInfo)
|
|
{
|
|
ClearErrorState();
|
|
// Do not attempt any updates unless the list has been populated.
|
|
if (transaction == null || !SysId.IsValid(transaction.Id) || transaction.Payments == null) return false;
|
|
|
|
// Build an item link list corresponding to the list of payment:
|
|
List<SbmItemLink> itemLinks = new List<SbmItemLink>();
|
|
foreach (SbmTransactionPayment transactionPayment in transaction.Payments)
|
|
{
|
|
if (transactionPayment == null) continue;
|
|
SbmItemLink itemLink = DataItemMgr.CreateItemLink(Sbm.ItemLinkType.Transaction_Payment, Sbm.ItemType.Transaction, transaction.Id, Sbm.ItemType.Unknown, new SysId(0));
|
|
if (itemLink != null)
|
|
{
|
|
itemLink.Seq = (short)transactionPayment.CodeSeq;
|
|
itemLink.DataContent = transactionPayment.ToString();
|
|
itemLink.Notes = transactionPayment.Notes;
|
|
itemLinks.Add(itemLink);
|
|
itemLink = null; // Now owned by the list.
|
|
}
|
|
}
|
|
// Store these details:
|
|
if (!DataItemMgr.StoreFromItemLinks(Sbm.ItemLinkType.Transaction_Payment, transaction.GetItemId(), itemLinks, dbUpdateInfo))
|
|
SetErrorState("Failed to save transaction payment item links - " + DataItemMgr.ErrorStateMessage);
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|