<commit_before>// # Update Checking Service
//
// Makes a request to Ghost.org to check if there is a new version of Ghost available.
// The service is provided in return for users opting in to anonymous usage data collection
// Blog owners can opt-out of update checks by setting 'updateCheck: false' in their config.js
//
// The data collected is as follows:
// - blog id - a hash of the blog hostname, pathname and dbHash, we do not store URL, IP or other identifiable info
// - ghost version
// - node version
// - npm version
// - env - production or development
// - database type - SQLite, MySQL, pg
// - email transport - mail.options.service, or otherwise mail.transport
// - created date - the date the database was created
// - post count - total number of posts
// - user count - total number of users
// - theme - name of the currently active theme
// - apps - names of any active apps

var crypto   = require('crypto'),
    exec     = require('child_process').exec,
    https    = require('https'),
    moment   = require('moment'),
    semver   = require('semver'),
    when     = require('when'),
    nodefn   = require('when/node/function'),
    _        = require('lodash'),
    url      = require('url'),

    api      = require('./api'),
    config   = require('./config'),
    errors   = require('./errorHandling'),
    packageInfo = require('../../package.json'),

    allowedCheckEnvironments = ['development', 'production'],
    checkEndpoint = 'updates.ghost.org',
    currentVersion = packageInfo.version;

function updateCheckError(error) {
    errors.logError(
        error,
        "Checking for updates failed, your blog will continue to function.",
        "If you get this error repeatedly, please seek help from https://ghost.org/forum."
    );
}

function updateCheckData() {
    var data = {},
        ops = [],
        mailConfig = config().mail;

    ops.push(api.settings.read.call({ internal: true }, 'dbHash').otherwise(errors.rejectError));
    ops.push(api.settings.read.call({ internal: true }, 'activeTheme').otherwise(errors.rejectError));
    ops.push(api.settings.read.call({ internal: true }, 'activeApps')
        .then(function (response) {
            var apps = response.settings[0];
            try {
                apps = JSON.parse(apps.value);
            } catch (e) {
                return errors.rejectError(e);
            }

            return _.reduce(apps, function (memo, item) { return memo === '' ? memo + item : memo + ', ' + item; }, '');
        }).otherwise(errors.rejectError));
    ops.push(api.posts.browse().otherwise(errors.rejectError));
    ops.push(api.users.browse.call({user: 1}).otherwise(errors.rejectError));
    ops.push(nodefn.call(exec, 'npm -v').otherwise(errors.rejectError));

    data.ghost_version   = currentVersion;
    data.node_version    = process.versions.node;
    data.env             = process.env.NODE_ENV;
    data.database_type   = require('./models/base').client;
    data.email_transport = mailConfig && (mailConfig.options && mailConfig.options.service ? mailConfig.options.service : mailConfig.transport);

    return when.settle(ops).then(function (descriptors) {
        var hash             = descriptors[0].value.settings[0],
            theme            = descriptors[1].value.settings[0],
            apps             = descriptors[2].value,
            posts            = descriptors[3].value,
            users            = descriptors[4].value,
            npm              = descriptors[5].value,
            blogUrl          = url.parse(config().url),
            blogId           = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;

        data.blog_id         = crypto.createHash('md5').update(blogId).digest('hex');
        data.theme           = theme ? theme.value : '';
        data.apps            = apps || '';
        data.post_count      = posts && posts.meta && posts.meta.pagination ? posts.meta.pagination.total : 0;
        data.user_count      = users && users.users && users.users.length ? users.users.length : 0;
        data.blog_created_at = users && users.users && users.users[0] && users.users[0].created_at ? moment(users.users[0].created_at).unix() : '';
        data.npm_version     = _.isArray(npm) && npm[0] ? npm[0].toString().replace(/\n/, '') : '';

        return data;
    }).otherwise(updateCheckError);
}

function updateCheckRequest() {
    return updateCheckData().then(function (reqData) {
        var deferred = when.defer(),
            resData = '',
            headers,
            req;

        reqData = JSON.stringify(reqData);

        headers = {
            'Content-Length': reqData.length
        };

        req = https.request({
            hostname: checkEndpoint,
            method: 'POST',
            headers: headers
        }, function (res) {
            res.on('error', function (error) { deferred.reject(error); });
            res.on('data', function (chunk) { resData += chunk; });
            res.on('end', function () {
                try {
                    resData = JSON.parse(resData);
                    deferred.resolve(resData);
                } catch (e) {
                    deferred.reject('Unable to decode update response');
                }
            });
        });

        req.write(reqData);
        req.end();

        req.on('error', function (error) {
            deferred.reject(error);
        });

        return deferred.promise;
    });
}

// ## Update Check Response
// Handles the response from the update check
// Does two things with the information received:
// 1. Updates the time we can next make a check
// 2. Checks if the version in the response is new, and updates the notification setting
function updateCheckResponse(response) {
    var ops = [];

    ops.push(api.settings.edit.call({user: 1}, 'nextUpdateCheck', response.next_check)
        .otherwise(errors.rejectError));

    ops.push(api.settings.edit.call({user: 1}, 'displayUpdateNotification', response.version)
                .otherwise(errors.rejectError));

    return when.settle(ops).then(function (descriptors) {
        descriptors.forEach(function (d) {
            if (d.state === 'rejected') {
                errors.rejectError(d.reason);
            }
        });
        return when.resolve();
    });
}

function updateCheck() {
    var deferred = when.defer();

    // The check will not happen if:
    // 1. updateCheck is defined as false in config.js
    // 2. we've already done a check this session
    // 3. we're not in production or development mode
    if (config().updateCheck === false || _.indexOf(allowedCheckEnvironments, process.env.NODE_ENV) === -1) {
        // No update check
        deferred.resolve();
    } else {
        api.settings.read.call({ internal: true }, 'nextUpdateCheck').then(function (result) {
            var nextUpdateCheck = result.settings[0];

            if (nextUpdateCheck && nextUpdateCheck.value && nextUpdateCheck.value > moment().unix()) {
                // It's not time to check yet
                deferred.resolve();
            } else {
                // We need to do a check
                return updateCheckRequest()
                    .then(updateCheckResponse)
                    .otherwise(updateCheckError);
            }
        }).otherwise(updateCheckError)
            .then(deferred.resolve);
    }

    return deferred.promise;
}

function showUpdateNotification() {
    return api.settings.read.call({ internal: true }, 'displayUpdateNotification').then(function (response) {
        var display = response.settings[0];

        // Version 0.4 used boolean to indicate the need for an update. This special case is
        // translated to the version string.
        // TODO: remove in future version.
        if (display.value === 'false' || display.value === 'true' || display.value === '1' || display.value === '0') {
            display.value = '0.4.0';
        }

        if (display && display.value && currentVersion && semver.gt(display.value, currentVersion)) {
            return when(true);
        }
        return when(false);
    });
}

module.exports = updateCheck;
module.exports.showUpdateNotification = showUpdateNotification;
<commit_msg>Fix unhandled rejected promises when using admin<commit_after>// # Update Checking Service
//
// Makes a request to Ghost.org to check if there is a new version of Ghost available.
// The service is provided in return for users opting in to anonymous usage data collection
// Blog owners can opt-out of update checks by setting 'updateCheck: false' in their config.js
//
// The data collected is as follows:
// - blog id - a hash of the blog hostname, pathname and dbHash, we do not store URL, IP or other identifiable info
// - ghost version
// - node version
// - npm version
// - env - production or development
// - database type - SQLite, MySQL, pg
// - email transport - mail.options.service, or otherwise mail.transport
// - created date - the date the database was created
// - post count - total number of posts
// - user count - total number of users
// - theme - name of the currently active theme
// - apps - names of any active apps

var crypto   = require('crypto'),
    exec     = require('child_process').exec,
    https    = require('https'),
    moment   = require('moment'),
    semver   = require('semver'),
    when     = require('when'),
    nodefn   = require('when/node/function'),
    _        = require('lodash'),
    url      = require('url'),

    api      = require('./api'),
    config   = require('./config'),
    errors   = require('./errorHandling'),
    packageInfo = require('../../package.json'),

    allowedCheckEnvironments = ['development', 'production'],
    checkEndpoint = 'updates.ghost.org',
    currentVersion = packageInfo.version;

function updateCheckError(error) {
    errors.logError(
        error,
        "Checking for updates failed, your blog will continue to function.",
        "If you get this error repeatedly, please seek help from https://ghost.org/forum."
    );
}

function updateCheckData() {
    var data = {},
        ops = [],
        mailConfig = config().mail;

    ops.push(api.settings.read.call({ internal: true }, 'dbHash').otherwise(errors.rejectError));
    ops.push(api.settings.read.call({ internal: true }, 'activeTheme').otherwise(errors.rejectError));
    ops.push(api.settings.read.call({ internal: true }, 'activeApps')
        .then(function (response) {
            var apps = response.settings[0];
            try {
                apps = JSON.parse(apps.value);
            } catch (e) {
                return errors.rejectError(e);
            }

            return _.reduce(apps, function (memo, item) { return memo === '' ? memo + item : memo + ', ' + item; }, '');
        }).otherwise(errors.rejectError));
    ops.push(api.posts.browse().otherwise(errors.rejectError));
    ops.push(api.users.browse.call({user: 1}).otherwise(errors.rejectError));
    ops.push(nodefn.call(exec, 'npm -v').otherwise(errors.rejectError));

    data.ghost_version   = currentVersion;
    data.node_version    = process.versions.node;
    data.env             = process.env.NODE_ENV;
    data.database_type   = require('./models/base').client;
    data.email_transport = mailConfig && (mailConfig.options && mailConfig.options.service ? mailConfig.options.service : mailConfig.transport);

    return when.settle(ops).then(function (descriptors) {
        var hash             = descriptors[0].value.settings[0],
            theme            = descriptors[1].value.settings[0],
            apps             = descriptors[2].value,
            posts            = descriptors[3].value,
            users            = descriptors[4].value,
            npm              = descriptors[5].value,
            blogUrl          = url.parse(config().url),
            blogId           = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;

        data.blog_id         = crypto.createHash('md5').update(blogId).digest('hex');
        data.theme           = theme ? theme.value : '';
        data.apps            = apps || '';
        data.post_count      = posts && posts.meta && posts.meta.pagination ? posts.meta.pagination.total : 0;
        data.user_count      = users && users.users && users.users.length ? users.users.length : 0;
        data.blog_created_at = users && users.users && users.users[0] && users.users[0].created_at ? moment(users.users[0].created_at).unix() : '';
        data.npm_version     = _.isArray(npm) && npm[0] ? npm[0].toString().replace(/\n/, '') : '';

        return data;
    }).otherwise(updateCheckError);
}

function updateCheckRequest() {
    return updateCheckData().then(function (reqData) {
        var deferred = when.defer(),
            resData = '',
            headers,
            req;

        reqData = JSON.stringify(reqData);

        headers = {
            'Content-Length': reqData.length
        };

        req = https.request({
            hostname: checkEndpoint,
            method: 'POST',
            headers: headers
        }, function (res) {
            res.on('error', function (error) { deferred.reject(error); });
            res.on('data', function (chunk) { resData += chunk; });
            res.on('end', function () {
                try {
                    resData = JSON.parse(resData);
                    deferred.resolve(resData);
                } catch (e) {
                    deferred.reject('Unable to decode update response');
                }
            });
        });

        req.write(reqData);
        req.end();

        req.on('error', function (error) {
            deferred.reject(error);
        });

        return deferred.promise;
    });
}

// ## Update Check Response
// Handles the response from the update check
// Does two things with the information received:
// 1. Updates the time we can next make a check
// 2. Checks if the version in the response is new, and updates the notification setting
function updateCheckResponse(response) {
    var ops = [];

    ops.push(api.settings.edit.call({internal: true}, 'nextUpdateCheck', response.next_check)
        .otherwise(errors.rejectError));

    ops.push(api.settings.edit.call({internal: true}, 'displayUpdateNotification', response.version)
                .otherwise(errors.rejectError));

    return when.settle(ops).then(function (descriptors) {
        descriptors.forEach(function (d) {
            if (d.state === 'rejected') {
                errors.rejectError(d.reason);
            }
        });
        return when.resolve();
    });
}

function updateCheck() {
    var deferred = when.defer();

    // The check will not happen if:
    // 1. updateCheck is defined as false in config.js
    // 2. we've already done a check this session
    // 3. we're not in production or development mode
    if (config().updateCheck === false || _.indexOf(allowedCheckEnvironments, process.env.NODE_ENV) === -1) {
        // No update check
        deferred.resolve();
    } else {
        api.settings.read.call({ internal: true }, 'nextUpdateCheck').then(function (result) {
            var nextUpdateCheck = result.settings[0];

            if (nextUpdateCheck && nextUpdateCheck.value && nextUpdateCheck.value > moment().unix()) {
                // It's not time to check yet
                deferred.resolve();
            } else {
                // We need to do a check
                return updateCheckRequest()
                    .then(updateCheckResponse)
                    .otherwise(updateCheckError);
            }
        }).otherwise(updateCheckError)
            .then(deferred.resolve);
    }

    return deferred.promise;
}

function showUpdateNotification() {
    return api.settings.read.call({ internal: true }, 'displayUpdateNotification').then(function (response) {
        var display = response.settings[0];

        // Version 0.4 used boolean to indicate the need for an update. This special case is
        // translated to the version string.
        // TODO: remove in future version.
        if (display.value === 'false' || display.value === 'true' || display.value === '1' || display.value === '0') {
            display.value = '0.4.0';
        }

        if (display && display.value && currentVersion && semver.gt(display.value, currentVersion)) {
            return when(true);
        }
        return when(false);
    });
}

module.exports = updateCheck;
module.exports.showUpdateNotification = showUpdateNotification;
<|endoftext|>


<commit_before>'use strict'

// external deps
var ObjectId = require("mongodb").ObjectId;

// internal deps
require('mongodb-toolkit');
var DLModels = require('dl-models');
var map = DLModels.map;
var PurchaseOrderExternal = DLModels.purchasing.PurchaseOrderExternal;
var PurchaseOrderManager = require('./purchase-order-manager');
var BaseManager = require('../base-manager');
var generateCode = require('../../utils/code-generator');

module.exports = class PurchaseOrderExternalManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.purchasing.collection.PurchaseOrderExternal);
        this.year = (new Date()).getFullYear().toString().substring(2, 4);
        this.purchaseOrderManager = new PurchaseOrderManager(db, user);
    }

    _getQuery(paging) {
        var filter = {
            _deleted: false
        };

        var query = paging.keyword ? {
            '$and': [filter]
        } : filter;

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");

            var filterPODLNo = {
                'no': {
                    '$regex': regex
                }
            };
            var filterSupplierName = {
                'supplier.name': {
                    '$regex': regex
                }
            };

            var $or = {
                '$or': [filterPODLNo, filterSupplierName]
            };

            query['$and'].push($or);
        }
        return query;
    }

    create(purchaseOrderExternal) {
        return new Promise((resolve, reject) => {
            this._validate(purchaseOrderExternal)
                .then(validPurchaseOrderExternal => {
                    validPurchaseOrderExternal.no = this.generatePOno();
                    this.collection.insert(validPurchaseOrderExternal)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    _validate(purchaseOrderGroup) {
        var purchaseOrderExternalError = {};
        return new Promise((resolve, reject) => {
            var valid = purchaseOrderGroup;

            if (!valid.supplierId || valid.supplierId.toString() == '')
                purchaseOrderExternalError["supplierId"] = "Nama Supplier tidak boleh kosong";

            if (!valid.expectedDeliveryDate || valid.expectedDeliveryDate == '')
                purchaseOrderExternalError["expectedDeliveryDate"] = "Tanggal tersedia tidak boleh kosong";

            if (!valid.date || valid.date == '')
                purchaseOrderExternalError["date"] = "Tanggal tidak boleh kosong";

            if (!valid.paymentMethod || valid.paymentMethod == '')
                purchaseOrderExternalError["paymentMethod"] = "Metode Pembayaran tidak boleh kosong";

            if ((valid.currency.toUpperCase() !="IDR") && !valid.currencyRate || valid.currencyRate == 0)
                purchaseOrderExternalError["currencyRate"] = "Rate tidak boleh kosong";

            if ((valid.paymentMethod.toUpperCase() !="CASH") && !valid.paymentDueDays || valid.paymentDueDays == '')
                purchaseOrderExternalError["paymentDueDays"] = "Tempo Pembayaran tidak boleh kosong";

            // if (valid.useVat == undefined || valid.useVat.toString() === '')
            //     purchaseOrderExternalError["useVat"] = "Pengenaan PPn harus dipilih";

            // if (valid.useIncomeTax == undefined || valid.useIncomeTax.toString() === '')
            //     purchaseOrderExternalError["useIncomeTax"] = "Pengenaan PPh harus dipilih";

            if (valid.items && valid.items.length < 1)
                purchaseOrderExternalError["items"] = "Harus ada minimal 1 po internal";
            else {
                var purchaseOrderExternalItemErrors = [];
                var poItemExternalHasError = false;
                for (var purchaseOrder of valid.items) {
                    var purchaseOrderError = {};
                    var purchaseOrderItemErrors = [];
                    var poItemHasError = false;

                    if (!purchaseOrder.no || purchaseOrder.no == "") {
                        poItemHasError = true;
                        purchaseOrderError["no"] = "Purchase order internal tidak boleh kosong";
                    }

                    for (var poItem of purchaseOrder.items || []) {
                        var poItemError = {};
                        if (!poItem.dealQuantity || poItem.dealQuantity == 0) {
                            poItemHasError = true;
                            poItemError["dealQuantity"] = "Jumlah kesepakatan tidak boleh kosong";
                        }
                        if (!poItem.dealUom || !poItem.dealUom.unit || poItem.dealUom.unit == "") {
                            poItemHasError = true;
                            poItemError["dealUom"] = "Jumlah kesepakatan tidak boleh kosong";
                        }
                        if (!poItem.pricePerDealUnit || poItem.pricePerDealUnit == 0) {
                            poItemHasError = true;
                            poItemError["pricePerDealUnit"] = "Harga tidak boleh kosong";
                        }

                        // if (!poItem.conversion || poItem.conversion == '') {
                        //     poItemHasError = true;
                        //     poItemError["conversion"] = "Konversi tidak boleh kosong";
                        // }

                        purchaseOrderItemErrors.push(poItemError);
                    }
                    if (poItemHasError) {
                        poItemExternalHasError = true;
                        purchaseOrderError["items"] = purchaseOrderItemErrors;
                    }

                    purchaseOrderExternalItemErrors.push(purchaseOrderError);
                }
                if (poItemExternalHasError)
                    purchaseOrderExternalError["items"] = purchaseOrderExternalItemErrors;
            }

            // 2c. begin: check if data has any error, reject if it has.
            for (var prop in purchaseOrderExternalError) {
                var ValidationError = require('../../validation-error');
                reject(new ValidationError('data podl does not pass validation', purchaseOrderExternalError));
            }

            if (!valid.stamp)
                valid = new PurchaseOrderExternal(valid);

            valid.stamp(this.user.username, 'manager');
            resolve(valid);
        });
    }

    post(listPurchaseOrderExternal) {
        var tasks = [];
        return new Promise((resolve, reject) => {
            for (var purchaseOrderExternal of listPurchaseOrderExternal) {
                for (var data of purchaseOrderExternal.items) {
                    var getPOItemById = this.purchaseOrderManager.getSingleById(data._id);
                    Promise.all([getPOItemById])
                        .then(results => {
                            for (var result of results) {
                                var poItem = result;
                                poItem.purchaseOrderExternalId = data._id;
                                poItem.purchaseOrderExternal = data;
                                poItem.supplierId = data.supplierId;
                                poItem.supplier = data.supplier;
                                poItem.freightCostBy = data.freightCostBy;
                                poItem.pricePerDealUnit = data.pricePerDealUnit;
                                poItem.paymentMethod = data.paymentMethod;
                                poItem.paymentDueDays = data.paymentDueDays;
                                poItem.useVat = data.useVat;
                                poItem.vatRate = data.vatRate;
                                poItem.useIncomeTax = data.useIncomeTax;
                                poItem.isPosted = true;
                                tasks.push(this.purchaseOrderManager.update(poItem));
                            }
                        })
                        .catch(e => {
                            reject(e);
                        })
                }
            }
            purchaseOrderExternal.isPosted = true;
            tasks.push(this.update(purchaseOrderExternal));
            Promise.all(tasks)
                .then(result => {
                    resolve(result);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    generatePOno() {
        var now = new Date();
        var stamp = now / 1000 | 0;
        var code = stamp.toString().substring(0,3);
        var year = now.getFullYear();
        var month = now.getMonth();
        var initial = 'AS';
        var div = "UMUM";
        var unit = '';
        switch (div.toUpperCase().trim()) {
            case "UMUM":
                unit = 'PBL.A';
                break;
            case 'UTILITY':
                unit = 'PBL.C';
                break;
            case "FINISHING&PRINTING":
                unit = 'PBL.D';
                break;
            case 'WEAVING':
                unit = 'PBL.E';
                break;
            case "SPINNING":
                unit = 'PBL.F';
                break;
            default:
                unit = "PBL.X";
        }
        var no = `${code}/DL-${unit}/PO-${initial}/${month}/${year}`;
        return no;
    }
}
<commit_msg>fix multiple post<commit_after>'use strict'

// external deps
var ObjectId = require("mongodb").ObjectId;

// internal deps
require('mongodb-toolkit');
var DLModels = require('dl-models');
var map = DLModels.map;
var PurchaseOrderExternal = DLModels.purchasing.PurchaseOrderExternal;
var PurchaseOrderManager = require('./purchase-order-manager');
var BaseManager = require('../base-manager');
var generateCode = require('../../utils/code-generator');

module.exports = class PurchaseOrderExternalManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.purchasing.collection.PurchaseOrderExternal);
        this.year = (new Date()).getFullYear().toString().substring(2, 4);
        this.purchaseOrderManager = new PurchaseOrderManager(db, user);
    }

    _getQuery(paging) {
        var filter = {
            _deleted: false
        };

        var query = paging.keyword ? {
            '$and': [filter]
        } : filter;

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");

            var filterPODLNo = {
                'no': {
                    '$regex': regex
                }
            };
            var filterSupplierName = {
                'supplier.name': {
                    '$regex': regex
                }
            };

            var $or = {
                '$or': [filterPODLNo, filterSupplierName]
            };

            query['$and'].push($or);
        }
        return query;
    }

    create(purchaseOrderExternal) {
        return new Promise((resolve, reject) => {
            this._validate(purchaseOrderExternal)
                .then(validPurchaseOrderExternal => {
                    validPurchaseOrderExternal.no = this.generatePOno();
                    this.collection.insert(validPurchaseOrderExternal)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    _validate(purchaseOrderGroup) {
        var purchaseOrderExternalError = {};
        return new Promise((resolve, reject) => {
            var valid = purchaseOrderGroup;

            if (!valid.supplierId || valid.supplierId.toString() == '')
                purchaseOrderExternalError["supplierId"] = "Nama Supplier tidak boleh kosong";

            if (!valid.expectedDeliveryDate || valid.expectedDeliveryDate == '')
                purchaseOrderExternalError["expectedDeliveryDate"] = "Tanggal tersedia tidak boleh kosong";

            if (!valid.date || valid.date == '')
                purchaseOrderExternalError["date"] = "Tanggal tidak boleh kosong";

            if (!valid.paymentMethod || valid.paymentMethod == '')
                purchaseOrderExternalError["paymentMethod"] = "Metode Pembayaran tidak boleh kosong";

            if ((valid.currency.toUpperCase() !="IDR") && !valid.currencyRate || valid.currencyRate == 0)
                purchaseOrderExternalError["currencyRate"] = "Rate tidak boleh kosong";

            if ((valid.paymentMethod.toUpperCase() !="CASH") && !valid.paymentDueDays || valid.paymentDueDays == '')
                purchaseOrderExternalError["paymentDueDays"] = "Tempo Pembayaran tidak boleh kosong";

            // if (valid.useVat == undefined || valid.useVat.toString() === '')
            //     purchaseOrderExternalError["useVat"] = "Pengenaan PPn harus dipilih";

            // if (valid.useIncomeTax == undefined || valid.useIncomeTax.toString() === '')
            //     purchaseOrderExternalError["useIncomeTax"] = "Pengenaan PPh harus dipilih";

            if (valid.items && valid.items.length < 1)
                purchaseOrderExternalError["items"] = "Harus ada minimal 1 po internal";
            else {
                var purchaseOrderExternalItemErrors = [];
                var poItemExternalHasError = false;
                for (var purchaseOrder of valid.items) {
                    var purchaseOrderError = {};
                    var purchaseOrderItemErrors = [];
                    var poItemHasError = false;

                    if (!purchaseOrder.no || purchaseOrder.no == "") {
                        poItemHasError = true;
                        purchaseOrderError["no"] = "Purchase order internal tidak boleh kosong";
                    }

                    for (var poItem of purchaseOrder.items || []) {
                        var poItemError = {};
                        if (!poItem.dealQuantity || poItem.dealQuantity == 0) {
                            poItemHasError = true;
                            poItemError["dealQuantity"] = "Jumlah kesepakatan tidak boleh kosong";
                        }
                        if (!poItem.dealUom || !poItem.dealUom.unit || poItem.dealUom.unit == "") {
                            poItemHasError = true;
                            poItemError["dealUom"] = "Jumlah kesepakatan tidak boleh kosong";
                        }
                        if (!poItem.pricePerDealUnit || poItem.pricePerDealUnit == 0) {
                            poItemHasError = true;
                            poItemError["pricePerDealUnit"] = "Harga tidak boleh kosong";
                        }

                        // if (!poItem.conversion || poItem.conversion == '') {
                        //     poItemHasError = true;
                        //     poItemError["conversion"] = "Konversi tidak boleh kosong";
                        // }

                        purchaseOrderItemErrors.push(poItemError);
                    }
                    if (poItemHasError) {
                        poItemExternalHasError = true;
                        purchaseOrderError["items"] = purchaseOrderItemErrors;
                    }

                    purchaseOrderExternalItemErrors.push(purchaseOrderError);
                }
                if (poItemExternalHasError)
                    purchaseOrderExternalError["items"] = purchaseOrderExternalItemErrors;
            }

            // 2c. begin: check if data has any error, reject if it has.
            for (var prop in purchaseOrderExternalError) {
                var ValidationError = require('../../validation-error');
                reject(new ValidationError('data podl does not pass validation', purchaseOrderExternalError));
            }

            if (!valid.stamp)
                valid = new PurchaseOrderExternal(valid);

            valid.stamp(this.user.username, 'manager');
            resolve(valid);
        });
    }

    post(listPurchaseOrderExternal) {
        var tasks = [];
        return new Promise((resolve, reject) => {
            for (var purchaseOrderExternal of listPurchaseOrderExternal) {
                for (var data of purchaseOrderExternal.items) {
                    var getPOItemById = this.purchaseOrderManager.getSingleById(data._id);
                    Promise.all([getPOItemById])
                        .then(results => {
                            for (var result of results) {
                                var poItem = result;
                                poItem.purchaseOrderExternalId = data._id;
                                poItem.purchaseOrderExternal = data;
                                poItem.supplierId = data.supplierId;
                                poItem.supplier = data.supplier;
                                poItem.freightCostBy = data.freightCostBy;
                                poItem.pricePerDealUnit = data.pricePerDealUnit;
                                poItem.paymentMethod = data.paymentMethod;
                                poItem.paymentDueDays = data.paymentDueDays;
                                poItem.useVat = data.useVat;
                                poItem.vatRate = data.vatRate;
                                poItem.useIncomeTax = data.useIncomeTax;
                                poItem.isPosted = true;
                                tasks.push(this.purchaseOrderManager.update(poItem));
                            }
                        })
                        .catch(e => {
                            reject(e);
                        })
                }
                purchaseOrderExternal.isPosted = true;
                tasks.push(this.update(purchaseOrderExternal));
            }
            Promise.all(tasks)
                .then(result => {
                    resolve(result);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    generatePOno() {
        var now = new Date();
        var stamp = now / 1000 | 0;
        var code = stamp.toString().substring(0,3);
        var year = now.getFullYear();
        var month = now.getMonth();
        var initial = 'AS';
        var div = "UMUM";
        var unit = '';
        switch (div.toUpperCase().trim()) {
            case "UMUM":
                unit = 'PBL.A';
                break;
            case 'UTILITY':
                unit = 'PBL.C';
                break;
            case "FINISHING&PRINTING":
                unit = 'PBL.D';
                break;
            case 'WEAVING':
                unit = 'PBL.E';
                break;
            case "SPINNING":
                unit = 'PBL.F';
                break;
            default:
                unit = "PBL.X";
        }
        var no = `${code}/DL-${unit}/PO-${initial}/${month}/${year}`;
        return no;
    }
}
<|endoftext|>


<commit_before>import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMeetingSeriesEditor } from './helpers/E2EMeetingSeriesEditor'
import { E2EMinutes } from './helpers/E2EMinutes'
import { E2ETopics } from './helpers/E2ETopics'

describe('Topics Responsibles', function () {
    const aProjectName = "E2E Topics Responsibles";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect (E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;

        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
    });

    before("reload page", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.launchApp();
        }
    });

    after("clear database", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.resetMyApp(true);
        }
    });

    it('can add a responsible to a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        E2ETopics.addTopicToMinutes('TOP-1', user1);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
    });

    it('can add two responsibles to a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        let user2 = E2EGlobal.SETTINGS.e2eTestUsers[1];
        E2ETopics.addTopicToMinutes('TOP-1', user1+","+user2);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
        expect (topicHeadingText).to.contain(user2);
    });

    it('can remove a responsible from a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        let user2 = E2EGlobal.SETTINGS.e2eTestUsers[1];
        E2ETopics.addTopicToMinutes('TOP-1', user1+","+user2);

        E2ETopics.openEditTopicForMinutes(1);
        browser.element(".select2-selection__choice__remove").click();  // remove first user
        browser.element(".select2-selection").click();
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime();

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user2);
    });

    it('can add arbitrary free text responsible name', function () {
        let username = "Max Mustermann";
        E2ETopics.addTopicToMinutes('TOP-1', username);
        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(username);
    });

    it('can add a responsible from the participant users', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        E2ETopics.addTopicToMinutes('TOP-1', "");

        E2ETopics.openEditTopicForMinutes(1);
        browser.element(".select2-selection").click();
        E2EGlobal.waitSomeTime();
        browser.keys("1\uE015\uE007");  // "1" (end of user1 string) + CursorDown + Enter
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime(500);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
    });

    it('can add a responsible from user collection that is not a participant', function () {
        let user3 = E2EGlobal.SETTINGS.e2eTestUsers[2];
        E2ETopics.addTopicToMinutes('TOP-1', "");

        E2ETopics.openEditTopicForMinutes(1);
        E2EGlobal.waitSomeTime();
        browser.element(".select2-selection").click();
        browser.keys("3\uE015\uE007");  // "3" (end of user3 string) + CursorDown + Enter
        E2EGlobal.waitSomeTime();
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime(500);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user3);
    });

    it('can add a responsible from drop-down that is an additional participant', function () {
        let additionalParticipant = "Additional Participant";
        browser.setValue('#edtParticipantsAdditional', additionalParticipant);

        E2ETopics.addTopicToMinutes('TOP-1', "");

        E2ETopics.openEditTopicForMinutes(1);
        E2EGlobal.waitSomeTime();
        browser.element(".select2-selection").click();
        // We only send the beginning of the name, to ensure the drop-down is used for selection!
        browser.keys("Add\uE015\uE007");  // + CursorDown + Enter
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime();

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(additionalParticipant);
    });
});
<commit_msg>Add screenshots to track down the cause for a failing test<commit_after>import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMeetingSeriesEditor } from './helpers/E2EMeetingSeriesEditor'
import { E2EMinutes } from './helpers/E2EMinutes'
import { E2ETopics } from './helpers/E2ETopics'

describe('Topics Responsibles', function () {
    const aProjectName = "E2E Topics Responsibles";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect (E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;

        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
    });

    before("reload page", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.launchApp();
        }
    });

    after("clear database", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.resetMyApp(true);
        }
    });

    it('can add a responsible to a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        E2ETopics.addTopicToMinutes('TOP-1', user1);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
    });

    it('can add two responsibles to a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        let user2 = E2EGlobal.SETTINGS.e2eTestUsers[1];
        E2ETopics.addTopicToMinutes('TOP-1', user1+","+user2);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
        expect (topicHeadingText).to.contain(user2);
    });

    it('can remove a responsible from a topic', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        let user2 = E2EGlobal.SETTINGS.e2eTestUsers[1];
        E2ETopics.addTopicToMinutes('TOP-1', user1+","+user2);

        E2ETopics.openEditTopicForMinutes(1);
        browser.element(".select2-selection__choice__remove").click();  // remove first user
        browser.element(".select2-selection").click();
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime();

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user2);
    });

    it('can add arbitrary free text responsible name', function () {
        let username = "Max Mustermann";
        E2ETopics.addTopicToMinutes('TOP-1', username);
        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(username);
    });

    it('can add a responsible from the participant users', function () {
        let user1 = E2EGlobal.SETTINGS.e2eTestUsers[0];
        E2ETopics.addTopicToMinutes('TOP-1', "");

        E2ETopics.openEditTopicForMinutes(1);
        browser.element(".select2-selection").click();
        E2EGlobal.waitSomeTime();
        browser.keys("1\uE015\uE007");  // "1" (end of user1 string) + CursorDown + Enter
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime(500);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user1);
    });

    it('can add a responsible from user collection that is not a participant', function () {
        let user3 = E2EGlobal.SETTINGS.e2eTestUsers[2];
        E2ETopics.addTopicToMinutes('TOP-1', "");

        E2ETopics.openEditTopicForMinutes(1);
        E2EGlobal.waitSomeTime();
        browser.element(".select2-selection").click();
        browser.keys("3\uE015\uE007");  // "3" (end of user3 string) + CursorDown + Enter
        E2EGlobal.waitSomeTime();
        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime(500);

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(user3);
    });

    it('can add a responsible from drop-down that is an additional participant', function () {
        let additionalParticipant = "Additional Participant";
        browser.setValue('#edtParticipantsAdditional', additionalParticipant);

        E2ETopics.addTopicToMinutes('TOP-1', "");

        browser.saveScreenshot("additional-responsible-1");

        E2ETopics.openEditTopicForMinutes(1);
        E2EGlobal.waitSomeTime();

        browser.saveScreenshot("additional-responsible-2");

        browser.element(".select2-selection").click();
        // We only send the beginning of the name, to ensure the drop-down is used for selection!
        browser.keys("Add\uE015\uE007");  // + CursorDown + Enter

        browser.saveScreenshot("additional-responsible-3");

        browser.click("#btnTopicSave");
        E2EGlobal.waitSomeTime();

        browser.saveScreenshot("additional-responsible-4");

        let topicHeadingText = browser.element("#topicPanel .well:nth-child(1) h3").getText();
        expect (topicHeadingText).to.contain(additionalParticipant);
    });
});
<|endoftext|>


<commit_before>define([
    'require',
    '../lib/jquery'
], function(require) {

    var init = function($el, opts) {
        var $first = $el.children(':first'),
            $rest = $el.children(':not(:first)'),
            $header = $('
'),
            $body = $('
'),
            $form = $el.find('form'),
            $closebutton = $(
                '<button type="button" class="close-panel">Close</button>');

        // separate into header and body
        if ($rest.length === 0) {
            $first.wrap($body);
            $el.prepend($header);
        } else {
            $first.wrap($header);
            $rest.wrapAll($body);
        }

        // add close-panel button to header
        $('.header', $el).append($closebutton);

        // event handler to remove element
        var remove = function(ev) {
            ev.preventDefault();
            $(ev.currentTarget).off('.remove.modal');
            $el.remove();
        };

        // remove on ESC
        $(document).on('keyup.remove.modal', function(ev) {
            if (ev.which == 27) remove(ev);
        });
        // remove on close-panel button click
        $el.find('.close-panel').on('click.remove.modal', remove);
        // remove on click of triggering element
        if (opts.$trigger_el) opts.$trigger_el.on('click.remove.modal', remove);

        // close forms that are successfully submitted or show error
        if ($form) {
            // prepare ajax request and submit function
            var params = {
                type: 'POST',
                error: function(jqXHR, textStatus, errorThrown) {
                    console.error(jqXHR, textStatus, errorThrown);
                },
                success: function(data, textStatus, jqXHR) {
                    $el.remove();
                }
            };
            var submit = function(ev) {
                ev.preventDefault();
                $form.ajaxSubmit(params);
            };

            $form.submit(submit);
        }
    };

    var pattern = {
        markup_trigger: "div.modal",
        initialised_class: "modal",
        default_opts: {
            shown: false
        },
        init: init
    };

    return pattern;
});
<commit_msg>another modal form close attempt<commit_after>define([
    'require',
    '../lib/jquery'
], function(require) {

    var init = function($el, opts) {
        var $first = $el.children(':first'),
            $rest = $el.children(':not(:first)'),
            $header = $('
'),
            $body = $('
'),
            $form = $el.find('form'),
            $closebutton = $(
                '<button type="button" class="close-panel">Close</button>');

        // separate into header and body
        if ($rest.length === 0) {
            $first.wrap($body);
            $el.prepend($header);
        } else {
            $first.wrap($header);
            $rest.wrapAll($body);
        }

        // add close-panel button to header
        $('.header', $el).append($closebutton);

        // event handler to remove element
        var remove = function(ev) {
            ev.preventDefault();
            $(ev.currentTarget).off('.remove.modal');
            $el.remove();
        };

        // remove on ESC
        $(document).on('keyup.remove.modal', function(ev) {
            if (ev.which == 27) remove(ev);
        });
        // remove on close-panel button click
        $el.find('.close-panel').on('click.remove.modal', remove);
        // remove on click of triggering element
        if (opts.$trigger_el) opts.$trigger_el.on('click.remove.modal', remove);

        // close forms that are successfully submitted or show error
        if ($form) {
            // prepare ajax request and submit function
            var params = {
                type: 'POST',
                error: function(jqXHR, textStatus, errorThrown) {
                    console.error(jqXHR, textStatus, errorThrown);
                },
                success: function(data, textStatus, jqXHR) {
                    $el.remove();
                }
            };
            var submit = function(ev) {
                ev.preventDefault();
                $form.ajaxSubmit(params);
            };
            $form.find('[type=submit]').on('click', submit);
        }
    };

    var pattern = {
        markup_trigger: "div.modal",
        initialised_class: "modal",
        default_opts: {
            shown: false
        },
        init: init
    };

    return pattern;
});
<|endoftext|>


<commit_before>var events = require('./events.js');

function Player(client) {
	this._client = client;
	this.name = client.username;
	this.pos = {}, this.facing = {};

	client.write(0x01, {
		entityId: client.id,
		levelType: 'default',
		gameMode: 1,
		dimension: 0,
		difficulty: 2,
		maxPlayers: 5
	});
}

Player.prototype.sendMessage = function(message) {
	this._client.write(0x03, JSON.stringify({
		text: message
	}));
};

Player.prototype.teleport = function(pos, facing) {
	if (facing) {
		this._client.write(0x0d, {
			x: pos.x,
			y: pos.y + 1.62,
			stance: pos.y,
			z: pos.z,
			yaw: facing.yaw,
			pitch: facing.pitch,
			onGround: true
		});
	} else {
		this._client.write(0x0b, {
			x: pos.x,
			y: pos.y + 1.62,
			stance: pos.y,
			z: pos.z,
			onGround: true
		});
	}
};

///////////////////////////////////////

function handleConnect(client) {
	var player = new Player(client);

	client.on('end', handleDisconnect(player));
	client.on(0x03, handleChatOrCommand(player));
	client.on(0x0b, handleMove(player));
	client.on(0x0c, handleLook(player));
	client.on(0x0d, handleMoveAndLook(player));

	events.fire('join', {
		player: player
	});
}

function handleDisconnect(player) {
	return function(data) {
		events.fire('quit', {
			player: player
		});
	};
}

function handleChatOrCommand(player) {
	return function(data) {
		var message = data.message;
		if (message.charAt(0) == '/') {
			var split = message.split(/\s+/);
			events.fire('command', {
				name: split[0].substr(1),
				args: split.slice(1, split.length),
				sender: player
			});
		} else {
			events.fire('chat', {
				message: message,
				sender: player
			});
		}
	};
}

function handleMove(player) {
	return function(data) {
		events.fire('move', {
			player: player,
			oldPos: player.pos,
			newPos: data
		});
		player.pos.x = data.x;
		player.pos.y = data.y - 1.62;
		player.pos.z = data.z;
	};
}

function handleLook(player) {
	return function(data) {
		player.facing.yaw = data.yaw;
		player.facing.pitch = data.pitch;
	};
}

function handleMoveAndLook(player) {
	return function(data) {
		player.pos.x = data.x;
		player.pos.y = data.y - 1.62;
		player.pos.z = data.z;
		player.facing.yaw = data.yaw;
		player.facing.pitch = data.pitch;
	};
}

module.exports = handleConnect;
<commit_msg>Fire move event only if player has actually moved<commit_after>var events = require('./events.js');

function Player(client) {
	this._client = client;
	this.name = client.username;
	this.pos = {}, this.facing = {};

	client.write(0x01, {
		entityId: client.id,
		levelType: 'default',
		gameMode: 1,
		dimension: 0,
		difficulty: 2,
		maxPlayers: 5
	});
}

Player.prototype.sendMessage = function(message) {
	this._client.write(0x03, JSON.stringify({
		text: message
	}));
};

Player.prototype.teleport = function(pos, facing) {
	if (facing) {
		this._client.write(0x0d, {
			x: pos.x,
			y: pos.y + 1.62,
			stance: pos.y,
			z: pos.z,
			yaw: facing.yaw,
			pitch: facing.pitch,
			onGround: true
		});
	} else {
		this._client.write(0x0b, {
			x: pos.x,
			y: pos.y + 1.62,
			stance: pos.y,
			z: pos.z,
			onGround: true
		});
	}
};

///////////////////////////////////////

function handleConnect(client) {
	var player = new Player(client);

	client.on('end', handleDisconnect(player));
	client.on(0x03, handleChatOrCommand(player));
	client.on(0x0b, handleMove(player));
	client.on(0x0c, handleLook(player));
	client.on(0x0d, handleMoveAndLook(player));

	events.fire('join', {
		player: player
	});
}

function handleDisconnect(player) {
	return function(data) {
		events.fire('quit', {
			player: player
		});
	};
}

function handleChatOrCommand(player) {
	return function(data) {
		var message = data.message;
		if (message.charAt(0) == '/') {
			var split = message.split(/\s+/);
			events.fire('command', {
				name: split[0].substr(1),
				args: split.slice(1, split.length),
				sender: player
			});
		} else {
			events.fire('chat', {
				message: message,
				sender: player
			});
		}
	};
}

function handleMove(player) {
	return function(data) {
		if (player.pos.x !== data.x || player.pos.y !== data.y - 1.62 || player.pos.z !== data.z) {
			events.fire('move', {
				player: player,
				oldPos: player.pos,
				newPos: data
			});
			player.pos.x = data.x;
			player.pos.y = data.y - 1.62;
			player.pos.z = data.z;
		}
	};
}

function handleLook(player) {
	return function(data) {
		player.facing.yaw = data.yaw;
		player.facing.pitch = data.pitch;
	};
}

function handleMoveAndLook(player) {
	return function(data) {
		player.pos.x = data.x;
		player.pos.y = data.y - 1.62;
		player.pos.z = data.z;
		player.facing.yaw = data.yaw;
		player.facing.pitch = data.pitch;
	};
}

module.exports = handleConnect;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE.txt file for terms.
 */

/*jslint nomen:true, node:true */

"use strict";

var libfs = require('fs'),
    libpath = require('path'),
    json5 = require('json5'),
    yrb2json = require('./yrb2json'),
    description = require('../package.json').description,

    // This regex only validates the primary language subtag. Subsequent
    // subtags (e.g., script and region) are simply validated against their
    // expected character class.
    //
    // This regex will detect false positives when:
    // 1) uses underscore delimiters in the module name and
    // 2) relies on an unspecified default language and
    // 3) ends with a hyphen-delimited token with 3 characters or less
    //
    // For example, given the file name `foo_bar_baz`, it will identify `baz`
    // as a language tag.
    LANG_TAG_RE = /_(?:i|x|[a-z]{2,3})(?:-[-a-zA-Z\d]+)*$/;

function PluginClass(config) {

    this.describe = {
        summary: description,
        extensions: ['js', 'json', 'json5', 'pres'],
        options: config || {}
    };

}

PluginClass.prototype = {

    fileUpdated: function (evt, api) {

        var file = evt.file,
            bundle = evt.bundle,
            source_path = file.fullPath,
            bundleName = file.bundleName,
            filename = libpath.basename(file.relativePath, '.' + file.ext),
            moduleName = (bundleName + '-lang-' + filename).toLocaleLowerCase(),
            format = this.describe.options.format,
            defaultLang = this.describe.options.defaultLang || 'en',
            destination_path,
            langBundleName,
            match,
            lang;

        match = filename.match(LANG_TAG_RE);
        lang  = (match && match[0].slice(1)) || defaultLang;

        // hoge_ja-JP => hoge
        langBundleName = filename.replace(LANG_TAG_RE, '');

        // Guarantee that build files will always include lang tags.
        // hoge => hoge_ja-JP.js
        // piyo_ja-JP => piyo_ja-JP.js
        destination_path = moduleName + (match ? '' : '_' + defaultLang) + '.js';

        // only files within the lang folder will be evaluated as lang bundles
        if (libpath.basename(libpath.dirname(source_path)) !== 'lang') {
            return;
        }

        return api.promise(function (fulfill, reject) {
            var langEntries,
                source;

            try {
                source = libfs.readFileSync(source_path, 'utf8').toString();
                if (file.ext === 'pres') {
                    source = yrb2json(source);
                }
                langEntries = json5.parse(source);
            } catch (e) {
                throw new Error('Error parsing lang bundle: ' +
                        file.relativePath, '. ' + e);
            }
            // provisioning lang entries for server side use
            bundle.lang = bundle.lang || {};
            bundle.lang[lang] = bundle.lang[lang] || {};
            bundle.lang[lang][langBundleName] = langEntries;

            if (format) {
                // trying to write the destination file which will fulfill or reject the initial promise
                api.writeFileInBundle(bundleName, destination_path,
                    require('./formats/' + format)(bundleName, langBundleName, moduleName, langEntries, lang))
                    .then(fulfill, reject);
            } else {
                fulfill();
            }

        });

    }

};

module.exports = PluginClass;
<commit_msg>adding transpiler argument<commit_after>/*
 * Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE.txt file for terms.
 */

/*jslint nomen:true, node:true */

"use strict";

var libfs = require('fs'),
    libpath = require('path'),
    json5 = require('json5'),
    yrb2json = require('./yrb2json'),
    description = require('../package.json').description,

    // This regex only validates the primary language subtag. Subsequent
    // subtags (e.g., script and region) are simply validated against their
    // expected character class.
    //
    // This regex will detect false positives when:
    // 1) uses underscore delimiters in the module name and
    // 2) relies on an unspecified default language and
    // 3) ends with a hyphen-delimited token with 3 characters or less
    //
    // For example, given the file name `foo_bar_baz`, it will identify `baz`
    // as a language tag.
    LANG_TAG_RE = /_(?:i|x|[a-z]{2,3})(?:-[-a-zA-Z\d]+)*$/;

function PluginClass(config) {

    this.describe = {
        summary: description,
        extensions: ['js', 'json', 'json5', 'pres'],
        options: config || {}
    };

}

PluginClass.prototype = {

    fileUpdated: function (evt, api) {

        var file = evt.file,
            bundle = evt.bundle,
            source_path = file.fullPath,
            bundleName = file.bundleName,
            filename = libpath.basename(file.relativePath, '.' + file.ext),
            moduleName = (bundleName + '-lang-' + filename).toLocaleLowerCase(),
            format = this.describe.options.format,
            transpiler = this.describe.options.transpiler,
            defaultLang = this.describe.options.defaultLang || 'en',
            destination_path,
            langBundleName,
            match,
            lang;

        match = filename.match(LANG_TAG_RE);
        lang  = (match && match[0].slice(1)) || defaultLang;

        // hoge_ja-JP => hoge
        langBundleName = filename.replace(LANG_TAG_RE, '');

        // Guarantee that build files will always include lang tags.
        // hoge => hoge_ja-JP.js
        // piyo_ja-JP => piyo_ja-JP.js
        destination_path = moduleName + (match ? '' : '_' + defaultLang) + '.js';

        // only files within the lang folder will be evaluated as lang bundles
        if (libpath.basename(libpath.dirname(source_path)) !== 'lang') {
            return;
        }

        return api.promise(function (fulfill, reject) {
            var langEntries,
                source,
                token;

            try {
                source = libfs.readFileSync(source_path, 'utf8').toString();
                if (file.ext === 'pres') {
                    source = yrb2json(source);
                }
                langEntries = json5.parse(source);
                // transpiler
                if (transpiler) {
                    transpiler = require('./transpilers/' + transpiler);
                    for (token in langEntries) {
                        if (langEntries.hasOwnProperty(token)) {
                            langEntries[token] = transpiler(langEntries[token]);
                        }
                    }
                }
            } catch (e) {
                throw new Error('Error parsing lang bundle: ' +
                        file.relativePath, '. ' + e);
            }
            // provisioning lang entries for server side use
            bundle.lang = bundle.lang || {};
            bundle.lang[lang] = bundle.lang[lang] || {};
            bundle.lang[lang][langBundleName] = langEntries;

            if (format) {
                // trying to write the destination file which will fulfill or reject the initial promise
                api.writeFileInBundle(bundleName, destination_path,
                    require('./formats/' + format)(bundleName, langBundleName, moduleName, langEntries, lang))
                    .then(fulfill, reject);
            } else {
                fulfill();
            }

        });

    }

};

module.exports = PluginClass;
<|endoftext|>


<commit_before>var extend = require( 'extend' );
var findParent = require( './find-parent' );
var falafel = require( './falafel-helper' );
var libFormat = require( './format-jsx' );
var ignore = require( 'esformatter-ignore' );

module.exports = {
  setOptions: function ( opts, esformatter ) {
    var me = this;
    opts = opts || { };
    me.opts = opts;
    me._esformatter = esformatter;

    var jsxOptions = opts.jsx || { };

    me.jsxOptions = extend( true, {
      formatJSX: true,
      attrsOnSameLineAsTag: true,
      maxAttrsOnTag: null,
      firstAttributeOnSameLine: false,
      alignWithFirstAttribute: true,
      JSXExpressionsSingleLine: true,
      formatJSXExpressions: true
    }, jsxOptions );

    if ( me.jsxOptions.maxAttrsOnTag < 1 ) {
      me.jsxOptions.maxAttrsOnTag = 1;
    }

    var htmlOptions = jsxOptions.htmlOptions || { };
    me.htmlOptions = extend( true, {
      brace_style: 'collapse', //eslint-disable-line
      indent_char: ' ', //eslint-disable-line
      //indentScripts: "keep",
      indent_size: 2, //eslint-disable-line
      max_preserve_newlines: 2, //eslint-disable-line
      preserve_newlines: true, //eslint-disable-line
      //indent_handlebars: true
      unformatted: require( './default-unformatted' ),
      wrap_line_length: 160 //eslint-disable-line
    }, htmlOptions );
  },

  stringBefore: function ( code ) {
    var me = this;
    if ( !me.jsxOptions.formatJSX ) {
      return code;
    }

    // me.jsxElements = me.jsxElements || [ ];
    // var jsxElements = [ ];

    me._ignore = me._ignore || [ ];

    var _ignore = Object.create( ignore );
    me._ignore.push( _ignore );

    code = _ignore.stringBefore( code );

    me._templateLiterals = me._templateLiterals || [ ];

    var templateLiterals = [ ];

    code = falafel( code, function ( node ) {
      if ( node.type === 'ClassProperty' ) {
        if ( node.value ) {
          var oldSource = node.source();

          var formattedProp = (node.static ? 'static ' : '')
              + (node.key.source() + ' = ' + node.value.source()
              + (oldSource.match( /;$/ ) ? ';' : ''));

          node.update( formattedProp );

        }
      }

      if ( node.type === 'TemplateLiteral' && (!findParent( node, 'JSXAttribute' ) && !findParent( node, 'TemplateLiteral' )) ) {

        var idx = templateLiterals.length;
        var replaceString = '\'__TEMPORARY_STRING--PLACEHOLDER___NODE_(' + idx + ')\'';

        templateLiterals.push( {
          code: node.source(),
          replacedWith: replaceString
        } );

        node.update( replaceString );
      }

      // if ( node.type === 'JSXElement'
      //   && !findParent( node, 'JSXElement' ) ) {
      //   var index = jsxElements.length;

      //   jsxElements.push( {
      //     loc: node.loc, code: node.source()
      //   } );

      //   node.update( '<__ESFORMATTER__JSX_NODE_0_' + index + ' />' );
      // }

      if ( node.type === 'ArrowFunctionExpression'
        || node.type === 'FunctionDeclaration'
        || node.type === 'ClassMethod'
        || node.type === 'FunctionExpression'
        || node.type === 'ObjectMethod' ) {

        node.update( node.source().replace( /^async\s+function/, 'async function' ) );
        node.update( node.source().replace( /^async\s+\(\)/, 'async ()' ) );
      }

      if ( node.type === 'Decorator' ) {
        if ( node.parent.type !== 'ClassMethod' && node.parent.type !== 'ClassProperty' ) {
          node.update( node.source().replace( /^\s*@/, '____decorator__at_sign___' ) + ';/*__decorator__semi__open*/\n/*__decorator__semi__end*/' );
        }
      }

      if ( node.type === 'SpreadProperty' ) {
        var _source = node.source().replace( /^\s*\.\.\./, '____esfmt_spread_sign___:' );
        node.update( _source );
      }

    } ).toString();

    var response = libFormat.replaceJSXExpressionContainers( code );
    me._jsxExpressionContainers = response.containers;
    me._templateLiterals.push( templateLiterals );
    return response.source;
  },

  _restoreJSXElements: function ( source ) {
    var me = this;
    var jsxElements = me.jsxElements.pop();

    jsxElements = jsxElements || [ ];

    jsxElements.forEach( function ( entry, idx ) {
      var container = entry.code;
      var rx = new RegExp( '<__ESFORMATTER__JSX_NODE_0_' + idx + '\\s\\/>' );

      // this is causing bug#13 using split/join fixed the issue
      //source = source.replace( rx, container );
      source = source.split( rx ).join( container );
    } );
    return source;
  },
  _restoreTemplateLiterals: function ( source ) {
    var me = this;

    var templateLiterals = me._templateLiterals.pop();
    templateLiterals = templateLiterals || [ ];

    templateLiterals.forEach( function ( entry ) {
      var code = entry.code;
      var replacedWith = entry.replacedWith;

      source = source.split( replacedWith ).join( code );
    } );

    return source;
  },
  stringAfter: function ( code ) {
    var me = this;

    if ( !me.jsxOptions.formatJSX ) {
      return code;
    }

    var jsxOptions = me.jsxOptions;

    code = libFormat.restoreJSXExpressionContainers(
      code,
      me._jsxExpressionContainers,
      jsxOptions.spaceInJSXExpressionContainers,
      jsxOptions.removeSpaceBeforeClosingJSX
    );
    // code = me._restoreJSXElements( code );

    var htmlOptions = me.htmlOptions;

    var formatter = libFormat.create( htmlOptions, jsxOptions, me.opts, me._esformatter );

    var ast = falafel( code, function ( node ) {
      if ( node.type !== 'JSXElement' ) {
        return;
      }
      var conditionalParent = findParent( node, 'ConditionalExpression' );
      if ( conditionalParent ) {
        var formatted = formatter.format( node );
        node.update( formatted );
        return;
      }
    } );

    code = ast.toString();

    // replace the spread operators
    code = code.replace( /____esfmt_spread_sign___\s*:\s*/g, '...' );

    ast = falafel( code, function ( node ) {
      // support for ES7 Decorators
      if ( node.type === 'CallExpression' && node.callee.source().indexOf( '____decorator__at_sign___' ) > -1 ) {
        node.callee.update( node.callee.source().replace( '____decorator__at_sign___', '@' ) );
      }
      if ( node.type === 'Identifier' && node.source().indexOf( '____decorator__at_sign___' ) > -1 ) {
        node.update( node.source().replace( '____decorator__at_sign___', '@' ) );
      }
      if ( node.type !== 'JSXElement' ) {
        return;
      }

      var formatted;
      if ( !findParent( node, 'JSXElement' ) ) {
        formatted = formatter.format( node );
        node.update( formatted );
      }
    } );

    code = ast.toString();

    // this is to make sure all decorators comments were removed from the source
    code = code.replace( /;\s*\/\*__decorator__semi__open\*\/\n\s*\/\*__decorator__semi__end\*\//g, '' );

    var _ignore = me._ignore.pop();

    code = _ignore.stringAfter( code );
    code = me._restoreTemplateLiterals( code );

    return code;
  }
};
<commit_msg>Replace string like placeholder with variable<commit_after>var extend = require( 'extend' );
var findParent = require( './find-parent' );
var falafel = require( './falafel-helper' );
var libFormat = require( './format-jsx' );
var ignore = require( 'esformatter-ignore' );

module.exports = {
  setOptions: function ( opts, esformatter ) {
    var me = this;
    opts = opts || { };
    me.opts = opts;
    me._esformatter = esformatter;

    var jsxOptions = opts.jsx || { };

    me.jsxOptions = extend( true, {
      formatJSX: true,
      attrsOnSameLineAsTag: true,
      maxAttrsOnTag: null,
      firstAttributeOnSameLine: false,
      alignWithFirstAttribute: true,
      JSXExpressionsSingleLine: true,
      formatJSXExpressions: true
    }, jsxOptions );

    if ( me.jsxOptions.maxAttrsOnTag < 1 ) {
      me.jsxOptions.maxAttrsOnTag = 1;
    }

    var htmlOptions = jsxOptions.htmlOptions || { };
    me.htmlOptions = extend( true, {
      brace_style: 'collapse', //eslint-disable-line
      indent_char: ' ', //eslint-disable-line
      //indentScripts: "keep",
      indent_size: 2, //eslint-disable-line
      max_preserve_newlines: 2, //eslint-disable-line
      preserve_newlines: true, //eslint-disable-line
      //indent_handlebars: true
      unformatted: require( './default-unformatted' ),
      wrap_line_length: 160 //eslint-disable-line
    }, htmlOptions );
  },

  stringBefore: function ( code ) {
    var me = this;
    if ( !me.jsxOptions.formatJSX ) {
      return code;
    }

    // me.jsxElements = me.jsxElements || [ ];
    // var jsxElements = [ ];

    me._ignore = me._ignore || [ ];

    var _ignore = Object.create( ignore );
    me._ignore.push( _ignore );

    code = _ignore.stringBefore( code );

    me._templateLiterals = me._templateLiterals || [ ];

    var templateLiterals = [ ];

    code = falafel( code, function ( node ) {
      if ( node.type === 'ClassProperty' ) {
        if ( node.value ) {
          var oldSource = node.source();

          var formattedProp = (node.static ? 'static ' : '')
              + (node.key.source() + ' = ' + node.value.source()
              + (oldSource.match( /;$/ ) ? ';' : ''));

          node.update( formattedProp );

        }
      }

      if ( node.type === 'TemplateLiteral' && (!findParent( node, 'JSXAttribute' ) && !findParent( node, 'TemplateLiteral' )) ) {

        var idx = templateLiterals.length;
        var replaceString = '__TEMPORARY_VARIABLE__PLACEHOLDER___NODE__' + idx + '_';

        templateLiterals.push( {
          code: node.source(),
          replacedWith: replaceString
        } );

        node.update( replaceString );
      }

      // if ( node.type === 'JSXElement'
      //   && !findParent( node, 'JSXElement' ) ) {
      //   var index = jsxElements.length;

      //   jsxElements.push( {
      //     loc: node.loc, code: node.source()
      //   } );

      //   node.update( '<__ESFORMATTER__JSX_NODE_0_' + index + ' />' );
      // }

      if ( node.type === 'ArrowFunctionExpression'
        || node.type === 'FunctionDeclaration'
        || node.type === 'ClassMethod'
        || node.type === 'FunctionExpression'
        || node.type === 'ObjectMethod' ) {

        node.update( node.source().replace( /^async\s+function/, 'async function' ) );
        node.update( node.source().replace( /^async\s+\(\)/, 'async ()' ) );
      }

      if ( node.type === 'Decorator' ) {
        if ( node.parent.type !== 'ClassMethod' && node.parent.type !== 'ClassProperty' ) {
          node.update( node.source().replace( /^\s*@/, '____decorator__at_sign___' ) + ';/*__decorator__semi__open*/\n/*__decorator__semi__end*/' );
        }
      }

      if ( node.type === 'SpreadProperty' ) {
        var _source = node.source().replace( /^\s*\.\.\./, '____esfmt_spread_sign___:' );
        node.update( _source );
      }

    } ).toString();

    var response = libFormat.replaceJSXExpressionContainers( code );
    me._jsxExpressionContainers = response.containers;
    me._templateLiterals.push( templateLiterals );
    return response.source;
  },

  _restoreJSXElements: function ( source ) {
    var me = this;
    var jsxElements = me.jsxElements.pop();

    jsxElements = jsxElements || [ ];

    jsxElements.forEach( function ( entry, idx ) {
      var container = entry.code;
      var rx = new RegExp( '<__ESFORMATTER__JSX_NODE_0_' + idx + '\\s\\/>' );

      // this is causing bug#13 using split/join fixed the issue
      //source = source.replace( rx, container );
      source = source.split( rx ).join( container );
    } );
    return source;
  },
  _restoreTemplateLiterals: function ( source ) {
    var me = this;

    var templateLiterals = me._templateLiterals.pop();
    templateLiterals = templateLiterals || [ ];

    templateLiterals.forEach( function ( entry ) {
      var code = entry.code;
      var replacedWith = entry.replacedWith;

      source = source.split( replacedWith ).join( code );
    } );

    return source;
  },
  stringAfter: function ( code ) {
    var me = this;

    if ( !me.jsxOptions.formatJSX ) {
      return code;
    }

    var jsxOptions = me.jsxOptions;

    code = libFormat.restoreJSXExpressionContainers(
      code,
      me._jsxExpressionContainers,
      jsxOptions.spaceInJSXExpressionContainers,
      jsxOptions.removeSpaceBeforeClosingJSX
    );
    // code = me._restoreJSXElements( code );

    var htmlOptions = me.htmlOptions;

    var formatter = libFormat.create( htmlOptions, jsxOptions, me.opts, me._esformatter );

    var ast = falafel( code, function ( node ) {
      if ( node.type !== 'JSXElement' ) {
        return;
      }
      var conditionalParent = findParent( node, 'ConditionalExpression' );
      if ( conditionalParent ) {
        var formatted = formatter.format( node );
        node.update( formatted );
        return;
      }
    } );

    code = ast.toString();

    // replace the spread operators
    code = code.replace( /____esfmt_spread_sign___\s*:\s*/g, '...' );

    ast = falafel( code, function ( node ) {
      // support for ES7 Decorators
      if ( node.type === 'CallExpression' && node.callee.source().indexOf( '____decorator__at_sign___' ) > -1 ) {
        node.callee.update( node.callee.source().replace( '____decorator__at_sign___', '@' ) );
      }
      if ( node.type === 'Identifier' && node.source().indexOf( '____decorator__at_sign___' ) > -1 ) {
        node.update( node.source().replace( '____decorator__at_sign___', '@' ) );
      }
      if ( node.type !== 'JSXElement' ) {
        return;
      }

      var formatted;
      if ( !findParent( node, 'JSXElement' ) ) {
        formatted = formatter.format( node );
        node.update( formatted );
      }
    } );

    code = ast.toString();

    // this is to make sure all decorators comments were removed from the source
    code = code.replace( /;\s*\/\*__decorator__semi__open\*\/\n\s*\/\*__decorator__semi__end\*\//g, '' );

    var _ignore = me._ignore.pop();

    code = _ignore.stringAfter( code );
    code = me._restoreTemplateLiterals( code );

    return code;
  }
};
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/**
 * @fileoverview Json based opensocial container.
 */

JsonContainer = function(baseUrl, domain, supportedFieldsArray) {
  opensocial.Container.call(this);

  var supportedFieldsMap = {};
  for (var objectType in supportedFieldsArray) {
    if (supportedFieldsArray.hasOwnProperty(objectType)) {
      supportedFieldsMap[objectType] = {};
      for (var i = 0; i < supportedFieldsArray[objectType].length; i++) {
        var supportedField = supportedFieldsArray[objectType][i];
        supportedFieldsMap[objectType][supportedField] = true;
      }
    }
  }

  this.environment_ = new opensocial.Environment(domain, supportedFieldsMap);
  this.baseUrl_ = baseUrl;
};
JsonContainer.inherits(opensocial.Container);

JsonContainer.prototype.getEnvironment = function() {
  return this.environment_;
};

JsonContainer.prototype.requestCreateActivity = function(activity,
    priority, opt_callback) {
  opt_callback = opt_callback || {};

  var req = opensocial.newDataRequest();
  var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
  req.add(this.newCreateActivityRequest(viewer, activity), 'key');
  req.send(function(response) {
    opt_callback(response.get('key'));
  });
};

JsonContainer.prototype.requestSendMessage = function(recipients, message,
    opt_callback) {
  opt_callback = opt_callback || {};

  var req = opensocial.newDataRequest();
  req.add(this.newRequestSendMessageRequest(recipients, message), 'key');
  req.send(function(response) {
    opt_callback(response.get('key'));
  });
};

JsonContainer.prototype.createJson = function(requestObjects) {
  var jsonObjects = [];
  for (var i = 0; i < requestObjects.length; i++) {
    jsonObjects[i] = requestObjects[i].request.jsonParams;
  }
  return gadgets.json.stringify(jsonObjects);
};

JsonContainer.prototype.requestData = function(dataRequest, callback) {
  callback = callback || {};

  var requestObjects = dataRequest.getRequestObjects();
  if (requestObjects.length == 0) {
    callback(new opensocial.DataResponse({}, true));
    return;
  }

  var jsonText = this.createJson(requestObjects);

  var sendResponse = function(result) {
    result = result.data;

    if (!result || result['error']) {
      callback(new opensocial.DataResponse({}, true));
      return;
    }

    var responses = result['responses'] || [];
    var globalError = false;

    var responseMap = {};

    for (var i = 0; i < responses.length; i++) {
      var response = responses[i];
      var rawData = response['response'];
      var error = response['error'];
      var errorMessage = response['errorMessage'];

      var processedData = requestObjects[i].request.processResponse(
          requestObjects[i].request, rawData, error, errorMessage);
      globalError = globalError || processedData.hadError();
      responseMap[requestObjects[i].key] = processedData;
    }

    var dataResponse = new opensocial.DataResponse(responseMap, globalError);
    callback(dataResponse);
  };

  new BatchRequest(this.baseUrl_, jsonText, sendResponse,
      {'st' : shindig.auth.getSecurityToken()}).send();
};

JsonContainer.prototype.newFetchPersonRequest = function(id, opt_params) {
  var peopleRequest = this.newFetchPeopleRequest(
      new opensocial.IdSpec({'userId' : id}), opt_params);

  var me = this;
  return new RequestItem(peopleRequest.jsonParams,
      function(rawJson) {
        return me.createPersonFromJson(rawJson['items'][0]);
      });
};

JsonContainer.prototype.newFetchPeopleRequest = function(idSpec, opt_params) {
  var me = this;
  // TODO: Handle filterOptions
  return new RequestItem(
      {'type' : 'FETCH_PEOPLE',
        'idSpec' : JsonContainer.translateIdSpec(idSpec),
        'profileDetail': opt_params['profileDetail'],
        'sortOrder': opt_params['sortOrder'] || 'topFriends',
        'filter': opt_params['filter'] || 'all',
        'first': opt_params['first'] || 0,
        'max': opt_params['max'] || 20},
      function(rawJson) {
        var jsonPeople = rawJson['items'];
        var people = [];
        for (var i = 0; i < jsonPeople.length; i++) {
          people.push(me.createPersonFromJson(jsonPeople[i]));
        }
        return new opensocial.Collection(people, rawJson['offset'],
            rawJson['totalSize']);
      });
};

JsonContainer.prototype.createPersonFromJson = function(serverJson) {
  return new JsonPerson(serverJson);
}

JsonContainer.prototype.newFetchPersonAppDataRequest = function(idSpec, keys,
    opt_params) {
  return new RequestItem({'type' : 'FETCH_PERSON_APP_DATA',
      'idSpec' : JsonContainer.translateIdSpec(idSpec),
      'keys' : keys},
      function (appData) {
        return opensocial.Container.escape(appData, opt_params, true);
      });
};

JsonContainer.prototype.newUpdatePersonAppDataRequest = function(id, key,
    value) {
  return new RequestItem({'type' : 'UPDATE_PERSON_APP_DATA', 'idSpec' : id,
    'key' : key, 'value' : value});
};

JsonContainer.prototype.newRemovePersonAppDataRequest = function(id, keys) {
  // TODO: This isn't supported on the server yet
  return new RequestItem({'type' : 'REMOVE_PERSON_APP_DATA', 'idSpec' : id,
    'keys' : keys});
};

JsonContainer.prototype.newFetchActivitiesRequest = function(idSpec,
    opt_params) {
  return new RequestItem({'type' : 'FETCH_ACTIVITIES',
      'idSpec' : JsonContainer.translateIdSpec(idSpec)},
      function(rawJson) {
        var activities = [];
        for (var i = 0; i < rawJson.length; i++) {
          activities.push(new JsonActivity(rawJson[i]));
        }
        return new opensocial.Collection(activities);
      });
};

JsonContainer.prototype.newActivity = function(opt_params) {
  return new JsonActivity(opt_params, true);
};

JsonContainer.prototype.newMediaItem = function(mimeType, url, opt_params) {
  opt_params = opt_params || {};
  opt_params['mimeType'] = mimeType;
  opt_params['url'] = url;
  return new JsonMediaItem(opt_params);
};

JsonContainer.prototype.newCreateActivityRequest = function(idSpec,
    activity) {
  return new RequestItem({'type' : 'CREATE_ACTIVITY',
    'idSpec' : JsonContainer.translateIdSpec(idSpec),
    'activity' : activity.toJsonObject()});
};

JsonContainer.prototype.newRequestSendMessageRequest = function(idSpec,
    message) {
  return new RequestItem({'type' : 'SEND_MESSAGE',
    'idSpec' : JsonContainer.translateIdSpec(idSpec),
    'message' : message});
};

JsonContainer.translateIdSpec = function(newIdSpec) {
  var oldIdSpec;
  var userId = newIdSpec.getField('userId');
  var groupId = newIdSpec.getField('groupId');

  if (groupId == 'FRIENDS') {
    if (userId == 'OWNER') {
      oldIdSpec = 'OWNER_FRIENDS';
    } else if (userId == 'VIEWER') {
      oldIdSpec = 'VIEWER_FRIENDS';
    } else {
      // TODO: We don't really support getting friends of an arbitrary user
      // with this old wire format
    }
  } else if (!groupId) {
    oldIdSpec = userId;
  } else {
    // TODO: Old wire format doesn't support groups
  }

  return oldIdSpec;
};

RequestItem = function(jsonParams, processData) {
  this.jsonParams = jsonParams;
  this.processData = processData ||
    function (rawJson) {
      return rawJson;
    };

  this.processResponse = function(originalDataRequest, rawJson, error,
      errorMessage) {
    return new opensocial.ResponseItem(originalDataRequest,
        error ? null : this.processData(rawJson), error, errorMessage);
  }
};
<commit_msg>SHINDIG-378 update broke requestSendMessage() patch from bruno<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/**
 * @fileoverview Json based opensocial container.
 */

JsonContainer = function(baseUrl, domain, supportedFieldsArray) {
  opensocial.Container.call(this);

  var supportedFieldsMap = {};
  for (var objectType in supportedFieldsArray) {
    if (supportedFieldsArray.hasOwnProperty(objectType)) {
      supportedFieldsMap[objectType] = {};
      for (var i = 0; i < supportedFieldsArray[objectType].length; i++) {
        var supportedField = supportedFieldsArray[objectType][i];
        supportedFieldsMap[objectType][supportedField] = true;
      }
    }
  }

  this.environment_ = new opensocial.Environment(domain, supportedFieldsMap);
  this.baseUrl_ = baseUrl;
};
JsonContainer.inherits(opensocial.Container);

JsonContainer.prototype.getEnvironment = function() {
  return this.environment_;
};

JsonContainer.prototype.requestCreateActivity = function(activity,
    priority, opt_callback) {
  opt_callback = opt_callback || {};

  var req = opensocial.newDataRequest();
  var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
  req.add(this.newCreateActivityRequest(viewer, activity), 'key');
  req.send(function(response) {
    opt_callback(response.get('key'));
  });
};

JsonContainer.prototype.requestSendMessage = function(recipients, message,
    opt_callback, opt_params) {
  opt_callback = opt_callback || {};
  opt_params = opt_params || {};
/*
 * TODO: Supporting just one IdSpec, but spec says Array.<String>, String
 * recipients Not sure how to implement it
 */
  var id = new opensocial.IdSpec({'userId' : recipients});
  var req = opensocial.newDataRequest();
  req.add(this.newRequestSendMessageRequest(id, message), 'key');
  req.send(function(response) {
    opt_callback(response.get('key'));
  });
};

JsonContainer.prototype.createJson = function(requestObjects) {
  var jsonObjects = [];
  for (var i = 0; i < requestObjects.length; i++) {
    jsonObjects[i] = requestObjects[i].request.jsonParams;
  }
  return gadgets.json.stringify(jsonObjects);
};

JsonContainer.prototype.requestData = function(dataRequest, callback) {
  callback = callback || {};

  var requestObjects = dataRequest.getRequestObjects();
  if (requestObjects.length == 0) {
    callback(new opensocial.DataResponse({}, true));
    return;
  }

  var jsonText = this.createJson(requestObjects);

  var sendResponse = function(result) {
    result = result.data;

    if (!result || result['error']) {
      callback(new opensocial.DataResponse({}, true));
      return;
    }

    var responses = result['responses'] || [];
    var globalError = false;

    var responseMap = {};

    for (var i = 0; i < responses.length; i++) {
      var response = responses[i];
      var rawData = response['response'];
      var error = response['error'];
      var errorMessage = response['errorMessage'];

      var processedData = requestObjects[i].request.processResponse(
          requestObjects[i].request, rawData, error, errorMessage);
      globalError = globalError || processedData.hadError();
      responseMap[requestObjects[i].key] = processedData;
    }

    var dataResponse = new opensocial.DataResponse(responseMap, globalError);
    callback(dataResponse);
  };

  new BatchRequest(this.baseUrl_, jsonText, sendResponse,
      {'st' : shindig.auth.getSecurityToken()}).send();
};

JsonContainer.prototype.newFetchPersonRequest = function(id, opt_params) {
  var peopleRequest = this.newFetchPeopleRequest(
      new opensocial.IdSpec({'userId' : id}), opt_params);

  var me = this;
  return new RequestItem(peopleRequest.jsonParams,
      function(rawJson) {
        return me.createPersonFromJson(rawJson['items'][0]);
      });
};

JsonContainer.prototype.newFetchPeopleRequest = function(idSpec, opt_params) {
  var me = this;
  // TODO: Handle filterOptions
  return new RequestItem(
      {'type' : 'FETCH_PEOPLE',
        'idSpec' : JsonContainer.translateIdSpec(idSpec),
        'profileDetail': opt_params['profileDetail'],
        'sortOrder': opt_params['sortOrder'] || 'topFriends',
        'filter': opt_params['filter'] || 'all',
        'first': opt_params['first'] || 0,
        'max': opt_params['max'] || 20},
      function(rawJson) {
        var jsonPeople = rawJson['items'];
        var people = [];
        for (var i = 0; i < jsonPeople.length; i++) {
          people.push(me.createPersonFromJson(jsonPeople[i]));
        }
        return new opensocial.Collection(people, rawJson['offset'],
            rawJson['totalSize']);
      });
};

JsonContainer.prototype.createPersonFromJson = function(serverJson) {
  return new JsonPerson(serverJson);
}

JsonContainer.prototype.newFetchPersonAppDataRequest = function(idSpec, keys,
    opt_params) {
  return new RequestItem({'type' : 'FETCH_PERSON_APP_DATA',
      'idSpec' : JsonContainer.translateIdSpec(idSpec),
      'keys' : keys},
      function (appData) {
        return opensocial.Container.escape(appData, opt_params, true);
      });
};

JsonContainer.prototype.newUpdatePersonAppDataRequest = function(id, key,
    value) {
  return new RequestItem({'type' : 'UPDATE_PERSON_APP_DATA', 'idSpec' : id,
    'key' : key, 'value' : value});
};

JsonContainer.prototype.newRemovePersonAppDataRequest = function(id, keys) {
  // TODO: This isn't supported on the server yet
  return new RequestItem({'type' : 'REMOVE_PERSON_APP_DATA', 'idSpec' : id,
    'keys' : keys});
};

JsonContainer.prototype.newFetchActivitiesRequest = function(idSpec,
    opt_params) {
  return new RequestItem({'type' : 'FETCH_ACTIVITIES',
      'idSpec' : JsonContainer.translateIdSpec(idSpec)},
      function(rawJson) {
        var activities = [];
        for (var i = 0; i < rawJson.length; i++) {
          activities.push(new JsonActivity(rawJson[i]));
        }
        return new opensocial.Collection(activities);
      });
};

JsonContainer.prototype.newActivity = function(opt_params) {
  return new JsonActivity(opt_params, true);
};

JsonContainer.prototype.newMediaItem = function(mimeType, url, opt_params) {
  opt_params = opt_params || {};
  opt_params['mimeType'] = mimeType;
  opt_params['url'] = url;
  return new JsonMediaItem(opt_params);
};

JsonContainer.prototype.newCreateActivityRequest = function(idSpec,
    activity) {
  return new RequestItem({'type' : 'CREATE_ACTIVITY',
    'idSpec' : JsonContainer.translateIdSpec(idSpec),
    'activity' : activity.toJsonObject()});
};

JsonContainer.prototype.newRequestSendMessageRequest = function(idSpec,
    message) {
  return new RequestItem({'type' : 'SEND_MESSAGE',
    'idSpec' : JsonContainer.translateIdSpec(idSpec),
    'message' : message});
};

JsonContainer.translateIdSpec = function(newIdSpec) {
  var oldIdSpec;
  var userId = newIdSpec.getField('userId');
  var groupId = newIdSpec.getField('groupId');

  if (groupId == 'FRIENDS') {
    if (userId == 'OWNER') {
      oldIdSpec = 'OWNER_FRIENDS';
    } else if (userId == 'VIEWER') {
      oldIdSpec = 'VIEWER_FRIENDS';
    } else {
      // TODO: We don't really support getting friends of an arbitrary user
      // with this old wire format
    }
  } else if (!groupId) {
    oldIdSpec = userId;
  } else {
    // TODO: Old wire format doesn't support groups
  }

  return oldIdSpec;
};

RequestItem = function(jsonParams, processData) {
  this.jsonParams = jsonParams;
  this.processData = processData ||
    function (rawJson) {
      return rawJson;
    };

  this.processResponse = function(originalDataRequest, rawJson, error,
      errorMessage) {
    return new opensocial.ResponseItem(originalDataRequest,
        error ? null : this.processData(rawJson), error, errorMessage);
  }
};
<|endoftext|>