public async Task GetPurchaseOrder_ioNumber_Mapping()
        {
            // Arrange
            const string ioNumber       = "234728934sdf";
            const string contentType    = "Video";
            const string productionType = "Full Production";
            var          costSubmitted  = GetCostRevisionStatusChanged(CostStageRevisionStatus.PendingBrandApproval);
            var          costId         = costSubmitted.AggregateId;

            var paymentDetails = new PgPaymentDetails
            {
                IoNumber = ioNumber
            };

            _customDataServiceMock.Setup(c => c.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), CustomObjectDataKeys.PgPaymentDetails))
            .ReturnsAsync(paymentDetails);

            SetupPurchaseOrderView(costId,
                                   new Dictionary <string, dynamic>
            {
                { "contentType", new { id = Guid.NewGuid(), value = contentType } },
                { "productionType", new { id = Guid.NewGuid(), value = productionType } }
            }
                                   );

            // Act
            var purchase = await PgPurchaseOrderService.GetPurchaseOrder(costSubmitted);

            // Assert
            purchase.IONumber.Should().Be($"00{ioNumber}");
        }
        public async Task GetApproverName_Coupa()
        {
            //Arrange
            var costId = Guid.NewGuid();
            var costStageRevisionId = Guid.NewGuid();
            var cost = new Cost
            {
                Id = costId,
                IsExternalPurchases       = true,
                LatestCostStageRevisionId = costStageRevisionId
            };
            var expectedApproverName = "Sarah Connor";
            var approvalType         = "Brand";
            var approverUserId       = Guid.NewGuid();

            _efContext.Add(cost);
            _efContext.SaveChanges();
            var pgPaymentDetails = new PgPaymentDetails
            {
                IoNumberOwner = expectedApproverName
            };

            _customObjectDataServiceMock
            .Setup(c => c.GetCustomData <PgPaymentDetails>(costStageRevisionId, CustomObjectDataKeys.PgPaymentDetails))
            .Returns(Task.FromResult(pgPaymentDetails));

            //Act
            var result = await _costUserService.GetApprover(costId, approverUserId, approvalType);

            //Assert
            result.Should().NotBeNull();
            result.Should().Be(expectedApproverName);
        }
        public async Task Consume_whenUpdatedAndStatusApprovedAndPendingApproval_shouldApproveTheCost()
        {
            // Arrange
            var activityType   = ActivityTypes.Updated;
            var approvalStatus = ApprovalStatuses.Approved;
            var requisition    = "requisitionId";

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    ApprovalStatus = approvalStatus
                }))
            };
            var operationResponse = new ApprovalServiceActionResult
            {
                Success = true
            };
            var dbPurchaseOrderResponse = new PgPurchaseOrderResponse()
            {
                Requisition = requisition,
            };
            var dbPaymentDetails = new PgPaymentDetails()
            {
                Requisition = requisition,
            };

            var cost = _efContext.Cost.Find(_costId);

            cost.Status = CostStageRevisionStatus.PendingBrandApproval;
            _efContext.Cost.Update(cost);
            await _efContext.SaveChangesAsync();

            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPurchaseOrderResponse));
            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPaymentDetails));
            _customDataServiceMock.Setup(cds => cds.Save(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <object>(), It.IsAny <UserIdentity>())).Returns(Task.FromResult(new CustomObjectData()));
            _approvalServiceMock.Setup(a => a.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa)).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _approvalServiceMock.Verify(s => s.Approve(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, SourceSystem.Coupa), Times.Once);
            _emailNotificationServiceMock.Verify(em => em.CostHasBeenApproved(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);

            Assert.AreEqual(requisition, dbPurchaseOrderResponse.Requisition);
            Assert.AreEqual(requisition, dbPaymentDetails.Requisition);
        }
        public async Task Consume_whenUpdatedAndStatusRejected_shouldRejectTheCost()
        {
            // Arrange
            var activityType   = ActivityTypes.Updated;
            var approvalStatus = ApprovalStatuses.Rejected;

            var purchaseOrderResponse = new PurchaseOrderResponse
            {
                ActivityType = activityType,
                CostNumber   = CostNumber,
                ClientName   = BuType.Pg.ToString(),
                Payload      = JObject.Parse(JsonConvert.SerializeObject(new PgPurchaseOrderResponse
                {
                    ApprovalStatus = approvalStatus
                }))
            };
            var operationResponse = new ApprovalServiceActionResult()
            {
                Success = true
            };
            var dbPurchaseOrderResponse = new PgPurchaseOrderResponse()
            {
                Requisition = "requisitionId",
            };
            var dbPaymentDetails = new PgPaymentDetails()
            {
                Requisition = "requisitionId",
            };

            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPurchaseOrderResponse));
            _customDataServiceMock.Setup(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>())).Returns(Task.FromResult(dbPaymentDetails));
            _customDataServiceMock.Setup(cds => cds.Save(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <object>(), It.IsAny <UserIdentity>())).Returns(Task.FromResult(new CustomObjectData()));
            _approvalServiceMock.Setup(a => a.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, It.IsAny <string>(), It.IsAny <SourceSystem>())).Returns(Task.FromResult(operationResponse));
            _emailNotificationServiceMock.Setup(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <string>())).Returns(Task.FromResult(true));

            // Act
            await _consumer.Consume(purchaseOrderResponse);

            // Assert
            _approvalServiceMock.Verify(s => s.Reject(It.IsAny <Guid>(), It.IsAny <UserIdentity>(), BuType.Pg, It.IsAny <string>(), It.IsAny <SourceSystem>()), Times.Once);
            _emailNotificationServiceMock.Verify(em => em.CostHasBeenRejected(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <string>()), Times.Once);
            _customDataServiceMock.Verify(cds => cds.GetCustomData <PgPurchaseOrderResponse>(It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);
            _customDataServiceMock.Verify(cds => cds.GetCustomData <PgPaymentDetails>(It.IsAny <Guid>(), It.IsAny <string>()), Times.Once);

            Assert.IsNull(dbPurchaseOrderResponse.Requisition);
            Assert.IsNull(dbPaymentDetails.Requisition);
        }
        protected void InitDataForReopenedFA(
            bool isAipe                                             = false,
            string stageKey                                         = "Aipe",
            string budgetRegion                                     = "AAK (Asia)",
            List <CostLineItemView> items                           = null,
            List <CostLineItemView> previousFAItems                 = null,
            string targetBudget                                     = "0",
            List <CostStageRevisionPaymentTotal> payments           = null,
            List <CostStageRevisionPaymentTotal> previousFAPayments = null,
            string contentType                                      = Constants.ContentType.Video,
            string productionType                                   = Constants.ProductionType.FullProduction,
            CostType costType                                       = CostType.Production,
            string agencyCurrency                                   = "USD",
            Guid?dpvCurrency                                        = null,
            Guid?dpvId            = null,
            string vendorCategory = null
            )
        {
            SetupCurrencies();

            var previousCostStageRevisionId = Guid.NewGuid();

            _costStageRevisionId = Guid.NewGuid();
            var _costPreviousStageRevisionId = Guid.NewGuid();

            var costId            = Guid.NewGuid();
            var costStageId       = Guid.NewGuid();
            var paymentCurrencyId = dpvCurrency ?? _efContext.Currency.FirstOrDefault(c => c.Code == agencyCurrency)?.Id;

            _stage = new CostStage {
                Key = stageKey, Id = costStageId
            };
            _contentType       = contentType;
            _productionType    = productionType;
            _stageDetails      = GetStageDetails(isAipe, budgetRegion, targetBudget, costType, agencyCurrency);
            _productionDetails = GetProductionDetails(dpvCurrency, dpvId, vendorCategory);
            _revision          = new CostStageRevision
            {
                Id           = _costStageRevisionId,
                StageDetails = new CustomFormData {
                    Data = JsonConvert.SerializeObject(_stageDetails)
                },
                ProductDetails = new CustomFormData {
                    Data = JsonConvert.SerializeObject(_productionDetails)
                },
                CostStage = _stage,
                Status    = CostStageRevisionStatus.Approved,
                Approvals = new List <Approval>()
            };

            _previousRevision = new CostStageRevision
            {
                Id           = _costPreviousStageRevisionId,
                StageDetails = new CustomFormData {
                    Data = JsonConvert.SerializeObject(_stageDetails)
                },
                ProductDetails = new CustomFormData {
                    Data = JsonConvert.SerializeObject(_productionDetails)
                },
                CostStage = _stage,
                Status    = CostStageRevisionStatus.Approved,
                Approvals = new List <Approval>()
            };

            _cost = new Cost
            {
                Id       = costId,
                CostType = costType,
                LatestCostStageRevisionId = _costStageRevisionId,
                LatestCostStageRevision   = _revision,

                Project = new Project(),
                Parent  = new AbstractType
                {
                    Agency = new Agency()
                },
                PaymentCurrencyId = paymentCurrencyId,
                ExchangeRate      = _efContext.ExchangeRate.FirstOrDefault(er => er.FromCurrency == paymentCurrencyId)?.Rate
            };
            _stage.Cost = _cost;
            _stage.Name = "Final Actual";

            var previousRevision = new CostStageRevision {
                Id = previousCostStageRevisionId
            };

            //add previous stage revision to the stage
            _stage.CostStageRevisions.Add(_previousRevision);

            _costApprovedEvent = new CostStageRevisionStatusChanged(_cost.Id, _previousRevision.Id, CostStageRevisionStatus.Approved, BuType.Pg);
            _costApprovedEvent = new CostStageRevisionStatusChanged(_cost.Id, _revision.Id, CostStageRevisionStatus.Approved, BuType.Pg);

            _paymentDetailsData = new PgPaymentDetails();
            _costLineItems      = new List <CostLineItemView>();
            if (items != null)
            {
                _costLineItems.AddRange(items);
            }
            var _previousCostLineItems = new List <CostLineItemView>();

            if (items != null)
            {
                _previousCostLineItems.AddRange(previousFAItems);
            }

            var paymentsList = new List <CostStageRevisionPaymentTotal>();

            if (payments != null)
            {
                foreach (var payment in payments)
                {
                    payment.CostStageRevision = _revision;
                }
                paymentsList.AddRange(payments);
            }
            var previousPaymentsList = new List <CostStageRevisionPaymentTotal>();

            if (previousFAPayments != null)
            {
                foreach (var payment in previousFAPayments)
                {
                    payment.CostStageRevision = _previousRevision;
                }
                previousPaymentsList.AddRange(previousFAPayments);
            }
            //set upp last stage revision data
            _costStageRevisionServiceMock.Setup(csr => csr.GetRevisionById(_costPreviousStageRevisionId)).ReturnsAsync(_previousRevision);
            _costStageRevisionServiceMock.Setup(csr => csr.GetPreviousRevision(costStageId)).ReturnsAsync(previousRevision);
            _costStageRevisionServiceMock.Setup(csr =>
                                                csr.GetStageDetails <PgStageDetailsForm>(It.Is <CostStageRevision>(r => r.Id == _costPreviousStageRevisionId)))
            .Returns(_stageDetails);
            _costStageRevisionServiceMock.Setup(csr =>
                                                csr.GetProductionDetails <PgProductionDetailsForm>(It.Is <CostStageRevision>(r => r.Id == _costPreviousStageRevisionId)))
            .Returns(_productionDetails);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostStageRevisionPaymentTotals(_costPreviousStageRevisionId, It.IsAny <bool>())).ReturnsAsync((List <CostStageRevisionPaymentTotal>)null);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostStageRevisionPaymentTotals(previousCostStageRevisionId, It.IsAny <bool>())).ReturnsAsync(previousPaymentsList);
            _costStageRevisionServiceMock.Setup(csr => csr.GetAllCostPaymentTotals(costId, costStageId)).ReturnsAsync(previousPaymentsList);
            _costStageRevisionServiceMock.Setup(csr => csr.GetAllCostPaymentTotalsFinalActual(costId, costStageId)).ReturnsAsync(previousPaymentsList);
            _customDataServiceMock.Setup(cd => cd.GetCustomData <PgPaymentDetails>(_costPreviousStageRevisionId, CustomObjectDataKeys.PgPaymentDetails))
            .ReturnsAsync(_paymentDetailsData);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostLineItems(_costPreviousStageRevisionId)).ReturnsAsync(_previousCostLineItems);

            //set up latest stage revision data
            _costStageRevisionServiceMock.Setup(csr => csr.GetRevisionById(_costStageRevisionId)).ReturnsAsync(_revision);
            _costStageRevisionServiceMock.Setup(csr => csr.GetPreviousRevision(costStageId)).ReturnsAsync(previousRevision);
            _costStageRevisionServiceMock.Setup(csr =>
                                                csr.GetStageDetails <PgStageDetailsForm>(It.Is <CostStageRevision>(r => r.Id == _costStageRevisionId)))
            .Returns(_stageDetails);
            _costStageRevisionServiceMock.Setup(csr =>
                                                csr.GetProductionDetails <PgProductionDetailsForm>(It.Is <CostStageRevision>(r => r.Id == _costStageRevisionId)))
            .Returns(_productionDetails);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostStageRevisionPaymentTotals(_costStageRevisionId, It.IsAny <bool>())).ReturnsAsync((List <CostStageRevisionPaymentTotal>)null);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostStageRevisionPaymentTotals(previousCostStageRevisionId, It.IsAny <bool>())).ReturnsAsync(paymentsList);
            _costStageRevisionServiceMock.Setup(csr => csr.GetAllCostPaymentTotals(costId, costStageId)).ReturnsAsync(paymentsList);
            _customDataServiceMock.Setup(cd => cd.GetCustomData <PgPaymentDetails>(_costStageRevisionId, CustomObjectDataKeys.PgPaymentDetails))
            .ReturnsAsync(_paymentDetailsData);
            _costStageRevisionServiceMock.Setup(csr => csr.GetCostLineItems(_costStageRevisionId)).ReturnsAsync(_costLineItems);


            _efContext.Cost.Add(_cost);
            _efContext.SaveChanges();
        }
Ejemplo n.º 6
0
        private async Task <CostSearchItem> CostSearchItem(Cost cost, ICostBuilder costBuilder)
        {
            Currency currency             = null;
            var      customObjectFormData =
                await _efContext.CustomObjectData.FirstOrDefaultAsync(
                    cofd => cofd.ObjectId == cost.LatestCostStageRevision.Id && cofd.Name == CustomObjectDataKeys.PgPaymentDetails);

            var stageDetailsForm = JsonConvert.DeserializeObject <PgStageDetailsForm>(cost.LatestCostStageRevision.StageDetails.Data);

            var productionDetailsForm = new PgProductionDetailsForm();

            if (cost.LatestCostStageRevision.ProductDetails != null)
            {
                productionDetailsForm = JsonConvert.DeserializeObject <PgProductionDetailsForm>(cost.LatestCostStageRevision.ProductDetails.Data);
            }

            PgPaymentDetails paymentDetails = null;

            if (customObjectFormData?.Data != null)
            {
                paymentDetails = JsonConvert.DeserializeObject <PgPaymentDetails>(customObjectFormData.Data);
            }

            var approvers =
                cost.LatestCostStageRevision.Approvals
                .SelectMany(a => a.ApprovalMembers)
                .Where(am => !am.IsExternal)
                .Select(am => new Approver
            {
                CostUserId = am.CostUser.Id,
                Name       = $"{am.CostUser.FirstName} {am.CostUser.LastName}",
                Role       = am.CostUser.UserBusinessRoles?.FirstOrDefault()?.BusinessRole?.Value ?? "Sap Approver",
                Status     = am.Status.ToString()
            });

            if (!string.IsNullOrEmpty(stageDetailsForm.AgencyCurrency))
            {
                currency = await _efContext.Currency.FirstOrDefaultAsync(c => c.Code == stageDetailsForm.AgencyCurrency);
            }

            if (productionDetailsForm?.DirectPaymentVendor?.CurrencyId != null)
            {
                currency = await _efContext.Currency.FirstOrDefaultAsync(c => c.Id == productionDetailsForm.DirectPaymentVendor.CurrencyId);
            }

            if (currency == null)
            {
                currency = await _efContext.Currency.FirstOrDefaultAsync(c => c.DefaultCurrency);
            }

            var costSearchItem = _mapper.Map <CostSearchItem>(cost);
            var totals         = await costBuilder.GetRevisionTotals(cost.LatestCostStageRevision.Id);

            costSearchItem.GrandTotal = totals.totalInLocalCurrency;
            costSearchItem.GrandTotalDefaultCurrency = totals.total;
            costSearchItem.ApprovalMembers           = new List <Approver>();
            costSearchItem.ApprovalMembers.AddRange(approvers);
            costSearchItem.LatestRevisionId = cost.LatestCostStageRevision.Id;

            costSearchItem.UserGroups  = (await _permissionService.GetObjectUserGroups(cost.Id, null)).ToList();
            costSearchItem.BrandId     = cost.Project.BrandId.ToString();
            costSearchItem.AgencyId    = cost.ParentId.ToString();
            costSearchItem.IoNumber    = paymentDetails?.IoNumber;
            costSearchItem.Initiatives = cost.LatestCostStageRevision.ExpectedAssets?.Select(a => a.Initiative).Distinct().ToList();
            _mapper.Map(stageDetailsForm, costSearchItem);
            costSearchItem.Stage    = cost.LatestCostStageRevision.CostStage.Name;
            costSearchItem.StageKey = cost.LatestCostStageRevision.CostStage.Key;

            return(_mapper.Map(currency, costSearchItem));
        }
Ejemplo n.º 7
0
        private void SetupPurchaseOrderCost(Cost cost, CostStageRevision latestRevision,
                                            CostUser costOwner, Guid previousRevisionId, Guid latestRevisionId, string poNumber)
        {
            const string brandApproverGdamUserId = "57e5461ed9563f268ef4f1ta";
            const string brandApproverName       = "John Smith";
            var          costId      = Guid.NewGuid();
            var          costOwnerId = Guid.NewGuid();
            var          projectId   = Guid.NewGuid();

            var previousStageId = Guid.NewGuid();
            var latestStageId   = Guid.NewGuid();

            var previousRevision        = new CostStageRevision();
            var previousStage           = new CostStage();
            var latestStage             = new CostStage();
            var project                 = new Project();
            var brand                   = new Brand();
            var agency                  = new Agency();
            var country                 = new Country();
            var brandApproval           = new Approval();
            var brandApprover           = new ApprovalMember();
            var brandApproverAsCostUser = new CostUser();

            previousRevision.CostStage = previousStage;
            previousRevision.Id        = previousRevisionId;

            previousStage.Id = previousRevision.CostStageId = previousStageId;
            latestStage.Id   = latestRevision.CostStageId = latestStageId;

            previousStage.Name = CostStages.OriginalEstimate.ToString();
            latestStage.Name   = CostStages.FinalActual.ToString();

            cost.CostStages.AddRange(new[] { previousStage, latestStage });

            //China non-Cyclone Agencies should create a notification for non-backup approver when the cost total amount has changed
            SetupDataSharedAcrossTests(agency, country, cost, latestRevision, project, costOwner, costOwnerId, latestStage,
                                       brand, costId, latestRevisionId, projectId, Constants.BudgetRegion.China);

            brandApproval.ApprovalMembers = new List <ApprovalMember> {
                brandApprover
            };
            brandApprover.CostUser = brandApproverAsCostUser;

            brandApproval.Type = ApprovalType.Brand;
            brandApproverAsCostUser.GdamUserId = brandApproverGdamUserId;
            brandApproverAsCostUser.FullName   = brandApproverName;

            var approvals = new List <Approval> {
                brandApproval
            };

            ApprovalServiceMock.Setup(a => a.GetApprovalsByCostStageRevisionId(It.IsAny <Guid>(), true)).ReturnsAsync(approvals);

            var pgPaymentDetails = new PgPaymentDetails
            {
                PoNumber = poNumber
            };

            CostStageServiceMock.Setup(cssm => cssm.GetPreviousCostStage(latestStageId)).Returns(Task.FromResult(previousStage));
            CostStageRevisionServiceMock.Setup(csrsm => csrsm.GetLatestRevision(previousStageId)).Returns(Task.FromResult(previousRevision));
            CustomObjectDataServiceMock
            .Setup(codsm => codsm.GetCustomData <PgPaymentDetails>(latestRevisionId, CustomObjectDataKeys.PgPaymentDetails))
            .Returns(Task.FromResult(pgPaymentDetails));
            CustomObjectDataServiceMock
            .Setup(codsm => codsm.GetCustomData <PgPaymentDetails>(previousRevisionId, CustomObjectDataKeys.PgPaymentDetails))
            .Returns(Task.FromResult(pgPaymentDetails));
        }