private decimal?GetByNameAndStage(string name, CostStages stage)
        {
            var split = Splits.FirstOrDefault(x => x.CostTotalName == name);

            if (split != null)
            {
                switch (stage)
                {
                case CostStages.Aipe:
                    return(split.AIPESplit);

                case CostStages.OriginalEstimate:
                    return(split.OESplit);

                case CostStages.FirstPresentation:
                    return(split.FPSplit);

                case CostStages.FinalActual:
                case CostStages.FinalActualRevision:
                    return(split.FASplit);

                default:
                    return(0);
                }
            }

            return(null);
        }
        public async Task GetPurchaseOrder_whenCostSubmittedAndNonProductionCostType_LongText_mapping()
        {
            // Arrange
            var costSubmitted          = GetCostRevisionStatusChanged(CostStageRevisionStatus.PendingBrandApproval);
            var costId                 = costSubmitted.AggregateId;
            const CostStages costStage = CostStages.FirstPresentation;
            const CostType   costType  = CostType.Buyout;

            const string expectedVNLine1 = "Purchase order does not authorize committing funds without approved EPCAT sheet.";
            const string expectedVNLine2 = "The services within this Purchase Order can only be ordered from 3rd parties after EPCAT approval.";
            var          expectedBN      = $"{costStage} APPROVED {costType}";
            var          expectedAN      = $"{FrontEndUrl.TrimEnd('/')}/#/cost/{costId}/review";

            SetupPurchaseOrderView(costId,
                                   costStage: costStage,
                                   costType: costType
                                   );

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

            // Assert
            purchase.LongText.Should().NotBeNull();
            purchase.LongText.VN.Should().Contain(expectedVNLine1);
            purchase.LongText.VN.Should().Contain(expectedVNLine2);
            purchase.LongText.BN.Should().Contain(expectedBN);
            purchase.LongText.AN.Should().Contain(expectedAN);
        }
        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);
        }
        public async Task GetPurchaseOrder_whenSubmittedAtFinalActualAndNotCreditNote_LongText_mapping(decimal creditAmount)
        {
            // Arrange
            var costSubmitted               = GetCostRevisionStatusChanged(CostStageRevisionStatus.PendingBrandApproval);
            var costId                      = costSubmitted.AggregateId;
            const CostStages costStage      = CostStages.FinalActual;
            const string     productionType = "Full Production";
            const string     poNumber       = "P&G PO_NUMBER";

            _paymentServiceMock.Setup(p => p.GetPaymentAmount(costSubmitted.CostStageRevisionId, false))
            .ReturnsAsync(new PaymentAmountResult
            {
                TotalCostAmountPayment = creditAmount
            });

            var expectedBN1 = $"{costStage} APPROVED Production {productionType} {poNumber}";

            SetupPurchaseOrderView(costId,
                                   new Dictionary <string, dynamic>
            {
                { "productionType", new { id = Guid.NewGuid(), key = productionType, value = productionType } },
                { "costType", CostType.Production.ToString() }
            },
                                   costStage: costStage
                                   );


            SetupCustomObjectData <PgPurchaseOrderResponse>(CustomObjectDataKeys.PgPurchaseOrderResponse, new Dictionary <string, dynamic> {
                { "poNumber", poNumber }
            });

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

            // Assert
            purchase.LongText.Should().NotBeNull();
            purchase.LongText.BN.Should().HaveCount(1);
            purchase.LongText.BN.Should().Contain(expectedBN1);
        }
        private dataAccess.Entity.Cost BuildCost(Guid costId, CostUser[] costUsers, dataAccess.Entity.Project project)
        {
            const string     agencyName    = "Saatchi";
            const string     brandName     = "P&G";
            const string     costNumber    = "P101";
            const CostStages costStageName = CostStages.OriginalEstimate;

            var cost = new dataAccess.Entity.Cost
            {
                Parent = new AbstractType()
            };

            var costOwner = costUsers[0];

            var latestRevision = new CostStageRevision();
            var costStage      = new CostStage();
            var brand          = new dataAccess.Entity.Brand();
            var agency         = new dataAccess.Entity.Agency();

            cost.CostNumber = costNumber;
            cost.LatestCostStageRevision = latestRevision;
            cost.Project             = project;
            cost.Parent.Agency       = agency;
            costOwner.Agency         = agency;
            costOwner.Id             = Guid.NewGuid();
            latestRevision.CostStage = costStage;

            agency.Name    = agencyName;
            brand.Name     = brandName;
            cost.Id        = costId;
            costStage.Name = costStageName.ToString();

            latestRevision.Id = Guid.NewGuid();

            return(cost);
        }
        private void SetupDataSharedAcrossTests()
        {
            const string     agencyLocation      = "United Kingdom";
            const string     agencyName          = "Saatchi";
            const string     brandName           = "P&G";
            const string     costNumber          = "P101";
            const CostStages costStageName       = CostStages.OriginalEstimate;
            const string     costOwnerGdamUserId = "57e5461ed9563f268ef4f19d";
            const string     costOwnerFullName   = "Mr Cost Owner";
            const string     projectName         = "Pampers";
            const string     projectGdamId       = "57e5461ed9563f268ef4f19c";
            const string     projectNumber       = "PandG01";

            var projectId = Guid.NewGuid();

            _cost = new Cost();
            var costOwner = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.FinanceManager,
                            Value = Constants.BusinessRole.FinanceManager
                        }
                    }
                }
            };
            var approverUser = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.Ipm,
                            Value = Constants.BusinessRole.Ipm
                        }
                    }
                }
            };
            var insuranceUser = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.InsuranceUser,
                            Value = Constants.BusinessRole.InsuranceUser
                        }
                    }
                }
            };

            var latestRevision = new CostStageRevision();
            var costStage      = new CostStage();
            var project        = new dataAccess.Entity.Project();
            var brand          = new Brand();
            var agency         = new dataAccess.Entity.Agency();
            var country        = new Country();

            agency.Country   = country;
            approverUser.Id  = _approverUserId;
            _cost.CostNumber = costNumber;
            _cost.LatestCostStageRevision = latestRevision;
            _cost.Project            = project;
            _cost.Owner              = costOwner;
            costOwner.Agency         = agency;
            costOwner.Id             = _costOwnerId;
            insuranceUser.Id         = _insuranceUserId;
            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;
            costOwner.Id          = _costOwnerId;
            latestRevision.Id     = _costStageRevisionId;
            project.Id            = projectId;
            project.Name          = projectName;
            project.GdamProjectId = projectGdamId;
            project.AdCostNumber  = projectNumber;
            country.Name          = agencyLocation;

            var agencies = new List <dataAccess.Entity.Agency> {
                agency
            };
            var brands = new List <Brand> {
                brand
            };
            var costs = new List <Cost> {
                _cost
            };
            var costStages = new List <CostStageRevision> {
                latestRevision
            };
            var costUsers = new List <CostUser> {
                approverUser, costOwner, insuranceUser
            };
            var countries = new List <Country> {
                country
            };
            var projects = new List <dataAccess.Entity.Project> {
                project
            };
            var insuranceUsers = new List <string> {
                _insuranceUserGdamId
            };

            _efContextMock.MockAsyncQueryable(agencies.AsQueryable(), c => c.Agency);
            _efContextMock.MockAsyncQueryable(brands.AsQueryable(), c => c.Brand);
            _efContextMock.MockAsyncQueryable(costs.AsQueryable(), c => c.Cost);
            _efContextMock.MockAsyncQueryable(costStages.AsQueryable(), c => c.CostStageRevision);
            _efContextMock.MockAsyncQueryable(costUsers.AsQueryable(), c => c.CostUser);
            _efContextMock.MockAsyncQueryable(countries.AsQueryable(), c => c.Country);
            _efContextMock.MockAsyncQueryable(projects.AsQueryable(), c => c.Project);

            _costUserServiceMock.Setup(cus => cus.GetInsuranceUsers(It.IsAny <dataAccess.Entity.Agency>())).Returns(Task.FromResult(insuranceUsers));
            _efContextMock.MockAsyncQueryable(new List <NotificationSubscriber>
            {
                new NotificationSubscriber
                {
                    CostId     = _cost.Id,
                    CostUserId = _costOwnerId,
                    CostUser   = costOwner
                }
            }.AsQueryable(), a => a.NotificationSubscriber);
        }
        protected Cost SetupPurchaseOrderView(
            Guid costId,
            IDictionary <string, dynamic> stageDetails          = null,
            IDictionary <string, dynamic> productionDetailsData = null,
            string brandName          = null,
            string costNumber         = null,
            string tNumber            = null,
            string requisitionerEmail = null,
            CostStages costStage      = CostStages.OriginalEstimate,
            string[] agencyLabels     = null,
            CostType costType         = CostType.Production,
            bool isExternalPurchase   = false
            )
        {
            var stage = new CostStage
            {
                Key  = costStage.ToString(),
                Name = costStage.ToString()
            };

            var costStageRevision = new CostStageRevision
            {
                Id           = Guid.NewGuid(),
                StageDetails = new CustomFormData
                {
                    Data = JsonConvert.SerializeObject(stageDetails ?? new Dictionary <string, dynamic>())
                },
                ProductDetails = new CustomFormData
                {
                    Data = JsonConvert.SerializeObject(productionDetailsData ?? new Dictionary <string, dynamic>())
                },
                CostStage = stage,
                Approvals = new List <Approval>
                {
                    new Approval
                    {
                        Type           = ApprovalType.Brand,
                        Requisitioners = new List <Requisitioner>
                        {
                            new Requisitioner
                            {
                                CostUser = new CostUser
                                {
                                    Email        = requisitionerEmail,
                                    FederationId = tNumber
                                }
                            }
                        },
                    }
                }
            };

            stage.CostStageRevisions = new List <CostStageRevision> {
                costStageRevision
            };

            var cost = new Cost
            {
                Id         = costId,
                CostNumber = costNumber,
                CostType   = costType,
                Project    = new Project
                {
                    Brand = new Brand {
                        Name = brandName
                    }
                },
                LatestCostStageRevision = costStageRevision,
                CostStages = new List <CostStage> {
                    stage
                },
                Parent = new AbstractType
                {
                    Agency = new Agency {
                        Labels = agencyLabels ?? new string[0]
                    }
                },
                IsExternalPurchases = isExternalPurchase
            };

            var costDbSetMock = _efContext.MockAsyncQueryable(new[] { cost }.AsQueryable(), d => d.Cost);

            costDbSetMock.Setup(c => c.FindAsync(costId)).ReturnsAsync(cost);

            _efContext.MockAsyncQueryable(new List <CostLineItem>().AsQueryable(), d => d.CostLineItem);

            return(cost);
        }
Example #8
0
        private static decimal GetSplit(IReadOnlyDictionary <string, decimal?> splits, CostStages costStage)
        {
            var percent = splits.ContainsKey(costStage.ToString()) ? splits[costStage.ToString()] : 0;

            if (percent < (decimal)0.0 || percent > (decimal)1.0)
            {
                throw new Exception("Payment split can't be outside 0 - 1 range.");
            }

            return(percent ?? 0);
        }
        public bool HasExplicitSplitForSectionAtStage(string sectionName, CostStages costStage)
        {
            var split = GetByNameAndStage(sectionName, costStage);

            return(split.HasValue);
        }
        public decimal?GetSplitByNameAndStage(string name, CostStages stage)
        {
            var split = GetByNameAndStage(name, stage);

            return(split);
        }
        protected IStageDetails BuildStageDetails(Guid revisionId, string contentType, decimal budget, string region,
                                                  CostType costType, string productionType = null, bool?isUsage = null, CostStages costStage = CostStages.OriginalEstimate)
        {
            _costStageRevisionService.Setup(x => x.GetCostLineItems(It.IsAny <Guid>()))
            .ReturnsAsync(new List <CostLineItemView>()
            {
                new CostLineItemView()
                {
                    ValueInDefaultCurrency = budget
                }
            });
            var t = new List <CostStageRevision>()
            {
                new CostStageRevision()
                {
                    Id        = revisionId,
                    CostStage = new CostStage()
                    {
                        Key = costStage.ToString()
                    }
                }
            };

            _efContext.MockAsyncQueryable(t.AsQueryable(), x => x.CostStageRevision);

            var result = new StageDetails()
            {
                Data = new Dictionary <string, dynamic>()
            };

            result.Data.Add("initialBudget", budget);
            result.Data.Add("budgetRegion", new AbstractTypeValue {
                Key = region
            });
            if (costType == CostType.Production)
            {
                result.Data.Add("contentType", JObject.Parse("{\"id\":\"b4a1bb22-90ab-4e37-82bd-494e512827da\",\"value\":\"" + contentType + "\",\"key\":\"" + contentType + "\"}"));
                result.Data.Add("productionType",
                                JObject.Parse("{\"id\":\"b4a1bb22-90ab-4e37-82bd-494e512827dd\",\"value\":\"" + productionType + "\",\"key\":\"" + productionType + "\"}"));
            }

            result.Data.Add("costType", costType);
            if (isUsage.HasValue)
            {
                result.Data.Add("isUsage", isUsage.Value);
                result.Data.Add("usageBuyoutType", new DictionaryValue {
                    Key = contentType
                });
            }
            return(result);
        }
        private void SetupDataSharedAcrossTests()
        {
            const string     agencyLocation      = "United Kingdom";
            const string     agencyName          = "Saatchi";
            const string     brandName           = "P&G";
            const string     costNumber          = "P101";
            const CostStages costStageName       = CostStages.OriginalEstimate;
            const string     costOwnerGdamUserId = "57e5461ed9563f268ef4f19d";
            const string     costOwnerFullName   = "Mr Cost Owner";
            const string     projectName         = "Pampers";
            const string     projectGdamId       = "57e5461ed9563f268ef4f19c";
            const string     projectNumber       = "PandG01";

            var projectId = Guid.NewGuid();

            _cost = new Cost();
            var costOwner = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.FinanceManager,
                            Value = Constants.BusinessRole.FinanceManager
                        }
                    }
                }
            };
            var approverUser = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.Ipm,
                            Value = Constants.BusinessRole.Ipm
                        }
                    }
                }
            };
            var insuranceUser = new CostUser
            {
                UserBusinessRoles = new List <UserBusinessRole>
                {
                    new UserBusinessRole
                    {
                        BusinessRole = new BusinessRole
                        {
                            Key   = Constants.BusinessRole.InsuranceUser,
                            Value = Constants.BusinessRole.InsuranceUser
                        }
                    }
                }
            };

            var latestRevision = new CostStageRevision();
            var costStage      = new CostStage();
            var project        = new Project();
            var brand          = new Brand();
            var agency         = new Agency();
            var country        = new Country();

            agency.Country                = country;
            approverUser.Id               = _approverUserId;
            _cost.CreatedBy               = costOwner;
            _cost.CreatedById             = _costOwnerId;
            _cost.Owner                   = costOwner;
            _cost.OwnerId                 = _costOwnerId;
            _cost.CostNumber              = costNumber;
            _cost.LatestCostStageRevision = latestRevision;
            _cost.Project                 = project;
            costOwner.Agency              = agency;
            costOwner.Id                  = _costOwnerId;
            insuranceUser.Id              = _insuranceUserId;
            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;
            costOwner.Id          = _costOwnerId;
            latestRevision.Id     = _costStageRevisionId;
            project.Id            = projectId;
            project.Name          = projectName;
            project.GdamProjectId = projectGdamId;
            project.AdCostNumber  = projectNumber;
            country.Name          = agencyLocation;

            var agencies = new List <Agency> {
                agency
            };
            var brands = new List <Brand> {
                brand
            };
            var costs = new List <Cost> {
                _cost
            };
            var costStages = new List <CostStageRevision> {
                latestRevision
            };
            var costUsers = new List <CostUser> {
                approverUser, costOwner, insuranceUser
            };
            var countries = new List <Country> {
                country
            };
            var projects = new List <Project> {
                project
            };

            _efContextMock.MockAsyncQueryable(agencies.AsQueryable(), c => c.Agency);
            _efContextMock.MockAsyncQueryable(brands.AsQueryable(), c => c.Brand);
            _efContextMock.MockAsyncQueryable(costs.AsQueryable(), c => c.Cost);
            _efContextMock.MockAsyncQueryable(costStages.AsQueryable(), c => c.CostStageRevision);
            _efContextMock.MockAsyncQueryable(costUsers.AsQueryable(), c => c.CostUser);
            _efContextMock.MockAsyncQueryable(countries.AsQueryable(), c => c.Country);
            _efContextMock.MockAsyncQueryable(projects.AsQueryable(), c => c.Project);

            _efContextMock.MockAsyncQueryable(new List <NotificationSubscriber>
            {
                new NotificationSubscriber
                {
                    CostId     = _cost.Id,
                    CostUserId = _costOwnerId,
                    CostUser   = costOwner
                }
            }.AsQueryable(), a => a.NotificationSubscriber);

            _stageDetails = new PgStageDetailsForm
            {
                Title        = "Test Title",
                BudgetRegion = new AbstractTypeValue
                {
                    Name = Constants.BudgetRegion.AsiaPacific
                },
                ContentType = new core.Builders.DictionaryValue
                {
                    Value = Constants.ContentType.Audio
                },
                ProductionType = new core.Builders.DictionaryValue
                {
                    Value = Constants.ProductionType.PostProductionOnly
                }
            };
            _costStageRevisionServiceMock.Setup(c => c.GetStageDetails <PgStageDetailsForm>(_cost.LatestCostStageRevision)).Returns(_stageDetails);
        }
        private static decimal?GetAllocatedSplitPayment(PgPaymentRule paymentInput, RuleType ruleType, PgPaymentRuleDefinition paymentRuleDefinition, string splitName, CostStages costStage)
        {
            var split = paymentRuleDefinition.GetSplitByNameAndStage(splitName, costStage);

            if (!split.HasValue)
            {
                return(null);
            }

            // change the allocation based on detailed splits
            var allocation = GetAllocation(paymentInput, ruleType, splitName);

            decimal payment = 0;

            if (DependentSections.ContainsKey(splitName))
            {
                foreach (var dependentSplit in DependentSections[splitName])
                {
                    if (paymentRuleDefinition.HasExplicitSplitForSectionAtStage(dependentSplit, costStage))
                    {
                        allocation -= GetAllocation(paymentInput, ruleType, dependentSplit);
                        payment    += GetAllocatedSplitPayment(paymentInput, ruleType, paymentRuleDefinition, dependentSplit, costStage) ?? 0;
                    }
                }
            }

            payment += (allocation ?? 0) * split.Value;

            return(payment);
        }
        private static decimal?GetAllocatedAmount(CostSectionTotals rawTotals, RuleType ruleType, PgPaymentRuleDefinition paymentRuleDefinition, string splitName, CostStages costStage)
        {
            if (!paymentRuleDefinition.HasExplicitSplitForSectionAtStage(splitName, costStage))
            {
                return(null);
            }

            // change the allocation based on detailed splits
            var allocation = GetAllocation(rawTotals, ruleType, splitName);

            if (DependentSections.ContainsKey(splitName))
            {
                foreach (var dependentSplit in DependentSections[splitName])
                {
                    if (paymentRuleDefinition.HasExplicitSplitForSectionAtStage(dependentSplit, costStage))
                    {
                        allocation -= GetAllocation(rawTotals, ruleType, dependentSplit);
                    }
                }
            }

            return(allocation);
        }
        public async Task CanEditIONumber_When_NotOEAIPEStagesAndStatusIsDraft_Should_ReturnFalse(CostStages costStage)
        {
            // Arrange
            var costStageObj = new CostStage {
                Key = costStage.ToString()
            };
            var cost = new Cost
            {
                Id         = Guid.NewGuid(),
                CostStages = new List <CostStage> {
                    costStageObj
                },
                LatestCostStageRevision = new CostStageRevision
                {
                    CostStage = costStageObj
                },
                Status = CostStageRevisionStatus.Draft
            };

            _efContext.Add(cost);
            _efContext.SaveChanges();

            // Act
            var canEditIONumber = await _pgRuleService.CanEditIONumber(cost.Id);

            // Assert
            canEditIONumber.Should().BeFalse();
        }