Add functionality for sale end dates

This commit is contained in:
Joseph Ferano 2022-06-17 10:49:22 +07:00
parent e47c6b2f40
commit 0491d232be
4 changed files with 36 additions and 10 deletions

View File

@ -105,7 +105,7 @@ let getStoreItems (storeId : string) =
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "sid", Sql.string storeId ] |> Sql.parameters [ "sid", Sql.string storeId ]
|> Sql.query """ |> Sql.query """
SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end,
buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods
FROM store_item FROM store_item
JOIN item i on store_item.item_id = i.id JOIN item i on store_item.item_id = i.id
@ -116,6 +116,7 @@ let getStoreItems (storeId : string) =
Stock = reader.int "stock" Stock = reader.int "stock"
LimitStock = reader.bool "limit_stock" LimitStock = reader.bool "limit_stock"
Available = reader.bool "available" Available = reader.bool "available"
SaleEnd = reader.int64OrNone "sale_end"
TotalSold = None TotalSold = None
RequiresInvites = reader.intOrNone "require_invites" RequiresInvites = reader.intOrNone "require_invites"
RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64
@ -127,7 +128,7 @@ let getAllActiveStoreItems () =
connStr connStr
|> Sql.connect |> Sql.connect
|> Sql.query """ |> Sql.query """
SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end,
buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods
FROM store_item FROM store_item
JOIN item i on store_item.item_id = i.id JOIN item i on store_item.item_id = i.id
@ -138,6 +139,7 @@ let getAllActiveStoreItems () =
Stock = reader.int "stock" Stock = reader.int "stock"
LimitStock = reader.bool "limit_stock" LimitStock = reader.bool "limit_stock"
Available = reader.bool "available" Available = reader.bool "available"
SaleEnd = reader.int64OrNone "sale_end"
TotalSold = None TotalSold = None
RequiresInvites = reader.intOrNone "require_invites" RequiresInvites = reader.intOrNone "require_invites"
RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64
@ -151,7 +153,7 @@ let getRafflesWithPurchases storeId =
|> Sql.parameters [ "sid" , Sql.string storeId ] |> Sql.parameters [ "sid" , Sql.string storeId ]
|> Sql.query """ |> Sql.query """
WITH raffles AS WITH raffles AS
(SELECT store_id,stock,available,limit_stock,i.id AS raffle_id,name,description,icon_url,image_url,category,require_role,require_invites, (SELECT store_id,stock,available,limit_stock,i.id AS raffle_id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end,
buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods
FROM store_item FROM store_item
JOIN item i on store_item.item_id = i.id JOIN item i on store_item.item_id = i.id
@ -166,6 +168,7 @@ FULL JOIN (SELECT item_id, count(*) AS total FROM inventory_item
Stock = reader.int "stock" Stock = reader.int "stock"
LimitStock = reader.bool "limit_stock" LimitStock = reader.bool "limit_stock"
Available = reader.bool "available" Available = reader.bool "available"
SaleEnd = reader.int64OrNone "sale_end"
TotalSold = reader.intOrNone "total" TotalSold = reader.intOrNone "total"
RequiresInvites = reader.intOrNone "require_invites" RequiresInvites = reader.intOrNone "require_invites"
RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64
@ -178,7 +181,7 @@ let getStoreItemBySymbol (itemSymbol : string) =
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "iid", Sql.string itemSymbol ] |> Sql.parameters [ "iid", Sql.string itemSymbol ]
|> Sql.query """ |> Sql.query """
SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites, SELECT store_id,stock,available,limit_stock,i.id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end,
buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods
FROM store_item FROM store_item
JOIN item i on store_item.item_id = i.id JOIN item i on store_item.item_id = i.id
@ -189,6 +192,7 @@ let getStoreItemBySymbol (itemSymbol : string) =
Stock = reader.int "stock" Stock = reader.int "stock"
LimitStock = reader.bool "limit_stock" LimitStock = reader.bool "limit_stock"
Available = reader.bool "available" Available = reader.bool "available"
SaleEnd = reader.int64OrNone "sale_end"
TotalSold = None TotalSold = None
RequiresInvites = reader.intOrNone "require_invites" RequiresInvites = reader.intOrNone "require_invites"
RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64 RequiresRole = reader.stringOrNone "require_role" |> Option.map uint64

View File

@ -142,6 +142,7 @@ type StoreItem = {
LimitStock : bool LimitStock : bool
Available : bool Available : bool
TotalSold : int option TotalSold : int option
SaleEnd : int64 option
RequiresRole : uint64 option RequiresRole : uint64 option
RequiresInvites : int option RequiresInvites : int option
Item : Item Item : Item

View File

@ -53,13 +53,20 @@ let checkDoesntExceedStackCap (item : Item) player =
| _ , Some _ -> "You already own this item" |> embedWithError | _ , Some _ -> "You already own this item" |> embedWithError
| _ -> Ok () | _ -> Ok ()
let checkItemSaleStillActive (item : StoreItem) =
match item.SaleEnd with
| Some time ->
let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime()
if DateTime.UtcNow < date then Ok () else $"Sale for {item.Item.Name} has already ended!" |> embedWithError
| None -> Ok ()
let checkSoldItemAlready (item : Item) player = let checkSoldItemAlready (item : Item) player =
if player.Inventory |> List.exists (fun i -> item.Id = i.Id) if player.Inventory |> List.exists (fun i -> item.Id = i.Id)
then Ok () then Ok ()
else $"{item.Name} not found in your inventory! Looks like you sold it already." else $"{item.Name} not found in your inventory! Looks like you sold it already."
|> embedWithError |> embedWithError
let checkHasItemsInArsenal itemType items player = let checkHasItemsInArsenal itemType items =
if List.isEmpty items |> not if List.isEmpty items |> not
then Ok () then Ok ()
else $"You currently have no {itemType} in your arsenal to sell!" else $"You currently have no {itemType} in your arsenal to sell!"
@ -125,6 +132,13 @@ let getItemEmbeds owned (items : StoreItem list) =
| _ -> ()) | _ -> ())
// if item.Item.Type = ItemType.Whitelist then // if item.Item.Type = ItemType.Whitelist then
// embed.AddField("Mint Allowance", (if item.Item.Id = "WHITEOG" then 2 else 1) |> string, true) |> ignore // embed.AddField("Mint Allowance", (if item.Item.Id = "WHITEOG" then 2 else 1) |> string, true) |> ignore
item.SaleEnd |> Option.iter (fun time ->
let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime()
if DateTime.UtcNow < date then
embed.AddField("⏰ Closes", $"<t:{time}:R>", true) |> ignore
else
embed.AddField("🚫 Closed", $"<t:{time}:R>", true) |> ignore)
item.TotalSold |> Option.iter (fun total -> embed.AddField("Total Sold", string total, true) |> ignore) item.TotalSold |> Option.iter (fun total -> embed.AddField("Total Sold", string total, true) |> ignore)
embed.Color <- WeaponClass.getClassEmbedColor item.Item embed.Color <- WeaponClass.getClassEmbedColor item.Item
embed.Title <- titleText embed.Title <- titleText
@ -142,12 +156,19 @@ let getBuyItemsEmbed storeId player (storeInventory : StoreItem list) =
storeInventory storeInventory
|> List.map (fun item -> |> List.map (fun item ->
let owned = player.Inventory |> List.exists (fun i -> i.Id = item.Item.Id) let owned = player.Inventory |> List.exists (fun i -> i.Id = item.Item.Id)
let saleStillOngoing =
match item.SaleEnd with
| Some time ->
let date = DateTimeOffset.FromUnixTimeSeconds(time).DateTime.ToUniversalTime()
DateTime.UtcNow < date
| None -> true
let inStock = item.Available && (item.Stock > 0 || item.LimitStock = false) let inStock = item.Available && (item.Stock > 0 || item.LimitStock = false)
match owned , inStock with match owned , inStock , saleStillOngoing with
| _ , false -> | _ , false , _ ->
let msg = if item.Available then "Out of Stock" else "Unavailable" let msg = if item.Available then "Out of Stock" else "Unavailable"
DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"{item.Item.Name} ({msg})", true) DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"{item.Item.Name} ({msg})", true)
| false , true -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}") | false , true , true -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}")
| _ , _ , false -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Closed {item.Item.Name}", true)
| _ -> | _ ->
match checkDoesntExceedStackCap item.Item player with match checkDoesntExceedStackCap item.Item player with
| Ok _ -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}") | Ok _ -> DiscordButtonComponent(WeaponClass.getClassButtonColor item.Item, $"Buy-{item.Item.Id}-{storeId}", $"Buy {item.Item.Name}")
@ -261,7 +282,7 @@ let buyForPlayer storeId player (filterBy : ItemType option) (ctx : IDiscordCont
let sell itemType getItems (ctx : IDiscordContext) = let sell itemType getItems (ctx : IDiscordContext) =
executePlayerAction ctx (fun player -> async { executePlayerAction ctx (fun player -> async {
let items = getItems player.Inventory let items = getItems player.Inventory
match checkHasItemsInArsenal itemType items player with match checkHasItemsInArsenal itemType items with
| Ok _ -> let itemStore = getSellEmbed items | Ok _ -> let itemStore = getSellEmbed items
do! ctx.FollowUp(itemStore) |> Async.AwaitTask do! ctx.FollowUp(itemStore) |> Async.AwaitTask
| Error e -> do! ctx.FollowUp e |> Async.AwaitTask | Error e -> do! ctx.FollowUp e |> Async.AwaitTask
@ -335,6 +356,7 @@ let handleBuyItem (dispatch : IDiscordContext -> Task) (ctx : IDiscordContext) i
let storeItem = storeInventory |> List.find (fun si -> si.Item.Id = itemId) let storeItem = storeInventory |> List.find (fun si -> si.Item.Id = itemId)
do! checkHasSufficientFunds storeItem.Item player do! checkHasSufficientFunds storeItem.Item player
do! checkHasStock storeItem do! checkHasStock storeItem
do! checkItemSaleStillActive storeItem
do! checkDoesntExceedStackCap storeItem.Item player do! checkDoesntExceedStackCap storeItem.Item player
do! checkHasRequiredRole storeItem (ctx.GetDiscordMember()) do! checkHasRequiredRole storeItem (ctx.GetDiscordMember())
do! checkHasRequiredInvites storeItem player do! checkHasRequiredInvites storeItem player

View File

@ -507,7 +507,6 @@ let submitAddress (address : string) (ctx : IDiscordContext) =
do! user.GrantRoleAsync(role) |> Async.AwaitTask do! user.GrantRoleAsync(role) |> Async.AwaitTask
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhiteOGPending) let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhiteOGPending)
do! user.RevokeRoleAsync(role) |> Async.AwaitTask do! user.RevokeRoleAsync(role) |> Async.AwaitTask
do! Messaging.sendFollowUpMessage ctx $""" do! Messaging.sendFollowUpMessage ctx $"""
🚀 __Mint Date:__ June 20th 🚀 __Mint Date:__ June 20th