using Comal.Classes; using Comal.Stores; using InABox.Core; using InABox.Database; using PRSStores; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static ICSharpCode.AvalonEdit.Document.TextDocumentWeakEventManager; namespace PRS.Shared; public class Update_7_52 : DatabaseUpdateScript { public override VersionNumber Version => new VersionNumber(7, 52); private IStore? _store; private IStore Store { get { _store ??= DbFactory.FindStore(Guid.Empty, "", Platform.Server, CoreUtils.GetVersion()); return _store; } } private static void UpdateStockMovements() { var jobRequiItems = DbFactory.Provider.Query( new Filter(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null), new Columns(x => x.ID) .Add(x => x.PurchaseOrderItem.ID)) .ToObjects() .ToList(); var mvts = DbFactory.Provider.Query( new Filter(x => x.JobRequisitionItem.ID).IsEqualTo(null) .And(x => x.OrderItem.ID).IsNotEqualTo(null) .And(new Filter(x => x.OrderItem.ID).InQuery(null, x => x.PurchaseOrderItem.ID) .Or(x => x.OrderItem.ID).InQuery(null, x => x.PurchaseOrderItem.ID)), new Columns(x => x.ID) .Add(x => x.OrderItem.ID)) .ToObjects() .ToList(); Logger.Send(LogType.Information, "", $"Updating JobRequisitionItem.ID for {mvts.Count} StockMovements"); var orderItemIDs = mvts.Select(x => x.OrderItem.ID).ToArray(); var jriPois = DbFactory.Provider.Query( new Filter(x => x.PurchaseOrderItem.ID).InList(orderItemIDs), new Columns(x => x.JobRequisitionItem.ID).Add(x => x.PurchaseOrderItem.ID)) .ToObjects(); var jris = DbFactory.Provider.Query( new Filter(x => x.PurchaseOrderItem.ID).InList(orderItemIDs), new Columns(x => x.ID).Add(x => x.PurchaseOrderItem.ID)) .ToObjects(); var requiIDs = new Dictionary(); foreach(var jriPoi in jriPois) { requiIDs.TryAdd(jriPoi.PurchaseOrderItem.ID, jriPoi.JobRequisitionItem.ID); } foreach (var jriPoi in jris) { requiIDs.TryAdd(jriPoi.PurchaseOrderItem.ID, jriPoi.ID); } foreach(var mvt in mvts) { if(requiIDs.TryGetValue(mvt.OrderItem.ID, out var requiItemID)) { mvt.JobRequisitionItem.ID = requiItemID; } else { Logger.Send(LogType.Error, "", $"StockMovement which didn't have an associated JobRequisitionItem: {mvt.ID}"); } } var changed = mvts.Where(x => x.IsChanged()).ToList(); // Not going through the store otherwise the JobRequisitionItem Status will be updated incorrectly. DbFactory.Provider.Save(changed); Logger.Send(LogType.Information, "", $"Updated {changed.Count} StockMovements"); } private void UpdateOrderStatus() { var jobRequiItems = DbFactory.Provider.Query( new Filter(x => x.OrderRequired).IsEqualTo(DateTime.MinValue) .And(new Filter(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OrderRequired) .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OnOrder) .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.Received)), new Columns(x => x.ID) .Add(x => x.LastUpdate)) .ToObjects() .ToList(); foreach (var jri in jobRequiItems) { jri.OrderRequired = jri.LastUpdate; } DbFactory.Provider.Save(jobRequiItems); } private void CreateJobRequisitionItemPurchaseOrderItems() { var jobRequiItems = DbFactory.Provider.Query( new Filter(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null) .And(x => x.ID).NotInQuery( null, x => x.JobRequisitionItem.ID), new Columns(x => x.ID) .Add(x => x.PurchaseOrderItem.ID) .Add(x => x.Status)) .ToObjects() .ToList(); Logger.Send(LogType.Information, "", $"Creating JobRequisitionPurchaseOrderItems for {jobRequiItems.Count} JobRequisitionItems"); var newJRIPois = new List(); foreach (var jri in jobRequiItems) { var jriPoi = new JobRequisitionItemPurchaseOrderItem(); jriPoi.JobRequisitionItem.ID = jri.ID; jriPoi.PurchaseOrderItem.ID = jri.PurchaseOrderItem.ID; newJRIPois.Add(jriPoi); } DbFactory.Provider.Save(newJRIPois); DbFactory.Provider.Save(jobRequiItems); } private void RefreshStatuses() { Logger.Send(LogType.Information, "", $"Refreshing JobRequisitionItem statuses"); var jobRequiItems = DbFactory.Provider.Query( null, JobRequisitionItemStore.StatusRequiredColumns().Add(x => x.Status)) .ToObjects() .ToList(); var statusUpdates = new Dictionary, List>(); var i = 0; foreach(var item in jobRequiItems) { if(i % 50 == 0) { Logger.Send(LogType.Information, "", $"Refreshing statuses: {(((double)i) / (double)jobRequiItems.Count * 100):F0}%"); } if (JobRequisitionItemStore.CalculateStatus(Store, item)) { var key = new Tuple(item.GetOriginalValue(x=>x.Status), item.Status); if(!statusUpdates.TryGetValue(key, out var list)) { list = new List(); statusUpdates.Add(key, list); } list.Add(item.ID); item.Issues += $"Updated status from {item.GetOriginalValue(x=>x.Status)} to {item.Status}"; } ++i; } foreach(var ((from, to), list) in statusUpdates) { Logger.Send(LogType.Information, "", $"{from} -> {to}: {list.Count} entries"); } new BaseStore { UserGuid = Guid.Empty, UserID = "", Platform = Platform.Server, Version = CoreUtils.GetVersion(), Provider = DbFactory.Provider }.Save(jobRequiItems, ""); } public override bool Update() { UpdateStockMovements(); UpdateOrderStatus(); CreateJobRequisitionItemPurchaseOrderItems(); RefreshStatuses(); return true; } }