-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
takeaway-challenge #2234
base: main
Are you sure you want to change the base?
takeaway-challenge #2234
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/**/.DS_Store | ||
/coverage | ||
|
||
.env | ||
# Local cache of Rubocop remote config | ||
.rubocop-* |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,6 @@ end | |
|
||
group :development, :test do | ||
gem 'rubocop', '1.20' | ||
gem 'twilio-ruby' | ||
gem 'dotenv' | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
require 'twilio-ruby' | ||
require 'dotenv' | ||
Dotenv.load | ||
|
||
class Confirmation | ||
|
||
def initialize | ||
@to = ENV['TO_PHONE_NUMBER'] | ||
from = ENV['TWILIO_PHONE_NUMBER'] | ||
end | ||
|
||
def send | ||
account_sid = ENV['TWILIO_ACCOUNT_SID'] | ||
auth_token = ENV['TWILIO_AUTH_TOKEN'] | ||
client = Twilio::REST::Client.new(account_sid, auth_token) | ||
|
||
client.messages.create( | ||
from: from, | ||
to: @to, | ||
body: "Thank you for your order" | ||
) | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
class Menu | ||
|
||
attr_reader :menu | ||
|
||
def initialize | ||
@menu = [ | ||
{ :item => 1, :dish => "Mattar Paneer", :price => 12.50 }, | ||
{ :item => 2, :dish => "Black Daal", :price => 7.50 }, | ||
{ :item => 3, :dish => "Raita", :price => 3.50 }, | ||
{ :item => 4, :dish => "Garlic Naan", :price => 3.50 } | ||
] | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hashes are most useful where you have a key value pair - eg. if the only information you needed to record was the item name and price, a simple hash could look like:
@menu[item_name] will return the cost of that item. For data requiring more than two values, where key/value isn't enough, I would suggest defining a new object, for example:
This way, you could work with an array of Dishes inside your Menu class, eg. @menu = [Dish.new(args), Dish.new(args), etc.] Singular dish data can be accessed with @menu[0].name, etc. Which can be quite a bit easier than traversing a complex hash! |
||
|
||
def view | ||
@menu.map { |dish| "#{dish[:item]}. #{dish[:dish]} £#{dish[:price]}" } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Were you to use just a single key/value hash as the one I suggested in my first comment, you could refactor this to something like:
This will print the full menu. |
||
end | ||
|
||
def existing_dish(number, qty) | ||
@menu.select { |dish| dish[:item] == number } != [] | ||
end | ||
|
||
def selection(number, qty) | ||
@menu.select { |dish| dish[:item] == number } | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
class Order | ||
|
||
DELIVERY = 2700 | ||
|
||
def initialize(time = Time.new) | ||
@time = time | ||
end | ||
|
||
def delivery_time | ||
duration = @time + DELIVERY | ||
duration.strftime("%H:%M") | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
class TakeAway | ||
|
||
attr_reader :menu, :order, :take_away | ||
|
||
def initialize(menu = Menu.new, confirmation = Confirmation.new) | ||
@confirmation = confirmation | ||
@menu = menu | ||
@order = [] | ||
@take_away = 0 | ||
@total = 0 | ||
@current_dish = [] | ||
end | ||
|
||
def view_menu | ||
@menu.view | ||
end | ||
|
||
def add_dish(number, qty) | ||
fail "please enter a valid dish number" if @menu.existing_dish(number, qty) != true | ||
if duplicate_dish(number, qty) == true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a good idea. I just kept adding to the 'basket' array of hashes, so your idea of actually editing a quantity value seems a lot more like a real user experience |
||
update_qty(number, qty) | ||
else | ||
@order << current_dish(number, qty) | ||
end | ||
dish_added_message(number, qty) | ||
end | ||
|
||
def view_basket | ||
@order.map { |dish| "#{dish[:qty]} x #{dish[:dish]} £#{dish[:price]}/each -> £#{dish[:subtotal]}" } | ||
end | ||
|
||
def order_total | ||
"Your order total is £#{total}" | ||
end | ||
|
||
def place_order | ||
@confirmation.send | ||
end | ||
|
||
private | ||
|
||
def duplicate_dish(number, qty) | ||
@order.select { |dish| dish[:item] == number } != [] | ||
end | ||
|
||
def update_qty(number, qty) | ||
@order.map { |dish| (dish[:qty] = (dish[:qty] + qty)) && (dish[:subtotal] = dish[:qty] * dish[:price]) if (dish[:item] == number) } | ||
end | ||
|
||
def current_dish(number, qty) | ||
(@menu.selection(number, qty).push(:qty => qty, :subtotal => sub_total(number, qty))).reduce(&:merge) | ||
end | ||
|
||
def dish_added_message(number, qty) | ||
(@menu.selection(number, qty)).map do |dish| | ||
"#{qty} x #{dish[:dish]} £#{dish[:price]}/each, has been added to your order -> £#{(sub_total(number, qty))}" | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although this is functional, the functionality to receive a confirmation for each item added to the order is not mentioned in the spec - you should stick as closely as possible to the spec as possible. This helps keep your code clean / simple! |
||
end | ||
|
||
def sub_total(number, qty) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could omit this and only calculate the total at runtime / when the user confirms the order. |
||
sub_total = @menu.selection(number, qty) | ||
sub_total.map { |item| item[:price] * qty } | ||
end | ||
|
||
def total | ||
@order.map { |item| (item[:subtotal]) }.flatten.sum | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
require 'confirmation' | ||
|
||
describe Confirmation do | ||
|
||
subject(:confirmation) { Confirmation.new } | ||
|
||
it "should create an instance of class Confirmation" do | ||
expect(confirmation).to be_instance_of(Confirmation) | ||
end | ||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a good idea - wish I'd thought of this!