Programming Fundamentals Assignment 2 2019 Semester 2 1 Programming Fundamentals 2019 Semester 2 Assignment Choices We the PF teaching team have allowed for assignment choices considering the diversity of students in PF. Therefore you are required to select either Assignment 2A or Assignment 2B considering your background, skills, aspirations and the type of learner you are (prefer guided/independent learning). The table below outline aspects of both, but you should do your own research before selecting one. Assignment 2A Assignment 2B Assignment 2A requires a deeper understanding of OO concepts and the use of Collection classes (ArrayList, HashMap). Some bonus marks are allocated to challenge the students. This project is suitable if you are an independent learner and love challenges or an advanced learner. Assignment 2B guides you step by step to develop classes, subclasses, exceptions etc. You need not make use of Collection classes. Assignment 2A: Timetabling and Enrolment System (20 marks) 1. Objective The main objective of this assignment is to familiarize you with object oriented design, programming, testing and refactoring. This assignment is better suited to those who have some previous programming experience and are interested in the OO design aspects. 2. Overview and Assumptions The Timetabling and Enrolment system is a standalone system to be used next semester in a new tertiary institution. At this stage, the admin-staff, the only user, will carry out all operations on behalf of students and staffs, and you are required to consider only one (next) semester. This system should take into account courses, course offerings, staffs, students, lessons (tutorials and lectures) and venues. The use cases and the activity diagram for the system are shown in the appendix I and II. Note, only some of the courses will be offered each semester. Moreover, there can be at most one offering for a course in a semester. Students can enrol up to 4 courses and you need not consider the course prerequisites. Students however, cannot take two courses where the lectures are overlapping. Moreover a student cannot enrol into a course offering which has already reached the maximum number. Existing Courses, Staffs and Venues Details of Currently available courses in the school are as follows but not all these courses will be offered this semester. Note each course can be uniquely identified based on Course ID. course1: “P101", "Programming 1", "Teach Basic Programming” course2: “P102", "Programming 2", "Teach Intermediate Programming” course3: “S101", "Software Engineering", "Teach UML and Modelling" course4: “WP1", "Web Programming", "Teach Web Technologies" course5: “UI1", "User Interface", "Teach UI Principles" course6: “Math","Discret Maths","Teach Maths needed for CS" course7: “Net1", "Networking","Teach networking principles" Programming Fundamentals Assignment 2 2019 Semester 2 2 Details of Currently available Venues in the school are as follows. Note the capacity of venues varies. Clearly no two lessons can be held at the same time and the system should check for any clashes. Venue can be used from 8.0 to 21.00. "12.10.02",100,"Interactive" "12.10.03",200,"Interactive" "10.10.22",36,"Traditional" "10.10.23",36,"Traditional" Currently all tutorials and lectures are taken by the staff from the school. The staff employee number, name, position and location are as follows: "e44556","Tim O'Connor","Lecturer","14.13.11" "e44321","Richard Cooper","Professor","14.13.12" "e54321","Jane Smith","Lecturer","14.13.13" "e53457", "Isaac Newton", "Associate Professor", "14.13.14" Note you are free to add more course, venues and staffs for testing purpose. 3. Requirements You are required to write a menu driven program that will use the existing courses, staffs and venues described in section two. In the first phase, the menu driven program caters mainly to staff and admin needs by allowing course offerings, lessons (lectures or tutorials) to be added as well as assigning a specific staff to a lesson. It should also allow printing venue, course offering and staff timetables. In the second phase, student specific menu options should be provided such as enrolling, withdrawing from course offerings and registering, deregistering from tutorials and printing student timetables. Adding Course Offering A course offering must be added before (lessons) lectures or tutorials can be added. When creating a course offering the maximum number of students must be specified. There can at most be one course offering for a course (in a given semester). Adding Lessons for a Course Offering The lessons in the school are either lectures or tutorials. For a given course offering there can only be one lecture though a lecture can last for many hours. For each lesson the start time, the duration and the venue must be specified. When adding lessons for a course offering the system should ensure no two lessons for a given course offering can overlap. Moreover the system should ensure the venue is not already used for other lessons. If a lecture is added, the system should ensure the venue capacity for the lecture is adequate for the maximum number of students allowed in the course offering. Adding Staff Staff can be assigned only after lectures or tutorials are already added. Clearly a staff cannot be taking two different lessons at the same time and the system should check for any clashes and alert the user if such an attempt is made. Programming Fundamentals Assignment 2 2019 Semester 2 3 Student Related Functionality Enrolling and Withdrawing Students Though prerequisites are not imposed at present, no student should be allowed to enrol in more than 4 courses. Students can however, withdraw from a course before enrolling in another. In the current phase, you are not required to consider the census date. Students should not be enrolled into a course offering if it has already reached the maximum capacity. Moreover, students should not be allowed to enrol into two courses where the lecture times are overlapping. Registering and Deregistering into Tutorials A student can register into a tutorial only if already enrolled in the course offering (it belongs to), the maximum capacity is not reached for the tutorial (36), and the selected lesson does not clash with any of the other tutorials for that student. Note a student is not required to register into a lecture, as any enrolled student is free to attend the lecture. Any attempt to register again into a tute already registered, or deregister from a tutorial without first registering must result in an error message being printed. Sub-Menu Options for Listing and Timetables List Students The system should allow admin to list the students in a course offering or a tutorial using separate menu options. View Timetables The system should allow timetables to be printed for each staff, each venue, each course offering (including all tutorials and lecture) and each student. Note the timetable need not be in a rectangular grid unless you are aiming for usability and bonus marks. Program Specific Requirements In the first stage you are not required to consider the students (which adds to the complexity) and you may use the sample designs provided through the class and sequence diagrams. You are however, required to come up with specific test cases (both negative and positive) to demonstrate all requirements are met. You are required to throw and catch the exceptions ClashException, PreExistException and CapacityException. A possible exception class for CapacityException is given below. public class CapacityException extends Exception { public CapacityException(String cause) { super(cause); } } You may also come up with utility classes with static methods such as Math.max() if such methods promote reuse. Programming Fundamentals Assignment 2 2019 Semester 2 4 4. Rationale, Guidance and Suggestions Object oriented programming helps to solve complex problems by coming up with a number of domain classes and associations. However, identifying meaningful classes and interactions requires a fair amount of design experience. Such experience cannot be gained by classroombased teaching alone but must be gained through project experience. We have structured this assignment (project) into two phases where student specific requirements can be deferred until the second phase. We have provided some initial UML design diagrams to foster the habit of designing before commencing on implementation. Marks have been allocated in the final submission for refactoring the design and code. You are also encouraged to use collections and exceptions, which simplify the implementation and error propagation. Repetition in this assignment (4 timetables) is intended to make you use OO techniques that promote code reuse (inheritance, polymorphism, utility classes and methods). Use of Java Collections You are encouraged to use collections such as ArrayList and HaspMap. ArrayList implements an array, which can grow indefinitely. HashMaps allow an association to be created between keys and objects. Using such classes also reduce the amount of code required as they provide methods for retrieving required objects easily. ArrayList<Lesson> lessons = new ArrayList<Lesson>(); lessons.add(new Lesson(…………)); To extract the 4th element Lesson lesson4 = lessons.get(3); // index starts at 0 You can use HashMap for storing objects, which have unique primary keys. For example, HashMap<String, Course> courses = new HashMap<String,Course>(); To add a course we use : courses.put(new Course("P101", "Programming 1", "Teach Basic Programming")); To extract the course use: Course course = courses.get("P101"); // returns null if no such course in the map Suggested Division of Work Phase 1: Weeks (7 – 9) Work on individual classes and carry out some unit testing. Phase 2: Weeks (10 – 12) Integrate classes and test the functionalities. In addition, suggested student related functionalities below should be incorporated Feature based Bonus Marks A. Allow all objects to be stored in a file and retrieved. B. Print all timetable in rectangular grid and save to a file (so that it can be printed) Programming Fundamentals Assignment 2 2019 Semester 2 5 Appendix I Use Case for TimeTabling and Student Enrolment System In the current version only the administrator will use the system to meet the staff and student needs. In the subsequent web-based version both staff and students will be allowed to interact directly. Add Course Offering Add Lesson Assign Staff Enrol in Course Offering Withdraw from Course Offering Register in Tutorial Deregister from Tutorial List Students View Timetable View Staff Timetable View Venue Timetable View Student Timetable List Students in Course Offering List Students in Tutorial Add Lecture Add Tutorial View Course Offering Timetable Programming Fundamentals Assignment 2 2019 Semester 2 6 Appendix II Activity-Diagrams Add Course Offering Add Course Add Staff Add Venue Add Lecture Add Tutorial Assign Staff to Lesson Enrol Student in Course Offering Register Student in Tutorial Programming Fundamentals Assignment 2 2019 Semester 2 7 Appendix III Possible Class Diagram (Phase I ) TimeTabling & Student Enrolment System Application Courses: HashMap<String,Course>; Venues: HashMap<String, Venue>; Staffs: HashMap<String, Staff>; createCourseOffering() addLesson(String type) assignStaff() getCourse(cID:String):Course getStaff(sID:String):Staff Course Course(ID:String,name:String, purpose:String) courseId : String name : String objective : String createOffering() getOffering():CourseOffering CourseOffering maxNum : int CourseOffering(maxNum:int,course:Course) addLecture(day:int,start:double,dur:double,ven:Venue) addTutorial(day:int,start:double,dur:double,ven:Venue) getLesson(day:int,start:int,end:int) checkClash(day:int, start) Lesson (abstract) Staff private String eNo; private String name; private String position; private String office; Staff(eNo: String, name: String, position: String, office:String) assign(Lesson lesson) exceptions=ClashException,PreExistException Tutorial Tutorial(day:int,startHr:double,dur:double,venue:Venue, co:CourseOffering) exceptions=ClashException Venue location: String capacity: int purpose: String Venue(location:String, capacity:int, purpose:String) getLessons():ArrayList<Lesson> addLesson(l:Lesson) Lecture Lecture(day:int,startHr:double,dur:double,venue:Venue, co:CourseOffering)exceptions=ClashException,CapacityException * * * * 0..1 * * startHour: double endHour: double day : int staff: Staff venue Venue co: CourseOffering Lesson(day:int,startHr:double,dur:double,venue:Venue,co:CourseOffering) exceptions=ClashException setStaff(staff:Staff) Programming Fundamentals Assignment 2 2019 Semester 2 8 Appendix IV Possible Sequence Diagram: Add Course Offering Application addCourseOffering(ID) course = getCourse(ID) course offering =createOffering() Programming Fundamentals Assignment 2 2019 Semester 2 9 Appendix V Possible Sequence Diagram: Add Tutorial application course = getCourse(ID) course offering =getOffering() offering addTutorial(ID,day,start,dur,venue) addTutorial(day,start,dur,venue) checkClash(day,start,dur) // with other offering lessons Tutorial new Tutorial(day,start,dur.venue) venue checkClash(day,start,dur) // with other venue lessons Note Tutorial Constructor will call the superclass (Lesson) constructor Programming Fundamentals Assignment 2 2019 Semester 2 10 Appendix VI Possible Sequence Diagram: Assign Lecturer to Lesson (Lecture or Tutorial) application course = getCourse(ID) course offering =getOffering() offering addTutorial(ID,day,start,dur,venue) lesson =getLesson(day,start) staff lesson setStaff(staff) staff = getStaff(ID) assignLesson(lesson) checkClash(lesson) add(lesson) Programming Fundamentals Assignment 2 2019 Semester 2 11 Assignment 2B: Vehicle Management System (20 marks) Overview This is a more prescriptive and incremental assignment suitable for those preferring clear guidance (instead of being open ended designs). You are required to complete Part A before proceeding to Part B, and similarly Part B before Part C. Part A: Develop a simple Vehicle class with three states ‘A’ (available), ‘S’ (servicing) and ’H’ (hired) and methods. Your class must implement the required interface and test it with the data provided. In the second part the Vehicle class must be used for developing a simple application. (assignment to be demonstrated in week 8 to your lab assistant) Part B: Extend to PremiumVehicle implementing the overridden methods (which introduce additional conditions for state transitions). You are also required to develop a menu-driven application where both Vehicle and PremiumVehicle objects are stored in a common array, which must be manipulated in a polymorphic way when appropriate. service serviceComplete/set odometer reading hire / set Hired Date/Time and Hirer status = ‘S’ Hire-complete / set odometer reading && compute charge status = ‘A’ status = ‘H’ Vehicle class service serviceComplete/set odometer reading && set last-service hire [car not due for service] / set Hired Date/Time and Hirer status = ‘S’ Hire-complete / set odometer reading && compute charge based on days of hire and mileage status = ‘A’ status = ‘H’ PremiumVehicle class Programming Fundamentals Assignment 2 2019 Semester 2 12 In part C you are required to extend the menu-driven application developed in section B incorporating file and exception handling. The customer details must also be included allowing specific discounts. All Vehicle and subclass objects must be written to a file when program exits and restored back when program commences. The methods should be made to throw appropriate exceptions when operation cannot be performed Programming Fundamentals Assignment 2 2019 Semester 2 13 Part A covers Chapters 1 to 6 Section I Writing a Vehicle class You are required to write a class named Vehicle to manage the hiring of vehicles. The requirements are specified below. Instance Variables Provide private instance variables to store the vehicle-ID, hirer-ID, description, status, dailyrate, odometer-reading and date/time of hire (use the DateTime class provided). Instance variable for status of a car must be set to either 'A' (available), 'H'(hired) or 'S'(servicing). Constructor Provide a constructor for the class that takes vehicle-ID, description, daily-rate and odometer reading to initialize the corresponding instance variables and to set the instance variable for status to 'A' (available for hire when first created) . public Vehicle(String vehicleID, String description, double dailyRate, int odometer) Methods Provide methods to hire a vehicle, complete a hire, service a vehicle, return a vehicle back from service and to print the current state of the vehicle. The hire() must take as argument ID of hirer. The date/time of hire should be set to current time which can be created using the default DateTime constructor (DateTime class described in later section). This method should return false if an attempt is made to hire a vehicle which is currently being serviced (status ‘S’) or already on hire (status ‘H’), otherwise(status ‘A’) the method should return true after setting the hirer ID (to the argument passed), the hire date (to current date), and status (to ‘H’ indicating hired). public boolean hire(String hirerID) // called when car is hired The methods below are required for servicing a vehicle and for returning a vehicle back from service. These operations must return true only when the status of the vehicle are 'A' and 'S' respectively. Note the method serviceComplete(into odo) must set the current odometer reading. public boolean service() // called when car is sent for service public boolean serviceComplete(int odo) // called when car is back from service Programming Fundamentals Assignment 2 2019 Semester 2 14 The hireComplete(int odo) must take one argument for odometer reading and return the charges based on the duration of hire if the operation is successful, and a negative value (-1.0) otherwise. It must succeed only if the status is'H' and the odometer reading is greater than odometer reading when car was hired. The duration-based charge can be computed multiplying daily-rate, by number of days. Assume that minimum rental duration is one day and the number of days is computed based on 24 hours from the time of hire. For example, if Jack hires a car at 9.00 am Monday morning and returns it on Tuesday 10.00 am, the hire duration should be set as two days for the purpose of computing the charges. public double hireComplete(int odo) // called when car hire is completed The print() must print the current date and time (using the getCurrentTime() method of DateTime class) and the necessary vehicle details (ID, description, daily-rate, status, odometer reading) of Vehicle. If the vehicle is currently on hire, the ID of hirer and date/time of hire must also be printed. public void print() Override the toString method to return the String equivalent public Sting toString() This class should also provide accessors for all the instance variables (required for the subclass). Programming Fundamentals Assignment 2 2019 Semester 2 15 DateTime class provided class DateTime { private static long advance; // keeps tracks of any time advance private long time; public DateTime() // constructor { time = System.currentTimeMillis() + advance; } public long getTime() {return time; } // advances date/time by specified days, hours and mins for testing purpose public static void setAdvance(int days, int hours, int mins) { advance = ((days * 24L + hours) * 60L) *60000L; } public String toString() { long l = getTime(); Date gct = new Date(l); return gct.toString(); } public static String getCurrentTime() // returns current date/time { Date d = new Date(System.currentTimeMillis() + advance); return d.toString(); } // returns difference in days public static int diffDays(DateTime d2, DateTime d1) { return (int) ( 1 + ( d2.getTime() - d1.getTime() )/(24L*60*60*1000)); } } Programming Fundamentals Assignment 2 2019 Semester 2 16 Test class and expected Output // Class to test the Vehicle class (provided) class TestVehicle { public static void main(String args[]) { // Constructing a car currently available for hire Vehicle v = new Vehicle("SAT123","Toyota Camry", 12.50, 100000); v.print(); // Sending the car for service if ( v.service() == true) System.out.println("\nCar " + v.getID() + " is now sent for service "); else System.out.println("\nWARNING: Car " + v.getID() + " cannot be sent for service "); v.print(); // Forward the time by 2 days (0 hours and 0 minutes) DateTime.setAdvance(2,0,0); // Attempt to hire a car on service if ( v.hire("User36784") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nWARNING: Car " + v.getID() + " could not be hired "); v.print(); // Car returning from service if ( v.serviceComplete(100100) == true) System.out.println("\nCar " + v.getID() + " is now returned from service "); else System.out.println("\nWARNING: Car " + v.getID() + " cannot be sent returnned from service "); v.print(); Programming Fundamentals Assignment 2 2019 Semester 2 17 DateTime.setAdvance(4,0,0); // Attempt to hire the car which is now available for hire if ( v.hire("User36784") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nWARNING: Car " + v.getID() + " could not be hired "); v.print(); DateTime.setAdvance(6,0,0); // Attempt to hire a car already on hire if ( v.hire("User9999") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nWARNING: Car " + v.getID() + " could not be hired "); v.print(); // Attempt to return car from hire double val = v.hireComplete(121000); if ( val > 0.0 ) { System.out.print("\nCar " + v.getID() + " is returned by " + v.getHirer()); System.out.println(" Charges = " + val); } else System.out.println("\nWARNING:Car "+v.getID() +" could not be returned from hire "); v.print(); DateTime.setAdvance(8,0,0); // Attempt to hire the car now available if ( v.hire("User9999") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nWARNING: Car " + v.getID() + " could not be hired "); v.print(); } } Programming Fundamentals Assignment 2 2019 Semester 2 18 Expected Output Programming Fundamentals Assignment 2 2019 Semester 2 19 Section II Using the Vehicle class (i) Declare an array named vehs that can store the references of up to 5 Vehicle objects. Create 5 Vehicle objects using its constructor passing the values specified below (for ID, description, daily-rate and odometer reading), storing their references in the array. SAM134, Toyota Camry 02, 45.00, 140000 QKO156, Honda Accord 04, 65.0, 125000 TUV178, Toyota Starlet 02, 35.00, 180000 SAG132, Toyota Avalon 05, 52.0, 190000 PRE342, Honda Civic 97, 35.00, 145000 (ii) Display the ID and description of all the vehicles stored in the array. Hint: Access the Vehicle objects by iterating through the array of references vehs (using a loop). Extract ID and description of these objects using their accessors. (iii) Allow user to view the vehicles in the required price range (by specifying lower- and upper limits for daily rate). Display ID, description and daily-rate of all matching vehicles. If no vehicles are found in the range, print an appropriate message. Hint: This requires you to loop through the array of references and select the required objects using the accessor for daily-rate. (iv) Allow user to hire, complete-hire, service or complete-service a vehicle specifying the vehicle ID. If a vehicle is being hired prompt the user to enter the hirer-ID, and if service-complete or hire-complete options are selected prompt the user to enter the odometer reading as well. Hint: This requires looping through the array of references to locate the object with the specified vehicle ID. If such an object is found then invoke the appropriate method on that object passing the required argument. Print appropriate error message if the object with specified ID cannot be found or if the required operation cannot be performed. (v) Allow user to repeat the step 4, using a do while loop. The loop should be repeated, as long as user responds positively to the prompt, “Any more transactions?”. (vi) Print the final details of all the vehicle objects using a for loop and the print() method. Programming Fundamentals Assignment 2 2019 Semester 2 20 Part B Section I : Writing the subclass PremiumVehicle BestDeals car-rentals also supplies premium cars, which are newer luxury cars. The charges for premium cars are based on distance covered and duration of hire. The premium cars are charged for each additional km beyond the free mileage allowed (based on daily mileage and the duration of hire). The free mileage allowance varies from one premium car to another. Assume the charge per km after the daily free mileage is $0.10 per km. All premium cars must be serviced within a specified duration, which also varies from car to car. Derive a subclass of Vehicle named PremiumVehicle. This subclass should include three additional instance variables: free mileage allowance per day, service length (for example after every 10000 km) and the odometer reading at last service. The constructor for this class should take three additional arguments corresponding to these three instance variables. This subclass (PremiumVehicle) must override the following methods which should make use of the superclass methods. serviceComplete(into do) // to update the odometer reading on completion of service hireComplete(int odo) // to include mileage based charges in addition to duration based charges. hire(String hirer) // to verify whether car service is due for service (in addition to availability) // For example a premium car with last service 15,000, service length 10,000 and current // odometer reading 26,000 cannot be hired (even if it is available). print() // to display the instance variables mileage, last-service and service duration in addition to // the superclass instance variables (ID, description, …) public String toString() // Override the toString method to return the String representation of the object Programming Fundamentals Assignment 2 2019 Semester 2 21 You are expected to test your PremiumVehicle class with the driver class TestPremiumVehicle class given below. Expected output is given below. // Class to test the PremiumVehicle class (provided) class TestPremiumVehicle { public static void main(String args[]) { // passing ID, description, daily-rate, odometer reading, daily-mileage, // service-length, last-service PremiumVehicle v = new PremiumVehicle("SAM134", "Lexus 05", 95.00, 18000, 200, 10000, 17500); v.print(); if ( v.hire("ST36784") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nCar " + v.getID() + " could not be hired "); v.print(); DateTime.setAdvance(4,2,0); int odoReading = 28000; double val = v.hireComplete(odoReading); if ( val > 0.0 ) { System.out.print("\nCar " + v.getID() + " is returned by " + v.getHirer()); System.out.println(" Charges = " + val + " odo Reading = " + odoReading); } else System.out.println("\nWARNING: Car " + v.getID() + " could not be returned from hire "); v.print(); Programming Fundamentals Assignment 2 2019 Semester 2 22 DateTime.setAdvance(6,0,0); // attemption to hire a car which is due for service if ( v.hire("ST7656") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nCar " + v.getID() + " could not be hired "); DateTime.setAdvance(7,0,0); // sending car for service if ( v.service() == true) System.out.println("\nCar " + v.getID() + " is now sent to service"); else System.out.println("\nCar " + v.getID() + " could not be serviced "); v.print(); DateTime.setAdvance(8,0,0); if ( v.serviceComplete(28100) == true) System.out.println("\nCar " + v.getID() + " is now returned from service"); else System.out.println("\nCar " + v.getID() + " could not be returned from serviced "); v.print(); DateTime.setAdvance(9,0,0); if ( v.hire("ST7656") == true) System.out.println("\nCar " + v.getID() + " is now hired to " + v.getHirer()); else System.out.println("\nCar " + v.getID() + " could not be hired "); v.print(); } } Programming Fundamentals Assignment 2 2019 Semester 2 23 Expected Output C02QN0BFFVH6:PF19 charles$ java TestPremiumVehicle ******************* Vehicle Details ********************* Tue Sep 24 06:39:52 AEST 2019 vehicle ID=SAM134 Description=Lexus 05 Ststus=A Daily Rate=95.0 Odometer reading =18000 Mileage Allowance = 200 Sevice Length = 10000 Last Service = 17500 Car SAM134 is now hired to ST36784 ******************* Vehicle Details ********************* Tue Sep 24 06:39:52 AEST 2019 vehicle ID=SAM134 Description=Lexus 05 Ststus=H Daily Rate=95.0 Odometer reading =18000 Hirer=ST36784 Date/time of hire=Tue Sep 24 06:39:52 AEST 2019 Mileage Allowance = 200 Sevice Length = 10000 Last Service = 17500 Car SAM134 is returned by ST36784 Charges = 1375.0 odo Reading = 28000 ******************* Vehicle Details ********************* Sat Sep 28 08:39:52 AEST 2019 vehicle ID=SAM134 Description=Lexus 05 Ststus=A Daily Rate=95.0 Odometer reading =28000 Mileage Allowance = 200 Sevice Length = 10000 Last Service = 17500 Car SAM134 could not be hired Car SAM134 is now sent to service ******************* Vehicle Details ********************* Tue Oct 01 06:39:52 AEST 2019 vehicle ID=SAM134 Description=Lexus 05 Ststus=S Daily Rate=95.0 Odometer reading =28000 Mileage Allowance = 200 Sevice Length = 10000 Last Service = 17500 Car SAM134 is