Commit 78d0a616 authored by Abdelhadi's avatar Abdelhadi

final release

parents
# LXP API Connector
The Classification Service Connector fetches the production plan from the ERP systems of two different company. For common products, this connector allows to upload generated Manufacturing Orders at non-confirmed status. Then, a production sequence analysis is done which return a Boolean to know if this sequence is relevant.
## Requirements
- Docker
- Internet connection
## Installation
Clone this repository with:
```
git clone https://engagementhub.caixamagica.pt/virtual-factory-operating-system/io-toolkit/api-connectors/classification-api-connector.git
cd classification-api-connector
docker build -t="classification" .
```
You can now execute the docker by the following command:
```
docker run -p 3000:3000 classification
```
## Functionnalities
The **classification Connector** provide some services for instance:
- ***CheckManufacturingOrderConsistency*** service analyse a production sequence in json input to know if the sequence is relevant or not and return a Boolean
## Endpoints
The **Classification Connector** provides the following endoints:
- ***POST /classificationModels/CheckManufacturingOrderConsistency --body {'json':{#product_sequence}}***
The **Classification Connector** services are accessibles by REST request which are describe and can be tested in the loopback interface at: [localhost:3000/explorer](localhost:3000/explorer)
![Classification Connector testing UI](https://drive.google.com/file/d/19fmjXiXTuUd_Z0ObjNtHuQTURpz3Di8R/view?usp=sharing)
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
/client/
\ No newline at end of file
{
"extends": "loopback"
}
\ No newline at end of file
*.csv
*.dat
*.iml
*.log
*.out
*.pid
*.seed
*.sublime-*
*.swo
*.swp
*.tgz
*.xml
.DS_Store
.idea
.project
.strong-pm
coverage
node_modules
npm-debug.log
{
"generator-loopback": {}
}
\ No newline at end of file
FROM node:8
LABEL vf-OS=true
LABEL vf-OS.author="lCoste l.coste@univ-lyon2.fr"
LABEL vf-OS.name="classificationConnector"
LABEL vf-OS.description="classification Connector for node"
LABEL vf-OS.processEndPoints="[{"name":"CheckManufacturingOrderConsistency","method":"POST","uri":"/CheckManufacturingOrderConsistency","inputs":[{"section":"form","name":"json","type":{"name":"Object"},"isRequired":false}],"output":[{"name":"result", "type":"boolean"}],"header":[{"name":"Content-Type","value":"application/json"}]}]"
WORKDIR /usr/src/app
COPY * ./
RUN npm install
EXPOSE 8080
CMD [ "npm", "start", "classification" ]
\ No newline at end of file
## Client
This is the place for your application front-end files.
let DateDiff = require('date-diff');
var product;
var subProduct;
//console.log("produit", produit);
module.exports = function(classificationModel)
{
classificationModel.CheckManufacturingOrderConsistency = function(json, callback)
{
console.log(json);
//project = JSON.parse(json);
product = json; //project;
try{
var result = displayTreeNode(product);
console.log(result);
callback(result);
} catch(err) {
var result = err;
callback(result);
}
}
function displayTreeNode(node)
{
console.log(node.produit);
// noeud suivant
if (node.sous_produit != null)
{
if (node.sous_produit.length > 1)
{
for (var i = 0; i < node.sous_produit.length; i++) {
if (checkManufacturer(node, node.sous_produit[i]) == false)
{
return false;
}
displayTreeNode(node.sous_produit[i]);
}
}
else
{
if (checkManufacturer(node, node.sous_produit) == false)
{
return false;
}
displayTreeNode(node.sous_produit);
}
}
return true;
}
function checkManufacturer(product, subProduct)
{
//console.log(product.produit + " manufacterd by : " + product.fabricant);
if (product.fabricant != subProduct.fabricant)
{
if (subProduct.date_livraison != null)
{
var productDate = setDate(product.date_debut);
var subProductDate = setDate(subProduct.date_livraison);
var diff = new DateDiff(productDate, subProductDate);
if (diff.days() < 0)
{
return false;
}
}
}
return true;
}
function setDate(date)
{
return new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0,2));
}
classificationModel.remoteMethod('CheckManufacturingOrderConsistency',
{
isStatic: true,
accepts:
[ { arg: 'json',
type: 'Object',
description: 'project MO organisation',
required: false,
http: { source: 'form' } } ],
produces:['boolean'],
returns: {arg: 'result', type: 'boolean'},
http: { verb: 'post', path: '/CheckManufacturingOrderConsistency' },
description: undefined }
);
}
\ No newline at end of file
{
"name": "classificationModel",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "deploy",
"version": "1.0.0",
"main": "server/server.js",
"engines": {
"node": ">=4"
},
"scripts": {
"lint": "eslint .",
"start": "node .",
"posttest": "npm run lint && nsp check"
},
"dependencies": {
"compression": "^1.0.3",
"cors": "^2.5.2",
"helmet": "^3.10.0",
"loopback-boot": "^2.6.5",
"serve-favicon": "^2.0.1",
"strong-error-handler": "^2.0.0",
"loopback-component-explorer": "^6.0.0",
"loopback": "^3.19.0",
"date-diff": "^0.2.1"
},
"devDependencies": {
"eslint": "^3.17.1",
"eslint-config-loopback": "^8.0.0",
"nsp": "^2.1.0",
"date-diff": "^0.2.1"
},
"repository": {
"type": "",
"url": ""
},
"license": "UNLICENSED",
"description": "deploy"
}
'use strict';
module.exports = function(server) {
// Install a `/` route that returns server status
var router = server.loopback.Router();
router.get('/', server.loopback.status());
server.use(router);
};
{
"loopback-component-explorer": {
"mountPath": "/explorer",
"generateOperationScopedModels": true
}
}
{
"restApiRoot": "/api",
"host": "0.0.0.0",
"port": 3000,
"remoting": {
"context": false,
"rest": {
"handleErrors": false,
"normalizeHttpPath": false,
"xml": false
},
"json": {
"strict": false,
"limit": "100kb"
},
"urlencoded": {
"extended": true,
"limit": "100kb"
},
"cors": false
}
}
{
"final:after": {
"strong-error-handler": {
"params": {
"debug": true,
"log": true
}
}
}
}
{
"initial:before": {
"loopback#favicon": {}
},
"initial": {
"compression": {},
"cors": {
"params": {
"origin": true,
"credentials": true,
"maxAge": 86400
}
},
"helmet#xssFilter": {},
"helmet#frameguard": {
"params": { "action": "deny" }
},
"helmet#hsts": {
"params": {
"maxAge": 0,
"includeSubdomains": true
}
},
"helmet#hidePoweredBy": {},
"helmet#ieNoOpen": {},
"helmet#noSniff": {},
"helmet#noCache": {
"enabled": false
}
},
"session": {},
"auth": {},
"parse": {},
"routes": {
"loopback#rest": {
"paths": [
"${restApiRoot}"
]
}
},
"files": {},
"final": {
"loopback#urlNotFound": {}
},
"final:after": {
"strong-error-handler": {}
}
}
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"loopback/server/mixins",
"../common/mixins",
"./mixins"
]
},
"classificationModel": {
"dataSource": null,
"public": true
}
}
\ No newline at end of file
'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module)
app.start();
});
{
"vf-OS" : true,
"author" : "lCoste l.coste@univ-lyon2.fr",
"name" : "classificationConnector",
"description" : "classification Connector for node",
"processEndPoints":[{"name":"CheckManufacturingOrderConsistency","method":"POST","uri":"/CheckManufacturingOrderConsistency","inputs":[{"section":"body","name":"json","type":{"name":"string"},"isRequired":false}],"output":[{"name":"result", "type":"boolean"}],"header":[{"name":"Content-Type","value":"application/json"}]}]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment