after dot 2 digit fixed
This commit is contained in:
parent
dbee0d4a30
commit
83750fb4e5
@ -31,6 +31,10 @@ export const createOrder = async (req, res) => {
|
|||||||
}
|
}
|
||||||
const addedBy = req.user._id;
|
const addedBy = req.user._id;
|
||||||
// Create a new PdOrder instance
|
// Create a new PdOrder instance
|
||||||
|
// Ensure subtotal, gstTotal, and grandTotal are formatted to two decimal places
|
||||||
|
const formattedSubtotal = parseFloat(subtotal).toFixed(2);
|
||||||
|
const formattedGstTotal = parseFloat(gstTotal).toFixed(2);
|
||||||
|
const formattedGrandTotal = parseFloat(grandTotal).toFixed(2);
|
||||||
const newOrder = new PdOrder({
|
const newOrder = new PdOrder({
|
||||||
paymentMode,
|
paymentMode,
|
||||||
shipTo,
|
shipTo,
|
||||||
@ -51,9 +55,9 @@ export const createOrder = async (req, res) => {
|
|||||||
quantity: item.count,
|
quantity: item.count,
|
||||||
remainingQuantity: item.count,
|
remainingQuantity: item.count,
|
||||||
})),
|
})),
|
||||||
subtotal,
|
subtotal: formattedSubtotal,
|
||||||
gstTotal,
|
gstTotal: formattedGstTotal,
|
||||||
grandTotal,
|
grandTotal: formattedGrandTotal,
|
||||||
addedBy,
|
addedBy,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,7 +135,10 @@ export const processOrder = async (req, res) => {
|
|||||||
gstTotal += itemGST;
|
gstTotal += itemGST;
|
||||||
invoiceAmount += itemSubtotal + itemGST;
|
invoiceAmount += itemSubtotal + itemGST;
|
||||||
});
|
});
|
||||||
|
// Round the final totals to two decimal places
|
||||||
|
subtotal = parseFloat(subtotal.toFixed(2));
|
||||||
|
gstTotal = parseFloat(gstTotal.toFixed(2));
|
||||||
|
invoiceAmount = parseFloat(invoiceAmount.toFixed(2));
|
||||||
// Create a new invoice
|
// Create a new invoice
|
||||||
const newInvoice = new Invoice({
|
const newInvoice = new Invoice({
|
||||||
invoiceId,
|
invoiceId,
|
||||||
@ -180,7 +187,9 @@ export const processOrder = async (req, res) => {
|
|||||||
pendingTotalAmount += itemPendingSubtotal + itemPendingGST;
|
pendingTotalAmount += itemPendingSubtotal + itemPendingGST;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
itemPendingSubtotal = parseFloat(itemPendingSubtotal.toFixed(2));
|
||||||
|
itemPendingGST = parseFloat(itemPendingGST.toFixed(2));
|
||||||
|
pendingTotalAmount = parseFloat(pendingTotalAmount.toFixed(2));
|
||||||
// Only update order status if all items have been fully processed
|
// Only update order status if all items have been fully processed
|
||||||
if (allItemsProcessed) {
|
if (allItemsProcessed) {
|
||||||
order.status = "processing"; // All items are fully processed
|
order.status = "processing"; // All items are fully processed
|
||||||
@ -251,13 +260,13 @@ export const processOrder = async (req, res) => {
|
|||||||
item.remainingQuantity
|
item.remainingQuantity
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
item.price
|
(item.price).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
(item.GST * item.price) / 100
|
((item.GST * item.price) / 100).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
(item.price + (item.GST * item.price) / 100) * item.remainingQuantity
|
((item.price + (item.GST * item.price) / 100) * item.remainingQuantity).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`
|
`
|
||||||
@ -415,9 +424,9 @@ export const cancelOrderController = async (req, res) => {
|
|||||||
|
|
||||||
const processedItems = invoice.items
|
const processedItems = invoice.items
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
const itemSubtotal = item.price * item.processquantity;
|
const itemSubtotal = (item.price * item.processquantity).toFixed(2);
|
||||||
const itemGST =
|
const itemGST =
|
||||||
((item.price * item.GST) / 100) * item.processquantity;
|
(((item.price * item.GST) / 100) * item.processquantity).toFixed(2);
|
||||||
|
|
||||||
subtotal += itemSubtotal;
|
subtotal += itemSubtotal;
|
||||||
gstTotal += itemGST;
|
gstTotal += itemGST;
|
||||||
@ -441,13 +450,13 @@ export const cancelOrderController = async (req, res) => {
|
|||||||
item.processquantity
|
item.processquantity
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
item.price
|
(item.price).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
(item.price * item.GST) / 100
|
((item.price * item.GST) / 100).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
itemSubtotal + itemGST
|
(itemSubtotal + itemGST).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@ -468,9 +477,9 @@ export const cancelOrderController = async (req, res) => {
|
|||||||
if (Array.isArray(order.orderItem)) {
|
if (Array.isArray(order.orderItem)) {
|
||||||
order.orderItem.forEach((item) => {
|
order.orderItem.forEach((item) => {
|
||||||
if (item.remainingQuantity > 0) {
|
if (item.remainingQuantity > 0) {
|
||||||
const itemSubtotal = item.price * item.remainingQuantity;
|
const itemSubtotal = i(tem.price * item.remainingQuantity).toFixed(2);
|
||||||
const itemGST =
|
const itemGST =
|
||||||
((item.price * item.GST) / 100) * item.remainingQuantity;
|
(((item.price * item.GST) / 100) * item.remainingQuantity).toFixed(2);
|
||||||
|
|
||||||
totalCancelAmount += itemSubtotal + itemGST;
|
totalCancelAmount += itemSubtotal + itemGST;
|
||||||
|
|
||||||
@ -492,13 +501,13 @@ export const cancelOrderController = async (req, res) => {
|
|||||||
item.remainingQuantity
|
item.remainingQuantity
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
item.price
|
(item.price).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
(item.price * item.GST) / 100
|
((item.price * item.GST) / 100).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
itemSubtotal + itemGST
|
(itemSubtotal + itemGST).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@ -968,7 +977,7 @@ export const updateCourierStatusToDispatched = async (req, res) => {
|
|||||||
product.processquantity
|
product.processquantity
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
product.price
|
(product.price).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${(
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${(
|
||||||
(product.GST * product.price) /
|
(product.GST * product.price) /
|
||||||
@ -985,7 +994,7 @@ export const updateCourierStatusToDispatched = async (req, res) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th colspan="7" style="border: 1px solid #555; padding: 2px; text-align: right;">Total Amount:</th>
|
<th colspan="7" style="border: 1px solid #555; padding: 2px; text-align: right;">Total Amount:</th>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
invoice.invoiceAmount
|
(invoice.invoiceAmount).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -1181,7 +1190,7 @@ export const updateCourierStatusToDelivered = async (req, res) => {
|
|||||||
product.processquantity
|
product.processquantity
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
product.price
|
(product.price).toFixed(2)
|
||||||
}</td>
|
}</td>
|
||||||
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${(
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${(
|
||||||
(product.GST * product.price) /
|
(product.GST * product.price) /
|
||||||
@ -1490,13 +1499,11 @@ export const gettotalorderandvalueofpd = async (req, res) => {
|
|||||||
// Get the date of the last order
|
// Get the date of the last order
|
||||||
const lastPurchaseOrderDate = totalOrders > 0 ? orders[0].createdAt : null;
|
const lastPurchaseOrderDate = totalOrders > 0 ? orders[0].createdAt : null;
|
||||||
|
|
||||||
res
|
res.status(200).json({
|
||||||
.status(200)
|
totalOrders,
|
||||||
.json({
|
totalValue: parseFloat(totalValue),
|
||||||
totalOrders,
|
lastPurchaseOrderDate,
|
||||||
totalValue: parseFloat(totalValue),
|
});
|
||||||
lastPurchaseOrderDate,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching orders:", error);
|
console.error("Error fetching orders:", error);
|
||||||
res.status(500).json({ message: "Server error", error });
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
@ -80,9 +80,11 @@ export const getProductsWithOpenInventoryInfo = async (req, res) => {
|
|||||||
name: product.name,
|
name: product.name,
|
||||||
brand: product.brand?.brandName || "N/A", // Access brandName here
|
brand: product.brand?.brandName || "N/A", // Access brandName here
|
||||||
category: product.category?.categoryName || "N/A", // Access categoryName here
|
category: product.category?.categoryName || "N/A", // Access categoryName here
|
||||||
allPDs: pdMap[product.SKU] || 0,
|
allPDs: (pdMap[product.SKU] || 0).toFixed(2),
|
||||||
allRDs: rdMap[product.SKU] || 0,
|
allRDs: (rdMap[product.SKU] || 0).toFixed(2),
|
||||||
allPdAndRd: (pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0),
|
allPdAndRd: (
|
||||||
|
(pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0)
|
||||||
|
).toFixed(2),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Step 7: Get total count for pagination
|
// Step 7: Get total count for pagination
|
||||||
@ -179,9 +181,11 @@ export const getProductsWithStockInfo = async (req, res) => {
|
|||||||
name: product.name,
|
name: product.name,
|
||||||
brand: product.brand?.brandName || "N/A", // Access brandName here
|
brand: product.brand?.brandName || "N/A", // Access brandName here
|
||||||
category: product.category?.categoryName || "N/A", // Access categoryName here
|
category: product.category?.categoryName || "N/A", // Access categoryName here
|
||||||
allPDs: pdMap[product.SKU] || 0,
|
allPDs: (pdMap[product.SKU] || 0).toFixed(2),
|
||||||
allRDs: rdMap[product.SKU] || 0,
|
allRDs: (rdMap[product.SKU] || 0).toFixed(2),
|
||||||
allPdAndRd: (pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0),
|
allPdAndRd: (
|
||||||
|
(pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0)
|
||||||
|
).toFixed(2),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Step 7: Get total count for pagination
|
// Step 7: Get total count for pagination
|
||||||
@ -261,24 +265,37 @@ export const DownloadProductsWithOpenInventoryInfo = async (req, res) => {
|
|||||||
// Combine product info with PD/RD counts using SKU
|
// Combine product info with PD/RD counts using SKU
|
||||||
const productData = products.map((product) => ({
|
const productData = products.map((product) => ({
|
||||||
"SKU Code": product.SKU,
|
"SKU Code": product.SKU,
|
||||||
"SKU Description": product.name, // SKU Description
|
"SKU Description": product.name, // SKU Description
|
||||||
"Category Name": product.category?.categoryName || "N/A", // Category Name
|
"Category Name": product.category?.categoryName || "N/A", // Category Name
|
||||||
"Brand Name": product.brand?.brandName || "N/A", // Brand Name
|
"Brand Name": product.brand?.brandName || "N/A", // Brand Name
|
||||||
"Total At PDs And Retailers": (pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0), // Total At PDs & Retailers
|
"Total At PDs And Retailers": (
|
||||||
"All PDs": pdMap[product.SKU] || 0, // All PDs
|
(pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0)
|
||||||
"All Retailers": rdMap[product.SKU] || 0, // All Retailers
|
).toFixed(2), // Total At PDs & Retailers
|
||||||
|
"All PDs": (pdMap[product.SKU] || 0).toFixed(2), // All PDs
|
||||||
|
"All Retailers": (rdMap[product.SKU] || 0).toFixed(2), // All Retailers
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Define headers (first row in the sheet)
|
// Define headers (first row in the sheet)
|
||||||
const headers = [
|
const headers = [
|
||||||
["SKU Code", "SKU Description", "Category Name", "Brand Name", "Total At PDs And Retailers", "All PDs", "All Retailers"]
|
[
|
||||||
|
"SKU Code",
|
||||||
|
"SKU Description",
|
||||||
|
"Category Name",
|
||||||
|
"Brand Name",
|
||||||
|
"Total At PDs And Retailers",
|
||||||
|
"All PDs",
|
||||||
|
"All Retailers",
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create worksheet with headers
|
// Create worksheet with headers
|
||||||
const worksheet = XLSX.utils.aoa_to_sheet(headers);
|
const worksheet = XLSX.utils.aoa_to_sheet(headers);
|
||||||
|
|
||||||
// Append product data below headers
|
// Append product data below headers
|
||||||
XLSX.utils.sheet_add_json(worksheet, productData, { skipHeader: true, origin: "A2" });
|
XLSX.utils.sheet_add_json(worksheet, productData, {
|
||||||
|
skipHeader: true,
|
||||||
|
origin: "A2",
|
||||||
|
});
|
||||||
|
|
||||||
// Calculate and set column widths based on content
|
// Calculate and set column widths based on content
|
||||||
const columnWidths = headers[0].map((header, index) => {
|
const columnWidths = headers[0].map((header, index) => {
|
||||||
@ -289,20 +306,28 @@ export const DownloadProductsWithOpenInventoryInfo = async (req, res) => {
|
|||||||
}
|
}
|
||||||
return { wch: maxLength + 2 }; // Add some padding
|
return { wch: maxLength + 2 }; // Add some padding
|
||||||
});
|
});
|
||||||
worksheet['!cols'] = columnWidths;
|
worksheet["!cols"] = columnWidths;
|
||||||
|
|
||||||
// Create workbook and append worksheet
|
// Create workbook and append worksheet
|
||||||
const workbook = XLSX.utils.book_new();
|
const workbook = XLSX.utils.book_new();
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, "OpeningInventoryReport");
|
XLSX.utils.book_append_sheet(workbook, worksheet, "OpeningInventoryReport");
|
||||||
|
|
||||||
// Write workbook to buffer
|
// Write workbook to buffer
|
||||||
const excelBuffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
|
const excelBuffer = XLSX.write(workbook, {
|
||||||
|
bookType: "xlsx",
|
||||||
|
type: "buffer",
|
||||||
|
});
|
||||||
|
|
||||||
// Send Excel file as response
|
// Send Excel file as response
|
||||||
res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
res.setHeader(
|
||||||
res.setHeader("Content-Disposition", "attachment; filename=OpeningInventoryReport.xlsx");
|
"Content-Type",
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
|
);
|
||||||
|
res.setHeader(
|
||||||
|
"Content-Disposition",
|
||||||
|
"attachment; filename=OpeningInventoryReport.xlsx"
|
||||||
|
);
|
||||||
res.send(excelBuffer);
|
res.send(excelBuffer);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ success: false, message: error.message });
|
res.status(500).json({ success: false, message: error.message });
|
||||||
}
|
}
|
||||||
@ -367,24 +392,37 @@ export const DownloadProductsWithStockInfo = async (req, res) => {
|
|||||||
// Combine product info with PD/RD counts using SKU
|
// Combine product info with PD/RD counts using SKU
|
||||||
const productData = products.map((product) => ({
|
const productData = products.map((product) => ({
|
||||||
"SKU Code": product.SKU,
|
"SKU Code": product.SKU,
|
||||||
"SKU Description": product.name, // SKU Description
|
"SKU Description": product.name, // SKU Description
|
||||||
"Category Name": product.category?.categoryName || "N/A", // Category Name
|
"Category Name": product.category?.categoryName || "N/A", // Category Name
|
||||||
"Brand Name": product.brand?.brandName || "N/A", // Brand Name
|
"Brand Name": product.brand?.brandName || "N/A", // Brand Name
|
||||||
"Total At PDs And Retailers": (pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0), // Total At PDs & Retailers
|
"Total At PDs And Retailers": (
|
||||||
"All PDs": pdMap[product.SKU] || 0, // All PDs
|
(pdMap[product.SKU] || 0) + (rdMap[product.SKU] || 0)
|
||||||
"All Retailers": rdMap[product.SKU] || 0, // All Retailers
|
).toFixed(2), // Total At PDs & Retailers
|
||||||
|
"All PDs": (pdMap[product.SKU] || 0).toFixed(2), // All PDs
|
||||||
|
"All Retailers": (rdMap[product.SKU] || 0).toFixed(2), // All Retailers
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Define headers (first row in the sheet)
|
// Define headers (first row in the sheet)
|
||||||
const headers = [
|
const headers = [
|
||||||
["SKU Code", "SKU Description", "Category Name", "Brand Name", "Total At PDs And Retailers", "All PDs", "All Retailers"]
|
[
|
||||||
|
"SKU Code",
|
||||||
|
"SKU Description",
|
||||||
|
"Category Name",
|
||||||
|
"Brand Name",
|
||||||
|
"Total At PDs And Retailers",
|
||||||
|
"All PDs",
|
||||||
|
"All Retailers",
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create worksheet with headers
|
// Create worksheet with headers
|
||||||
const worksheet = XLSX.utils.aoa_to_sheet(headers);
|
const worksheet = XLSX.utils.aoa_to_sheet(headers);
|
||||||
|
|
||||||
// Append product data below headers
|
// Append product data below headers
|
||||||
XLSX.utils.sheet_add_json(worksheet, productData, { skipHeader: true, origin: "A2" });
|
XLSX.utils.sheet_add_json(worksheet, productData, {
|
||||||
|
skipHeader: true,
|
||||||
|
origin: "A2",
|
||||||
|
});
|
||||||
|
|
||||||
// Calculate and set column widths based on content
|
// Calculate and set column widths based on content
|
||||||
const columnWidths = headers[0].map((header, index) => {
|
const columnWidths = headers[0].map((header, index) => {
|
||||||
@ -395,20 +433,28 @@ export const DownloadProductsWithStockInfo = async (req, res) => {
|
|||||||
}
|
}
|
||||||
return { wch: maxLength + 2 }; // Add some padding
|
return { wch: maxLength + 2 }; // Add some padding
|
||||||
});
|
});
|
||||||
worksheet['!cols'] = columnWidths;
|
worksheet["!cols"] = columnWidths;
|
||||||
|
|
||||||
// Create workbook and append worksheet
|
// Create workbook and append worksheet
|
||||||
const workbook = XLSX.utils.book_new();
|
const workbook = XLSX.utils.book_new();
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, "StockReport");
|
XLSX.utils.book_append_sheet(workbook, worksheet, "StockReport");
|
||||||
|
|
||||||
// Write workbook to buffer
|
// Write workbook to buffer
|
||||||
const excelBuffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
|
const excelBuffer = XLSX.write(workbook, {
|
||||||
|
bookType: "xlsx",
|
||||||
|
type: "buffer",
|
||||||
|
});
|
||||||
|
|
||||||
// Send Excel file as response
|
// Send Excel file as response
|
||||||
res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
res.setHeader(
|
||||||
res.setHeader("Content-Disposition", "attachment; filename=StockReport.xlsx");
|
"Content-Type",
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
|
);
|
||||||
|
res.setHeader(
|
||||||
|
"Content-Disposition",
|
||||||
|
"attachment; filename=StockReport.xlsx"
|
||||||
|
);
|
||||||
res.send(excelBuffer);
|
res.send(excelBuffer);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ success: false, message: error.message });
|
res.status(500).json({ success: false, message: error.message });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user