How to define a table schedule? - ruby-on-rails-3

I have a table Schedules where I can store the day(s) a Person work. Now I want to add the hours this Person works. Let's say Person works Monday from 9am to 11am, Tuesday from 9am to 6pm, and so on...
Also in every date range (from start_time to end_time ) how can I set the hours Person do not work like lunch time?
create_table "schedules", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "person_id"
t.boolean "sun"
t.boolean "mon"
t.boolean "tue"
t.boolean "wed"
t.boolean "thu"
t.boolean "fri"
t.boolean "sat"
end
Should I create a second table to store the hours of each day?

I think modeling a Person's work schedule will work better as a one-to-many:
Person
has_many :shifts
end
Shift
#fields person_id, day, start_time, end_time
belongs_to :person
end
Then, to create the schedule you describe ('Monday from 9am to 11am, Tuesday from 9am to 6pm, and so on...'):
#person = Person.find(1)
#person.shifts.create!(:day => 'mon', :start_time => '9 am', :end_time => '11 am')
#person.shifts.create!(:day => 'tue', :start_time => '9 am', :end_time => '6 pm')
When you wanted to display this info, just iterate over the Person's Shifts:
#person.shifts.each do |s|
puts "#{#person.name} works on #{s.day} from #{s.start_time} to #{s.end_time}."
end
You could choose to simply model 'lunch breaks' by giving the Person two shifts for that day . If, for instance, they worked from 9am to 7pm with an hour off starting at 1pm, give them on shift on that day from 9am to 1pm and one from 2pm to 7pm.

You could create a ref table between Person and Days (for example) that would include the Time and the flag for whenever they work or not.

Related

Stripe subscription with fixed monthly renewal date

I want fixed subscription invoice date on my stripe subscriptions. Currently it takes 30days in each month and If I create a subscription on 1st, next invoice comes on 30th but it should be 1st for every month. Here is my code-
$subscription = $stripe->subscriptions->create([
'customer' => $customerID,
'items' => $items,
'add_invoice_items' => $invoiceitems,
'payment_behavior' => 'default_incomplete',
'expand' => ['latest_invoice.payment_intent'],
'trial_end' => $startdate,
//'cancel_at' => $enddate,
'proration_behavior' => 'always_invoice',
'billing_cycle_anchor' => $startdate
]);
I can see in your code snippet that you are using the billing_date_anchor. The docs state
Determines the date of the first full invoice, and, for plans with month or year intervals, the day of the month for subsequent invoices.
Based on that here are two things you should try.
Verify the price.recurring attribute has your prices recurring with interval set to "month" and interval_count set to 1.
Ensure the $startdate value passed in is anchored to your timezone.

Oracle SQL for Last Business Day of Current Month including federal holidays in oracle

I'm trying to find the Oracle SQL for finding the last business day of current month and also last business day of previous month. Both cases should consider the federal holidays calendar.
For Example:
Last Business Day of Current Month
If am running as of date 15th November, 2019
I should technically get my output as 29th November since 28th is Thanksgiving holiday.
Store those federal holidays in a holidays table as DATE type and then
try something like this: Find the oldest ( MAX ) day in the last seven days of the month that is neither a Saturday or a Sunday nor a holiday mentioned in
the holidays table.
The assumptions here are that 1) not all seven days at the end of the month can all be holidays or weekend and 2) Saturday and Sundays are off. You may adjust the level or where clause accordingly, depending on whether the above assumption should always hold true or not.
SELECT MAX(dt) AS last_working_day
FROM
(
SELECT last_day(SYSDATE) - level + 1 as dt
FROM dual CONNECT BY
level <= 7 -- the last seven days of the month
) WHERE TO_CHAR(dt,'DY', 'NLS_DATE_LANGUAGE = AMERICAN') NOT IN ('SAT','SUN')
AND dt NOT IN ( SELECT holiday from federal_holidays );
A much better approach would be to have a Calendar table with all the dates of the year and predefined column called isbusinessday. Then the query would be much simpler.
SELECT MAX(dt)
FROM calendar
WHERE isbusinessday = 'Y'
AND TO_CHAR(dt,'YYYYMM') = TO_CHAR(SYSDATE,'YYYYMM');
Having a holiday table is working in general, however it requires some maintenance as certain holidays are moving. For example Thanksgiving Day is the 4th Thursday in November, i.e. it varies from November 22 to November 28.
You can also use the Oracle build-in Scheduler. Usually it is used to control the SCHEDULER JOBS but I don't see any reason why it should not be used for something else.
First create a list of federal holidays, for example this:
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'CHRISTMAS', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=1225', comments => 'December 25');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'COLUMBUS_DAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=OCT;BYDAY=2 MON', comments => '2nd Monday in October');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'INDEPENDENCE_DAY', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=0704', comments => 'July 4');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'MARTIN_LUTHER_KING_DAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=JAN;BYDAY=3 MON', comments => '3rd Monday in January');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'MEMORIAL_DAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=MAY;BYDAY=-1 MON', comments => 'Last Monday of May');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'NEW_YEARS_DAY', repeat_interval => 'FREQ=YEARLY;INTERVAL=1;BYDATE=0101', comments => 'January 1');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'THANKSGIVING', repeat_interval => 'FREQ=MONTHLY;BYMONTH=NOV;BYDAY=4 THU', comments => '4th Thursday in November');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'WASHINGTONS_BIRTHDAY', repeat_interval => 'FREQ=MONTHLY;BYMONTH=FEB;BYDAY=3 MON', comments => '3rd Monday in February');
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'WEEKEND', repeat_interval => 'FREQ=DAILY;INTERVAL=1;BYDAY=SAT,SUN');
-- Combined schedule for all federal holidays
DBMS_SCHEDULER.CREATE_SCHEDULE(schedule_name => 'FEDERAL_HOLIDAYS', repeat_interval => 'FREQ=DAILY;INTERSECT=CHRISTMAS,INDEPENDENCE_DAY,MARTIN_LUTHER_KING_DAY,MEMORIAL_DAY,NEW_YEARS_DAY,THANKSGIVING,WASHINGTONS_BIRTHDAY');
END;
/
Have a look at Calendaring Syntax to see how repeat_interval needs to be specified.
Then you can use procedure DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING to get your date:
CREATE OR REPLACE FUNCTION LAST_BUSINESS_DAY(today IN TIMESTAMP DEFAULT SYSTIMESTAMP) RETURN TIMESTAMP AS
return_date_after TIMESTAMP := TRUNC(today);
next_run_date TIMESTAMP;
BEGIN
LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=DAILY;INTERVAL=1;EXCLUDE=FEDERAL_HOLIDAYS,WEEKEND', NULL, return_date_after, next_run_date);
EXIT WHEN next_run_date >= LAST_DAY(TRUNC(today));
return_date_after := next_run_date;
END LOOP;
RETURN return_date_after;
END LAST_BUSINESS_DAY;

Get series of counts with conditions using ActiveRecord

I'm displaying a graph of Subscription counts that may have been soft_destroyed_at at some point.
To do this I run a query for each month which is of course not as good as one big honking query but my SQL skills fail me once again.
Here's how I do it in Ruby:
months = (0..12).map { |i| i.months.ago.end_of_month }
stats = Hash[months.map do |eom|
[
eom.beginning_of_month.to_date,
Subscription.where(
'created_at < ?' \
'AND (soft_destroyed_at IS NULL ' \
' OR soft_destroyed_at > ?) ' \
'AND (suspended_at IS NULL ' \
' OR suspended_at > ?)',
eom, eom, eom
).count
]
end]
# => { 2018-04-01 => 10, 2018-03-01 => 15, ... }
How could I write this as one query using ActiveRecord – or if necessary using raw SQL>
The database is Postgres 10.2, the app is Rails 5.2.
Thanks!
You can use this query (I used 12 month in 2017; just change as you wish). This assumes a Postgresql DB, as you said in a comment:
query =
"select months.month, count(created_at) "\
"from "\
"(select DATE '2017-01-01'+(interval '1' month * generate_series(0,11)) as month, "\
"DATE '2017-02-01'+(interval '1' month * generate_series(0,11)) as next) months "\
"outer join subscriptions on "\
"created_at < month and "\
"(soft_destroyed_at IS NULL or soft_destroyed_at >= next) and "\
"(suspended_at IS NULL OR suspended_at >= next) "\
"group by month "\
"order by month"
results = ActiveRecord::Base.connection.execute(query)
The first subquery (the select inside from) generates this:
month next
"2017-01-01 00:00:00";"2017-02-01 00:00:00"
"2017-02-01 00:00:00";"2017-03-01 00:00:00"
"2017-03-01 00:00:00";"2017-04-01 00:00:00"
"2017-04-01 00:00:00";"2017-05-01 00:00:00"
"2017-05-01 00:00:00";"2017-06-01 00:00:00"
"2017-06-01 00:00:00";"2017-07-01 00:00:00"
"2017-07-01 00:00:00";"2017-08-01 00:00:00"
"2017-08-01 00:00:00";"2017-09-01 00:00:00"
"2017-09-01 00:00:00";"2017-10-01 00:00:00"
"2017-10-01 00:00:00";"2017-11-01 00:00:00"
"2017-11-01 00:00:00";"2017-12-01 00:00:00"
"2017-12-01 00:00:00";"2018-01-01 00:00:00"
Next is only used to make it easier to check if the subscription was active at least until next month (destroyed or suspended are >= next (which guarantees the subscriber was active during current month).

Need to know the specific shipping method code for UPS Standard within Shopify's API

I have an urgent need to know the specific code for UPS Standard shipping within Shopify's API. It would be a 2-digit number found in the Order API, shipping-lines > shipping-line > code.
Thanks for any assistance.
UPS Standart code value is '11'
Also some other UPS codes:
'01' => 'Next Day Air ("Red")',
'02' => 'Second Day Air ("Blue")',
'03' => 'Ground',
'07' => 'Express',
'08' => 'Expedited',
'11' => 'Standard',
'12' => 'Third Day Select',
'13' => 'Next Day Air Saver ("Red Saver")',
'14' => 'Next Day Air Early A.M.',
'15' => 'Next Day Air Early A.M.',
'22' => 'Ground - Returns Plus - Three Pickup Attempts',
'32' => 'Next Day Air Early A.M. - COD',
'33' => 'Next Day Air Early A.M. - Saturday Delivery, COD',
'41' => 'Next Day Air Early A.M. - Saturday Delivery',
'42' => 'Ground - Signature Required',
'44' => 'Next Day Air - Saturday Delivery',
'54' => 'Express Plus',
'59' => 'Second Day Air A.M.',
'65' => 'WorldWide Saver',
'66' => 'Worldwide Express',
'72' => 'Ground - Collect on Delivery',
'78' => 'Ground - Returns Plus - One Pickup Attempt',
'90' => 'Ground - Returns - UPS Prints and Mails Label',
'A0' => 'Next Day Air Early A.M. - Adult Signature Required',
'A1' => 'Next Day Air Early A.M. - Saturday Delivery, Adult Signature Required',
'A2' => 'Next Day Air - Adult Signature Required',
'A8' => 'Ground - Adult Signature Required',
'A9' => 'Next Day Air Early A.M. - Adult Signature Required, COD',
'AA' => 'Next Day Air Early A.M. - Saturday Delivery, Adult Signature Required, COD',
If you download the UPS shipping developer documentation, there are no longer any codes for 'Saturday' delivery in the Appendix or elsewhere. Instead you use the service you want, say 'Next Day Air' or 'Next Day Air Early AM' would be the common ones along with the SaturdayDeliveryIndicator. From their documentation:
Saturday delivery indicator. The presence indicates Saturday delivery;
the absence indicates not Saturday delivery.
There are several ways:
in magento admin go to system > configuration and click on shipping methods tab and rightclick inside of the Allowed Methods box, Inpect the element and you'll see something like UPS Standard value represents the method code.
or open app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php and around the line 327 you will see all shipping methods with corresponding codes.

Distance of time in days

In rails 3 there is distance_of_time_in_words which works fine, but I would like to tweak its output a bit.
The thing is that if the dates are exactly the same it will say "Less Than a day" I would like it to show "Today" instead.
Is that possible?
I wrote a gem called "date-casually" that monkey-patches the Date class with a "casual" method:
Date.today.casual
#=> 'today'
(Date.today + 1).casual
#=> 'tomorrow'
(Date.today - 1).casual
#=> 'yesterday'
Hope it helps:
http://rubygems.org/gems/date-casually