forked from mykle1/MMM-AfterShip
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathnormalize-tracktry.js
111 lines (101 loc) · 3.95 KB
/
normalize-tracktry.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*******************************/
/* Normalizer to prepare for various interfaces
/* MMM-Parcel
/* Martin Kooij
/* 2021
/*******************************/
var moment = require('moment');
function normalize(rawList) { // normalize for Tracktry Interface
const statMap = new Map();
var list = [];
if ( !Array.isArray(rawList)) { return (list)}
setMap(statMap) ;
for (const rawItem of rawList) {
var item = {
courier_name : "",
courier_code : "no_courier",
status : "exception",
tobe_collected: false,
substatus : null,
tracking_code : "No track",
title : "" ,
updated_time : "2000-01-01",
expected_deliverytime : "2000-01-01",
last_loc: null
} ;
try {
var lastLoc = {} ;
item.courier_name = null ;
item.courier_code = rawItem.carrier_code ;
item.tobe_collected = (rawItem.status === "pickup") ;
item.status = statMap.get(rawItem.status)?statMap.get(rawItem.status):"pending" ; // only known statuses are passed all others are mapped to "pending"
item.tracking_code = rawItem.tracking_number ;
item.title = rawItem.title?rawItem.title:(rawItem.order_id?rawItem.order_id:"") ; // use title or order_id as title
item.title = string_tidy(item.title);
item.updated_time = rawItem.updated_at ;
item.expected_deliverytime = null ;
item.substatus = null ;
const rawLoc_o = (rawItem.origin_info && rawItem.origin_info.trackinfo && rawItem.origin_info.trackinfo[0]) ;
const rawLoc_d = (rawItem.destination_info && rawItem.destination_info.trackinfo && rawItem.destination_info.trackinfo[0]) ;
const rawLoc = newest(rawLoc_o,rawLoc_d);
if (rawLoc) {
lastLoc.time = adaptTime(item,rawLoc.Date) ;
lastLoc.info = rawLoc.StatusDescription.trim() ;
lastLoc.details = rawLoc.Details.trim() ;
item.substatus = rawLoc.substatus ; // note that this is moved to toplayer
}
item.last_loc = (Object.keys(lastLoc).length > 0)?lastLoc:null; ;
} catch(e) { console.log ('[ERROR NORMALIZING Parcel in MMM-Parcel]', e, rawItem);} ;
list.push(item) ;
}
return list ;
}
function setMap(map) {
//defaults
statusList = ["exception","undelivered", "indelivery", "transit", "pending", "notfound", "delivered", "expired"] ;
statusList.forEach( (v) => map.set(v,v) ) ;
//extra mappings
map.set("InfoReceived","pending") ; // UPS
map.set("pickup", "delivered") ; // map pickup status to delivered
}
function printMap(map) {
map.forEach( (v,k) => console.log('<',k,',',v,'>' )) ;
}
function adaptTime(item,t) {
if (item.courier_code === "postnl-3s") {
if (t && !t.includes("-", 11) && !t.includes("+", 11) ) {t = t.trim()+"+0700"}; // adjust time at postnl-3s if no TZ given
}
return t // no adjustments known for other couriers
}
function newest(loc1,loc2) {
if (!loc1 && !loc2){ return null ;}
if (!loc1 && loc2) { return loc2 ;}
if (!loc2 && loc1) { return loc1 ;}
if (moment(loc1.Date) < moment(loc2.Date)) {return loc2;}
return loc1 ;
}
function string_tidy(str) {
return str.replace(/\\'/i,"'");
}
module.exports = normalize ;
/******************** DEFINITION of normalized RESULT ****************
/* [
/* {
/* courier_name : full text name of courier if available (not used in MMM-Parcel),
/* courier : short code of courier,
/* status : one of "exception","undelivered", "pickup", "transit", "pending", "notfound", "delivered", "expired",
/* substatus : substatus (see internet, not (yet) used in MMM-Parcel)
/* tracking_code : tracking identifier ;
/* title : text title ,
/* updated_time :last updated time ( parsable time string),
/* expected_deliverytime : expected delivery time if available (parsable time string, not used in MMM-Parcel),
/* last_loc :
/* {
/* time : time at this location event,
/* info : textual description of status at location,
/* details : extra details (city, state, country, etc. depending on availbility in API)
/* }
/* } ,
/* ...
/* ]
/****************************************************************************/