PageRenderTime 26ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/example/commandline-pizza/dominos-commandline-pizza.js

https://gitlab.com/edelmaks/PizzaPI
JavaScript | 510 lines | 425 code | 78 blank | 7 comment | 60 complexity | aa8f41c23efcc214486d998fcf99b495 MD5 | raw file
  1. var fs = require('fs'),
  2. path = require('path'),
  3. readline = require('readline'),
  4. colors = require('colors'),
  5. pizzapi = require('../../dominos-pizza-api.js');
  6. colors.setTheme(
  7. {
  8. menuItem : 'bgCyan',
  9. menuTitle : 'bgBlue',
  10. store : 'bgBlue',
  11. info : 'cyan'
  12. }
  13. );
  14. var rl = readline.createInterface(
  15. {
  16. input: process.stdin,
  17. output: process.stdout,
  18. terminal:true
  19. }
  20. );
  21. process.stdin.setEncoding('utf8');
  22. readline.cursorTo(process.stdout, 0, 0);
  23. readline.clearScreenDown(process.stdout);
  24. rl.setPrompt('Pizza> ');
  25. rl.prompt();
  26. var order=new pizzapi.Order(
  27. );
  28. rl.on(
  29. 'line',
  30. function(chunk) {
  31. chunk=chunk.trim();
  32. if (chunk !== null) {
  33. chunk = chunk.replace( /\s\s+/g, ' ' ).trim();
  34. var data = chunk.toLowerCase();
  35. if(data.indexOf('find near ')>-1){
  36. findStores(data.slice(10));
  37. return;
  38. }
  39. if(data.indexOf('find closest ')>-1){
  40. findStores(data.slice(data.indexOf('find closest ')+13),true);
  41. return;
  42. }
  43. if(data.indexOf('full menu for closest')>-1){
  44. findStores(data.slice(data.indexOf('full menu for closest')+21),true,false,true);
  45. return;
  46. }
  47. if(data.indexOf('menu for closest')>-1){
  48. findStores(data.slice(data.indexOf('menu for closest')+16),true,true);
  49. return;
  50. }
  51. if(data.indexOf('full menu for ')>-1){
  52. showMenu(data.slice(data.indexOf('full menu for ')+14));
  53. return;
  54. }
  55. if(data.indexOf('menu for ')>-1){
  56. showMenu(data.slice(data.indexOf('menu for ')+9),true);
  57. return;
  58. }
  59. if(data.indexOf('order ')>-1){
  60. orderPizza(data.slice(data.indexOf('order ')+6),true);
  61. return;
  62. }
  63. if(data.indexOf('help')>-1){
  64. help();
  65. return;
  66. }
  67. rl.prompt();
  68. }
  69. }
  70. );
  71. function help(){
  72. var commands=[
  73. 'find closest'.bgCyan+' {address info}'.info+' //can be full address city and state, postal code etc...',
  74. 'find near'.bgCyan+' {address info}'.info+' //can be full address city and state, postal code etc...',
  75. 'menu for closest'.bgCyan+' {address info}'.info+' //can be full address city and state, postal code etc...',
  76. 'full menu for closest'.bgCyan+' {address info}'.info+' //can be full address city and state, postal code etc...',
  77. 'menu for'.bgCyan+' {storeID}'.info+' //get store id as part of a find closest or find near request',
  78. 'full menu for'.bgCyan+' {storeID}'.info+' //get store id as part of a find closest or find near request',
  79. 'order'.bgCyan+' {comma deliminated list of item codes}'.info+' //get item codes from menu'
  80. ];
  81. for(var i in commands){
  82. console.log(commands[i]+'\n');
  83. }
  84. }
  85. /*
  86. * pass in pizza info
  87. *
  88. */
  89. function showMenu(storeID,quick){
  90. console.log('Fetching menu for '+storeID.info+'...');
  91. order.StoreID=storeID
  92. rl.prompt();
  93. var store=new pizzapi.Store(
  94. {
  95. ID:storeID
  96. }
  97. );
  98. store.getMenu(
  99. function(data){
  100. if(quick){
  101. console.log(
  102. '\n##########################\n'.blue,
  103. 'Quick Menu'.yellow,
  104. '\n##########################\n'.blue
  105. );
  106. for(var i in data.result.PreconfiguredProducts){
  107. var product=data.result.PreconfiguredProducts[i];
  108. console.log(
  109. '\n'.blue+
  110. (
  111. (
  112. product.Name.bold+' : '+
  113. product.Code+'\n'
  114. ).menuTitle+
  115. product.Description+'\n'+
  116. product.Size
  117. ).menuItem.white
  118. );
  119. };
  120. rl.prompt();
  121. return;
  122. }
  123. console.log(
  124. '\n##########################\n'.blue,
  125. 'Full Menu'.yellow,
  126. '\n##########################\n'.blue
  127. );
  128. var menuPortions=[
  129. 'Sides',
  130. 'PreconfiguredProducts',
  131. 'Products'
  132. ];
  133. for(var j in menuPortions){
  134. for(var i in data.result[menuPortions[j]]){
  135. if(!data.result[menuPortions[j]][i].Name){
  136. console.log(
  137. (
  138. '=========='.cyan+
  139. i.blue+
  140. '=========='.cyan
  141. ).bgYellow
  142. );
  143. for(var k in data.result[menuPortions[j]][i]){
  144. var product=data.result[menuPortions[j]][i][k];
  145. console.log(
  146. '(+)'+(
  147. (
  148. product.Name.bold+' : '+
  149. product.Code+'\n'
  150. ).menuTitle+
  151. product.Description+'\n'+
  152. product.Size
  153. ).menuItem.white
  154. );
  155. }
  156. continue;
  157. }
  158. var product=data.result[menuPortions[j]][i];
  159. console.log(
  160. '(+)'+(
  161. (
  162. product.Name.bold+' : '+
  163. product.Code+'\n'
  164. ).menuTitle+
  165. product.Description+'\n'+
  166. product.Size
  167. ).menuItem.white
  168. );
  169. };
  170. }
  171. }
  172. );
  173. }
  174. function validateAddress(address){
  175. console.log(address);
  176. pizzapi.store.find(
  177. address,
  178. function(storeData){
  179. order.Address=storeData.result.Address;
  180. if(!order.Address.Street){
  181. rl.question(
  182. 'Not a valid address.'.red+' What is the full address for delivery?',
  183. validateAddress
  184. );
  185. return;
  186. }
  187. validateOrder(order);
  188. }
  189. );
  190. }
  191. function findStores(address, closest, menu, fullMenu){
  192. console.log('Looking for stores near '+address.info+'...');
  193. rl.prompt();
  194. pizzapi.Util.findNearbyStores(
  195. address,
  196. 'Delivery',
  197. function(storeData){
  198. var openStores=[];
  199. order.Address=new pizzapi.Address(storeData.result.Address);
  200. for(var i in storeData.result.Stores){
  201. if(storeData.result.Stores[i].IsOpen &&
  202. storeData.result.Stores[i].IsOnlineNow &&
  203. storeData.result.Stores[i].ServiceIsOpen.Delivery
  204. ){
  205. openStores.push(storeData.result.Stores[i]);
  206. }
  207. }
  208. if(openStores.length<1){
  209. console.log('No Open Stores allowing delivery right now for the specified location'.bgRed.black.bold);
  210. return;
  211. }
  212. var count=openStores.length;
  213. if(closest){
  214. count=1;
  215. order.StoreID=openStores[0].StoreID
  216. }
  217. console.log('\n');
  218. for(var i=0; i<count; i++){
  219. var store=openStores[i];
  220. console.log(
  221. '###############################################################\n'.blue+
  222. (
  223. 'StoreID : '+store.StoreID.bold+
  224. '\nAddress : '+store.AddressDescription+
  225. '\nPhone : '+store.Phone+
  226. '\nDelivery Hours : '+store.ServiceHoursDescription.Delivery
  227. ).store.white
  228. );
  229. }
  230. rl.prompt();
  231. if(!menu && !fullMenu)
  232. return;
  233. if(menu){
  234. showMenu(
  235. openStores[0].StoreID,
  236. true
  237. );
  238. return;
  239. }
  240. if(fullMenu){
  241. showMenu(
  242. openStores[0].StoreID
  243. );
  244. return;
  245. }
  246. }
  247. );
  248. }
  249. function orderPizza(items){
  250. var items=items.split(',');
  251. for(var i=0; i<items.length; i++){
  252. //create a new product to add to the order
  253. var product=new pizzapi.Product();
  254. //set the product code using the random item key
  255. product.Code=items[i].trim();
  256. //add the item to the order
  257. order.Products.push(product);
  258. }
  259. if(!order.Address.Street){
  260. rl.question(
  261. 'what is the full address for delivery?',
  262. validateAddress
  263. );
  264. return;
  265. }
  266. validateOrder();
  267. }
  268. function validateOrder(){
  269. if(!order.FirstName){
  270. rl.question(
  271. 'First Name?',
  272. function(data){
  273. order.FirstName=data;
  274. validateOrder();
  275. }
  276. );
  277. return;
  278. }
  279. if(!order.LastName){
  280. rl.question(
  281. 'Last Name?',
  282. function(data){
  283. order.LastName=data;
  284. validateOrder();
  285. }
  286. );
  287. return;
  288. }
  289. if(!order.Email){
  290. rl.question(
  291. 'E-Mail?',
  292. function(data){
  293. order.Email=data;
  294. validateOrder();
  295. }
  296. );
  297. return;
  298. }
  299. if(!order.Phone){
  300. rl.question(
  301. 'Phone number?',
  302. function(data){
  303. order.Phone=data;
  304. validateOrder();
  305. }
  306. );
  307. return;
  308. }
  309. if(!order.Phone){
  310. rl.question(
  311. 'Phone number?',
  312. function(data){
  313. order.Phone=data;
  314. validateOrder();
  315. }
  316. );
  317. return;
  318. }
  319. pizzapi.order.validate(
  320. order,
  321. validatedOrder
  322. );
  323. }
  324. function validatedOrder(data){
  325. order=orderData.result;
  326. pizzapi.order.price(
  327. order,
  328. pricedOrder
  329. );
  330. }
  331. function pricedOrder(priceData) {
  332. console.log(priceData.result.Order.Amounts);
  333. var cardInfo = new pizzapi.Payment();
  334. cardInfo.Amount = priceData.result.Order.Amounts.Customer;
  335. order.Payments.push(cardInfo);
  336. placeOrder();
  337. }
  338. function validateCC(number){
  339. var re = {
  340. visa : /^4[0-9]{12}(?:[0-9]{3})?$/,
  341. mastercard : /^5[1-5][0-9]{14}$/,
  342. amex : /^3[47][0-9]{13}$/,
  343. diners : /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
  344. discover : /^6(?:011|5[0-9]{2})[0-9]{12}$/,
  345. jcb : /^(?:2131|1800|35\d{3})\d{11}$/,
  346. enroute : /^(?:2014|2149)\d{11}$/
  347. };
  348. if (re.visa.test(number))
  349. return 'VISA';
  350. if (re.mastercard.test(number))
  351. return 'MASTERCARD';
  352. if (re.amex.test(number))
  353. return 'AMEX';
  354. if (re.diners.test(number))
  355. return 'DINERS';
  356. if (re.discover.test(number))
  357. return 'DISCOVER';
  358. if (re.jcb.test(number))
  359. return 'JCB';
  360. if (re.enroute.test(number))
  361. return 'JCB';
  362. return "";
  363. }
  364. function placeOrder(){
  365. if(!order.Payments[0].Number){
  366. rl.question(
  367. 'Credit Card Number?',
  368. function(data){
  369. order.Payments[0].Number = data;
  370. order.Payments[0].CardType = validateCC(data);
  371. placeOrder();
  372. }
  373. );
  374. return;
  375. }
  376. if(!order.Payments[0].Expiration){
  377. rl.question(
  378. 'Credit Card Expiration?',
  379. function(data){
  380. order.Payments[0].Expiration = data.replace(/\D/g,'');
  381. placeOrder();
  382. }
  383. );
  384. return;
  385. }
  386. if(!order.Payments[0].SecurityCode){
  387. rl.question(
  388. 'Credit Card Security Code or CVV (3 or 4 digit code on card)?',
  389. function(data){
  390. order.Payments[0].SecurityCode = data;
  391. placeOrder();
  392. }
  393. );
  394. return;
  395. }
  396. if(!order.Payments[0].PostalCode){
  397. rl.question(
  398. 'Postal Code?',
  399. function(data){
  400. order.Payments[0].PostalCode = data;
  401. placeOrder();
  402. }
  403. );
  404. rl.write(order.Address.PostalCode);
  405. return;
  406. }
  407. pizzapi.order.place(order, orderPlaced);
  408. }
  409. function orderPlaced(data){
  410. order=data.result;
  411. if(orderData.result.Order.Status==-1){
  412. console.log(order.CorrectiveAction);
  413. rl.prompt();
  414. return;
  415. }
  416. trackOrder();
  417. }
  418. function trackOrder(){
  419. pizzapi.track.orderKey(
  420. order.OrderID,
  421. order.StoreID,
  422. function(pizzaData){
  423. readline.cursorTo(process.stdout, 0, 0);
  424. readline.clearScreenDown(process.stdout);
  425. console.log(JSON.stringify(pizzaData.orders));
  426. setTimeout(
  427. trackOrder,
  428. 15000
  429. );
  430. }
  431. );
  432. }