Advertisement
Venciity

Travel agency EXAM JS OOP [ 15.11.2014 ]

Nov 17th, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function processTravelAgencyCommands(commands) {
  2.     'use strict';
  3.  
  4.     // ---------- extends ----------
  5.     Object.prototype.extends = function (parent) {
  6.         this.prototype = Object.create(parent.prototype);
  7.         this.prototype.constructor = this;
  8.     }
  9.  
  10.     var Models = (function () {
  11.         var Destination = (function () {
  12.             function Destination(location, landmark) {
  13.                 this.setLocation(location);
  14.                 this.setLandmark(landmark);
  15.             }
  16.  
  17.             Destination.prototype.getLocation = function () {
  18.                 return this._location;
  19.             }
  20.  
  21.             Destination.prototype.setLocation = function (location) {
  22.                 if (location === undefined || location === "") {
  23.                     throw new Error("Location cannot be empty or undefined.");
  24.                 }
  25.                 this._location = location;
  26.             }
  27.  
  28.             Destination.prototype.getLandmark = function () {
  29.                 return this._landmark;
  30.             }
  31.  
  32.             Destination.prototype.setLandmark = function (landmark) {
  33.                 if (landmark === undefined || landmark == "") {
  34.                     throw new Error("Landmark cannot be empty or undefined.");
  35.                 }
  36.                 this._landmark = landmark;
  37.             }
  38.  
  39.             Destination.prototype.toString = function () {
  40.                 return this.constructor.name + ": " +
  41.                     "location=" + this.getLocation() +
  42.                     ",landmark=" + this.getLandmark();
  43.             }
  44.  
  45.             return Destination;
  46.         }());
  47.  
  48.         var Travel = (function () {
  49.             function Travel(name, startDate, endDate, price) {
  50.                 if (this.constructor === Travel) {
  51.                     throw new Error('Cannot instantiate abstract class Travel.');
  52.                 }
  53.                 this.setName(name);
  54.                 this.setStartDate(startDate);
  55.                 this.setEndDate(endDate);
  56.                 this.setPrice(price);
  57.             }
  58.  
  59.             Travel.prototype.getName = function () {
  60.                 return this._name;
  61.             };
  62.  
  63.             Travel.prototype.setName = function (name) {
  64.                 if (name === undefined || name === "") {
  65.                     throw new Error("Name cannot be empty or undefined.");
  66.                 }
  67.                 this._name = name;
  68.             };
  69.  
  70.             Travel.prototype.getStartDate = function () {
  71.                 return this._startDate;
  72.             };
  73.  
  74.             Travel.prototype.setStartDate = function (startDate) {
  75.                 if (startDate === undefined || !(startDate instanceof Date)) {
  76.                     throw new Error("Start date should be a non-empty date object.")
  77.                 }
  78.                 this._startDate = startDate;
  79.             };
  80.  
  81.             Travel.prototype.getEndDate = function () {
  82.                 return this._endDate;
  83.             };
  84.  
  85.             Travel.prototype.setEndDate = function (endDate) {
  86.                 if (endDate === undefined || !(endDate instanceof Date)) {
  87.                     throw new Error("End date should be a non-empty date object.")
  88.                 }
  89.                 this._endDate = endDate;
  90.             };
  91.  
  92.             Travel.prototype.getPrice = function () {
  93.                 return this._price;
  94.             };
  95.  
  96.             Travel.prototype.setPrice = function (price) {
  97.                 if (price === undefined || isNaN(price) || price < 0) {
  98.                     throw new Error("Price cannot be negative.");
  99.                 }
  100.                 this._price = price;
  101.             };
  102.  
  103.  
  104.             Travel.prototype.toString = function () {
  105.  
  106.                 return " * " + this.constructor.name + ": " +
  107.                        "name=" + this.getName() +
  108.                        ",start-date=" + formatDate(this.getStartDate()) +
  109.                        ",end-date=" + formatDate(this.getEndDate()) +
  110.                        ",price=" + this.getPrice().toFixed(2);
  111.             };
  112.  
  113.             return Travel;
  114.         }());
  115.  
  116.         var Excursion = (function () {
  117.             function Excursion(name, startDate, endDate, price, transport) {
  118.                 Travel.call(this, name, startDate, endDate, price);
  119.                 this.setTransport(transport);
  120.                 this._destinations = [];
  121.             }
  122.  
  123.             Excursion.extends(Travel);
  124.  
  125.             Excursion.prototype.getDestinations = function () {
  126.                 return this._destinations;
  127.             };
  128.  
  129.             Excursion.prototype.getTransport = function () {
  130.                 return this._transport;
  131.             };
  132.  
  133.             Excursion.prototype.setTransport = function (transport) {
  134.                 if (transport === undefined || transport === "") {
  135.                     throw new Error("Transport cannot be empty or undefined.");
  136.                 }
  137.                 this._transport = transport;
  138.             };
  139.  
  140.             Excursion.prototype.addDestination = function (destination) {
  141.                 this.getDestinations().push(destination);
  142.             };
  143.  
  144.             Excursion.prototype.removeDestination = function (destination) {
  145.                 var index = this.getDestinations().indexOf(destination);
  146.                 if (index !== -1) {
  147.                     this.getDestinations().splice(index, 1);
  148.                 } else {
  149.                     throw new Error("Travel does not contain such destination.");
  150.                 }
  151.             }
  152.  
  153.             Excursion.prototype.getDestinationsInfo = function () {
  154.                 var destinationsInfo;
  155.                 destinationsInfo = " ** Destinations: " +
  156.                                    (this.getDestinations().length > 0 ? this.getDestinations().join(";") : "-");
  157.  
  158.                 return destinationsInfo;
  159.             }
  160.  
  161.             Excursion.prototype.toString = function () {
  162.                 // * Excursion: name=Do Chikago i nazad,start-date=17-Dec-2014,end-date=28-Dec-2014,price=1250.50,transport=bus and cruiser
  163.                 return Travel.prototype.toString.call(this) +
  164.                        ",transport=" + this.getTransport() + "\n" + this.getDestinationsInfo();
  165.             };
  166.  
  167.             return Excursion;
  168.         }());
  169.  
  170.         var Vacation = (function () {
  171.             function Vacation(name, startDate, endDate, price, location, accommodation) {
  172.                 Travel.call(this, name, startDate, endDate, price);
  173.                 this.setAccommodation(accommodation);
  174.                 this.setLocation(location);
  175.             }
  176.  
  177.             Vacation.extends(Travel);
  178.  
  179.             Vacation.prototype.getLocation = function () {
  180.                 return this._location;
  181.             };
  182.  
  183.             Vacation.prototype.setLocation = function (location) {
  184.                 if (location === undefined || location === "") {
  185.                     throw new Error("Location cannot be empty or undefined.");
  186.                 }
  187.                 this._location = location;
  188.             };
  189.  
  190.             Vacation.prototype.getAccommodation = function () {
  191.                 return this._accommodation;
  192.             };
  193.  
  194.             Vacation.prototype.setAccommodation = function (accommodation) {
  195.                 if (accommodation !== undefined && accommodation === "") {
  196.                     throw new Error("Accommodation cannot be empty.");
  197.                 }
  198.                 this._accommodation = accommodation;
  199.             };
  200.  
  201.             Vacation.prototype.toString = function () {
  202.                 return Travel.prototype.toString.call(this) +
  203.                     ",location=" + this.getLocation() +
  204.                     (this.getAccommodation() ? ",accommodation=" + this.getAccommodation() : "");
  205.             };
  206.  
  207.             return Vacation;
  208.         }());
  209.  
  210.         var Cruise = (function () {
  211.  
  212.             var CRUISE_TRANSPORT = "cruise liner";
  213.  
  214.             function Cruise(name, startDate, endDate, price, transport, startDock) {
  215.                 Excursion.call(this, name, startDate, endDate, price, CRUISE_TRANSPORT);
  216.                 this.setStartDock(startDock);
  217.             }
  218.  
  219.             Cruise.extends(Excursion);
  220.  
  221.             Cruise.prototype.getStartDock = function () {
  222.                 return this._startDock;
  223.             };
  224.  
  225.             Cruise.prototype.setStartDock = function (startDock) {
  226.                 if (startDock !== undefined && startDock === "") {
  227.                     throw new Error("Start dock cannot be empty.");
  228.                 }
  229.                 this._startDock = startDock;
  230.             };
  231.  
  232.  
  233.             Cruise.prototype.toString = function () {
  234.                 // * Cruise: name=Transatlantic cruise,start-date=2-Jan-2015,end-date=16-Jan-2015,price=1778.00,transport=cruise liner
  235.                 return Excursion.prototype.toString.call(this) +
  236.                        (this.getStartDock() ? ",start-dock=" + this.getStartDock() : "");
  237.             };
  238.  
  239.             return Cruise;
  240.         }());
  241.  
  242.         return {
  243.             Destination: Destination,
  244.             Travel: Travel,
  245.             Excursion: Excursion,
  246.             Vacation: Vacation,
  247.             Cruise: Cruise
  248.         }
  249.     }());
  250.  
  251.     var TravellingManager = (function () {
  252.         var _travels;
  253.         var _destinations;
  254.  
  255.         function init() {
  256.             _travels = [];
  257.             _destinations = [];
  258.         }
  259.  
  260.         var CommandProcessor = (function () {
  261.  
  262.             function processInsertCommand(command) {
  263.                 var object;
  264.  
  265.                 switch (command["type"]) {
  266.                     case "excursion":
  267.                         object = new Models.Excursion(command["name"], parseDate(command["start-date"]), parseDate(command["end-date"]),
  268.                             parseFloat(command["price"]), command["transport"]);
  269.                         _travels.push(object);
  270.                         break;
  271.                     case "vacation":
  272.                         object = new Models.Vacation(command["name"], parseDate(command["start-date"]), parseDate(command["end-date"]),
  273.                             parseFloat(command["price"]), command["location"], command["accommodation"]);
  274.                         _travels.push(object);
  275.                         break;
  276.                     case "cruise":
  277.                         object = new Models.Cruise(command["name"], parseDate(command["start-date"]), parseDate(command["end-date"]),
  278.                             parseFloat(command["price"]), command["start-dock"]);
  279.                         _travels.push(object);
  280.                         break;
  281.                     case "destination":
  282.                         object = new Models.Destination(command["location"], command["landmark"]);
  283.                         _destinations.push(object);
  284.                         break;
  285.                     default:
  286.                         throw new Error("Invalid type.");
  287.                 }
  288.  
  289.                 return object.constructor.name + " created.";
  290.             }
  291.  
  292.             function processDeleteCommand(command) {
  293.                 var object,
  294.                     index,
  295.                     destinations;
  296.  
  297.                 switch (command["type"]) {
  298.                     case "destination":
  299.                         object = getDestinationByLocationAndLandmark(command["location"], command["landmark"]);
  300.                         _travels.forEach(function (t) {
  301.                             if (t instanceof Models.Excursion && t.getDestinations().indexOf(object) !== -1) {
  302.                                 t.removeDestination(object);
  303.                             }
  304.                         });
  305.                         index = _destinations.indexOf(object);
  306.                         _destinations.splice(index, 1);
  307.                         break;
  308.                     case "excursion":
  309.                     case "vacation":
  310.                     case "cruise":
  311.                         object = getTravelByName(command["name"]);
  312.                         index = _travels.indexOf(object);
  313.                         _travels.splice(index, 1);
  314.                         break;
  315.                     default:
  316.                         throw new Error("Unknown type.");
  317.                 }
  318.  
  319.                 return object.constructor.name + " deleted.";
  320.             }
  321.  
  322.             function processListCommand(command) {
  323.                 return formatTravelsQuery(_travels);
  324.             }
  325.  
  326.             // ---------- processFilterInPriceRange ----------
  327.             function processFilterInPriceRange(command) {
  328.                 var type = command["type"],
  329.                     priceMin = parseFloat(command["price-min"]),
  330.                     priceMax = parseFloat(command["price-max"]),
  331.                     filteredByType,
  332.                     filteredByPrice,
  333.                    sortedByDateAsc;
  334.  
  335.                 filteredByType = _travels
  336.                     .filter(function (e) {
  337.                         switch (type) {
  338.                             case "excursion":
  339.                                 return e.constructor.name === "Excursion";
  340.                             case "vacation":
  341.                                 return e.constructor.name === "Vacation";
  342.                             case "cruise":
  343.                                 return e.constructor.name === "Cruise";
  344.                             case "all":
  345.                                 return true;
  346.                             default:
  347.                                 return false;
  348.                         }
  349.                     });
  350.  
  351.                 filteredByPrice = filteredByType
  352.                     .filter(function (e) {
  353.                         return priceMin <= e.getPrice() && e.getPrice() <= priceMax;
  354.                     });
  355.                
  356.                 sortedByDateAsc = filteredByPrice
  357.                     .sort(function (e1, e2) {
  358.                         var dateOne = e1.getStartDate().valueOf(),
  359.                             dateTwo = e2.getStartDate().valueOf();
  360.  
  361.                         if (dateOne === dateTwo) {
  362.                             return e1.getName().localeCompare(e2.getName());
  363.                         }
  364.  
  365.                         return dateOne - dateTwo;
  366.                     });
  367.  
  368.                 return formatTravelsQuery(sortedByDateAsc);
  369.             }
  370.  
  371.             function processAddDestinationCommand(command) {
  372.                 var destination = getDestinationByLocationAndLandmark(command["location"], command["landmark"]),
  373.                     travel = getTravelByName(command["name"]);
  374.  
  375.                 if (!(travel instanceof Models.Excursion)) {
  376.                     throw new Error("Travel does not have destinations.");
  377.                 }
  378.                 travel.addDestination(destination);
  379.  
  380.                 return "Added destination to " + travel.getName() + ".";
  381.             }
  382.  
  383.             function processRemoveDestinationCommand(command) {
  384.                 var destination = getDestinationByLocationAndLandmark(command["location"], command["landmark"]),
  385.                     travel = getTravelByName(command["name"]);
  386.  
  387.                 if (!(travel instanceof Models.Excursion)) {
  388.                     throw new Error("Travel does not have destinations.");
  389.                 }
  390.                 travel.removeDestination(destination);
  391.  
  392.                 return "Removed destination from " + travel.getName() + ".";
  393.             }
  394.  
  395.             function getTravelByName(name) {
  396.                 var i;
  397.  
  398.                 for (i = 0; i < _travels.length; i++) {
  399.                     if (_travels[i].getName() === name) {
  400.                         return _travels[i];
  401.                     }
  402.                 }
  403.                 throw new Error("No travel with such name exists.");
  404.             }
  405.  
  406.             function getDestinationByLocationAndLandmark(location, landmark) {
  407.                 var i;
  408.  
  409.                 for (i = 0; i < _destinations.length; i++) {
  410.                     if (_destinations[i].getLocation() === location
  411.                         && _destinations[i].getLandmark() === landmark) {
  412.                         return _destinations[i];
  413.                     }
  414.                 }
  415.                 throw new Error("No destination with such location and landmark exists.");
  416.             }
  417.  
  418.             function formatTravelsQuery(travelsQuery) {
  419.                 var queryString = "";
  420.  
  421.                 if (travelsQuery.length > 0) {
  422.                     queryString += travelsQuery.join("\n");
  423.                 } else {
  424.                     queryString = "No results.";
  425.                 }
  426.  
  427.                 return queryString;
  428.             }
  429.  
  430.             return {
  431.                 processInsertCommand: processInsertCommand,
  432.                 processDeleteCommand: processDeleteCommand,
  433.                 processListCommand: processListCommand,
  434.                 processFilterTravelsCommand: processFilterInPriceRange,
  435.                 processAddDestinationCommand: processAddDestinationCommand,
  436.                 processRemoveDestinationCommand: processRemoveDestinationCommand
  437.             }
  438.         }());
  439.  
  440.         var Command = (function () {
  441.             function Command(cmdLine) {
  442.                 this._cmdArgs = processCommand(cmdLine);
  443.             }
  444.  
  445.             function processCommand(cmdLine) {
  446.                 var parameters = [],
  447.                     matches = [],
  448.                     pattern = /(.+?)=(.+?)[;)]/g,
  449.                     key,
  450.                     value,
  451.                     split;
  452.  
  453.                 split = cmdLine.split("(");
  454.                 parameters["command"] = split[0];
  455.                 while ((matches = pattern.exec(split[1])) !== null) {
  456.                     key = matches[1];
  457.                     value = matches[2];
  458.                     parameters[key] = value;
  459.                 }
  460.  
  461.                 return parameters;
  462.             }
  463.  
  464.             return Command;
  465.         }());
  466.  
  467.         function executeCommands(cmds) {
  468.             var commandArgs = new Command(cmds)._cmdArgs,
  469.                 action = commandArgs["command"],
  470.                 output;
  471.  
  472.             switch (action) {
  473.                 case "insert":
  474.                     output = CommandProcessor.processInsertCommand(commandArgs);
  475.                     break;
  476.                 case "delete":
  477.                     output = CommandProcessor.processDeleteCommand(commandArgs);
  478.                     break;
  479.                 case "add-destination":
  480.                     output = CommandProcessor.processAddDestinationCommand(commandArgs);
  481.                     break;
  482.                 case "remove-destination":
  483.                     output = CommandProcessor.processRemoveDestinationCommand(commandArgs);
  484.                     break;
  485.                 case "list":
  486.                     output = CommandProcessor.processListCommand(commandArgs);
  487.                     break;
  488.                 case "filter":
  489.                     output = CommandProcessor.processFilterTravelsCommand(commandArgs);
  490.                     break;
  491.                 default:
  492.                     throw new Error("Unsupported command.");
  493.             }
  494.  
  495.             return output;
  496.         }
  497.  
  498.         return {
  499.             init: init,
  500.             executeCommands: executeCommands
  501.         }
  502.     }());
  503.  
  504.     var parseDate = function (dateStr) {
  505.         if (!dateStr) {
  506.             return undefined;
  507.         }
  508.         var date = new Date(Date.parse(dateStr.replace(/-/g, ' ')));
  509.         var dateFormatted = formatDate(date);
  510.         if (dateStr != dateFormatted) {
  511.             throw new Error("Invalid date: " + dateStr);
  512.         }
  513.         return date;
  514.     }
  515.  
  516.     var formatDate = function (date) {
  517.         var day = date.getDate();
  518.         var monthName = date.toString().split(' ')[1];
  519.         var year = date.getFullYear();
  520.         return day + '-' + monthName + '-' + year;
  521.     }
  522.  
  523.     var output = "";
  524.     TravellingManager.init();
  525.  
  526.     commands.forEach(function (cmd) {
  527.         var result;
  528.         if (cmd != "") {
  529.             try {
  530.                 result = TravellingManager.executeCommands(cmd) + "\n";
  531.             } catch (e) {
  532.                 result = "Invalid command." + "\n";
  533.             }
  534.             output += result;
  535.         }
  536.     });
  537.  
  538.     return output;
  539. }
  540.  
  541. // ------------------------------------------------------------
  542. // Read the input from the console as array and process it
  543. // Remove all below code before submitting to the judge system!
  544. // ------------------------------------------------------------
  545.  
  546. (function () {
  547.     var arr = [];
  548.     if (typeof (require) == 'function') {
  549.         // We are in node.js --> read the console input and process it
  550.         require('readline').createInterface({
  551.             input: process.stdin,
  552.             output: process.stdout
  553.         }).on('line', function (line) {
  554.             arr.push(line);
  555.         }).on('close', function () {
  556.             console.log(processTravelAgencyCommands(arr));
  557.         });
  558.     }
  559. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement