const utils = require('../../pdm-dsu-toolkit/services/utils');
const {STATUS_MOUNT_PATH, INFO_PATH} = require('../constants');
const GRANULARITY = [10000, 1000, 100, 10, 1]; // amounts to 10000 packs per biggest container
const {Shipment, ShipmentLine, ShipmentCode, TrackingCode} = require('../model');
/**
* @param {string} domain: anchoring domain. defaults to 'default'
* @param {strategy} strategy
* @function ShipmentCodeService
* @memberOf Services
*/
function ShipmentCodeService(domain, strategy){
const strategies = require("../../pdm-dsu-toolkit/services/strategy");
const endpoint = 'shipmentcode';
domain = domain || "default";
let isSimple = strategies.SIMPLE === (strategy || strategies.SIMPLE);
this.getContainerGranularity = () => GRANULARITY.slice();
/**
* Resolves the DSU and loads the OrderLine object with all its properties, mutable or not
* @param {KeySSI} keySSI
* @param {function(err, OrderLine)} callback
*/
this.get = function(keySSI, callback){
utils.getResolver().loadDSU(keySSI, (err, dsu) => {
if (err)
return callback(err);
dsu.readFile(INFO_PATH, (err, data) => {
if (err)
return callback(err);
try{
const orderLine = JSON.parse(data);
dsu.readFile(`${STATUS_MOUNT_PATH}${INFO_PATH}`, (err, status) => {
if (err)
return callback(`could not retrieve shipmentLine status`);
try{
orderLine.status = JSON.parse(status);
callback(undefined, orderLine);
} catch (e) {
callback(`unable to parse ShipmentLine status: ${data.toString()}`);
}
});
} catch (e){
callback(`Could not parse ShipmentLine in DSU ${keySSI.getIdentifier()}`);
}
})
});
}
/**
* Creates an orderLine DSU
* @param {ShipmentCode} shipmentCode
* @param {function} callback
* @param {KeySSI} statusSSI the keySSI for the OrderStus DSU
* @return {string} keySSI
*/
this.create = function(shipmentCode, statusSSI, callback){
let data = typeof shipmentCode == 'object' ? JSON.stringify(shipmentCode) : shipmentCode;
if (isSimple){
let keyGenFunction = require('../commands/setShipmentCodeSSI').createShipmentCodeSSI;
let keySSI = keyGenFunction('shipmentcode', domain);
utils.selectMethod(keySSI)(keySSI, (err, dsu) => {
if (err)
return callback(err);
const cb = function(err, ...results){
if (err)
return dsu.cancelBatch(err2 => {
callback(err);
});
callback(undefined, ...results);
}
try {
dsu.beginBatch();
} catch (e) {
return callback(e);
}
dsu.writeFile(INFO_PATH, data, (err) => {
if (err)
return cb(err);
dsu.mount(STATUS_MOUNT_PATH, statusSSI.getIdentifier(), (err) => {
if (err)
return cb(err);
dsu.commitBatch((err) => {
if (err)
return cb(err);
dsu.getKeySSIAsObject(callback);
});
});
});
});
} else {
let getEndpointData = function (shipmentId, senderId, shipmentLine){
return {
endpoint: endpoint,
data: {
gtin: shipmentLine.gtin,
senderId: senderId,
shipmentId: shipmentId
}
}
}
utils.getDSUService().create(domain, getEndpointData(shipmentId, senderId, shipmentLine), (builder, cb) => {
builder.addFileDataToDossier(INFO_PATH, data, cb);
}, callback);
}
};
this.fromShipment = function(shipment, statusSSI, dsu, callback){
const self = this;
if (!callback && typeof dsu === 'function'){
callback = dsu;
dsu = undefined;
}
const fallbackCreate = function(){
self.create(shipment.status, statusSSI, (err, shipmentCodeDSU) => err
? callback(err)
: self.fromShipment(shipment, statusSSI, shipmentCodeDSU, callback));
}
const storeStatusInOuterCode = function (dsu, statusSSI, callback){
dsu.mount(STATUS_MOUNT_PATH, statusSSI, callback);
}
const createShipmentCodesRecursively = function(){
const lines = [];
const orderLineIterator = function(orderLinesCopy, callback){
const orderLine = orderLinesCopy.shift();
if (!orderLine)
return callback();
}
}
if (!dsu)
return fallbackCreate();
if (!statusSSI)
return createShipmentCodesRecursively();
storeStatusInOuterCode(dsu, statusSSI, (err) => err
? callback(err)
: createShipmentCodesRecursively())
}
}
function getTrackingData(shipmentLine, granularity){
const {gtin, batch, quantity} = shipmentLine;
function splitIntoTrackingCodes(quantity, granularity){
function getFirstGranularity(granularity, quantity){
return granularity.find(g => g <= quantity);
}
function decrementQuantity(quantity, decrement){
return quantity - decrement;
}
function joinAsTrackingCode(code1, code2){
}
const g = getFirstGranularity(granularity, quantity);
const remainder = quantity % g;
if (remainder === 0)
return {
code: new TrackingCode(splitIntoTrackingCodes(shipmentLine, granularity.slice(1))),
remainder: undefined
};
const mainDecremented = decrementQuantity(shipmentLine, remainder);
return {
code: new TrackingCode(splitIntoTrackingCodes(mainDecremented, granularity.slice(1))),
remainder: undefined
};
}
return result;
}
module.exports = ShipmentCodeService;
Source