private ProposalResult Update(FixedPriceProposal proposal, bool commit = true, bool fireEvents = true)
        {
            _logger.LogInformation(GetLogMessage("Proposal:{0}"), proposal.Id);

            _logger.LogInformation(GetLogMessage("Proposal story Point basis : {0}"), proposal.StoryPointBasis);

            _logger.LogInformation(GetLogMessage("Proposal estimation basis : {0}"), proposal.EstimationBasis);

            _logger.LogInformation(GetLogMessage("Proposal customer rate basis : {0}"), proposal.CustomerRateBasis);

            _logger.LogInformation(GetLogMessage("Proposal other percent basis : {0}"), proposal.OtherPercentBasis);

            _logger.LogInformation(GetLogMessage("Proposal total hours : {0}"), proposal.TotalHours);

            _logger.LogInformation(GetLogMessage("Proposal total price quoted : {0}"), proposal.TotalPriceQuoted);

            var retVal = new ProposalResult()
            {
                ProposalId = proposal.Id
            };

            proposal.UpdatedById = _userInfo.UserId;
            proposal.Updated     = DateTimeOffset.UtcNow;
            proposal.ObjectState = ObjectState.Modified;

            var records = Repository.InsertOrUpdateGraph(proposal, commit);

            _logger.LogDebug(GetLogMessage("{0} records updated"), records);
            if (records > 0)
            {
                retVal.Succeeded = true;
            }

            return(retVal);
        }
        private async Task <ProposalResult> RevokeProposal(FixedPriceProposal proposal)
        {
            _logger.LogInformation(GetLogMessage("Proposal: {0}"), proposal.Id);

            var retVal = new ProposalResult()
            {
                ProposalId = proposal.Id
            };

            proposal.UpdatedById = _userInfo.UserId;
            proposal.Updated     = DateTimeOffset.UtcNow;
            proposal.ObjectState = ObjectState.Modified;


            proposal.Status = ProposalStatus.Draft;
            proposal.StatusTransitions.Add(new ProposalStatusTransition()
            {
                Status      = ProposalStatus.Draft,
                ObjectState = ObjectState.Added
            });

            var result = Repository.Update(proposal, true);

            _logger.LogDebug(GetLogMessage("Records updated: {0}"), result);
            if (result > 0)
            {
                retVal.Succeeded = true;
            }

            return(retVal);
        }
Пример #3
0
        private async Task <ProposalResult> SendProposal(FixedPriceProposal proposal)
        {
            _logger.LogInformation(GetLogMessage("Sending Proposal: {0}"), proposal.Id);

            var retVal = new ProposalResult
            {
                ProposalId = proposal.Id
            };

            if (proposal == null)
            {
                retVal.ErrorMessage = "Proposal does not exist";
                return(retVal);
            }

            if (proposal.Status != ProposalStatus.Pending)
            {
                _logger.LogDebug(GetLogMessage("Proposal ready to be sent"));

                proposal.Status = ProposalStatus.Pending;
                proposal.StatusTransitions.Add(new ProposalStatusTransition()
                {
                    Status      = ProposalStatus.Pending,
                    ObjectState = ObjectState.Added
                });

                proposal.UpdatedById = _userInfo.UserId;
                proposal.Updated     = DateTimeOffset.UtcNow;
                proposal.ObjectState = ObjectState.Modified;

                var records = Repository.Update(proposal, true);

                _logger.LogDebug("{0} records updated in database");

                if (records > 0)
                {
                    retVal.Succeeded = true;
                    await Task.Run(() =>
                    {
                        RaiseEvent(new ProposalSentEvent()
                        {
                            ProposalId = proposal.Id
                        });
                    });
                }
            }

            return(retVal);
        }
Пример #4
0
        private async Task <bool> DeleteProposal(FixedPriceProposal proposal)
        {
            bool retVal = false;

            if (proposal?.ProposalAcceptance != null)
            {
                throw new ApplicationException("You cannot delete a proposal that's been accepted");
            }

            if (proposal != null)
            {
                retVal = await Repository.DeleteAsync(proposal, true);
            }

            return(retVal);
        }
        private async Task <ProposalResult> RejectProposal(FixedPriceProposal proposal, ProposalRejectionInput input)
        {
            if (proposal == null)
            {
                throw new ApplicationException("No proposal found with this id for this organization");
            }

            var retVal = new ProposalResult()
            {
                ProposalId = proposal.Id
            };

            proposal.Status      = ProposalStatus.Rejected;
            proposal.UpdatedById = _userInfo.UserId;
            proposal.Updated     = DateTimeOffset.UtcNow;

            proposal.StatusTransitions.Add(new ProposalStatusTransition()
            {
                Status      = ProposalStatus.Rejected,
                ObjectState = ObjectState.Added
            });

            proposal.InjectFrom(input);

            var result = Update(proposal);

            if (result.Succeeded)
            {
                retVal.Succeeded = true;
                await Task.Run(() =>
                {
                    RaiseEvent(new ProposalRejectedEvent
                    {
                        ProposalId = result.ProposalId
                    });
                });
            }

            return(retVal);
        }
        private async Task <ProposalResult> AcceptFixedPriceProposal(FixedPriceProposal proposal)
        {
            var retVal = new ProposalResult()
            {
                ProposalId = proposal.Id
            };

            if (proposal.Status == ProposalStatus.Accepted && proposal.ProposalAcceptance != null)
            {
                retVal.ErrorMessage = "Proposal is already accepted";
                return(retVal);
            }

            var now = DateTimeOffset.UtcNow;


            proposal.Status      = ProposalStatus.Accepted;
            proposal.UpdatedById = _userInfo.UserId;
            proposal.Updated     = now;
            proposal.ObjectState = ObjectState.Modified;

            proposal.Project.Status      = ProjectStatus.Active;
            proposal.Project.ObjectState = ObjectState.Modified;
            proposal.Project.Updated     = now;
            proposal.Project.UpdatedById = _userInfo.UserId;


            proposal.StatusTransitions.Add(new ProposalStatusTransition()
            {
                Status      = ProposalStatus.Accepted,
                ObjectState = ObjectState.Added
            });

            foreach (var contract in proposal.Project.Contracts.Where(x => x.Status == ContractStatus.Pending))
            {
                contract.Status      = ContractStatus.Active;
                contract.ObjectState = ObjectState.Modified;
                contract.UpdatedById = _userInfo.UserId;
                contract.Updated     = now;
                contract.StatusTransitions.Add(new ContractStatusTransition()
                {
                    ObjectState = ObjectState.Added,
                    Status      = ContractStatus.Active
                });
            }

            proposal.ProposalAcceptance = new ProposalAcceptance()
            {
                Created = now,
                AcceptedCompletionDate = DateTimeOffset.UtcNow.Date
                                         .AddDays(Convert.ToDouble(proposal.TotalDays))
                                         .Date,
                TotalCost              = proposal.TotalPriceQuoted,
                CustomerRate           = proposal.CustomerRateBasis,
                NetTerms               = 7, // todo: fix this
                ProposalType           = proposal.ProposalType,
                TotalDays              = proposal.TotalDays,
                Velocity               = proposal.VelocityBasis,
                AgreementText          = proposal.AgreementText,
                Updated                = now,
                CustomerId             = proposal.Project.CustomerId,
                CustomerOrganizationId = proposal.Project.CustomerOrganizationId,
                AcceptedBy             = _userInfo.UserId,
                ProposalBlob           = string.Empty,
                ObjectState            = ObjectState.Added
            };


            foreach (var story in proposal.Project.Stories.Where(x => x.Status == StoryStatus.Pending))
            {
                story.CustomerAcceptanceDate = now;
                story.Updated               = now;
                story.ObjectState           = ObjectState.Modified;
                story.Status                = StoryStatus.Approved;
                story.CustomerApprovedHours = story.StoryPoints * proposal.EstimationBasis;

                story.StatusTransitions.Add(new StoryStatusTransition()
                {
                    Status      = StoryStatus.Approved,
                    ObjectState = ObjectState.Added
                });

                _logger.LogDebug(GetLogMessage("Setting approved story hours for story: {0}, amount: {1}"),
                                 story.Id, story.CustomerApprovedHours);
            }

            var proposalResult = Repository.InsertOrUpdateGraph(proposal, true);

            _logger.LogDebug(GetLogMessage("{0} records updated"), proposalResult);

            if (proposalResult > 0)
            {
                retVal.Succeeded = true;
                await Task.Run(() =>
                {
                    RaiseEvent(new ProposalAcceptedEvent()
                    {
                        ProposalId = proposal.Id
                    });
                });

                foreach (var contract in proposal.Project.Contracts.Where(x => x.Updated == now))
                {
                    await Task.Run(() =>
                    {
                        RaiseEvent(new ContractApprovedEvent()
                        {
                            ContractId = contract.Id
                        });
                    });
                }

                foreach (var story in proposal.Project.Stories.Where(x => x.Updated == now))
                {
                    await Task.Run(() =>
                    {
                        RaiseEvent(new StoryApprovedEvent()
                        {
                            StoryId = story.Id
                        });
                    });
                }
            }

            return(retVal);
        }
Пример #7
0
        private async Task <ProposalResult> Create(ProposalOptions input, Guid projectId, Guid organizationId)
        {
            _logger.LogInformation(GetLogMessage($@"Create Proposal Proposal For Project ID: {projectId}"));

            var retVal = new ProposalResult();

            var project = _projectRepository.Queryable()
                          .Include(x => x.Proposal)
                          .Include(x => x.Stories)
                          .Include(x => x.Contracts)
                          .FirstAsync(x => x.Id == projectId);

            var org = _organizationRepository.Queryable()
                      .Include(x => x.ProviderOrganization)
                      .FirstOrDefaultAsync(x => x.Id == organizationId);

            await Task.WhenAll(project, org);


            if (project.Result.Proposal != null)
            {
                throw new ApplicationException("Proposal already exists");
            }

            if (project.Result.Stories.Count == 0)
            {
                throw new ApplicationException("Project must have at least one story with one story point");
            }

            if (project.Result.Contracts.Count == 0)
            {
                throw new ApplicationException("Project must have at least one contract");
            }

            var proposal = new FixedPriceProposal()
            {
                Id              = projectId,
                ObjectState     = ObjectState.Added,
                Status          = ProposalStatus.Draft,
                ProposalType    = ProposalType.Fixed,
                UpdatedById     = _userInfo.UserId,
                CreatedById     = _userInfo.UserId,
                StoryPointBasis = input.StoryPointBasis.GetValueOrDefault(
                    project
                    .Result.Stories.Sum(x => x.StoryPoints.GetValueOrDefault())),
                AgreementText     = input.AgreementText,
                OtherPercentBasis = input.OtherPercentBasis,
                BudgetBasis       = input.BudgetBasis,
                CustomerRateBasis = input.CustomerRateBasis.GetValueOrDefault(),
                EstimationBasis   = input.EstimationBasis
                                    .GetValueOrDefault(org.Result.ProviderOrganization.EstimationBasis),
                WeeklyMaxHourBasis = input.WeeklyMaxHourBasis
                                     .GetValueOrDefault(project
                                                        .Result.Contracts.Sum(x => x.MaxWeeklyHours)),
            };

            proposal.StatusTransitions.Add(new ProposalStatusTransition()
            {
                Status      = ProposalStatus.Draft,
                ObjectState = ObjectState.Added
            });

            proposal.InjectFrom(input);

            _logger.LogInformation(GetLogMessage("Proposal story Point basis : {0}"), proposal.StoryPointBasis);

            _logger.LogInformation(GetLogMessage("Proposal estimation basis : {0}"), proposal.EstimationBasis);

            _logger.LogInformation(GetLogMessage("Proposal customer rate basis : {0}"), proposal.CustomerRateBasis);

            _logger.LogInformation(GetLogMessage("Proposal other percent basis : {0}"), proposal.OtherPercentBasis);

            _logger.LogInformation(GetLogMessage("Proposal total hours : {0}"), proposal.TotalHours);

            _logger.LogInformation(GetLogMessage("Proposal total price quoted : {0}"), proposal.TotalPriceQuoted);

            var records = await Repository.InsertAsync(proposal, true);

            _logger.LogDebug(GetLogMessage("{0} records updated"), records);

            if (records > 0)
            {
                retVal.Succeeded  = true;
                retVal.ProposalId = projectId;

                await Task.Run(() =>
                {
                    RaiseEvent(new ProposalCreatedEvent
                    {
                        ProposalId = projectId
                    });
                });
            }

            return(retVal);
        }