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.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; namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr { //======================================================================= partial class SbmStockMgr_Dbas { //******************************************************************* // M o v e m e n t //******************************************************************* // Data members. private bool locationIdsPopulated = false; private List locationIds_All = new List(); private List locationIds_Sales = new List(); private List locationIds_Calc = new List(); private int orderQuantityDecimals; //------------------------------------------------------------------- // Utilities. private List GetLogProperties(SbmMovement movement) { return new List() { new StringPair("Id",SysId.ToString(movement.Id)), new StringPair("Quantity",movement.Quantity.ToString("N3")), new StringPair("Status",movement.StatusCode) }; } public override String GetItemSource(Sbm.ItemType itemType, SysId id, bool brief = false) { return ""; } // Reference - can be seen in Commodity-MgrDbas & Requirement-MgrDbas as PopulateLocationIdsList public override bool PopulateLocationIds() { if (locationIdsPopulated) return true; if (CommodityMgr != null) { SbmLocation.Params prmLocation = new SbmLocation.Params(); prmLocation.StatusCat = SbmLocation.StatusCat.ActiveOnly; foreach (SbmLocation location in StockMgr.GetLocationList(prmLocation)) { if (location == null) break; locationIds_All.Add(location.Id); if (location.SalesStock) locationIds_Sales.Add(location.Id); if (location.CalculateStock) locationIds_Calc.Add(location.Id); } locationIdsPopulated = true; } return locationIdsPopulated; } public override bool CancelMovementsForSourceItem(Sbm.ItemType itemType, SysId itemId) { ClearErrorState(); if (Database.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement))) return true; // Commodity database names. String colMovement_ItemId = SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemId); String colMovement_Status = SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_Status); List lFilterSourceItem = new List(); lFilterSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemTypeSource) + "=" + ((int)itemType).ToString()); lFilterSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemIdSource) + "=" + itemId.ToString()); // Retrieve a list of commodities that have actioned movements against this item. List commodityIds = new List(); DbQuery qryMovCmd = new DbQuery(Database.DbmsType); qryMovCmd.DistinctRows = true; qryMovCmd.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement)); qryMovCmd.Columns.Add(colMovement_ItemId); qryMovCmd.Filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemType) + "=" + ((int)Sbm.ItemType.Commodity).ToString()); qryMovCmd.Filters.AddRange(lFilterSourceItem); using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(Database, qryMovCmd.BuildQuery())) { while (dbResultSet != null && dbResultSet.NextRecord()) { NamedValue.Map value = dbResultSet.GetRecordValues(); commodityIds.Add(new SysId((int)value.GetValue(colMovement_ItemId).AsLong())); } } // Update the associated movements to set their status to 'Cancelled'. List values = new List(); SacsDatabase.AddValuePair(values, colMovement_Status, StatusCancelled, true); Database.ExecuteUpdate(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement), values, lFilterSourceItem.Concat(" AND ", "(", ")")); if (Database.HasErrorState()) SetErrorState($"{Database.ErrorStateMessage}"); // ToDo CalculateStockLevels(commodityIds); > in Stock-MgrDbas return !HasErrorState(); } public override bool ClearMovementsForSourceItem(Sbm.ItemType itemType, SysId itemId) { ClearErrorState(); if (Database.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement))) return true; // Commodity database names. String colMovement_ItemId = SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemId); String colMovement_Status = SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_Status); List filtersSourceItem = new List(); filtersSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemTypeSource) + "=" + ((int)itemType).ToString()); filtersSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemIdSource) + "=" + itemId.ToString()); // Retrieve a list of commodities that have actioned movements against this item. List commodityIds = new List(); DbQuery qryMovCmd = new DbQuery(Database.DbmsType); qryMovCmd.DistinctRows = true; qryMovCmd.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement)); qryMovCmd.Columns.Add(colMovement_ItemId); qryMovCmd.Filters.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemType) + "=" + ((int)Sbm.ItemType.Commodity).ToString()); qryMovCmd.Filters.AddRange(filtersSourceItem); using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(Database, qryMovCmd.BuildQuery())) { while (dbResultSet != null && dbResultSet.NextRecord()) { NamedValue.Map value = dbResultSet.GetRecordValues(); commodityIds.Add(new SysId((int)value.GetValue(colMovement_ItemId).AsLong())); } } // Delete the associated movements. Database.ExecuteDelete(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement), filtersSourceItem.Concat(" AND ", "(", ")")); // ToDo CalculateStockLevels(commodityIds); > in Stock-MgrDbas return !HasErrorState(); } // Check for references to source item. public override bool SourceItemHasMovements(Sbm.ItemType itemType, SysId itemId) { if ((int)itemType < 1 || !SysId.IsValid(itemId)) return false; if (Database.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement))) return false; List filtersSourceItem = new List(); filtersSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemTypeSource) + ((int)itemType).ToString()); filtersSourceItem.Add(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Movement_ItemIdSource) + "=" + itemId.ToString()); return Database.GetRowCount(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement), filtersSourceItem.Concat(" AND ", "(", ")")) > 0; } //------------------------------------------------------------------- // Get Movement. public override SbmMovement GetMovement(SbmMovement.Params prm) { return GetMovement(GetMovementQueryFilter(prm).Concat(" AND ", "(", ")")); } private SbmMovement GetMovement(String filter) { ClearErrorState(); long count = GetMovementCount(filter); if (count == 0) return null; if (count != 1) { SetErrorState("Multiple Movement found"); return null; } SbmMovement movement = null; // Query data. using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); Movement_Db dbMovement = new Movement_Db(DbInfo); dbMovement.PopulateFrom(dbCommand, aliasMovement, filter); movement = CreateMovement(dbMovement); } catch (Exception exc) { SetErrorState("Database query exception"); SaLogger.Warn($"{SysUtil.Fn}\n\tQuery: {dbCommand.CommandText}\n\t{ExceptionUtil.GetErrorStateMessage(exc)}"); } } return movement; } //------------------------------------------------------------------- // Create Movement. public override SbmMovement CreateMovement(Sbm.ItemType itemType, SysId itemId, Sbm.MovementType movementType) { return new SbmMovement_Dbas(Internals, new SysId(), itemType, itemId, movementType, 0); } private SbmMovement_Dbas CreateMovement(Movement_Db dbMovement) { ClearErrorState(); SbmMovement_Dbas movement = new SbmMovement_Dbas(Internals, new SysId(dbMovement._Id), (Sbm.ItemType)dbMovement._ItemType, new SysId(dbMovement._ItemId), (Sbm.MovementType)dbMovement._Type, (ushort)dbMovement._Flags); PopulateFrom(dbMovement, movement); return movement; } //------------------------------------------------------------------- // Validate Movement. public override bool IsValidMovementData(SbmMovement.Data data, SbmMovement.ErrField errField) { ClearErrorState(); if (!base.IsValidMovementData(data, errField)) return false; return true; } //------------------------------------------------------------------- // Insert Movement. public override bool InsertMovement(SbmMovement movement, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!IsValidMovement(movement)) return false; if (SysId.IsValid(movement.Id)) return SetErrorState(ErrorMessage.ValiditemId); using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); Movement_Db dbMovement = new Movement_Db(DbInfo); PopulateTo(dbMovement, movement, dbUpdateInfo); if (Movement_Db.FieldsNonId.Contains("Id")) { // Generate next Id. dbMovement._Id = SysId.ToInt(Database.GetNextId("Movement", dbUpdateInfo)); } dbMovement.ExecuteInsertCommand(dbCommand); movement.Id = new SysId(dbMovement._Id); movement.Changed = false; if (DebugMode) SaLogger.Debug($"{SysUtil.Fn} Inserted. " + GetLogProperties(movement).Concat(": ").Concat("", "\n\t")); } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Update Movement. public override bool UpdateMovement(SbmMovement movement, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!IsValidMovement(movement)) return false; if (!SysId.IsValid(movement.Id)) return SetErrorState(ErrorMessage.InvalidItemId); if (!movement.Changed) { if (DebugMode) SaLogger.Debug($"{SysUtil.Fn} Data not changed. " + GetLogProperties(movement).Concat(": ").Concat("", "\n\t")); return true; } using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { // Retrieve Movement. dbConnection.Open(); Movement_Db dbMovement = new Movement_Db(DbInfo); dbMovement.PopulateFrom(dbCommand, aliasMovement, "Id=" + SysId.ToString(movement.Id)); SbmUpdateLogItemMonitor_Movement updateLogMonitor = new SbmUpdateLogItemMonitor_Movement(Internals, CreateMovement(dbMovement)); // Update properties. PopulateTo(dbMovement, movement, dbUpdateInfo); dbMovement.ExecuteUpdateCommand(dbCommand); movement.Changed = false; if (DebugMode) SaLogger.Debug($"{SysUtil.Fn} Updated. " + GetLogProperties(movement).Concat(": ").Concat("", "\n\t")); // Record updates. updateLogMonitor.RecordUpdatedValues(movement); updateLogMonitor.LogUpdates(); } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Delete Movement. public override bool MovementCanBeDeleted(SbmMovement movement) { ClearErrorState(); if (!base.MovementCanBeDeleted(movement)) return false; return true; } public override bool DeleteMovement(SbmMovement movement, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!MovementCanBeDeleted(movement)) return false; using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { // Retrieve Movement. dbConnection.Open(); Movement_Db dbMovement = new Movement_Db(DbInfo); dbMovement.PopulateFrom(dbCommand, aliasMovement, "Id=" + movement.Id.ToString()); // Delete Movement. dbCommand.CommandType = System.Data.CommandType.Text; dbCommand.CommandText = "DELETE FROM " + SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement) + " WHERE Id=" + SysId.ToString(movement.Id) + ";"; dbCommand.ExecuteNonQuery(); movement.Changed = false; if (DebugMode) SaLogger.Debug($"{SysUtil.Fn} Deleted. " + GetLogProperties(movement).Concat(": ").Concat("", "\n\t")); } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Copy data properties to and from database. private void PopulateTo(Movement_Db dbMovement, SbmMovement movement, DbUpdateInfo dbUpdateInfo) { dbMovement._Id = movement.Id.ToInt(); dbMovement._ItemType = (short)movement.ItemType; dbMovement._ItemId = movement.ItemId.ToInt(); dbMovement._Type = (short)movement.MovementType; dbMovement._Movement = movement.Movement; dbMovement._LocationIdFrom = movement.LocationIdFrom.ToInt(); dbMovement._LocationIdTo = movement.LocationIdTo.ToInt(); dbMovement._Quantity = movement.Quantity; dbMovement._MovementIdSource = movement.MovementIdSource.ToInt(); dbMovement._ItemTypeSource = (short)movement.ItemTypeSource; dbMovement._ItemIdSource = movement.ItemIdSource.ToInt(); // Common properties. dbMovement._Notes = movement.Notes; dbMovement._Flags = (short)movement.Flags; dbMovement._Status = SacsSystem.GetStatusCode(movement.Status); if (!SysId.IsValid(movement.Id)) { dbMovement._CreateOn = DateTime.UtcNow; dbMovement._CreateBy = dbUpdateInfo.UserId.ToInt(); dbMovement._CreateHost = dbUpdateInfo.Host; } dbMovement._UpdateOn = DateTime.UtcNow; dbMovement._UpdateBy = dbUpdateInfo.UserId.ToInt(); dbMovement._UpdateHost = dbUpdateInfo.Host; } private void PopulateFrom(Movement_Db dbMovement, SbmMovement movement) { movement.Id = new SysId(dbMovement._Id); movement.ItemType = (Sbm.ItemType)dbMovement._ItemType; movement.ItemId = new SysId(dbMovement._ItemId); movement.MovementType = (Sbm.MovementType)(dbMovement._Type ?? 0); movement.Movement = dbMovement._Movement ?? default(DateTime); movement.LocationIdFrom = new SysId(dbMovement._LocationIdFrom ?? 0); movement.LocationIdTo = new SysId(dbMovement._LocationIdTo ?? 0); movement.Quantity = dbMovement._Quantity; movement.MovementIdSource = new SysId(dbMovement._MovementIdSource ?? 0); movement.ItemTypeSource = (Sbm.ItemType)(dbMovement._ItemTypeSource ?? 0); movement.ItemIdSource = new SysId(dbMovement._ItemIdSource ?? 0); // Common properties. movement.Notes = dbMovement._Notes; movement.Status = SacsSystem.GetStatusForCode(dbMovement._Status); movement.SetCreateStamp(dbMovement._CreateOn, new SysId(dbMovement._CreateBy), dbMovement._CreateHost); movement.SetUpdateStamp(dbMovement._UpdateOn ?? default(DateTime), new SysId(dbMovement._UpdateBy ?? 0), dbMovement._UpdateHost); movement.AcceptChanges(); } //------------------------------------------------------------------- // Column definitions. private static readonly String aliasMovement = "aMov"; private static String aliasMovement_Commodity = "Mov_Cmd"; private static String prefixMovement_Commodity = aliasMovement_Commodity + "_"; private static String aliasMovement_Container = "Mov_Cnt"; private static String prefixMovement_Container = aliasMovement_Container + "_"; private static String aliasMovement_ContainerItem = "Mov_CntItem"; private static String prefixMovement_ContainerItem = aliasMovement_ContainerItem + "_"; private static String aliasMovement_LocationFrom = "Mov_LocFrom"; private static String prefixMovement_LocationFrom = aliasMovement_LocationFrom + "_"; private static String aliasMovement_LocationTo = "Mov_LocTo"; private static String prefixMovement_LocationTo = aliasMovement_LocationTo + "_"; // Column definition population. private void SetMovementColDfn (ColumnDfn col, String caption, int width, SbmDbDfn.ColumnIdx dbCol, ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String, String alias = "", String prefix = "") { if (String.IsNullOrEmpty(alias) && SbmDbDfn.GetTableForColumn(dbCol) == SbmDbDfn.TableIdx.Movement) alias = aliasMovement; col.Set(caption, width, (int)dbCol, prefix + SbmDbDfn.GetColumnName(dbCol, false), SbmDbDfn.GetColumnNameQual(dbCol, alias), dataType, align); if (dataType == DataValue.DataType.String && dbCol != SbmDbDfn.ColumnIdx.Unknown) col.MaxLength = (int)SbmDbDfn.GetColTextLen(dbCol); } //------------------------------------------------------------------- // Getting Movement column definition. public override ColumnDfn GetMovementColumnDfn(SbmMovement.Column columnId, string caption = "", int width = 0) { orderQuantityDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.OrderQuantity); ColumnDfn columnDfn = new ColumnDfn((int)columnId, caption, width); switch (columnId) { case SbmMovement.Column.Pos: SetMovementColDfn(columnDfn, "Pos", 45, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right); columnDfn.SortMode = ColumnDfn.ColumnSortMode.Off; columnDfn.ReadOnly = true; columnDfn.Resizable = false; break; // Movement Properties. case SbmMovement.Column.Id: SetMovementColDfn(columnDfn, "Id", 60, SbmDbDfn.ColumnIdx.Movement_Id, ColumnAlignment.Right, DataValue.DataType.Long); columnDfn.ReadOnly = true; break; case SbmMovement.Column.ItemType: SetMovementColDfn(columnDfn, "Item type", 70, SbmDbDfn.ColumnIdx.Movement_ItemType, ColumnAlignment.Center, DataValue.DataType.Long); break; case SbmMovement.Column.ItemType_Desc: SetMovementColDfn(columnDfn, "Item type", 100, SbmDbDfn.ColumnIdx.Movement_ItemType, ColumnAlignment.Center); break; case SbmMovement.Column.ItemId: SetMovementColDfn(columnDfn, "Item Id", 70, SbmDbDfn.ColumnIdx.Movement_ItemId, ColumnAlignment.Center, DataValue.DataType.Long); break; case SbmMovement.Column.Type_Desc: SetMovementColDfn(columnDfn, "Type", 70, SbmDbDfn.ColumnIdx.Movement_Type); break; case SbmMovement.Column.Movement: SetMovementColDfn(columnDfn, "Movement", 100, SbmDbDfn.ColumnIdx.Movement_Movement, ColumnAlignment.Center, DataValue.DataType.DateTime); break; case SbmMovement.Column.MovementDate: SetMovementColDfn(columnDfn, "Movement on", 90, SbmDbDfn.ColumnIdx.Movement_Movement, ColumnAlignment.Center, DataValue.DataType.Date); break; case SbmMovement.Column.MovementTime: SetMovementColDfn(columnDfn, "at", 80, SbmDbDfn.ColumnIdx.Movement_Movement, ColumnAlignment.Center, DataValue.DataType.Time); break; case SbmMovement.Column.DiaryEntry: SetMovementColDfn(columnDfn, "Diary", 50, SbmDbDfn.ColumnIdx.Movement_Flags, ColumnAlignment.Center, DataValue.DataType.Bool); columnDfn.BoolFormat = ColumnBoolFormat.Tick; break; case SbmMovement.Column.Quantity: SetMovementColDfn(columnDfn, "Quantity", 80, SbmDbDfn.ColumnIdx.Movement_Quantity, ColumnAlignment.Right, DataValue.DataType.Double); columnDfn.NumDecimals = (byte)orderQuantityDecimals; break; case SbmMovement.Column.MovementIdSource: SetMovementColDfn(columnDfn, "SourceMovId", 100, SbmDbDfn.ColumnIdx.Movement_MovementIdSource, ColumnAlignment.Right, DataValue.DataType.Long); break; case SbmMovement.Column.SourceItemType: SetMovementColDfn(columnDfn, "Source item type", 120, SbmDbDfn.ColumnIdx.Movement_ItemTypeSource, ColumnAlignment.Center, DataValue.DataType.Long); break; case SbmMovement.Column.SourceItemId: SetMovementColDfn(columnDfn, "Source item Id", 100, SbmDbDfn.ColumnIdx.Movement_ItemIdSource, ColumnAlignment.Right, DataValue.DataType.Long); break; /*case SbmMovement.Column.SourceItem: SetMovementColDfn(columnDfn,"Source", 160, SbmDbDfn.ColumnIdx.Movement_Sou); break; case SbmMovement.Column.SourceItemPos: SetMovementColDfn(columnDfn,"Item pos", 70); columnDfn.Align(ColumnAlignment.Center); break;*/ //--------------------------------------------------------------- // Joined Commodity columns. case SbmMovement.Column.Commodity_Code: SetMovementColDfn(columnDfn, "Commodity code", 120, SbmDbDfn.ColumnIdx.Commodity_Code, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Commodity, prefixMovement_Commodity); break; case SbmMovement.Column.Commodity_DescBrief: SetMovementColDfn(columnDfn, "Commodity", 160, SbmDbDfn.ColumnIdx.Commodity_DescBrief, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Commodity, prefixMovement_Commodity); break; //--------------------------------------------------------------- // Joined Container columns. case SbmMovement.Column.Container_Reference: SetMovementColDfn(columnDfn, "Container ref", 100, SbmDbDfn.ColumnIdx.Container_Reference, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Container, prefixMovement_Container); break; case SbmMovement.Column.Container_DescBrief: SetMovementColDfn(columnDfn, "Container name", 160, SbmDbDfn.ColumnIdx.Container_DescBrief, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Container, prefixMovement_Container); break; case SbmMovement.Column.Container_TagId: SetMovementColDfn(columnDfn, "Container tag", 100, SbmDbDfn.ColumnIdx.Container_TagId, ColumnAlignment.Default, DataValue.DataType.Long, aliasMovement_Container, prefixMovement_Container); break; case SbmMovement.Column.Container_Notes: SetMovementColDfn(columnDfn, "Container notes", 100, SbmDbDfn.ColumnIdx.Container_Notes, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Container, prefixMovement_Container); break; case SbmMovement.Column.Container_Status: SetMovementColDfn(columnDfn, "Container status", 100, SbmDbDfn.ColumnIdx.Container_Status, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_Container, prefixMovement_Container); break; //--------------------------------------------------------------- // Associated Container item. case SbmMovement.Column.Container_Item_ItemType: SetMovementColDfn(columnDfn, "ContainerItem_ItemType", 100, SbmDbDfn.ColumnIdx.ContainerItem_ItemType, ColumnAlignment.Default, DataValue.DataType.String, aliasMovement_ContainerItem, prefixMovement_ContainerItem); break; case SbmMovement.Column.Container_Item_ItemId: SetMovementColDfn(columnDfn, "ContainerItem_ItemId", 100, SbmDbDfn.ColumnIdx.ContainerItem_ItemId, ColumnAlignment.Default, DataValue.DataType.Long, aliasMovement_ContainerItem, prefixMovement_ContainerItem); break; case SbmMovement.Column.Container_Item_Quantity: SetMovementColDfn(columnDfn, "ContainerItem_Quantity", 100, SbmDbDfn.ColumnIdx.ContainerItem_Quantity, ColumnAlignment.Right, DataValue.DataType.Double, aliasMovement_ContainerItem, prefixMovement_ContainerItem); columnDfn.NumDecimals = (byte)orderQuantityDecimals; break; case SbmMovement.Column.Container_Item_Status: SetMovementColDfn(columnDfn, "ContainerItem_Status", 100, SbmDbDfn.ColumnIdx.ContainerItem_Status, ColumnAlignment.Default, DataValue.DataType.Long, aliasMovement_ContainerItem, prefixMovement_ContainerItem); break; //--------------------------------------------------------------- // Joined 'From' Location columns. case SbmMovement.Column.LocationIdFrom: SetMovementColDfn(columnDfn, "From loc id", 70, SbmDbDfn.ColumnIdx.Movement_LocationIdFrom, ColumnAlignment.Center, DataValue.DataType.Long, aliasMovement_LocationFrom, prefixMovement_LocationFrom); break; case SbmMovement.Column.LocationFrom_CategoryDesc: SetMovementColDfn(columnDfn, "From location cat", 120, SbmDbDfn.ColumnIdx.Location_Category, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationFrom, prefixMovement_LocationFrom); break; case SbmMovement.Column.LocationFrom_Code: SetMovementColDfn(columnDfn, "From location code", 100, SbmDbDfn.ColumnIdx.Location_Code, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationFrom, prefixMovement_LocationFrom); break; case SbmMovement.Column.LocationFrom_Name: SetMovementColDfn(columnDfn, "From location", 160, SbmDbDfn.ColumnIdx.Location_Name, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationFrom, prefixMovement_LocationFrom); break; //--------------------------------------------------------------- // Joined 'To' Location columns. case SbmMovement.Column.LocationIdTo: SetMovementColDfn(columnDfn, "To loc id", 70, SbmDbDfn.ColumnIdx.Movement_LocationIdTo, ColumnAlignment.Center, DataValue.DataType.Long, aliasMovement_LocationTo, prefixMovement_LocationTo); break; case SbmMovement.Column.LocationTo_CategoryDesc: SetMovementColDfn(columnDfn, "To location cat", 120, SbmDbDfn.ColumnIdx.Location_Category, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationTo, prefixMovement_LocationTo); break; case SbmMovement.Column.LocationTo_Code: SetMovementColDfn(columnDfn, "To location code", 100, SbmDbDfn.ColumnIdx.Location_Code, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationTo, prefixMovement_LocationTo); break; case SbmMovement.Column.LocationTo_Name: SetMovementColDfn(columnDfn, "To location", 160, SbmDbDfn.ColumnIdx.Location_Name, ColumnAlignment.Center, DataValue.DataType.String, aliasMovement_LocationTo, prefixMovement_LocationTo); break; // Common properties. case SbmMovement.Column.Notes: SetMovementColDfn(columnDfn, "Notes", 200, SbmDbDfn.ColumnIdx.Movement_Notes); break; case SbmMovement.Column.Status: SetMovementColDfn(columnDfn, "Status", 50, SbmDbDfn.ColumnIdx.Movement_Status, ColumnAlignment.Center); break; case SbmMovement.Column.Status_Desc: SetMovementColDfn(columnDfn, "Status", 50, SbmDbDfn.ColumnIdx.Movement_Status, ColumnAlignment.Center); break; case SbmMovement.Column.Status_Ind: SetMovementColDfn(columnDfn, "Status", 50, SbmDbDfn.ColumnIdx.Movement_Status, ColumnAlignment.Center, DataValue.DataType.TriState); columnDfn.TriStateFormat = ColumnTriStateFormat.Lights; break; case SbmMovement.Column.CreateOn_Date: SetMovementColDfn(columnDfn, "Created", 65, SbmDbDfn.ColumnIdx.Movement_CreateOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.ReadOnly = true; break; case SbmMovement.Column.UpdateOn_Date: SetMovementColDfn(columnDfn, "Updated", 65, SbmDbDfn.ColumnIdx.Movement_UpdateOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.ReadOnly = true; break; } if (!String.IsNullOrEmpty(caption)) columnDfn.Caption = caption; if (width > 0) columnDfn.Width = width; return columnDfn; } //------------------------------------------------------------------- // Movement query filter. public override List GetMovementQueryFilter(SbmMovement.Params prm) { List filters = new List(); // Table Alias - if specified to this method, it implies that the corresponding table is already incorporated into the query e.g. as a join. String tableAlias_Commodity = ""; bool tableAvailable_Commodity = true; if (StringUtil.IsEmpty(tableAlias_Commodity)) { tableAlias_Commodity = "taMovCmd"; tableAvailable_Commodity = false; } String tableAlias_Container = ""; bool tableAvailable_Container = true; if (StringUtil.IsEmpty(tableAlias_Container)) { tableAlias_Container = "taMovCnt"; tableAvailable_Container = false; } String tableAlias_ContainerItem = ""; bool tableAvailable_ContainerItem = true; if (StringUtil.IsEmpty(tableAlias_ContainerItem)) { tableAlias_ContainerItem = "taMovCntItem"; tableAvailable_ContainerItem = false; } //Movement Id. String colMovement_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Id, aliasMovement); String includedIds = prm.IdsIncluded.Concat(","); if (!includedIds.IsEmpty()) filters.Add(colMovement_Id + " IN (" + includedIds + ")"); String excludedIds = prm.IdsExcluded.Concat(","); if (!excludedIds.IsEmpty()) filters.Add(colMovement_Id + " NOT IN (" + excludedIds + ")"); //--------------------------------------------------------------------- // Item. //String itemIds = prm.ItemIds.Concat(","); String itemIds = ""; if (prm.ItemIds != null) itemIds = prm.ItemIds.Concat(","); String colMovement_ItemType = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemType, aliasMovement); String colMovement_ItemId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId, aliasMovement); if (prm.ItemType != Sbm.ItemType.Unknown) filters.Add(colMovement_ItemType + "=" + ((int)prm.ItemType).ToString()); if (!itemIds.IsEmpty()) filters.Add(colMovement_ItemId + " IN (" + itemIds + ")"); //--------------------------------------------------------------------- // Container item. if (prm.ContainerItemType != Sbm.ItemType.Unknown && SysId.IsValid(prm.ContainerItemId)) { // Filter on container status. List filtersContainer = new List(); List statusesExclude = new List(); statusesExclude.Add(StatusDisabled); statusesExclude.Add(StatusCancelled); if (prm.ExcludeProvisionalContainers) statusesExclude.Add(StatusProvisional); filtersContainer.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Status, aliasMovement_Container) + " NOT IN(" + statusesExclude.Concat(",", "'", "'") + ")"); if (tableAvailable_Container) { filters.AddRange(filtersContainer); } else { // NOT YET IMPLEMENTED! } // Filter the container item. List filterContainerItem = new List(); filterContainerItem.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_ItemType, aliasMovement_ContainerItem) + "=" + ((int)prm.ContainerItemType).ToString()); filterContainerItem.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_ItemId, aliasMovement_ContainerItem) + "=" + prm.ContainerItemId.ToString()); filterContainerItem.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_Status, aliasMovement_ContainerItem) + "='" + StatusActive + "'"); // Sub query to identify (active) containers that reference the specified item: if (tableAvailable_ContainerItem) { // Container item table is already in the main query - filter directly: filters.AddRange(filterContainerItem); } else { // *** NOT TESTED beyond here! // Container item table is not in the main query - sub query is required: DbQuery qryContainer = new DbQuery(Database.DbmsType); qryContainer.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.ContainerItem), aliasMovement_ContainerItem); qryContainer.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Id, aliasMovement_Container)); qryContainer.Filters.AddRange(filterContainerItem); if (tableAvailable_Container) { // Container table is in main query - can restrict sub query directly against this instance: filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Id, aliasMovement_Container) + " IN (" + qryContainer.BuildQuery() + ")"); } else { // Container table is not in main query - it must be added to the sub-query: qryContainer.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Container), aliasMovement_Container); qryContainer.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Id, aliasMovement_Container) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_ContainerId, aliasMovement_ContainerItem)); qryContainer.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Status, aliasMovement_Container) + "='" + StatusActive + "'"); // Restrict movements to these containers: filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemType, aliasMovement) + "=" + ((int)Sbm.ItemType.Container).ToString()); filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId, aliasMovement) + " IN (" + qryContainer.BuildQuery() + ")"); } } } //--------------------------------------------------------------------- // Type. String colMovement_Type = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Type, aliasMovement); if (prm.MovementType > 0) filters.Add(colMovement_Type + "=" + ((int)prm.MovementType).ToString()); //--------------------------------------------------------------------- // Movement date. String colMovement_MovementDate = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Movement, aliasMovement); if (DateUtil.IsValid(prm.MovementFrom)) filters.Add(colMovement_MovementDate + ">=" + DbQuery.FormatDateForCondition(prm.MovementFrom)); if (DateUtil.IsValid(prm.MovementTo)) filters.Add(colMovement_MovementDate + "<" + DbQuery.FormatDateForCondition(DateUtil.IncrementDate(prm.MovementTo, 1))); //--------------------------------------------------------------------- // Locations. String colMovement_LocationIdFrom = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdFrom, aliasMovement); String colMovement_LocationIdTo = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdTo, aliasMovement); if (SysId.IsValid(prm.LocationId)) filters.Add(colMovement_LocationIdFrom + "=" + prm.LocationId.ToString() + " OR " + colMovement_LocationIdTo + "=" + prm.LocationId.ToString()); else { if (SysId.IsValid(prm.LocationIdFrom)) filters.Add(colMovement_LocationIdFrom + "=" + prm.LocationIdFrom.ToString()); if (SysId.IsValid(prm.LocationIdTo)) filters.Add(colMovement_LocationIdTo + "=" + prm.LocationIdTo.ToString()); } if (prm.RestrictToSalesStockLocations) { // Build list of 'Sales Stock' locations. Include invalid value '-1' in the list incase there are no 'Sales Stock' locations. PopulateLocationIds(); filters.Add(colMovement_LocationIdFrom + " IN (-1" + locationIds_Sales.Concat(",") + ") OR " + colMovement_LocationIdTo + " IN (-1" + locationIds_Sales.Concat(",") + ")"); } if (prm.RestrictToCalculateStockLocations) { // Build list of 'Calculate Stock' locations. Include invalid value '-1' in the list incase there are no 'Calculate Stock' locations. PopulateLocationIds(); filters.Add(colMovement_LocationIdFrom + " IN (-1" + locationIds_Calc.Concat(",") + ") OR " + colMovement_LocationIdTo + " IN (-1" + locationIds_Calc.Concat(",") + ")"); } //--------------------------------------------------------------------- // Source Movement. String colMovement_MovementIdSource = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_MovementIdSource, aliasMovement); if (SysId.IsValid(prm.MovementIdSource)) filters.Add(colMovement_MovementIdSource + "=" + prm.MovementIdSource.ToString()); //--------------------------------------------------------------------- // Source Item. //String sourceItemIds = prm.ItemIdSource.Concat(","); String sourceItemIds = ""; if (prm.ItemIdSource != null) sourceItemIds = prm.ItemIdSource.Concat(","); String colMovement_ItemTypeSource = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemTypeSource, aliasMovement); String colMovement_ItemIdSource = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemIdSource, aliasMovement); if (prm.IncludeRequirementsForTransactions && prm.ItemTypeSource == Sbm.ItemType.Transaction && !sourceItemIds.IsEmpty() && TransactionMgr != null) { // Performance of querying requirements for transaction(s) within movement query is very poor - eg. ItemIdSource in (Select Id From Requirement Where TransactionId in (1,2,3)). // Get list of requirement Ids first and then explicitly query against these in the movement query. SbmTransaction.Params prmTrans = new SbmTransaction.Params(); prmTrans.IdsIncluded.UnionWith(prm.ItemIdSource); List requirementId = TransactionMgr.GetRequirementIds(prmTrans); // Movements can be matched: either directly to one of the transactions or to any of their associated requirements. List filtersTrans = new List(); List filtersReqnt = new List(); filtersTrans.Add(colMovement_ItemTypeSource + "=" + ((int)prm.ItemTypeSource).ToString()); filtersTrans.Add(colMovement_ItemIdSource + " IN (" + sourceItemIds + ")"); String filter = "(" + filtersTrans.Concat(" AND ", "(", ")") + ")"; if (!StringUtil.IsEmpty(requirementId.ToString())) { // Include any movements for requirements associated with the listed transactions. //String sTblAliasReq("taMTA"); //SaDbQuery qryReq; //qryReq.lTable.Add(SbmDbDfn.GetTableName(eSaDbTblRequirement),sTblAliasReq); //qryReq.lColumn.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_Id,sTblAliasReq)); //qryReq.filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Requirement_TransId,sTblAliasReq)+" IN ("+sSourceItemIds+")"); // Query against the list of requirements for the specified transactions. filtersReqnt.Add(colMovement_ItemTypeSource + "=" + ((int)Sbm.ItemType.Requirement).ToString()); filtersReqnt.Add(colMovement_ItemIdSource + " IN (" + requirementId.Concat(",") + ")"); filter = "(" + filter + " OR (" + filtersReqnt.Concat(" AND ", "(", ")") + "))"; } filters.Add(filter); } else { if (prm.ItemTypeSource != Sbm.ItemType.Unknown) filters.Add(colMovement_ItemTypeSource + "=" + ((int)prm.ItemTypeSource).ToString()); if (!sourceItemIds.IsEmpty()) filters.Add(colMovement_ItemIdSource + " IN (" + sourceItemIds + ")"); } //--------------------------------------------------------------------- // Movement status. String colMovement_Status = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Status, aliasMovement); if (prm.Status > 0) { filters.Add(colMovement_Status + "='" + SacsSystem.GetStatusCode(prm.Status) + "'"); } if (filters.Count < 1) filters.Add("1=1"); return filters; } //------------------------------------------------------------------- // Movement sort columns. public List GetMovementSortColumns(SbmMovement.Params prm) { // Sort sequence: List sortColumnNames = new List(); foreach (var columnDfn in prm.SortColumns) { // Need to ensure correct alias used for Movement columns in case of conflict. String sortCol = String.Empty; if (SbmDbDfn.GetTableForColumn((SbmDbDfn.ColumnIdx)columnDfn.DbColumn) == SbmDbDfn.TableIdx.Movement) { sortCol = SbmDbDfn.GetColumnNameQual((SbmDbDfn.ColumnIdx)columnDfn.DbColumn, aliasMovement); } else { sortCol = columnDfn.DataName; if (!StringUtil.IsEmpty(columnDfn.SortDataName)) sortCol = columnDfn.SortDataName; } if (!sortCol.IsEmpty()) { DbOrderByNullMode orderByNullMode = DbOrderByNullMode.Default; // eSaOrderByDemoteNulls, eSaOrderByPromoteNulls sortColumnNames.Add(DbQuery.FormatForOrderBy(sortCol, columnDfn.SortAscending, orderByNullMode).Concat(", ")); } } sortColumnNames.RemoveBlanks(); if (sortColumnNames.IsEmpty()) { // Default sort columns: sortColumnNames.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Type, aliasMovement) + " ASC"); } return sortColumnNames; } //------------------------------------------------------------------- // Movement count. private long GetMovementCount(String filter) { ClearErrorState(); return Database.GetRowCount(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement) + " As " + aliasMovement, filter); } public override long GetMovementCount(SbmMovement.Params prm) { ClearErrorState(); return GetMovementCount(GetMovementQueryFilter(prm).Concat(" AND ", "(", ")")); } //------------------------------------------------------------------- // Movement list. public override List GetMovementList(SbmMovement.Params prm) { ClearErrorState(); List movements = new List(); DbQuery DbQuery = new DbQuery(Database.DbmsType); DbQuery.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement), aliasMovement); Movement_Db dbMovement = new Movement_Db(DbInfo); DbQuery.Columns.AddRange(dbMovement.ExistingColumnNames); DbQuery.Filters.AddRange(GetMovementQueryFilter(prm)); DbQuery.OrderBy.AddRange(GetMovementSortColumns(prm)); // Query data. using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); dbCommand.CommandText = DbQuery.BuildQuery(prm.ResultsPaging); using (DbDataReader dbDataReader = dbCommand.ExecuteReader()) { while (dbDataReader.Read()) { dbMovement = new Movement_Db(DbInfo); dbMovement.PopulateFrom(dbDataReader); movements.Add(CreateMovement(dbMovement)); } } } catch (Exception exc) { SetErrorState("Database query exception"); SaLogger.Warn($"{SysUtil.Fn}\n\tQuery: {dbCommand.CommandText}\n\t{ExceptionUtil.GetErrorStateMessage(exc)}"); } } return movements; } //------------------------------------------------------------------- // Movement query execution. public override DbResultSet ExecuteMovementQuery(List columns, SbmMovement.Params prm) { ClearErrorState(); //--------------------------------------------------------------- // Construct query. DbQuery query = new DbQuery(Database.DbmsType); query.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Movement), aliasMovement); //--------------------------------------------------------------- // Movement Properties - add columns as defined in query list. query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Id, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemType, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Type, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdFrom, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdTo, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Movement, aliasMovement)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Quantity, aliasMovement)); if (columns.HasId((int)SbmMovement.Column.MovementIdSource)) query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_MovementIdSource)); if (columns.HasId((int)SbmMovement.Column.SourceItemType) || columns.HasId((int)SbmMovement.Column.SourceItemId) || columns.HasId((int)SbmMovement.Column.SourceItem)) { query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemTypeSource)); query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemIdSource)); } if (columns.HasId((int)SbmMovement.Column.Notes)) query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Notes, aliasMovement)); if (columns.HasId((int)SbmMovement.Column.Status) || columns.HasId((int)SbmMovement.Column.Status_Desc) || columns.HasId((int)SbmMovement.Column.Status_Ind)) query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_Status, aliasMovement)); if (columns.HasId((int)SbmMovement.Column.CreateOn_Date)) query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_CreateOn, aliasMovement)); if (columns.HasId((int)SbmMovement.Column.UpdateOn_Date)) query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_UpdateOn, aliasMovement)); //--------------------------------------------------------------------- // Commodity join. bool commodityTableRequired = columns.HasId((int)SbmMovement.Column.Commodity_Code); if (!commodityTableRequired) commodityTableRequired = columns.HasId((int)SbmMovement.Column.Commodity_DescBrief); if (commodityTableRequired && (prm.ItemType == Sbm.ItemType.Commodity || prm.ItemTypeSource == Sbm.ItemType.Transaction)) { // Join to the Commodity. DbQueryJoin joinCmd = new DbQueryJoin(DbJoinType.LeftOuter); joinCmd.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Commodity), aliasMovement_Commodity); joinCmd.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Commodity_Id, aliasMovement_Commodity) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId)); query.Joins.Add(joinCmd); // Commodity columns. List commodityCols = new List() { SbmDbDfn.ColumnIdx.Commodity_Code, SbmDbDfn.ColumnIdx.Commodity_DescBrief }; foreach (SbmDbDfn.ColumnIdx dbColumn in commodityCols) query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasMovement_Commodity), prefixMovement_Commodity + SbmDbDfn.GetColumnName(dbColumn, false)); } //--------------------------------------------------------------------- // Container join bool containerTableRequired = columns.HasId((int)SbmMovement.Column.Container_Reference); if (!containerTableRequired) containerTableRequired = columns.HasId((int)SbmMovement.Column.Container_DescBrief); if (!containerTableRequired) containerTableRequired = columns.HasId((int)SbmMovement.Column.Container_TagId); if (!containerTableRequired) containerTableRequired = columns.HasId((int)SbmMovement.Column.Container_Notes); if (!containerTableRequired) containerTableRequired = columns.HasId((int)SbmMovement.Column.Container_Status); if (containerTableRequired && prm.ItemType == Sbm.ItemType.Container) { // Join to the container. DbQueryJoin joinCnt = new DbQueryJoin(DbJoinType.LeftOuter); joinCnt.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Container), aliasMovement_Container); joinCnt.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Id, aliasMovement_Container) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId)); query.Joins.Add(joinCnt); // Container columns. List containerCols = new List(); //containerCols.Add(SbmDbDfn.ColumnIdx.Container_Category); //containerCols.Add(SbmDbDfn.ColumnIdx.Container_Type); if (columns.HasId((int)SbmMovement.Column.Container_Reference)) containerCols.Add(SbmDbDfn.ColumnIdx.Container_Reference); if (columns.HasId((int)SbmMovement.Column.Container_DescBrief)) containerCols.Add(SbmDbDfn.ColumnIdx.Container_DescBrief); if (columns.HasId((int)SbmMovement.Column.Container_TagId)) containerCols.Add(SbmDbDfn.ColumnIdx.Container_TagId); if (columns.HasId((int)SbmMovement.Column.Container_Notes)) containerCols.Add(SbmDbDfn.ColumnIdx.Container_Notes); if (columns.HasId((int)SbmMovement.Column.Container_Status)) containerCols.Add(SbmDbDfn.ColumnIdx.Container_Status); foreach (SbmDbDfn.ColumnIdx dbColumn in containerCols) query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasMovement_Container), prefixMovement_Container + SbmDbDfn.GetColumnName(dbColumn, false)); /*else {#if _DEBUG return SaProcessMessage("GetQueryFilter Container tables referenced and not available"); #endif}*/ } //--------------------------------------------------------------------- // Container item join. bool containerItemTableRequired = columns.HasId((int)SbmMovement.Column.Container_Item_ItemType); if (!containerItemTableRequired) containerItemTableRequired = columns.HasId((int)SbmMovement.Column.Container_Item_ItemId); if (!containerItemTableRequired) containerItemTableRequired = columns.HasId((int)SbmMovement.Column.Container_Item_Quantity); if (!containerItemTableRequired) containerItemTableRequired = columns.HasId((int)SbmMovement.Column.Container_Item_Status); // Join to the container. DbQueryJoin joinItm = new DbQueryJoin(DbJoinType.LeftOuter); joinItm.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.ContainerItem), aliasMovement_ContainerItem); // Items can be joined to their corresponding container if it is present in the query. if (containerTableRequired) joinItm.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_ContainerId, aliasMovement_ContainerItem) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Container_Id, aliasMovement_Container)); else // Otherwise, they must be joined to the movement itself. joinItm.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.ContainerItem_ContainerId, aliasMovement_ContainerItem) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_ItemId)); query.Joins.Add(joinItm); // Container item columns. List containerItemCols = new List(); if (columns.HasId((int)SbmMovement.Column.Container_Item_ItemType)) containerItemCols.Add(SbmDbDfn.ColumnIdx.ContainerItem_ItemType); if (columns.HasId((int)SbmMovement.Column.Container_Item_ItemId)) containerItemCols.Add(SbmDbDfn.ColumnIdx.ContainerItem_ItemId); if (columns.HasId((int)SbmMovement.Column.Container_Item_Quantity)) containerItemCols.Add(SbmDbDfn.ColumnIdx.ContainerItem_Quantity); if (columns.HasId((int)SbmMovement.Column.Container_Item_Status)) containerItemCols.Add(SbmDbDfn.ColumnIdx.ContainerItem_Status); foreach (SbmDbDfn.ColumnIdx dbColumn in containerItemCols) query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasMovement_ContainerItem), prefixMovement_ContainerItem + SbmDbDfn.GetColumnName(dbColumn, false)); /*else {#if _DEBUG return SaProcessMessage("GetQueryFilter Container tables referenced and not available"); #endif}*/ //--------------------------------------------------------------------- // From Location join. bool locationFromTableRequired = columns.HasId((int)SbmMovement.Column.LocationFrom_CategoryDesc); if (!locationFromTableRequired) locationFromTableRequired = columns.HasId((int)SbmMovement.Column.LocationFrom_Code); if (!locationFromTableRequired) locationFromTableRequired = columns.HasId((int)SbmMovement.Column.LocationFrom_Name); if (locationFromTableRequired) { // Join to the 'From' Location. DbQueryJoin joinLocFrom = new DbQueryJoin(DbJoinType.LeftOuter); joinLocFrom.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Location), aliasMovement_LocationFrom); joinLocFrom.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Location_Id, aliasMovement_LocationFrom) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdFrom)); query.Joins.Add(joinLocFrom); // LocationFrom columns. List locationFromCols = new List() { SbmDbDfn.ColumnIdx.Location_Category, SbmDbDfn.ColumnIdx.Location_Code, SbmDbDfn.ColumnIdx.Location_Name }; foreach (SbmDbDfn.ColumnIdx dbColumn in locationFromCols) query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasMovement_LocationFrom), prefixMovement_LocationFrom + SbmDbDfn.GetColumnName(dbColumn, false)); } //--------------------------------------------------------------------- // To Location join. bool locationToTableRequired = columns.HasId((int)SbmMovement.Column.LocationTo_CategoryDesc); if (!locationToTableRequired) locationToTableRequired = columns.HasId((int)SbmMovement.Column.LocationTo_Code); if (!locationToTableRequired) locationToTableRequired = columns.HasId((int)SbmMovement.Column.LocationTo_Name); if (locationToTableRequired) { // Join to the 'To' Location. DbQueryJoin joinLocTo = new DbQueryJoin(DbJoinType.LeftOuter); joinLocTo.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Location), aliasMovement_LocationTo); joinLocTo.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Location_Id, aliasMovement_LocationTo) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Movement_LocationIdTo)); query.Joins.Add(joinLocTo); // LocationTo columns. List locationToCols = new List() { SbmDbDfn.ColumnIdx.Location_Category, SbmDbDfn.ColumnIdx.Location_Code, SbmDbDfn.ColumnIdx.Location_Name }; foreach (SbmDbDfn.ColumnIdx dbColumn in locationToCols) query.Columns.Add(SbmDbDfn.GetColumnNameQual(dbColumn, aliasMovement_LocationTo), prefixMovement_LocationTo + SbmDbDfn.GetColumnName(dbColumn, false)); } // ToDo copy&paste Sap code to Sbm code for sorting out the filter with other table? //--------------------------------------------------------------- // Populate filter. query.Filters.AddRange(GetMovementQueryFilter(prm)); if (prm.IdsIncluded.Count != 1) { // Configure sort sequence. foreach (String sortColumn in GetMovementSortColumns(prm)) query.OrderBy.Add(sortColumn); } //--------------------------------------------------------------- //return new DbResultSet_DataTableReader(Database, query.BuildQuery()); return DbResultSet_DataReader.ExecuteQuery(Database, query.BuildQuery(prm.ResultsPaging)); } //------------------------------------------------------------------- } //======================================================================= }