4291552b6d
Co-authored-by: Copilot <copilot@github.com>
238 lines
6.2 KiB
JavaScript
238 lines
6.2 KiB
JavaScript
import express from "express";
|
|
import { authenticate, generateToken } from "../../services/authentication.js";
|
|
import {
|
|
checkIfServiceIsActive,
|
|
checkIfServiceIsActive2,
|
|
} from "../../services/functions.js";
|
|
|
|
// mailer imports
|
|
import { sendMail } from "../../services/mailer/send.js";
|
|
import { loanMail } from "../../services/mailer/templates/loan_created.js";
|
|
|
|
import dotenv from "dotenv";
|
|
dotenv.config();
|
|
const router = express.Router();
|
|
|
|
const loan_service = "Loan Service";
|
|
const loan_mailer_service = "Loan Mailer";
|
|
|
|
// database funcs import
|
|
import {
|
|
createLoanInDatabase,
|
|
getLoanInfoWithID,
|
|
getLoansFromDatabase,
|
|
getBorrowableItemsFromDatabase,
|
|
getALLLoans,
|
|
getItems,
|
|
SETdeleteLoanFromDatabase,
|
|
setReturnDate,
|
|
setTakeDate,
|
|
} from "./database/loansMgmt.database.js";
|
|
|
|
router.post(
|
|
"/createLoan",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
try {
|
|
const { items, startDate, endDate, note } = req.body || {};
|
|
|
|
if (!Array.isArray(items) || items.length === 0) {
|
|
return res.status(400).json({ message: "Items array is required" });
|
|
}
|
|
|
|
// If dates are not provided, default to now .. +7 days
|
|
const start =
|
|
startDate ?? new Date().toISOString().slice(0, 19).replace("T", " ");
|
|
const end =
|
|
endDate ??
|
|
new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
|
.toISOString()
|
|
.slice(0, 19)
|
|
.replace("T", " ");
|
|
|
|
// Coerce item IDs to numbers and filter invalids
|
|
const itemIds = items
|
|
.map((v) => Number(v))
|
|
.filter((n) => Number.isFinite(n));
|
|
|
|
if (itemIds.length === 0) {
|
|
return res.status(400).json({ message: "No valid item IDs provided" });
|
|
}
|
|
|
|
const result = await createLoanInDatabase(
|
|
req.user.username,
|
|
start,
|
|
end,
|
|
note,
|
|
itemIds,
|
|
);
|
|
if (result.success) {
|
|
if (await checkIfServiceIsActive2(loan_mailer_service)) {
|
|
const mailInfo = await getLoanInfoWithID(result.data.id);
|
|
console.log(mailInfo);
|
|
const { html, text } = loanMail(
|
|
req.user.first_name + " " + req.user.last_name,
|
|
mailInfo.data.loaned_items_name,
|
|
mailInfo.data.start_date,
|
|
mailInfo.data.end_date,
|
|
mailInfo.data.created_at,
|
|
mailInfo.data.note,
|
|
);
|
|
await sendMail({
|
|
to: process.env.MAIL_SENDEES,
|
|
subject: "Neue Ausleihe erstellt!",
|
|
html,
|
|
text,
|
|
});
|
|
}
|
|
|
|
return res.status(201).json({
|
|
message: "Loan created successfully",
|
|
loanId: result.data.id,
|
|
loanCode: result.data.loan_code,
|
|
});
|
|
}
|
|
|
|
if (result.code === "CONFLICT") {
|
|
return res
|
|
.status(409)
|
|
.json({ message: "Items not available in the selected period" });
|
|
}
|
|
|
|
if (result.code === "BAD_REQUEST") {
|
|
return res.status(400).json({ message: result.message });
|
|
}
|
|
|
|
return res.status(500).json({ message: "Failed to create loan" });
|
|
} catch (err) {
|
|
console.error("createLoan error:", err);
|
|
return res.status(500).json({ message: "Failed to create loan" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.get(
|
|
"/loans",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const result = await getLoansFromDatabase(req.user.username);
|
|
if (result.success) {
|
|
res.status(200).json(result.data);
|
|
} else if (result.status) {
|
|
res.status(200).json([]);
|
|
} else {
|
|
res.status(500).json({ message: "Failed to fetch loans" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.post(
|
|
"/set-return-date/:loan_code",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const loanCode = req.params.loan_code;
|
|
const result = await setReturnDate(loanCode);
|
|
if (result.success) {
|
|
res.status(200).json({ data: result.data });
|
|
} else {
|
|
res.status(500).json({ message: "Failed to set return date" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.post(
|
|
"/set-take-date/:loan_code",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const loanCode = req.params.loan_code;
|
|
const result = await setTakeDate(loanCode);
|
|
if (result.success) {
|
|
res.status(200).json({ data: result.data });
|
|
} else {
|
|
res.status(500).json({ message: "Failed to set take date" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.get("/all-items", authenticate, async (req, res) => {
|
|
const result = await getItems();
|
|
if (result.success) {
|
|
res.status(200).json(result.data);
|
|
} else {
|
|
res.status(500).json({ message: "Failed to fetch items" });
|
|
}
|
|
});
|
|
|
|
router.delete(
|
|
"/delete-loan/:id",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const loanId = req.params.id;
|
|
const result = await SETdeleteLoanFromDatabase(loanId);
|
|
if (result.success) {
|
|
res.status(200).json({ message: "Loan deleted successfully" });
|
|
} else {
|
|
if (result.code === "LOAN_NOT_FOUND") {
|
|
res.status(404).json({ message: "Loan not found" });
|
|
}
|
|
|
|
if (result.code === "LOAN_NOT_RETURNED") {
|
|
res.status(507).json({
|
|
message: "Cannot delete loan that has not been returned",
|
|
});
|
|
}
|
|
|
|
res.status(500).json({ message: "Failed to delete loan" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.get(
|
|
"/all-loans",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const result = await getALLLoans();
|
|
if (result.success) {
|
|
res.status(200).json(result.data);
|
|
} else {
|
|
res.status(500).json({ message: "Failed to fetch loans" });
|
|
}
|
|
},
|
|
);
|
|
|
|
router.post(
|
|
"/borrowable-items",
|
|
checkIfServiceIsActive(loan_service),
|
|
authenticate,
|
|
async (req, res) => {
|
|
const { startDate, endDate } = req.body || {};
|
|
if (!startDate || !endDate) {
|
|
return res
|
|
.status(400)
|
|
.json({ message: "startDate and endDate are required" });
|
|
}
|
|
|
|
const result = await getBorrowableItemsFromDatabase(
|
|
startDate,
|
|
endDate,
|
|
req.user.role,
|
|
);
|
|
if (result.success) {
|
|
// return the array directly for consistency with /items
|
|
return res.status(200).json(result.data);
|
|
} else {
|
|
return res
|
|
.status(500)
|
|
.json({ message: "Failed to fetch borrowable items" });
|
|
}
|
|
},
|
|
);
|
|
|
|
export default router;
|