/// <summary> /// Reloads the NonProductiveTask full data keeping the current UOW /// </summary> public void Reload() { HasVm = false; if (UOW == null) UOW = new Dal.SoheilEdmContext(); var nptDataService = new DataServices.NPTDataService(UOW); ModifiedDate = DateTime.MinValue;//??? Model = nptDataService.GetSingle(Id); Start = Model.StartDateTime; End = Model.EndDateTime; }
private void initializeActions() { #region Items(Blocks/NPTs) actions //----------------------- ADD BLOCK ------------------------------- _actionLoadItem = (object data) => { try { var actionData = data as PPRange; if (!actionData.IsValidRange()) return; #region Load blockInfos var blockInfos = new DataServices.BlockDataService() .GetInRange(actionData.Start, actionData.End).ToArray(); //add each blockInfo to cache foreach (var blockInfo in blockInfos) { //find b in cache PPItemBlock b; lock (_cacheLock) b = _blocks[blockInfo.StationIndex].FirstOrDefault(x => x.Id == blockInfo.Id); if (b == null) { //new block (not in cache) is found //create the PPItemBlock and load full data //set HasVm to false b = new PPItemBlock(blockInfo.Id); lock (_cacheLock) { //add to cache _blocks[blockInfo.StationIndex].Add(b); } } else { //newer version (of an existing block in cache) is found lock (_cacheLock) { if (b.Model.ModifiedDate != blockInfo.ModifiedDate) { //reload b //set HasVm to false b.Reload(); } } } if (!_force && !_qThreadAlive) return; Thread.Sleep(10); } #endregion #region Load NptInfos //find npt Ids within the range var nptInfos = new DataServices.NPTDataService() .GetInRange(actionData.Start, actionData.End).ToArray(); //add each nptInfo to cache foreach (var nptInfo in nptInfos) { //find n in cache PPItemNpt n; lock (_cacheLock) n = _npts[nptInfo.StationIndex].FirstOrDefault(x => x.Id == nptInfo.Id); if (n == null) { //new npt (not in cache) is found //create the PPItemNPT and load full data //set HasVm to false n = new PPItemNpt(nptInfo.Id); lock (_cacheLock) { //add to cache _npts[nptInfo.StationIndex].Add(n); } } else { //newer version (of an existing block in cache) is found //check for newer version??? } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); } #endregion #region find VIndex of each item in cache for (int st = 0; st < _stations; st++) { lock (_cacheLock) { if (_blocks[st].Any() || _npts[st].Any()) { //find VIndexes for station[st] (row) var row = (_blocks[st].Concat<PPItemBase>(_npts[st])) .OrderBy(x => x.Start) .ToArray(); int maxV = 1; for (int i = 0; i < row.Length; i++) { //block (b) var item = row[i]; //find VIndex of block (b) if (i == 0) { item.VIndex = 0; } else { //search through previous blocks var targetRow = row .Take(i) .GroupBy(g => g.VIndex) .FirstOrDefault(g => g .All(x => (x.End - item.Start < TimeSpan.FromSeconds(1)))); if (targetRow == null) { //non of rows has space item.VIndex = maxV; maxV++; } else { //nom is the row item.VIndex = targetRow.First().VIndex; } } //fire event to add it if (!PPItemBase.IsNull(item)) { if (item is PPItemBlock) _dispatcher.Invoke(() => { //set HasVm to true if (BlockAddedOrUpdated != null) BlockAddedOrUpdated(item as PPItemBlock); }); else if (item is PPItemNpt) //fire event to add it _dispatcher.Invoke(() => { if (NptAddedOrUpdated != null) NptAddedOrUpdated(item as PPItemNpt); }); } } //sleep if station[st] contains some block if (!_force && !_qThreadAlive) return; Thread.Sleep(10); } } } #endregion #region Delete outside Items //widen the range var actionData2 = new PPRange(actionData.Start.Add(-_rangeMargin), actionData.End.Add(_rangeMargin)); for (int st = 0; st < _stations; st++) { //find outside blocks PPItemBlock[] outsideBlocks; lock (this) { outsideBlocks = _blocks[st].Where(x => !actionData2.IsInRange(x) || x.Id == 0).ToArray(); } foreach (var item in outsideBlocks) { //remove from list lock (this) { _blocks[st].Remove(item); } //remove from Vm _dispatcher.Invoke(() => { if (BlockRemoved != null) BlockRemoved(item); }); } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); //find outside NPTs PPItemNpt[] outsideNpts; lock (this) { outsideNpts = _npts[st].Where(x => !actionData2.IsInRange(x)).ToArray(); } foreach (var item in outsideNpts) { //remove from list lock (this) { _npts[st].Remove(item); } //remove from Vm _dispatcher.Invoke(() => { if (NptRemoved != null) NptRemoved(item); }); } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); } #endregion } catch (Exception e) { if (!LoginInfo.IsDebugMode) return; _qThreadAlive = false; using (var log = new System.IO.StreamWriter(System.IO.Path.Combine(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Soheil"), "Exceptions.log"), append: true)) { log.WriteLine(DateTime.Now.ToShortTimeString()); log.Write("Ex = "); log.WriteLine(e.Message); if (e.InnerException != null) { log.Write("InnerEx = "); log.WriteLine(e.InnerException.Message); } log.Write("Source = "); log.WriteLine(e.Source); log.Write("Trace = "); log.WriteLine(e.StackTrace); log.WriteLine(); log.Close(); } System.Windows.MessageBox.Show("Fatal error.\nfor more info see %appdata%\\Soheil\\Exceptions.Log"); } finally { if(_force) { _force = false; Pause = false; } } }; #endregion #region WorkTimes actions //----------------------- ADD WORK TIME ------------------------------- _actionLoadWorkTimes = (object data) => { //retreive data var actionData = data as PPRange; if (!actionData.IsValidRange()) return; var _workProfilePlanDataService = new DataServices.WorkProfilePlanDataService(); lock (this) { //remove all from Vm _dispatcher.Invoke(() => { if (WorkTimesRemoved != null) WorkTimesRemoved(); }); _shifts.Clear(); } //find workprofiles var workTimes = _workProfilePlanDataService.GetShiftsInRange(actionData.Start, actionData.End) .Where(x => x.Item1.IsOpen); foreach (var tuple in workTimes) { //keep updated with _shiftsDates //if (_shifts.Any(x => x.Id == tuple.Item1.Id && x.DayStart == tuple.Item2)) continue; //create PPItemWorkTime var shiftItem = new PPItemWorkTime(tuple.Item1, tuple.Item2); //add PPItemWorkTime lock (this) { _shifts.Add(shiftItem); } //fire event to add it and its breaks _dispatcher.Invoke(() => { if (WorkTimeAdded != null) WorkTimeAdded(shiftItem); }); } //find day colors var dayColors = _workProfilePlanDataService.GetBusinessDayColorsInRange(actionData.Start, actionData.End).ToArray(); //change colors of Days _dispatcher.Invoke(() => { if (DayColorsUpdated != null) DayColorsUpdated(actionData.Start, dayColors); }); _workProfilePlanDataService.Dispose(); }; #endregion }
/// <summary> /// Saves this block and also finds the best empty space if needed /// </summary> internal void Save() { var task = Model.Tasks.FirstOrDefault(); if (task == null) throw new Exception("Task not found."); var prId = Model.StateStation.State.OnProductRework.Id; #region Evaluate times and space var nptDs = new DataServices.NPTDataService(_uow); //recalc Start/End/Duration Model.StartDateTime = task.Processes.Min(x => x.StartDateTime); if (task.Processes.Any()) Model.EndDateTime = task.Processes.Max(x => x.EndDateTime); else Model.EndDateTime = EndDate.Add(EndTime); Model.DurationSeconds = (int)(Model.EndDateTime - Model.StartDateTime).TotalSeconds; if(Model.DurationSeconds < 300) { if (MessageBox.Show("طول برنامه کمتر از 5 دقیقه است.\nپیشنهاد می شود که گزینه خیر را انتخاب و اطلاعات وارد شده را دوباره بررسی کنید", "هشدار", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No) == MessageBoxResult.No) return; } task.StartDateTime = Model.StartDateTime; task.EndDateTime = Model.EndDateTime; task.DurationSeconds = Model.DurationSeconds; task.TaskTargetPoint = Model.BlockTargetPoint; //check how it should be placed if(IsLastSpace) { var lastItem = _blockDataService.GetLastItem(Model, StationId); if (lastItem.Item1 != null) { var setupDs = new DataServices.SetupDataService(_uow); if (lastItem.Item2 != null) setupDs.DeleteModel(lastItem.Item2); var setup = setupDs.AddModel(StationId, lastItem.Item1.StateStation.State.OnProductRework.Id, prId, lastItem.Item1.EndDateTime); var diff = setup.EndDateTime - Model.StartDateTime; Move(diff); _blockDataService.AddModel(Model); } else throw new Exception("هیچ برنامه ای در ایستگاه وجود ندارد (گزینه موازی را از بالای صفحه انتخاب کنید)"); } else if (IsFirstSpace) { //check if it fits bool fits = true; DateTime start = EditorStartDate.Add(EditorStartTime); var inRangeBlocks = _blockDataService.GetInRange(Model, StationId); var inRangeNPTs = nptDs.GetInRange(Model.StartDateTime, StationId); //if not fit, make it auto start if (inRangeBlocks.Any(x => x != Model) || inRangeNPTs.Any()) fits = false; //check if should use auto start if (!fits) { // Updates the start datetime of this block to fit the first empty space Core.PP.Smart.SmartManager sman = new Core.PP.Smart.SmartManager(_blockDataService, nptDs); var seq = sman.FindNextFreeSpace( StationId, State.ProductRework.Id, start, //put it after specifed time if it wasn't auto start (int)Duration.TotalSeconds, Model); var block = seq.FirstOrDefault(x => x.Type == Core.PP.Smart.SmartRange.RangeType.NewTask); //measure start change var change = block.StartDT - Model.StartDateTime; //apply start change to block Model.StartDateTime = block.StartDT; Model.EndDateTime += change; //apply start change to task task.StartDateTime = block.StartDT; task.EndDateTime += change; //apply start change to processes foreach (var process in task.Processes) { process.StartDateTime += change; process.EndDateTime += change; } if (!sman.SaveSetups(seq)) Message.AddEmbeddedException("Some setups could not be added. check setup times table."); } } #endregion #region correct machines foreach (var act in ActivityList) { foreach (var process in act.ProcessList) { //delete from model foreach (var sm in process.Model.SelectedMachines.ToArray()) { if (sm.StateStationActivityMachine.StateStationActivity.Id != process.Model.StateStationActivity.Id || !process.SelectedMachines.Any(x=>x.MachineId == sm.StateStationActivityMachine.Machine.Id)) { process.Model.SelectedMachines.Remove(sm); new Dal.Repository<Model.SelectedMachine>(_uow).Delete(sm); }; } //add to model foreach (var sm in process.SelectedMachines) { //skip if exists if (process.Model.SelectedMachines.Any(x => x.StateStationActivityMachine.Machine.Id == sm.MachineId)) continue; //find the proper ssam var ssam = process.Model.StateStationActivity.StateStationActivityMachines. FirstOrDefault(x => x.Machine.Id == sm.MachineId); //create a selected machines if (ssam != null) process.Model.SelectedMachines.Add(new Model.SelectedMachine { Process = process.Model, StateStationActivityMachine = ssam, }); } } } #endregion _blockDataService.SaveBlock(Model); }