private CostStageRevision SetupCostStageRevision(Guid costStageRevisionId, Guid costId, bool mockApproval = false)
            {
                var costStageId = Guid.NewGuid();
                var revision    = new CostStageRevision
                {
                    Id           = costStageRevisionId,
                    StageDetails = new CustomFormData
                    {
                        Id   = new Guid(),
                        Data = JsonConvert.SerializeObject(new Dictionary <string, dynamic>())
                    },
                    CostStageId = costStageId,
                    CostStage   = new CostStage
                    {
                        Id = costStageId,

                        CostId = costId,
                        Cost   = new Cost
                        {
                            Id       = costId,
                            CostType = CostType.Buyout,
                        }
                    }
                };

                if (mockApproval)
                {
                    CostBuilderMock.Setup(s => s.GetApprovals(It.IsAny <CostType>(), It.IsAny <IStageDetails>(), It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <Guid>()))
                    .ReturnsAsync(new List <Builders.Response.ApprovalModel>());
                }
                return(revision);
            }
Пример #2
0
        private CostLineItem GetOrCreateCostLineItem(CostStageRevision costStageRevision, Guid userId, CostLineItemSectionTemplateModel section,
                                                     CostLineItemSectionTemplateItemModel item)
        {
            if (costStageRevision.CostLineItems == null)
            {
                costStageRevision.CostLineItems = new List <CostLineItem>();
            }

            foreach (var cli in costStageRevision.CostLineItems)
            {
                if (cli.Name == item.Name &&
                    cli.CostLineItemSectionTemplate?.Name == section.Name)
                {
                    return(cli);
                }
            }

            //Create new
            var costLineItem = new CostLineItem
            {
                CostStageRevision = costStageRevision,
                Id = Guid.NewGuid(),
                LocalCurrencyId   = Guid.Empty,
                Name              = item.Name,
                TemplateSectionId = section.Id
            };

            costStageRevision.CostLineItems.Add(costLineItem);
            costLineItem.SetCreatedNow(userId);
            return(costLineItem);
        }
            protected Cost MockCost()
            {
                var costId              = Guid.NewGuid();
                var costStageId         = Guid.NewGuid();
                var costStageRevisionId = Guid.NewGuid();
                var costStage           = new CostStage
                {
                    Id = costStageId
                };
                var costStageRevision = new CostStageRevision
                {
                    Id          = costStageRevisionId,
                    CostStage   = costStage,
                    CostStageId = costStageId
                };
                var cost = new Cost
                {
                    Id     = costId,
                    Status = CostStageRevisionStatus.Draft,
                    LatestCostStageRevisionId = costStageRevisionId,
                    LatestCostStageRevision   = costStageRevision
                };

                EFContext.Cost.Add(cost);
                EFContext.SaveChanges();

                return(cost);
            }
Пример #4
0
        public void GetPreviousRevision_HasOnePreviousRevision()
        {
            //Arrange
            var cost               = new Cost();
            var latestRevision     = new CostStageRevision();
            var latestRevisionId   = Guid.NewGuid();
            var previousRevision   = new CostStageRevision();
            var previousRevisionId = Guid.NewGuid();
            var costStage          = new CostStage();

            latestRevision.CostStage = costStage;
            latestRevision.Id        = latestRevisionId;
            latestRevision.Modified  = DateTime.Now;
            latestRevision.Created   = DateTime.Now;

            previousRevision.Id       = previousRevisionId;
            previousRevision.Modified = DateTime.Now.AddSeconds(-1);
            previousRevision.Created  = DateTime.Now.AddSeconds(-1);

            costStage.CostStageRevisions.Add(latestRevision);
            costStage.CostStageRevisions.Add(previousRevision);

            cost.LatestCostStageRevision = latestRevision;

            //Act
            var result = cost.GetPreviousRevision();

            //Assert
            result.Should().NotBeNull();
            result.Should().Be(previousRevision);
        }
        internal async Task<IEnumerable<EmailNotificationMessage<CostNotificationObject>>> Build(Cost cost,
            CostNotificationUsers costUsers, CostStageRevision costStageRevision, DateTime timestamp)
        {
            var notifications = new List<EmailNotificationMessage<CostNotificationObject>>();

            //Cost Owner
            var costOwner = costUsers.CostOwner;
            var recipients = new List<string> { costOwner.GdamUserId };
            recipients.AddRange(costUsers.Watchers);

            var costOwnerNotification = new EmailNotificationMessage<CostNotificationObject>(Constants.EmailNotificationActionType.Cancelled, recipients);
            AddSharedTo(costOwnerNotification);
            MapEmailNotificationObject(costOwnerNotification.Object, cost, costOwner);
            PopulateOtherFields(costOwnerNotification, Constants.EmailNotificationParents.CostOwner, timestamp, cost.Id, costStageRevision.Id);
            await PopulateMetadata(costOwnerNotification.Object, cost.Id);
            notifications.Add(costOwnerNotification);

            if (ShouldNotifyInsuranceUsers(costUsers))
            {
                var insuranceUserNotification = new EmailNotificationMessage<CostNotificationObject>(Constants.EmailNotificationActionType.Cancelled, costUsers.InsuranceUsers);
                AddSharedTo(insuranceUserNotification);
                MapEmailNotificationObject(insuranceUserNotification.Object, cost, costOwner);
                PopulateOtherFields(insuranceUserNotification, Constants.EmailNotificationParents.InsuranceUser, timestamp, cost.Id, costStageRevision.Id);
                await PopulateMetadata(insuranceUserNotification.Object, cost.Id);
                notifications.Add(insuranceUserNotification);
            }
            await AddFinanceManagerNotification(Constants.EmailNotificationActionType.Cancelled,
                cost, costUsers, costStageRevision, timestamp, notifications);

            return notifications;
        }
            public async Task ReturnNull_WhenNoPreviousRevision()
            {
                // Arrange
                var costStageKey = CostStages.FirstPresentation.ToString();
                var costId       = Guid.NewGuid();
                var createdById  = Guid.NewGuid();
                var revision2    = new CostStageRevision
                {
                    Id          = Guid.NewGuid(),
                    CreatedById = createdById,
                    Created     = DateTime.UtcNow
                };
                var costStage = new CostStage
                {
                    Key  = costStageKey,
                    Cost = new Cost
                    {
                        Id = costId
                    },
                    CostStageRevisions = new List <CostStageRevision> {
                        revision2
                    }
                };

                EFContext.CostStage.Add(costStage);
                await EFContext.SaveChangesAsync();

                // Act
                var previousRevision = await Service.GetPreviousRevision(revision2.Id);

                // Assert
                previousRevision.Should().BeNull();
            }
        public bool DoesUserHaveRoleForCost(CostUser costUser, CostStageRevision costStageRevision, string businessRole)
        {
            if (costUser == null)
            {
                throw new ArgumentNullException(nameof(costUser));
            }

            if (costUser.UserBusinessRoles == null)
            {
                throw new ArgumentException($"{nameof(costUser.UserBusinessRoles)} are missing");
            }

            if (costStageRevision == null)
            {
                throw new ArgumentException($"{nameof(costStageRevision)} is missing");
            }

            if (costStageRevision.StageDetails == null)
            {
                throw new ArgumentException($"{nameof(costStageRevision.StageDetails)} is missing");
            }

            var stageDetails = _costStageRevisionService.GetStageDetails <PgStageDetailsForm>(costStageRevision);
            var smoName      = stageDetails.SmoName;

            var hasRole = costUser.UserBusinessRoles.Any(ubr =>
                                                         ubr.BusinessRole != null &&
                                                         ubr.BusinessRole.Key == businessRole &&
                                                         (ubr.ObjectId != null || ubr.Labels.Contains(smoName))
                                                         );

            return(hasRole);
        }
        public async Task GetMediaTypes_Types_WhenCostTypeIsTrafficking_ShouldReturnValidListOfMediaTypes()
        {
            // Arrange
            var revisionId         = Guid.NewGuid();
            var pgStageDetailsForm = new PgStageDetailsForm();

            var revision = new CostStageRevision
            {
                Id           = revisionId,
                StageDetails = new CustomFormData
                {
                    Data = JsonConvert.SerializeObject(pgStageDetailsForm)
                },
                CostStage = new CostStage
                {
                    Cost = new Cost
                    {
                        CostType = CostType.Trafficking
                    }
                }
            };

            _efContext.CostStageRevision.Add(revision);
            _efContext.SaveChanges();
            _costStageRevisionServiceMock.Setup(s =>
                                                s.GetStageDetails <PgStageDetailsForm>(revision))
            .Returns(pgStageDetailsForm);

            // Act
            var result = await _service.GetMediaTypes(revisionId);

            // Assert
            result.Select(i => i.Key).Should().BeEquivalentTo(Constants.MediaType.NA);
        }
Пример #9
0
            private async Task <Cost> CreateCost_At_OE_Stage_With_Revision(Cost cost)
            {
                var newCostStageRevision = new CostStageRevision()
                {
                    Id     = Guid.NewGuid(),
                    Name   = nameof(CostStages.OriginalEstimateRevision),
                    Status = CostStageRevisionStatus.PendingTechnicalApproval
                };

                cost.ExchangeRateDate = DateTime.UtcNow;

                cost.CostStages.Where(cs => cs.Name == nameof(CostStages.OriginalEstimate)).ToList().ForEach(cs =>
                {
                    cs.CostStageRevisions.Where(csr => csr.Name == nameof(CostStages.OriginalEstimateRevision)).ToList().ForEach(csr =>
                    {
                        csr.Status = CostStageRevisionStatus.Rejected;
                    });
                });

                cost.CostStages.LastOrDefault().CostStageRevisions.Add(newCostStageRevision);
                cost.LatestCostStageRevision   = newCostStageRevision;
                cost.LatestCostStageRevisionId = newCostStageRevision.Id;

                _eFContext.Cost.Update(cost);
                await _eFContext.SaveChangesAsync();

                return(cost);
            }
Пример #10
0
        public void CostStageRevision_To_RevisionModel_IsValid()
        {
            // Arrange
            var costStageRevision = new CostStageRevision
            {
                Id          = Guid.NewGuid(),
                CreatedById = Guid.NewGuid(),
                Created     = DateTime.Now,
                Modified    = DateTime.Now.AddDays(1),
                Status      = CostStageRevisionStatus.Draft,
                CreatedBy   = new CostUser {
                    Id = Guid.NewGuid()
                }
            };

            // Act
            var model = _mapper.Map <CostStageRevision, RevisionModel>(costStageRevision);

            // Assert
            model.Id.Should().Be(costStageRevision.Id);
            model.CostStageId.Should().Be(costStageRevision.CostStageId);
            model.Name.Should().Be(costStageRevision.Name);
            model.Status.Should().Be(costStageRevision.Status);
            model.StageDetailsId.Should().Be(costStageRevision.StageDetailsId);
            model.ProductDetailsId.Should().Be(costStageRevision.ProductDetailsId);
            model.CreatedById.Should().Be(costStageRevision.CreatedById);
            model.IsPaymentCurrencyLocked.Should().Be(costStageRevision.IsPaymentCurrencyLocked);
            model.IsLineItemSectionCurrencyLocked.Should().Be(costStageRevision.IsLineItemSectionCurrencyLocked);
            model.Created.Should().Be(costStageRevision.Created);
            model.Modified.Should().Be(costStageRevision.Modified.Value);
            model.CreatedBy.Id.Should().Be(costStageRevision.CreatedBy.Id);
        }
Пример #11
0
            private async Task <Cost> CreateCost_At_FA_Stage_With_Revision(Cost cost)
            {
                //Reject current stages
                cost.CostStages.Where(cs => cs.Name == nameof(CostStages.FinalActual)).ToList().ForEach(cs =>
                {
                    cs.CostStageRevisions.Where(csr => csr.Name == nameof(CostStages.FinalActualRevision)).ToList().ForEach(csr =>
                    {
                        csr.Status = CostStageRevisionStatus.Rejected;
                    });
                });

                //Add new item for current stages
                var newCostStageRevision = new CostStageRevision()
                {
                    Id     = Guid.NewGuid(),
                    Name   = nameof(CostStages.FinalActualRevision),
                    Status = CostStageRevisionStatus.PendingTechnicalApproval
                };

                cost.CostStages.LastOrDefault().CostStageRevisions.Add(newCostStageRevision);
                cost.LatestCostStageRevision   = newCostStageRevision;
                cost.LatestCostStageRevisionId = newCostStageRevision.Id;

                _eFContext.Cost.Update(cost);
                await _eFContext.SaveChangesAsync();

                return(cost);
            }
Пример #12
0
            public async Task CreateVersion_Stages_Reopen(string testCase, string strCostAction, string shouldClearExchangeRateDate)
            {
                // Arrange
                var costHasExchangeRateDate = string.IsNullOrWhiteSpace(shouldClearExchangeRateDate)
                    ? true
                    : false;
                var cost = await SetupCostStageData(testCase);

                CostAction action      = (CostAction)Enum.Parse(typeof(CostAction), strCostAction);
                var        newRevision = new CostStageRevision {
                    Name = cost.LatestCostStageRevision.Name
                };

                _costStageRevisionServiceMock.Setup(crs => crs.CreateVersion(It.IsAny <CostStageRevision>(), It.IsAny <Guid>(), It.IsAny <BuType>(), action))
                .ReturnsAsync(newRevision);
                CostStatusServiceMock.Setup(b => b.UpdateCostStatus(It.IsAny <BuType>(), cost.Id, action))
                .ReturnsAsync(new OperationResponse {
                });
                CostApprovalServiceMock.Setup(b => b.UpdateApprovals(It.IsAny <Guid>(), User.Id, It.IsAny <BuType>()))
                .Returns(Task.FromResult(default(object)));
                _activityLogServiceMock.Setup(b => b.Log(It.IsAny <CostReopened>()))
                .Returns(Task.FromResult(default(object)));

                // Act
                var response = await CostActionService.CreateVersion(cost.Id, User, action);

                // Assert
                var updatedCost = await _eFContext.Cost.FindAsync(cost.Id);

                updatedCost.ExchangeRateDate.HasValue.Should().Be(costHasExchangeRateDate);
                updatedCost.ExchangeRate.HasValue.Should().Be(costHasExchangeRateDate);
            }
Пример #13
0
        public void HasPreviousRevisions_HasRevisions()
        {
            //Arrange
            var cost               = new Cost();
            var latestRevision     = new CostStageRevision();
            var latestRevisionId   = Guid.NewGuid();
            var previousRevision   = new CostStageRevision();
            var previousRevisionId = Guid.NewGuid();
            var costStage          = new CostStage();

            latestRevision.CostStage = costStage;
            latestRevision.Id        = latestRevisionId;
            previousRevision.Id      = previousRevisionId;

            costStage.CostStageRevisions.Add(latestRevision);
            costStage.CostStageRevisions.Add(previousRevision);

            cost.LatestCostStageRevision = latestRevision;

            //Act
            var result = cost.HasPreviousRevision();

            //Assert
            result.Should().BeTrue();
        }
            protected Cost MockCost()
            {
                var latestRevision = new CostStageRevision
                {
                    Status    = CostStageRevisionStatus.PendingReopen,
                    Id        = Guid.NewGuid(),
                    CostStage = new CostStage
                    {
                        CostStageRevisions = new List <CostStageRevision>
                        {
                            new CostStageRevision
                            {
                                Status = CostStageRevisionStatus.Approved,
                                Id     = Guid.NewGuid(),
                            },
                            new CostStageRevision
                            {
                                Status = CostStageRevisionStatus.PendingReopen,
                                Id     = Guid.NewGuid(),
                            },
                        }
                    }
                };
                var cost = new Cost
                {
                    Id = Guid.NewGuid(),
                    LatestCostStageRevisionId = latestRevision.Id,
                    LatestCostStageRevision   = latestRevision,
                };

                EFContextMock.MockAsyncQueryable(new List <Cost> {
                    cost
                }.AsQueryable(), d => d.Cost);
                return(cost);
            }
Пример #15
0
        public async Task <Decimal?> GetTargetBudget(CostStageRevision revision)
        {
            var stageDetails = await _efContext.CustomFormData.FirstOrDefaultAsync(form => form.Id == revision.StageDetailsId);

            var stageDetailsForm = JsonConvert.DeserializeObject <PgStageDetailsForm>(stageDetails.Data);

            return(stageDetailsForm.InitialBudget);
        }
        protected void SetupDataSharedAcrossTests(Agency agency, Country country,
                                                  Cost cost, CostStageRevision latestRevision, Project project, CostUser costOwner, Guid costOwnerId, CostStage costStage,
                                                  Brand brand, Guid costId, Guid costStageRevisionId, Guid projectId, string budgetRegion = Constants.BudgetRegion.AsiaPacific)
        {
            agency.Country  = country;
            cost.CostNumber = CostNumber;
            cost.LatestCostStageRevision = latestRevision;
            cost.Project             = project;
            costOwner.Agency         = agency;
            costOwner.Id             = costOwnerId;
            latestRevision.CostStage = costStage;
            project.Brand            = brand;

            agency.Name           = AgencyName;
            brand.Name            = BrandName;
            cost.Id               = costId;
            costStage.Name        = CostStageName.ToString();
            costOwner.FullName    = CostOwnerFullName;
            costOwner.GdamUserId  = CostOwnerGdamUserId;
            latestRevision.Id     = costStageRevisionId;
            project.Id            = projectId;
            project.Name          = ProjectName;
            project.GdamProjectId = ProjectGdamId;
            project.AdCostNumber  = ProjectNumber;
            country.Name          = AgencyLocation;

            var stageDetails = new PgStageDetailsForm
            {
                ContentType = new core.Builders.DictionaryValue
                {
                    Id  = Guid.NewGuid(),
                    Key = ContentType
                },
                CostType       = cost.CostType.ToString(),
                ProductionType = new core.Builders.DictionaryValue
                {
                    Id  = Guid.NewGuid(),
                    Key = CostProductionType
                },
                Title = CostTitle,
                AgencyTrackingNumber = AgencyTrackingNumber,
                BudgetRegion         = new AbstractTypeValue
                {
                    Key  = budgetRegion,
                    Name = budgetRegion
                }
            };
            var existingUser = EFContext.CostUser.FirstOrDefault(a => a.GdamUserId == CostOwnerGdamUserId);

            if (existingUser == null)
            {
                EFContext.Add(costOwner);
                EFContext.SaveChanges();
            }

            CostStageRevisionServiceMock.Setup(csr => csr.GetStageDetails <PgStageDetailsForm>(costStageRevisionId)).ReturnsAsync(stageDetails);
        }
Пример #17
0
        public async Task GrNumbers_whenMultipleStages_shouldReturnGrNumberForEachVersionOfEachStage()
        {
            // Arrange
            var costSubmitted = GetCostRevisionStatusChanged(CostStageRevisionStatus.PendingCancellation);
            var costId        = costSubmitted.AggregateId;
            var cost          = SetupPurchaseOrderView(costId);
            var costStage1    = cost.LatestCostStageRevision.CostStage;
            var revision1     = cost.LatestCostStageRevision;
            var grNumber1     = "gr-number-1";

            var revision2 = new CostStageRevision {
                Id = Guid.NewGuid()
            };

            costStage1.CostStageRevisions.Add(revision2);
            var grNumber2 = "gr-number-2";

            var costStage2 = new CostStage();
            var revision3  = new CostStageRevision {
                Id = Guid.NewGuid(), CostStage = costStage2
            };

            costStage2.CostStageRevisions.Add(revision3);
            var grNumber3 = "gr-number-3";

            _customDataServiceMock.Setup(cd => cd.GetCustomData <PgPurchaseOrderResponse>(
                                             It.Is <IEnumerable <Guid> >(ids =>
                                                                         ids.Contains(revision1.Id) &&
                                                                         ids.Contains(revision2.Id) &&
                                                                         ids.Contains(revision2.Id)), CustomObjectDataKeys.PgPurchaseOrderResponse)
                                         )
            .ReturnsAsync(new List <PgPurchaseOrderResponse>
            {
                new PgPurchaseOrderResponse
                {
                    GrNumber = grNumber1
                },
                new PgPurchaseOrderResponse
                {
                    GrNumber = grNumber2
                },
                new PgPurchaseOrderResponse
                {
                    GrNumber = grNumber3
                }
            });

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

            // Assert
            purchase.GrNumbers.Should().NotBeNull();
            purchase.GrNumbers.Should().HaveCount(3);
            purchase.GrNumbers.Should().Contain(grNumber1);
            purchase.GrNumbers.Should().Contain(grNumber2);
            purchase.GrNumbers.Should().Contain(grNumber3);
        }
Пример #18
0
        public async Task GetCostStagesLatestRevisions_OneStage()
        {
            // Arrange
            var currency = new Currency
            {
                Code            = "AFN",
                DefaultCurrency = false,
                Description     = "",
                Id     = Guid.NewGuid(),
                Symbol = "symbol"
            };
            var cost = new Cost
            {
                Id = Guid.NewGuid(),
                PaymentCurrency = currency
            };
            const string costNumber = "AC1489594599188";

            var costStage = new CostStage
            {
                Id          = Guid.NewGuid(),
                CostId      = cost.Id,
                CreatedById = Guid.NewGuid(),
                Created     = DateTime.Now,
                Modified    = DateTime.Now,
                Key         = CostStages.OriginalEstimate.ToString(),
                StageOrder  = 2,
                Cost        = cost
            };
            var costStageRevision = new CostStageRevision
            {
                StageDetails = new CustomFormData
                {
                    Data = JsonConvert.SerializeObject(new PgStageDetailsForm
                    {
                        CostNumber = costNumber
                    }, _serializerSettings)
                },
                Id        = Guid.NewGuid(),
                CostStage = costStage
            };

            _efContext.CostStageRevision.Add(costStageRevision);
            _efContext.SaveChanges();

            CostStageRevisionServiceMock.Setup(a => a.GetLatestRevisionWithPaymentCurrency(It.IsAny <Guid>())).ReturnsAsync(costStageRevision);

            // Act
            var result = await CostStageService.GetStagesLatestRevision(cost.Id, BuType.Pg);

            // Assert
            result.Should().HaveCount(1);
            result[0].Currency.Should().Be(currency);
            result[0].LatestRevision.Should().Be(costStageRevision);
        }
Пример #19
0
            private async Task <Cost> CreateCost_At_FA_Stage(Cost cost)
            {
                if (!cost.CostStages.Any(cs => cs.Name == nameof(CostStages.FinalActual)))
                {
                    cost.CostStages.Add(new CostStage {
                        Name = nameof(CostStages.FinalActual)
                    });
                }

                //Approved previous stages
                cost.CostStages.Where(cs => cs.Name == nameof(CostStages.OriginalEstimate)).ToList().ForEach(cs =>
                {
                    cs.CostStageRevisions.Last(csr => csr.Name == nameof(CostStages.OriginalEstimate)).Status = CostStageRevisionStatus.Approved;
                    if (cs.CostStageRevisions.Any(csr => csr.Name == nameof(CostStages.OriginalEstimateRevision)))
                    {
                        cs.CostStageRevisions.Last(csr => csr.Name == nameof(CostStages.OriginalEstimateRevision)).Status = CostStageRevisionStatus.Approved;
                    }
                });
                cost.CostStages.Where(cs => cs.Name == nameof(CostStages.FirstPresentation)).ToList().ForEach(cs =>
                {
                    cs.CostStageRevisions.Last(csr => csr.Name == nameof(CostStages.FirstPresentation)).Status = CostStageRevisionStatus.Approved;
                    if (cs.CostStageRevisions.Any(csr => csr.Name == nameof(CostStages.FirstPresentationRevision)))
                    {
                        cs.CostStageRevisions.Last(csr => csr.Name == nameof(CostStages.FirstPresentationRevision)).Status = CostStageRevisionStatus.Approved;
                    }
                });

                //Reject current stages
                cost.CostStages.Where(cs => cs.Name == nameof(CostStages.FinalActual)).ToList().ForEach(cs =>
                {
                    cs.CostStageRevisions.Where(csr => csr.Name == nameof(CostStages.FinalActual)).ToList().ForEach(csr =>
                    {
                        csr.Status = CostStageRevisionStatus.Rejected;
                    });
                });

                //Add new item for current stages
                var newCostStageRevisionId = Guid.NewGuid();
                var newCostStageRevision   = new CostStageRevision()
                {
                    Id     = newCostStageRevisionId,
                    Name   = nameof(CostStages.FinalActual),
                    Status = CostStageRevisionStatus.PendingTechnicalApproval
                };

                //update cost
                cost.CostStages.LastOrDefault().CostStageRevisions.Add(newCostStageRevision);
                cost.LatestCostStageRevision   = newCostStageRevision;
                cost.LatestCostStageRevisionId = newCostStageRevisionId;

                _eFContext.Cost.Update(cost);
                await _eFContext.SaveChangesAsync();

                return(cost);
            }
            public async Task ReturnPreviousRevisionOfFromPreviousStage()
            {
                // Arrange
                var costStageKey1 = CostStages.OriginalEstimate.ToString();
                var costStageKey2 = CostStages.FirstPresentation.ToString();
                var costId        = Guid.NewGuid();
                var createdById   = Guid.NewGuid();
                var revision1     = new CostStageRevision
                {
                    Id          = Guid.NewGuid(),
                    CreatedById = createdById,
                    Created     = DateTime.UtcNow,
                    Status      = CostStageRevisionStatus.Approved
                };
                var revision2 = new CostStageRevision
                {
                    Id          = Guid.NewGuid(),
                    CreatedById = createdById,
                    Created     = DateTime.UtcNow.AddMilliseconds(1)
                };
                var costStage1 = new CostStage
                {
                    Key  = costStageKey1,
                    Cost = new Cost
                    {
                        Id = costId
                    },
                    CostStageRevisions = new List <CostStageRevision> {
                        revision1
                    }
                };
                var costStage2 = new CostStage
                {
                    Key  = costStageKey2,
                    Cost = new Cost
                    {
                        Id = costId
                    },
                    CostStageRevisions = new List <CostStageRevision> {
                        revision2
                    }
                };

                EFContext.CostStage.Add(costStage1);
                EFContext.CostStage.Add(costStage2);
                await EFContext.SaveChangesAsync();

                // Act
                var previousRevision = await Service.GetPreviousRevision(revision2.Id);

                // Assert
                previousRevision.Id.Should().Be(revision1.Id);
            }
Пример #21
0
        private async Task<Dictionary<string, ActionModel>> GetCostActions(UserIdentity userIdentity,
            Cost cost, CostStageRevision costStageRevision, CostUser user)
        {
            var isCostNeverSubmitted = costStageRevision.Status == CostStageRevisionStatus.Draft && costStageRevision.Name == CostStageConstants.OriginalEstimate;

            var stageDetails = JsonConvert.DeserializeObject<PgStageDetailsForm>(costStageRevision.StageDetails?.Data);
            var costUser = new
            {
                isApprover = user.UserUserGroups.Any(uug => uug.UserGroup.ObjectId == cost.Id && uug.UserGroup.Role.Name == Roles.CostApprover),
                isAdmin = user.UserUserGroups.Any(x => x.UserGroup.Role.Name == Roles.ClientAdmin && x.UserGroup.ObjectId == userIdentity.ModuleId),
                authLimit = user.ApprovalLimit,
                isFinanceManager = user.UserBusinessRoles.Any(ubr => ubr.BusinessRole != null && ubr.BusinessRole.Key == Constants.BusinessRole.FinanceManager && (ubr.ObjectId != null || ubr.Labels.Contains(stageDetails.SmoName)))
            };

            var purchaseOrderResponse = _customObjectDataService
                .GetCustomData<PgPurchaseOrderResponse>(costStageRevision.CustomObjectData, CustomObjectDataKeys.PgPurchaseOrderResponse);

            // current user is IPM user and is approved
            var userIsIPMAndApproved = costStageRevision.Approvals
                .Any(s => s.ApprovalMembers.Any(a => a.MemberId == userIdentity.Id && !a.IsExternal && a.Status == ApprovalStatus.Approved));

            var isLatestRevision = cost.LatestCostStageRevisionId == costStageRevision.Id;

            var paymentBelowAuthLimit = true;
            decimal costTotal = 0;

            if (cost.Status != CostStageRevisionStatus.Draft && costUser.authLimit.HasValue)
            {
                costTotal = costStageRevision.CostLineItems.Sum(cli => cli.ValueInDefaultCurrency);
                paymentBelowAuthLimit = costUser.authLimit.Value >= costTotal;
            }

            var actionRule = new PgActionRule
            {
                CostStage = costStageRevision.CostStage.Key,
                Status = costStageRevision.Status.ToString(),
                IsRevision = RevisionStages.Contains(costStageRevision.CostStage.Key),
                IsOwner = cost.OwnerId.Equals(userIdentity.Id),
                IsApprover = costUser.isApprover,
                HasPONumber = !string.IsNullOrEmpty(purchaseOrderResponse?.PoNumber),
                NeverSubmitted = isCostNeverSubmitted,
                HasExternalIntegration = cost.IsExternalPurchases,
                CostStageTotal = costTotal,
                CostTotalBelowAuthLimit = paymentBelowAuthLimit,
                IsAdmin = costUser.isAdmin,
                UserIsIPMAndApproved = userIsIPMAndApproved,
                UserIsFinanceManager = costUser.isFinanceManager,
                IsLatestRevision = isLatestRevision
            };

            var actions = await GetActions(actionRule);
            return actions;
        }
Пример #22
0
        private async Task AddApproverNotification(List <EmailNotificationMessage <CostNotificationObject> > notifications,
                                                   Cost cost, CostUser costOwner, CostStageRevision costStageRevision, DateTime timestamp, string actionType, CostUser user)
        {
            var notificationMessage = new EmailNotificationMessage <CostNotificationObject>(actionType, user.GdamUserId);

            AddSharedTo(notificationMessage);
            MapEmailNotificationObject(notificationMessage.Object, cost, costOwner, user);
            await PopulateOtherFieldsForRecall(notificationMessage, Constants.EmailNotificationParents.Approver, timestamp, cost.Id, costStageRevision.Id);
            await PopulateMetadata(notificationMessage.Object, cost.Id);

            notifications.Add(notificationMessage);
        }
Пример #23
0
        public async Task <PaymentAmountResult> GetPaymentAmount(CostStageRevision costStageRevision, bool persist = true)
        {
            // first let's try and get the current calculation - no need to re-calculate if we've got everything
            var currentPaymentTotals = await _costStageRevisionService.GetCostStageRevisionPaymentTotals(costStageRevision);

            if (currentPaymentTotals.Count > 0)
            {
                return(TransformPaymentResult(currentPaymentTotals));
            }

            return(await CalculatePaymentAmount(costStageRevision.Id, persist));
        }
Пример #24
0
        /// <summary>
        /// Get total amount which is paid (shown in payment summary screen - only OE / FP / FA - not count their revisions) for this cost until this revision
        /// <para>Required: Cost has data of Cost Stages / Revisions / Payments </para>
        /// </summary>
        public static decimal GetAccumulatedAmount(this Cost cost, CostStageRevision currentRevision)
        {
            var     calculatedRevisions = GetAccumulatedRevisions(cost, currentRevision);
            decimal accumulatedAmount   = 0;

            foreach (var revision in calculatedRevisions)
            {
                accumulatedAmount += GetTotalCalculatedPayment(revision, cost.ExchangeRate ?? 1m).PaymentAmount;
            }

            return(accumulatedAmount);
        }
        public async Task GetCostFormDetails_should_return_deserializedFormDetailsModel()
        {
            // Arrange
            var testModel = new TestModel
            {
                Name = "Test model 1",
                ComplexProperties = new[]
                {
                    new TestModel.ComplexProperty {
                        Id = Guid.NewGuid(), PropertyName = "Property 1"
                    },
                    new TestModel.ComplexProperty {
                        Id = Guid.NewGuid(), PropertyName = "Property "
                    }
                }
            };

            var testModelData       = JsonConvert.SerializeObject(testModel);
            var costStageRevisionId = Guid.NewGuid();
            var costStageRevision   = new CostStageRevision
            {
                Id = costStageRevisionId,
                CostFormDetails = new List <CostFormDetails>
                {
                    new CostFormDetails
                    {
                        FormDefinition = new FormDefinition
                        {
                            Name = "testModel"
                        },
                        CustomFormData = new CustomFormData
                        {
                            Data = testModelData
                        }
                    }
                }
            };

            _efContextMock.MockAsyncQueryable(new List <CostStageRevision> {
                costStageRevision
            }.AsQueryable(), c => c.CostStageRevision);

            // Act
            var result = await _sut.GetCostFormDetails <TestModel>(costStageRevisionId);

            // Assert
            result.Name.Should().Be(testModel.Name);
            result.ComplexProperties.Should().HaveCount(testModel.ComplexProperties.Length);
            result.ComplexProperties[0].Id.Should().Be(testModel.ComplexProperties[0].Id);
            result.ComplexProperties[0].PropertyName.Should().Be(testModel.ComplexProperties[0].PropertyName);
            result.ComplexProperties[1].Id.Should().Be(testModel.ComplexProperties[1].Id);
            result.ComplexProperties[1].PropertyName.Should().Be(testModel.ComplexProperties[1].PropertyName);
        }
Пример #26
0
        public async Task Do_Not_Update_AgencyCurrency_From_BudgetForm_For_LockedPaymentCurrency()
        {
            //Arrange
            var          userId = _userId;
            var          costId = _costId;
            var          costStageRevisionId    = _costStageRevisionId;
            const string initialAgencyCurrency  = "GBP";
            const string expectedAgencyCurrency = "EUR";

            _stageDetails.AgencyCurrency = initialAgencyCurrency;
            var entries = new ExcelCellValueLookup
            {
                ["currency.agency"] = new ExcelCellValue
                {
                    Value = expectedAgencyCurrency
                }
            };
            var originalEstimateStage = new CostStage
            {
                Key = CostStages.OriginalEstimate.ToString()
            };

            var originalEstimateRevisionStage = new CostStage
            {
                Key = CostStages.OriginalEstimateRevision.ToString()
            };

            _costStageRevision.CostStage = originalEstimateRevisionStage;
            _costStageRevision.IsPaymentCurrencyLocked = true;

            var firstRevision = new CostStageRevision();

            firstRevision.CostStage = originalEstimateStage;
            firstRevision.IsPaymentCurrencyLocked            = false;
            originalEstimateRevisionStage.CostStageRevisions = new List <CostStageRevision>
            {
                firstRevision,
                _costStageRevision
            };

            //Act
            ServiceResult result = await _target.Update(entries, userId, costId, costStageRevisionId);

            //Assert
            result.Should().NotBeNull();
            result.Success.Should().BeFalse();
            result.Errors.Should().NotBeNull();
            result.Errors.Should().HaveCount(1);
            _stageFormData.Data.Should().NotContain(expectedAgencyCurrency);
        }
        public void GetRemovedApprovers_EmptyCostStageRevision()
        {
            //Arrange
            var x      = new CostStageRevision();
            var y      = new CostStageRevision();
            var target = new CostStageRevisionAnalyser();

            //Act
            var result = target.GetRemovedApprovers(x, y);

            //Assert
            result.Should().NotBeNull();
            result.Should().BeEmpty();
        }
        protected void SetPreviousRevision(CostStages costStage)
        {
            var previous = new CostStageRevision()
            {
                Id        = Guid.NewGuid(),
                Name      = costStage.ToString(),
                CostStage = new CostStage()
                {
                    Key = costStage.ToString()
                }
            };

            _costStageRevisionService.Setup(s => s.GetPreviousRevision(It.IsAny <Guid>())).ReturnsAsync(previous);
        }
Пример #29
0
        /// <summary>
        /// Get total amount which is paid for this cost until this revision
        /// <para>Required: Cost has data of Cost Stages / Revisions / Payments </para>
        /// </summary>
        public static List <XMGPaidStep> GetPaidSteps(this Cost cost, CostStageRevision currentRevision)
        {
            var result = new List <XMGPaidStep>();
            var calculatedRevisions = GetAccumulatedRevisions(cost, currentRevision);

            foreach (var revision in calculatedRevisions)
            {
                result.Add(new XMGPaidStep {
                    Name   = revision.Name,
                    Amount = GetTotalCalculatedPayment(revision, cost.ExchangeRate ?? 1m).PaymentAmount
                });
            }

            return(result);
        }
        protected void InitData(
            string budgetRegion   = Constants.BudgetRegion.AsiaPacific,
            string contentType    = Constants.ContentType.Photography,
            string productionType = Constants.ProductionType.FullProduction,
            CostType costType     = CostType.Production
            )
        {
            CreateTemplateIfNotCreated(User).Wait();

            var costTemplateId = costType == CostType.Production
                ? CostTemplate.Id
                : costType == CostType.Buyout
                    ? UsageCostTemplate.Id
                    : TrafficCostTemplate.Id;

            var costModel = new CreateCostModelBuilder()
                            .WithBudgetRegion(budgetRegion)
                            .WithContentType(contentType)
                            .WithProductionType(productionType)
                            .WithTemplateId(costTemplateId)
                            .Build();

            var createCostResponse = CreateCost(User, costModel).Result;

            _cost     = Deserialize <Cost>(createCostResponse.Body);
            _revision = EFContext.CostStageRevision.First(csr => csr.Id == _cost.LatestCostStageRevisionId.Value);
            var costStageRevisionId = _revision.Id;

            _contentType    = contentType;
            _productionType = productionType;
            _stageDetails   = new PgStageDetailsForm
            {
                ContentType = new DictionaryValue {
                    Key = _contentType
                },
                ProductionType = new DictionaryValue {
                    Key = _productionType
                },
                BudgetRegion = new AbstractTypeValue {
                    Key = budgetRegion
                }
            };
            _productionDetails = new PgProductionDetailsForm();

            _costStageRevisionServiceMock.Setup(csr => csr.GetRevisionById(costStageRevisionId)).ReturnsAsync(_revision);
            _costStageRevisionServiceMock.Setup(csr => csr.GetStageDetails <PgStageDetailsForm>(costStageRevisionId)).ReturnsAsync(_stageDetails);
            _costStageRevisionServiceMock.Setup(csr => csr.GetProductionDetails <PgProductionDetailsForm>(costStageRevisionId)).ReturnsAsync(_productionDetails);
        }