Home Reference Source

lib/index.js

const fs = require('fs');
const path = require('path');

const MWS = require('@ericblade/mws-simple');
const Queues = require('./endpoints/Queue');

const errors = require('./errors');
const constants = require('./constants');

const { flattenResult } = require('./util/flatten-result');
const { validateAndTransformParameters } = require('./util/validation');
const { digResponseResult } = require('./util/dig-response-result.js');

// esdoc doesn't handle this line when destructuring for some reason.
const MWS_ENDPOINTS = constants.MWS_ENDPOINTS; // eslint-disable-line prefer-destructuring

// TODO: add Subscriptions and Recommendations categories
const {
    feeds, finances, inbound, inventory, outbound,
    merchFulfillment, orders, products, sellers, reports,
    recommendations,
} = require('./endpoints');

// TODO: THIS MAY BE A BAD IDEA CONSIDERING THAT SOME CATEGORIES SHARE SOME ENDPOINT NAMES
// TODO: WE MAY NEED TO COME UP WITH A WAY TO DEAL WITH THAT.

/** simple flat list of all the endpoints required from individual modules above */
const endpoints = {
    ...feeds,
    ...finances,
    ...inbound,
    ...inventory,
    ...merchFulfillment,
    ...orders,
    ...outbound,
    ...products,
    ...sellers,
    ...reports,
    ...recommendations,
};

/*
 * holds a reference to a MwsAdvanced if you call static init for old-style use,
 * to prevent garbage collection
 */
let staticMws = null;

class MwsAdvanced {
    /**
     * Create a new instance of MWSAdvanced, calling init(), and binding this instance of callEndpoint
     * to this instance of MWSAdvanced.
     *
     * @param {object} rest - passed on to @see {@link #init}
     * @returns {MWSAdvanced} - new instance of MWSAdvanced
     */
    constructor(...args) {
        this.init(...args);
        this.callEndpoint = this.callEndpoint.bind(this);

        // argh, binding of functions.
        this.init = this.init.bind(this);
        this.doRequest = this.doRequest.bind(this);
        this.parseEndpoint = this.parseEndpoint.bind(this);
        this.callEndpoint = this.callEndpoint.bind(this);
        this.getInboundGuidanceForASIN = this.getInboundGuidanceForASIN.bind(this);
        this.getInboundGuidanceForSKU = this.getInboundGuidanceForSKU.bind(this);
        this.getMarketplaces = this.getMarketplaces.bind(this);
        this.listOrders = this.listOrders.bind(this);
        this.listOrderItems = this.listOrderItems.bind(this);
        this.getOrder = this.getOrder.bind(this);
        this.listFinancialEvents = this.listFinancialEvents.bind(this);
        this.listInventorySupply = this.listInventorySupply.bind(this);
        this.listMatchingProducts = this.listMatchingProducts.bind(this);
        this.getMatchingProductForId = this.getMatchingProductForId.bind(this);
        this.getLowestPricedOffersForAsin = this.getLowestPricedOffersForAsin.bind(this);
        this.getLowestPricedOffersForSku = this.getLowestPricedOffersForSku.bind(this);
        this.getProductCategoriesForAsins = this.getProductCategoriesForAsins.bind(this);
        this.getProductCategoriesForSkus = this.getProductCategoriesForSkus.bind(this);
        this.getMyFeesEstimate = this.getMyFeesEstimate.bind(this);
        this.requestReport = this.requestReport.bind(this);
        this.getReportRequestList = this.getReportRequestList.bind(this);
        this.getReport = this.getReport.bind(this);
        this.getReportList = this.getReportList.bind(this);
        this.getReportListByNextToken = this.getReportListByNextToken.bind(this);
        this.getReportListAll = this.getReportListAll.bind(this);
        this.requestAndDownloadReport = this.requestAndDownloadReport.bind(this);
        this.manageReportSchedule = this.manageReportSchedule.bind(this);
        this.updateReportAcknowledgements = this.updateReportAcknowledgements.bind(this);
        this.getReportScheduleList = this.getReportScheduleList.bind(this);
        return this;
    }

    static init(...args) {
        staticMws = new MwsAdvanced(...args);
        return staticMws.init(...args);
    }

    /**
     * Initialize mws-advanced with your MWS access keys, merchantId, optionally authtoken, host, port
     * If accessKeyId, secretAccessKey, and/or merchantId are not provided, they will be read from
     * the environment variables MWS_ACESS_KEY, MWS_SECRET_ACCESS_KEY, and MWS_MERCHANT_ID respectively
     *
     * @public
     * @example
     * const mws = MWS.init({ region: 'NA', accessKeyId: '1234', secretAccessKey: '2345', merchantId: '1234567890' });
     * const mws = MWS.init({ region: 'EU', accessKeyId, ... });
     * const mws = MWS.init({ authToken: 'qwerty', accessKeyId, ...});
     * const mws = MWS.init({ host: 'alternate-mws-server.com', accessKeyId, ... });
     * @param {object} config Contains your MWS Access Keys/Tokens and options to configure the API
     * @param {string} [config.accessKeyId=process.env.MWS_ACCESS_KEY] Your MWS Access Key
     * @param {string} [config.secretAccessKey=process.env.MWS_SECRET_ACCESS_KEY] Your MWS Secret Access Key
     * @param {string} [config.merchantId=process.env.MWS_MERCHANT_ID] Your MWS Merchant ID
     * @param {string} [config.authToken] If making a call for a third party account, the Auth Token provided
     *                           for the third party account
     * @param {string} [config.region='NA'] One of the Amazon regions as specified in https://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html
     * @param {string} [config.host='mws.amazonservices.com'] Set MWS host server name, see https://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html
     * @param {number} [config.port=443] Set MWS host port
     * @returns {mws-simple} - The mws-simple instance used to communicate with the API
     */
    init({
        region = 'NA',
        accessKeyId = process.env.MWS_ACCESS_KEY,
        secretAccessKey = process.env.MWS_SECRET_ACCESS_KEY,
        merchantId = process.env.MWS_MERCHANT_ID,
        authToken,
        host = MWS_ENDPOINTS[region] || 'mws.amazonservices.com',
        port,
    } = {}) {
        this.mws = new MWS({
            accessKeyId,
            secretAccessKey,
            merchantId,
            authToken,
            host,
            port,
        });
        return this.mws;
    }

    async doRequest(requestData, options = {}) {
        try {
            const { result, headers } = await this.mws.request(requestData);
            const ret = options.noFlatten ? result : flattenResult(result);
            ret.headers = headers;
            return ret;
        } catch (err) {
            throw err;
        }
    }

    parseEndpoint(outParser, inParser = x => x) {
        return mwsApiName => async (callOptions, opt) => outParser(await this.callEndpoint(mwsApiName, inParser(callOptions), opt));
    }

    static parseEndpoint(...args) {
        return staticMws.parseEndpoint(...args);
    }

    static async callEndpoint(...args) {
        // TODO: throw error if init() not called yet
        return staticMws.callEndpoint(...args);
    }

    /**
     * Call a known endpoint at MWS, returning the raw data from the function. Parameters are
     * transformed and validated according to the rules defined in lib/endpoints
     *
     * @async
     * @public
     * @param {string} name - name of MWS API function to call
     * @param {object} [callOptions] - named hash object of the parameters to pass to the API
     * @param {string} [callOptions.feedContent] - if calling a function that submits a feed, supply the feed data here
     * @param {any} [callOptions....rest] - other parameters will be passed through validation and into the API
     * @param {object} [opt] - options for callEndpoint
     * @param {boolean} [opt.noFlatten] - do not flatten results
     * @param {boolean} [opt.returnRaw] - return only the raw data (may or may not be flattened)
     * @param {string} [opt.saveRaw] - filename to save raw data to (may or may not be flattened)
     * @param {string} [opt.saveParsed] - filename to save final parsed data to (not compatible with returnRaw, since parsing won't happen)
     * @param {int} [opt.maxThrottleRetries=2] - maximum number of retries for throttling
     * @returns {any} - Results of the call to MWS
     */
    async callEndpoint(name, callOptions = {}, opt = { maxThrottleRetries: 2 }) {
        const endpoint = endpoints[name];
        if (!endpoint) {
            throw new errors.InvalidUsage(`Unknown endpoint name supplied to callEndpoint, ${name}`);
        }

        const newOptions = endpoint.params
            ? validateAndTransformParameters(endpoint.params, callOptions)
            : callOptions;

        const { feedContent } = newOptions;
        delete newOptions.feedContent;

        const queryOptions = {
            ...newOptions,
            Action: endpoint.action,
            Version: endpoint.version,
        };

        const params = {
            path: `/${endpoint.category}/${endpoint.version}`,
            query: queryOptions,
            feedContent,
        };

        let q = Queues.getQueue(endpoint.category, endpoint.action, this.mws.merchantId);
        if (!q) {
            q = new Queues.Queue({
                api: this,
                category: endpoint.category,
                action: endpoint.action,
                maxInFlight: (endpoint.throttle && endpoint.throttle.maxInFlight) || 0,
                restoreRate: (endpoint.throttle && endpoint.throttle.restoreRate) || 0,
            });
            Queues.registerQueue(q, endpoint.category, endpoint.action, this.mws.merchantId);
        }
        // TODO: reduce the size of this try!
        try {
            const result = await q.request(params, { noFlatten: opt.noFlatten });
            if (opt.saveRaw) {
                fs.writeFileSync(path.join(process.cwd(), opt.saveRaw), JSON.stringify(result));
            }
            if (opt.returnRaw) {
                return result;
            }
            const digResult = digResponseResult(name, result);
            if (opt.saveParsed) {
                fs.writeFileSync(path.join(process.cwd(), opt.saveParsed), JSON.stringify(digResult));
            }
            return digResult;
        } catch (error) {
            throw error;
        }
    }

    /* eslint-disable global-require */

    // TODO: fill in documentation for getInboundGuidance*
    /**
     * Call MWS GetInboundGuidanceForASIN, return parsed results
     * @example
     */
    getInboundGuidanceForASIN(...params) {
        const { getInboundGuidanceForASIN } = require('./helpers/getInboundGuidance');
        return getInboundGuidanceForASIN(this)(...params);
    }

    static getInboundGuidanceForASIN(...params) {
        return staticMws.getInboundGuidanceForASIN(...params);
    }

    getInboundGuidanceForSKU(...params) {
        const { getInboundGuidanceForSKU } = require('./helpers/getInboundGuidance');
        return getInboundGuidanceForSKU(this)(...params);
    }

    static getInboundGuidanceForSKU(...params) {
        return staticMws.getInboundGuidanceForSKU(...params);
    }

    /**
     * Call MWS ListMarketplaceParticipations, return parsed results
     * @example
     * const marketplaces = (async () => await mws.getMarketplaces())();
     * (async function() {
     *    const result = await mws.getMarketplaces();
     *    console.log(result);
     * })();
     * @return {MarketDetail}
     */

    getMarketplaces(...params) {
        const helper = require('./helpers/getMarketplaces');
        return helper(this)(...params);
    }

    static getMarketplaces(...params) {
        return staticMws.getMarketplaces(...params);
    }

    /**
     * Return orders created or updated during a specific time frame
     * see https://docs.developer.amazonservices.com/en_UK/orders-2013-09-01/Orders_ListOrders.html
     * At least ONE of the search options (and maybe more depending on which ones you select) must be
     * specified. Error messages may or may not return information on what parameters you are missing.
     * If you are having trouble, see the official parameter documentation above.
     *
     * @param {object} options
     * @param {string[]} options.MarketplaceId Array of Marketplace IDs to search @see {@link MWS_MARKETPLACES}
     * @param {Date} [options.CreatedAfter] Select orders created at or after the given Date
     * @param {Date} [options.CreatedBefore] Select orders created at or before the given Date
     * @param {Date} [options.LastUpdatedAfter] Select orders updated at or after the given Date
     * @param {Date} [options.LastUpdatedBefore] Select orders updated at or before the given Date
     * @param {string} [options.OrderStatus] OrderStatus, see MWS doc page
     * @param {string} [options.FulfillmentChannel] AFN for Amazon fulfillment, MFN for merchant
     * @param {string} [options.PaymentMethod] All, COD, CVS, Other
     * @param {string} [options.BuyerEmail] Search for orders with given Email address
     * @param {string} [options.SellerOrderId] Specified seller order ID
     * @param {string} [options.MaxResultsPerPage=100] Max number of results to return, 1 <=> 100
     * @param {string} [options.TFMShipmentStatus] See MWS doc page
     * @returns {object}
     */
    listOrders(...params) {
        const helper = require('./helpers/listOrders');
        return helper(this)(...params);
    }

    static listOrders(...params) { return staticMws.listOrders(...params); }

    /**
     * Returns order items based on the AmazonOrderId that you specify.
     *
     * If you've pulled a list of orders using @see {@link ListOrders}, or have order identifiers
     * stored in some other fashion, then to find out what items are actually on the orders, you will
     * need to call ListOrderItems to obtain details about the items that were ordered.  The ListOrders
     * call does not give you any information about the items, except how many of them have shipped or
     * not shipped.
     *
     * If an Order is in the Pending state, ListOrderItems will not return any pricing or promotion
     * information. Once an order has left the Pending state, the following items will be returned:
     *
     * ItemTax, GiftWrapPrice, ItemPrice, PromotionDiscount, GiftWrapTax, ShippingTax, ShippingPrice,
     * ShippingDiscount
     *
     * @public
     * @param {string} AmazonOrderId - 3-7-7 Amazon Order ID formatted string
     * @returns {OrderItemList}
     */
    listOrderItems(...params) {
        const helper = require('./helpers/listOrderItems');
        return helper(this)(...params);
    }

    static listOrderItems(...params) { return staticMws.listOrderItems(...params); }

    /**
     * Return orders by ID, i.e. Amazon Order ID.
     * see https://docs.developer.amazonservices.com/en_UK/orders-2013-09-01/Orders_GetOrder.html
     *
     * @param {object} options
     * @param {string[]} options A list of AmazonOrderId values. An AmazonOrderId is an Amazon-defined order identifier, in 3-7-7 format.
     * @returns {object} A list of orders
     */
    getOrder(...params) {
        const helper = require('./helpers/getOrder');
        return helper(this)(...params);
    }

    static getOrder(...params) { return staticMws.getOrder(...params); }

    /**
     * https://docs.developer.amazonservices.com/en_UK/finances/Finances_ListFinancialEvents.html
     *
     * @param {object} options
     * @param {number} options.maxResultsPerPage Maximum number of results to return (1 <=> 100)
     * @param {string} options.amazonOrderId An order number to search for
     * @param {string} options.financialEventGroupId Type of Financial Event to search for
     * @param {Date} options.postedAfter When to search for events after
     * @param {Date} options.postedBefore When to search for events prior to
     * @returns {object}
     */
    listFinancialEvents(...params) {
        const helper = require('./helpers/listFinancialEvents');
        return helper(this)(...params);
    }

    static listFinancialEvents(...params) { return staticMws.listFinancialEvents(...params); }

    /**
     * Return information about the availability of a seller's FBA inventory
     *
     * @param {object} options
     * @param {String[]} options.sellerSkus A list of SKUs for items to get inventory info for
     * @param {Date} options.queryStartDateTime Date to begin searching at
     * @param {string} options.responseGroup 'Basic' = Do not include SupplyDetail, 'Detailed' = Do
     * @param {string} options.marketplaceId Marketplace ID to search
     *
     * @returns {{ nextToken: string, supplyList: object[] }}
     */
    listInventorySupply(...params) {
        const helper = require('./helpers/listInventorySupply');
        return helper(this)(...params);
    }

    static listInventorySupply(...params) { return staticMws.listInventorySupply(...params); }

    /**
     * Return a list of products and their attributes, based on a text query and contextId.
     *
     * @param {object} options
     * @param {string} options.marketplaceId - marketplace identifier to search
     * @param {string} options.query - a search string "with the same support as that provided on Amazon marketplace websites"
     * @param {string} [options.queryContextId] - context in which to limit search. Not specified will mean "search everywhere". See https://docs.developer.amazonservices.com/en_UK/products/Products_QueryContextIDs.html
     * @returns {Product[]} - Array of product information
     */
    listMatchingProducts(...params) {
        const helper = require('./helpers/listMatchingProducts');
        return helper(this)(...params);
    }

    static listMatchingProducts(...params) { return staticMws.listMatchingProducts(...params); }

    /**
     * Returns a list of products and their attributes, based on a list of ASIN, GCID, SellerSKU, UPC,
     * EAN, ISBN, or JAN values
     *
     * @param {Object} options see https://docs.developer.amazonservices.com/en_UK/products/Products_GetMatchingProductForId.html
     * @param {string} options.marketplaceId Identifier for marketplace (see getMarketplaces)
     * @param {string} options.idType Type of lookup to perform: ASIN, GCID, SellerSKU, UPC, EAN, ISBN, JAN
     * @param {string[]} options.idList List of codes to perform lookup on
     * @public
     * @returns {Product[]}
     */
    getMatchingProductForId(...params) {
        const helper = require('./helpers/getMatchingProduct');
        return helper(this)(...params);
    }

    static getMatchingProductForId(...params) { return staticMws.getMatchingProductForId(...params); }

    /**
     * getLowestPricedOffersForASIN
     *
     * Calls GetLowestPricedOffersForASIN, reformats results, and returns the data
     *
     * @param {object} options see https://docs.developer.amazonservices.com/en_UK/products/Products_GetLowestPricedOffersForASIN.html
     * @param {string} options.MarketplaceId Marketplace ID to search
     * @param {string} options.ASIN ASIN to search for
     * @param {string} options.ItemCondition Listing Condition: New, Used, Collectible, Refurbished, Club
     *
     * @return {LowestPricedOffers}
     */
    getLowestPricedOffersForAsin(...params) {
        const { getLowestPricedOffersForASIN } = require('./helpers/getLowestPricedOffers');
        return getLowestPricedOffersForASIN(this)(...params);
    }

    static getLowestPricedOffersForAsin(...params) {
        return staticMws.getLowestPricedOffersForAsin(...params);
    }

    /**
     * getLowestPricedOffersForSKU
     *
     * Calls GetLowestPricedOffersForSKU, reformats results, and returns the data
     *
     * @param {object} options see https://docs.developer.amazonservices.com/en_UK/products/Products_GetLowestPricedOffersForASIN.html
     * @param {string} options.MarketplaceId Marketplace ID to search
     * @param {string} options.SellerSKU SKU to search for
     * @param {string} options.ItemCondition Listing Condition: New, Used, Collectible, Refurbished, Club
     *
     * @return {LowestPricedOffers}
     */
    getLowestPricedOffersForSku(...params) {
        const { getLowestPricedOffersForSKU } = require('./helpers/getLowestPricedOffers');
        return getLowestPricedOffersForSKU(this)(...params);
    }

    static getLowestPricedOffersForSku(...params) {
        return staticMws.getLowestPricedOffersForSKU(...params);
    }

    /**
     * return product categories for multiple asins
     *
     * @param {object} parameters
     * @param {string} parameters.marketplaceId - marketplace identifier to run query on
     * @param {string[]} parameters.asins - Array of string ASINs to query for
     * @returns {productCategoryByAsin[]} - Array of product category information
     */
    getProductCategoriesForAsins(...params) {
        const { getProductCategoriesForAsins } = require('./helpers/getProductCategories');
        return getProductCategoriesForAsins(this)(...params);
    }

    static getProductCategoriesForAsins(...params) {
        return staticMws.getProductCategoriesForAsins(...params);
    }

    /**
     * return product categories for multiple SKUs
     *
     * @param {object} parameters
     * @param {string} parameters.marketplaceId - marketplace identifier to run query on
     * @param {string[]} parameters.skus - Array of string SKUs to query for
     * @returns {productCategoryBySku[]} - Array of product category information
     */
    getProductCategoriesForSkus(...params) {
        const { getProductCategoriesForSkus } = require('./helpers/getProductCategories');
        return getProductCategoriesForSkus(this)(...params);
    }

    static getProductCategoriesForSkus(...params) {
        return staticMws.getProductCategoriesForSkus(...params);
    }

    /**
     * Get an estimate of fees for an item, based on listing and shipping prices.
     *
     * @param {EstimateRequest[]} - Array of EstimateRequest items to get fees for
     * @returns {Object} - Object of Estimate items, indexed by EstimateRequest Identifier
     */
    getMyFeesEstimate(...params) {
        const helper = require('./helpers/getMyFeesEstimate');
        return helper(this)(...params);
    }

    static getMyFeesEstimate(...params) { return staticMws.getMyFeesEstimate(...params); }

    /**
     * Request a report from MWS
     * Many optional parameters may be required by MWS! Read [ReportType](https://docs.developer.amazonservices.com/en_US/reports/Reports_ReportType.html) for specifics!
     *
     * @async
     * @param {object} options
     * @param {string} options.ReportType Type of Report to Request @see {@link REQUEST_REPORT_TYPES}
     * @param {Date} [options.StartDate] Date to start report
     * @param {Date} [options.EndDate] Date to end report at
     * @param {object} [options.ReportOptions] Reports may have additional options available. Please see the [ReportType](https://docs.developer.amazonservices.com/en_US/reports/Reports_ReportType.html) official docs
     * @param {string[]} [MarketplaceId] Array of marketplace IDs to generate reports covering
     * @returns {ReportRequestInfo}
     */
    requestReport(...params) {
        const { requestReport: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static requestReport(...params) { return staticMws.requestReport(...params); }

    /**
     * Returns a list of report requests that you can use to get the ReportRequestId for a report
     * After calling requestReport, you should call this function occasionally to see if/when the report
     * has been processed.
     *
     * @async
     * @param {object} [options] Options to pass to GetReportRequestList
     * @param {string[]} [ReportRequestIdList] List of report request IDs @see {@link requestReport}
     * @param {string[]} [ReportTypeList] List of Report Types @see {@link REQUEST_REPORT_TYPES}
     * @param {string[]} [ReportProcessingStatusList] List of Report Processing
     * Status @see {@link REPORT_PROCESSING_STATUS_TYPES}
     * @param {number} [MaxCount=10] Maximum number of report requests to return, max is 100
     * @param {Date} [RequestedFromDate=90-days-past] Oldest date to search for
     * @param {Date} [RequestedToDate=Now] Newest date to search for
     * @returns {GetReportRequestListResult[]}
     */
    getReportRequestList(...params) {
        const { getReportRequestList: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static getReportRequestList(...params) { return staticMws.getReportRequestList(...params); }

    /**
     * Download a specific report identified by the ReportId and return it
     *
     * @async
     * @function getReport
     * @example mws.getReport({ ReportId: '12660293969017879' });
     *
     * @param {object} options - GetReport options, should contain a [ReportId]
     * @param {string} options.ReportId - Report number from [GetReportList] or [GeneratedReportId] from [GetReportRequestListResult]
     * @returns {(Array|object)} - Contents of the report to return (format may vary WIDELY between different reports generated, see [ReportType](https://docs.developer.amazonservices.com/en_US/reports/Reports_ReportType.html))
     */
    getReport(options) {
        const { getReport: helper } = require('./helpers/reports');
        return helper(this)(options);
    }

    static getReport(...params) { return staticMws.getReport(...params); }

    /**
     * TODO: write documentation for getReportList
    */
    getReportList(...params) {
        const { getReportList: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static getReportList(...params) { return staticMws.getReportList(...params); }

    /**
     * TODO: write documentation for getReportListByNextToken
     * (or just roll getReportList and getReportListByNextToken into the same wrapper)
     * (that wrapper might be getReportListAll, and just rename it)
     */
    getReportListByNextToken(...params) {
        const { getReportListByNextToken: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static getReportListByNextToken(...params) {
        return staticMws.getReportListByNextToken(...params);
    }

    /**
     * TODO: write documentation for getReportListAll (or see comment on getReportListByNextToken)
    */
    getReportListAll(...params) {
        const { getReportListAll: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static getReportListAll(...params) { return staticMws.getReportListAll(...params); }

    /**
     * TODO: Document requestAndDownloadReport
    */
    requestAndDownloadReport(...params) {
        const { requestAndDownloadReport: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static requestAndDownloadReport(...params) {
        return staticMws.requestAndDownloadReport(...params);
    }

    /**
     * TO DO: WRITE DOCUMENTATION
     */
    manageReportSchedule(...params) {
        const { manageReportSchedule: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static manageReportSchedule(...params) { return staticMws.manageReportSchedule(...params); }

    /**
     * TO DO: WRITE DOCUMENTATION
     */
    updateReportAcknowledgements(...params) {
        const { updateReportAcknowledgements: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static updateReportAcknowledgements(...params) {
        return staticMws.updateReportAcknowledgements(...params);
    }

    /**
     * TO DO: WRITE DOCUMENTATION
     */
    getReportScheduleList(...params) {
        const { getReportScheduleList: helper } = require('./helpers/reports');
        return helper(this)(...params);
    }

    static getReportScheduleList(...params) {
        return staticMws.getReportScheduleList(...params);
    }

    /* eslint-enable global-require */
}

MwsAdvanced.constants = constants;
module.exports = MwsAdvanced;
// module.exports.constants = constants;