123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Core;
- using InABox.DynamicGrid;
- using PRSDesktop.Panels.Invoices;
- using Syncfusion.Windows.Shared;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Forms;
- using System.Windows.Media;
- namespace PRSDesktop;
- public class ProgressClaim : BaseObject
- {
- public JobScopeLink JobScope { get; set; }
- [CurrencyEditor(Editable = Editable.Disabled, Summary = Summary.Sum)]
- public double Materials { get; set; }
- [CurrencyEditor(Editable = Editable.Disabled, Summary = Summary.Sum)]
- public double Labour { get; set; }
- [DoubleEditor(Editable = Editable.Disabled,Summary = Summary.Sum)]
- public double PreviouslyClaimed { get; set; }
- [DoubleEditor(Editable = Editable.Disabled)]
- public double PreviouslyClaimedPercent { get; set; }
- [DoubleEditor(Editable = Editable.Enabled)]
- public double PercentCost { get; set; }
- [DoubleEditor(Editable = Editable.Disabled,Summary = Summary.Sum)]
- public double Cost { get; set; }
- }
- public class ProgressClaimGrid : DynamicItemsListGrid<ProgressClaim>
- {
- private DynamicGridCustomColumnsComponent<ProgressClaim> ColumnsComponent;
- public Guid JobID { get; set; }
-
- public Guid InvoiceID { get; set; }
-
- public double ProjectContract { get; private set; }
- public double ProjectVariations { get; private set; }
- public double ProjectSubTotal { get; private set; }
- public double ProjectRetention { get; private set; }
- public double ProjectRetentionPercent { get; private set; }
- public double ProjectTotal { get; private set; }
-
- public double CompletedContract { get; private set; }
- public double CompletedContractPercent { get; private set; }
- public double CompletedVariations { get; private set; }
- public double CompletedVariationsPercent { get; private set; }
- public double CompletedSubTotal { get; private set; }
- public double CompletedSubTotalPercent { get; private set; }
- public double CompletedRetention { get; private set; }
- public double CompletedRetentionPercent { get; private set; }
- public double CompletedTotal { get; private set; }
- public double CompletedTotalPercent { get; private set; }
-
- public double PreviousContract { get; private set; }
- public double PreviousContractPercent { get; private set; }
- public double PreviousVariations { get; private set; }
- public double PreviousVariationsPercent { get; private set; }
- public double PreviousSubTotal { get; private set; }
- public double PreviousSubTotalPercent { get; private set; }
- public double PreviousRetention { get; private set; }
- public double PreviousRetentionPercent { get; private set; }
- public double PreviousTotal { get; private set; }
- public double PreviousTotalPercent { get; private set; }
-
- public double CurrentContract { get; private set; }
- public double CurrentContractPercent { get; private set; }
- public double CurrentVariations { get; private set; }
- public double CurrentVariationsPercent { get; private set; }
- public double CurrentSubTotal { get; private set; }
- public double CurrentSubTotalPercent { get; private set; }
- public double CurrentRetention { get; private set; }
- public double CurrentRetentionPercent { get; private set; }
- public double CurrentTotal { get; private set; }
- public double CurrentTotalPercent { get; private set; }
- protected override void Init()
- {
- base.Init();
- ColumnsComponent = new(this, nameof(ProgressClaimGrid));
- }
- protected override void DoReconfigure(DynamicGridOptions options)
- {
- base.DoReconfigure(options);
- options.SelectColumns = false;
- }
- private Job Job;
- private JobScope[] Scopes;
- private Invoice[] Invoices;
- private Invoice Invoice;
- private List<InvoiceLine> InvoiceLines;
-
- private bool _loadedData = false;
- private void LoadData()
- {
- var columns =
- Columns.None<JobScope>()
- .Add(x => x.ID)
- .Add(x => x.Number)
- .Add(x => x.ExTax)
- .Add(x => x.InvoiceExTax)
- .Add(x => x.TaxCode.ID)
- .Add(x => x.TaxCode.Rate)
- .Add(x=>x.Tax)
- .Add(x => x.Description)
- .Add(x => x.MaterialsExTax)
- .Add(x => x.Job.DefaultScope.ID)
- .Add(x=>x.Type);
- var scopeColumn = new Column<ProgressClaim>(x => x.JobScope).Property + ".";
- foreach(var column in DataColumns().Where(x => x.Property.StartsWith(scopeColumn)))
- {
- columns.Add(column.Property[scopeColumn.Length..]);
- }
- MultiQuery query = new MultiQuery();
-
- query.Add(
- new Filter<Job>(x=>x.ID).IsEqualTo(JobID),
- Columns.None<Job>()
- .Add(x => x.ID)
- .Add(x=>x.Retention.Maximum)
- .Add(x=>x.Retention.Rate)
- .Add(x=>x.Retention.IncludeVariations)
- );
-
- query.Add(
- new Filter<JobScope>(x => x.Job.ID).IsEqualTo(JobID)
- .And(x => x.Status.Approved).IsEqualTo(true),
- columns);
-
- query.Add(
- new Filter<Assignment>(x => x.JobLink.ID).IsEqualTo(JobID),
- Columns.None<Assignment>().Add(x => x.JobScope.ID)
- .Add(x => x.Actual.Duration)
- .Add(x => x.EmployeeLink.HourlyRate));
- query.Add(
- new Filter<Invoice>(x=>x.JobLink.ID).IsEqualTo(JobID),
- Columns.None<Invoice>().Add(x => x.ID).Add(x => x.Retained));
-
- if (InvoiceID != Guid.Empty)
- query.Add(
- new Filter<InvoiceLine>(x=>x.InvoiceLink.ID).IsEqualTo(InvoiceID),
- Columns.None<InvoiceLine>()
- .Add(x => x.ID)
- .Add(x => x.Scope.ID)
- .Add(x => x.ExTax));
-
- query.Query();
- Job = query.Get<Job>().ToObjects<Job>().FirstOrDefault() ?? new Job();
- Scopes = query.Get<JobScope>().ToArray<JobScope>();
- var assignments = query.Get<Assignment>().ToObjects<Assignment>()
- .GroupBy(x => x.JobScope.ID)
- .ToDictionary(x => x.Key, x => x.Sum(x => x.Actual.Duration.TotalHours * x.EmployeeLink.HourlyRate));
- Invoices = query.Get<Invoice>().ToArray<Invoice>();
-
- Invoice = Invoices.FirstOrDefault(x => x.ID == InvoiceID) ?? new Invoice();
-
- InvoiceLines = InvoiceID != Guid.Empty
- ? query.Get<InvoiceLine>().ToObjects<InvoiceLine>().ToList()
- : new List<InvoiceLine>();
-
-
- var items = new List<ProgressClaim>();
- foreach(var scope in Scopes)
- {
- var newItem = new ProgressClaim();
- newItem.JobScope.CopyFrom(scope);
-
- var invoiceline = InvoiceLines.FirstOrDefault(x =>
- x.Scope.ID == scope.ID || (x.Scope.ID == Guid.Empty && scope.ID == scope.Job.DefaultScope.ID));
- if (invoiceline != null)
- {
- newItem.PreviouslyClaimed = scope.InvoiceExTax - invoiceline.ExTax;
- newItem.PreviouslyClaimedPercent = scope.ExTax.IsEffectivelyEqual(0.0) ? 0.0 : (scope.InvoiceExTax - invoiceline.ExTax) / scope.ExTax * 100;
- newItem.PercentCost = scope.ExTax.IsEffectivelyEqual(0.0) ? 0.0 : scope.InvoiceExTax / scope.ExTax * 100;
- newItem.Cost = invoiceline.ExTax;
- }
- else
- {
- newItem.PreviouslyClaimed = scope.InvoiceExTax;
- newItem.PreviouslyClaimedPercent = scope.ExTax.IsEffectivelyEqual(0.0) ? 0.0 : scope.InvoiceExTax / scope.ExTax * 100;
- newItem.PercentCost = newItem.PreviouslyClaimedPercent;
- newItem.Cost = 0;
- }
- newItem.Materials = scope.MaterialsExTax;
- newItem.Labour = assignments.GetValueOrDefault(scope.ID);
-
- items.Add(newItem);
- }
- Items = items;
- CalculateTotals();
-
- _loadedData = true;
- }
- protected override void Changed()
- {
- base.Changed();
- CalculateTotals();
- }
- private void CalculateTotals()
- {
- Guid[] contractscopeids = Scopes.Where(x => x.Type == JobScopeType.Contract).Select(x => x.ID).ToArray();
- Guid[] variationscopeids = Scopes.Where(x => x.Type != JobScopeType.Contract).Select(x => x.ID).ToArray();
-
- ProjectContract = Items.Where(x => contractscopeids.Contains(x.JobScope.ID)).Sum(x => x.JobScope.ExTax);
-
- PreviousContract = Items.Where(x => contractscopeids.Contains(x.JobScope.ID)).Sum(x => x.PreviouslyClaimed);
- PreviousContractPercent = ProjectContract.IsEffectivelyEqual(0.0)
- ? 0.0
- : PreviousContract * 100.0 / ProjectContract;
-
- CurrentContract = Items.Where(x => contractscopeids.Contains(x.JobScope.ID)).Sum(x => x.Cost);
- CurrentContractPercent = ProjectContract.IsEffectivelyEqual(0.0)
- ? 0.0
- : CurrentContract * 100.0 / ProjectContract;
-
- CompletedContract = PreviousContract + CurrentContract;
- CompletedContractPercent = ProjectContract.IsEffectivelyEqual(0.0)
- ? 0.0
- : CompletedContract * 100.0 / ProjectContract;
-
- ProjectVariations = Items.Where(x => variationscopeids.Contains(x.JobScope.ID)).Sum(x => x.JobScope.ExTax);
-
- PreviousVariations = Items.Where(x => variationscopeids.Contains(x.JobScope.ID)).Sum(x => x.PreviouslyClaimed);
- PreviousVariationsPercent = ProjectVariations.IsEffectivelyEqual(0.0)
- ? 0.0
- : PreviousVariations * 100.0 / ProjectVariations;
-
- CurrentVariations = Items.Where(x => variationscopeids.Contains(x.JobScope.ID)).Sum(x => x.Cost);
- CurrentVariationsPercent = ProjectVariations.IsEffectivelyEqual(0.0)
- ? 0.0
- : CurrentVariations * 100.0 / ProjectVariations;
-
- CompletedVariations = PreviousVariations + CurrentVariations;
- CompletedVariationsPercent = ProjectVariations.IsEffectivelyEqual(0.0)
- ? 0.0
- : CompletedVariations * 100.0 / ProjectVariations;
-
-
- ProjectSubTotal = ProjectContract + ProjectVariations;
-
- PreviousSubTotal = PreviousContract + PreviousVariations;
- PreviousSubTotalPercent = ProjectSubTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : PreviousSubTotal * 100.0 / ProjectSubTotal;
-
- CurrentSubTotal = CurrentContract + CurrentVariations;
- CurrentSubTotalPercent = ProjectSubTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : CurrentSubTotal * 100.0 / ProjectSubTotal;
-
- CompletedSubTotal = PreviousSubTotal + CurrentSubTotal;
- CompletedSubTotalPercent = ProjectSubTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : CompletedSubTotal * 100.0 / ProjectSubTotal;
-
- var retentionbase = Job.Retention.IncludeVariations
- ? ProjectSubTotal
- : ProjectContract;
- ProjectRetention = retentionbase * Job.Retention.Maximum / 100.0;
- ProjectRetentionPercent = Job.Retention.Maximum;
-
-
- PreviousRetention = Invoices.Where(x => x.ID != InvoiceID).Sum(x=>x.Retained);
- PreviousRetentionPercent = retentionbase.IsEffectivelyEqual(0.0)
- ? 0.0
- : PreviousRetention * 100.0 / retentionbase;
-
- CurrentRetention = Math.Min(ProjectRetention - PreviousRetention,CurrentSubTotal * Job.Retention.Rate / 100.0);
- CurrentRetentionPercent = retentionbase.IsEffectivelyEqual(0.0)
- ? 0.0
- : CurrentRetention * 100.0 / retentionbase;
-
- CompletedRetention = PreviousRetention + CurrentRetention;
- CompletedRetentionPercent = retentionbase.IsEffectivelyEqual(0.0)
- ? 0.0
- : CompletedRetention * 100.0 / retentionbase;
-
- ProjectTotal = (ProjectSubTotal - ProjectRetention);
-
- CompletedTotal = (CompletedSubTotal - CompletedRetention);
- CompletedTotalPercent = ProjectTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : CompletedTotal * 100.0 / ProjectTotal;
-
- PreviousTotal = (PreviousSubTotal - PreviousRetention);
- PreviousTotalPercent = ProjectTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : PreviousTotal * 100.0 / ProjectTotal;
-
- CurrentTotal = (CurrentSubTotal - CurrentRetention);
- CurrentTotalPercent = ProjectTotal.IsEffectivelyEqual(0.0)
- ? 0.0
- : CurrentTotal * 100.0 / ProjectTotal;
- }
- protected override void Reload(Filters<ProgressClaim> criteria, Columns<ProgressClaim> columns, ref SortOrder<ProgressClaim>? sort, CancellationToken token, Action<CoreTable?, Exception?> action)
- {
- LoadData();
- base.Reload(criteria, columns, ref sort, token, action);
- }
- protected override void SaveColumns(DynamicGridColumns columns)
- {
- ColumnsComponent.SaveColumns(columns);
- }
- protected override void LoadColumnsMenu(ContextMenu menu)
- {
- ColumnsComponent.LoadColumnsMenu(menu);
- }
- protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
- {
- if (args.Row is null) return;
- if(args.Column is DynamicGridColumn gridColumn)
- {
- var claim = LoadItem(args.Row);
- if(new Column<ProgressClaim>(x => x.Materials).IsEqualTo(gridColumn.ColumnName))
- {
- var grid = new ProgressClaimMaterialsGrid(claim, Invoice);
- var window = DynamicGridUtils.CreateGridWindow($"Materials", grid);
- window.ShowDialog();
- }
- else if(new Column<ProgressClaim>(x => x.Labour).IsEqualTo(gridColumn.ColumnName))
- {
- var grid = new ProgressClaimLabourGrid(claim, Invoice, Job);
- var window = DynamicGridUtils.CreateGridWindow($"Labour", grid);
- window.ShowDialog();
- }
- }
- }
- public override DynamicGridColumns GenerateColumns()
- {
- var columns = new DynamicGridColumns();
- columns.Add<ProgressClaim, string>(x => x.JobScope.Number, 80, "Number", "", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, string>(x => x.JobScope.Description, 0, "Description", "", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, double>(x => x.Materials, 80, "Material $", "", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, double>(x => x.Labour, 80, "Labour $", "", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, double>(x => x.JobScope.ExTax, 100, "Quote $", "", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, double>(x => x.PreviouslyClaimed, 100, "Prev $", "C2", Alignment.MiddleCenter);
- columns.Add<ProgressClaim, double>(x => x.PreviouslyClaimedPercent, 80, "Prev %", "", Alignment.MiddleCenter);
- return columns;
- }
- protected override DynamicGridColumns LoadColumns()
- {
- var columns = ColumnsComponent.LoadColumns();
- ActionColumns.Clear();
-
- ActionColumns.Add(new DynamicTemplateColumn(row =>
- {
- var item = LoadItem(row);
- var editor = new DoubleTextBox
- {
- VerticalAlignment = VerticalAlignment.Stretch,
- HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
- Background = new SolidColorBrush(Colors.LightYellow),
- BorderThickness = new Thickness(0.0),
- MinValue = 0.0,
- MaxValue = 100.0,
- Value = item.PercentCost
- };
- editor.ValueChanged += (o, e) =>
- {
- var maxValue = 100.0;
- var value = (double?)e.NewValue ?? default;
- if(value > maxValue)
- {
- Dispatcher.BeginInvoke(() => editor.Value = maxValue);
- }
- else
- {
- item.PercentCost = value;
- item.Cost = item.JobScope.ExTax * item.PercentCost / 100 - item.PreviouslyClaimed;
- UpdateRow(row, item);
- InvalidateRow(row);
- DoChanged();
- }
- };
-
- return editor;
- })
- {
- HeaderText = "Cur %",
- Width = 80,
- });
-
- ActionColumns.Add(new DynamicTextColumn(row =>
- {
- if (row is null) return null;
-
- var item = LoadItem(row);
- return item.Cost;
- })
- {
- Format = "C2",
- HeaderText = "Claim $",
- Width = 100
- });
- return columns;
- }
-
- private DynamicGridTreeUIComponent<ProgressClaim>? _uiComponent;
-
- private DynamicGridTreeUIComponent<ProgressClaim> UIComponent
- {
- get
- {
- if(_uiComponent is null)
- {
- _uiComponent = new DynamicGridTreeUIComponent<ProgressClaim>(
- x => x.JobScope.ID,
- x => x.JobScope.Parent.ID)
- {
- Parent = this,
- MaxRowHeight = 30,
- };
- //_uiComponent.OnContextMenuOpening += JobDocumentSetFolderTree_OnContextMenuOpening;
- }
- return _uiComponent;
- }
- }
-
- protected override IDynamicGridUIComponent<ProgressClaim> CreateUIComponent()
- {
- return UIComponent;
- }
-
- }
|