95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
|
|
import "./_env";
|
||
|
|
import { getAdminPocketBase } from "../src/lib/server/pocketbase-admin";
|
||
|
|
|
||
|
|
const LOCATION =
|
||
|
|
"NSS Fasteners price list - spring pin ISO8752 (Spring Steel CS70)";
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const pb = await getAdminPocketBase();
|
||
|
|
|
||
|
|
const total = await pb.collection("stock_items").getList(1, 1, {
|
||
|
|
filter: `location = "${LOCATION}"`,
|
||
|
|
});
|
||
|
|
console.log(`SPRING PINS imported rows in PB: ${total.totalItems}\n`);
|
||
|
|
|
||
|
|
const rows = await pb.collection("stock_items").getList(1, 5, {
|
||
|
|
filter: `location = "${LOCATION}"`,
|
||
|
|
sort: "sku",
|
||
|
|
});
|
||
|
|
for (const r of rows.items) {
|
||
|
|
console.log("SKU: " + r.sku);
|
||
|
|
console.log("name: " + JSON.stringify(r.name));
|
||
|
|
console.log("description:" + JSON.stringify(r.description));
|
||
|
|
console.log("cost_price: " + r.cost_price);
|
||
|
|
console.log("selling: " + r.selling_price);
|
||
|
|
console.log("markup: " + r.markup);
|
||
|
|
console.log("notes: " + JSON.stringify(r.notes?.substring(0, 200)));
|
||
|
|
console.log("name == description? " + (r.name === r.description ? "YES ✓" : "NO ✗"));
|
||
|
|
console.log("");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Anomalies
|
||
|
|
const zeroPrice = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && cost_price = 0`,
|
||
|
|
fields: "sku,cost_price,name",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows with cost_price = 0: ${zeroPrice.length}`);
|
||
|
|
if (zeroPrice.length > 0) {
|
||
|
|
console.log(" Examples:");
|
||
|
|
for (const r of zeroPrice.slice(0, 5)) {
|
||
|
|
console.log(` ${r.sku} ${r.name}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const noMarkup = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && cost_price > 0 && markup = 0`,
|
||
|
|
fields: "sku,cost_price,name,selling_price",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows with cost>0 and markup=0 (anomaly!): ${noMarkup.length}`);
|
||
|
|
|
||
|
|
const noSelling = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && cost_price > 0 && selling_price = 0`,
|
||
|
|
fields: "sku,cost_price,name,selling_price",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows with cost>0 and selling_price=0 (anomaly!): ${noSelling.length}`);
|
||
|
|
|
||
|
|
// Diameter / length coverage
|
||
|
|
const noDiam = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && notes !~ "Diameter:"`,
|
||
|
|
fields: "sku",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows missing 'Diameter:' in notes: ${noDiam.length}`);
|
||
|
|
const noLen = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && notes !~ "Length:"`,
|
||
|
|
fields: "sku",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows missing 'Length:' in notes: ${noLen.length}`);
|
||
|
|
const noFinish = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && notes !~ "Finish:"`,
|
||
|
|
fields: "sku",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows missing 'Finish:' in notes: ${noFinish.length}`);
|
||
|
|
const noSpringPin = await pb.collection("stock_items").getFullList({
|
||
|
|
filter: `location = "${LOCATION}" && name !~ "SPRING PIN"`,
|
||
|
|
fields: "sku,name",
|
||
|
|
batch: 500,
|
||
|
|
});
|
||
|
|
console.log(`Rows missing 'SPRING PIN' in name: ${noSpringPin.length}`);
|
||
|
|
if (noSpringPin.length > 0) {
|
||
|
|
console.log(" Examples:");
|
||
|
|
for (const r of noSpringPin.slice(0, 5)) {
|
||
|
|
console.log(` ${r.sku} ${r.name}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
main().catch((e) => {
|
||
|
|
console.error(e);
|
||
|
|
process.exit(1);
|
||
|
|
});
|