public void CreateRequestDetail(WCFItemTotalQty req) { Request r = new Work().GetRequest(); Request_Details rdetail = new Request_Details(); rdetail.deleted = "N"; rdetail.request_id = r.request_id; Stock_Inventory item = new Work().GetStockInventory(req.ItemDes); rdetail.item_code = item.item_code; rdetail.orig_quantity = Convert.ToInt32(req.TotalQty); new Work().CreateRequestDetail(rdetail); Request_Details newreq = new Work().GetLastRequestDetail(); Request_Event revent = new Request_Event(); revent.request_detail_id = newreq.request_detail_id; revent.status = RequestStatus.PENDING; revent.quantity = Convert.ToInt32(newreq.orig_quantity); revent.date_time = Convert.ToDateTime(r.date_time); revent.deleted = "N"; revent.username = r.username; new Work().CreateRequestEvent(revent); }
public static Dictionary <ItemModel, int> _getPendingOrUpdatedItemsForRequest(Request efRequest) { try { List <Request_Details> details = efRequest.Request_Details.Where(x => x.deleted != "Y").ToList(); Dictionary <ItemModel, int> itemsAndQuantities = new Dictionary <ItemModel, int>(); //string status = RequestStatus.PENDING; //bool wasUpdated = false; details.ForEach(x => { // Get the latest event that is either pending or updated Request_Event eventItem = x.Request_Event .Where(e => e.deleted != "Y" && (e.status == RequestStatus.PENDING || e.status == RequestStatus.UPDATED) ) .OrderBy(o => o.date_time) .Last(); itemsAndQuantities.Add(new ItemModel(x.Stock_Inventory), eventItem.quantity); }); return(itemsAndQuantities); } catch (NullReferenceException nullExec) { throw new ItemNotFoundException("Item not found", nullExec); } }
public static Dictionary <ItemModel, int> _getItemsForRequest(Request efRequest, string status) { try { List <Request_Details> details = efRequest.Request_Details.Where(x => x.deleted != "Y").ToList(); Dictionary <ItemModel, int> itemsAndQuantities = new Dictionary <ItemModel, int>(); details.ForEach(x => { Request_Event eventItem = x.Request_Event.Where(e => e.deleted != "Y").OrderBy(o => o.date_time).Last(); int qty = 0; if (eventItem != null) { qty = eventItem.quantity; } itemsAndQuantities.Add(new ItemModel(x.Stock_Inventory), qty); }); return(itemsAndQuantities); } catch (NullReferenceException nullExec) { throw new ItemNotFoundException("NULLEXEC: Item not found", nullExec); } }
private void _moveFromTransient(Request request, Dictionary <ItemModel, int> items, string currentUser, string fromStatus, string toStatus) { DateTime now = DateTime.Now; List <Request_Details> details = request.Request_Details.ToList(); foreach (var detail in details) { if (detail.deleted == "Y") { continue; } var itemCode = detail.item_code; // Match item codes var item = items.Where(w => w.Key.ItemCode == itemCode).First(); // Quantity to move to nonTransient var quantity = item.Value; // Get the latest allocated & approved & transient Request_Event alloc = detail.Request_Event.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); Request_Event approv = detail.Request_Event.Where(w => w.status == EventStatus.APPROVED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); Request_Event transient = detail.Request_Event.Where(w => w.status == fromStatus && w.deleted != "Y").OrderBy(o => o.date_time).Last(); int newAllocQty = alloc.quantity; int newApprovQty = approv.quantity; int shortfall = transient.quantity - quantity; if (shortfall > 0) { // There was a discrepany, so try to allocate // Find out how much system can allocate int availableQty = item.Key.AvailableQuantity; int canAllocateQty = availableQty - shortfall; if (canAllocateQty >= 0) { // System can allocate all shortfall newAllocQty = shortfall; newApprovQty = 0; } if (canAllocateQty < 0) { // System can allocate some newAllocQty = availableQty; newApprovQty = shortfall - newAllocQty; } } Request_Event nonTransientEv = _newRequestEvent(now, quantity, detail.request_detail_id, currentUser, EventStatus.RETRIEVED); Request_Event allocEv = _newRequestEvent(now, 0, detail.request_detail_id, currentUser, EventStatus.ALLOCATED); Request_Event approvedEv = _newRequestEvent(now, approv.quantity, detail.request_detail_id, currentUser, EventStatus.APPROVED); context.Request_Event.Add(nonTransientEv); context.Request_Event.Add(allocEv); context.Request_Event.Add(approvedEv); } }
public bool setRequestToCancelled(int requestId, string username) { Request request = context.Requests.Find(requestId); if (request.current_status != RequestStatus.PENDING && request.current_status != RequestStatus.UPDATED) { throw new RequestAlreadyApprovedException("Already approved or rejected."); //return false; } DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { try { List <Request_Details> targetDetails = request.Request_Details.ToList(); foreach (Request_Details detail in targetDetails) { Request_Event existingEvent = detail.Request_Event.Where(w => w.deleted != "Y").First(); if (existingEvent == null) { continue; } context.Request_Event.Find(existingEvent.request_event_id).date_time = timestamp; context.Request_Event.Find(existingEvent.request_event_id).status = EventStatus.CANCELLED; //Request_Event newEvent = new Request_Event(); //newEvent.deleted = "N"; //newEvent.date_time = timestamp; //newEvent.quantity = detail.Request_Event.OrderBy(o => o.date_time).Where(w => (w.status == EventStatus.UPDATED || w.status == EventStatus.PENDING) && w.deleted != "Y").Last().quantity; //newEvent.status = EventStatus.CANCELLED; //newEvent.username = username; // Establish relationships //newEvent.request_detail_id = detail.request_detail_id; // Add to DB //context.Request_Event.Add(newEvent); } // Update Status context.Requests.Find(requestId).current_status = RequestStatus.CANCELLED; } catch (Exception exec) { transaction.Rollback(); throw exec; } transaction.Commit(); } return(true); }
private int _setStatusOfRequests(List <RequestModel> requests, string currentUser, string status) { int added = 0; DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { //try //{ foreach (RequestModel request in requests) { if (RequestStatus.requestHasHadStatus(request, status)) { continue; } Request efRequest = context.Requests.Find(request.RequestId); efRequest.current_status = status; List <Request_Details> efDetails = context.Request_Details.Where(x => x.request_id == request.RequestId).ToList(); if (efRequest == null) { throw new ItemNotFoundException("Could not find Request object"); } if (efDetails.Count == 0) { throw new ItemNotFoundException("Could not find Request Details objects"); } foreach (Request_Details efDetail in efDetails) { // For each item, add a new event that is "_the_status" Request_Event newEvent = new Request_Event(); newEvent.request_detail_id = efDetail.request_detail_id; // get the quantity from the provided item quantity in the method arguments newEvent.quantity = request.Items.Where(x => x.Key.ItemCode == efDetail.item_code).First().Value; newEvent.status = status; newEvent.username = currentUser; newEvent.date_time = timestamp; newEvent.deleted = "N"; context.Request_Event.Add(newEvent); added++; } } //} catch (Exception exec) //{ // transaction.Rollback(); // throw exec; //} transaction.Commit(); } return(added); }
public bool saveNewRequest(RequestModel request) { DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { try { Request newRequest = new Request(); newRequest.current_status = RequestStatus.PENDING; newRequest.deleted = "N"; newRequest.dept_code = request.Department.dept_code; newRequest.reason = request.Reason; newRequest.rejected = "N"; newRequest.rejected_reason = ""; newRequest.username = request.UserModel.Username; newRequest.date_time = timestamp; List <Request_Details> newDetails = new List <Request_Details>(); foreach (KeyValuePair <ItemModel, int> itemAndQty in request.Items) { Request_Details newDetail = new Request_Details(); newDetail.deleted = "N"; newDetail.item_code = itemAndQty.Key.ItemCode; newDetail.orig_quantity = itemAndQty.Value; Request_Event newEvent = new Request_Event(); newEvent.deleted = "N"; newEvent.date_time = timestamp; newEvent.quantity = itemAndQty.Value; newEvent.allocated = 0; newEvent.not_allocated = 0; newEvent.status = RequestStatus.PENDING; newEvent.username = request.UserModel.Username; // Establish relationships newDetail.Request_Event.Add(newEvent); newRequest.Request_Details.Add(newDetail); } // Add to DB context.Requests.Add(newRequest); } catch (Exception exec) { transaction.Rollback(); throw exec; } transaction.Commit(); } return(true); }
private Request_Event _newRequestEvent(DateTime dateTime, int quantity, int detailId, string username, string status) { Request_Event newEv = new Request_Event(); newEv.date_time = dateTime; newEv.deleted = "N"; newEv.quantity = quantity; newEv.request_detail_id = detailId; newEv.username = username; newEv.status = status; return(newEv); }
public int markRequestAsRetrieved(RequestModel toAllocate, string currentUser) { int added = 0; // For each item provided, find the related item in DB, and add an event to it if (RequestStatus.requestHasHadStatus(toAllocate, RequestStatus.DISBURSED)) { throw new RequestAlreadyApprovedException("Already fully disbursed."); //return false; } DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { try { Request targetRequest = context.Requests.Find(toAllocate.RequestId); List <Request_Details> targetDetails = targetRequest.Request_Details.ToList(); foreach (KeyValuePair <ItemModel, int> itemAndQty in toAllocate.Items) { if (itemAndQty.Value == 0) { // No items to retrieve continue; } Request_Event newEvent = new Request_Event(); newEvent.deleted = "N"; newEvent.date_time = timestamp; newEvent.quantity = itemAndQty.Value; newEvent.status = EventStatus.RETRIEVED; newEvent.username = toAllocate.UserModel.Username; // Establish relationships Request_Details targetDetail = targetDetails.Where(x => x.item_code == itemAndQty.Key.ItemCode).First(); targetDetail.Request_Event.Add(newEvent); added++; } } catch (Exception exec) { transaction.Rollback(); throw exec; } transaction.Commit(); } return(added); }
public void DeleteRequestDetail(string id) { int req_id = Convert.ToInt32(id); Request_Details req = context.Request_Details.Where(x => x.request_detail_id == req_id).First(); req.deleted = "Y"; context.SaveChanges(); Request_Event revent = context.Request_Event.Where(x => x.request_detail_id == req.request_detail_id).First(); revent.deleted = "Y"; context.SaveChanges(); }
public void UpdateRequestDetail(string id, string qty) { int req_id = Convert.ToInt32(id); Request_Details req = context.Request_Details.Where(x => x.request_detail_id == req_id).First(); req.orig_quantity = Convert.ToInt32(qty); context.SaveChanges(); Request_Event revent = context.Request_Event.Where(x => x.request_detail_id == req.request_detail_id).First(); revent.quantity = Convert.ToInt32(qty); context.SaveChanges(); }
private void _moveToTransient(int requestId, List <string> itemCodes, string currentUser, string fromStatus, string toStatus, bool resetAllocQty) { DateTime now = DateTime.Now; Request request = context.Requests.Find(requestId); List <Request_Details> details = request.Request_Details.ToList(); foreach (var detail in details) { if (detail.deleted == "Y") { continue; } if (!itemCodes.Contains(detail.item_code)) { continue; } // Get the latest allocated & approved //Request_Event alloc = detail.Request_Event.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); //Request_Event approv = detail.Request_Event.Where(w => w.status == EventStatus.APPROVED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); // Get latest nonTransient Request_Event nonTransient = detail.Request_Event.Where(w => w.status == fromStatus && w.deleted != "Y").OrderBy(o => o.date_time).Last(); if (nonTransient == null) { continue; } int eventId = nonTransient.request_event_id; context.Request_Event.Find(eventId).status = toStatus; context.Request_Event.Find(eventId).date_time = now; context.Request_Event.Find(eventId).username = currentUser; //int allocQty = resetAllocQty ? 0 : alloc.quantity; //Request_Event transientEv = _newRequestEvent(now, nonTransient.quantity, detail.request_detail_id, currentUser, toStatus); //Request_Event allocEv = _newRequestEvent(now, allocQty, detail.request_detail_id, currentUser, EventStatus.ALLOCATED); //Request_Event approvedEv = _newRequestEvent(now, approv.quantity, detail.request_detail_id, currentUser, EventStatus.APPROVED); //context.Request_Event.Add(transientEv); //context.Request_Event.Add(allocEv); //context.Request_Event.Add(approvedEv); } }
public void moveFromDisbursingToDisbursed(RequestModel requestModel, string currentUser) { Request request = context.Requests.Find(requestModel.RequestId); _moveFromTransient(request, requestModel.Items, currentUser, EventStatus.DISBURSING, EventStatus.DISBURSED); // Check if all were disbursed bool fullyDisbursed = true; // Assume true first List <Request_Details> details = request.Request_Details.ToList(); foreach (var detail in details) { if (detail.deleted == "Y") { continue; } var itemCode = detail.item_code; // Match item codes var item = requestModel.Items.Where(w => w.Key.ItemCode == itemCode).First(); // Quantity for disbursed item var quantity = item.Value; // Get earliest approved Request_Event approv = detail.Request_Event.Where(w => w.status == EventStatus.APPROVED && w.deleted != "Y").OrderBy(o => o.date_time).First(); int initialQty = approv.quantity; if (quantity != initialQty) { fullyDisbursed = false; break; } } if (fullyDisbursed) { request.current_status = RequestStatus.DISBURSED; } else { request.current_status = RequestStatus.PART_DISBURSED; } }
public void Reject(String id) { int req_id = Convert.ToInt32(id); Request r = new Request(); Request req = context.Requests.Where(x => x.request_id == req_id).First(); req.current_status = RequestStatus.REJECTED; req.rejected = "Y"; context.SaveChanges(); List <Request_Details> rdetailList = context.Request_Details.Where(x => x.request_id == req_id).ToList(); foreach (Request_Details rdetail in rdetailList) { Request_Event revent = context.Request_Event.Where(x => x.request_detail_id == rdetail.request_detail_id).First(); revent.status = RequestStatus.REJECTED; revent.date_time = DateTime.Today; context.SaveChanges(); } }
private static int _getAvailableQuantity(string itemCode, int currentQuantity) { int cumulativeAvailable = currentQuantity; using (SSISEntities context = new SSISEntities()) { // Get all RequestDetails for an item code List <Request_Details> details = context.Request_Details .Where(w => w.item_code == itemCode && w.deleted != "Y" && (w.Request.current_status == RequestStatus.APPROVED || w.Request.current_status == RequestStatus.PART_DISBURSED) ).ToList(); // For each of this item's details, get the stock it's occupying foreach (var detail in details) { var eventItems = detail.Request_Event.Where(w => w.deleted != "Y" && w.status != EventStatus.DISBURSED); // No matching if (eventItems.Count() == 0) { continue; } Request_Event eventItem = eventItems.First(); // Just check allocated amount int allocatedQty = eventItem.allocated.HasValue ? eventItem.allocated.Value : 0; List <Request_Event> events = detail.Request_Event.OrderByDescending(o => o.date_time).ToList(); //int numAllocated = events.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").Count(); int numAllocated = allocatedQty; // For each detail, subtract its minusQty from the cumulative total cumulativeAvailable -= numAllocated; } } return(cumulativeAvailable); }
public void allocateRequest(int requestId, string currentUser) { DateTime now = DateTime.Now; // Get request Request targetRequest = context.Requests.Find(requestId); if (targetRequest.current_status != RequestStatus.APPROVED && targetRequest.current_status != RequestStatus.PART_DISBURSED) { return; } // Get items List <Request_Details> targetDetails = targetRequest.Request_Details.ToList(); // Get approved quantities foreach (var detail in targetDetails) { if (detail.deleted == "Y") { continue; } Request_Event approvedEvent = detail.Request_Event.OrderByDescending(o => o.date_time).Where(w => w.status == EventStatus.APPROVED).DefaultIfEmpty(null).FirstOrDefault(); if (approvedEvent == null) { continue; } ItemModel item = new ItemModel(context.Stock_Inventory.Find(approvedEvent.Request_Details.item_code)); int approvedQty = approvedEvent.quantity; int availableQty = item.AvailableQuantity; int newApprovedQty = 0; int newAllocQty = 0; // See if there's available // Allocate whatever you can if (availableQty >= approvedQty) { // Can allocate all newAllocQty = approvedQty; newApprovedQty = 0; } else if (availableQty > 0) { // Can allocate some newAllocQty = availableQty; newApprovedQty = approvedQty - newAllocQty; } else { // Cannot allocate at all, skip this item continue; } // Save new events Request_Event allocEv = _newRequestEvent(now, newAllocQty, detail.request_detail_id, currentUser, EventStatus.ALLOCATED); Request_Event approvedEv = _newRequestEvent(now, newApprovedQty, detail.request_detail_id, currentUser, EventStatus.APPROVED); context.Request_Event.Add(allocEv); context.Request_Event.Add(approvedEv); } }
public int allocateRequest(RequestModel toAllocate, string currentUser) { List <ItemModel> itemsAllocateable = new List <ItemModel>(); // First, make sure each item can be allocated in its entirety. If it can, allocate it. foreach (var item in toAllocate.Items) { if (item.Key.AvailableQuantity >= item.Value) { // Can be completely allocated itemsAllocateable.Add(item.Key); } } int added = 0; DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { try { Request efRequest = context.Requests.Find(toAllocate.RequestId); if (efRequest == null) { throw new ItemNotFoundException("Could not find Request object"); } foreach (var item in itemsAllocateable) { // get associated request_detail Request_Details targetDetail = efRequest.Request_Details.Where(r => r.item_code == item.ItemCode).First(); if (targetDetail == null) { throw new ItemNotFoundException("Could not find Request_Details object"); } // For each item, add a new event that is allocated Request_Event newEvent = new Request_Event(); newEvent.request_detail_id = targetDetail.request_detail_id; // get the quantity from the provided item quantity in the method arguments newEvent.quantity = toAllocate.Items.Where(i => i.Key.ItemCode == item.ItemCode).First().Value; newEvent.status = EventStatus.ALLOCATED; newEvent.username = currentUser; newEvent.date_time = timestamp; newEvent.deleted = "N"; context.Request_Event.Add(newEvent); added++; } } catch (Exception exec) { transaction.Rollback(); throw exec; } transaction.Commit(); } return(added); }
public int reAllocateRequest(RequestModel toAllocate, string currentUser) { int added = 0; DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { try { // For each item: // - Get the latest status (e.g. retrieved or disbursed) // - Compare this latest status to the approved amount // - If there is a difference, try to reallocate it // Get a list of details (items) List <Request_Details> details = context.Requests.Find(toAllocate.RequestId).Request_Details.ToList(); if (details.Count == 0) { throw new ItemNotFoundException("Request could not be found"); } // For each of these, get the latest status, and approved event foreach (var detail in details) { Request_Event latest = detail.Request_Event.OrderBy(o => o.date_time).Last(); if (latest == null) { throw new ItemNotFoundException("event item could not be found"); } Request_Event approved = detail.Request_Event.Where(e => e.status == EventStatus.APPROVED).OrderBy(o => o.date_time).Last(); if (approved == null) { throw new ItemNotFoundException("event item could not be found"); } // Get the difference in quantity int difference = approved.quantity - latest.quantity; if (difference < 0) { throw new RequestDataIntegrityFailureException( string.Format("Request id ({0}) has quantities that don't match up!\n==>Request_Event id: {1}\n==>Request_Event id: {2}", toAllocate.RequestId, latest.request_event_id, approved.request_event_id) ); } if (difference > 0) { // There is a difference, so reAllocate it, using the difference quantity // Get the item model Stock_Inventory stock = context.Stock_Inventory.Find(detail.item_code); if (stock == null) { throw new ItemNotFoundException("Could not find stock_inventory for itemCode: " + detail.item_code); } ItemModel item = new ItemModel(stock); // First, make sure each item can be allocated in its entirety. If it can, allocate it. if (item.AvailableQuantity >= difference) { // For each item, add a new event that is allocated Request_Event newEvent = new Request_Event(); newEvent.request_detail_id = detail.request_detail_id; // get the quantity from the provided item quantity in the method arguments newEvent.quantity = toAllocate.Items.Where(i => i.Key.ItemCode == item.ItemCode).First().Value; newEvent.status = EventStatus.ALLOCATED; newEvent.username = currentUser; newEvent.date_time = timestamp; newEvent.deleted = "N"; context.Request_Event.Add(newEvent); added++; } } } } catch (Exception exec) { transaction.Rollback(); throw exec; } transaction.Commit(); } return(added); }
public AllocatedModel findLatestAllocatedByRequestId(int requestId) { // This NOW ALLOCATES UPON FINDING // Get all allocated: depending on: // Determine there's any latest allocation // Find the difference with the previous allocation, to see how much to fulfill //{ PENDING, APPROVED, REJECTED, DISBURSED, PART_DISBURSED, CANCELLED, UPDATED }); Request efRequest = context.Requests .Where(x => x.request_id == requestId && (x.current_status == RequestStatus.APPROVED || x.current_status == RequestStatus.PART_DISBURSED) ).First(); if (efRequest == null) { throw new ItemNotFoundException("No records exist"); } IEnumerable <IGrouping <string, Request_Event> > events = efRequest.Request_Details.SelectMany(x => x.Request_Event).GroupBy(g => g.Request_Details.item_code).ToList(); Dictionary <ItemModel, int> itemsToFulfill = new Dictionary <ItemModel, int>(); foreach (IGrouping <string, Request_Event> eventItem in events) { Request_Event item = eventItem.Where(w => w.deleted != "Y").DefaultIfEmpty(null).FirstOrDefault(); if (item == null) { continue; } // If neither approved nor disbursed, skip it. if (item.status != EventStatus.APPROVED && item.status != EventStatus.DISBURSED && item.status != EventStatus.ALLOCATED) { continue; } Stock_Inventory inv = context.Stock_Inventory.Find(eventItem.Key); ItemModel itemModel = new ItemModel(inv); // Already allocated, just add it if (item.status == EventStatus.ALLOCATED && item.allocated.HasValue) { itemsToFulfill.Add(itemModel, item.allocated.Value); continue; } // Fully allocated, can skip if (item.status == EventStatus.DISBURSED && item.not_allocated == 0) { continue; } int qtyToAllocate; if (item.status == EventStatus.APPROVED) { // Take the whole quantity qtyToAllocate = item.quantity; } else { // Disbursed. Take just the not-allocated qtyToAllocate = item.not_allocated.HasValue ? item.not_allocated.Value : 0; } // if for some reason it's still zero, just skip. if (qtyToAllocate == 0) { continue; } int canAllocateQty = 0; int availableQty = itemModel.AvailableQuantity; if (availableQty > 0) { // There is available stock if (availableQty >= qtyToAllocate) { // Lots of stock canAllocateQty = qtyToAllocate; } else { // Only some stock canAllocateQty = availableQty; } } else { // Cannot allocate at all, cannot retrieve, SKIP continue; } // At this point, there is some qtyToAllocate context.Request_Event.Find(item.request_event_id).allocated = canAllocateQty; if (item.status == EventStatus.DISBURSED) { context.Request_Event.Find(item.request_event_id).quantity = qtyToAllocate; context.Request_Event.Find(item.request_event_id).not_allocated -= canAllocateQty; } else { // Approved only // it.quantity doesn't change //context.Request_Event.Find(item.request_event_id).quantity = //doesn't change; context.Request_Event.Find(item.request_event_id).not_allocated = item.quantity - canAllocateQty; } context.Request_Event.Find(item.request_event_id).status = EventStatus.ALLOCATED; itemsToFulfill.Add(itemModel, canAllocateQty); } if (itemsToFulfill.Count == 0) { // Nothing to allocate, or cannot allocate anything at all. return(null); } AllocatedModel alloc = new AllocatedModel(efRequest, itemsToFulfill); // Save changes to update Available Qty context.SaveChanges(); return(alloc); }
private bool _moveFromTransient(Request request, Dictionary <string, int> items, string currentUser, string fromStatus, string toStatus) { bool wasFullyAllocated = true; DateTime now = DateTime.Now; List <Request_Details> details = request.Request_Details.ToList(); foreach (var detail in details) { if (detail.deleted == "Y") { continue; } var itemCode = detail.item_code; // Match item codes var itemMatches = items.Where(w => w.Key == itemCode); KeyValuePair <string, int> item; // If there are no matches, skip this detail if (itemMatches.Count() == 0) { continue; } item = itemMatches.First(); // Quantity to move to nonTransient var quantity = item.Value; // Get the latest allocated & approved & transient //Request_Event alloc = detail.Request_Event.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); //Request_Event approv = detail.Request_Event.Where(w => w.status == EventStatus.APPROVED && w.deleted != "Y").OrderBy(o => o.date_time).Last(); Request_Event transient = detail.Request_Event.Where(w => w.status == fromStatus && w.deleted != "Y").First(); if (transient == null) { continue; } int initialQty = transient.quantity; int newAllocQty = quantity; int newNonAllocQty = initialQty - quantity; // Check if the quantity was changed if (newNonAllocQty > 0) { wasFullyAllocated = false; } context.Request_Event.Find(transient.request_event_id).allocated = newAllocQty; context.Request_Event.Find(transient.request_event_id).not_allocated = newNonAllocQty; context.Request_Event.Find(transient.request_event_id).status = toStatus; context.Request_Event.Find(transient.request_event_id).date_time = now; context.Request_Event.Find(transient.request_event_id).username = currentUser; if (toStatus == EventStatus.DISBURSED) { // If moving to disbursed, we need to minus the Stock_Inventory current_quantity // Get the relevant Stock_Inv //Stock_Inventory stock = context.Stock_Inventory.Find(detail.item_code); // newAllocQty is what was finally minused off. So: context.Stock_Inventory.Find(detail.item_code).current_qty -= newAllocQty; } } return(wasFullyAllocated); // Was in ForEach loop previously: //int shortfall = transient.quantity - quantity; //if (shortfall > 0) //{ // // There was a discrepany, so try to allocate // // Find out how much system can allocate // int availableQty = item.Key.AvailableQuantity; // int canAllocateQty = availableQty - shortfall; // if (canAllocateQty >= 0) // { // // System can allocate all shortfall // newAllocQty = shortfall; // newNonAllocQty = 0; // } // if (canAllocateQty < 0) // { // // System can allocate some // newAllocQty = availableQty; // newNonAllocQty = shortfall - newAllocQty; // } //} //Request_Event nonTransientEv = _newRequestEvent(now, quantity, detail.request_detail_id, currentUser, EventStatus.RETRIEVED); //Request_Event allocEv = _newRequestEvent(now, 0, detail.request_detail_id, currentUser, EventStatus.ALLOCATED); //Request_Event approvedEv = _newRequestEvent(now, approv.quantity, detail.request_detail_id, currentUser, EventStatus.APPROVED); //context.Request_Event.Add(nonTransientEv); //context.Request_Event.Add(allocEv); //context.Request_Event.Add(approvedEv); }
public RetrievalModel findLatestRetrievalsByRequestId(int requestId) { // Get all allocated: depending on: // Determine there's any latest retrieval // Find the difference with the previous retrieval, to see how much to fulfill //{ PENDING, APPROVED, REJECTED, DISBURSED, PART_DISBURSED, CANCELLED, UPDATED }); Request efRequest = context.Requests .Where(x => x.request_id == requestId && (x.current_status == RequestStatus.APPROVED || x.current_status == RequestStatus.PART_DISBURSED) ).First(); if (efRequest == null) { throw new ItemNotFoundException("No records exist"); } IEnumerable <IGrouping <string, Request_Event> > events = efRequest.Request_Details.SelectMany(x => x.Request_Event).GroupBy(g => g.Request_Details.item_code).ToList(); Dictionary <ItemModel, int> itemsToFulfill = new Dictionary <ItemModel, int>(); foreach (IGrouping <string, Request_Event> eventItem in events) { // Grouping: // A101 // - Approved, 10 // - Allocated, 9 // A102 // - Approved, 10 List <Request_Event> latestRetrieval = eventItem.Where(x => x.status == EventStatus.RETRIEVED).OrderBy(o => o.date_time).ToList(); if (latestRetrieval.Count == 0) { continue; } int quantityToFulfil = 0; if (latestRetrieval.Count > 1) { Request_Event last = latestRetrieval.Last(); Request_Event secondLast = latestRetrieval[latestRetrieval.Count - 2]; quantityToFulfil = last.quantity - secondLast.quantity; } else { quantityToFulfil = latestRetrieval.Last().quantity; } Stock_Inventory inv = context.Stock_Inventory.Find(eventItem.Key); itemsToFulfill.Add(new ItemModel(inv), quantityToFulfil); } if (itemsToFulfill.Count == 0) { return(null); } RetrievalModel retrieval = new RetrievalModel(efRequest, itemsToFulfill); return(retrieval); }
public bool updateRequestChanges(RequestModel newRequest) { if (RequestStatus.requestHasHadStatus(newRequest, RequestStatus.APPROVED)) { throw new RequestAlreadyApprovedException("Already approved or rejected."); //return false; } DateTime timestamp = DateTime.Now; using (var transaction = context.Database.BeginTransaction()) { //try //{ Request targetRequest = context.Requests.Find(newRequest.RequestId); List <Request_Details> targetDetails = targetRequest.Request_Details.ToList(); RequestModel targetRequestModel = findRequestById(newRequest.RequestId); foreach (var item in targetRequestModel.Items) { if (!newRequest.Items.ContainsKey(item.Key)) { // New requestModel does not contain old key // So add it in, but set quantity to 0 newRequest.Items.Add(item.Key, 0); } } foreach (KeyValuePair <ItemModel, int> itemAndQty in newRequest.Items) { Request_Event newEvent = new Request_Event(); newEvent.deleted = "N"; newEvent.date_time = timestamp; newEvent.quantity = itemAndQty.Value; newEvent.status = EventStatus.UPDATED; newEvent.username = newRequest.UserModel.Username; // Establish relationships Request_Details targetDetail = targetDetails.Where(x => x.item_code == itemAndQty.Key.ItemCode).DefaultIfEmpty(null).FirstOrDefault(); if (targetDetail == null) { // Need to insert new detail Request_Details newDetail = new Request_Details(); newDetail.deleted = "N"; newDetail.item_code = itemAndQty.Key.ItemCode; newDetail.orig_quantity = itemAndQty.Value; newDetail.Request_Event.Add(newEvent); newDetail.request_id = newRequest.RequestId; context.Request_Details.Add(newDetail); } else { newEvent.request_detail_id = targetDetail.request_detail_id; // Add to DB context.Request_Event.Add(newEvent); } //targetDetail.Request_Event.Add(newEvent); } // Update Status context.Requests.Find(newRequest.RequestId).current_status = RequestStatus.UPDATED; context.Requests.Find(newRequest.RequestId).reason = newRequest.Reason; //} //catch (Exception exec) //{ //transaction.Rollback(); //throw exec; //} transaction.Commit(); } return(true); }
public void CreateRequestEvent(Request_Event r) { context.Entry(r).State = System.Data.Entity.EntityState.Added; context.SaveChanges(); }
private int _getAvailableQuantityOld() { int cumulativeAvailable = currentQuantity; using (SSISEntities context = new SSISEntities()) { // Get all RequestDetails for an item code List <Request_Details> details = context.Request_Details .Where(w => w.item_code == itemCode && w.deleted != "Y" && (w.Request.current_status == RequestStatus.APPROVED || w.Request.current_status == RequestStatus.PART_DISBURSED) ).ToList(); // For each of this item's details, get the stock it's occupying foreach (var detail in details) { int minusQty = 0; List <Request_Event> events = detail.Request_Event.OrderByDescending(o => o.date_time).ToList(); int numAllocated = events.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").Count(); if (numAllocated == 0) { // Never been allocated, can skip this request_detail continue; } else if (numAllocated == 1) { // Only just allocated one, this is the one to subtract from minusQty = events.Where(w => w.status == EventStatus.ALLOCATED && w.deleted != "Y").First().quantity; } else { for (int i = 0; i < events.Count; i++) { Request_Event ev = events[i]; if (ev.status == EventStatus.APPROVED || ev.deleted == "Y") { // Skip all Approved and deleted continue; } if (ev.status == EventStatus.DISBURSED || ev.status == EventStatus.DISBURSING || ev.status == EventStatus.RETRIEVED) { // Find the closest Allocated int closestAllocQty = 0; for (int j = i; j >= 0; j--) { Request_Event ev2 = events[j]; if (ev2.status == EventStatus.ALLOCATED) { closestAllocQty = ev2.quantity; break; } } // Set minus qty minusQty = ev.quantity + closestAllocQty; // Break out of this detail's events list break; } else if (ev.status == EventStatus.RETRIEVING) { minusQty = ev.quantity; } } } // For each detail, subtract its minusQty from the cumulative total cumulativeAvailable -= minusQty; } } return(cumulativeAvailable); }
public RetrievalModel findLatestRetrievingByRequestId(int requestId, string currentUser) { // For at the warehouse // Get all allocated: depending on: // Determine there's any latest retrieval // Find the difference with the previous retrieval, to see how much to fulfill //{ PENDING, APPROVED, REJECTED, DISBURSED, PART_DISBURSED, CANCELLED, UPDATED }); Request efRequest = context.Requests .Where(x => x.request_id == requestId && (x.current_status == RequestStatus.APPROVED || x.current_status == RequestStatus.PART_DISBURSED) && x.deleted != "Y" ).First(); if (efRequest == null) { throw new ItemNotFoundException("No records exist"); } Dictionary <ItemModel, int> itemsToFulfill = new Dictionary <ItemModel, int>(); List <Request_Details> details = efRequest.Request_Details.ToList(); foreach (var detail in details) { if (detail.deleted == "Y") { continue; } List <Request_Event> events = detail.Request_Event.Where(w => w.deleted != "Y").ToList(); // If there are no events for some reason, SKIP if (events.Count == 0) { continue; } Request_Event eventItem = events.First(); // If the event does not have anything allocated to it, SKIP if (eventItem.allocated == 0) { continue; } // Only add if it's retrieving AND it was by the currentUser if (eventItem.status == EventStatus.RETRIEVING && eventItem.username == currentUser && eventItem.allocated.HasValue) { Stock_Inventory s = detail.Stock_Inventory; itemsToFulfill.Add(new ItemModel(s), eventItem.allocated.Value); } } if (itemsToFulfill.Count == 0) { return(null); } RetrievalModel retrieval = new RetrievalModel(efRequest, itemsToFulfill); return(retrieval); }
private DisbursementModel _findLatestBetweenStatuses(int requestId, string fromStatus, string toStatus, string currentUser) { // For signing off forms (all disbursing ones) Request efRequest = context.Requests .Where(x => x.request_id == requestId && (x.current_status == RequestStatus.APPROVED || x.current_status == RequestStatus.PART_DISBURSED) ).First(); if (efRequest == null) { throw new ItemNotFoundException("No records exist"); } Dictionary <ItemModel, int> itemsToFulfill = new Dictionary <ItemModel, int>(); List <Request_Details> details = efRequest.Request_Details.ToList(); foreach (var detail in details) { //int itemQty = 0; if (detail.deleted == "Y") { continue; } List <Request_Event> events = detail.Request_Event.Where(w => w.deleted != "Y").ToList(); // If there are no events for some reason, SKIP if (events.Count == 0) { continue; } Request_Event eventItem = events.First(); // If the event does not have anything allocated to it, SKIP if (eventItem.allocated.HasValue && eventItem.allocated.Value == 0) { continue; } // Only add if it's retrieving AND it was by the currentUser if (eventItem.status == fromStatus && eventItem.allocated.HasValue) { // currentUser was specified, skip if it's not by them if (currentUser != null && eventItem.username != currentUser) { continue; } Stock_Inventory s = detail.Stock_Inventory; itemsToFulfill.Add(new ItemModel(s), eventItem.allocated.Value); } } if (itemsToFulfill.Count == 0) { return(null); } DisbursementModel retrieved = new DisbursementModel(efRequest, itemsToFulfill); return(retrieved); }