Slow response when calculating dynamic prices for hotels - ruby-on-rails

I need to show the cheapest available accommodation for a hotel by calculating its price based on certain conditions like check-in date, check-out date, number of adults, and many others.
Right now what I'm doing is that I'm passing hotel ids as params and looping all hotel accommodations and calculate the price against each accommodation and then fetching the accommodation with the least calculated price.
NOTE: Prices for a specific duration used to calculate the dynamic price is fetched using search kick gem and elasticsearch.
#hotels = Lodging.where(id: params[:ids].try(:split, ',')).includes(:accommodations)
#hotels.map{ |hotel| hotel.accommodations.map { |accom| accom.cumulative_price(params.clone) } }
The issue now is that I need to show 18 hotels on a single page and each hotel has at least 4-5 accommodations which take about 4-5 seconds to respond. Can someone guide me how can I reduce this response time?

Related

Modelling recurrent items (expenses) as records with Rails

I am writing what could be defined as an accountancy/invoicing app using Rails 5. I am in need of implementing a section that predicts the company's cashflow in the future. So far I've got the following:
Actual bank movements and balances (in the past), imported from the bank
Future invoices (income) which are expected to be paid on a certain date
Future one-time expenses which are expected to be paid on a certain date
Using these three sets of data, I can calculate, for any given date in the future, the sum of: the last known bank balance, plus all the future invoices values coming IN, minus all the future expenses going OUT, so I get, theoretically, the expected balance of the company for any given date.
My doubt arises when it comes to recurrent expenses (or potentially incomes). Given that all of the items I mentioned before (bank movements, invoices and expenses) are actual ActiveRecord records stored in my database, I'm not sure about how to treat the recurrent expenses, for example:
Let's imagine I want to enter a known future recurrent paycheck of a certain employee, which is $2000 every first day of the month.
1- Should I generate at some point the next X entries and treat them as normal future expenses (each with its own ID, date and amount)?
2- The other option I've thought of is having some kind of "declaration" on the nature of the recurrent expense, as in "it's $2000 every day 1 of month until -forever-", similarly to a cronjob. But, if I were to take this approach, I'd like to have an ActiveRecord - similar interface, so that I can do something like:
cashflow = []
last_movement = BankMovement.last
value = last_movement.balance
(last_movement.date..(last_movement.date + 12.months)).each do |day|
value += Invoice.pending.expected_on(day).sum(:gross_amount)
value -= Expense.pending.expected_on(day).sum(:gross_amount)
value -= RecurringExpense.expected_on(day).sum(:gross_amount)
cashflow.push( { date: day, balance: value } )
end
This feels almost right but, I'm not sure about how to link the actual expense when it comes with the recurrent/calculated one. How can I then change the date if the expense gets paid the day after it was supposed? I need to have an actual record of each one of those, at least whenever they are "consolidated".
I'm not really sure if I was clear enough with my trouble here, so, should anyone want and have some spare time to help me out, please feel free to ask for any extra relevant info, I'd really appreciate some help, especially if we can find a way of doing this "the Rails way"!

Database Design for product prices depending on time of a day

I'm building a food ordering web application with a standard product/category setup - a category (for example Pizza) has many products (Pizza Salami).
Category
--------
id
name
Product
-------
id
name
category_id
The problem: the price of a category depends on the time of the day. For example for 2pm - 6pm and 9pm - 11pm the price for a pizza is cheaper.
How would I design the prices table and relationships in an effective way?
If your pricing is predictable, you could put a "base price" attribute in the product table, then read it from code, and calculate the "final price", depending on the time. You'll then store that final price in your orders table.
But if you want to be able to read tje final price from the database, I sugest you look into your database documentation, for how to create functions and views.

Algorithm for tracking changes in value over time

I am writing a rails app that deals with product inventory. I would like to include the following features, and am struggling with developing an efficient algorithm:
View stock history (how many were in stock on each date)
Quantity removed from warehouse, and quantity added to warehouse over specific periods of time
Amount of time the product was out of stock in any given period
My questions are as follows:
What is the best way of tracking changes? In addition to my Products
table, should I create another table called
HistoricProductQuantities, and insert a new record each time there
is a change in the quantity?
What number should I track? The historic stock quantity (i.e. 50 in
stock on this day, 24 in stock on that day), or the CHANGE in stock
quantity i.e. -5 (5 sold) or 15 (15 added to inventory)? Or do I
track both in separate tables?
Thanks for your help.
First of all I recommend implementing Date Dimensions on your application, as it seems like you will be doing a lot of Time related calculations. Search on Google for date dimensions as it's beyond the scope of your questions. That said, I believe it will be of great benefit for your app to implement and use date dimensions.
As far as your direct questions go:
What is the best way of tracking changes? In addition to my Products table, should I create another table called HistoricProductQuantities, and insert a new record each time there is a change in the quantity?
Yes you could do this, I would probably call it HistoricProductSnapshot and keep track of the product activity in there on daily basis. With this information as well as time dimensions you could do calculations such as "how many of Product X Did we have 5 days ago or a month ago etc etc."
What number should I track? The historic stock quantity (i.e. 50 in stock on this day, 24 in stock on that day), or the CHANGE in stock quantity i.e. -5 (5 sold) or 15 (15 added to inventory)? Or do I track both in separate tables?
I do not have experience writing inventory control software but I believe with the Snapshot table I mentioned on the question above you would only have to keep track of quantities per day. The Change in product counts could then be calculated from your snapshot table. You could for example have a function that will output the product amount in a given time range as an array. Example: From March 1 to March 7 these were the stock amounts for Product Y [45,40,39,27,22,45,44].
Hope that helps. As I said I am not a product inventory guy but I have worked with Point of Sales Systems and the procedure above should give you a could enough start for what you are trying to do.
This gem could be usefull for tracking changes in models https://github.com/collectiveidea/audited
Keep the data raw. I would personally create a new data entry every day, displaying how much items you have in stock per day. Or you can make the interval much shorter, such as every 12 hours.
For our particular use case:
We had a table called Days, which had a many to many relationship with products, and each "relationship" will have a value called quantity (to keep track of quantity of product per day). Additionally per relationship, we had another value for the relationship with transactions (a one to many relationship) that has the entries for the time of transaction and remaining stocks.
I would personally advise you to use the quantity of stock as the raw data, as it will enable you to gather the data such as how much items were removed during a certain transaction, when the item was out of stock and when it became in stock, all through the data. When you have data in which you need to perform statistical calculations on, it's best to store this data as raw values (quantity of the item).

How to sum up different currencies in Rails app?

I am currently building a Ruby on Rails invoicing application that is multilingual and supports a range of currencies. In the dashboard view all invoices a user has produced are totalled.
Now it would be nice if a user could choose the currency for each invoice.
But how can those invoices be totalled if different currencies are used?
E.g. if these three invoices were created today:
Invoice No. 1: $1000.00
Invoice No. 2: $2000.00
Invoice No. 3: €1000.00
Total: $4333.60
----------------------
The dollar-euro exchange rate would have to be based on each invoice's date of course.
How can this be achieved in Rails and does it even make sense?
Thanks for any pointers.
The sum of of multiple invoices using different currencies is not a single number, it's a collection of numbers. If you have a 20 USD invoice, a 15 EUR invoice, and a 20 EUR invoice, the sum is "20 USD + 35 EUR".
At the time when a payment is made from a single account using a single base currency, then a conversion will be performed to determine how much will have to be paid in that currency to cover the total converted costs. Presumably, there will also be currency conversion fees added at that time.
It would be convenient if you change the currency to a single one, either euro or dollar right when the user makes an invoice. That is, you save the 'converted' value in your database. In this way you won't have to lookup for past day rates.
Eu_central_bank provides exchange rates.

YQL Fantasy Hockey - League Standings by Month?

I'm trying to gather league standings by month (or a custom time period)
I know how to do it for a specific date but can't seem to find a way to do from x to y
Is this possible? (other than repeating the query for each day I want)
Is is not a head to head or rotisserie league, just straight overall points.
Edit:
Example query:
No, there is no way to fetch by month or for a date range. If you look at the YQL table fantasysports.leagues.scoreboard, you can see the parameters only accept the optional week parameter. This matches the Yahoo! Fantasy Sports API docs (search for 'scoreboard') which shows it can give results for the current week, or another specified week.
I think this is because the Yahoo! Fantasy Sports scoreboards are all week-based, regardless of the actual frequency of games for the specific sport.
To capture scores by month, you can make several individual calls for each week.

Resources