//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); }
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); } } }