Let's simulate a grocery store system! We want to be able to keep track of the orders that folks make, both online and physically in our grocery store.
This project will allow you to explore object-oriented design as well as a few other new topics. This is an individual, stage 1 project.
The project is due before class on Tuesday February 20th
You should demonstrate an ability to:
- Practice Test-Driven-Development
 - Use instance variables and methods
 - Reading from a CSV file
 - Write DRY code by reusing methods
 - Use inheritance to create a subclass
 
- Fork the project master.
 - Clone the forked repo: 
$ git clone [YOUR FORKED REPO URL] cdinto the dir created$ cd grocery-store- Run 
git remote -vto verify the folder you are in corresponds to the fork you have created.
If it is correct it will include your username If it is incorrect it will include "AdaGold" or "Ada-CX" - Run 
gem install minitest-skipto install an extra gem for testing (more on what this actually does later). 
This is our first project with real tests! Following the instructions from the TDD lecture, there are three things in our project directory:
Rakefile
lib/
specs/
Each class you write (there will only be one until wave 3) should get its own file, lib/class_name.rb. The specs for that class will be in specs/class_name_spec.rb, and you can run all specs using the rake command from your terminal.
- Create a class inside of a module
 - Create methods inside the class to perform actions
 - Learn how Ruby does error handling
 - Verify code correctness by testing
 
For Wave 1, all tests have been provided for you. For each piece of functionality that you build, you should run the tests from the command line using the rake command. To focus on only one test at a time, change all it methods to xit except for the one test you'd like to run. All tests provided should be passing at the end of your work on Wave 1.
Create a Grocery module which will contain an Order class and any future grocery store logic.
Create an Order class which should have the following functionality:
- A new order should be created with:
- an ID, read-only
 - a collection of products and their cost
- zero products is permitted
 - you can assume that there is only one of each product
 
 
 - A 
totalmethod which will calculate the total cost of the order by:- summing up the products
 - adding a 7.5% tax
 - ensure the result is rounded to two decimal places
 
 - An 
add_productmethod which will take in two parameters, product name and price, and add the data to the product collection- It should return 
trueif the item was successfully added andfalseif it was not 
 - It should return 
 
Make sure to write tests for any optionals you implement!
- Add a 
remove_productmethod to theOrderclass which will take in one parameter, a product name, and remove the product from the collection- It should return 
trueif the item was successfully remove andfalseif it was not 
 - It should return 
 
- Create and use class methods
 - Use a CSV file for loading data
 - Create your own tests to verify method correctness.
 
You enter Wave 2 with all tests from Wave 1 passing. In Wave 2, you will fill in the test stubs that have already been provided for you in the order_spec.rb file and add the code which will get these tests to pass. You should run the tests regularly alongside the code you are writing in the Order class itself.
- Update the 
Orderclass to be able to handle all of the fields from the CSV file used as input- To try it out, manually choose the data from the first line of the CSV file and ensure you can create a new instance of your 
Orderusing that data 
 - To try it out, manually choose the data from the first line of the CSV file and ensure you can create a new instance of your 
 - Add the following class methods to your existing 
Orderclassself.all- returns a collection ofOrderinstances, representing all of the Orders described in the CSV. See below for the CSV file specifications- Determine if the data structure you used in Wave 1 will still work for these new requirements
 - Note that to parse the product string from the CSV file you will need to use the 
splitmethod 
self.find(id)- returns an instance ofOrderwhere the value of the id field in the CSV matches the passed parameter.
 
- What should your program do if 
Order.findis called with an ID that doesn't exist? 
The data, in order in the CSV, consists of:
| Field | Type | Description | 
|---|---|---|
| ID | Integer | A unique identifier for that Order | 
| Products | String | The list of products in the following format: name:price;nextname:nextprice | 
- Use inheritance to share some behavior across classes
 - Enhance functionality built in Wave 1
 - Add tests for all new classes and inherited functionality
 
You enter Wave 3 with all of your Order tests passing from Waves 1 & 2. In Wave 3 you will take the test stubs that are already written for you and fill in the test code that will get the tests to pass. You will continue running these test alongside the code you write to ensure you are going in the right direction.
For wave 3, you will create two new classes: Customer and OnlineOrder.
The OnlineOrder class will inherit behavior from the Order class and include additional data to track the customer and order status. An instance of the Customer class will be used within each instance of the OnlineOrder class.
Each class should get its own file under the lib/ directory, and each already has a spec file with stub tests.
Create a Customer class within the Grocery module.
Each new Customer should include the following attributes:
- 
ID
 - 
email address
 - 
delivery address information
 - 
The Customer should also have the following class methods:
self.all- returns a collection ofCustomerinstances, representing all of the Customer described in the CSV. See below for the CSV file specificationsself.find(id)- returns an instance ofCustomerwhere the value of the id field in the CSV matches the passed parameter.
 
The data for the customer CSV file consists of:
| Field | Type | Description | 
|---|---|---|
| Customer ID | Integer | A unique identifier corresponding to the Customer | 
| String | The customer's e-mail address | |
| Address 1 | String | The customer's street address | 
| City | String | The customer's city | 
| State | String | The customer's state | 
| Zip Code | String | The customer's zip code | 
Create an OnlineOrder class which will inherit behavior from the Order class.
Each new OnlineOrder should include all attributes from the Order class as well as the following additional attributes:
- A customer object
 - A fulfillment status (stored as a Symbol)
- pending, paid, processing, shipped or complete
 - If no status is provided, it should set to pending as the default
 
 
The OnlineOrder should include the following updated functionality:
- The 
totalmethod should be the same, except it will add a $10 shipping fee - The 
add_productmethod should be updated to permit a new product to be added ONLY if the status is either pending or paid (no other statuses permitted)- Otherwise, it should raise an 
ArgumentError(Google this!) 
 - Otherwise, it should raise an 
 
The OnlineOrder should also have the following class methods:
self.all- returns a collection ofOnlineOrderinstances, representing all of the OnlineOrders described in the CSV. See below for the CSV file specifications- Question Ask yourself, what is different about this 
allmethod versus theOrder.allmethod? What is the same? 
- Question Ask yourself, what is different about this 
 self.find(id)- returns an instance ofOnlineOrderwhere the value of the id field in the CSV matches the passed parameter. -Question Ask yourself, what is different about thisfindmethod versus theOrder.findmethod?self.find_by_customer(customer_id)- returns a list ofOnlineOrderinstances where the value of the customer's ID matches the passed parameter.
The data for the online order CSV file consists of:
| Field | Type | Description | 
|---|---|---|
| ID | Integer | A unique identifier for that Online Order | 
| Products | String | The list of products in the following format: name:price;nextname:nextprice | 
| Customer ID | Integer | A unique identifier corresponding to a Customer | 
| Status | String | A string representing the order's current status | 
Check out the feedback template to see what instructors will be looking for.