Exemple #1
0
        //Bikin function untuk View Detail MO

        public void GenerateTaskTimbang(string MONumber, DateTime?ExecuteDate, bool IsPriority)
        {
            entPreparation.StartTransaction();

            //disini proses MO yang akan dikerjakan. Save ke QueueMO table dengan detail urutan by ID Sequence dan jika ada prioritas
            //Table ini untuk nanti menentukan MO mana yang dikerjain dulu, ketika terminal Request Task
            MOQueue queue = new MOQueue();

            queue.MoNumber    = MONumber;
            queue.ExecuteDate = ExecuteDate.HasValue ? ExecuteDate.Value : DateTime.Now.Date;
            queue.IsPriority  = IsPriority;
            queue.Status      = "NEW";
            entPreparation.Resolve <MOQueue>().Add(queue);

            List <OracleHeader> oracleH = entPreparation.Resolve <OracleHeader>().GetAll(x => x.MoNumber == MONumber && x.IsProcessed == false);
            int seqCounter = 1;

            foreach (OracleHeader dataOracleH in oracleH)
            {
                //Kondisi jika TIMBANG --//MUNGKIN KAH DIBUAT GET ALL DENGAN KONDISI ORDER ASC / DESC
                List <OracleDetail> oracleD = entPreparation.Resolve <OracleDetail>().GetAll(x => x.MOLineId == dataOracleH.MOLineId).OrderByDescending(x => x.LotQty).ToList();

                decimal?totalQty = oracleD.Select(x => x.LotQty).Sum();
                if (totalQty != null && totalQty >= dataOracleH.Qty)
                {
                    //Hitung jumlah BAG dari --> TIMBANG : TotalQty / QtyPerCharges || NON_TIMBANG : TotalQty / PackingSize
                    int nBag = dataOracleH.IsTimbang == true ? (int)Math.Ceiling(dataOracleH.Qty / dataOracleH.QtyPerCharge ?? 1) : (int)Math.Ceiling(dataOracleH.Qty / dataOracleH.PackingSize ?? 1);

                    int     bagCounter = 1;
                    decimal qtyPerBag  = 0;
                    decimal remainsQty = 0;

                    foreach (OracleDetail dataOracleD in oracleD)
                    {
                        remainsQty = remainsQty + dataOracleD.LotQty;

                        qtyPerBag = dataOracleH.IsTimbang == true ? dataOracleH.QtyPerCharge ?? 0 : dataOracleH.PackingSize ?? 0;

                        while (remainsQty >= qtyPerBag)
                        {
                            //Get New ED
                            DateTime newED = DateTime.Today.AddDays(Convert.ToDouble(dataOracleH.SelfLife));

                            //Create Task Timbang
                            TaskTimbang taskTimbang = new TaskTimbang();
                            taskTimbang.Barcode           = GenerateBarcodeNo(); //Generate Barcode No
                            taskTimbang.OracleHeaderId    = dataOracleH.OracleHeaderId;
                            taskTimbang.Seq               = seqCounter;
                            taskTimbang.BagNo             = bagCounter.ToString() + " of " + nBag.ToString();
                            taskTimbang.ItemCode          = dataOracleH.ItemCode;
                            taskTimbang.Weight            = qtyPerBag;
                            taskTimbang.LotNo             = dataOracleD.LotNo;
                            taskTimbang.ExpirationDate    = dataOracleD.ExpirationDate;
                            taskTimbang.NewLotNo          = dataOracleD.LotNo.ToString() + GenerateNewLotNo(dataOracleD.ItemCode, dataOracleD.LotNo, dataOracleH.DateRequired);
                            taskTimbang.NewExpirationDate = dataOracleD.ExpirationDate < newED ? dataOracleD.ExpirationDate : newED;
                            taskTimbang.Type              = qtyPerBag > 5.00M ? "B" : "K";
                            taskTimbang.IsAllergen        = dataOracleH.IsAllergen;
                            taskTimbang.IsTimbang         = dataOracleH.IsTimbang;
                            taskTimbang.Status            = "PREP";

                            remainsQty  = remainsQty - qtyPerBag;
                            seqCounter += 1;
                            if (remainsQty >= qtyPerBag)
                            {
                                bagCounter += 1;
                            }
                            entPreparation.Resolve <TaskTimbang>().Add(taskTimbang);
                        }
                        dataOracleD.IsProcessed = true;
                    }
                }
                dataOracleH.IsProcessed = true;
            }
            entPreparation.Save(TransactionAttribute.Commit);
        }
Exemple #2
0
        public void RequestTask(string TerminalId, int UserId)
        {
            Int64  MOQueueId = 0;
            string MONumber  = "";
            //BELUM!! Seharusnya digrouping terlebih dahulu terhadap Nomor MO, dengan default by : First In First Out DAN Skala Prioritas MO, tetapi harus selesai per TASK
            //Ketika Processed jadi TaskTimbang, masukin table QueueMO isinya: MONumber, IsPriority, Sequence, status.

            //1. Pertama cari yang on progress (status = "EXE")
            MOQueue moOnProgress = entTerminal.Resolve <MOQueue>().Get(x => x.Status == "EXE");

            //2. Jika ada yg on Progress maka selesaikan
            if (moOnProgress != null)
            {
                MOQueueId = moOnProgress.MOQueueId;
                MONumber  = moOnProgress.MoNumber;
            }
            else
            {
                //3. Jika ga ada yang sedang dikerjakan, ambil yang prioritas utama, urutan berdasarkan MOQueueId
                MOQueue moPriority = entTerminal.Resolve <MOQueue>().GetAll(x => x.Status == "NEW" && x.IsPriority == true).OrderBy(x => x.MOQueueId).FirstOrDefault();

                if (moPriority != null)
                {
                    MOQueueId = moPriority.MOQueueId;
                    MONumber  = moPriority.MoNumber;
                }
                else
                {
                    //4. Jika ga ada yang prioritas, ambil MO paling pertama masuk FIFO, berdasarkan urutan Execute Date & MOQueueId
                    MOQueue moFifo = entTerminal.Resolve <MOQueue>().GetAll(x => x.Status == "NEW").OrderBy(x => x.ExecuteDate).ThenBy(x => x.MOQueueId).FirstOrDefault();
                    if (moFifo != null)
                    {
                        MOQueueId = moFifo.MOQueueId;
                        MONumber  = moFifo.MoNumber;
                    }
                    else
                    {
                        //Tidak ada MO yang harus dikerjakan
                    }
                }
            }

            if (MONumber != "")
            {
                //IsProcessed True artinya sudah dibentuk TaskTimbang
                List <Int64> listOracleHId = entTerminal.Resolve <OracleHeader>().GetAll(x => x.MoNumber == MONumber && x.IsProcessed == true).Select(x => x.OracleHeaderId).ToList();

                //Cek dulu apakah semua Task Timbang untuk MO Number ini sudah diproses semua atau belum, jika sudah semua TMB atau COM, update MOQueue status jadi COM
                int taskPending = entTerminal.Resolve <TaskTimbang>().GetAll(x => listOracleHId.Contains(x.OracleHeaderId) && x.Status.Contains("PREP")).Count();

                if (taskPending > 0)
                {
                    //Get Semua Data Terminal Configuration Terlebih dahulu
                    List <TerminalConfiguration> listAllTerminal = entTerminal.Resolve <TerminalConfiguration>().GetAll();

                    //Terminal Requester
                    TerminalConfiguration terminal = listAllTerminal.Where(x => x.TerminalId == TerminalId).FirstOrDefault();

                    if (terminal.IsActive)
                    {
                        //Get (Task Allergen / Non Allergen) & sesuai dengan type timbangan (B / K)
                        var listItemPeMO = (from a in entTerminal.Resolve <TaskTimbang>().AsQueryable()
                                            .Where(x => listOracleHId.Contains(x.OracleHeaderId) && x.IsAllergen == terminal.IsAllergen && x.Type == terminal.TerminalCategory)
                                            group a by new { a.ItemCode } into g
                                            orderby g.Count(x => x.ItemCode != null) descending
                                            select new
                        {
                            ItemCode = g.Key.ItemCode,
                            Qty = g.Count(x => x.ItemCode != null),
                            TerminalAssign = g.Count(x => x.TerminalId != null)
                        }).ToList();


                        //var listItemPeMO = (from a in entTerminal.Resolve<TaskTimbang>().AsQueryable()
                        //                .Where(x => listOracleHId.Contains(x.OracleHeaderId) && x.Status == "PREP" && x.IsAllergen == terminal.IsAllergen && x.Type == terminal.TerminalCategory)
                        //                    group a by a.ItemCode into g
                        //                    let qty = g.Count()
                        //                    orderby qty descending
                        //                    select new { ItemCode = g.Key, Qty = qty }).ToList();

                        //jika sudah tidak ada Item lain yang kosong, maka boleh cross Item
                        bool allowCrossItem = listItemPeMO.Where(x => x.TerminalAssign == 0).Count() > 0 ? false : true;


                        //Bagi Task
                        foreach (var item in listItemPeMO)
                        {
                            //Daftar Terminal yang sedang Execute Item Code ini
                            List <TaskTimbang> listTaskTimbangPerItem = entTerminal.Resolve <TaskTimbang>().GetAll(x => x.ItemCode == item.ItemCode.ToString() && x.Type == terminal.TerminalCategory);
                            List <string>      listTerminalActive     = listTaskTimbangPerItem.Where(x => x.ItemCode == item.ItemCode.ToString() && x.TerminalId != null && x.Type == terminal.TerminalCategory && x.Status == "TMB").Select(x => x.TerminalId).Distinct().ToList();
                            List <int?>        terminalGroupActive    = listAllTerminal.Where(x => listTerminalActive.Contains(x.TerminalId)).Select(x => x.TerminalGroup).Distinct().ToList();
                            int taskLeft = listTaskTimbangPerItem.Where(x => x.ItemCode == item.ItemCode.ToString() && x.TerminalId == null && x.Type == terminal.TerminalCategory && x.Status == "PREP").Count();

                            if (taskLeft > 0 && (terminalGroupActive.Contains(terminal.TerminalGroup) || listTerminalActive.Count == 0 || allowCrossItem))
                            {
                                //Masih ada Item tersebut yang belum ditimbang, kasi task yang sama karena 1 group
                                //kasi task sejumlah settingan, perhitungkan juga sisa tasknya jika < n%, kasi semua langsung
                                int taskTimbangCount = int.Parse(GS.GetValue("TASK_TIMBANG_COUNT"));

                                decimal percentage = ((Convert.ToDecimal(taskLeft) - Convert.ToDecimal(taskTimbangCount)) / Convert.ToDecimal(taskTimbangCount) * 100);

                                List <Int64> taskIdToAssign = new List <Int64>();

                                if (percentage < decimal.Parse(GS.GetValue("TASK_LEFT_PERCENTAGE")))
                                {
                                    //Set semua TASK sesuai taskLeft
                                    taskIdToAssign = listTaskTimbangPerItem.Where(x => x.ItemCode == item.ItemCode.ToString() && x.TerminalId == null && x.Status == "PREP").Select(x => x.TaskTimbangId).ToList();
                                }
                                else
                                {
                                    //Set jumlah TASK sesuai taskTimbangCount
                                    taskIdToAssign = listTaskTimbangPerItem.Where(x => x.ItemCode == item.ItemCode.ToString() && x.TerminalId == null && x.Status == "PREP").OrderBy(x => x.Seq).Take(taskTimbangCount).Select(x => x.TaskTimbangId).ToList();
                                }

                                //Update TaskTimbang, assign to Terminal
                                entTerminal.StartTransaction();

                                //update Status MOQueue jadi EXEcute
                                MOQueue queue = entTerminal.Resolve <MOQueue>().Get(x => x.MOQueueId == MOQueueId);
                                queue.Status = "EXE";

                                //Assign Task to Terminal Timbang
                                List <TaskTimbang> taskTimbangToAssign = entTerminal.Resolve <TaskTimbang>().GetAll(x => taskIdToAssign.Contains(x.TaskTimbangId));
                                DateTime           executeDate         = DateTime.Now;

                                taskTimbangToAssign.ForEach(x =>
                                {
                                    x.TerminalId  = terminal.TerminalId;
                                    x.UserId      = UserId;
                                    x.ExecuteDate = executeDate;
                                    x.Status      = "TMB";
                                });

                                entTerminal.Save(TransactionAttribute.Commit);
                                break;
                            }
                        }
                    }
                    else
                    {
                        //ERROR : Terminal Tidak Active
                    }
                }
                else
                {
                    entTerminal.StartTransaction();
                    //update Status MOQueue jadi EXEcute
                    MOQueue queue = entTerminal.Resolve <MOQueue>().Get(x => x.MOQueueId == MOQueueId);
                    queue.Status = "COM";
                    entTerminal.Save(TransactionAttribute.Commit);
                }
            }
        }