Advertisement
Guest User

Untitled

a guest
Jan 17th, 2020
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.01 KB | None | 0 0
  1. /*model*/ {
  2. function Item (json) {
  3. this.name = json.name;
  4. }
  5.  
  6. function Product (json) {
  7. this.sku = json.sku;
  8. this.price = json.price;
  9. //if (!(json.sku && json.price)) throw JSON.stringify(this, null, 2);
  10. }
  11.  
  12. function Order (json) {
  13. this.name = json.name;
  14. this.tax = parseFloat(json.tax);
  15. this.country = json.country;
  16. this.city = json.city;
  17. this.address = json.address;
  18. this.exchangeRate = parseFloat(json.exchangeRate);
  19. this.invoiceId = parseInt(json.invoiceId);
  20. this.invoiceYear = parseInt(json.invoiceYear);
  21. this.shippingDate = json.shippingDate;
  22. this.currency = json.currency;
  23. this.date = json.date
  24. this.id = parseInt(json.id);
  25. this.sku = json.sku ? json.sku.toString() : json.sku;
  26. this.quantity = parseInt(json.quantity);
  27. this.status = json.status;
  28. this.total = parseFloat(json.total);
  29. this.paymentMethod = json.paymentMethod;
  30. this.time = (new Date(json.date)).getTime();
  31. this.storno = json.storno;
  32. }
  33.  
  34. function Stock (json) {
  35. this.date = json.date;
  36. this.sku = json.sku ? json.sku.toString() : json.sku;
  37. this.quantity = parseInt(json.quantity);
  38. this.price = parseFloat(json.price);
  39. this.time = (new Date(json.date)).getTime();
  40. if (!(this.date && this.sku && this.quantity && this.price && this.time)) process.exit(Dump(this));
  41. }
  42.  
  43. }
  44.  
  45. /*validate*/ {
  46. function validateOrder (Order) {
  47. var e = [];
  48. if (!Order.paymentMethod) e.push('paymentMethod');
  49. if (!Order.shippingDate && !config.refundedStatus.includes(Order.status)) e.push('shippingDate');
  50. if (!Order.total) e.push('total');
  51. if (!Order.name) e.push('name');
  52. if (!Order.tax && Order.tax !== 0) e.push('tax');
  53. if (!Order.country) e.push('country');
  54. if (!Order.city) e.push('city');
  55. if (!Order.address) e.push('address');
  56. if (!Order.exchangeRate && (Order.time > config.exchangeRateStartTime || config.baseCurrency != Order.currency)) {
  57. if (config.refundedStatus.includes(Order.status)) {
  58. var stornoDigits = parseInt(Order.storno.replace('-', ''));
  59. var startStronoDigits = parseInt(config.exchangeRateStartStorno.replace('-', ''));
  60. if (stornoDigits > startStronoDigits) e.push('exchangeRate');
  61. }
  62. }
  63. if (!Order.invoiceId) e.push('invoiceId');
  64. if (!Order.invoiceYear) e.push('invoiceYear');
  65. if (!Order.currency) e.push('currency');
  66. if (!Order.date) e.push('date');
  67. if (!Order.id) e.push('id');
  68. if (!Order.sku) e.push('sku');
  69. if (!Order.quantity) e.push('quantity');
  70. if (!Order.time) e.push('time');
  71. if (!Order.status) e.push('status');
  72. if (!Order.storno && config.refundedStatus.includes(Order.status)) e.push('storno');
  73. if (e[0]) process.exit(Dump([Order, e]));
  74. }
  75. }
  76.  
  77. /*functions*/ {
  78. function readXlsx(dirname, onFileContent) {
  79. var filenames = fs.readdirSync(dirname);
  80. var jsons = [];
  81. for (i in filenames) {
  82. var filename = filenames[i];
  83. if (!filename.match(/\.xlsx$/)) return;
  84. var book = XLSX.readFile(dirname + filename);
  85. var sheets = book.SheetNames;
  86. var json = XLSX.utils.sheet_to_json(book.Sheets[sheets[0]]);
  87. jsons.push(json);
  88. }
  89. return jsons;
  90. }
  91.  
  92. function InventoryByTime(time) {
  93. var Inventory = {};
  94. Inventory["#date_time#"] = (new Date(time)).toLocaleString();
  95. Inventory["#missing#"] = [];
  96. for (var i = 0; i < Stocks.length; i++) {
  97. var Stock = Stocks[i];
  98. if (Stock.time > time) break;
  99. if (!Inventory[Stock.sku]) Inventory[Stock.sku] = [];
  100. Inventory[Stock.sku].push(iterationCopy(Stock));
  101. }
  102. //console.log(Inventory);
  103.  
  104. orders: for (i = 0; i < Orders.length; i++) {
  105. var Order = iterationCopy(Orders[i]);
  106. if (!config.completedStatus.includes(Order.status)) continue;
  107. if (Order.time > time) break;
  108. if (!Inventory[Order.sku] || Inventory[Order.sku][0].time > Order.time) {
  109. Inventory['#missing#'].push(iterationCopy(Order));
  110. continue;
  111. }
  112.  
  113. var j;
  114. for (j = 0; j < Inventory[Order.sku].length; j++) {
  115. var Stock = Inventory[Order.sku][j];
  116. if (Stock.quantity > 0 && Stock.time < Order.time) break;
  117. var nextStock = Inventory[Order.sku][j+1];
  118. if (!nextStock) break;
  119. if (Stock.time < Order.time && (!nextStock || nextStock.time > Order.time)) break;
  120. }
  121.  
  122. for (var k = 0; k < Order.quantity; k++) {
  123. var Stock = Inventory[Order.sku][j];
  124. var nextStock = Inventory[Order.sku][j+1];
  125. if (Stock.quantity == 0 && nextStock && nextStock.time < Order.time) {
  126. j++;
  127. k--;
  128. continue;
  129. }
  130. Stock.quantity--;
  131. }
  132. }
  133.  
  134. return Inventory;
  135. }
  136.  
  137. function areInvoicesContinous () {
  138.  
  139. var _Orders = [];
  140. for (i in Orders) {
  141. var Order = iterationCopy(Orders[i]);
  142. _Orders.push(Order);
  143. }
  144. _Orders = _Orders.sort(function (a, b) {
  145. return a.invoiceId - b.invoiceId;
  146. });
  147.  
  148. var years = {};
  149.  
  150. for (var i = 0; i < _Orders.length -1; i++) {
  151. var Order = _Orders[i];
  152. if (years[Order.invoiceYear]) years[Order.invoiceYear] = [];
  153. years[Order.invoiceYear].push(Order.invoiceId);
  154. }
  155.  
  156. var res = [];
  157. for (i in years) {
  158. var NextOrder = _Orders[i+1];
  159. if (NextOrder.invoiceId == Order.invoiceId || NextOrder.invoiceId == Order.invoiceId + 1) continue;
  160. if (NextOrder.invoiceYear != Order.invoiceYear) continue;
  161. res.push('missing invoiceId ' + (Order.invoiceId + 1) + ' invoiceYear ' + Order.invoiceYear);
  162. }
  163. return res;
  164.  
  165. }
  166.  
  167. function allCancelledHaveStorno() {
  168. var cancelled = [];
  169. var storno = [];
  170. for (i in Orders) {
  171. var Order = Orders[i];
  172. if (Order.storno && config.refundedStatus.includes(Order.status)) storno.push(Order.storno);
  173. if (Order.status == config.cancelledStatus) cancelled.push([Order.invoiceYear, Order.invoiceId].join('-'));
  174. }
  175.  
  176. var res = [];
  177. for (i in cancelled) {
  178. if (!storno.includes(cancelled[i])) res.push('missing cancelled ' + cancelled[i]);
  179. }
  180. for (i in storno) {
  181. if (!cancelled.includes(storno[i])) res.push('missing storno ' + storno[i]);
  182. }
  183. return res;
  184. }
  185.  
  186. function getDateTime() {
  187. return new Date().toLocaleString();
  188. }
  189.  
  190. function Dump (dump, format='json') {
  191. if (format == 'json') {
  192. dump = dump || {Stocks: Stocks, Orders: Orders, Products: Products};
  193. var folder = dir + '/dump/';
  194. var data = JSON.stringify(dump, null, 4);
  195. var time = new Date().getTime();
  196. var file = folder + time + '.json';
  197. fs.writeFileSync(file, data);
  198. console.log(time);
  199. return time;
  200. } else if (format == 'xlsx') {
  201.  
  202. }
  203.  
  204. /*var wb = XLSX.utils.book_new();
  205. var ws = XLSX.utils.json_to_sheet(dump);
  206. XLSX.utils.book_append_sheet(wb, ws);
  207. XLSX.writeFile(wb, folder + new Date().getTime() + '.xlsx');*/
  208. }
  209.  
  210. function findNegativeStocks () {
  211. var negative = {};
  212.  
  213. var times = [];
  214. for (i in Orders) {
  215. var Order = iterationCopy(Orders[i]);
  216. var time = [new Date(Order.time).toLocaleString(), Order.sku].join(' ');
  217. if (times.includes(time)) continue;
  218. var I = InventoryByTime(Order.time);
  219. I: for (j in I) {
  220. for (k in I[j]) {
  221. if (I[j][k].quantity < 0 && I[j][k].sku == Order.sku) {
  222. times.push(time);
  223. negative[time] = {Stock: I[j][k], Order: Order};
  224. break I;
  225. }
  226. }
  227. }
  228. }
  229. return negative;
  230. }
  231.  
  232. function invoiceReportByTimeInterval (time1=0, time2=Infinity) {
  233. var ids = [];
  234. var line = {
  235. name: null,
  236. country: null,
  237. city: null,
  238. address: null,
  239. invoiceYear: null,
  240. invoiceId: null,
  241. date: null,
  242. shippingDate: null,
  243. exchangeRate: null,
  244. tax: null,
  245. total: null,
  246. calcTaxEur: null,
  247. calcTotalEur: null,
  248. storno: null,
  249. paymentMethod: null,
  250. currency: null
  251. };
  252. var report = [];
  253. for (i in Orders) {
  254. var Order = iterationCopy(Orders[i]);
  255. if (ids.includes(Order.id)) continue;
  256. ids.push(Order.id);
  257. if (Order.time < time1 || Order.time > time2) continue;
  258. var r = {};
  259. r.id = Order.id;
  260. r.name = Order.name;
  261. r.country = Order.country;
  262. r.city = Order.city;
  263. r.address = Order.address;
  264. r.invoiceYear = Order.invoiceYear;
  265. r.invoiceId = Order.invoiceId;
  266. r.date = Order.date;
  267. r.shippingDate = Order.shippingDate;
  268. r.exchangeRate = Order.exchangeRate;
  269. r.tax = Order.tax;
  270. r.total = Order.total;
  271. r.calcTaxEur = r.tax / r.exchangeRate;
  272. r.calcTotalEur = r.total / r.exchangeRate;
  273. r.storno = Order.storno;
  274. r.paymentMethod = Order.paymentMethod;
  275. r.currency = Order.currency;
  276. report.push(r);
  277. }
  278. return report;
  279. }
  280.  
  281.  
  282. }
  283.  
  284. /*utils*/ {
  285. function isObject(obj) {
  286. var type = typeof obj;
  287. return type === 'function' || type === 'object' && !!obj;
  288. };
  289. function iterationCopy(src) {
  290. let target = {};
  291. for (let prop in src) {
  292. if (src.hasOwnProperty(prop)) {
  293. // if the value is a nested object, recursively copy all it's properties
  294. if (isObject(src[prop])) {
  295. target[prop] = iterationCopy(src[prop]);
  296. } else {
  297. target[prop] = src[prop];
  298. }
  299. }
  300. }
  301. return target;
  302. }
  303. }
  304.  
  305. /*view*/ {
  306. fs = require('fs');
  307. //path = require('path');
  308. XLSX = require('xlsx');
  309. dir = __dirname;
  310. args = process.argv.slice(2);
  311. config = require(dir + '/config.json');
  312. mode = args[0];
  313. }
  314.  
  315. /*controller*/ {
  316.  
  317. /*init*/ {
  318. Products = [];
  319. var jsons = readXlsx(dir + "/products/");
  320. for (i in jsons) {
  321. for (j in jsons[i]) {
  322. var json = jsons[i][j];
  323. var P = new Product(json);
  324. Products.push(P);
  325. }
  326. }
  327.  
  328. Orders = [];
  329. var jsons = readXlsx(dir + "/orders/");
  330. var filter = config.orderStatusFilter[0] ? config.orderStatusFilter : false;
  331. for (i in jsons) {
  332. for (j in jsons[i]) {
  333. var json = jsons[i][j];
  334. if (filter && !filter.includes(json.status)) continue;
  335. var O = new Order(json);
  336. validateOrder(O);
  337. //group by sku
  338. for (j in config.groupSkuByRegexp) {
  339. var search = config.groupSkuByRegexp[j];
  340. var rex = new RegExp(search);
  341. if (O.sku.toString().match(rex)) O.sku = search;
  342. }
  343.  
  344. Orders.push(O);
  345. }
  346. }
  347. Orders = Orders.sort(function (a, b) {
  348. return a.time - b.time;
  349. });
  350.  
  351.  
  352. Stocks = [];
  353. var jsons = readXlsx(dir + "/stocks/");
  354. for (i in jsons) {
  355. for (j in jsons[i]) {
  356. var json = jsons[i][j];
  357. var S = new Stock(json);
  358. for (j in config.groupSkuByRegexp) {
  359. var search = config.groupSkuByRegexp[j];
  360. var rex = new RegExp(search);
  361. if (S.sku.toString().match(rex)) S.sku = search;
  362. }
  363. Stocks.push(S);
  364. }
  365. }
  366. Stocks = Stocks.sort(function (a, b) {
  367. return a.time - b.time;
  368. });
  369.  
  370. }
  371.  
  372. if (mode == 6) {
  373. time = new Date(args[1]).getTime();
  374. var I = InventoryByTime(time);
  375. process.exit(Dump(I));
  376. } else if (mode == 1) {
  377. var res = areInvoicesContinous();
  378. process.exit(Dump(res));
  379. } else if (mode == 2) {
  380. process.exit(Dump());
  381. } else if (mode == 3) {
  382. var ne = findNegativeStocks();
  383. process.exit(Dump(ne));
  384. } else if (mode == 4) {
  385. var res = allCancelledHaveStorno();
  386. process.exit(Dump(res));
  387. } else if (mode == 5) {
  388. var time1 = new Date(args[1]).getTime() || 0;
  389. var time2 = new Date(args[2]).getTime() || Infinity;
  390. var r = invoiceReportByTimeInterval(time1, time2);
  391. process.exit(Dump(r));
  392. }
  393.  
  394. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement