public void ErrorsOnMissingProgram()
        {
            //Test when processes have different pallet lists
            var job1 = new JobPlan("Job1", 2, new int[] { 2, 2 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);

            job1.AddProcessOnPallet(1, 1, "4");
            job1.AddProcessOnPallet(1, 2, "10");
            job1.AddProcessOnPallet(2, 1, "40");
            job1.AddProcessOnPallet(2, 2, "100");

            AddBasicStopsWithProg(job1);

            var dset = CreateReadSet();

            var log  = new List <string>();
            var pMap = ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1 },
                3,
                dset,
                new HashSet <string>(),
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            log.Should().BeEquivalentTo(new[] {
                // one for each process
                "Part Part1 program 1234 does not exist in the cell controller.",
                "Part Part1 program 1234 does not exist in the cell controller."
            });
        }
        public void ErrorsOnLongFixture()
        {
            //Test when processes have different pallet lists
            var job1 = new JobPlan("Job1", 1, new int[] { 1 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.AddProcessOnPallet(1, 1, "4");
            job1.SetFixtureFace(1, 1, "aaaaaaaaaaaaaaaaa", 1);

            AddBasicStopsWithProg(job1);

            var dset = CreateReadSet();

            CreateProgram(dset, "1234");

            var    log = new List <string>();
            Action act = () =>
                         ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1 },
                3,
                dset,
                new HashSet <string>(),
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            act
            .Should()
            .Throw <BadRequestException>()
            .WithMessage(
                "Fixture aaaaaaaaaaaaaaaaa:4 is too long to fit in the mazak databases"
                );
        }
Exemple #3
0
        private JobPlan CreateJob()
        {
            var job1 = new JobPlan("Unique1", 2, new int[] { 2, 3 });

            job1.PartName = "Job1";
            job1.SetPlannedCyclesOnFirstProcess(1, 125);
            job1.SetPlannedCyclesOnFirstProcess(2, 53);
            job1.RouteStartingTimeUTC                    = DateTime.Parse("2019-10-22 20:24 GMT").ToUniversalTime();
            job1.RouteEndingTimeUTC                      = job1.RouteStartingTimeUTC.AddHours(100);
            job1.Archived                                = false;
            job1.JobCopiedToSystem                       = true;
            job1.ScheduleId                              = "Job1tag1245";
            job1.HoldEntireJob.UserHold                  = true;
            job1.HoldEntireJob.ReasonForUserHold         = "test string";
            job1.HoldEntireJob.HoldUnholdPatternStartUTC = job1.RouteStartingTimeUTC;
            job1.HoldEntireJob.HoldUnholdPatternRepeats  = true;
            job1.HoldEntireJob.HoldUnholdPattern.Add(TimeSpan.FromMinutes(10));
            job1.HoldEntireJob.HoldUnholdPattern.Add(TimeSpan.FromMinutes(18));
            job1.HoldEntireJob.HoldUnholdPattern.Add(TimeSpan.FromMinutes(125));
            job1.Priority         = 164;
            job1.Comment          = "Hello there";
            job1.CreateMarkerData = true;
            job1.ScheduledBookingIds.Add("booking1");
            job1.ScheduledBookingIds.Add("booking2");
            job1.ScheduledBookingIds.Add("booking3");

            job1.SetPartsPerPallet(1, 1, 10);
            job1.SetPartsPerPallet(1, 2, 15);
            job1.SetPartsPerPallet(2, 1, 20);
            job1.SetPartsPerPallet(2, 2, 22);
            job1.SetPartsPerPallet(2, 3, 23);

            job1.SetPathGroup(1, 1, 64);
            job1.SetPathGroup(1, 2, 74);
            job1.SetPathGroup(2, 1, 12);
            job1.SetPathGroup(2, 2, 88);
            job1.SetPathGroup(2, 3, 5);

            job1.SetInputQueue(1, 1, "in11");
            job1.SetOutputQueue(1, 2, "out12");
            job1.SetInputQueue(2, 1, "in21");
            job1.SetOutputQueue(2, 3, "out23");

            job1.SetSimulatedStartingTimeUTC(1, 1, DateTime.Parse("1/5/2011 11:34 PM GMT").ToUniversalTime());
            job1.SetSimulatedStartingTimeUTC(1, 2, DateTime.Parse("2/10/2011 12:45 AM GMT").ToUniversalTime());
            job1.SetSimulatedStartingTimeUTC(2, 1, DateTime.Parse("3/14/2011 2:03 AM GMT").ToUniversalTime());
            job1.SetSimulatedStartingTimeUTC(2, 2, DateTime.Parse("4/20/2011 3:22 PM GMT").ToUniversalTime());
            job1.SetSimulatedStartingTimeUTC(2, 3, DateTime.Parse("5/22/2011 4:18 AM GMT").ToUniversalTime());

            job1.SetSimulatedAverageFlowTime(1, 1, TimeSpan.FromMinutes(0.5));
            job1.SetSimulatedAverageFlowTime(1, 2, TimeSpan.FromMinutes(1.5));
            job1.SetSimulatedAverageFlowTime(2, 1, TimeSpan.FromMinutes(2.5));
            job1.SetSimulatedAverageFlowTime(2, 2, TimeSpan.FromMinutes(3.5));
            job1.SetSimulatedAverageFlowTime(2, 3, TimeSpan.FromMinutes(4.5));

            job1.AddProcessOnPallet(1, 1, "Pal2");
            job1.AddProcessOnPallet(1, 1, "Pal5");
            job1.AddProcessOnPallet(1, 2, "Pal4");
            job1.AddProcessOnPallet(1, 2, "Pal35");
            job1.AddProcessOnPallet(2, 1, "Pal12");
            job1.AddProcessOnPallet(2, 1, "Pal64");
            job1.AddProcessOnPallet(2, 2, "Hi");
            job1.AddProcessOnPallet(2, 2, "Pal2");
            job1.AddProcessOnPallet(2, 3, "Pal5");
            job1.AddProcessOnPallet(2, 3, "OMG");

            job1.SetFixtureFace(1, 1, "Fix1", 1);
            job1.SetFixtureFace(1, 2, "ABC", 4);
            job1.SetFixtureFace(2, 1, "Fix123", 6);
            // 2, 2 has non-integer face, so should be ignored
            job1.SetFixtureFace(2, 3, "Fix17", 7);

            job1.AddLoadStation(1, 1, 35);
            job1.AddLoadStation(1, 1, 64);
            job1.AddLoadStation(1, 2, 785);
            job1.AddLoadStation(1, 2, 15);
            job1.AddLoadStation(2, 1, 647);
            job1.AddLoadStation(2, 1, 474);
            job1.AddLoadStation(2, 2, 785);
            job1.AddLoadStation(2, 2, 53);
            job1.AddLoadStation(2, 3, 15);

            job1.SetExpectedLoadTime(1, 1, TimeSpan.FromSeconds(100));
            job1.SetExpectedLoadTime(1, 2, TimeSpan.FromMinutes(53));
            job1.SetExpectedLoadTime(2, 1, TimeSpan.FromHours(52));
            job1.SetExpectedLoadTime(2, 2, TimeSpan.FromSeconds(98));
            job1.SetExpectedLoadTime(2, 3, TimeSpan.FromSeconds(35));

            job1.AddUnloadStation(1, 1, 75);
            job1.AddUnloadStation(1, 1, 234);
            job1.AddUnloadStation(1, 2, 53);
            job1.AddUnloadStation(2, 1, 563);
            job1.AddUnloadStation(2, 2, 2);
            job1.AddUnloadStation(2, 2, 12);
            job1.AddUnloadStation(2, 3, 32);

            job1.SetExpectedUnloadTime(1, 1, TimeSpan.FromSeconds(13));
            job1.SetExpectedUnloadTime(1, 2, TimeSpan.FromMinutes(12));
            job1.SetExpectedUnloadTime(2, 1, TimeSpan.FromHours(63));
            job1.SetExpectedUnloadTime(2, 2, TimeSpan.FromSeconds(73));
            job1.SetExpectedUnloadTime(2, 3, TimeSpan.FromSeconds(532));

            var route = new JobMachiningStop("Machine");

            route.Stations.Add(12);
            route.Stations.Add(23);
            route.ProgramName       = "Emily";
            route.ExpectedCycleTime = TimeSpan.FromHours(1.2);
            route.Tools["tool1"]    = TimeSpan.FromMinutes(30);
            route.Tools["tool2"]    = TimeSpan.FromMinutes(35);
            job1.AddMachiningStop(1, 1, route);

            route = new JobMachiningStop("Other Machine");
            route.Stations.Add(23);
            route.Stations.Add(12);
            route.ProgramName       = "awef";
            route.ExpectedCycleTime = TimeSpan.FromHours(2.8);
            route.Tools["tool1"]    = TimeSpan.FromMinutes(9);
            route.Tools["tool33"]   = TimeSpan.FromMinutes(42);
            job1.AddMachiningStop(1, 2, route);

            route = new JobMachiningStop("Test");
            route.Stations.Add(64);
            route.Stations.Add(323);
            route.ProgramName       = "Goodbye";
            route.ExpectedCycleTime = TimeSpan.FromHours(6.3);
            route.Tools["tool2"]    = TimeSpan.FromMinutes(12);
            route.Tools["tool44"]   = TimeSpan.FromMinutes(99);
            job1.AddMachiningStop(2, 1, route);

            route = new JobMachiningStop("Test");
            route.Stations.Add(32);
            route.Stations.Add(64);
            route.ProgramName = "wefq";
            job1.AddMachiningStop(2, 2, route);

            route = new JobMachiningStop("Test");
            route.Stations.Add(245);
            route.Stations.Add(36);
            route.ProgramName = "dduuude";
            job1.AddMachiningStop(2, 1, route);

            route = new JobMachiningStop("Test");
            route.Stations.Add(23);
            route.Stations.Add(53);
            route.ProgramName = "so cool";
            job1.AddMachiningStop(2, 2, route);

            job1.AddInspection(new JobInspectionData("Insp1", "counter1", 53, TimeSpan.FromMinutes(100), 12));
            job1.AddInspection(new JobInspectionData("Insp2", "counter1", 12, TimeSpan.FromMinutes(64)));
            job1.AddInspection(new JobInspectionData("Insp3", "abcdef", 175, TimeSpan.FromMinutes(121), 2));
            job1.AddInspection(new JobInspectionData("Insp4", "counter2", 16.12, TimeSpan.FromMinutes(33)));
            job1.AddInspection(new JobInspectionData("Insp5", "counter3", 0.544, TimeSpan.FromMinutes(44)));

            job1.HoldMachining(1, 1).UserHold                  = false;
            job1.HoldMachining(1, 1).ReasonForUserHold         = "reason for user hold";
            job1.HoldMachining(1, 1).HoldUnholdPatternRepeats  = false;
            job1.HoldMachining(1, 1).HoldUnholdPatternStartUTC = DateTime.Parse("2010/5/3 7:32 PM").ToUniversalTime();
            job1.HoldMachining(1, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(5));
            job1.HoldMachining(1, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(53));

            job1.HoldMachining(1, 2).UserHold                  = true;
            job1.HoldMachining(1, 2).ReasonForUserHold         = "another reason for user hold";
            job1.HoldMachining(1, 2).HoldUnholdPatternRepeats  = true;
            job1.HoldMachining(1, 2).HoldUnholdPatternStartUTC = DateTime.Parse("2010/5/12 6:12 PM").ToUniversalTime();
            job1.HoldMachining(1, 2).HoldUnholdPattern.Add(TimeSpan.FromMinutes(84));
            job1.HoldMachining(1, 2).HoldUnholdPattern.Add(TimeSpan.FromMinutes(1));

            job1.HoldMachining(2, 1).UserHold                  = false;
            job1.HoldMachining(2, 1).ReasonForUserHold         = "oh my reason for user hold";
            job1.HoldMachining(2, 1).HoldUnholdPatternRepeats  = true;
            job1.HoldMachining(2, 1).HoldUnholdPatternStartUTC = DateTime.Parse("2010/9/1 1:30 PM").ToUniversalTime();
            job1.HoldMachining(2, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(532));
            job1.HoldMachining(2, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(64));

            job1.HoldLoadUnload(1, 1).UserHold                  = true;
            job1.HoldLoadUnload(1, 1).ReasonForUserHold         = "abcdef";
            job1.HoldLoadUnload(1, 1).HoldUnholdPatternRepeats  = true;
            job1.HoldLoadUnload(1, 1).HoldUnholdPatternStartUTC = DateTime.Parse("2010/12/2 3:32 PM").ToUniversalTime();
            job1.HoldLoadUnload(1, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(63));
            job1.HoldLoadUnload(1, 1).HoldUnholdPattern.Add(TimeSpan.FromMinutes(7));

            job1.HoldLoadUnload(1, 2).UserHold                  = false;
            job1.HoldLoadUnload(1, 2).ReasonForUserHold         = "agr";
            job1.HoldLoadUnload(1, 2).HoldUnholdPatternRepeats  = false;
            job1.HoldLoadUnload(1, 2).HoldUnholdPatternStartUTC = DateTime.Parse("2010/6/1 3:12 PM").ToUniversalTime();
            job1.HoldLoadUnload(1, 2).HoldUnholdPattern.Add(TimeSpan.FromMinutes(174));
            job1.HoldLoadUnload(1, 2).HoldUnholdPattern.Add(TimeSpan.FromMinutes(83));

            job1.HoldLoadUnload(2, 3).UserHold                  = true;
            job1.HoldLoadUnload(2, 3).ReasonForUserHold         = "erhagsad";
            job1.HoldLoadUnload(2, 3).HoldUnholdPatternRepeats  = false;
            job1.HoldLoadUnload(2, 3).HoldUnholdPatternStartUTC = DateTime.Parse("2010/11/5 9:30 AM").ToUniversalTime();
            job1.HoldLoadUnload(2, 3).HoldUnholdPattern.Add(TimeSpan.FromMinutes(32));
            job1.HoldLoadUnload(2, 3).HoldUnholdPattern.Add(TimeSpan.FromMinutes(64));

            return(job1);
        }
Exemple #4
0
        private static void AddRoutingToJob(MazakSchedulesPartsPallets mazakData, MazakPartRow partRow, JobPlan job, IMachineGroupName machineGroupName, MazakPart.IProcToPath procToPath, MazakDbType mazakTy)
        {
            //Add routing and pallets
            foreach (var partProcRow in partRow.Processes)
            {
                var path = procToPath.PathForProc(partProcRow.ProcessNumber);
                job.SetPartsPerPallet(partProcRow.ProcessNumber, path, partProcRow.FixQuantity);
                job.SetPathGroup(partProcRow.ProcessNumber, path, path);
                job.SetHoldMachining(partProcRow.ProcessNumber, path, job.HoldMachining(partProcRow.ProcessNumber, path));
                job.SetHoldLoadUnload(partProcRow.ProcessNumber, path, job.HoldLoadUnload(partProcRow.ProcessNumber, path));

                //Routing
                string fixStr    = partProcRow.FixLDS;
                string cutStr    = partProcRow.CutMc;
                string removeStr = partProcRow.RemoveLDS;

                if (mazakTy != MazakDbType.MazakVersionE)
                {
                    fixStr    = ConvertStatIntV2ToV1(Convert.ToInt32(fixStr));
                    cutStr    = ConvertStatIntV2ToV1(Convert.ToInt32(cutStr));
                    removeStr = ConvertStatIntV2ToV1(Convert.ToInt32(removeStr));
                }

                foreach (char c in fixStr)
                {
                    if (c != '0')
                    {
                        job.AddLoadStation(partProcRow.ProcessNumber, path, int.Parse(c.ToString()));
                    }
                }
                foreach (char c in removeStr)
                {
                    if (c != '0')
                    {
                        job.AddUnloadStation(partProcRow.ProcessNumber, path, int.Parse(c.ToString()));
                    }
                }

                JobMachiningStop routeStop = null;
                foreach (char c in cutStr)
                {
                    if (c != '0')
                    {
                        if (routeStop == null)
                        {
                            routeStop = new JobMachiningStop(machineGroupName.MachineGroupName);
                            job.AddMachiningStop(partProcRow.ProcessNumber, path, routeStop);
                        }
                        routeStop.Stations.Add(int.Parse(c.ToString()));
                    }
                }

                if (routeStop != null)
                {
                    routeStop.ProgramName = partProcRow.MainProgram;
                }

                //Planned Pallets
                foreach (var palRow in mazakData.Pallets)
                {
                    if (palRow.PalletNumber > 0 &&
                        palRow.Fixture == partProcRow.Fixture &&
                        !job.HasPallet(partProcRow.ProcessNumber, path, palRow.PalletNumber.ToString()))
                    {
                        job.AddProcessOnPallet(partProcRow.ProcessNumber, path, palRow.PalletNumber.ToString());
                    }
                }
            }
        }
        public void AddsSchedules()
        {
            //basic job
            var job1 = new JobPlan("uniq1", 2, new int[] { 2, 2 });

            job1.PartName = "part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);
            job1.SetSimulatedStartingTimeUTC(1, 1, new DateTime(2018, 1, 9, 8, 7, 6, DateTimeKind.Local).ToUniversalTime());
            job1.SetSimulatedStartingTimeUTC(1, 2, new DateTime(2018, 1, 2, 3, 4, 5, DateTimeKind.Local).ToUniversalTime());
            job1.SetPlannedCyclesOnFirstProcess(1, 51);
            job1.SetPlannedCyclesOnFirstProcess(2, 41);
            job1.SetFixtureFace(1, 1, "fixA", 1);
            job1.SetFixtureFace(1, 2, "fixA", 1);
            job1.SetFixtureFace(2, 1, "fixA", 2);
            job1.SetFixtureFace(2, 2, "fixA", 2);

            //one with an input queue
            var job2 = new JobPlan("uniq2", 2, new int[] { 2, 2 });

            job2.PartName = "part2";
            job2.SetPathGroup(1, 1, 1);
            job2.SetPathGroup(1, 2, 2);
            job2.SetPathGroup(2, 1, 1);
            job2.SetPathGroup(2, 2, 2);
            job2.SetSimulatedStartingTimeUTC(1, 1, new DateTime(2018, 2, 9, 8, 7, 6, DateTimeKind.Local).ToUniversalTime());
            job2.SetSimulatedStartingTimeUTC(1, 2, new DateTime(2018, 2, 2, 3, 4, 5, DateTimeKind.Local).ToUniversalTime());
            job2.SetPlannedCyclesOnFirstProcess(1, 12);
            job2.SetPlannedCyclesOnFirstProcess(2, 42);
            job2.SetInputQueue(1, 1, "aaa");
            job2.SetInputQueue(1, 2, "bbb");
            job2.SetFixtureFace(1, 1, "fixA", 2); // conflicts with both job1 paths
            job2.SetFixtureFace(2, 2, "fixB", 2); // no conflicts

            //a schedule which already exists
            var job3 = new JobPlan("uniq3", 2, new int[] { 1, 1 });

            job3.PartName = "part3";
            job3.SetSimulatedStartingTimeUTC(1, 1, new DateTime(2018, 3, 9, 8, 7, 6, DateTimeKind.Local).ToUniversalTime());
            job3.SetPlannedCyclesOnFirstProcess(1, 23);

            // all the parts, plus a schedule for uniq3
            var curData = new MazakSchedulesPartsPallets()
            {
                Parts = new[] {
                    new MazakPartRow()
                    {
                        PartName = "part1:6:1",
                        Comment  = MazakPart.CreateComment("uniq1", new[] { 1, 1 }, false)
                    },
                    new MazakPartRow()
                    {
                        PartName = "part1:6:2",
                        Comment  = MazakPart.CreateComment("uniq1", new[] { 2, 2 }, false)
                    },
                    new MazakPartRow()
                    {
                        PartName = "part2:6:1",
                        Comment  = MazakPart.CreateComment("uniq2", new[] { 1, 1 }, false)
                    },
                    new MazakPartRow()
                    {
                        PartName = "part2:6:2",
                        Comment  = MazakPart.CreateComment("uniq2", new[] { 2, 2 }, false)
                    },
                    new MazakPartRow()
                    {
                        PartName = "part3:6:1",
                        Comment  = MazakPart.CreateComment("uniq3", new[] { 1, 1 }, false)
                    }
                },
                Schedules = new[] {
                    new MazakScheduleRow()
                    {
                        Id       = 1,
                        PartName = "part3:6:1",
                        Comment  = MazakPart.CreateComment("uniq3", new[] { 1, 1 }, false)
                    }
                }
            };

            var actions = BuildMazakSchedules.AddSchedules(curData, new[] { job1, job2, job3 }, true);

            actions.Parts.Should().BeEmpty();
            actions.Fixtures.Should().BeEmpty();
            actions.Pallets.Should().BeEmpty();

            actions.Schedules.Should().BeEquivalentTo(new[]
            {
                //uniq1
                new MazakScheduleRow()
                {
                    Command      = MazakWriteCommand.Add,
                    Id           = 2,
                    PartName     = "part1:6:1",
                    Comment      = MazakPart.CreateComment("uniq1", new[] { 1, 1 }, false),
                    PlanQuantity = 51,
                    Priority     = 91 + 1, // one earlier conflict
                    DueDate      = new DateTime(2018, 1, 9, 0, 0, 0, DateTimeKind.Local),
                    Processes    =
                    {
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 2,
                            ProcessNumber           = 1,
                            ProcessMaterialQuantity = 51
                        },
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 2,
                            ProcessNumber           = 2,
                            ProcessMaterialQuantity = 0
                        },
                    }
                },
                new MazakScheduleRow()
                {
                    Command      = MazakWriteCommand.Add,
                    Id           = 3,
                    PartName     = "part1:6:2",
                    Comment      = MazakPart.CreateComment("uniq1", new[] { 2, 2 }, false),
                    PlanQuantity = 41,
                    Priority     = 91,
                    DueDate      = new DateTime(2018, 1, 2, 0, 0, 0, DateTimeKind.Local),
                    Processes    =
                    {
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 3,
                            ProcessNumber           = 1,
                            ProcessMaterialQuantity = 41
                        },
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 3,
                            ProcessNumber           = 2,
                            ProcessMaterialQuantity = 0
                        },
                    }
                },

                //uniq2
                new MazakScheduleRow()
                {
                    Command      = MazakWriteCommand.Add,
                    Id           = 4,
                    PartName     = "part2:6:1",
                    Comment      = MazakPart.CreateComment("uniq2", new[] { 1, 1 }, false),
                    PlanQuantity = 12,
                    Priority     = 91 + 2, // conflicts with 2 earlier
                    DueDate      = new DateTime(2018, 2, 9, 0, 0, 0, DateTimeKind.Local),
                    Processes    =
                    {
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 4,
                            ProcessNumber           = 1,
                            ProcessMaterialQuantity = 0 // no material, input queue
                        },
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 4,
                            ProcessNumber           = 2,
                            ProcessMaterialQuantity = 0
                        },
                    }
                },
                new MazakScheduleRow()
                {
                    Command      = MazakWriteCommand.Add,
                    Id           = 5,
                    PartName     = "part2:6:2",
                    Comment      = MazakPart.CreateComment("uniq2", new[] { 2, 2 }, false),
                    PlanQuantity = 42,
                    Priority     = 91,
                    DueDate      = new DateTime(2018, 2, 2, 0, 0, 0, DateTimeKind.Local),
                    Processes    =
                    {
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 5,
                            ProcessNumber           = 1,
                            ProcessMaterialQuantity = 0 //no material, input queue
                        },
                        new MazakScheduleProcessRow()
                        {
                            MazakScheduleRowId      = 5,
                            ProcessNumber           = 2,
                            ProcessMaterialQuantity = 0
                        },
                    }
                }
            });
        }
Exemple #6
0
        public void MultplePathsAndProcs()
        {
            // path 1: plan 50, complete 30, 5 in-proc #1, 3 in-proc #2, 2 material proc #2, 0 material proc1 (has input queue).  10 un-started parts
            // path 2: plan 25, complete 3, 2 in-proc #1, 4 in-proc #2, 3 material proc #2, 25 - 3 - 2 - 4 - 3 = 13 un-started parts
            _read.LoadSchedulesAndLoadActions().Returns(new MazakSchedulesAndLoadActions()
            {
                Schedules = new[] {
                    new MazakScheduleRow()
                    {
                        Id               = 15,
                        Comment          = MazakPart.CreateComment("uuuu", new[] { 1, 2 }, false),
                        PartName         = "pppp:1",
                        PlanQuantity     = 50,
                        CompleteQuantity = 30,
                        Processes        = new List <MazakScheduleProcessRow> {
                            new MazakScheduleProcessRow()
                            {
                                MazakScheduleRowId      = 15,
                                FixQuantity             = 1,
                                ProcessNumber           = 1,
                                ProcessMaterialQuantity = 0,
                                ProcessExecuteQuantity  = 5
                            },
                            new MazakScheduleProcessRow()
                            {
                                MazakScheduleRowId      = 15,
                                FixQuantity             = 1,
                                ProcessNumber           = 2,
                                ProcessMaterialQuantity = 2,
                                ProcessExecuteQuantity  = 3
                            }
                        }
                    },
                    new MazakScheduleRow()
                    {
                        Id               = 16,
                        Comment          = MazakPart.CreateComment("uuuu", new[] { 2, 1 }, false),
                        PartName         = "pppp:1",
                        PlanQuantity     = 25,
                        CompleteQuantity = 3,
                        Processes        = new List <MazakScheduleProcessRow> {
                            new MazakScheduleProcessRow()
                            {
                                MazakScheduleRowId      = 16,
                                FixQuantity             = 1,
                                ProcessNumber           = 1,
                                ProcessMaterialQuantity = 0,
                                ProcessExecuteQuantity  = 2
                            },
                            new MazakScheduleProcessRow()
                            {
                                MazakScheduleRowId      = 16,
                                FixQuantity             = 1,
                                ProcessNumber           = 2,
                                ProcessMaterialQuantity = 3,
                                ProcessExecuteQuantity  = 4
                            }
                        }
                    }
                }
            });

            var j = new JobPlan("uuuu", 2, new[] { 2, 2 });

            j.PartName = "pppp";
            j.SetPlannedCyclesOnFirstProcess(path: 1, numCycles: 50);
            j.SetPlannedCyclesOnFirstProcess(path: 2, numCycles: 25);
            j.SetPathGroup(process: 1, path: 1, pgroup: 1);
            j.SetPathGroup(process: 2, path: 2, pgroup: 1);
            j.SetPathGroup(process: 1, path: 2, pgroup: 2);
            j.SetPathGroup(process: 2, path: 1, pgroup: 2);
            j.SetInputQueue(process: 1, path: 1, queue: "castings");
            j.SetInputQueue(process: 1, path: 2, queue: "castings");
            _jobDB.AddJobs(new NewJobs()
            {
                Jobs = new List <JobPlan> {
                    j
                }
            }, null);

            var now = DateTime.UtcNow;

            _decr.Decrement(now);

            _write.Schedules.Count.Should().Be(2);
            _write.Schedules[0].Id.Should().Be(15);
            _write.Schedules[0].PlanQuantity.Should().Be(50 - 10);
            _write.Schedules[1].Id.Should().Be(16);
            _write.Schedules[1].PlanQuantity.Should().Be(25 - 13);

            _jobDB.LoadDecrementsForJob("uuuu").Should().BeEquivalentTo(new[] {
                new InProcessJobDecrement()
                {
                    DecrementId = 0,
                    TimeUTC     = now,
                    Quantity    = 10 + 13
                }
            });
        }
        public void DeleteUnusedPartsPals()
        {
            //Test when processes have different pallet lists
            var job1 = new JobPlan("Job1", 2, new int[] { 2, 2 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);

            job1.AddProcessOnPallet(1, 1, "4");
            job1.AddProcessOnPallet(1, 1, "5");
            job1.AddProcessOnPallet(1, 2, "10");
            job1.AddProcessOnPallet(1, 2, "11");
            job1.AddProcessOnPallet(1, 2, "12");
            job1.AddProcessOnPallet(2, 1, "40");
            job1.AddProcessOnPallet(2, 1, "50");
            job1.AddProcessOnPallet(2, 2, "100");
            job1.AddProcessOnPallet(2, 2, "110");
            job1.AddProcessOnPallet(2, 2, "120");

            AddBasicStopsWithProg(job1);

            var dset = CreateReadSet();

            CreateFixture(dset, "aaaa:1");
            CreatePart(dset, "uniq1", "part1:1:1", 1, "aaaa");
            CreatePart(dset, "uniq2", "part2:1:1", 1, "Test");
            CreatePallet(dset, 5, "aaaa", 1); // this should be deleted since part1:1:1 is being deleted
            CreatePallet(dset, 6, "Test", 1); // this should be kept because part2:1:1 is being kept
            CreateProgram(dset, "1234");

            var log  = new List <string>();
            var pMap = ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1 },
                3,
                dset,
                new HashSet <string>()
            {
                "part2:1:1"
            },
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            if (log.Count > 0)
            {
                Assert.True(false, log[0]);
            }

            var del = pMap.DeleteOldPartPalletRows();

            del.Pallets.Should().BeEquivalentTo(new[] {
                new MazakPalletRow()
                {
                    PalletNumber = 5,
                    Fixture      = "aaaa:1",
                    Command      = MazakWriteCommand.Delete
                }
            });
            dset.TestParts[0].Command      = MazakWriteCommand.Delete;
            dset.TestParts[0].TotalProcess = dset.TestParts[0].Processes.Count;
            dset.TestParts[0].Processes.Clear();
            del.Parts.Should().BeEquivalentTo(new[] {
                dset.TestParts[0]
            });
            del.Fixtures.Should().BeEmpty();
            del.Schedules.Should().BeEmpty();
        }
        public void ManualFixtureAssignment()
        {
            var job1 = new JobPlan("Job1", 2, new int[] { 2, 2 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);

            //proc 1 and proc 2 on same pallets
            job1.AddProcessOnPallet(1, 1, "4");
            job1.AddProcessOnPallet(1, 1, "5");
            job1.AddProcessOnPallet(1, 2, "10");
            job1.AddProcessOnPallet(1, 2, "11");
            job1.AddProcessOnPallet(1, 2, "12");
            job1.AddProcessOnPallet(2, 1, "4");
            job1.AddProcessOnPallet(2, 1, "5");
            job1.AddProcessOnPallet(2, 2, "10");
            job1.AddProcessOnPallet(2, 2, "11");
            job1.AddProcessOnPallet(2, 2, "12");

            //each process uses different faces
            job1.SetFixtureFace(1, 1, "fixAA", 1);
            job1.SetFixtureFace(2, 1, "fixAA", 2);
            job1.SetFixtureFace(1, 2, "fixBB", 1);
            job1.SetFixtureFace(2, 2, "fixBB", 2);

            AddBasicStopsWithProg(job1);

            var job2 = new JobPlan("Job2", 2, new int[] { 2, 2 });

            job2.PartName = "Part2";

            //make path groups twisted
            job2.SetPathGroup(1, 1, 1);
            job2.SetPathGroup(1, 2, 2);
            job2.SetPathGroup(2, 1, 2);
            job2.SetPathGroup(2, 2, 1);

            //process groups on the same pallet.
            job2.AddProcessOnPallet(1, 1, "4");
            job2.AddProcessOnPallet(1, 1, "5");
            job2.AddProcessOnPallet(1, 2, "10");
            job2.AddProcessOnPallet(1, 2, "11");
            job2.AddProcessOnPallet(1, 2, "12");
            job2.AddProcessOnPallet(2, 2, "4");
            job2.AddProcessOnPallet(2, 2, "5");
            job2.AddProcessOnPallet(2, 1, "10");
            job2.AddProcessOnPallet(2, 1, "11");
            job2.AddProcessOnPallet(2, 1, "12");

            //each process uses different faces
            job2.SetFixtureFace(1, 1, "fixAA", 1);
            job2.SetFixtureFace(2, 2, "fixAA", 2);
            job2.SetFixtureFace(1, 2, "fixBB", 1);
            job2.SetFixtureFace(2, 1, "fixBB", 2);

            AddBasicStopsWithProg(job2);

            var job3 = new JobPlan("Job3", 1, new int[] { 2 });

            job3.PartName = "Part3";
            job3.AddProcessOnPallet(1, 1, "20");
            job3.AddProcessOnPallet(1, 1, "21");
            job3.AddProcessOnPallet(1, 2, "30");
            job3.AddProcessOnPallet(1, 2, "31");

            //job3 uses separate fixture than job 4, but same fixture and face for both procs
            job3.SetFixtureFace(1, 1, "fix3", 1);
            job3.SetFixtureFace(1, 2, "fix3", 1);

            AddBasicStopsWithProg(job3);

            var job4 = new JobPlan("Job4", 1, new int[] { 2 });

            job4.PartName = "Part4";
            job4.AddProcessOnPallet(1, 1, "20");
            job4.AddProcessOnPallet(1, 1, "21");
            job4.AddProcessOnPallet(1, 2, "30");
            job4.AddProcessOnPallet(1, 2, "31");

            //job3 uses separate fixture than job 4
            job4.SetFixtureFace(1, 1, "fix4", 1);
            job4.SetFixtureFace(1, 2, "fix4", 1);

            AddBasicStopsWithProg(job4);

            var log = new List <string>();

            var dset = CreateReadSet();

            CreateProgram(dset, "1234");

            var pMap = ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1, job2, job3, job4 },
                3,
                dset,
                new HashSet <string>(),
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            if (log.Count > 0)
            {
                Assert.True(false, log[0]);
            }

            CheckNewFixtures(pMap, new string[] {
                "F:3:fixAA:4:1",
                "F:3:fixAA:4:2",
                "F:3:fixBB:10:1",
                "F:3:fixBB:10:2",
                "F:3:fix3:20:1",
                "F:3:fix3:30:1",
                "F:3:fix4:20:1",
                "F:3:fix4:30:1",
            }, new[] { "Test" });

            var trans = pMap.CreatePartPalletDatabaseRows();

            CheckPartProcessFromJob(trans, "Part1:3:1", 1, "F:3:fixAA:4:1");
            CheckPartProcessFromJob(trans, "Part1:3:1", 2, "F:3:fixAA:4:2");
            CheckPart(trans, "Part1:3:1", "Job1-Path1-1-0");

            CheckPartProcessFromJob(trans, "Part1:3:2", 1, "F:3:fixBB:10:1");
            CheckPartProcessFromJob(trans, "Part1:3:2", 2, "F:3:fixBB:10:2");
            CheckPart(trans, "Part1:3:2", "Job1-Path2-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:1", 1, "F:3:fixAA:4:1");
            CheckPartProcessFromJob(trans, "Part2:3:1", 2, "F:3:fixAA:4:2");
            CheckPart(trans, "Part2:3:1", "Job2-Path1-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:2", 1, "F:3:fixBB:10:1");
            CheckPartProcessFromJob(trans, "Part2:3:2", 2, "F:3:fixBB:10:2");
            CheckPart(trans, "Part2:3:2", "Job2-Path2-1-0");

            CheckPartProcessFromJob(trans, "Part3:3:1", 1, "F:3:fix3:20:1");
            CheckPart(trans, "Part3:3:1", "Job3-Path1-0");

            CheckPartProcessFromJob(trans, "Part3:3:2", 1, "F:3:fix3:30:1");
            CheckPart(trans, "Part3:3:2", "Job3-Path2-0");

            CheckPartProcessFromJob(trans, "Part4:3:1", 1, "F:3:fix4:20:1");
            CheckPart(trans, "Part4:3:1", "Job4-Path1-0");

            CheckPartProcessFromJob(trans, "Part4:3:2", 1, "F:3:fix4:30:1");
            CheckPart(trans, "Part4:3:2", "Job4-Path2-0");

            CheckPalletGroup(trans, 31, new[] { "F:3:fixAA:4:1", "F:3:fixAA:4:2" }, new int[] { 4, 5 });
            CheckPalletGroup(trans, 32, new[] { "F:3:fixBB:10:1", "F:3:fixBB:10:2" }, new int[] { 10, 11, 12 });
            CheckPalletGroup(trans, 33, new[] { "F:3:fix3:20:1" }, new int[] { 20, 21 });
            CheckPalletGroup(trans, 34, new[] { "F:3:fix3:30:1" }, new int[] { 30, 31 });
            CheckPalletGroup(trans, 35, new[] { "F:3:fix4:20:1" }, new int[] { 20, 21 });
            CheckPalletGroup(trans, 36, new[] { "F:3:fix4:30:1" }, new int[] { 30, 31 });

            AssertPartsPalletsDeleted(trans);
        }
        public void DifferentPallets()
        {
            //Test when processes have different pallet lists
            var job1 = new JobPlan("Job1", 2, new int[] { 2, 2 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);

            job1.AddProcessOnPallet(1, 1, "4");
            job1.AddProcessOnPallet(1, 1, "5");
            job1.AddProcessOnPallet(1, 2, "10");
            job1.AddProcessOnPallet(1, 2, "11");
            job1.AddProcessOnPallet(1, 2, "12");
            job1.AddProcessOnPallet(2, 1, "40");
            job1.AddProcessOnPallet(2, 1, "50");
            job1.AddProcessOnPallet(2, 2, "100");
            job1.AddProcessOnPallet(2, 2, "110");
            job1.AddProcessOnPallet(2, 2, "120");

            AddBasicStopsWithProg(job1);

            var job2 = new JobPlan("Job2", 2, new int[] { 2, 2 });

            job2.PartName = "Part2";

            //make path groups twisted
            job2.SetPathGroup(1, 1, 1);
            job2.SetPathGroup(1, 2, 2);
            job2.SetPathGroup(2, 1, 2);
            job2.SetPathGroup(2, 2, 1);

            //process groups on the same pallet.
            job2.AddProcessOnPallet(1, 1, "4");
            job2.AddProcessOnPallet(1, 1, "5");
            job2.AddProcessOnPallet(1, 2, "10");
            job2.AddProcessOnPallet(1, 2, "11");
            job2.AddProcessOnPallet(1, 2, "12");
            job2.AddProcessOnPallet(2, 2, "40");
            job2.AddProcessOnPallet(2, 2, "50");
            job2.AddProcessOnPallet(2, 1, "100");
            job2.AddProcessOnPallet(2, 1, "110");
            job2.AddProcessOnPallet(2, 1, "120");

            AddBasicStopsWithProg(job2);

            var job3 = new JobPlan("Job3", 2, new int[] { 2, 2 });

            job3.PartName = "Part3";

            job3.SetPathGroup(1, 1, 1);
            job3.SetPathGroup(1, 2, 2);
            job3.SetPathGroup(2, 1, 1);
            job3.SetPathGroup(2, 2, 2);

            //These do not all match above (some do, but not all)
            job3.AddProcessOnPallet(1, 1, "4");
            job3.AddProcessOnPallet(1, 1, "5");
            job3.AddProcessOnPallet(1, 2, "22");
            job3.AddProcessOnPallet(1, 2, "23");
            job3.AddProcessOnPallet(1, 2, "24");
            job3.AddProcessOnPallet(2, 1, "30");
            job3.AddProcessOnPallet(2, 1, "31");
            job3.AddProcessOnPallet(2, 2, "100");
            job3.AddProcessOnPallet(2, 2, "110");
            job3.AddProcessOnPallet(2, 2, "120");

            AddBasicStopsWithProg(job3);

            var log = new List <string>();

            var dset = new MazakTestData();

            CreateProgram(dset, "1234");

            var pMap = ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1, job2, job3 },
                3,
                dset,
                new HashSet <string>(),
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            if (log.Count > 0)
            {
                Assert.True(false, log[0]);
            }

            CheckNewFixtures(pMap, new string[] {
                "F:3:0:4:1",
                "F:3:1:40:2",
                "F:3:2:10:1",
                "F:3:3:100:2",
                "F:3:4:30:2",
                "F:3:5:22:1"
            });

            var trans = pMap.CreatePartPalletDatabaseRows();

            CheckPartProcessFromJob(trans, "Part1:3:1", 1, "F:3:0:4:1");
            CheckPartProcessFromJob(trans, "Part1:3:1", 2, "F:3:1:40:2");
            CheckPart(trans, "Part1:3:1", "Job1-Path1-1-0");

            CheckPartProcessFromJob(trans, "Part1:3:2", 1, "F:3:2:10:1");
            CheckPartProcessFromJob(trans, "Part1:3:2", 2, "F:3:3:100:2");
            CheckPart(trans, "Part1:3:2", "Job1-Path2-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:1", 1, "F:3:0:4:1");
            CheckPartProcessFromJob(trans, "Part2:3:1", 2, "F:3:1:40:2");
            CheckPart(trans, "Part2:3:1", "Job2-Path1-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:2", 1, "F:3:2:10:1");
            CheckPartProcessFromJob(trans, "Part2:3:2", 2, "F:3:3:100:2");
            CheckPart(trans, "Part2:3:2", "Job2-Path2-1-0");

            CheckPartProcessFromJob(trans, "Part3:3:1", 1, "F:3:0:4:1");
            CheckPartProcessFromJob(trans, "Part3:3:1", 2, "F:3:4:30:2");
            CheckPart(trans, "Part3:3:1", "Job3-Path1-1-0");

            CheckPartProcessFromJob(trans, "Part3:3:2", 1, "F:3:5:22:1");
            CheckPartProcessFromJob(trans, "Part3:3:2", 2, "F:3:3:100:2");
            CheckPart(trans, "Part3:3:2", "Job3-Path2-2-0");

            CheckSingleProcPalletGroup(trans, 31, "F:3:0:4:1", new int[] { 4, 5 });
            CheckSingleProcPalletGroup(trans, 32, "F:3:1:40:2", new int[] { 40, 50 });
            CheckSingleProcPalletGroup(trans, 33, "F:3:2:10:1", new int[] { 10, 11, 12 });
            CheckSingleProcPalletGroup(trans, 34, "F:3:3:100:2", new int[] { 100, 110, 120 });
            CheckSingleProcPalletGroup(trans, 35, "F:3:4:30:2", new int[] { 30, 31 });
            CheckSingleProcPalletGroup(trans, 36, "F:3:5:22:1", new int[] { 22, 23, 24 });

            AssertPartsPalletsDeleted(trans);
        }
        public void BasicFromJob()
        {
            var job1 = new JobPlan("Job1", 2, new int[] { 2, 2 });

            job1.PartName = "Part1";
            job1.SetPathGroup(1, 1, 1);
            job1.SetPathGroup(1, 2, 2);
            job1.SetPathGroup(2, 1, 1);
            job1.SetPathGroup(2, 2, 2);

            //proc 1 and proc 2 on same pallets
            job1.AddProcessOnPallet(1, 1, "4");
            job1.AddProcessOnPallet(1, 1, "5");
            job1.AddProcessOnPallet(1, 2, "10");
            job1.AddProcessOnPallet(1, 2, "11");
            job1.AddProcessOnPallet(1, 2, "12");
            job1.AddProcessOnPallet(2, 1, "4");
            job1.AddProcessOnPallet(2, 1, "5");
            job1.AddProcessOnPallet(2, 2, "10");
            job1.AddProcessOnPallet(2, 2, "11");
            job1.AddProcessOnPallet(2, 2, "12");

            AddBasicStopsWithProg(job1);

            var job2 = new JobPlan("Job2", 2, new int[] { 2, 2 });

            job2.PartName = "Part2";

            //make path groups twisted
            job2.SetPathGroup(1, 1, 1);
            job2.SetPathGroup(1, 2, 2);
            job2.SetPathGroup(2, 1, 2);
            job2.SetPathGroup(2, 2, 1);

            //process groups on the same pallet.
            job2.AddProcessOnPallet(1, 1, "4");
            job2.AddProcessOnPallet(1, 1, "5");
            job2.AddProcessOnPallet(1, 2, "10");
            job2.AddProcessOnPallet(1, 2, "11");
            job2.AddProcessOnPallet(1, 2, "12");
            job2.AddProcessOnPallet(2, 2, "4");
            job2.AddProcessOnPallet(2, 2, "5");
            job2.AddProcessOnPallet(2, 1, "10");
            job2.AddProcessOnPallet(2, 1, "11");
            job2.AddProcessOnPallet(2, 1, "12");

            AddBasicStopsWithProg(job2);

            var job3 = new JobPlan("Job3", 1, new int[] { 2 });

            job3.PartName = "Part3";
            job3.AddProcessOnPallet(1, 1, "20");
            job3.AddProcessOnPallet(1, 1, "21");
            job3.AddProcessOnPallet(1, 2, "30");
            job3.AddProcessOnPallet(1, 2, "31");

            AddBasicStopsWithProg(job3);

            //make Job 4 a template
            var job4 = new JobPlan("Job4", 1, new int[] { 2 });

            job4.PartName = "Part4";
            job4.AddProcessOnPallet(1, 1, "20");
            job4.AddProcessOnPallet(1, 1, "21");
            job4.AddProcessOnPallet(1, 2, "30");
            job4.AddProcessOnPallet(1, 2, "31");


            var log = new List <string>();

            var dset = CreateReadSet();

            CreatePart(dset, "Job4", "Part4", 1, "Test");
            CreateProgram(dset, "1234");
            CreateFixture(dset, "unusedfixture");

            var pMap = ConvertJobsToMazakParts.JobsToMazak(
                new JobPlan[] { job1, job2, job3, job4 },
                3,
                dset,
                new HashSet <string>(),
                MazakDbType.MazakVersionE,
                checkPalletsUsedOnce: false,
                fmsSettings: new FMSSettings(),
                errors: log
                );

            if (log.Count > 0)
            {
                Assert.True(false, log[0]);
            }

            CheckNewFixtures(pMap,
                             new string[] {
                "F:3:0:4:1",
                "F:3:0:4:2",
                "F:3:1:10:1",
                "F:3:1:10:2",
                "F:3:2:20:1",
                "F:3:3:30:1"
            },
                             new[] { "unusedfixture", "Test" }
                             );

            var trans = pMap.CreatePartPalletDatabaseRows();

            CheckPartProcessFromJob(trans, "Part1:3:1", 1, "F:3:0:4:1");
            CheckPartProcessFromJob(trans, "Part1:3:1", 2, "F:3:0:4:2");
            CheckPart(trans, "Part1:3:1", "Job1-Path1-1-0");

            CheckPartProcessFromJob(trans, "Part1:3:2", 1, "F:3:1:10:1");
            CheckPartProcessFromJob(trans, "Part1:3:2", 2, "F:3:1:10:2");
            CheckPart(trans, "Part1:3:2", "Job1-Path2-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:1", 1, "F:3:0:4:1");
            CheckPartProcessFromJob(trans, "Part2:3:1", 2, "F:3:0:4:2");
            CheckPart(trans, "Part2:3:1", "Job2-Path1-2-0");

            CheckPartProcessFromJob(trans, "Part2:3:2", 1, "F:3:1:10:1");
            CheckPartProcessFromJob(trans, "Part2:3:2", 2, "F:3:1:10:2");
            CheckPart(trans, "Part2:3:2", "Job2-Path2-1-0");

            CheckPartProcessFromJob(trans, "Part3:3:1", 1, "F:3:2:20:1");
            CheckPart(trans, "Part3:3:1", "Job3-Path1-0");

            CheckPartProcessFromJob(trans, "Part3:3:2", 1, "F:3:3:30:1");
            CheckPart(trans, "Part3:3:2", "Job3-Path2-0");

            CheckPartProcess(trans, "Part4:3:1", 1, "F:3:2:20:1");
            CheckPart(trans, "Part4:3:1", "Job4-Path1-0");

            CheckPartProcess(trans, "Part4:3:2", 1, "F:3:3:30:1");
            CheckPart(trans, "Part4:3:2", "Job4-Path2-0");

            CheckPalletGroup(trans, 31, "F:3:0:4", 2, new int[] { 4, 5 });
            CheckPalletGroup(trans, 32, "F:3:1:10", 2, new int[] { 10, 11, 12 });
            CheckPalletGroup(trans, 33, "F:3:2:20", 1, new int[] { 20, 21 });
            CheckPalletGroup(trans, 34, "F:3:3:30", 1, new int[] { 30, 31 });

            AssertPartsPalletsDeleted(trans);
        }