Genesis
This commit is contained in:
23
src/endpoints/category.js
Normal file
23
src/endpoints/category.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { sendJson, serverTimestamp } from '../http.js';
|
||||
import { getCategoryList } from '../queries/category-list.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/category';
|
||||
|
||||
export async function handle(_req, res, { url }) {
|
||||
const cursor = Number(url.searchParams.get('lastChangedCategory')) || 0;
|
||||
const limit = Number(url.searchParams.get('limit')) || 20;
|
||||
|
||||
const categories = await getCategoryList({ cursor, limit });
|
||||
const timestamp = serverTimestamp();
|
||||
|
||||
return sendJson(
|
||||
res,
|
||||
200,
|
||||
categories.map((category) => ({
|
||||
...category,
|
||||
updated_at: timestamp,
|
||||
created_at: timestamp,
|
||||
}))
|
||||
);
|
||||
}
|
||||
6
src/endpoints/cimage.js
Normal file
6
src/endpoints/cimage.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { createImageHandler } from './image-handler.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/cimage';
|
||||
|
||||
export const handle = createImageHandler();
|
||||
71
src/endpoints/client.js
Normal file
71
src/endpoints/client.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import { sendJson, serverTimestamp } from '../http.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/client';
|
||||
|
||||
function buildClientStep1(config) {
|
||||
const {
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
serverFingerprint,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
authCode: null,
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName: null,
|
||||
mandantDatabase: null,
|
||||
serverFingerprint,
|
||||
name: null,
|
||||
serverTimestamp: serverTimestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
function buildClientStep2(authCode, config) {
|
||||
const {
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName,
|
||||
mandantDatabase,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
authCode,
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName,
|
||||
mandantDatabase,
|
||||
serverFingerprint: null,
|
||||
name: null,
|
||||
serverTimestamp: serverTimestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
export function handle(req, res, { url, pairingStore, config }) {
|
||||
const authCode = url.searchParams.get('authCode') || '';
|
||||
const name = url.searchParams.get('name') || 'JTL-POS';
|
||||
|
||||
if (authCode.length <= 4 && authCode.length > 0) {
|
||||
return sendJson(res, 200, buildClientStep1(config));
|
||||
}
|
||||
|
||||
if (authCode.length === 6) {
|
||||
if (pairingStore.hasPairingCode(authCode)) {
|
||||
pairingStore.revokePairingCode(authCode);
|
||||
pairingStore.registerDevice(config.authToken, name);
|
||||
return sendJson(res, 200, buildClientStep2(authCode, config));
|
||||
}
|
||||
return sendJson(res, 400, { Message: 'Der Authentifizierungscode ist falsch.' });
|
||||
}
|
||||
|
||||
return sendJson(res, 400, { Message: 'Keinen passenden Authentifizierungscode gefunden.' });
|
||||
}
|
||||
13
src/endpoints/customergroup.js
Normal file
13
src/endpoints/customergroup.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { sendJson } from '../http.js';
|
||||
import { getCustomerGroupList } from '../queries/customer-groups.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/customergroup';
|
||||
|
||||
export async function handle(_req, res, { url }) {
|
||||
const cursor = Number(url.searchParams.get('lastChangedCustomerGroup')) || 0;
|
||||
|
||||
const customerGroups = await getCustomerGroupList({ cursor });
|
||||
|
||||
return sendJson(res, 200, customerGroups);
|
||||
}
|
||||
21
src/endpoints/image-handler.js
Normal file
21
src/endpoints/image-handler.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { sendBinary, sendJson } from '../http.js';
|
||||
import { resizeImage } from '../image-resize.js';
|
||||
import { getImageByHash } from '../queries/image.js';
|
||||
|
||||
export function createImageHandler() {
|
||||
return async function handle(_req, res, { url }) {
|
||||
const path = url.searchParams.get('path');
|
||||
|
||||
if (!path) {
|
||||
return sendJson(res, 400, { Message: "Missing required query parameter 'path'." });
|
||||
}
|
||||
|
||||
const image = await getImageByHash(path, '200');
|
||||
if (!image) {
|
||||
return sendJson(res, 404, { Message: `No image was found for path '${path}'.` });
|
||||
}
|
||||
|
||||
const buffer = await resizeImage(image.buffer);
|
||||
return sendBinary(res, 200, buffer, image.contentType);
|
||||
};
|
||||
}
|
||||
10
src/endpoints/index.js
Normal file
10
src/endpoints/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as category from './category.js';
|
||||
import * as cimage from './cimage.js';
|
||||
import * as client from './client.js';
|
||||
import * as customergroup from './customergroup.js';
|
||||
import * as init from './init.js';
|
||||
import * as order from './order.js';
|
||||
import * as pimage from './pimage.js';
|
||||
import * as product from './product.js';
|
||||
|
||||
export const endpoints = [client, init, category, product, pimage, cimage, customergroup, order];
|
||||
33
src/endpoints/init.js
Normal file
33
src/endpoints/init.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { sendJson } from '../http.js';
|
||||
import { getMaxExternalId } from '../order-log.js';
|
||||
import { getCategoryCount } from '../queries/category-count.js';
|
||||
import { getCustomerGroupCount } from '../queries/customer-groups.js';
|
||||
import { getProductCount } from '../queries/product-count.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/init';
|
||||
|
||||
export async function handle(_req, res, { url }) {
|
||||
const productCursor = Number(url.searchParams.get('lastChangedProduct')) || 0;
|
||||
const categoryCursor = Number(url.searchParams.get('lastChangedCategory')) || 0;
|
||||
const customerGroupCursor = Number(url.searchParams.get('lastChangedCustomerGroup')) || 0;
|
||||
|
||||
const [productCount, categoryCount, customerGroupCount] = await Promise.all([
|
||||
getProductCount({ cursor: productCursor }),
|
||||
getCategoryCount({ cursor: categoryCursor }),
|
||||
getCustomerGroupCount({ cursor: customerGroupCursor }),
|
||||
]);
|
||||
|
||||
return sendJson(res, 200, {
|
||||
version: '1.10.12.0',
|
||||
product_count: String(productCount),
|
||||
category_count: String(categoryCount),
|
||||
customer_count: '0',
|
||||
customerGroup_count: String(customerGroupCount),
|
||||
compositeProduct_count: '0',
|
||||
configurationGroup_count: '0',
|
||||
configurationItem_count: '0',
|
||||
deletedEntity_count: '0',
|
||||
max_orderId_count: getMaxExternalId(),
|
||||
});
|
||||
}
|
||||
48
src/endpoints/order.js
Normal file
48
src/endpoints/order.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { sendJson } from '../http.js';
|
||||
import { logOrder } from '../order-log.js';
|
||||
|
||||
export const method = 'POST';
|
||||
export const path = '/v1/order';
|
||||
|
||||
function parseBody(buffer) {
|
||||
if (!buffer || !buffer.length) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(buffer.toString('utf8'));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getOrders(body) {
|
||||
if (!body || typeof body !== 'object') {
|
||||
return [];
|
||||
}
|
||||
if (Array.isArray(body.orders)) {
|
||||
return body.orders;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export async function handle(req, res) {
|
||||
const body = parseBody(req.rawBody);
|
||||
|
||||
if (body === undefined) {
|
||||
return sendJson(res, 500, []);
|
||||
}
|
||||
|
||||
const orders = getOrders(body);
|
||||
const results = orders.map((order) => {
|
||||
logOrder(order);
|
||||
const externalOrderId = String(order?.externalId ?? '');
|
||||
|
||||
return {
|
||||
status: 'OK',
|
||||
externalOrderId,
|
||||
message: '',
|
||||
};
|
||||
});
|
||||
|
||||
return sendJson(res, 200, results);
|
||||
}
|
||||
6
src/endpoints/pimage.js
Normal file
6
src/endpoints/pimage.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { createImageHandler } from './image-handler.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/pimage';
|
||||
|
||||
export const handle = createImageHandler();
|
||||
67
src/endpoints/product.js
Normal file
67
src/endpoints/product.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { sendJson } from '../http.js';
|
||||
import { getProductList } from '../queries/product-list.js';
|
||||
|
||||
export const method = 'GET';
|
||||
export const path = '/v1/product';
|
||||
|
||||
const STATIC_DEFAULTS = {
|
||||
sort: '0',
|
||||
p_price: '0.00',
|
||||
discountable: '0',
|
||||
deposit: '0',
|
||||
discount: '',
|
||||
d_price: '0.0',
|
||||
tax_rate2: '',
|
||||
use_in_out_tax: '0',
|
||||
barcode: null,
|
||||
use_stock: '0',
|
||||
q_div: '0',
|
||||
quantity: '0',
|
||||
unit: null,
|
||||
single_bookable: '0',
|
||||
annotation: '',
|
||||
status: '0',
|
||||
tags: '',
|
||||
is_parent: '0',
|
||||
parent: '0',
|
||||
variants: '',
|
||||
print_kitchen_receipt: '0',
|
||||
deposit_name: '',
|
||||
updated_at: '0001-01-01 00:00:00',
|
||||
isCompositeProduct: '0',
|
||||
attributes: [],
|
||||
configurationGroups: '',
|
||||
options: null,
|
||||
hasBestBeforeDate: '0',
|
||||
hasLotNumber: '0',
|
||||
hasSerialNumber: '0',
|
||||
PLU: '',
|
||||
short_description: '',
|
||||
minStock: '0',
|
||||
container: [],
|
||||
reservedQuantity: '0.00',
|
||||
deliveryDetails: [],
|
||||
isbn: '',
|
||||
manufacturerName: null,
|
||||
han: null,
|
||||
productType: '0',
|
||||
voucherData: null,
|
||||
inputPrice: '0',
|
||||
inputQuantity: '0',
|
||||
};
|
||||
|
||||
export async function handle(_req, res, { url }) {
|
||||
const cursor = Number(url.searchParams.get('lastChangedProduct')) || 0;
|
||||
const limit = Number(url.searchParams.get('limit')) || 20;
|
||||
|
||||
const products = await getProductList({ cursor, limit });
|
||||
|
||||
return sendJson(
|
||||
res,
|
||||
200,
|
||||
products.map((product) => ({
|
||||
...STATIC_DEFAULTS,
|
||||
...product,
|
||||
}))
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user