Grails - find where date ranges overlap - grails

I have a Grails domain object with a startDate and endDate property.
What's the best way to find all those objects where the range [startDate, endDate] overlaps with a specified date range? I know how to do this in SQL but wonder if there's any Grails/GORM magic to do it more succinctly.
Also, the endDate is an optional property.
The SQL / JPQL query would be something like
from MyObject obj where obj.startDate <= ?1 and (obj.endDate is null OR obj.endDate >= ?2)

Two Ways to embrace Grails/GORM in this case:
Lazy:-
def today = new Date()
def query = MyObject.where {
startDate <= (today - 10) && (endDate == null || endDate >= today + 10)
}
def listOfMyObjects = query.list()
Eager:-
def today = new Date()
def listOfMyObjects = MyObject.findAll {//or find{} if you need the first occurance
startDate <= (today - 10) && (endDate == null || endDate >= today + 10)
}

Related

Ruby use guard to assign variable inside if clause

Is it possible to replace below if clause by guard?
end_date = if transaction_end_date.nil?
(starts_in_the_future ? start_date : today) + MIN_END_DATE
else
transaction_end_date
end
You can do this instead
end_date = transaction_end_date
end_date ||= (starts_in_the_future ? start_date : today) + MIN_END_DATE
or just
end_date = transaction_end_date ||
(starts_in_the_future ? start_date : today) + MIN_END_DATE

How do I set params max and offset in the List in Grails

I am stuck at a point where i am fetching a list from domain and save it into another list. How do i pass param to the newly created list
the code looks likes below:
params.max = Math.min(max ?: 10, 100)
params.offset = params.offset as Integer ?: 0
Calendar date = Calendar.getInstance();
date.set(Calendar.DAY_OF_MONTH, 1);
Calendar date2 = Calendar.getInstance();
date2.set(Calendar.DAY_OF_MONTH, date.getActualMaximum(Calendar.DAY_OF_MONTH));
def MonthStartDate =date.getTime()
def MonthEndDate =date2.getTime()
int monthMaxDays = MonthEndDate - MonthStartDate + 1
Calendar cal0 = Calendar.getInstance();
cal0.set(Calendar.DAY_OF_MONTH,1);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,1);
def myNewList = new ArrayList<DomainABCTYPE>()
def perDayDates = new ArrayList<Date>()
for(int i=0;i<monthMaxDays;i++) {
Date date1 = cal0.getTime();
cal.add(Calendar.DATE, 1);
Date calDate = cal.getTime();
def myListPerDay = DomainABCTYPE.findAllByStartDateLessThanAndEndDateGreaterThanEquals(calDate, date1, params)
int k=0
for(;k < myListPerDay .size(); k++){
myNewList.add(myListPerDay .get(k))
perDayDates.add(date1)
}
cal0.add(Calendar.DATE, 1)
}
render(view: "index", model:[ListInstance:myNewList ,ListCount:myNewList.size(), DatesList:perDayDates, MonthStartDate: MonthStartDate, MonthEndDate: MonthEndDate])
}
Have a look here on how you can pass pagination params directly into a GORM find method.
I was briefly looking over your code in all honesty it all looks insane, you are calculating a date diff then iterating the date diff to find records.
Why not write a HQL query and use between
where a.date BETWEEN :date1 AND :date2
In short all of that could be done with 1 lookup and no nested iterations lookup should be needed

Ruby on Rails, Select Users with age range from Active Record

User.rb
# Attributes
# (..)
# birthdate (string)
# format "mm/yyyy"
def age
dob = self.birthdate.to_date
now = Time.now.utc.to_date
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
In the console:
irb(main):002:0> current_user.age
=> 7
I'd be able to do the following:
age_range = "25-65"
User.where(:age => between age_range)
I'm stuck at the point how to get the value from age (class method) into the where call
First of all: use a date as type for birthdate in the database.
Then you can just use:
User.where(birthdate: 65.years.ago..25.years.ago)
If you can't change the birthdate type convert it using SQL (example with PostrgeSQL):
User.where('to_date(birthdate, 'MM/YYYY') between ? and ?', 65.years.ago, 25.years.ago)
But you may still have to correct it since you don't have the exact day and only the month.
With PostgreSQL you can use that Rails scope
scope :for_age_range, -> min, max {
where("date_part('year', age(birthdate)) >= ? AND date_part('year', age(birthdate)) <= ?", min, max)
}
User.for_age_range(18, 24)

How to find the data between month in entityframework?

I had requirement to display the data of this month (between month starting to ending data )
I know how to do in MySQL below query
enter code here select #MonthAmount := IFNULL(sum(AmountReceived), 0.0) as TotoalAmountperMonth
from collection
where date_time between DATE_FORMAT(NOW() ,'%Y-%m-01')
and LAST_DAY(now() - interval 0 month ) and AgentID=v_agent) as monthamount
but how to do using entity (lambda expression) I am new to entity when I google I got to get the data of today but in month?
below query got the result of today data
enter code here var newAuctionsResults = repo.FindAllAuctions()
.Where(a => a.IsActive == true
|| (a.StartTime.Value.Year == todayYear
&& a.StartTime.Value.Month == todayMonth
&& a.StartTime.Value.Day == todayDay))
.ToList();
Try
DateTime date = DateTime.Today;
var newAuctionsResults = repo.FindAllAuctions()
.Where(a => a.StartTime.Value.Year == date.Year
&& a.StartTime.Value.Month == date.Month)

Searching the values by using dynamic finders for two fields in grails

I am trying to search using dynamic finders for two fields: status and OpenOn (a date).
render(view:'list', model:[incidentInstanceList:Incident.findAllByStatusIlikeAndOpenOnGreaterThan("closed",new Date()-7,[sort:"id",order:"desc"])])
The above query searches the last 7 days, but I want to search for "last week", not the last 7 days. How can I do this?
You may want something like this:
def lastWeek
use(org.codehaus.groovy.runtime.TimeCategory) {
lastWeek = new Date() - 1.week
}
render(view:'list', model: [incidentInstanceList: Incident.findAllByStatusIlikeAndOpenOnGreaterThan( "closed", lastWeek, [sort:"id", order: "desc"])] )
UPDATE:
import java.util.Calendar
import groovy.time.TimeCategory
def roundToLastMonday(date) {
Calendar cal=Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - cal.get(Calendar.DAY_OF_WEEK) + Calendar.MONDAY)
cal.getTime()
}
def getLastWeekRange() {
def startDate, endDate
use(TimeCategory) {
startDate = roundToLastMonday(1.week.ago)
endDate = startDate + 1.week - 1.second
}
[startDate, endDate]
}
def range = getLastWeekRange()
def result = Incident.withCriteria {
like ("status", "closed")
between ("open", range[0], range[1])
}
render(view:'list', model: [incidentInstanceList: result]

Resources