// A sell order was found so the deal is done instantly public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWallet, MarketOrder marketSellOrder, double pricePerPiece, int duration, int quantity, PublicContainer publicContainer, long?forMembersOf) { var forCorporation = forMembersOf != null; var seller = Character.GetByEid(marketSellOrder.submitterEID); Item itemOnMarket; if (!marketSellOrder.isVendorItem) { //the seller is NOT a vendor itemOnMarket = GetItemByMarketOrder(marketSellOrder); seller.ThrowIfEqual(null, ErrorCodes.CharacterNotFound); if (itemOnMarket.Quantity > quantity) { // unstack a fraction var fractionItem = itemOnMarket.Unstack(quantity); fractionItem.Owner = buyer.Eid; // save the remaining item itemOnMarket.Save(); // add to public container and change owner publicContainer.AddItem(fractionItem, true); //the remaining amount marketSellOrder.quantity = itemOnMarket.Quantity; // update remaining amount _orderRepository.UpdateQuantity(marketSellOrder); //cash in _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); } else if (itemOnMarket.Quantity == quantity) { itemOnMarket.Owner = buyer.Eid; // add to public container and change owner publicContainer.AddItem(itemOnMarket, true); //delete the sell order coz it's done _orderRepository.Delete(marketSellOrder); //cash in _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal the sell order delete to the client } else if (itemOnMarket.Quantity < quantity) { //a part of the buy order is fulfilled immediately itemOnMarket.Owner = buyer.Eid; // add to public container and change owner publicContainer.AddItem(itemOnMarket, true); _orderRepository.Delete(marketSellOrder); // create a buy order for the rest of the quantity var newBuyOrder = CreateBuyOrder(buyer, marketSellOrder.itemDefinition, duration, pricePerPiece, quantity - itemOnMarket.Quantity, marketSellOrder.useCorporationWallet, forMembersOf); // cash in for the actual transaction _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, itemOnMarket.Quantity, TransactionType.marketBuy); // cash in for the deposit - for the rest of the quantity _marketHelper.CashIn(buyer, useBuyerCorporationWallet, pricePerPiece, marketSellOrder.itemDefinition, quantity - itemOnMarket.Quantity, TransactionType.buyOrderDeposit); AddCentralBank(TransactionType.buyOrderDeposit, pricePerPiece * (quantity - itemOnMarket.Quantity)); //pay out for the current market item this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, itemOnMarket.Quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal to the client //the item he just bought, the sell order update //the new buy order Message.Builder.SetCommand(Commands.MarketBuyOrderCreated) .WithData(new Dictionary <string, object> { { k.buyOrder, newBuyOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); } Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, marketSellOrder.ToDictionary() } }) .ToCharacters(seller, buyer) .Send(); return; } //check VENDOR sell order's quantity if (marketSellOrder.quantity > 0) { //finite order cases var boughtQuantity = quantity; if (marketSellOrder.quantity == quantity) { _orderRepository.Delete(marketSellOrder); marketSellOrder.quantity = 0; //signal client } else if (marketSellOrder.quantity > quantity) { marketSellOrder.quantity -= quantity; //signal client _orderRepository.UpdateQuantity(marketSellOrder); } else if (marketSellOrder.quantity < quantity) { _orderRepository.Delete(marketSellOrder); boughtQuantity = marketSellOrder.quantity; //create buyorder for the rest of the quantity var buyOrder = CreateBuyOrder(buyer, marketSellOrder.itemDefinition, duration, pricePerPiece, quantity - marketSellOrder.quantity, marketSellOrder.useCorporationWallet, forMembersOf); Message.Builder.SetCommand(Commands.MarketBuyOrderCreated) .WithData(new Dictionary <string, object> { { k.item, buyOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); marketSellOrder.quantity = 0; //signal client //cash in deposit _marketHelper.CashIn(buyer, useBuyerCorporationWallet, pricePerPiece, marketSellOrder.itemDefinition, quantity - boughtQuantity, TransactionType.buyOrderDeposit); AddCentralBank(TransactionType.buyOrderDeposit, pricePerPiece * (quantity - boughtQuantity)); } //take the money for the quantity bought _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, boughtQuantity, TransactionType.marketBuy); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, marketSellOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); // vendor stuff itemOnMarket = publicContainer.CreateAndAddItem(marketSellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = boughtQuantity; }); Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, boughtQuantity * marketSellOrder.price, boughtQuantity); AddCentralBank(TransactionType.marketBuy, boughtQuantity * pricePerPiece); //vendor income return; } //infinite quantity case _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); itemOnMarket = publicContainer.CreateAndAddItem(marketSellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = quantity; }); Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, quantity * marketSellOrder.price, quantity); AddCentralBank(TransactionType.marketBuy, quantity * pricePerPiece); //vendor income }
public void HandleRequest(IRequest request) { using (var scope = Db.CreateTransaction()) { var buyer = request.Session.Character; var marketItemId = request.Data.GetOrDefault <int>(k.marketItemID); var useCorporationWallet = request.Data.GetOrDefault <int>(k.useCorporationWallet) == 1; var quantity = request.Data.GetOrDefault <int>(k.quantity); quantity.ThrowIfLessOrEqual(0, ErrorCodes.WTFErrorMedicalAttentionSuggested); buyer.IsDocked.ThrowIfFalse(ErrorCodes.CharacterHasToBeDocked); buyer.CheckPrivilegedTransactionsAndThrowIfFailed(); var market = buyer.GetCurrentDockingBase().GetMarketOrThrow(); var sellOrder = _marketOrderRepository.Get(marketItemId).ThrowIfNull(ErrorCodes.ItemNotFound); sellOrder.submitterEID.ThrowIfEqual(buyer.Eid, ErrorCodes.CannotBuyFromYourself); var corporationEid = buyer.CorporationEid; if (sellOrder.forMembersOf != null) { corporationEid.ThrowIfNotEqual((long)sellOrder.forMembersOf, ErrorCodes.AccessDenied); } var publicContainer = buyer.GetPublicContainerWithItems(); var sellerEid = sellOrder.submitterEID; var seller = Character.GetByEid(sellerEid); if (!sellOrder.isVendorItem) { //nem vendor, hanem player az aki eladja a cuccot var forCorporation = sellOrder.forMembersOf != null; var boughtQuantity = quantity; seller.ThrowIfEqual(null, ErrorCodes.CharacterNotFound); // the item as entity var itemOnMarket = market.GetItemByMarketOrder(sellOrder); var resultItem = itemOnMarket; if (sellOrder.quantity == quantity) { //delete the sell order coz it's done _marketOrderRepository.Delete(sellOrder); sellOrder.quantity = 0; } else if (sellOrder.quantity > quantity) { sellOrder.quantity = sellOrder.quantity - quantity; _marketOrderRepository.UpdateQuantity(sellOrder); resultItem = itemOnMarket.Unstack(quantity); itemOnMarket.Save(); } else if (sellOrder.quantity < quantity) { //bought quantity => marketitem.quantity boughtQuantity = sellOrder.quantity; //delete the sell order coz it's done _marketOrderRepository.Delete(sellOrder); sellOrder.quantity = 0; } resultItem.Owner = buyer.Eid; // add to public container publicContainer.AddItem(resultItem, false); publicContainer.Save(); //take money _marketHelper.CashIn(buyer, useCorporationWallet, sellOrder.price, sellOrder.itemDefinition, boughtQuantity, TransactionType.marketBuy); //pay out market.PayOutToSeller(seller, sellOrder.useCorporationWallet, resultItem.Definition, sellOrder.price, boughtQuantity, TransactionType.marketSell, sellOrder.IsAffectsAverage(), forCorporation); Market.SendMarketItemBoughtMessage(buyer, resultItem); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, sellOrder.ToDictionary() } }) .ToCharacters(seller, buyer) .Send(); } else { // the item is a vendor sell order if (sellOrder.quantity < 0) { //infinite quantity case _marketHelper.CashIn(buyer, useCorporationWallet, sellOrder.price, sellOrder.itemDefinition, quantity, TransactionType.marketBuy); var boughtItem = publicContainer.CreateAndAddItem(sellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = quantity; }); Market.SendMarketItemBoughtMessage(buyer, boughtItem); //average price _marketHandler.InsertAveragePrice(market, sellOrder.itemDefinition, quantity * sellOrder.price, quantity); market.AddCentralBank(TransactionType.marketBuy, quantity * sellOrder.price); //vendor income } else { // vendor finite var boughtQuantity = quantity; if (sellOrder.quantity == quantity) { sellOrder.quantity = 0; //signal order delete //all sold _marketOrderRepository.Delete(sellOrder); } else if (sellOrder.quantity < quantity) { boughtQuantity = sellOrder.quantity; //clip the amount sellOrder.quantity = 0; //signal order delete //all sold _marketOrderRepository.Delete(sellOrder); } else if (sellOrder.quantity > quantity) { sellOrder.quantity -= quantity; //update entry _marketOrderRepository.UpdateQuantity(sellOrder); } _marketHelper.CashIn(buyer, useCorporationWallet, sellOrder.price, sellOrder.itemDefinition, boughtQuantity, TransactionType.marketBuy); //average price _marketHandler.InsertAveragePrice(market, sellOrder.itemDefinition, boughtQuantity * sellOrder.price, boughtQuantity); market.AddCentralBank(TransactionType.marketBuy, boughtQuantity * sellOrder.price); //vendor income var boughtItem = publicContainer.CreateAndAddItem(sellOrder.itemDefinition, false, item => { item.Owner = buyer.Eid; item.Quantity = boughtQuantity; }); Market.SendMarketItemBoughtMessage(buyer, boughtItem); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary <string, object> { { k.sellOrder, sellOrder.ToDictionary() } }) .ToCharacter(buyer) .Send(); } } publicContainer.Save(); Message.Builder.SetCommand(Commands.ListContainer) .WithData(publicContainer.ToDictionary()) .ToCharacter(buyer) .Send(); scope.Complete(); } }