- Added main router in src/index.js to register endpoints. - Implemented GET /mayo-api/products to fetch product list with pagination and filters. - Implemented GET /mayo-api/dictionaries to fetch various dictionaries for frontend use. - Created separate files for routes, repositories, serializers, and utilities to maintain clean architecture. - Added utility functions for async handling, pagination, and order search parsing. - Introduced serializers for products and dictionaries to format data for frontend consumption. - Established repository functions for database queries related to products and dictionaries. - Updated package.json to include license information. - Created documentation for the API extension detailing current state and future implementation plans.
253 lines
7.2 KiB
JavaScript
253 lines
7.2 KiB
JavaScript
export default {
|
|
id: "mayo-api",
|
|
handler: (router, context) => {
|
|
const { services, getSchema, database } = context;
|
|
const { ItemsService } = services;
|
|
|
|
router.get("/products", async (req, res) => {
|
|
const productsService = new ItemsService("mayo_products", {
|
|
schema: await getSchema(),
|
|
accountability: req.accountability,
|
|
});
|
|
const partsService = new ItemsService("mayo_parts", {
|
|
schema: await getSchema(),
|
|
accountability: req.accountability,
|
|
});
|
|
|
|
try {
|
|
const products = await productsService.readByQuery({
|
|
fields: [
|
|
"id",
|
|
"note",
|
|
"model_id.name",
|
|
"model_id.strings_count",
|
|
"model_id.scale",
|
|
],
|
|
limit: -1,
|
|
});
|
|
|
|
const productIds = products.map((product) => product.id);
|
|
|
|
const parts = await partsService.readByQuery({
|
|
fields: [
|
|
"id",
|
|
"product_id",
|
|
"part_type",
|
|
"top_color_id.name",
|
|
"back_color_id.name",
|
|
"top_finish",
|
|
"back_finish",
|
|
],
|
|
filter: {
|
|
product_id: {
|
|
_in: productIds,
|
|
},
|
|
},
|
|
limit: -1,
|
|
});
|
|
const partsByProductId = new Map();
|
|
|
|
for (const part of parts) {
|
|
const productId =
|
|
typeof part.product_id === "object"
|
|
? part.product_id.id
|
|
: part.product_id;
|
|
|
|
if (!partsByProductId.has(productId)) {
|
|
partsByProductId.set(productId, []);
|
|
}
|
|
|
|
partsByProductId.get(productId).push(part);
|
|
}
|
|
|
|
const response = products.map((product) => ({
|
|
...product,
|
|
parts: partsByProductId.get(product.id) ?? [],
|
|
}));
|
|
|
|
res.json(response);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get("/products-new", async (req, res) => {
|
|
try {
|
|
const products = await database("mayo_products as product")
|
|
.select(
|
|
"product.id",
|
|
"product.note",
|
|
"model.name as model_name",
|
|
"model.strings_count as model_strings_count",
|
|
"model.scale as model_scale",
|
|
)
|
|
.leftJoin("mayo_models as model", "product.model_id", "model.id");
|
|
|
|
const productIds = products.map((product) => product.id);
|
|
|
|
const parts = productIds.length
|
|
? await database("mayo_parts as part")
|
|
.select(
|
|
"part.id",
|
|
"part.product_id",
|
|
"part.part_type",
|
|
"part.top_finish",
|
|
"part.back_finish",
|
|
"top_color.name as top_color_name",
|
|
"back_color.name as back_color_name",
|
|
)
|
|
.leftJoin(
|
|
"mayo_colors as top_color",
|
|
"part.top_color_id",
|
|
"top_color.id",
|
|
)
|
|
.leftJoin(
|
|
"mayo_colors as back_color",
|
|
"part.back_color_id",
|
|
"back_color.id",
|
|
)
|
|
.whereIn("part.product_id", productIds)
|
|
: [];
|
|
|
|
const partsByProductId = new Map();
|
|
|
|
for (const part of parts) {
|
|
if (!partsByProductId.has(part.product_id)) {
|
|
partsByProductId.set(part.product_id, []);
|
|
}
|
|
|
|
partsByProductId.get(part.product_id).push({
|
|
id: part.id,
|
|
product_id: part.product_id,
|
|
part_type: part.part_type,
|
|
top_color_id: {
|
|
name: part.top_color_name,
|
|
},
|
|
back_color_id: {
|
|
name: part.back_color_name,
|
|
},
|
|
top_finish: part.top_finish,
|
|
back_finish: part.back_finish,
|
|
});
|
|
}
|
|
|
|
const response = products.map((product) => ({
|
|
id: product.id,
|
|
note: product.note,
|
|
model_id: {
|
|
name: product.model_name,
|
|
strings_count: product.model_strings_count,
|
|
scale: product.model_scale,
|
|
},
|
|
parts: partsByProductId.get(product.id) ?? [],
|
|
}));
|
|
|
|
res.json(response);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get("/orders", async (req, res) => {
|
|
const itemsService = new ItemsService("mayo_order_products", {
|
|
schema: await getSchema(),
|
|
accountability: req.accountability,
|
|
});
|
|
|
|
try {
|
|
const items = await itemsService.readByQuery({
|
|
fields: [
|
|
"id",
|
|
"product_order_index",
|
|
"order_id.order_number",
|
|
"order_id.order_year",
|
|
"order_id.client_id.name",
|
|
"product_id.id",
|
|
"product_id.note",
|
|
"product_id.model_id.name",
|
|
"product_id.model_id.strings_count",
|
|
"product_id.model_id.scale",
|
|
],
|
|
limit: -1,
|
|
});
|
|
|
|
res.json(items);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get("/my-products", async (req, res) => {
|
|
try {
|
|
const products = await database("mayo_products as mp")
|
|
.select(
|
|
"mp.id",
|
|
"mm.name as model",
|
|
"mo.order_number",
|
|
"mo.order_year",
|
|
"mop.product_order_index as order_index",
|
|
)
|
|
.leftJoin("mayo_order_products as mop", "mop.product_id", "mp.id")
|
|
.leftJoin("mayo_orders as mo", "mo.id", "mop.order_id")
|
|
.leftJoin("mayo_models as mm", "mm.id", "mp.model_id");
|
|
|
|
const productIds = products.map((product) => product.id);
|
|
|
|
const parts = productIds.length
|
|
? await database("mayo_parts as part")
|
|
.select("part.product_id", "part.part_type")
|
|
.whereIn("part.product_id", productIds)
|
|
: [];
|
|
|
|
const partTypesByProductId = new Map();
|
|
|
|
for (const part of parts) {
|
|
if (!partTypesByProductId.has(part.product_id)) {
|
|
partTypesByProductId.set(part.product_id, []);
|
|
}
|
|
|
|
if (part.part_type) {
|
|
partTypesByProductId.get(part.product_id).push(part.part_type);
|
|
}
|
|
}
|
|
|
|
const response = products.map((product) => ({
|
|
...product,
|
|
part_types: partTypesByProductId.get(product.id) ?? [],
|
|
}));
|
|
|
|
res.json(response);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get("/my-products2", async (req, res) => {
|
|
const productsService = new ItemsService("mayo_products", {
|
|
schema: await getSchema(),
|
|
accountability: req.accountability,
|
|
});
|
|
const partsService = new ItemsService("mayo_parts", {
|
|
schema: await getSchema(),
|
|
accountability: req.accountability,
|
|
});
|
|
|
|
try {
|
|
const products = await productsService.readByQuery({
|
|
fields: [
|
|
"id",
|
|
"note",
|
|
"model_id.name",
|
|
"model_id.strings_count",
|
|
"model_id.scale",
|
|
],
|
|
limit: -1,
|
|
});
|
|
res.json(products);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
},
|
|
};
|