public ActionResult Edit(CreateOrderModel model, string itemsString) { if (!Authorized(RoleType.OrdersWriter)) return Error(Loc.Dic.error_no_permission); if (!ModelState.IsValid) return Error(Loc.Dic.error_invalid_form); // Initializing needed temporary variables bool wasReturnedToCreator; bool allowExeeding = true; List<Orders_OrderToAllocation> AllocationsToCreate = new List<Orders_OrderToAllocation>(); Order orderFromDatabase; List<Orders_OrderToItem> itemsFromEditForm = new List<Orders_OrderToItem>(); List<Orders_OrderToItem> itemsToDelete = new List<Orders_OrderToItem>(); List<Orders_OrderToItem> itemsToCreate = new List<Orders_OrderToItem>(); List<Orders_OrderToItem> itemsToUpdate = new List<Orders_OrderToItem>(); decimal totalOrderPrice; decimal totalAllocation; List<Budgets_Allocations> orderAllocations = new List<Budgets_Allocations>(); using (OrdersRepository orderRep = new OrdersRepository(CurrentUser.CompanyId)) { orderFromDatabase = orderRep.GetEntity(model.Order.Id, "Supplier", "Orders_OrderToItem", "Orders_OrderToAllocation", "Users_ApprovalRoutes.Users_ApprovalStep"); } if (orderFromDatabase == null) return Error(Loc.Dic.error_order_not_found); if (orderFromDatabase.UserId != CurrentUser.UserId) return Error(Loc.Dic.error_no_permission); if (orderFromDatabase.StatusId != (int)StatusType.Pending && orderFromDatabase.StatusId != (int)StatusType.PendingOrderCreator) return Error(Loc.Dic.error_order_edit_after_approval); wasReturnedToCreator = orderFromDatabase.StatusId == (int)StatusType.PendingOrderCreator; itemsFromEditForm = ItemsFromString(itemsString, model.Order.Id); if (itemsFromEditForm == null) return Error(Loc.Dic.error_invalid_form); if (itemsFromEditForm.Count == 0) return Error(Loc.Dic.error_order_has_no_items); if (itemsFromEditForm.Count == 0) return Error(Loc.Dic.error_order_has_no_items); totalOrderPrice = (decimal.Floor(itemsFromEditForm.Sum(x => x.SingleItemPrice * x.Quantity) * 1000) / 1000); if (model.Allocations == null || model.Allocations.Where(x => x.IsActive).Count() == 0) return Error(Loc.Dic.error_invalid_form); model.Allocations = model.Allocations.Where(x => x.IsActive).ToList(); totalAllocation = (decimal.Floor(model.Allocations.Sum(x => x.Amount) * 1000) / 1000); if (totalOrderPrice != totalAllocation) return Error(Loc.Dic.error_order_insufficient_allocation); using (OrdersRepository ordersRep = new OrdersRepository(CurrentUser.CompanyId)) using (AllocationRepository allocationsRep = new AllocationRepository(CurrentUser.CompanyId)) using (BudgetsRepository budgetsRep = new BudgetsRepository(CurrentUser.CompanyId)) { Budget currentBudget = budgetsRep.GetList().SingleOrDefault(x => x.CompanyId == CurrentUser.CompanyId && x.IsActive); if (currentBudget == null) return Error(Loc.Dic.error_database_error); model.Order.BudgetId = currentBudget.Id; int[] orderAllocationsIds = model.Allocations.Select(x => x.AllocationId).Distinct().ToArray(); var allocationsData = allocationsRep.GetAllocationsData(orderAllocationsIds, StatusType.Pending); bool IsValidAllocations = (allocationsData.Count == orderAllocationsIds.Length) && model.Allocations.All(x => (x.MonthId == null || (x.MonthId >= 1 && x.MonthId <= 12)) && x.Amount > 0); if (!IsValidAllocations) return Error(Loc.Dic.error_invalid_form); if (model.IsFutureOrder) { foreach (var allocationData in allocationsData) { List<OrderAllocation> allocationMonths = model.Allocations.Where(x => x.AllocationId == allocationData.AllocationId).ToList(); foreach (var month in allocationMonths) { if (month.MonthId == DateTime.Now.Month) { OrderAllocation currentAllocation = model.Allocations.SingleOrDefault(x => x.AllocationId == allocationData.AllocationId); var newAllocations = allocationsRep.GenerateOrderAllocations(allocationData, currentAllocation.Amount, allowExeeding, DateTime.Now.Month, orderFromDatabase.Id); if (newAllocations == null) return Error(Loc.Dic.error_order_insufficient_allocation); AllocationsToCreate.AddRange(newAllocations); } else { var monthData = allocationData.Months.SingleOrDefault(x => x.MonthId == month.MonthId); if (!allowExeeding && month.Amount > monthData.RemainingAmount) return Error(Loc.Dic.error_order_insufficient_allocation); Orders_OrderToAllocation newAllocation = new Orders_OrderToAllocation() { AllocationId = allocationData.AllocationId, MonthId = month.MonthId.Value, Amount = month.Amount, OrderId = orderFromDatabase.Id }; AllocationsToCreate.Add(newAllocation); } } } } else { foreach (var allocationData in allocationsData) { OrderAllocation currentAllocation = model.Allocations.SingleOrDefault(x => x.AllocationId == allocationData.AllocationId); var newAllocations = allocationsRep.GenerateOrderAllocations(allocationData, currentAllocation.Amount, allowExeeding, DateTime.Now.Month, orderFromDatabase.Id); if (newAllocations == null) return Error(Loc.Dic.error_order_insufficient_allocation); AllocationsToCreate.AddRange(newAllocations); } } } using (OrderToAllocationRepository orderAllocationRep = new OrderToAllocationRepository()) { foreach (var item in orderFromDatabase.Orders_OrderToAllocation) { orderAllocationRep.Delete(item.Id); } foreach (var item in AllocationsToCreate) { orderAllocationRep.Create(item); } } foreach (var newItem in itemsFromEditForm) { Orders_OrderToItem existingItem = orderFromDatabase.Orders_OrderToItem.SingleOrDefault(x => x.ItemId == newItem.ItemId); if (existingItem != null) { if ( existingItem.Quantity != newItem.Quantity || existingItem.SingleItemPrice != newItem.SingleItemPrice ) { newItem.Id = existingItem.Id; itemsToUpdate.Add(newItem); } } else { itemsToCreate.Add(newItem); } } foreach (var existingItem in orderFromDatabase.Orders_OrderToItem) { Orders_OrderToItem newItem = itemsFromEditForm.SingleOrDefault(x => x.ItemId == existingItem.ItemId); if (newItem == null) { itemsToDelete.Add(existingItem); } } bool noErrors = true; using (OrderToItemRepository orderToItemRep = new OrderToItemRepository()) { foreach (var item in itemsToCreate) { if (!orderToItemRep.Create(item) && noErrors) noErrors = false; } foreach (var item in itemsToUpdate) { if (orderToItemRep.Update(item) == null && noErrors) noErrors = false; } foreach (var item in itemsToDelete) { if (!orderToItemRep.Delete(item.Id) && noErrors) noErrors = false; } using (OrdersRepository ordersRep = new OrdersRepository(CurrentUser.CompanyId)) { if (!CurrentUser.OrdersApprovalRouteId.HasValue) { model.Order.NextOrderApproverId = null; model.Order.StatusId = (int)StatusType.ApprovedPendingInvoice; } else { Users_ApprovalRoutes orderRoute = orderFromDatabase.Users_ApprovalRoutes; //routesRep.GetEntity(CurrentUser.OrdersApprovalRouteId.Value, "Users_ApprovalStep"); Users_ApprovalStep firstStep = orderRoute.Users_ApprovalStep.OrderBy(x => x.StepNumber).FirstOrDefault(); if (firstStep != null) { model.Order.ApprovalRouteId = orderRoute.Id; model.Order.ApprovalRouteStep = firstStep.StepNumber; model.Order.NextOrderApproverId = firstStep.UserId; model.Order.StatusId = (int)StatusType.Pending; } else { model.Order.ApprovalRouteId = null; model.Order.ApprovalRouteStep = null; model.Order.NextOrderApproverId = null; model.Order.StatusId = (int)StatusType.ApprovedPendingInvoice; } } model.Order.CompanyId = orderFromDatabase.CompanyId; model.Order.CreationDate = orderFromDatabase.CreationDate; model.Order.SupplierId = orderFromDatabase.SupplierId; model.Order.UserId = orderFromDatabase.UserId; model.Order.OrderNumber = orderFromDatabase.OrderNumber; model.Order.InvoiceNumber = orderFromDatabase.InvoiceNumber; model.Order.InvoiceDate = orderFromDatabase.InvoiceDate; model.Order.LastStatusChangeDate = DateTime.Now; model.Order.ValueDate = orderFromDatabase.ValueDate; model.Order.WasAddedToInventory = orderFromDatabase.WasAddedToInventory; model.Order.IsFutureOrder = model.IsFutureOrder; model.Order.Price = totalOrderPrice; ordersRep.Update(model.Order); model.Order = ordersRep.GetEntity(model.Order.Id, "User", "User1"); } } if (noErrors) { int? historyActionId = null; historyActionId = (int)HistoryActions.Edited; Orders_History orderHistory = new Orders_History(); using (OrdersHistoryRepository ordersHistoryRep = new OrdersHistoryRepository(CurrentUser.CompanyId, CurrentUser.UserId, model.Order.Id)) if (historyActionId.HasValue) ordersHistoryRep.Create(orderHistory, historyActionId.Value, model.NotesForApprover); if (wasReturnedToCreator) { if (model.Order.NextOrderApproverId.HasValue) { SendNotifications.OrderPendingApproval(model.Order, Url); } } return RedirectToAction("MyOrders"); } else return Error(Loc.Dic.error_order_update_items_error); }
public ActionResult Create(CreateOrderModel model) { /// Validating user input if (!Authorized(RoleType.OrdersWriter)) return Error(Loc.Dic.error_no_permission); if (!ModelState.IsValid) return Error(Loc.Dic.error_invalid_form); if (String.IsNullOrEmpty(model.ItemsString)) return Error(Loc.Dic.error_invalid_form); List<Orders_OrderToItem> ItemsList = ItemsFromString(model.ItemsString, 0); if (ItemsList == null || ItemsList.Count == 0) return Error(Loc.Dic.error_invalid_form); if (model.IsFutureOrder && !Authorized(RoleType.FutureOrderWriter)) return Error(Loc.Dic.Error_NoPermission); if (model.Allocations == null || model.Allocations.Where(x => x.IsActive).Count() == 0) return Error(Loc.Dic.error_invalid_form); model.Allocations = model.Allocations.Where(x => x.IsActive).ToList(); decimal totalOrderPrice = (decimal.Floor(ItemsList.Sum(x => x.SingleItemPrice * x.Quantity) * 1000) / 1000); decimal totalAllocation = (decimal.Floor(model.Allocations.Sum(x => x.Amount) * 1000) / 1000); if (totalOrderPrice != totalAllocation) return Error(Loc.Dic.error_order_insufficient_allocation); // Initializing needed temporary variables bool allowExeeding = true; List<Orders_OrderToAllocation> AllocationsToCreate = new List<Orders_OrderToAllocation>(); // Setting order properties model.Order.UserId = CurrentUser.UserId; model.Order.Price = totalOrderPrice; model.Order.IsFutureOrder = model.IsFutureOrder; using (AllocationRepository allocationsRep = new AllocationRepository(CurrentUser.CompanyId)) using (BudgetsRepository budgetsRep = new BudgetsRepository(CurrentUser.CompanyId)) using (ApprovalRoutesRepository routesRep = new ApprovalRoutesRepository(CurrentUser.CompanyId)) { Budget currentBudget = budgetsRep.GetList().SingleOrDefault(x => x.IsActive); if (currentBudget == null) return Error(Loc.Dic.error_database_error); model.Order.BudgetId = currentBudget.Id; int[] orderAllocationsIds = model.Allocations.Select(x => x.AllocationId).Distinct().ToArray(); var allocationsData = allocationsRep.GetAllocationsData(orderAllocationsIds, StatusType.Pending); bool IsValidAllocations = (allocationsData.Count == orderAllocationsIds.Length) && model.Allocations.All(x => (x.MonthId == null || (x.MonthId >= 1 && x.MonthId <= 12)) && x.Amount > 0); if (!IsValidAllocations) return Error(Loc.Dic.error_invalid_form); if (model.IsFutureOrder) { foreach (var allocationData in allocationsData) { List<OrderAllocation> allocationMonths = model.Allocations.Where(x => x.AllocationId == allocationData.AllocationId).ToList(); foreach (var month in allocationMonths) { if (month.MonthId == DateTime.Now.Month) { OrderAllocation currentAllocation = model.Allocations.SingleOrDefault(x => x.AllocationId == allocationData.AllocationId); var newAllocations = allocationsRep.GenerateOrderAllocations(allocationData, currentAllocation.Amount, allowExeeding, DateTime.Now.Month); if (newAllocations == null) return Error(Loc.Dic.error_order_insufficient_allocation); AllocationsToCreate.AddRange(newAllocations); } else { var monthData = allocationData.Months.SingleOrDefault(x => x.MonthId == month.MonthId); if (!allowExeeding && month.Amount > monthData.RemainingAmount) return Error(Loc.Dic.error_order_insufficient_allocation); Orders_OrderToAllocation newAllocation = new Orders_OrderToAllocation() { AllocationId = allocationData.AllocationId, MonthId = month.MonthId.Value, Amount = month.Amount, OrderId = 0 }; AllocationsToCreate.Add(newAllocation); } } } } else { foreach (var allocationData in allocationsData) { OrderAllocation currentAllocation = model.Allocations.SingleOrDefault(x => x.AllocationId == allocationData.AllocationId); var newAllocations = allocationsRep.GenerateOrderAllocations(allocationData, currentAllocation.Amount, allowExeeding, DateTime.Now.Month); if (newAllocations == null) return Error(Loc.Dic.error_order_insufficient_allocation); AllocationsToCreate.AddRange(newAllocations); } } if (!CurrentUser.OrdersApprovalRouteId.HasValue) { model.Order.NextOrderApproverId = null; model.Order.StatusId = (int)StatusType.ApprovedPendingInvoice; } else { Users_ApprovalRoutes orderRoute = routesRep.GetEntity(CurrentUser.OrdersApprovalRouteId.Value, "Users_ApprovalStep"); Users_ApprovalStep firstStep = orderRoute.Users_ApprovalStep.OrderBy(x => x.StepNumber).FirstOrDefault(); if (firstStep != null) { model.Order.ApprovalRouteId = orderRoute.Id; model.Order.ApprovalRouteStep = firstStep.StepNumber; model.Order.NextOrderApproverId = firstStep.UserId; model.Order.StatusId = (int)StatusType.Pending; } else { model.Order.ApprovalRouteStep = null; model.Order.NextOrderApproverId = null; model.Order.StatusId = (int)StatusType.ApprovedPendingInvoice; } } } using (OrdersRepository ordersRep = new OrdersRepository(CurrentUser.CompanyId)) using (OrderToItemRepository orderToItemRep = new OrderToItemRepository()) using (OrderToAllocationRepository orderAllocationsRep = new OrderToAllocationRepository()) { bool creationError = false; if (!ordersRep.Create(model.Order)) return Error(Loc.Dic.error_orders_create_error); model.Order = ordersRep.GetEntity(model.Order.Id, "User", "User1"); foreach (Orders_OrderToItem item in ItemsList) { item.OrderId = model.Order.Id; if (!orderToItemRep.Create(item)) { creationError = true; break; } } foreach (var allocation in AllocationsToCreate) { allocation.OrderId = model.Order.Id; if (!orderAllocationsRep.Create(allocation)) { creationError = true; break; } } if (creationError) { ordersRep.Delete(model.Order.Id); return Error(Loc.Dic.error_orders_create_error); } } using (OrdersHistoryRepository ordersHistoryRepository = new OrdersHistoryRepository(CurrentUser.CompanyId, CurrentUser.UserId, model.Order.Id)) { Orders_History orderHis = new Orders_History(); ordersHistoryRepository.Create(orderHis, (int)HistoryActions.Created, model.NotesForApprover); } if (model.Order.NextOrderApproverId.HasValue) { SendNotifications.OrderPendingApproval(model.Order, Url); } return RedirectToAction("MyOrders"); }