Gloriafood integration customer address filleds help [SOLVED]

Everything you changed seems syntactically correct. But comparing your script to others posted you’re missing functions: getCustomer, createCustomer, etc.

Using a script Jesse posted a few years ago, I think I’ve merged your changes and the number formatting over. You’ll have to test. Also, check the config at the top of the script. I think I copied everything over but please make sure.

Source @ pastebin

var express = require('express');
var request = require('request');
var querystring = require('querystring');
var libphonenumber = require('libphonenumber - js');
var app = express();
var messageServer = 'localhost';
var messageServerPort = 9000;
var gloriaFoodKey = 'XXXXXXX';
var serverKey = '553181';
var timeout = 30000;
var customerEntityType = 'Customers';
var itemTagName = 'Gloria Name';
var ticketType = 'Ticket';
var departmentName = 'pizza';
var userName = 'Administrator';
var terminalName = 'Server';
var printJobName = 'Print Bill';
var additionalPrintJobs = []; // array of additional print job names
var miscProductName = 'Misc';
var deliveryFeeCalculation = 'Delivery Service';
var tipCalculation = 'Tip';
var accessToken = undefined;
var accessTokenExpires = '';

var formatPhoneNumber = true;
var formatPhoneNumberCountry = 'IL'; // set to your ISO country code
var formatPhoneNumberFormat = 'National'; // format type, this should suffice
var formatPhoneNumberHyphen = false;
var formatPhoneNumberNoSpaces = true;

Authorize(loop());

function Authorize(callback) {
    accessToken = undefined;
    var form = {
        grant_type: 'client_credentials',
        client_secret: serverKey,
        client_id: 'gloria'
    };
    var formData = querystring.stringify(form);
    var contentLength = formData.length;

    request({
        headers: {
            'Content-Length': contentLength,
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        uri: 'http://' + messageServer + ':' + messageServerPort + '/Token',
        body: formData,
        method: 'POST'
    }, function (err, res, body) {
        if (err) {
            console.log('Error while trying to authorize >', err.message);
        } else if (res.statusCode === 400) {
            console.log(body);
            if (callback) callback();
        } else {
            var result = JSON.parse(body);
            accessToken = result.access_token;
            accessTokenExpires = new Date(result['.expires']);
            if (callback) callback();
        }
    });
}

function gql(query, callback) {
    if (!accessToken) {
        console.log('Valid access Token is needed to execute GQL calls.')
        return;
    }
    var data = JSON.stringify({
        query: query
    });
    request({
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': 'Bearer ' + accessToken
        },
        uri: 'http://' + messageServer + ':' + messageServerPort + '/api/graphql',
        body: data,
        method: 'POST'
    }, function (err, res, body) {
        if (res.statusCode === 401) {
            console.log('Should Authorize...');
            Authorize(() => gql(query, callback));
        } else {
            var data = JSON.parse(body).data;
            if (callback) callback(data);
        }
    });
}

function readTickets(callback) {
    request({
        method: 'POST',
        uri: 'https://pos.gloriafood.com/pos/order/pop',
        headers: {
            'Authorization': gloriaFoodKey,
            'Accept': 'application/json',
            'Glf-Api-Version': '2'
        }
    }, function (err, res, body) {
        if (err) {
            console.log(`problem with request: ${err.message}`);
        } else {
            callback(JSON.parse(body));
        }
    });
}

function loop() {
    if (!accessToken) {
        console.log('There is no valid access token. Skipping...')
        Authorize();
    } else if (accessTokenExpires < new Date()) {
        console.log('Access Token Expired. Reauthenticating...');
        Authorize(() => loop());
        return;
    } else {
        console.log('Reading Tickets...');
        readTickets((tickets) => processTickets(tickets));
    }
    setTimeout(loop, timeout);
}

function processTickets(tickets) {
    if (tickets.count == 0) return;
    tickets.orders.forEach((order) => processOrder(order));
}

function processOrder(order) {
    // Format phone number
    if (formatPhoneNumber) {
        order.client_phone = libphonenumber.formatNumber({
            country: formatPhoneNumberCountry,
            phone: order.client_phone
        }, formatPhoneNumberFormat);

        if (formatPhoneNumberHyphen) {
            order.client_phone = order.client_phone.replace(/ +/g, '-');
        } else {
            order.client_phone = order.client_phone.replace(/-+/g, '');
        }

        if (formatPhoneNumberNoSpaces) {
            order.client_phone = order.client_phone.replace(/ +/g, '');
        }
    }

    var street = null;
    var bloc = null;
    var floor = null;
    var apartment = null;
    var intercom = null;
    var moreAddress = null;
    var zipcode = null;
    var city = null;

    if (order.client_address_parts != null) {
        street = order.client_address_parts.street;
        bloc = order.client_address_parts.bloc;
        floor = order.client_address_parts.floor;
        apartment = order.client_address_parts.apartment;
        intercom = order.client_address_parts.intercom;
        moreAddress = order.client_address_parts.more_address;
        zipcode = order.client_address_parts.zipcode;
        city = order.client_address_parts.city;
    }

    var customer = {
        firstName: order.client_first_name,
        lastName: order.client_last_name,
        email: order.client_email,
        phone: order.client_phone,
        street: street,
        city: city,
        bloc: bloc,
        floor: floor,
        apartment: apartment,
        intercom: intercom,
        moreAddress: moreAddress,
        zipcode: zipcode,
        newCustomer: false
    }

    loadCustomer(customer, customer => {
        var services = order.items
            .filter(x => x.type === 'tip' || x.type === 'delivery_fee' || x.type === 'promo_cart')
            .map(x => {
                return {
                    name: getCalculationName(x.type),
                    amount: Math.abs((x.cart_discount_rate) * 100) || x.price
                };
            })
            .filter(x => x.name);
        loadItems(order.items.map(x => processItem(x)), items => {
            createTicket(customer, items, order.instructions, order.fulfill_at, services, order.payment, ticketId => {
                gql('mutation m {postTicketRefreshMessage(id:0){id}}', () => {
                    console.log(`Ticket ${ticketId} created...`);
                });
            });
        });
    });
}

function getCalculationName(name) {
    if (name === 'promo_cart') return promotionDiscount;
    if (name === 'tip') return tipCalculation;
    if (name === 'delivery_fee') return deliveryFeeCalculation;
    return undefined;
}

function loadItems(items, callback) {
    var script = getLoadItemsScript(items);
    gql(script, data => {
        callback(items.filter(x => x.type === 'item').map(item => {
            return {
                id: item.id,
                name: item.name,
                type: item.type,
                sambaName: data[`i${item.id}`][0] ? data[`i${item.id}`][0].name : miscProductName,
                price: item.price,
                quantity: item.quantity,
                instructions: item.instructions,
                options: item.options,
                portions: item.portions
            }
        }));
    });
}

function isNewCustomer(customer) {
    if (customer.states && customer.states.find(x => x.stateName === 'CStatus')) {
        return customer.states.find(x => x.stateName === 'CStatus').state === 'Unconfirmed';
    }
    return false;
}

function createTicket(customer, items, instructions, fulfill_at, services, payment, callback) {
    var newCustomer = isNewCustomer(customer);
    gql(getAddTicketScript(items, customer.name, newCustomer, instructions, fulfill_at, services, payment), data => {
        if (newCustomer)
            callback(data.addTicket.id);
        else printTicketToKitchen(data.addTicket.id, () => callback(data.addTicket.id));
    });
}

function printTicketToKitchen(ticketId, callback) {
    gql(getKitchenPrintScript(ticketId), callback);
}

function loadCustomer(customer, callback) {
    gql(getIsEntityExistsScript(customer), (data) => {
        if (!data.isEntityExists) {
            createCustomer(customer, callback);
        } else getCustomer(customer.phone, callback);
    });
}

function createCustomer(customer, callback) {
    gql(getAddCustomerScript(customer), (data) => {
        gql(getNewCustomerStateScript(customer), () => {
            getCustomer(data.addEntity.name, callback);
        })
    });
}

function getCustomer(customerName, callback) {
    gql(getCustomerScript(customerName), (data) => {
        callback(data.getEntity);
    });
}

function getLoadItemsScript(items) {
    var part = items.map(item => `i${item.id}: getProducts(itemTag:{name:"${itemTagName}",value:"${item.name}"}){name} `);
    return `{${part}}`;
}

function getCustomerScript(name) {
    return `{getEntity(type:"${customerEntityType}",name:"${name}"){name,customData{name,value},states{stateName,state}}}`;
}

function getIsEntityExistsScript(customer) {
    return `{isEntityExists(type:"${customerEntityType}",name:"${customer.phone}")}`;
}

function getAddCustomerScript(customer) {
    return `
    mutation m{addEntity(entity:{
        entityType:"${customerEntityType}",name:"${customer.phone}",customData:[
            {name:"First Name",value:"${customer.firstName}"},
            {name:"Last Name",value:"${customer.lastName}"},
            {name:"Address",value:"${customer.address}"},
            {name:"EMail",value:"${customer.email}"},
            {name:"street",value:"${customer.street}"}
        ]})
        {name}
     }`;
}

function getNewCustomerStateScript(customer) {
    return `mutation m{updateEntityState(entityTypeName:"${customerEntityType}",entityName:"${customer.phone}",state:"Unconfirmed",stateName:"CStatus"){name}}`;
}

function getKitchenPrintScript(ticketId) {
    return `mutation m {
                executePrintJob(name: "${printJobName}", ticketId: ${ticketId}, 
                    orderStateFilters: [{stateName: "Status", state: "New"}],
                    nextOrderStates:[{stateName:"Status",currentState:"New",state:"Submitted"}]) 
                {name}
            }`;
}

function GetOrderTags(order) {
    if (order.options) {
        var options = order.options.map(x => `{tagName:"${x.group_name}",tag:"${x.name}",price:${x.price},quantity:${x.quantity}}`);
        if (order.instructions) {
            options.push(`{tagName:"Default",tag:"Instructions",note:"${order.instructions}"}`);
        }
        var result = options.join();
        return `tags:[${result}],`
    }
    return "";
}

function GetPortions(order) {
    if (order.portions) {
        var portions = order.portions.map(x => `portion:"${x.name}",`);
        var result = portions.join();
        return `${result}`
    }
    return "";
}

function GetOrderPrice(order) {
    if (order.portions) {
        var price = order.portions.map(x => `price:${Math.abs((x.price) + (order.price))},`);
        var result = price.join();
        return `${result}`
    }
    if (order.price > 0)
        return `price:${order.price},`;
    return "";

}

function getAddTicketScript(orders, customerName, newCustomer, instructions, fulfill_at, services, payment) {
    var orderLines = orders.map(order => {
        return `{
            name:"${order.sambaName ? order.sambaName : order.name}",
            menuItemName:"${order.sambaName === miscProductName ? order.name : ''}",
            quantity:${order.quantity > 0 ? order.quantity : 1},
            ${GetPortions(order)}
            ${GetOrderPrice(order)}
            ${GetOrderTags(order)}
            states:[
                {stateName:"Status",state:"Submitted"}
            ]
        }`;
    });

    var entityPart = customerName ?
        `entities:[{entityType:"${customerEntityType}",name:"${customerName}"}],` :
        '';
    var calculationsPart = services ?
        `calculations:[${services.map(x => `{name:"${x.name}",amount:${x.amount}}`).join()}],` :
        '';

    var result = `
        mutation m{addTicket(
            ticket:{type:"${ticketType}",
                department:"${departmentName}",
                user:"${userName}",
                terminal:"${terminalName}",
                note:"${instructions !== null ? instructions : ''}",
                ${entityPart}
                states:[
                    {stateName:"Status",state:"Unpaid"},
                    {stateName:"Source",state:"Gloria"},
                    {stateName:"Payment",state:"${payment}"}
                ],
                tags:[{tagName:"Cook Time Minutes",tag:"${Math.ceil(Math.abs(new Date(fulfill_at) - Date.now()) / 60000)}"}],
                ${calculationsPart}
                orders:[${orderLines.join()}]
            }){id}}`;
    return result;
}

function processItem(item) {
    var result = {
        id: item.id,
        name: item.name,
        type: item.type,
        price: item.price,
        quantity: item.quantity,
        instructions: item.instructions,
        options: item.options.filter(x => x.type === 'option').map(x => {
            return {
                group_name: x.group_name,
                name: x.name,
                quantity: x.quantity,
                price: x.price
            }
        }),
        portions: item.options.filter(x => x.type === 'size').map(x => {
            return {
                name: x.name,
                price: x.price
            }
        })
    };
    return result;
}