Esempio n. 1
0
        private Error recreatePurchaseOrderPdfs(SplitPurchaseModel model,
                                                CompanyModel company,
                                                UserModel user,
                                                PurchaseOrderHeaderModel updatedOrder,
                                                PurchaseOrderHeaderModel newOrder)
        {
            var error = new Error();

            // Recreate purchase order PDFs

            // Newly created order (if any)
            if (newOrder != null)
            {
                error = createRevisedPurchaseOrder(newOrder.Id, company, user, "Purchase Order Created with items moved from Order " + model.OrderNumber.ToString());
            }

            // New Source order (Order split from)
            error = createRevisedPurchaseOrder(updatedOrder.Id, company, user, "Purchase Order Updated (due to items split out)");

            // Orders split to
            foreach (var targetOrderId in model.SplitItems
                     .Where(si => si.TargetOrderId > 0)
                     .Select(si => si.TargetOrderId)
                     .Distinct())
            {
                error = createRevisedPurchaseOrder(targetOrderId, company, user, "Purchase Order Updated - items moved from Order " + model.OrderNumber.ToString());
                if (error.IsError)
                {
                    break;
                }
            }

            return(error);
        }
Esempio n. 2
0
        private Error copyOrder(CompanyModel company, SplitPurchaseModel model, UserModel user)
        {
            var error = new Error();

            var updatedOrderNo = LookupService.GetNextSequenceNumber(company, SequenceNumberType.PurchaseOrderNumber, origPoh.OrderNumber.Value, true);

            var newPohId = db.CopyPurchaseOrder(model.PurchaseOrderHeaderId, updatedOrderNo, true).First().Value;

            updatedPoh     = FindPurchaseOrderHeaderModel(newPohId, company, false);
            updatedDetails = FindPurchaseOrderDetailListModel(updatedPoh);

            updatedAllocations = AllocationService.FindAllocationsToPurchaseOrder(updatedPoh).Items;

            return(error);
        }
Esempio n. 3
0
        public Error SplitOrder(CompanyModel company, SplitPurchaseModel model, UserModel user,
                                string lockGuid,
                                ref int updatedPOId, ref int newPOId)
        {
            var error = new Error();

            updatedPOId = 0;
            newPOId     = 0;

            // Create a transaction as this involves a lot of changes which we
            // will need to roll back if there is a failure.
            // We don't create the transaction in test mode as the data is specifically created for the
            // test, so it doesn't matter if we mess it up. The key is that if there is a failure, we
            // can look at the database to see the state of the data at the point of failure without it
            // being relled back.
            DbContextTransaction trans = null;

            if (!db.IsTesting)
            {
                trans = db.Database.BeginTransaction();
            }
            try {
                // Validate the user splitting selections
                if (!error.IsError)
                {
                    error = validateSplit(company, model, user, lockGuid);
                }

                // Get the original order into memory
                if (!error.IsError)
                {
                    error = copyOrder(company, model, user);
                }

                // Split the order in memory
                if (!error.IsError)
                {
                    error = doSplit(company, model, user);
                }

                // Recreate the order PDFs
                if (!error.IsError)
                {
                    error = recreatePurchaseOrderPdfs(model, company, user, updatedPoh, newPoh);
                }

                // return the ids of the copy of the original order and a new order (if any)
                if (updatedPoh != null)
                {
                    updatedPOId = updatedPoh.Id;
                }
                if (newPoh != null)
                {
                    newPOId = newPoh.Id;
                }

                if (trans != null)
                {
                    trans.Commit();
                }
            } catch (Exception e1) {
                if (trans != null)
                {
                    trans.Rollback();
                }
                error.SetError(e1);
            }

            return(error);
        }
Esempio n. 4
0
        private Error doSplit(CompanyModel company, SplitPurchaseModel model, UserModel user)
        {
            var error = new Error();

            string lgs;

            // Proceed to do the split
            for (int i = 0; i < podList.Count() && !error.IsError; i++)
            {
                var podListItem = podList[i];
                var splitItem   = model.SplitItems[i];

                var updatedItem = updatedDetails.Items
                                  .Where(ud => ud.OriginalRowId == podListItem.Id)
                                  .FirstOrDefault();

                PurchaseOrderDetailModel pod = new PurchaseOrderDetailModel {
                    CompanyId             = company.Id,
                    PurchaseOrderHeaderId = 0,
                    LineNumber            = 0,
                    ProductId             = podListItem.ProductId.Value,
                    ProductDescription    = podListItem.ProductDescription,
                    UnitPriceExTax        = podListItem.UnitPriceExTax,
                    TaxCodeId             = podListItem.TaxCodeId,
                    DiscountPercent       = podListItem.DiscountPercent,
                    //LineStatus = podListItem.LineStatus,
                    //IsReceived = podListItem.IsReceived
                };

                if (splitItem.NewOrderQty > 0)
                {
                    // Add a new line to a new order
                    if (newPoh == null)
                    {
                        // Create the new order first
                        newPoh             = mapToModel(updatedPoh);
                        newPoh.Id          = 0;
                        newPoh.OrderNumber = LookupService.GetNextSequenceNumber(company, SequenceNumberType.PurchaseOrderNumber, 0, false);
                        error = InsertOrUpdatePurchaseOrderHeader(newPoh, user, "");
                    }
                    if (!error.IsError)
                    {
                        pod.PurchaseOrderHeaderId = newPoh.Id;
                        pod.OrderQty   = splitItem.NewOrderQty;
                        pod.LineNumber = db.GetNextPurchaseOrderDetailLineNumber(pod.PurchaseOrderHeaderId, false);
                        InsertOrUpdatePurchaseOrderDetail(pod, user, "");

                        // Move the # of split item allocations across to the new purchase order line
                        pod.OrderQty -= splitItem.NewOrderQty;
                        var allocList1 = updatedAllocations.Where(a => a.PurchaseLineId == pod.Id)
                                         .ToList();
                        AllocationService.AllocateOnPurchaseOrderSplit(updatedItem, allocList1, newPoh, pod, splitItem.NewOrderQty, user);
                    }
                }

                if (!error.IsError && splitItem.TargetOrderQty > 0)
                {
                    // Add a new line to the target order
                    pod.Id = 0;
                    pod.PurchaseOrderHeaderId = splitItem.TargetOrderId;
                    pod.OrderQty   = splitItem.TargetOrderQty;
                    pod.LineNumber = db.GetNextPurchaseOrderDetailLineNumber(pod.PurchaseOrderHeaderId, false);

                    error = InsertOrUpdatePurchaseOrderDetail(pod, user, "");

                    // Move the # of split item allocations across to the new purchase order line
                    pod.OrderQty -= splitItem.TargetOrderQty;
                    var allocList2 = updatedAllocations.Where(a => a.PurchaseLineId == pod.Id)
                                     .ToList();
                    AllocationService.AllocateOnPurchaseOrderSplit(updatedItem, allocList2, newPoh, pod, splitItem.TargetOrderQty, user);
                }

                if (!error.IsError)
                {
                    InsertOrUpdatePurchaseOrderDetail(updatedItem, user, LockPurchaseOrderDetail(updatedItem));
                }
            }

            if (!error.IsError)
            {
                // Obsolete the existing order
                origPoh.POStatus = LookupService.FindPurchaseOrderHeaderStatusByValueModel(PurchaseOrderStatus.Superceded).Id;
                lgs   = LockPurchaseOrderHeader(origPoh);
                error = InsertOrUpdatePurchaseOrderHeader(origPoh, user, lgs);
            }
            return(error);
        }
Esempio n. 5
0
        private Error validateSplit(CompanyModel company, SplitPurchaseModel model, UserModel user,
                                    string lockGuid)
        {
            var error = new Error();

            // Check that the lock is still current because we are about to change it by
            // moving detail lines from it
            if (!db.IsLockStillValid(typeof(PurchaseOrderHeader).ToString(), model.PurchaseOrderHeaderId, lockGuid))
            {
                error.SetError(EvolutionResources.errRecordChangedByAnotherUser, "NewOrderAdvertisedETA");
            }
            else
            {
                podList = new List <PurchaseOrderDetailModel>();

                numItems = 0;
                origPoh  = FindPurchaseOrderHeaderModel(model.PurchaseOrderHeaderId, company, false);

                foreach (var splitItem in model.SplitItems)
                {
                    // Count the items to be split/moved
                    numItems += splitItem.NewOrderQty + splitItem.TargetOrderQty;

                    // Get the items on the order
                    var pod = FindPurchaseOrderDetailModel(splitItem.PurchaseOrderDetailId);
                    if (pod == null)
                    {
                        error.SetRecordError("PurchaseOrderDetail", splitItem.PurchaseOrderDetailId);
                        break;
                    }
                    else if (splitItem.NewOrderQty + splitItem.TargetOrderQty > pod.OrderQty)
                    {
                        if (splitItem.NewOrderQty > 0)
                        {
                            error.SetError(EvolutionResources.errCantSplitMoreThanOriginalQty, $"txtSplitToNewOrderQty{splitItem.RowNumber}_4_0");
                        }
                        else
                        {
                            error.SetError(EvolutionResources.errCantSplitMoreThanOriginalQty, $"txtTargetOrderQty{splitItem.RowNumber}_5_0");
                        }
                        break;
                    }
                    else
                    {
                        // If we have a target order...
                        if (splitItem.TargetOrderId != 0)
                        {
                            var tempPoh = db.FindPurchaseOrderHeader(splitItem.TargetOrderId);
                            if (tempPoh != null)
                            {
                                // Found it, so check the base numbers (the value to the left of the decimal)
                                if ((int)origPoh.OrderNumber != (int)tempPoh.OrderNumber)
                                {
                                    // Base is different, but is target a root order ?
                                    if ((int)tempPoh.OrderNumber != tempPoh.OrderNumber)
                                    {
                                        // Target order isn't root
                                        error.SetError(EvolutionResources.errYouCannotMoveItemsToNonRootOrder, $"ddlTargetOrder{splitItem.RowNumber}_6_0");
                                        break;
                                    }
                                    else
                                    {
                                        podList.Add(pod);
                                    }
                                }
                                else
                                {
                                    // Base is the same, so valid target order
                                    podList.Add(pod);
                                }
                            }
                            else
                            {
                                // Not found
                                error.SetError(EvolutionResources.errMustSelectValidOrderNumber, $"ddlTargetOrder{splitItem.RowNumber}_6_0");
                                break;
                            }
                        }
                        else
                        {
                            // No target order so make sure qty is 0 for target order
                            if (splitItem.TargetOrderQty > 0)
                            {
                                error.SetError(EvolutionResources.errTargetQtyMustBeZeroWhenNoOrderSpecified, $"txtTargetOrderQty{splitItem.RowNumber}_6_0");
                                break;
                            }
                            else
                            {
                                podList.Add(pod);
                            }
                        }
                    }
                }
                if (!error.IsError && numItems == 0)
                {
                    error.SetError(EvolutionResources.errNoItemsHaveBeenSpecifiedToMoveOrSplit, "");
                }
            }
            return(error);
        }
Esempio n. 6
0
        public void SplitToExistingOrderTest()
        {
            var testUser    = GetTestUser();
            var testCompany = GetTestCompany(testUser, true);

            var sourceOrder      = GetTestPurchaseOrderHeader(testCompany, testUser, 4);
            var sourceOrderItems = PurchasingService.FindPurchaseOrderDetailListModel(sourceOrder);

            // Create a model to split an item off to a new order
            SplitPurchaseModel model = new SplitPurchaseModel {
                PurchaseOrderHeaderId = sourceOrder.Id,
                SupplierName          = "",
                OrderNumber           = 0,
                AdvertisedETA         = null,
                NewOrderAdvertisedETA = DateTimeOffset.Now.AddDays(20),
                LocationId            = 0
            };


            // Try to split off more items than the original order
            var existingOrder = GetTestPurchaseOrderHeader(testCompany, testUser, 0);
            var splitItem     = createSplitItemModel(sourceOrderItems.Items[0].Id, 0, 1500, existingOrder.Id, 1);

            model.SplitItems.Add(splitItem);

            int updatedPOId = 0,
                newPOId     = 0;
            var lgs         = PurchasingService.LockPurchaseOrderHeader(sourceOrder);
            var error       = PurchasingService.SplitOrder(testCompany, model, testUser, lgs, ref updatedPOId, ref newPOId);

            Assert.IsTrue(error.IsError, "$Error: An error was expected but none was returned");


            // Try to split off to an invalid 'existing' order
            splitItem = createSplitItemModel(sourceOrderItems.Items[0].Id, 0, 5, -1, 1);
            model.SplitItems.Clear();
            model.SplitItems.Add(splitItem);

            error = PurchasingService.SplitOrder(testCompany, model, testUser, lgs, ref updatedPOId, ref newPOId);
            Assert.IsTrue(error.IsError, "$Error: An error was expected but none was returned");


            // Now try to split a valid number of items off to an existing order
            int originalQty = sourceOrderItems.Items[0].OrderQty.Value,
                splitQty    = 10;

            splitItem = createSplitItemModel(sourceOrderItems.Items[0].Id, 0, splitQty, existingOrder.Id, 1);
            model.SplitItems.Clear();
            model.SplitItems.Add(splitItem);
            lgs   = PurchasingService.LockPurchaseOrderHeader(sourceOrder);
            error = PurchasingService.SplitOrder(testCompany, model, testUser, lgs, ref updatedPOId, ref newPOId);
            Assert.IsTrue(!error.IsError, error.Message);


            // Check the newly created copy of the original record we have split
            var updatedOrder = PurchasingService.FindPurchaseOrderHeaderModel(updatedPOId, testCompany, false);

            Assert.IsTrue(updatedOrder != null, "Error: A NULL value was returned when an object was expected");

            var updatedPohd = PurchasingService.FindPurchaseOrderDetailListModel(updatedOrder);
            int expected    = originalQty - splitQty,
                actual      = updatedPohd.Items[0].OrderQty.Value;

            Assert.IsTrue(actual == expected, $"Error: The order quantity is now {actual} when {expected} was expected");

            // .. and that the updated order has a note with PDF attachment
            var noteList = NoteService.FindNotesListModel(NoteType.Purchase, updatedPOId, 0, 1, 1000, "", MediaSize.Medium, 0, 0);

            expected = 1;
            actual   = noteList.Items.Count();
            Assert.IsTrue(actual == expected, $"Error: (1) Order was found to have {actual} notes when {expected} were expected");

            var noteAttachments = NoteService.FindNoteAttachmentsModel(noteList.Items[0], MediaSize.Medium, 0, 0);

            expected = 1;
            actual   = noteAttachments.Count();
            Assert.IsTrue(actual == expected, $"Error: (1) Order note was found to have {actual} attachment PDFs when {expected} were expected");


            // Look for the new record in the exiting order
            var newPohdList = db.FindPurchaseOrderDetails(testCompany.Id, existingOrder.Id)
                              .OrderByDescending(ni => ni.Id)
                              .ToList();

            Assert.IsTrue(newPohdList.Count() == 1, $"Error: {newPohdList.Count()} items were returned when 1 was expected");
            expected = splitQty;
            actual   = newPohdList[0].OrderQty.Value;
            Assert.IsTrue(actual == splitQty, $"Error: {actual} items were returned when {expected} was expected");

            // .. and that the existing order has a note with PDF attachment
            noteList = NoteService.FindNotesListModel(NoteType.Purchase, existingOrder.Id, 0, 1, 1000, "", MediaSize.Medium, 0, 0);
            expected = 1;
            actual   = noteList.Items.Count();
            Assert.IsTrue(actual == expected, $"Error: (2) Order was found to have {actual} notes when {expected} were expected");

            noteAttachments = NoteService.FindNoteAttachmentsModel(noteList.Items[0], MediaSize.Medium, 0, 0);
            expected        = 1;
            actual          = noteAttachments.Count();
            Assert.IsTrue(actual == expected, $"Error: (2) Order note was found to have {actual} attachment PDFs when {expected} were expected");

            // TBD: Check that the allocations have been modified
        }