SpaceNinjaServerOnlyGit/src/controllers/api/claimCompletedRecipeController.ts

88 lines
3.4 KiB
TypeScript

//this is a controller for the claimCompletedRecipe route
//it will claim a recipe for the user
import { RequestHandler } from "express";
import { logger } from "@/src/utils/logger";
import { getRecipe } from "@/src/services/itemDataService";
import { IOid } from "@/src/types/commonTypes";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory, updateCurrency, addItem, addMiscItems, addRecipes } from "@/src/services/inventoryService";
export interface IClaimCompletedRecipeRequest {
RecipeIds: IOid[];
}
export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
const claimCompletedRecipeRequest = getJSONfromString(String(req.body)) as IClaimCompletedRecipeRequest;
const accountId = await getAccountIdForRequest(req);
if (!accountId) throw new Error("no account id");
const inventory = await getInventory(accountId);
const pendingRecipe = inventory.PendingRecipes.find(
recipe => recipe._id?.toString() === claimCompletedRecipeRequest.RecipeIds[0].$oid
);
if (!pendingRecipe) {
logger.error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
}
//check recipe is indeed ready to be completed
// if (pendingRecipe.CompletionDate > new Date()) {
// logger.error(`recipe ${pendingRecipe._id} is not ready to be completed`);
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
// }
inventory.PendingRecipes.pull(pendingRecipe._id);
await inventory.save();
const recipe = getRecipe(pendingRecipe.ItemType);
if (!recipe) {
logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
}
if (req.query.cancel) {
const currencyChanges = await updateCurrency(recipe.buildPrice * -1, false, accountId);
const inventory = await getInventory(accountId);
addMiscItems(inventory, recipe.ingredients);
await inventory.save();
// Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root.
res.json({
...currencyChanges,
MiscItems: recipe.ingredients
});
} else {
logger.debug("Claiming Recipe", { recipe, pendingRecipe });
let InventoryChanges = {};
if (recipe.consumeOnUse) {
const recipeChanges = [
{
ItemType: pendingRecipe.ItemType,
ItemCount: -1
}
];
InventoryChanges = { ...InventoryChanges, Recipes: recipeChanges };
const inventory = await getInventory(accountId);
addRecipes(inventory, recipeChanges);
await inventory.save();
}
if (req.query.rush) {
InventoryChanges = {
...InventoryChanges,
...(await updateCurrency(recipe.skipBuildTimePrice, true, accountId))
};
}
res.json({
InventoryChanges: {
...InventoryChanges,
...(await addItem(accountId, recipe.resultType, recipe.num)).InventoryChanges
}
});
}
};