2023-06-21 01:28:38 +02:00
|
|
|
const fs = require("fs");
|
|
|
|
const path = require("path");
|
2023-05-25 13:54:28 +02:00
|
|
|
const axios = require("axios");
|
2023-05-28 19:48:06 +02:00
|
|
|
const utils = require("./utils");
|
2023-05-25 13:54:28 +02:00
|
|
|
|
2023-06-03 15:09:29 +02:00
|
|
|
const units = {
|
2023-06-02 16:45:54 +02:00
|
|
|
"": { unit: "stk", factor: 1 },
|
|
|
|
gg: { unit: "g", factor: 1 },
|
|
|
|
er: { unit: "stk", factor: 1 },
|
|
|
|
teebeutel: { unit: "stk", factor: 1 },
|
2023-05-27 22:00:27 +02:00
|
|
|
};
|
|
|
|
|
2023-06-02 16:45:54 +02:00
|
|
|
exports.getCanonical = function (item, today) {
|
2023-05-27 22:00:27 +02:00
|
|
|
// try to read quantity and unit from product name
|
|
|
|
const name = item.ProductName;
|
2023-05-31 23:12:16 +02:00
|
|
|
let [quantity, unit] = utils.parseUnitAndQuantityAtEnd(name);
|
2023-06-03 15:09:29 +02:00
|
|
|
|
|
|
|
return utils.convertUnit(
|
|
|
|
{
|
|
|
|
id: item.ProductID,
|
|
|
|
name,
|
2023-06-17 20:54:45 +02:00
|
|
|
// description: "", not available
|
2023-06-03 15:09:29 +02:00
|
|
|
price: item.Price,
|
|
|
|
priceHistory: [{ date: today, price: item.Price }],
|
|
|
|
isWeighted: item.IsBulk,
|
2023-06-13 10:09:52 +02:00
|
|
|
unit: !unit ? item.UnitType : unit,
|
|
|
|
quantity: !quantity ? item.Unit : quantity,
|
2023-06-03 15:09:29 +02:00
|
|
|
bio: item.IsBio,
|
|
|
|
url: `${item.CategorySEOName}/${item.SEOName}`,
|
|
|
|
},
|
|
|
|
units,
|
2023-06-05 14:19:38 +02:00
|
|
|
"hofer",
|
|
|
|
{
|
|
|
|
quantity: item.Unit,
|
|
|
|
unit: item.UnitType,
|
|
|
|
}
|
2023-06-03 15:09:29 +02:00
|
|
|
);
|
|
|
|
};
|
2023-05-25 13:54:28 +02:00
|
|
|
|
2023-06-21 01:28:38 +02:00
|
|
|
const HOFER_BASE_URL = `https://shopservice.roksh.at`;
|
|
|
|
const CATEGORIES = HOFER_BASE_URL + `/category/GetFullCategoryList/`;
|
|
|
|
const CONFIG = { headers: { authorization: null } };
|
|
|
|
const TOKEN_DATA = {
|
|
|
|
OwnWebshopProviderCode: "",
|
|
|
|
SetUserSelectedShopsOnFirstSiteLoad: true,
|
|
|
|
RedirectToDashboardNeeded: false,
|
|
|
|
ShopsSelectedForRoot: "hofer",
|
|
|
|
BrandProviderSelectedForRoot: null,
|
|
|
|
UserSelectedShops: [],
|
|
|
|
};
|
|
|
|
const ITEMS = HOFER_BASE_URL + `/productlist/CategoryProductList`;
|
2023-05-25 13:54:28 +02:00
|
|
|
|
2023-06-21 01:28:38 +02:00
|
|
|
exports.fetchData = async function () {
|
|
|
|
const { subCategories } = await exports.getCategories();
|
2023-05-25 13:54:28 +02:00
|
|
|
|
|
|
|
let hoferItems = [];
|
|
|
|
for (let subCategory of subCategories) {
|
2023-06-02 16:45:54 +02:00
|
|
|
let categoryData = (await axios.get(`${ITEMS}?progId=${subCategory.ProgID}&firstLoadProductListResultNum=4&listResultProductNum=24`, CONFIG))
|
|
|
|
.data;
|
2023-05-25 13:54:28 +02:00
|
|
|
const numPages = categoryData.ProductListResults[0].ListContext.TotalPages;
|
|
|
|
|
|
|
|
for (let iPage = 1; iPage <= numPages; iPage++) {
|
2023-06-02 16:45:54 +02:00
|
|
|
let items = (
|
|
|
|
await axios.post(`${HOFER_BASE_URL}/productlist/GetProductList`, { CategoryProgId: subCategory.ProgID, Page: iPage }, CONFIG)
|
|
|
|
).data;
|
2023-05-25 13:54:28 +02:00
|
|
|
hoferItems = hoferItems.concat(items.ProductList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hoferItems;
|
2023-06-03 15:09:29 +02:00
|
|
|
};
|
2023-06-02 10:38:14 +02:00
|
|
|
|
2023-06-21 01:28:38 +02:00
|
|
|
exports.getCategories = async () => {
|
|
|
|
const token = (
|
|
|
|
await axios.post("https://shopservice.roksh.at/session/configure", TOKEN_DATA, {
|
|
|
|
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
|
|
|
})
|
|
|
|
).headers["jwt-auth"];
|
|
|
|
CONFIG.headers.authorization = "Bearer " + token;
|
|
|
|
|
|
|
|
// concat all subcategories (categories.[i].ChildList)
|
|
|
|
const categories = (await axios.post(CATEGORIES, {}, CONFIG)).data;
|
|
|
|
const subCategories = categories.reduce((acc, category) => acc.concat(category.ChildList), []);
|
|
|
|
return { categories, subCategories };
|
|
|
|
};
|
|
|
|
|
2023-06-02 16:56:22 +02:00
|
|
|
exports.urlBase = "https://www.roksh.at/hofer/produkte/";
|
2023-06-21 01:28:38 +02:00
|
|
|
|
|
|
|
exports.initializeCategoryMapping = async () => {};
|
|
|
|
|
|
|
|
exports.mapCategory = (rawItem) => {};
|
|
|
|
|
|
|
|
exports.generateCategoryMapping = async (rawItems) => {
|
|
|
|
const { categories } = await exports.getCategories();
|
|
|
|
const lookup = {};
|
|
|
|
const processCategory = (category) => {
|
|
|
|
lookup[category.ProgID] = {
|
|
|
|
category: category.ProgID,
|
|
|
|
url: category.Url,
|
|
|
|
code: "",
|
|
|
|
numItems: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
for (const child of category.ChildList) {
|
|
|
|
processCategory(child);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
for (const category of categories) {
|
|
|
|
processCategory(category);
|
|
|
|
}
|
|
|
|
|
|
|
|
let total = 0;
|
|
|
|
for (const item of rawItems) {
|
|
|
|
if (!lookup[item.CategorySEOName]) {
|
|
|
|
console.log(`Couldn't find category '${item.CategorySEOName}' for Hofer product ${item.ProductName}`);
|
|
|
|
total++;
|
|
|
|
lookup[item.CategorySEOName] = {
|
|
|
|
category: item.CategorySEOName,
|
|
|
|
url: "",
|
|
|
|
code: "",
|
|
|
|
numItems: 1,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
const category = lookup[item.CategorySEOName];
|
|
|
|
category.item = item;
|
|
|
|
category.numItems++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const output = Object.keys(lookup).map((key) => lookup[key]);
|
|
|
|
const oldCategories = path.join(__dirname, "hofer-categories.json");
|
|
|
|
fs.writeFileSync(path.join(__dirname, "hofer-categories.json"), JSON.stringify(output, null, 2));
|
|
|
|
};
|
|
|
|
|
|
|
|
// Generate JSON for category mapping in stores/hofer-categories.json
|
|
|
|
if (require.main === module) {
|
|
|
|
(async () => {
|
|
|
|
const { readJSON } = require("../analysis");
|
|
|
|
// const rawItems = await this.fetchData();
|
|
|
|
const rawItems = readJSON("data/hofer-2023-06-20.json.br");
|
|
|
|
await exports.generateCategoryMapping(rawItems);
|
|
|
|
})();
|
|
|
|
}
|