Beispiel #1
0
        public static OfferDto CreateNew(RioDbContext dbContext, int postingID, OfferUpsertDto offerUpsertDto)
        {
            if (!offerUpsertDto.TradeID.HasValue)
            {
                var trade = Trade.CreateNew(dbContext, postingID, offerUpsertDto.CreateAccountID);
                offerUpsertDto.TradeID = trade.TradeID;
            }

            var offer = new Offer
            {
                TradeID         = offerUpsertDto.TradeID.Value,
                OfferNotes      = offerUpsertDto.OfferNotes,
                CreateAccountID = offerUpsertDto.CreateAccountID,
                OfferDate       = DateTime.UtcNow,
                Price           = offerUpsertDto.Price,
                Quantity        = offerUpsertDto.Quantity,
                OfferStatusID   = offerUpsertDto.OfferStatusID
            };

            dbContext.Offer.Add(offer);
            dbContext.SaveChanges();
            dbContext.Entry(offer).Reload();

            return(GetByOfferID(dbContext, offer.OfferID));
        }
Beispiel #2
0
        public IActionResult New([FromRoute] int postingID, [FromBody] OfferUpsertDto offerUpsertDto)
        {
            if (!_rioConfiguration.ALLOW_TRADING)
            {
                return(BadRequest());
            }

            var posting = Posting.GetByPostingID(_dbContext, postingID);

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            if ((posting.PostingType.PostingTypeID == (int)PostingTypeEnum.OfferToSell) && (offerUpsertDto.OfferStatusID == (int)OfferStatusEnum.Pending || offerUpsertDto.OfferStatusID == (int)OfferStatusEnum.Accepted) && posting.AvailableQuantity < offerUpsertDto.Quantity)
            {
                ModelState.AddModelError("Quantity", "Exceeds remaining balance in posting");
                return(BadRequest(ModelState));
            }

            if (offerUpsertDto.OfferStatusID != (int)OfferStatusEnum.Rescinded && Posting.HasOpenOfferByAccountID(_dbContext, posting, offerUpsertDto.CreateAccountID))
            {
                ModelState.AddModelError("Posting", "You currently have an open offer on this posting. Please wait until the other party responds to the current offer.");
                return(BadRequest(ModelState));
            }

            var offer        = Offer.CreateNew(_dbContext, postingID, offerUpsertDto);
            var smtpClient   = HttpContext.RequestServices.GetRequiredService <SitkaSmtpClientService>();
            var currentTrade = Trade.GetByTradeID(_dbContext, offer.Trade.TradeID);
            var rioUrl       = _rioConfiguration.WEB_URL;

            // update trades status if needed
            switch (offerUpsertDto.OfferStatusID)
            {
            case (int)OfferStatusEnum.Accepted:
                var tradeDto = Trade.Update(_dbContext, offer.Trade.TradeID, TradeStatusEnum.Accepted);
                // write a water transfer record
                var waterTransfer = WaterTransfer.CreateNew(_dbContext, offer, tradeDto, posting);
                offer.WaterTransferID = waterTransfer.WaterTransferID;
                var mailMessages = GenerateAcceptedOfferEmail(rioUrl, offer, currentTrade, posting, waterTransfer, smtpClient);
                foreach (var mailMessage in mailMessages)
                {
                    SendEmailMessage(smtpClient, mailMessage);
                }
                break;

            case (int)OfferStatusEnum.Rejected:
                UpdateTradeStatusSendEmail(offer, smtpClient, GenerateRejectedOfferEmail(rioUrl, offer, currentTrade, posting, smtpClient), TradeStatusEnum.Rejected);
                break;

            case (int)OfferStatusEnum.Rescinded:
                UpdateTradeStatusSendEmail(offer, smtpClient, GenerateRescindedOfferEmail(rioUrl, offer, currentTrade, posting, smtpClient), TradeStatusEnum.Rescinded);
                break;

            default:
                SendEmailMessage(smtpClient, GeneratePendingOfferEmail(rioUrl, currentTrade, offer, posting, smtpClient));
                break;
            }

            // get current balance of posting
            var acreFeetOfAcceptedTrades = Posting.CalculateAcreFeetOfAcceptedTrades(_dbContext, postingID);
            var postingStatusToUpdateTo  = (int)PostingStatusEnum.Open;

            if (posting.Quantity == acreFeetOfAcceptedTrades)
            {
                postingStatusToUpdateTo = (int)PostingStatusEnum.Closed;
                // expire all other outstanding offers
                var postingCreateAccountID = posting.CreateAccount.AccountID;
                var activeTradesForPosting = Trade.GetPendingTradesForPostingID(_dbContext, postingID).ToList();
                foreach (var activeTrade in activeTradesForPosting)
                {
                    var offerStatus = activeTrade.OfferCreateAccount.AccountID == postingCreateAccountID
                        ? OfferStatusEnum.Rescinded
                        : OfferStatusEnum.Rejected;
                    var offerUpsertDtoForRescindReject = new OfferUpsertDto
                    {
                        TradeID         = activeTrade.TradeID,
                        Price           = activeTrade.Price,
                        CreateAccountID = postingCreateAccountID,
                        Quantity        = activeTrade.Quantity,
                        OfferStatusID   = (int)offerStatus,
                        OfferNotes      = $"Offer {offerStatus} because original posting is now closed"
                    };
                    var resultingOffer = Offer.CreateNew(_dbContext, postingID, offerUpsertDtoForRescindReject);
                    switch (offerStatus)
                    {
                    case OfferStatusEnum.Rejected:
                        UpdateTradeStatusSendEmail(resultingOffer, smtpClient, GenerateRejectedOfferEmail(rioUrl, resultingOffer, Trade.GetByTradeID(_dbContext, activeTrade.TradeID), posting, smtpClient), TradeStatusEnum.Rejected);
                        break;

                    case OfferStatusEnum.Rescinded:
                        UpdateTradeStatusSendEmail(resultingOffer, smtpClient, GenerateRescindedOfferEmail(rioUrl, resultingOffer, Trade.GetByTradeID(_dbContext, activeTrade.TradeID), posting, smtpClient), TradeStatusEnum.Rescinded);
                        break;
                    }
                }
            }
            Posting.UpdateStatus(_dbContext, postingID,
                                 new PostingUpdateStatusDto {
                PostingStatusID = postingStatusToUpdateTo
            }, posting.Quantity - acreFeetOfAcceptedTrades);

            return(Ok(offer));
        }