Exemplo n.º 1
0
        private void UpdateFinanceOperationStatus(FinanceOperation fo, PaymentData paymentData)
        {
            switch (paymentData.Status)
            {
            // Do nothing
            case PaymentStatus.New:
            case PaymentStatus.AwaitingForPayment:
            case PaymentStatus.Refunded:
            case PaymentStatus.Hold:
            case PaymentStatus.Undefined:
                break;

            // All ok
            case PaymentStatus.Paid:
                fo.State   = FinanceOperationState.Approved;
                fo.Changed = Now;
                break;

            // Something wrong
            case PaymentStatus.Expired:
            case PaymentStatus.Cancelled:
            case PaymentStatus.Error:     // TODO: Probably have to store last error within finance op?
            case PaymentStatus.Rejected:
                fo.State   = FinanceOperationState.Declined;
                fo.Changed = Now;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 2
0
        private async Task <FinanceOperation> LoadFinanceOperationAsync(int projectId, int claimId, int operationId)
        {
            // Loading finance operation
            FinanceOperation fo = await UnitOfWork.GetDbSet <FinanceOperation>().FindAsync(operationId);

            if (fo == null)
            {
                throw new JoinRpgEntityNotFoundException(operationId, nameof(FinanceOperation));
            }

            if (fo.ClaimId != claimId)
            {
                throw new JoinRpgEntityNotFoundException(claimId, nameof(Claim));
            }

            if (fo.ProjectId != projectId)
            {
                throw new JoinRpgEntityNotFoundException(projectId, nameof(Project));
            }

            if (fo.OperationType != FinanceOperationType.Online || fo.PaymentType?.TypeKind != PaymentTypeKind.Online)
            {
                throw new PaymentException(fo.Project, "Finance operation is not online payment");
            }

            return(fo);
        }
Exemplo n.º 3
0
 public static void RequestModerationAccess(this FinanceOperation finance, int currentUserId)
 {
     if (!finance.Claim.HasMasterAccess(currentUserId, acl => acl.CanManageMoney) &&
         finance.PaymentType?.UserId != currentUserId)
     {
         throw new NoAccessToProjectException(finance, currentUserId);
     }
 }
Exemplo n.º 4
0
        protected async Task <FinanceOperationEmail> AcceptFeeImpl(string contents, DateTime operationDate, int feeChange,
                                                                   int money, PaymentType paymentType, Claim claim)
        {
            paymentType.EnsureActive();

            CheckOperationDate(operationDate);

            if (feeChange != 0 || money < 0)
            {
                claim.RequestAccess(CurrentUserId, acl => acl.CanManageMoney);
            }
            var state = FinanceOperationState.Approved;

            if (paymentType.UserId != CurrentUserId)
            {
                if (claim.PlayerUserId == CurrentUserId)
                {
                    //Player mark that he pay fee. Put this to moderation
                    state = FinanceOperationState.Proposed;
                }
                else
                {
                    claim.RequestAccess(CurrentUserId, acl => acl.CanManageMoney);
                }
            }

            var comment = AddCommentImpl(claim, null, contents, isVisibleToPlayer: true);

            var financeOperation = new FinanceOperation()
            {
                Created       = Now,
                FeeChange     = feeChange,
                MoneyAmount   = money,
                Changed       = Now,
                Claim         = claim,
                Comment       = comment,
                PaymentType   = paymentType,
                State         = state,
                ProjectId     = claim.ProjectId,
                OperationDate = operationDate,
            };

            comment.Finance = financeOperation;

            claim.FinanceOperations.Add(financeOperation);

            claim.UpdateClaimFeeIfRequired(operationDate);

            var email = await CreateClaimEmail <FinanceOperationEmail>(claim, contents,
                                                                       s => s.MoneyOperation,
                                                                       commentExtraAction : null,
                                                                       extraRecipients : new[] { paymentType.User });

            email.FeeChange = feeChange;
            email.Money     = money;
            return(email);
        }
Exemplo n.º 5
0
 public OnlinePaymentUnexpectedStateException(
     FinanceOperation financeOperation,
     FinanceOperationState desiredState)
     : base(
         financeOperation.Project,
         $"Unexpected finance operation {financeOperation.CommentId} state. {desiredState} expected, but {financeOperation.State} found")
 {
     FinanceOperation = financeOperation;
     DesiredState     = desiredState;
 }
Exemplo n.º 6
0
 public FinOperationListItemViewModel(FinanceOperation fo, IUriService uriService)
 {
     PaymentTypeName    = fo.PaymentType?.GetDisplayName();
     PaymentMaster      = fo.PaymentType?.User;
     Claim              = fo.Claim.Name;
     FeeChange          = fo.FeeChange;
     Money              = fo.MoneyAmount;
     OperationDate      = fo.OperationDate;
     FinanceOperationId = fo.CommentId;
     MarkingMaster      = fo.Comment.Author;
     Player             = fo.Claim.Player;
     ClaimLink          = uriService.Get(fo.Claim);
 }
Exemplo n.º 7
0
 public FinOperationListItemViewModel(FinanceOperation fo, UrlHelper url)
 {
     PaymentTypeName    = fo.PaymentType?.GetDisplayName();
     PaymentMaster      = fo.PaymentType?.User;
     Claim              = fo.Claim.Name;
     FeeChange          = fo.FeeChange;
     Money              = fo.MoneyAmount;
     OperationDate      = fo.OperationDate;
     FinanceOperationId = fo.CommentId;
     MarkingMaster      = fo.Comment.Author;
     Player             = fo.Claim.Player;
     ClaimLink          = url.Action("Edit", "Claim", new { fo.ProjectId, fo.ClaimId },
                                     url.RequestContext.HttpContext.Request.Url?.Scheme ?? "http");
 }
Exemplo n.º 8
0
        public FinanceOperationViewModel(FinanceOperation source, bool isMaster)
        {
            Id              = source.CommentId;
            ClaimId         = source.ClaimId;
            ProjectId       = source.ProjectId;
            Money           = source.MoneyAmount;
            LinkedClaimId   = source.LinkedClaimId;
            LinkedClaimName = LinkedClaimId.HasValue ? source.LinkedClaim.Name : "";
            LinkedClaimUser = source.LinkedClaim?.Player;
            OperationType   = (FinanceOperationTypeViewModel)source.OperationType;
            OperationState  = (FinanceOperationStateViewModel)source.State;
            RowCssClass     = source.State.ToRowClass();
            Date            = source.OperationDate.ToShortDateString();
            ShowLinkedClaimLinkIfTransfer = isMaster;

            Title = OperationType.GetDescription() ?? "";
            if (string.IsNullOrWhiteSpace(Title))
            {
                Title = OperationType.GetDisplayName();
            }
            else
            {
                Title = string.Format(
                    Title,
                    OperationType.GetDisplayName(),
                    source.PaymentType?.GetDisplayName());
            }

            switch (OperationType)
            {
            case FinanceOperationTypeViewModel.Submit when source.Approved:
            case FinanceOperationTypeViewModel.Submit when source.State == FinanceOperationState.Proposed:
                Description = OperationState.GetDisplayName();
                break;

            case FinanceOperationTypeViewModel.Online when source.Approved:
                Description = OperationState.GetShortNameOrDefault() ?? "";
                break;

            case FinanceOperationTypeViewModel.Online when source.State == FinanceOperationState.Invalid:
                Description = OperationState.GetDisplayName();
                break;

            case FinanceOperationTypeViewModel.Online when source.State == FinanceOperationState.Proposed:
                CheckPaymentState = true;
                break;
            }
        }
Exemplo n.º 9
0
        public async Task RequestPreferentialFee(MarkMeAsPreferentialFeeOperationRequest request)
        {
            var claim = await LoadClaimAsMaster(request, ExtraAccessReason.Player);

            CheckOperationDate(request.OperationDate);

            var comment = AddCommentImpl(claim,
                                         null,
                                         request.Contents,
                                         isVisibleToPlayer: true,
                                         extraAction: CommentExtraAction.RequestPreferential);

            var financeOperation = new FinanceOperation()
            {
                Created              = Now,
                FeeChange            = 0,
                MoneyAmount          = 0,
                Changed              = Now,
                Claim                = claim,
                Comment              = comment,
                PaymentType          = null,
                State                = FinanceOperationState.Proposed,
                ProjectId            = claim.ProjectId,
                OperationDate        = request.OperationDate,
                MarkMeAsPreferential = true,
            };

            comment.Finance = financeOperation;

            claim.FinanceOperations.Add(financeOperation);

            claim.UpdateClaimFeeIfRequired(request.OperationDate);

            await UnitOfWork.SaveChangesAsync();

            var email = await CreateClaimEmail <FinanceOperationEmail>(claim,
                                                                       request.Contents,
                                                                       s => s.MoneyOperation,
                                                                       commentExtraAction : CommentExtraAction.RequestPreferential);


            await EmailService.Email(email);
        }
        public FinOperationListItemViewModel(FinanceOperation fo, IUriService uriService)
        {
            ProjectId          = fo.ProjectId;
            PaymentTypeName    = fo.PaymentType?.GetDisplayName();
            PaymentMaster      = fo.PaymentType?.User;
            Claim              = fo.Claim.Name;
            FeeChange          = fo.FeeChange;
            Money              = fo.MoneyAmount;
            OperationDate      = fo.OperationDate;
            FinanceOperationId = fo.CommentId;
            MarkingMaster      = fo.Comment.Author;
            Player             = fo.Claim.Player;
            ClaimLink          = uriService.Get(fo.Claim);

            ClaimId = fo.ClaimId;

            if (fo.OperationType == FinanceOperationType.TransferFrom ||
                fo.OperationType == FinanceOperationType.TransferTo)
            {
                PaymentTypeName =
                    ((FinanceOperationTypeViewModel)fo.OperationType).GetDisplayName();
            }
        }
Exemplo n.º 11
0
        protected async Task <FinanceOperationEmail> AcceptFeeImpl(string contents, DateTime operationDate, int feeChange,
                                                                   int money, PaymentType paymentType, Claim claim)
        {
            paymentType.EnsureActive();

            if (operationDate > Now.AddDays(1)
                ) //TODO[UTC]: if everyone properly uses UTC, we don't have to do +1
            {
                throw new CannotPerformOperationInFuture();
            }

            if (feeChange != 0 || money < 0)
            {
                claim.RequestMasterAccess(CurrentUserId, acl => acl.CanManageMoney);
            }
            var state = FinanceOperationState.Approved;

            if (paymentType.UserId != CurrentUserId)
            {
                if (claim.PlayerUserId == CurrentUserId)
                {
                    //Player mark that he pay fee. Put this to moderation
                    state = FinanceOperationState.Proposed;
                }
                else
                {
                    claim.RequestMasterAccess(CurrentUserId, acl => acl.CanManageMoney);
                }
            }

            var comment = AddCommentImpl(claim, null, contents, isVisibleToPlayer: true, extraAction: null);

            var financeOperation = new FinanceOperation()
            {
                Created       = Now,
                FeeChange     = feeChange,
                MoneyAmount   = money,
                Changed       = Now,
                Claim         = claim,
                Comment       = comment,
                PaymentType   = paymentType,
                State         = state,
                ProjectId     = claim.ProjectId,
                OperationDate = operationDate
            };

            comment.Finance = financeOperation;

            claim.FinanceOperations.Add(financeOperation);

            claim.UpdateClaimFeeIfRequired(operationDate);

            var email = EmailHelpers.CreateClaimEmail <FinanceOperationEmail>(claim, contents,
                                                                              s => s.MoneyOperation,
                                                                              commentExtraAction: null,
                                                                              initiator: await UserRepository.GetById(CurrentUserId),
                                                                              extraRecipients: new[] { paymentType.User });

            email.FeeChange = feeChange;
            email.Money     = money;
            return(email);
        }
Exemplo n.º 12
0
        public async Task FeeAcceptedOperation(int projectId, int claimId, int currentUserId, string contents, DateTime operationDate,
                                               int feeChange, int money, int paymentTypeId)
        {
            var claim = await ClaimsRepository.GetClaim(projectId, claimId);

            var now         = DateTime.UtcNow;
            var paymentType = claim.Project.PaymentTypes.Single(pt => pt.PaymentTypeId == paymentTypeId);

            paymentType.EnsureActive();

            if (operationDate > now.AddDays(1)) //TODO[UTC]: if everyone properly uses UTC, we don't have to do +1
            {
                throw new CannotPerformOperationInFuture();
            }

            if (feeChange != 0 || money < 0)
            {
                claim.RequestMasterAccess(currentUserId, acl => acl.CanManageMoney);
            }
            var state = FinanceOperationState.Approved;

            if (paymentType.UserId != currentUserId)
            {
                if (claim.PlayerUserId == currentUserId)
                {
                    //Player mark that he pay fee. Put this to moderation
                    state = FinanceOperationState.Proposed;
                }
                else
                {
                    claim.RequestMasterAccess(currentUserId, acl => acl.CanManageMoney);
                }
            }

            var comment = claim.AddCommentImpl(currentUserId, null, contents, now, isVisibleToPlayer: true, extraAction: null);

            var financeOperation = new FinanceOperation()
            {
                Created       = now,
                FeeChange     = feeChange,
                MoneyAmount   = money,
                Changed       = now,
                Claim         = claim,
                Comment       = comment,
                PaymentType   = paymentType,
                State         = state,
                ProjectId     = projectId,
                OperationDate = operationDate
            };

            comment.Finance = financeOperation;

            claim.FinanceOperations.Add(financeOperation);

            claim.UpdateClaimFeeIfRequired(operationDate);

            await UnitOfWork.SaveChangesAsync();

            var email = await CreateClaimEmail <FinanceOperationEmail>(claim, currentUserId, contents, s => s.MoneyOperation,
                                                                       isVisibleToPlayer : true, commentExtraAction : null, extraRecepients : new [] { paymentType.User });

            email.FeeChange = feeChange;
            email.Money     = money;

            await EmailService.Email(email);
        }