| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 | using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using InABox.Core;namespace Comal.Classes{    public class ManufacturingPacketArea : IFormula<ManufacturingPacket, object>    {        public Expression<Func<ManufacturingPacket, object>> Value => x => x.Height;        public Expression<Func<ManufacturingPacket, object>>[] Modifiers =>            new Expression<Func<ManufacturingPacket, object>>[] { x => x.Width, x => 0.000001m };        public FormulaOperator Operator => FormulaOperator.Multiply;        public FormulaType Type => FormulaType.Virtual;    }    public class ManufacturingPacketVolume : IFormula<ManufacturingPacket, object>    {        public Expression<Func<ManufacturingPacket, object>> Value => x => x.Height;        public Expression<Func<ManufacturingPacket, object>>[] Modifiers => new Expression<Func<ManufacturingPacket, object>>[]            { x => x.Width, x => x.Length, x => 0.000000001m };        public FormulaOperator Operator => FormulaOperator.Multiply;                public FormulaType Type => FormulaType.Virtual;    }    public class ManufacturingPacketTime : CoreAggregate<ManufacturingPacket, ManufacturingPacketStage, TimeSpan>    {        public override Expression<Func<ManufacturingPacketStage, TimeSpan>> Aggregate => x => x.Time;        public override AggregateCalculation Calculation => AggregateCalculation.Sum;        public override Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>            new Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>>()            {                { ManufacturingPacketStage => ManufacturingPacketStage.Parent.ID, ManufacturingPacket => ManufacturingPacket.ID }            };    }    public class ManufacturingPacketTimeRemaining : CoreAggregate<ManufacturingPacket, ManufacturingPacketStage, TimeSpan>    {        public override Expression<Func<ManufacturingPacketStage, TimeSpan>> Aggregate => x => x.TimeRemaining;        public Expression<Func<ManufacturingPacketStage, Guid>> Link => x => x.Parent.ID;        public override AggregateCalculation Calculation => AggregateCalculation.Sum;        public override Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>            new Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>>()            {                { ManufacturingPacketStage => ManufacturingPacketStage.Parent.ID, ManufacturingPacket => ManufacturingPacket.ID }            };    }    public class ManufacturingPacketActualTime : CoreAggregate<ManufacturingPacket, ManufacturingHistory, TimeSpan>    {        public override Expression<Func<ManufacturingHistory, TimeSpan>> Aggregate => x => x.WorkDuration;        public override AggregateCalculation Calculation => AggregateCalculation.Sum;        public override Dictionary<Expression<Func<ManufacturingHistory, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>            new Dictionary<Expression<Func<ManufacturingHistory, object>>, Expression<Func<ManufacturingPacket, object>>>()            {                { ManufacturingHistory => ManufacturingHistory.Packet.ID, ManufacturingPacket => ManufacturingPacket.ID }            };    }    [UserTracking("Manufacturing")]    [Caption("Manufacturing")]    public class ManufacturingPacket : Entity, IPersistent, IRemotable, IOneToMany<Setout>, ILicense<ManufacturingLicense>, IIssues, IProblems<ManagedProblem>    {        [TextBoxEditor]        [EditorSequence(1)]        public string Title { get; set; }        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]        [EditorSequence(2)]        public string Serial { get; set; }        private class SetoutLookup : LookupDefinitionGenerator<Setout, ManufacturingPacket>        {            public override Filter<Setout> DefineFilter(ManufacturingPacket[] items)            {                return new Filter<Setout>(x => x.JobLink.ID).IsEqualTo(items.First().SetoutLink.JobLink.ID);            }            public override Columns<ManufacturingPacket> DefineFilterColumns()                => Columns.None<ManufacturingPacket>().Add(x => x.SetoutLink.JobLink.ID);        }        [LookupDefinition(typeof(SetoutLookup))]        [EditorSequence(3)]        [EntityRelationship(DeleteAction.Cascade)]        public SetoutLink SetoutLink { get; set; }        private class JobITPLookup : LookupDefinitionGenerator<JobITP, ManufacturingPacket>        {            public override Filter<JobITP> DefineFilter(ManufacturingPacket[] items)            {                if (items.Length == 1)                    return new Filter<JobITP>(x => x.Job.ID).IsEqualTo(items.First().SetoutLink.JobLink.ID);                return LookupFactory.DefineFilter<JobITP>();            }            public override Columns<ManufacturingPacket> DefineFilterColumns()                => Columns.None<ManufacturingPacket>().Add(x => x.SetoutLink.JobLink.ID);            }        [EditorSequence(4)]        [LookupDefinition(typeof(JobITPLookup))]        public JobITPLink ITP { get; set; }        [TextBoxEditor]        [EditorSequence(5)]        public string Location { get; set; }        // Used to calculate time & materials        [EditorSequence(7)]        [IntegerEditor]        public int Quantity { get; set; }        [EditorSequence(8)]        [IntegerEditor]        // Determines # of barcodes to print        public int BarcodeQty { get; set; }        [EditorSequence(9)]        [TimestampEditor(Editable = Editable.Hidden)]        public override DateTime Created        {            get => base.Created;            set => base.Created = value;        }        [EditorSequence(10)]        [DateTimeEditor]        public DateTime DueDate { get; set; }        [EditorSequence("Design", 101)]        [EntityRelationship(DeleteAction.Cascade)]        public PDFDocumentLink Drawing { get; set; }        // To be overlaid over the PDF document        [EditorSequence("Design", 102)]        [TextBoxEditor]        public string WaterMark { get; set; }        [EditorSequence("Design", 103)]        public double Height { get; set; }        [EditorSequence("Design", 104)]        public double Width { get; set; }        [EditorSequence("Design", 105)]        public double Length { get; set; }        [EditorSequence("Manufacturing", 200)]        public ManufacturingTemplateLink ManufacturingTemplateLink { get; set; }        [EditorSequence("Manufacturing", 201)]        [TimestampEditor(Editable = Editable.Disabled)]        public DateTime Issued { get; set; }        [EditorSequence("Manufacturing", 202)]        [LoggableProperty]        public bool Priority { get; set; }        [EditorSequence("Manufacturing", 203)]        [LoggableProperty]        public bool Distributed { get; set; }        [EditorSequence("Manufacturing", 204)]        [TextBoxEditor(Editable = Editable.Disabled)]        public string Trolleys { get; set; }        [EditorSequence("Manufacturing", 205)]        [TimestampEditor(Editable = Editable.Hidden)]        public DateTime BarcodePrinted { get; set; }        [EditorSequence("Manufacturing", 206)]        [DateTimeEditor(Editable = Editable.Disabled)]        [SecondaryIndex]        public DateTime Completed { get; set; }        [SecondaryIndex]        [TimestampEditor]        [EditorSequence("Manufacturing", 207)]        public DateTime Archived { get; set; } = DateTime.MinValue;        [NullEditor]        [Obsolete("Replaced with Problem", true)]        public string Issues { get; set; }                [EditorSequence("Issues", 1)]        public ManagedProblem Problem { get; set; }        [CheckBoxEditor]        [EditorSequence("Issues", 2)]        [LoggableProperty]        public bool OnHold { get; set; }                public override string ToString()        {            return string.Format("{0} {1}", SetoutLink.Number, Serial);        }        public static void Progress(IEnumerable<ManufacturingPacket> packets, ManufacturingPacketStage[] Stages)        {            //List<ManufacturingPacketStage> updates = new List<ManufacturingPacketStage>();            foreach (var packet in packets.Where(x => !x.StageLink.Equals(CoreUtils.FullGuid)))            {                var stages = Stages.Where(x => x.Parent.ID.Equals(packet.ID));                long sequence = 0;                var stage = stages.FirstOrDefault(x => x.ID.Equals(packet.StageLink.ID));                if (stage != null)                {                    stage.Completed = DateTime.Now;                    stage.PercentageComplete = 100.0F;                    sequence = stage.Sequence;                }                // Update the pointer to the next stage                stage = stages.Where(x => x.Sequence > sequence).FirstOrDefault();                if (stage != null)                {                    stage.QualityStatus = QualityStatus.NotChecked;                    stage.QualityNotes = "";                    stage.Station = 0;                    stage.Started = DateTime.MinValue;                    stage.Completed = DateTime.MinValue;                    stage.PercentageComplete = 0.0F;                    packet.StageLink.ID = stage.ID;                    packet.StageLink.Synchronise(stage);                }                else                {                    packet.StageLink.ID = CoreUtils.FullGuid;                }                packet.Issued = !packet.StageLink.IsValid() ? DateTime.MinValue : packet.Issued.IsEmpty() ? DateTime.Now : packet.Issued;                packet.Completed = packet.StageLink.ID.Equals(CoreUtils.FullGuid)                    ? packet.Completed.IsEmpty() ? DateTime.Now : packet.Completed                    : DateTime.MinValue;            }        }        public static void Regress(IEnumerable<ManufacturingPacket> pkts, ManufacturingPacketStage[] stgs)        {            foreach(var packet in pkts)            {                var stages = stgs.Where(x => x.Parent.ID.Equals(packet.ID));                var sequence = long.MaxValue;                var stage = stages.FirstOrDefault(x => x.ID.Equals(packet.StageLink.ID));                if (stage != null)                {                    stage.Completed = DateTime.MinValue;                    stage.PercentageComplete = 0.0F;                    stage.QualityStatus = QualityStatus.NotChecked;                    stage.QualityNotes = "";                    sequence = stage.Sequence;                }                // Update the pointer to the previous stage                stage = stages.Where(x => x.Sequence < sequence).LastOrDefault();                if (stage != null)                {                    stage.QualityStatus = QualityStatus.NotChecked;                    stage.QualityNotes = "";                    stage.Station = 0;                    stage.Started = DateTime.MinValue;                    stage.Completed = DateTime.MinValue;                    stage.PercentageComplete = 0.0F;                }                packet.StageLink.ID = stage == null ? Guid.Empty : stage.ID;                packet.Issued = !packet.StageLink.IsValid() ? DateTime.MinValue : packet.Issued.IsEmpty() ? DateTime.Now : packet.Issued;                packet.DueDate = packet.Issued.IsEmpty() ? DateTime.MinValue : packet.DueDate;                packet.Completed = packet.StageLink.ID.Equals(CoreUtils.FullGuid)                    ? packet.Completed.IsEmpty() ? DateTime.Now : packet.Completed                    : DateTime.MinValue;            }        }        #region Aggregates        [EditorSequence(300)]        [DoubleEditor(Editable = Editable.Hidden)]        [Formula(typeof(ManufacturingPacketArea))]        public double Area { get; set; }        [EditorSequence(301)]        [DoubleEditor(Editable = Editable.Hidden)]        [Formula(typeof(ManufacturingPacketVolume))]        public double Volume { get; set; }        [EditorSequence(302)]        [Aggregate(typeof(ManufacturingPacketTime))]        public TimeSpan Time { get; set; }        [EditorSequence(303)]        [Aggregate(typeof(ManufacturingPacketTimeRemaining))]        public TimeSpan TimeRemaining { get; set; }        [EditorSequence(304)]        [Aggregate(typeof(ManufacturingPacketActualTime))]        public TimeSpan ActualTime { get; set; }        #endregion        #region Internal / NullEditor Properties        private class ManufacturingPacketStageLookup : LookupDefinitionGenerator<ManufacturingPacketStage, ManufacturingPacket>        {            public override Filter<ManufacturingPacketStage>? DefineFilter(ManufacturingPacket[] items)            {                if (items.Any())                    return new Filter<ManufacturingPacketStage>(x => x.Parent.ID).IsEqualTo(items.First().ID);                return null;            }            public override Columns<ManufacturingPacket> DefineFilterColumns()                => Columns.None<ManufacturingPacket>().Add(x => x.ID);        }        [LookupDefinition(typeof(ManufacturingPacketStageLookup))]        [NullEditor]        public ManufacturingPacketStageLink StageLink { get; set; }        [NullEditor]        public QAFormLink QAForm { get; set; }        // I think ITPs will end up being linked to a stage,        // So this might get obsoleted at some point        private class JobStageLookup : LookupDefinitionGenerator<JobStage, ManufacturingPacket>        {            public override Filter<JobStage> DefineFilter(ManufacturingPacket[] items)            {                if (items.Length == 1)                    return new Filter<JobStage>(x => x.Job.ID).IsEqualTo(items.First().SetoutLink.JobLink.ID).And(x => x.IsHeader).IsEqualTo(false);                return new Filter<JobStage>(x => x.ID).IsEqualTo(Guid.Empty);            }            public override Columns<ManufacturingPacket> DefineFilterColumns()                => Columns.None<ManufacturingPacket>().Add(x => x.SetoutLink.JobLink.ID);        }        [LookupDefinition(typeof(JobStageLookup))]        [NullEditor]        public JobStageLink JobStage { get; set; }        [NullEditor]        [EntityRelationship(DeleteAction.SetNull)]        public PurchaseOrderItemLink OrderItem { get; set; }        [NullEditor]        public DateTime EstimatedDate { get; set; }        #endregion        #region Obsolete Properties        // The code of the Linked Manufacturing Template        // Suggested - set to obsolete?        [NullEditor]        [Obsolete("Replaced with ManufacturingTemplateLink.Code", true)]        public string Code { get; set; }        // The Factory to which this packet template belongs        // Suggestion - Set to obsolete?        [NullEditor]        [Obsolete("Replaced with ManufacturingTemplateLink.FactoryLink.ID")]        public string Group { get; set; }        [NullEditor]        [Obsolete("Replaced with BarcodeQty")]        public bool GroupedBarcode { get; set; }        private BarcodeType _barcodetype = BarcodeType.Unspecified;        [NullEditor]        [Obsolete("Replaced with BarcodeQty")]        public BarcodeType BarcodeType        {            get => _barcodetype == BarcodeType.Unspecified ? GroupedBarcode ? BarcodeType.Grouped : BarcodeType.Individual : _barcodetype;            set => _barcodetype = value;        }        // Comes from Setout.Title (Should be Reference)        [NullEditor]        [Obsolete("Replaced with SetoutLink.Reference")]        public string Reference { get; set; }        // Comes from Setout.Location        [NullEditor]        [Obsolete("Replaced with SetoutLink.Description")]        public string Description { get; set; }        [Obsolete("Replaced With ManufacturingTemplateLink")]        [NullEditor]        public Guid ManufacturingItemID { get; set; }        [NullEditor]        [Obsolete("Replaced with ManufacturingPacketLink.Code")]        public string Template { get; set; }        [Obsolete("Replaced With SetoutLink.JobLink")]        [EntityRelationship(DeleteAction.Cascade)]        [NullEditor]        public JobLink JobLink { get; set; }        #endregion        #region Functions        //public void MovePrevious()        //{        //    bool bFound = false;        //    SetoutStage prev = null;        //    foreach (SetoutStage stage in Stages)        //    {        //        if (bFound)        //        {        //            stage.Started = DateTime.MinValue;        //            stage.Completed = DateTime.MinValue;        //            stage.PercentageComplete = 0.0F;        //        }        //        else if (stage.Completed.IsEmpty())        //        {        //            stage.Started = DateTime.MinValue;        //            stage.Completed = DateTime.MinValue;        //            stage.PercentageComplete = 0.0F;        //            bFound = true;        //            if (prev != null)        //                prev.Completed = DateTime.MinValue;        //        }        //        else        //            prev = stage;        //    }        //    if (prev == null)        //        Issued = DateTime.MinValue;        //    Completed = DateTime.MinValue;        //    Stage = CurrentStage();        //}        //public void MoveNext()        //{        //    bool bFound = false;        //    bool bComplete = true;        //    if (Issued.IsEmpty())        //        Issued = DateTime.Now;        //    foreach (SetoutStage stage in Stages)        //    {        //        if (bFound)        //        {        //            stage.Started = DateTime.MinValue;        //            stage.Completed = DateTime.MinValue;        //            stage.PercentageComplete = 0.0F;        //            bComplete = false;        //        }        //        else if (stage.Started.IsEmpty())        //        {        //            //stage.Started = DateTime.Now;        //            stage.Completed = DateTime.MinValue;        //            stage.PercentageComplete = 0.0F;        //            bComplete = false;        //            bFound = true;        //        }        //        else if (stage.Completed.IsEmpty())        //        {        //            stage.Completed = DateTime.Now;        //            stage.PercentageComplete = 100.0F;        //            bFound = true;        //        }        //    }        //    //Completed = bComplete ? DateTime.Now : DateTime.MinValue;        //    bool bIsComplete = !Stages.Any(x => x.Completed.Equals(DateTime.MinValue));        //    if (bIsComplete && Completed.Equals(DateTime.MinValue))        //        Completed = DateTime.Now;        //    Stage = CurrentStage();        //}        //public Boolean IsComplete()        //{        //    if ((!Issued.IsEmpty()) && (Stages != null))        //    {        //        foreach (SetoutStage stage in Stages)        //        {        //            if (stage.Completed.IsEmpty())        //                return false;        //        }        //        return true;        //    }        //    return false;        //}        //public String Status()        //{        //    if ((Stages == null) || (!Stages.Any()))        //        return "No Template!";        //    if (Issued.IsEmpty())        //        return "To Be Issued";        //    var stage = GetCurrentStage();        //    if (stage != null)        //    {        //        if (!Archived.IsEmpty())        //            return "Cancelled";        //        else        //            return String.Format("{0} ({1:F2}%)", stage.Name, stage.PercentageComplete);        //    }        //    return "Complete";        //}        //public Guid CurrentStage()        //{        //    if (Issued.IsEmpty())        //        return Guid.Empty;        //    SetoutStage stage = GetCurrentStage();        //    if (stage != null)        //        return stage.SectionID;        //    return CoreUtils.FullGuid;        //}        //public SetoutStage GetCurrentStage()        //{        //    if ((!Issued.IsEmpty()) && (Stages != null))        //    {        //        foreach (SetoutStage stage in Stages)        //        {        //            if (stage.Completed.IsEmpty())        //                return stage;        //        }        //    }        //    return null;        //}        //public void SetStage(Guid id, bool complete = false)        //{        //    bool bFound = id == Guid.Empty;        //    Issued = (id == Guid.Empty) ? DateTime.MinValue : Issued.IsEmpty() ? DateTime.Now : Issued;        //    if (id == CoreUtils.FullGuid)        //    {        //        foreach (SetoutStage stage in Stages)        //        {        //            stage.Started = stage.Started.IsEmpty() ? DateTime.Now : stage.Started;        //            stage.Completed = stage.Completed.IsEmpty() ? DateTime.Now : stage.Completed;        //            stage.PercentageComplete = 100.0F;        //            Completed = stage.Completed;        //        }        //    }        //    else        //    {        //        //Completed = DateTime.MinValue;        //        foreach (SetoutStage stage in Stages)        //        {        //            if (stage.SectionID.Equals(id))        //            {        //                bFound = true;        //                //stage.Started = stage.Started.IsEmpty() ? DateTime.Now : stage.Started;        //                stage.Completed = complete ? DateTime.Now : DateTime.MinValue;        //                stage.PercentageComplete = stage.Completed.IsEmpty() ? 0.0F : 100.0F;        //            }        //            else        //            {        //                if (!bFound)        //                {        //                    // Stages Before this stage - Update Started and Completed if Empty        //                    if (stage.Started.IsEmpty())        //                        stage.Started = DateTime.Now;        //                    if (stage.Completed.IsEmpty())        //                        stage.Completed = DateTime.Now;        //                    stage.PercentageComplete = 100.0F;        //                }        //                else        //                {        //                    // Stages After This Stage - Blank out Started and Completed        //                    stage.Started = DateTime.MinValue;        //                    stage.Completed = DateTime.MinValue;        //                    stage.PercentageComplete = 0.0F;        //                }        //            }        //        }        //    }        //    bool bIsComplete = !Stages.Any(x => x.Completed.Equals(DateTime.MinValue));        //    if (bIsComplete && Completed.Equals(DateTime.MinValue))        //        Completed = DateTime.Now;        //    Stage = CurrentStage();        //}        #endregion    }}
 |