Skip to content

Commit

Permalink
Merge branch 'new-rms-adapter' into alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
Xziy committed Jul 19, 2023
2 parents c53240c + 4fd9cf3 commit 2a48e1f
Show file tree
Hide file tree
Showing 40 changed files with 845 additions and 323 deletions.
12 changes: 10 additions & 2 deletions adapters/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import RMSAdapter from "./rms/RMSAdapter";
import RMSAdapter, { ConfigRMSAdapter } from "./rms/RMSAdapter";
import MapAdapter from "./map/MapAdapter";
import CaptchaAdapter from "./captcha/CaptchaAdapter";
import OTPAdapter from "./otp/OneTimePasswordAdapter";
Expand All @@ -7,7 +7,7 @@ import PaymentAdapter from "./payment/PaymentAdapter";
import { DiscountAdapter } from "./discount/default/discountAdapter";
import BonusProgramAdapter from "./bonusprogram/BonusProgramAdapter";
/**
* retruns RMS-adapter
* // TODO: delete getAdapter RMS after release new adapter RMS
*/
export declare class RMS {
static getAdapter(adapterName: string): Promise<typeof RMSAdapter>;
Expand Down Expand Up @@ -44,10 +44,18 @@ export declare class OTP {
}
/** TODO: move other Adapters to one class adapter */
export declare class Adapter {
private static instanceRMS;
static getDiscountAdapter(adapterName?: string, initParams?: {
[key: string]: string | number | boolean;
}): Promise<DiscountAdapter>;
/**
* retruns BonusProgram-adapter
*/
static getBonusProgramAdapter(adapterName?: string, initParams?: {
[key: string]: string | number | boolean;
}): Promise<BonusProgramAdapter>;
/**
* retruns RMS-adapter
*/
static getRMSAdapter(adapter?: string | RMSAdapter, initParams?: ConfigRMSAdapter): Promise<RMSAdapter>;
}
44 changes: 43 additions & 1 deletion adapters/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Adapter = exports.OTP = exports.Captcha = exports.Payment = exports.Media = exports.Map = exports.RMS = void 0;
const RMSAdapter_1 = require("./rms/RMSAdapter");
const pow_1 = require("./captcha/default/pow");
const defaultOTP_1 = require("./otp/default/defaultOTP");
const fs = require("fs");
const discountAdapter_1 = require("./discount/default/discountAdapter");
// import DiscountAdapter from "./discount/AbstractDiscountAdapter";
const WEBRESTO_MODULES_PATH = process.env.WEBRESTO_MODULES_PATH === undefined ? "@webresto" : process.env.WEBRESTO_MODULES_PATH;
/**
* retruns RMS-adapter
* // TODO: delete getAdapter RMS after release new adapter RMS
*/
class RMS {
static async getAdapter(adapterName) {
Expand Down Expand Up @@ -184,6 +185,9 @@ class Adapter {
throw new Error("Module " + adapterLocation + " not found");
}
}
/**
* retruns BonusProgram-adapter
*/
static async getBonusProgramAdapter(adapterName, initParams) {
if (!adapterName) {
let defaultAdapterName = await Settings.get("DEFAULT_BONUS_ADAPTER");
Expand All @@ -201,5 +205,43 @@ class Adapter {
throw new Error("Module " + adapterLocation + " not found");
}
}
/**
* retruns RMS-adapter
*/
static async getRMSAdapter(adapter, initParams) {
// Return the singleon
if (this.instanceRMS) {
return this.instanceRMS;
}
let adapterName;
if (adapter) {
if (typeof adapter === "string") {
adapterName = adapter;
}
else if (adapter instanceof RMSAdapter_1.default) {
this.instanceRMS = adapter;
return this.instanceRMS;
}
else {
throw new Error("Adapter should be a string or instance of rmsadapter");
}
}
if (!adapterName) {
adapterName = await Settings.get("DEFAULT_RMS_ADAPTER");
if (!adapterName)
throw 'RMS adapter is not installed';
}
let adapterLocation = WEBRESTO_MODULES_PATH + "/" + adapterName.toLowerCase() + "-rms-adapter";
adapterLocation = fs.existsSync(adapterLocation) ? adapterLocation : "@webresto/" + adapterName.toLowerCase() + "-rms-adapter";
try {
const adapterModule = require(adapterLocation);
this.instanceRMS = new adapterModule.RMSAdapter(initParams);
return this.instanceRMS;
}
catch (e) {
sails.log.error("CORE > getAdapter RMS > error; ", e);
throw new Error("Module " + adapterLocation + " not found");
}
}
}
exports.Adapter = Adapter;
57 changes: 53 additions & 4 deletions adapters/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import RMSAdapter from "./rms/RMSAdapter";
import RMSAdapter, { ConfigRMSAdapter } from "./rms/RMSAdapter";
import MapAdapter from "./map/MapAdapter";
import CaptchaAdapter from "./captcha/CaptchaAdapter";
import { POW } from "./captcha/default/pow";
Expand All @@ -14,9 +14,10 @@ import BonusProgramAdapter from "./bonusprogram/BonusProgramAdapter";
const WEBRESTO_MODULES_PATH = process.env.WEBRESTO_MODULES_PATH === undefined ? "@webresto" : process.env.WEBRESTO_MODULES_PATH;

/**
* retruns RMS-adapter
* // TODO: delete getAdapter RMS after release new adapter RMS
*/
export class RMS {

public static async getAdapter(adapterName: string): Promise<typeof RMSAdapter> {

// if(!Boolean(adapterName)) {
Expand Down Expand Up @@ -188,6 +189,10 @@ export class OTP {

/** TODO: move other Adapters to one class adapter */
export class Adapter {

// Singletons
private static instanceRMS: RMSAdapter;

public static async getDiscountAdapter(adapterName?: string, initParams?: {[key: string]:string | number | boolean}): Promise<DiscountAdapter> {

if(!adapterName) {
Expand All @@ -210,7 +215,9 @@ export class Adapter {
}
}


/**
* retruns BonusProgram-adapter
*/
public static async getBonusProgramAdapter(adapterName?: string, initParams?: {[key: string]:string | number | boolean}): Promise<BonusProgramAdapter> {
if(!adapterName) {
let defaultAdapterName = await Settings.get("DEFAULT_BONUS_ADAPTER") as string;
Expand All @@ -229,5 +236,47 @@ export class Adapter {
}
}

}

/**
* retruns RMS-adapter
*/
public static async getRMSAdapter(adapter?: string | RMSAdapter, initParams?: ConfigRMSAdapter): Promise<RMSAdapter> {
// Return the singleon
if (this.instanceRMS) {
return this.instanceRMS;
}

let adapterName: string;
if(adapter) {
if(typeof adapter === "string") {
adapterName = adapter;
} else if(adapter instanceof RMSAdapter) {
this.instanceRMS = adapter;
return this.instanceRMS;
} else {
throw new Error("Adapter should be a string or instance of rmsadapter");
}

}

if(!adapterName) {
adapterName = await Settings.get("DEFAULT_RMS_ADAPTER") as string;
if (!adapterName) throw 'RMS adapter is not installed';
}


let adapterLocation = WEBRESTO_MODULES_PATH + "/" + adapterName.toLowerCase() + "-rms-adapter";
adapterLocation = fs.existsSync(adapterLocation) ? adapterLocation : "@webresto/" + adapterName.toLowerCase() + "-rms-adapter";

try {
const adapterModule = require(adapterLocation);
this.instanceRMS = new adapterModule.RMSAdapter(initParams);
return this.instanceRMS;
} catch (e) {
sails.log.error("CORE > getAdapter RMS > error; ", e);
throw new Error("Module " + adapterLocation + " not found");
}
}


}
7 changes: 0 additions & 7 deletions adapters/rms/OrderResponse.d.ts

This file was deleted.

2 changes: 0 additions & 2 deletions adapters/rms/OrderResponse.js

This file was deleted.

7 changes: 0 additions & 7 deletions adapters/rms/OrderResponse.ts

This file was deleted.

56 changes: 35 additions & 21 deletions adapters/rms/RMSAdapter.d.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,66 @@
import OrderResponse from "./OrderResponse";
import Order from "../../models/Order";
import Dish from "../../models/Dish";
import Group from "../../models/Group";
export type ConfigRMSAdapter = {
[key: string]: number | boolean | string;
};
/**
* Responce from RMS
*/
export interface OrderResponse {
code: number;
body: any;
}
/**
* An abstract RMS adapter class. Used to create new RMS adapters.
*/
export default abstract class RMSAdapter {
protected readonly syncMenuTime: number;
protected readonly syncBalanceTime: number;
protected readonly syncStreetsTime: number;
protected constructor(menuTime: number, balanceTime: number, streetsTime: number);
readonly config: ConfigRMSAdapter;
private static syncProductsInterval;
private static syncOutOfStocksInterval;
constructor(config?: ConfigRMSAdapter);
private static initialize;
/**
* Menu synchronization with RMS system
* At first, groups are synchronized, then dishes are synchronized for each of these groups.
* When synchronizing groups, those groups that were not on the list will be turned off before the start of synchronization
* Those dishes that are left without ties will be marked with isDeleted
* There can be no dishes in the root.
*/
protected abstract sync(): Promise<void>;
static syncProducts(concept?: string, force?: boolean): Promise<void>;
/**
* Synchronization of streets with RMS systems
* Synchronizing the balance of dishes with the RMS adapter
*/
protected abstract syncStreets(): Promise<void>;
static syncOutOfStocks(): Promise<void>;
/**
* Synchronizing the balance of dishes with the RMS adapter
* Checks whether the nomenclature was updated if the last time something has changed will return to True
* @returns boolean
*/
protected abstract syncBalance(): Promise<void>;
protected abstract nomenclatureHasUpdated(): Promise<boolean>;
/**
*
* @returns
*/
protected abstract loadNomenclatureTree(rmsGroupIds?: string[]): Promise<Group[]>;
protected abstract loadProductsByGroup(group: Group): Promise<Dish[]>;
protected abstract loadOutOfStocksDishes(concept?: string): Promise<Dish[]>;
/**
* Create an order
* @param orderData - webresto order
* @return Order response
*/
abstract createOrder(orderData: Order): Promise<OrderResponse>;
/**
* Order check
* Order check before order
* @param orderData - webresto order
* @return Order response
*/
abstract checkOrder(orderData: Order): Promise<OrderResponse>;
/**
* Getting system information
* @return RMS system information
*/
abstract getSystemData(): Promise<any>;
/**
* Direct request to the RMS API
* @param method - method name
* @param params - params
* @return
*/
abstract api(method: string, params: any): Promise<any>;
/**
* Method for creating and getting an already existing RMS adapter
* @param params - parameters for initialization
*/
static getInstance(...params: any[]): RMSAdapter;
}
87 changes: 78 additions & 9 deletions adapters/rms/RMSAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,87 @@ Object.defineProperty(exports, "__esModule", { value: true });
* An abstract RMS adapter class. Used to create new RMS adapters.
*/
class RMSAdapter {
// TODO: надо убрать от сюда настройки синхронизации
constructor(menuTime, balanceTime, streetsTime) {
this.syncMenuTime = menuTime;
this.syncBalanceTime = balanceTime;
this.syncStreetsTime = streetsTime;
constructor(config) {
this.config = {};
this.config = config;
// Run async inittilization
RMSAdapter.initialize();
}
static async initialize() {
// Run product sync interval
const NO_SYNC_NOMENCLATURE = await Settings.get("NO_SYNC_NOMENCLATURE") ?? false;
if (!NO_SYNC_NOMENCLATURE) {
const SYNC_PRODUCTS_INTERVAL_SECOUNDS = await Settings.get("SYNC_PRODUCTS_INTERVAL_SECOUNDS");
if (RMSAdapter.syncProductsInterval)
clearInterval(RMSAdapter.syncProductsInterval);
RMSAdapter.syncProductsInterval = setInterval(async () => {
RMSAdapter.syncProducts();
}, SYNC_PRODUCTS_INTERVAL_SECOUNDS < 120 ? 120000 : SYNC_PRODUCTS_INTERVAL_SECOUNDS * 1000 || 120000);
}
// Run sync OutOfStock
const NO_SYNC_OUT_OF_STOCKS = await Settings.get("NO_SYNC_OUT_OF_STOCKS") ?? false;
if (!NO_SYNC_OUT_OF_STOCKS) {
const SYNC_OUT_OF_STOCKS_INTERVAL_SECOUNDS = await Settings.get("SYNC_OUT_OF_STOCKS_INTERVAL_SECOUNDS");
if (RMSAdapter.syncOutOfStocksInterval)
clearInterval(RMSAdapter.syncOutOfStocksInterval);
RMSAdapter.syncOutOfStocksInterval = setInterval(async () => {
RMSAdapter.syncOutOfStocks();
}, SYNC_OUT_OF_STOCKS_INTERVAL_SECOUNDS < 60 ? 60000 : SYNC_OUT_OF_STOCKS_INTERVAL_SECOUNDS * 1000 || 60000);
}
}
/**
* Menu synchronization with RMS system
* At first, groups are synchronized, then dishes are synchronized for each of these groups.
* When synchronizing groups, those groups that were not on the list will be turned off before the start of synchronization
* Those dishes that are left without ties will be marked with isDeleted
* There can be no dishes in the root.
*/
static async syncProducts(concept, force = false) {
// TODO: implement concept
const rootGroupsToSync = await Settings.get("rootGroupsRMSToSync");
const rmsAdapter = await Adapter.getRMSAdapter();
if (rmsAdapter.nomenclatureHasUpdated() || force) {
const currentRMSGroupsFlatTree = await rmsAdapter.loadNomenclatureTree(rootGroupsToSync);
// Get ids of all current RMS groups
const rmsGroupIds = currentRMSGroupsFlatTree.map(group => group.rmsId);
// Set all groups not in the list to inactive
await Group.update({ where: { rmsId: { not: rmsGroupIds } } }, { isDeleted: true }).fetch();
for (const group of currentRMSGroupsFlatTree) {
emitter.emit("rms-sync:before-each-group-item", group);
// Update or create group
const groupData = { ...group, isDeleted: false };
await Group.createOrUpdate(groupData);
}
// Collect all product ids
let allProductIds = [];
for (const group of currentRMSGroupsFlatTree) {
const productsToUpdate = await rmsAdapter.loadProductsByGroup(group);
// Get ids of all current products in group
const productIds = productsToUpdate.map(product => product.rmsId);
allProductIds = allProductIds.concat(productIds);
for (let product of productsToUpdate) {
emitter.emit("rms-sync:before-each-product-item", product);
// Update or create product
const productData = { ...product, isDeleted: false };
await Dish.createOrUpdate(productData);
}
}
// Find all inactive groups
const inactiveGroups = await Group.find({ isDeleted: true });
const inactiveGroupIds = inactiveGroups.map(group => group.id);
// Delete all dishes in inactive groups or not in the updated list
await Dish.update({ where: { or: [{ parentGroup: { in: inactiveGroupIds } }, { rmsId: { not: allProductIds } }, { parentGroup: null }] } }, { isDeleted: true });
}
return;
}
;
/**
* Method for creating and getting an already existing RMS adapter
* @param params - parameters for initialization
* Synchronizing the balance of dishes with the RMS adapter
*/
static getInstance(...params) {
return RMSAdapter.prototype;
static syncOutOfStocks() {
// Consider the concepts
return;
}
;
}
exports.default = RMSAdapter;
Loading

0 comments on commit 2a48e1f

Please sign in to comment.