Ejemplo n.º 1
0
        public static ViewModels.Bond ToViewBond(this Models.DBUserBond dbUserBond)
        {
            var bond = dbUserBond.Bond.ToViewBond();

            bond.Count = dbUserBond.Count;
            return(bond);
        }
Ejemplo n.º 2
0
        public async Task <ActionResult <ViewModels.Bond> > Buy(ViewModels.UserBondBuyRequest userBond)
        {
            var accessAllowed = _roleChecker.CheckAccessList(User, userBond.UserId, _defaultAccessList, "Buy bond");

            if (!accessAllowed)
            {
                return(StatusCode(StatusCodes.Status403Forbidden, new
                {
                    error = "Access denied"
                }));
            }

            var bond = await _context.Bonds
                       .FirstOrDefaultAsync(bond => bond.Id == userBond.BondId);

            if (bond is null)
            {
                _logger.LogInformation(Helpers.LogEvents.GetItem,
                                       $"BondId {userBond.BondId} not fount");
                return(NotFound(
                           new
                {
                    error = "BondId not found",
                    userBond
                }));
            }

            if (bond.CurrentPurchasePrice is null)
            {
                _logger.LogInformation(Helpers.LogEvents.GetItem,
                                       $"BondId {userBond.BondId} not fount");
                return(StatusCode(StatusCodes.Status410Gone,
                                  new
                {
                    error = "Bond is not for sale",
                    userBond
                }));
            }

            for (int i = 1; i < 6; ++i)
            {
                using var transaction = _context.Database.BeginTransaction();
                try
                {
                    var dbUser = await _context.Users
                                 .Where(user => user.Id == userBond.UserId)
                                 .Include(user => user.Bonds
                                          .Where(bond => bond.BondId == userBond.BondId))
                                 .FirstOrDefaultAsync();

                    if (dbUser is null)
                    {
                        _logger.LogInformation(Helpers.LogEvents.GetItem,
                                               $"UserId {userBond.UserId} not fount");
                        return(NotFound(
                                   new
                        {
                            error = "UserId not found",
                            userBond
                        }));
                    }

                    var requiredMoney = bond.CurrentPurchasePrice * userBond.Count;
                    if (dbUser.Money < requiredMoney)
                    {
                        return(StatusCode(StatusCodes.Status403Forbidden, new
                        {
                            error = "Payment required",
                            correntMoney = dbUser.Money,
                            requiredMoney = userBond.Count * bond.CurrentPurchasePrice
                        }));
                    }

                    dbUser.Money -= (long)requiredMoney;

                    Models.DBUserBond result = null;

                    if (dbUser.Bonds.Count == 0)
                    {
                        result = new Models.DBUserBond
                        {
                            UserId = userBond.UserId,
                            Count  = userBond.Count,
                            Bond   = bond
                        };
                        _context.UserBonds.Add(result);
                    }
                    else
                    {
                        result        = dbUser.Bonds.First();
                        result.Count += userBond.Count;
                    }

                    await _context.SaveChangesAsync();

                    await transaction.CommitAsync();

                    return(Ok(result.ToViewBond()));
                }
                catch (Exception ex)
                {
                    await transaction.RollbackAsync();

                    _logger.LogWarning(Helpers.LogEvents.UpdateItem,
                                       $"Rollback {i} transaction buy bond {userBond}, error: {ex}");
                }
            }
            _logger.LogError(Helpers.LogEvents.UpdateItem,
                             $"Rollback 5 transaction buy bond {userBond}");

            return(Conflict(new
            {
                error = "Rollback 5 transaction buy bond",
                userBond
            }));
        }