[
    {
        "id": "d75dd96899f2f8c0",
        "type": "subflow",
        "name": "Get Products from MIP",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 40,
                "y": 80,
                "wires": [
                    {
                        "id": "85081c4f92039982"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 1560,
                "y": 80,
                "wires": [
                    {
                        "id": "b7b57f63e3f252fb",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "d4f2b19af0006d7e",
        "type": "http request",
        "z": "d75dd96899f2f8c0",
        "name": "service call to MIP",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "x": 370,
        "y": 80,
        "wires": [
            [
                "468aba4576d29785"
            ]
        ]
    },
    {
        "id": "85081c4f92039982",
        "type": "function",
        "z": "d75dd96899f2f8c0",
        "name": "build request",
        "func": "msg.payload = { \n    \"params\": [], \n    \"columns\": [        \n        \"operation.article\", \n        \"operation.cycle.target\"\n    ], \n    \"returnAsObject\": true,\n    \"languageKey\": msg.languageKey\n}\n\nmsg.url = msg.baseUrl + \"/data/BOOperation/list?X-Access-Id=\" + msg.xAccessId\n\nlet basic_encrypted = \"Basic \" + new Buffer(msg.user + ':' + msg.password).toString('base64')\n\nmsg.headers = { \n    \"Content-Type\": \"application/json\",\n    \"Authorization\": basic_encrypted\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 190,
        "y": 80,
        "wires": [
            [
                "d4f2b19af0006d7e"
            ]
        ]
    },
    {
        "id": "781afa9d17c05f7d",
        "type": "split",
        "z": "d75dd96899f2f8c0",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 1230,
        "y": 80,
        "wires": [
            [
                "b7b57f63e3f252fb"
            ]
        ]
    },
    {
        "id": "468aba4576d29785",
        "type": "change",
        "z": "d75dd96899f2f8c0",
        "name": "Clean up for next requests",
        "rules": [
            {
                "t": "delete",
                "p": "headers",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "url",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 600,
        "y": 80,
        "wires": [
            [
                "e0df0481fabecdac"
            ]
        ]
    },
    {
        "id": "e0df0481fabecdac",
        "type": "change",
        "z": "d75dd96899f2f8c0",
        "name": "Delete META data",
        "rules": [
            {
                "t": "delete",
                "p": "payload[0]",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 830,
        "y": 80,
        "wires": [
            [
                "0eaf3e7b6e0a45b5"
            ]
        ]
    },
    {
        "id": "0eaf3e7b6e0a45b5",
        "type": "function",
        "z": "d75dd96899f2f8c0",
        "name": "Remove doubles",
        "func": "const uniqueData = msg.payload.filter((v, i, a) => {\n  const operationArticle = v.obj['operation.article'];\n  // Check if operation.article exists and is unique\n  return operationArticle && a.findIndex(t => t.obj['operation.article'] === operationArticle) === i;\n});\n\nmsg.payload = uniqueData;\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1050,
        "y": 80,
        "wires": [
            [
                "781afa9d17c05f7d"
            ]
        ]
    },
    {
        "id": "b7b57f63e3f252fb",
        "type": "function",
        "z": "d75dd96899f2f8c0",
        "name": "calculate target-speed",
        "func": "const time_for_1k = msg.payload.obj[\"operation.cycle.target\"];\n// MIP saves time for 1000 products in seconds\nif(time_for_1k){\n    msg[\"target-speed\"] = time_for_1k / 1000;  \n}else{\n    msg[\"target-speed\"] = 1;\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1400,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "add565707d291876",
        "type": "subflow",
        "name": "Post products",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 220,
                "y": 220,
                "wires": [
                    {
                        "id": "7ef5e7c148cf0a7b"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 800,
                "y": 220,
                "wires": [
                    {
                        "id": "db341d98f56b996c",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "7ef5e7c148cf0a7b",
        "type": "function",
        "z": "add565707d291876",
        "name": "Formatting json payload",
        "func": "msg.headers = {\n    \"Content-Type\": \"application/vnd.api+json\",\n    \"Authorization\": \"Bearer \" + msg.bearerToken\n}\n\nmsg.payload = {\n    \"data\": {\n        \"type\": \"products\",\n        \"attributes\": {\n            \"code\": msg.code,\n            \"description\": msg.description,\n            \"color\": msg.color,\n            \"production-unit\": msg[\"production-unit\"],\n            \"cycle-time-mode\": msg[\"cycle-time-mode\"],\n            \"cycle-time-unit\": msg[\"cycle-time-unit\"],\n            \"target-speed\": msg[\"target-speed\"],\n            \"units-multiplier\": msg[\"units-multiplier\"],\n            \"units-divisor\": msg[\"units-divisor\"],\n            \"info\": msg.info\n        },\n        \"relationships\": {\n            \"location\": {\n                \"data\": {\n                    \"type\": \"locations\",\n                    \"id\": msg.location\n                }\n            }\n        }\n    }\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 220,
        "wires": [
            [
                "db341d98f56b996c"
            ]
        ]
    },
    {
        "id": "db341d98f56b996c",
        "type": "http request",
        "z": "add565707d291876",
        "name": "POST product to oee.ai",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.oee.ai/products",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "x": 630,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "f51662145c16c667",
        "type": "subflow",
        "name": "Patch products",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 180,
                "y": 160,
                "wires": [
                    {
                        "id": "ee5989b6e6bd58a3"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 2220,
                "y": 160,
                "wires": [
                    {
                        "id": "b5ec8138a6de0f03",
                        "port": 0
                    },
                    {
                        "id": "6d0db9f101177a9c",
                        "port": 1
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "084fb25d157ed9ce",
        "type": "http request",
        "z": "f51662145c16c667",
        "name": "Get existing product",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.oee.ai/products?filter[code-or-description]={{{code}}}&filter[location]={{{location}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "x": 840,
        "y": 160,
        "wires": [
            [
                "6d0db9f101177a9c"
            ]
        ]
    },
    {
        "id": "d82019c0b8785004",
        "type": "function",
        "z": "f51662145c16c667",
        "name": "Formatting json payload",
        "func": "msg.headers = {\n    \"Content-Type\": \"application/vnd.api+json\",\n    \"Authorization\": \"Bearer \" + msg.bearerToken\n};\n\nmsg.method = \"PATCH\";\n\nmsg.oldProductId = msg.payload.data[0].id;\n\nmsg.payload = {\n    \"data\": {\n        \"id\": msg.oldProductId,\n        \"type\": \"products\",\n        \"attributes\": {\n            \"code\": msg.code,\n            \"description\": msg.description,\n            \"color\": msg.color,\n            \"production-unit\": msg[\"production-unit\"],\n            \"cycle-time-mode\": msg[\"cycle-time-mode\"],\n            \"cycle-time-unit\": msg[\"cycle-time-unit\"],\n            \"target-speed\": msg[\"target-speed\"],\n            \"units-multiplier\": msg[\"units-multiplier\"],\n            \"units-divisor\": msg[\"units-divisor\"],\n            \"info\": msg.info\n        },\n        \"relationships\": {\n            \"location\": {\n                \"data\": {\n                    \"type\": \"locations\",\n                    \"id\": msg.location\n                }\n            }\n        }\n    }\n};\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1570,
        "y": 140,
        "wires": [
            [
                "73946bc6e044dc90"
            ]
        ]
    },
    {
        "id": "73946bc6e044dc90",
        "type": "http request",
        "z": "f51662145c16c667",
        "name": "Patch product",
        "method": "use",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.oee.ai/products/{{{oldProductId}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "x": 1780,
        "y": 140,
        "wires": [
            [
                "b5ec8138a6de0f03"
            ]
        ]
    },
    {
        "id": "ee5989b6e6bd58a3",
        "type": "change",
        "z": "f51662145c16c667",
        "name": "delete response header",
        "rules": [
            {
                "t": "delete",
                "p": "headers",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 370,
        "y": 160,
        "wires": [
            [
                "0e90fa88568de2a6"
            ]
        ]
    },
    {
        "id": "5794069f51aa5752",
        "type": "change",
        "z": "f51662145c16c667",
        "name": "delete response header",
        "rules": [
            {
                "t": "delete",
                "p": "headers",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1330,
        "y": 140,
        "wires": [
            [
                "d82019c0b8785004"
            ]
        ]
    },
    {
        "id": "0e90fa88568de2a6",
        "type": "function",
        "z": "f51662145c16c667",
        "name": "Set Authorization header",
        "func": "msg.headers = {\n    \"Authorization\": \"Bearer \" + msg.bearerToken\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 610,
        "y": 160,
        "wires": [
            [
                "084fb25d157ed9ce"
            ]
        ]
    },
    {
        "id": "6d0db9f101177a9c",
        "type": "function",
        "z": "f51662145c16c667",
        "name": "Check if product changed",
        "func": "function compareProperties(a, b, properties) {\n  return properties.every(prop => {\n      if (prop == 'target-speed'){\n        if (parseFloat(a[prop]) == parseFloat(b[prop])){\n            return true;\n        }else{\n            return false;\n        }\n      }else{\n        if(a[prop] == b[prop]){\n            return true;\n        }else{\n            return false;\n        }\n      }});\n}\n\nlet existingProduct = {}\n// potential bug when product code is substring of other product i.e. h123 and h123-02\nif (msg.payload.data.length > 1){\n    existingProduct = msg.payload.data.find(entry => entry.attributes.code == msg.code).attributes;\n}else{\n    existingProduct = msg.payload.data[0].attributes;\n}\n\nlet propertiesToCompare = [\n  'code',\n  'description',\n  'target-speed',\n  'info',\n  'color',\n  'production-unit',\n  'cycle-time-mode',\n  'units-multiplier',\n  'units-divisor'\n];\n\nif (compareProperties(existingProduct, msg, propertiesToCompare)) {\n  return [null, msg];\n}\n\nreturn [msg, null]",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1090,
        "y": 160,
        "wires": [
            [
                "5794069f51aa5752"
            ],
            []
        ]
    },
    {
        "id": "b5ec8138a6de0f03",
        "type": "change",
        "z": "f51662145c16c667",
        "name": "delete response header and method",
        "rules": [
            {
                "t": "delete",
                "p": "headers",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "method",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 2030,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "d644b32827ab5ff7",
        "type": "subflow",
        "name": "Send products to oee.ai",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 140,
                "y": 260,
                "wires": [
                    {
                        "id": "c989c8789ff6d538"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 1060,
                "y": 260,
                "wires": [
                    {
                        "id": "81d1d177247aa9df",
                        "port": 1
                    },
                    {
                        "id": "a575dcb265c27b3d",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "81d1d177247aa9df",
        "type": "switch",
        "z": "d644b32827ab5ff7",
        "name": "Check if product already exists",
        "property": "statusCode",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "422",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 2,
        "x": 530,
        "y": 260,
        "wires": [
            [
                "a575dcb265c27b3d"
            ],
            [
                "4f0f204355cbaa5e"
            ]
        ]
    },
    {
        "id": "a575dcb265c27b3d",
        "type": "subflow:f51662145c16c667",
        "z": "d644b32827ab5ff7",
        "name": "",
        "x": 780,
        "y": 220,
        "wires": [
            [
                "91effa9eddfb437c"
            ]
        ]
    },
    {
        "id": "c989c8789ff6d538",
        "type": "subflow:add565707d291876",
        "z": "d644b32827ab5ff7",
        "name": "",
        "x": 290,
        "y": 260,
        "wires": [
            [
                "81d1d177247aa9df"
            ]
        ]
    },
    {
        "id": "91effa9eddfb437c",
        "type": "debug",
        "z": "d644b32827ab5ff7",
        "name": "PATCH",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 200,
        "wires": []
    },
    {
        "id": "4f0f204355cbaa5e",
        "type": "debug",
        "z": "d644b32827ab5ff7",
        "name": "POST",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1110,
        "y": 320,
        "wires": []
    },
    {
        "id": "086fd29526322b8c",
        "type": "tab",
        "label": "MIP synchronizing products",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "c278c920c52a1349",
        "type": "comment",
        "z": "086fd29526322b8c",
        "name": "^^ enter your oee.ai API token",
        "info": "You can find your API Token on oee.ai",
        "x": 1200,
        "y": 340,
        "wires": []
    },
    {
        "id": "af161a2441ca5b23",
        "type": "inject",
        "z": "086fd29526322b8c",
        "name": "Every day",
        "props": [],
        "repeat": "86400",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 230,
        "y": 300,
        "wires": [
            [
                "89484017d0956c14"
            ]
        ]
    },
    {
        "id": "b29ba189327b6eff",
        "type": "change",
        "z": "086fd29526322b8c",
        "name": "Set API Token",
        "rules": [
            {
                "t": "set",
                "p": "bearerToken",
                "pt": "msg",
                "to": "",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1160,
        "y": 300,
        "wires": [
            [
                "20deeb57a8500fa5"
            ]
        ]
    },
    {
        "id": "70338f0a7c377091",
        "type": "change",
        "z": "086fd29526322b8c",
        "name": "Mapping product attributes",
        "rules": [
            {
                "t": "set",
                "p": "code",
                "pt": "msg",
                "to": "payload.obj[\"operation.article\"]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "description",
                "pt": "msg",
                "to": "payload.obj[\"operation.article\"]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "color",
                "pt": "msg",
                "to": "red",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "production-unit",
                "pt": "msg",
                "to": "parts",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "cycle-time-mode",
                "pt": "msg",
                "to": "time_per_part",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "cycle-time-unit",
                "pt": "msg",
                "to": "seconds",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "target-speed",
                "pt": "msg",
                "to": "target-speed",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "units-multiplier",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "units-divisor",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "info",
                "pt": "msg",
                "to": "",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "location",
                "pt": "msg",
                "to": "",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 920,
        "y": 300,
        "wires": [
            [
                "b29ba189327b6eff"
            ]
        ]
    },
    {
        "id": "922a3dcbfd4210f3",
        "type": "comment",
        "z": "086fd29526322b8c",
        "name": "^^ set product attributes",
        "info": "Format your message to the data model of oee.ai\nThen map your message values to the predefined\nmessage values in the change node",
        "x": 910,
        "y": 340,
        "wires": []
    },
    {
        "id": "20deeb57a8500fa5",
        "type": "subflow:d644b32827ab5ff7",
        "z": "086fd29526322b8c",
        "name": "",
        "x": 1450,
        "y": 300,
        "wires": [
            []
        ]
    },
    {
        "id": "89484017d0956c14",
        "type": "change",
        "z": "086fd29526322b8c",
        "name": "set settings",
        "rules": [
            {
                "t": "set",
                "p": "baseUrl",
                "pt": "msg",
                "to": "",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "user",
                "pt": "msg",
                "to": "",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "password",
                "pt": "msg",
                "to": "",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "xAccessId",
                "pt": "msg",
                "to": "",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "languageKey",
                "pt": "msg",
                "to": "en",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 410,
        "y": 300,
        "wires": [
            [
                "82c5a3ed0338ddcd"
            ]
        ]
    },
    {
        "id": "82c5a3ed0338ddcd",
        "type": "subflow:d75dd96899f2f8c0",
        "z": "086fd29526322b8c",
        "name": "Get Products from MIP",
        "x": 630,
        "y": 300,
        "wires": [
            [
                "70338f0a7c377091"
            ]
        ]
    },
    {
        "id": "5061268859da56e2",
        "type": "comment",
        "z": "086fd29526322b8c",
        "name": "^^ configure settings",
        "info": "",
        "x": 440,
        "y": 340,
        "wires": []
    }
]