using com.sun.org.glassfish.external.statistics; using Comal.Classes; using InABox.Configuration; using InABox.Core; using InABox.Database.Stores; using InABox.Scripting; using PRSStores; using System; namespace Comal.Stores; internal class BillStore : BaseStore { protected override void BeforeSave(Bill entity) { base.BeforeSave(entity); if(entity.HasOriginalValue(x => x.Number) || entity.SupplierLink.HasOriginalValue(x => x.ID)) { var existing = Provider.Query( new Filter(x => x.Number).IsEqualTo(entity.Number) .And(x => x.SupplierLink.ID).IsEqualTo(entity.SupplierLink.ID) .And(x => x.ID).IsNotEqualTo(entity.ID), Columns.None().Add(x => x.ID)); if(existing.Rows.Count > 0) { throw new DuplicateCodeException(typeof(Bill), new Dictionary {{ nameof(Bill.Number), entity.Number }}); } } if (entity.ID == Guid.Empty) { var defaultApprovalSet = Provider.Query( new Filter(x => x.IsDefault).IsEqualTo(true), Columns.None().Add(x => x.ID)) .ToObjects().FirstOrDefault(); if (defaultApprovalSet is not null) { entity.ApprovalSet.ID = defaultApprovalSet.ID; } } //UpdateAggregate(entity, entity.SupplierLink, Sum(b => b.Balance, s => s.Balance)); } private void ClearBillApprovals(Bill bill) { // We need to clear all automatic bill approvals. var approvals = Provider.Query( new Filter(x => x.Bill.ID).IsEqualTo(bill.ID) .And(x => x.IsCustom).IsEqualTo(false), Columns.Required().Add(x => x.ID)) .ToList(); Provider.Delete(approvals, UserID); } private void UpdateBillApprovals(Bill bill) { if (bill.ID == Guid.Empty) return; if(bill.ApprovalSet.ID == Guid.Empty) { ClearBillApprovals(bill); return; } var setEmployees = Provider.Query( new Filter(x => x.ApprovalSet.ID).IsEqualTo(bill.ApprovalSet.ID), Columns.None().Add(x => x.Employee.ID), new SortOrder(x => x.Sequence)) .ToArray(); var approvals = Provider.Query( new Filter(x => x.Bill.ID).IsEqualTo(bill.ID), Columns.Required().Add(x => x.Employee.ID).Add(x => x.IsCustom).Add(x => x.Approved)) .ToList(); try { var customApprovals = new List(); foreach(var approval in approvals) { if (approval.IsCustom) { customApprovals.Add(approval); } else { if(approval.Approved != DateTime.MinValue) { // These really are custom approvals for our purposes, since they've been modified. customApprovals.Add(approval); } } } // Build up the automatic list. var autoApprovals = new List(); foreach(var employee in setEmployees) { var approval = new BillApproval(); approval.Employee.CopyFrom(employee.Employee); approval.IsCustom = false; autoApprovals.Add(approval); } if(BillApprovalSetStore.GetUpdateApprovalsScript(bill.ApprovalSet.ID) is ScriptDocument script) { script.Execute(methodname: BillApprovalSet.UpdateBillApprovalsMethodName, parameters: [bill, autoApprovals]); } // Now, we have to merge the custom and auto lists, only saving auto approvals if there are no custom ones for that employee. var toAdd = new List(); var toRemove = new List(); var newList = customApprovals.ToList(); foreach(var approval in autoApprovals) { newList.Add(approval); if (!approvals.Any(x => x.Employee.ID == approval.Employee.ID)) { toAdd.Add(approval); } } foreach(var approval in approvals) { if (!newList.Any(x => x.Employee.ID == approval.Employee.ID)) { toRemove.Add(approval); } } foreach(var approval in toAdd) { approval.Bill.ID = bill.ID; } Provider.Save(toAdd); Provider.Delete(toRemove, UserID); } catch(Exception e) { CoreUtils.LogException(UserID, e, "Error running bill approval script"); } } protected override void AfterSave(Bill entity) { base.AfterSave(entity); UpdateBillApprovals(entity); } protected override void BeforeDelete(Bill entity) { base.BeforeDelete(entity); entity.SupplierLink.ID = Guid.Empty; //UpdateAggregate(entity, entity.SupplierLink, Sum(b => b.Balance, s => s.Balance)); } }