示例#1
0
		public ChangeoverCell(Rework row, Rework column, int stationId, Dal.SoheilEdmContext context)
		{
			Row = row;
			Column = column;
			RowIndex = row.RowIndex;
			ColumnIndex = column.ColumnIndex;
			_stationId = stationId;

			CrossColors = new CrossColors(row.Product.Color, column.Product.Color);
			if (Row.IsValid)
			{
				var ds = new DataServices.ChangeoverDataService();
				int fromPRId = row.ProductReworkId;
				int toPRId = column.ProductReworkId;
				//Model = await new Task<Model.Changeover>(()=>ds.GetByInfoOrAdd(stationId, fromPRId, toPRId, context));
				Model = ds.GetByInfoOrAdd(stationId, fromPRId, toPRId, context);
			}

			if (row.Product.Id == column.Product.Id)
				CellType = CellType.None;
			else
				CellType = CellType.ChangeoverCell;
		}
示例#2
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="stationId"></param>
		/// <param name="productReworkId"></param>
		/// <param name="startFrom"></param>
		/// <param name="durationOftask"></param>
		/// <param name="snapToLast">indicates if setups after an auto task should snap to its next task(true) or to the auto task(false)</param>
		/// <returns></returns>
		internal List<SmartRange> FindNextFreeSpace(int stationId, int productReworkId, DateTime startFrom, int durationOftask, Model.Block excludeModel = null)
		{
			//Find all tasks in database, which end after startFrom
			var inRangeItems = _blockDataService.GetInRange(startFrom, stationId, excludeModel)
				.Select(x => SmartRange.ExistingBlock(x)).ToList();
			var inRangeNPTs = _nptDataService.GetInRange(startFrom, stationId)
				.Select(x => SmartRange.ExistingSetup(x))
				.Where(x => x != null).ToList();
			//find the task and setup in database, which is just before startFrom
			var previousItem = _blockDataService.FindPreviousBlock(stationId, startFrom);
			var previousTask = SmartRange.ExistingBlock(previousItem.Item1);
			var previousSetup = SmartRange.ExistingSetup(previousItem.Item2);

			//create a row for specified station if needed
			if (!_reserve.Any(x => x.Key == stationId))
				_reserve.Add(new KeyValuePair<int, List<SmartRange>>(stationId, new List<SmartRange>()));
			var reserve = _reserve.First(x => x.Key == stationId).Value.Where(y => y.EndDT >= startFrom).ToList();

			PolynomialUnion(inRangeItems, inRangeNPTs);
			PolynomialUnion(inRangeItems, reserve);
			//*all are saved in inRangeItems*

			TimeSpan minFreeSpace = TimeSpan.FromSeconds(durationOftask);


			#region findSequenceOfSpotsBetween
			// Find the sequence of tasks and setups needed to be added or removed after the specified time
			// according to items starting before start and items starting before end
			// it's supposed that in the range (start..end) there is no other items
			var findSequenceOfSpotsBetween = new Func<DateTime, DateTime?, List<SmartRange>>((start,end) =>
			{
				var previousTaskInRange = inRangeItems.Where(x => x.Type == SmartRange.RangeType.Task || x.Type == SmartRange.RangeType.NewTask)
					.LastOrDefault(x => x.StartDT <= start);
				var previousSetupInRange = inRangeItems.Where(x => x.Type == SmartRange.RangeType.Setup || x.Type == SmartRange.RangeType.NewSetup)
					.LastOrDefault(x => x.StartDT <= start);
				if (previousTaskInRange != null)
					previousTask = previousTaskInRange;
				if (previousSetupInRange != null)
					previousSetup = previousSetupInRange;

				//nothing before this
				if (previousTask == null)
				{
					return new List<SmartRange> { 
						SmartRange.NewTask(start, durationOftask, stationId, productReworkId) 
					};
				}
				//product before this
				else
				{
					//no setup yet
					if (previousSetup == null)
					{
						//if the task ends after start
						if (previousTask.EndDT > start)
							start = previousTask.EndDT;

						//same products
						if (previousTask.ProductReworkId == productReworkId)
							return new List<SmartRange> { 
								SmartRange.NewTask(start, durationOftask, stationId, productReworkId) 
							};
						//different products
						else
						{
							var warmup = new DataServices.WarmupDataService().SmartFind(productReworkId, stationId);
							var changeover = new DataServices.ChangeoverDataService().SmartFind(previousTask.ProductReworkId, productReworkId, stationId);
							var smartSetup = SmartRange.NewSetup(start, warmup, changeover, stationId);
							return new List<SmartRange> { 
								smartSetup,
								SmartRange.NewTask(start.AddSeconds(smartSetup.DurationSeconds), durationOftask, stationId, productReworkId) 
							};
						}
					}
					//a setup after previous task and before this
					else
					{
						//same products
						if (previousTask.ProductReworkId == productReworkId)
						{
							//if the task ends after start (because setup is gonna be deleted)
							if (previousTask.EndDT > start)
								start = previousTask.EndDT;

							return new List<SmartRange> { 
								SmartRange.NewDeleteSetup(previousSetup),
								SmartRange.NewTask(start, durationOftask, stationId, productReworkId) 
							};
						}
						//if setup is ok due to its from_productRework and to_productRework
						else if (previousSetup.FromProductReworkId == previousTask.ProductReworkId
							&& previousSetup.ProductReworkId == productReworkId)
						{
							//if the setup ends after start
							if (previousSetup.EndDT > start)
								start = previousSetup.EndDT;

							return new List<SmartRange> { 
								SmartRange.NewTask(start, durationOftask, stationId, productReworkId) 
							};
						}
						//if setup is wrong due to its from_pdorcut_rorewk or to_productRework
						else
						{
							//if the task ends after start (because setup is gonna be deleted)
							if (previousTask.EndDT > start)
								start = previousTask.EndDT;

							var warmup = new DataServices.WarmupDataService().SmartFind(productReworkId, stationId);
							var changeover = new DataServices.ChangeoverDataService().SmartFind(
								previousTask.ProductReworkId,
								productReworkId, stationId);
							var smartSetup = SmartRange.NewSetup(start, warmup, changeover, stationId);
							return new List<SmartRange> { 
								SmartRange.NewDeleteSetup(previousSetup),
								smartSetup,
								SmartRange.NewTask(start.AddSeconds(smartSetup.DurationSeconds), durationOftask, stationId, productReworkId) 
							};
						}
					}
				}
			});
			#endregion


			#region what's this?
			// read the placement expressions left to right
			// second line [ ] is the range on which findSequenceOfSpotsBetween is called
			// first line is before adding, next lines are afterwards
			// 1111,2222,... are tasks
			// | is startFrom point
			// --- is empty space
			// TTTT is new task
			// x is setuptime (if needed)
			#endregion

			//--|---------
			//   [
			//--|xTTTT----
			//if no task: use startFrom as start of sequence finding
			if (inRangeItems.Count() == 0)
				return findSequenceOfSpotsBetween(startFrom, null);

			//if 1 task:
			else if (inRangeItems.Count() == 1)
			{
				var only = inRangeItems.First();

				//if the only task starts before startFrom but ends after it: use the end of it as start of sequence finding
				// 11|11---------
				//      [
				// 11|11xTTTT----
				if (only.StartDT <= startFrom)
					return findSequenceOfSpotsBetween(only.EndDT, null);
				else
				{
					//if the only task, starts after startFrom and enough space between startFrom and only task: 
					//					use startFrom as start of sequence finding and also add a reverse setup (from T to 1)
					// --|--------1111
					//    [      ]
					// --|xTTTT--x1111 snapToLast
					// --|xTTTTx--1111 snapToFirst
					//check if after-task setup is needed
					var warmup = only.ProductReworkId == productReworkId ?
						null : new DataServices.WarmupDataService().SmartFind(only.ProductReworkId, stationId);
					var changeover = only.ProductReworkId == productReworkId ?
						null : new DataServices.ChangeoverDataService().SmartFind(productReworkId, only.ProductReworkId, stationId);
					int reverseSetupDelay = only.ProductReworkId == productReworkId ?
						0 : warmup.Seconds + changeover.Seconds;
					
					var seq = findSequenceOfSpotsBetween(startFrom, only.StartDT);
					if(only.ProductReworkId != productReworkId)
						seq.Add(SmartRange.NewSetup(only.StartDT.AddSeconds(-reverseSetupDelay), warmup, changeover, stationId));//???

					if(validateSequence(seq, (int)only.StartDT.Subtract(startFrom).TotalSeconds)) 
						return seq;
					//if not enough space between startFrom and the only task: use the end of it as start of sequence finding
					// --|--1111-------
					// --|--1111xTTTT--
					else
						return findSequenceOfSpotsBetween(only.EndDT, null);
				}
			}
			//if more than 1 task:
			else
			{
				var first = inRangeItems.First();

				//if the first task, starts after startFrom and enough space between startFrom and first task:
				//					use startFrom as start of sequence finding and also add a reverse setup (from T to 1)
				// --|--------1111
				// --|xTTTT--x1111 snapToLast
				// --|xTTTTx--1111 snapToFirst
				if (first.StartDT > startFrom)
				{
					//check if after-task setup is needed
					var warmup = first.ProductReworkId == productReworkId ?
						null : new DataServices.WarmupDataService().SmartFind(first.ProductReworkId, stationId);
					var changeover = first.ProductReworkId == productReworkId ?
						null : new DataServices.ChangeoverDataService().SmartFind(productReworkId, first.ProductReworkId, stationId);
					int reverseSetupDelay = first.ProductReworkId == productReworkId ?
						0 : warmup.Seconds + changeover.Seconds;

					var seq = findSequenceOfSpotsBetween(startFrom, first.StartDT);
					if (first.ProductReworkId != productReworkId)
						seq.Add(SmartRange.NewSetup(first.StartDT.AddSeconds(-reverseSetupDelay), warmup, changeover, stationId));//???
					
					if (validateSequence(seq, (int)first.StartDT.Subtract(startFrom).TotalSeconds))
						return seq;
				}
				// after task prev and before inRangeTask
				// --|--prev--------inRangeTask
				// --|--prevxTTTT--xinRangeTask snapToLast
				// --|--prevxTTTTx--inRangeTask snapToFirst
				//for any of above ifs: 'else'
				{
					SmartRange prev = null;
					foreach (var inRangeTask in inRangeItems)
					{
						if (prev != null)
						{
							//if enough space between i & i+1: use end of i as start of sequence finding
							if (inRangeTask.StartDT.Subtract(prev.EndDT) >= minFreeSpace)
							{
								//check if after-task setup is needed
								var warmup = inRangeTask.ProductReworkId == productReworkId ?
									null : new DataServices.WarmupDataService().SmartFind(inRangeTask.ProductReworkId, stationId);
								var changeover = inRangeTask.ProductReworkId == productReworkId ?
									null : new DataServices.ChangeoverDataService().SmartFind(productReworkId, inRangeTask.ProductReworkId, stationId);
								int reverseSetupDelay = inRangeTask.ProductReworkId == productReworkId ?
									0 : warmup.Seconds + changeover.Seconds;

								var seq = findSequenceOfSpotsBetween(prev.EndDT, inRangeTask.StartDT);
								if(inRangeTask.ProductReworkId != productReworkId)
								seq.Add(SmartRange.NewSetup(inRangeTask.StartDT.AddSeconds(-reverseSetupDelay), warmup, changeover, stationId));//???

								if (validateSequence(seq, (int)inRangeTask.StartDT.Subtract(prev.EndDT).TotalSeconds))
									return seq;
							}
						}
						prev = inRangeTask;
					}
					//if not enough space between tasks: use end of last task as start of sequence finding
					// --|--last-------
					// --|--lastxTTTT--
					return findSequenceOfSpotsBetween(inRangeItems.Last().EndDT, null);
				}
			}
		}