How to filter in execute query by Date range value? - range

I have to made a Query in executeQuery , and I have to filter by date field,
my code is :
public void executeQuery()
{
utcDateTime dateUTC, datenullUTC;
query q = new Query();
QueryBuildRange qbr;
QueryBuildDataSource qbds ;
QueryRun queryRun;
dateUTC = DateTimeUtil::newDateTime(_dateValue, 0, DateTimeUtil::getCompanyTimeZone());
qbds = q.addDataSource(tableNum(MCRCustCategory) );
qbds.addRange(fieldNum(MCRCustCategory, ValidTo)).value(strFmt ("> %1", dateUTC) );
queryRun = new QueryRun (q);
super();
}
In my init I call the executeQuery, but don't filter in my Form.
How to use the date in the Range ?
Thanks all,
enjoy!

You use a table which use date effective. You assume you have to do the selection yourself, this is not true.
Use this instead:
public void executeQuery()
{
this.queryBuildDataSource().validTimeStateAsOfDate(_dateValue);
super();
}
If you have an interval, use this instead:
this.queryBuildDataSource().validTimeStateDateRange(fromDate, toDate)
Your code as provided in the question does not do anything at all, as the form does not use the query you build. You buildt the wrong query anyway!
This blog post explains it concisely.

Related

How to query by substring in a MongoDB ODM

I have this actual code
public function findCode($code_received)
{
$pellicules =
$this->createQueryBuilder()
->field('code_base')->equals($code_received)
->getQuery()
;
}
But sometimes my code received is inside my code_base, for example:
Code_received = Abata
Code_base = Abata23xiub
I tried to use the in instead of equals but I'm not having success. How could I do it?

please help me to convert trigger to batch apex

please help me in converting my after trigger to batch apex.
This trigger fires when opportunity stage changes to won.
It runs through line items and checks if forecast(custom objet) exists with that acunt.if yes,iit links to them..if no,itt will create a new forecat.
my trigger works fine forr some records.but to mass update i am getting timed out error.So opting batch apex but i had never written it.pls help me.
trigger Accountforecast on Opportunity (after insert,after update) {
List<Acc_c> AccproductList =new List<Acc_c>();
List<Opportunitylineitem> opplinitemlist =new List<Opportunitylineitem>();
list<opportunitylineitem > oppdate= new list<opportunitylineitem >();
List<Acc__c> accquery =new List<Acc__c>();
List<date> dt =new List<date>();
Set<Id> sProductIds = new Set<Id>();
Set<Id> sAccountIds = new Set<Id>();
Set<id> saccprodfcstids =new set<Id>();
Acc__c accpro =new Acc__c();
string aname;
Integer i;
Integer myIntMonth;
Integer myIntyear;
Integer myIntdate;
opplinitemlist=[select Id,PricebookEntry.Product2.Name,opp_account__c,Opp_account_name__c,PricebookEntry.Product2.id, quantity,ServiceDate,Acc_Product_Fcst__c from Opportunitylineitem WHERE Opportunityid IN :Trigger.newMap.keySet() AND Acc__c=''];
for(OpportunityLineItem oli:opplinitemlist) {
sProductIds.add(oli.PricebookEntry.Product2.id);
sAccountIds.add(oli.opp_account__c);
}
accquery=[select id,Total_Qty_Ordered__c,Last_Order_Qty__c,Last_Order_Date__c,Fcst_Days_Period__c from Acc__c where Acc__c.product__c In :sproductids and Acc__c.Account__c in :saccountids];
for(Acc__c apf1 :accquery){
saccprodfcstids.add(apf1.id);
}
if(saccprodfcstids!=null){
oppdate=[select servicedate from opportunitylineitem where Acc__c IN :saccprodfcstids ];
i =[select count() from Opportunitylineitem where acc_product_fcst__c in :saccprodfcstids];
}
for(Opportunity opp :trigger.new)
{
if(opp.Stagename=='Closed Won')
{
for(opportunitylineitem opplist:opplinitemlist)
{
if(!accquery.isempty())
{
for(opportunitylineitem opldt :oppdate)
{
string myDate = String.valueOf(opldt);
myDate = myDate.substring(myDate.indexof('ServiceDate=')+12);
myDate = myDate.substring(0,10);
String[] strDate = myDate.split('-');
myIntMonth = integer.valueOf(strDate[1]);
myIntYear = integer.valueOf(strDate[0]);
myIntDate = integer.valueOf(strDate[2]);
Date d = Date.newInstance(myIntYear, myIntMonth, myIntDate);
dt.add(d);
}
dt.add(opp.closedate);
dt.sort();
integer TDays=0;
system.debug('*************dt:'+dt.size());
for(integer c=0;c<dt.size()-1;c++)
{
TDays=TDays+dt[c].daysBetween(dt[c+1]);
}
for(Acc_product_fcst__c apf:accquery)
{
apf.Fcst_Days_Period__c = TDays/i;
apf.Total_Qty_Ordered__c =apf.Total_Qty_Ordered__c +opplist.quantity;
apf.Last_Order_Qty__c=opplist.quantity;
apf.Last_Order_Date__c=opp.CloseDate ;
apf.Fcst_Qty_Avg__c=apf.Total_Qty_Ordered__c/(i+1);
Opplist.Acc__c =apf.Id;
}
}
else{
accpro.Account__c=opplist.opp_account__c;
accpro.product__c=opplist.PricebookEntry.Product2.Id;
accpro.opplineitemid__c=opplist.id;
accpro.Total_Qty_Ordered__c =opplist.quantity;
accpro.Last_Order_Qty__c=opplist.quantity;
accpro.Last_Order_Date__c=opp.CloseDate;
accpro.Fcst_Qty_Avg__c=opplist.quantity;
accpro.Fcst_Days_Period__c=7;
accproductList.add(accpro);
}
}
}
}
if(!accproductlist.isempty()){
insert accproductlist;
}
update opplinitemlist;
update accquery;
}
First of all, you should take a look at this: Apex Batch Processing
Once you get a better idea on how batches work, we need to take into account the following points:
Identify the object that requires more processing. Account? Opportunity?
Should the data be maintained across batch calls? Stateful?
Use correct data structure in terms of performance. Map, List?
From your code, we can see you have three objects: OpportunityLineItems, Accounts, and Opportunities. It seems that your account object is using the most processing here.
It seems you're just keeping track of dates and not doing any aggregations. Thus, you don't need to maintain state across batch calls.
Your code has a potential of hitting governor limits, especially memory limits on the heap. You have a four-nested loop. Our suggestion would be to maintain opportunity line items related to Opportunities in a Map rather than in a List. Plus, we can get rid of those unnecessary for loops by refactoring the code as follows:
Note: This is just a template for the batch you will need to construct.
globalglobal Database.QueryLocator start(Database.BatchableContext BC) class AccountforecastBatch implements Database.Batchable<sObject>
{
global Database.QueryLocator start(Database.BatchableContext BC)
{
// 1. Do some initialization here: (i.e. for(OpportunityLineItem oli:opplinitemlist) {sProductIds.add(oli.PricebookEntry.Product2.id)..}
// 2. return Opportunity object here: return Database.getQueryLocator([select id,Total_Qty_Ordered__c,Last_Order_Qty ....]);
}
global void execute(Database.BatchableContext BC, List<sObject> scope)
{
// 1. Traverse your scope which at this point will be a list of Accounts
// 2. You're adding dates inside the process for Opportunity Line Items. See if you can isolate this process outside the for loops with a Map data structure.
// 3. You have 3 potential database transactions here (insert accproductlist;update opplinitemlist; update accquery; ). Ideally, you will only need one DB transaction per batch.If you can complete step 2 above, you might only need to update your opportunity line items. Otherwise, you're trying to do more than one thing in a method and you will need to redesign your solution
}
global void finish(Database.BatchableContext BC)
{
// send email or do some other tasks here
}
}

Symfony 2.4.1 and Doctrine 2 dates interval query

I have two tables: Empleado and Fichaje in a (1..*) relationship.
I created a query builder for getting fichajes corresponding to IdEmpleado (key) property in Fichaje.
I attempt to filter those Fichajes, but it never works. So I've searched for any clear example of dates in Doctrine for this basic case in vane.
The query result is empty always. No error is thrown.
If I check for IdEmpleado parameter only it gives me all the available records.
The dates interval is the problematic one.
Note: I checked this similar post
Here is the table data, I'm quite convinced of the dates availability.
This is my function:
public function empleadoAction(Request $request){
...
$repository = $em->getRepository('ZkTimeBundle:Fichaje');
$fichajes = $repository->FindByEmpleadoAndDateInterval(
array(
'IdEmpleado' => $workerId,
'FechaInicial' => (new \DateTime('2014-01-10'))->format('Y-m-d'),
'FechaFinal' => (new \DateTime('today'))->format('Y-m-d')
));
...
This is my repository function:
public function FindByEmpleadoAndDateInterval($parameters = array(), $limit = null){
...
$qb = $this->createQueryBuilder('q');
$qb
->where('q.IdEmpleado = :IdEmpleado')
->andWhere('q.Fecha > :FechaInicial')
->andWhere('q.Fecha < :FechaFinal')
->setParameter('IdEmpleado', $parameters['IdEmpleado'])
->setParameter('FechaInicial', $parameters['FechaInicial'])
->setParameter('FechaFinal', $parameters['FechaFinal'])
;
return $qb->getQuery()->execute();
}
Folks, careful with this, have a nice look to the format of dates when you're working with Doctrine 2. The problem was this:
-I've set dates format as: 'Y-M-d', but: 'Ymd' was the correct one (in my particular case).
So, have faith in Doctrine 2 and try every known format (Y-m-d), (Y/m/d), etc. So, you could use dates intervals in these simple ways:
public function findByEmpleadoAndDateInterval($parameters = array(), $limit = null)
{
$qb = $this->createQueryBuilder('q');
$qb->where('q.IdEmpleado = :IdEmpleado')
->andWhere('q.Fecha between :FechaInicial and :FechaFinal')
->setParameters($parameters);
return $qb->getQuery()->execute();
}
OR
public function findByEmpleadoAndDateInterval($parameters = array(), $limit = null)
{
$qb = $this->createQueryBuilder('q');
$qb->where('q.IdEmpleado = :IdEmpleado')
->andWhere('q.Fecha >= :FechaInicial and q.Fecha <= :FechaFinal')
->setParameters($parameters);
return $qb->getQuery()->execute();
}
Maybe, out there, there are more elaborated examples, but this case took me a while to figure it out. Specially because isn't directly accesible online.

Better and correct way of quering with multiple condtion?

[Authorize(Roles="Admin,Manager")]
public class PermissionController : ApiController
{
[HttpGet]
public IEnumerable<permission> Get()
{
using (var mydb = new ModelContainer())
{
if(User.IsInRole("Admin")){
return mydb.permissionSet.ToList();
}
else
{
//////Work
return mydb.permissionSet.Where(x=>x.name!="Admin").ToList().Where(x=>x.name!="Coder").ToList().Where(x=>x.name!="Tester").ToList();
//////Not work
return from a in mydb.permissionSet where a.name!="Admin" && a.name!="Manager" && a.name!="Coder" && a.name != "Tester" select a;
}
}
}
}
I think there are two ways of return the correct result, the first way above will work, but seems weird and I think it will query many times. The second way seems better way, but not work.
With LINQ you are building a query. Calling ToList() on such a query will force the query to execute and return the results. Your first option will build the query and return the results. Your second option returns the query. That is the difference.
mydb.permissionSet.Where(x=>x.name!="Admin").ToList().Where(x=>x.name!="Coder").ToList().Where(x=>x.name!="Tester").ToList();
Can be broken up as this:
var qryNoAdmin = mydb.permissionSet.Where(x=>x.name!="Admin");
var permissionSetNoAdmins = qryNoAdmin.ToList();
var qryNoAdminNoCoder = permissionSetNoAdmins.Where(x=>x.name!="Coder");
var permissionSetNoAdminsNoCoders = qryNoAdminNoCoder.ToList();
var qryNoAdminNoCoderNoTester = permissionSetNoAdminsNoCoders .Where(x=>x.name!="Tester");
var permissionSetNoAdminsNoCodersNoTesters = qryNoAdminNoCoderNoTester.ToList();
return permissionSetNoAdminsNoCodersNoTesters;
If that looks inefficient to you... Yes it is. Look at #user1778606 suggestion to make it more efficient.
Now your second option only returns the query. If you call ToList() on that, the query will be executed and you get the results.
var qryNoAdminNoCoderNoTester = from a in mydb.permissionSet where a.name!="Admin" && a.name!="Manager" && a.name!="Coder" && a.name != "Tester" select a;
var permissionSetNoAdminsNoCodersNoTesters = qryNoAdminNoCoderNoTester.ToList();
return permissionSetNoAdminsNoCodersNoTesters;
Please note I didn't test this code. There might be typos.
Suggested reading: Introduction to LINQ Queries (C#)
try to put them all in the same where clause line, ie.
return mydb.permissionSet.Where(x=>x.name!="Admin" & x.name!="Coder" & x.name!="Tester").ToList();
btw, I dont think it re-queries in the way you did it first, it just filters the resulting list, but there may be a bit of overhead in recreating the list each time after the filter, ie. I think
return db.permissionSet.Where(x=>x.name!="Admin").Where(x=>x.name!="Coder").Where(x=>x.name!="Tester").ToList();
should be equally efficient to the consolidated where clause above

MongoDB DateTime Format

In mongodb adhoc query, before executing the query, how to format the date type element to dd\mm\yyyy format and then execute the query?
I solved this by inserting the datetime as integer using the getTime() method in java.
EG:
Date dt=new Date();
long integer_date=dt.getTime();
I used the above line of code to insert date as integer.With this it was easy to fetch records between a particular date.
I asked a similar question a little while back...this might be what you're looking for: What is the syntax for Dates in MongoDB running on MongoLab?
If you are using Java, you can create Date objects from strings using the parse method of the DateFormat class.
The Java documentation on the DateFormat Class may be found here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DateFormat.html
The specific section on the parse method is here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DateFormat.html#parse%28java.lang.String%29
The Java documentation on the Date object may be found here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Date.html
As per the "Constructor Summary" section, the ability to pass a string into the constructor is "Deprecated. As of JDK version 1.1, replaced by DateFormat.parse(String s)."
While I was researching the above, I also came across the Calendar class, which may be used for converting a Date object and a set of integers. It may not be necessary for this application, but I thought it might be useful to include a link to the documentation:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html
Integers for year, month, day, hour, etcetera may be passed in via the set method:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html#set%28int,%20int,%20int,%20int,%20int%29
By way of example, here is a short Java Program that creates a number of Date objects, stores them in a Mongo collection, and then executes a query similar to what you have described. Hopefully it will help you to accomplish your goal. NOTE: This program drops a collection named "dates", so be sure to change the collection name if you already have such a collection in your database!
public static void main(String[] args) throws UnknownHostException, MongoException {
Mongo m = new Mongo( "localhost:27017" );
DB db = m.getDB("test");
DBCollection coll = db.getCollection("dates");
coll.drop();
DateFormat df = DateFormat.getInstance();
String dateString = new String();
Date myDate = new Date();
// Save some test documents
for(int i=1; i<11; i++){
dateString = "04/" + String.valueOf(i) + "/12 11:00 AM, EST";
BasicDBObject myObj = new BasicDBObject("_id", i);
try {
myDate = df.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
myObj.put("date", myDate);
System.out.println(myDate);
coll.save(myObj);
}
// Build the query
Date startDate = new Date();
Date endDate = new Date();
try {
startDate = df.parse("04/4/12 11:00 AM, EST");
endDate = df.parse("04/6/12 11:00 AM, EST");
} catch (ParseException e) {
e.printStackTrace();
}
BasicDBObject dateQuery = new BasicDBObject();
dateQuery.put("$gte", startDate);
dateQuery.put("$lte", endDate);
System.out.println("---------------");
//Execute the query
DBCursor myCursor = coll.find(new BasicDBObject("date", dateQuery));
//Print the results
while(myCursor.hasNext()){
System.out.println(myCursor.next().toString());
}
}
This is use full to format code to date format from simple date time format and the reverse steps also supporting this way to retrieve date from MongoDB.
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date fDate = formatter.parse((String) metaData.getValue());
newMeta.setValue(fDate);[![In this image you can see how is the save scenario process in mongoDB][1]][1]
Date class has a before(date) or after(date) method... It is easy to use: no conversion to seconds/milliseconds.
public void execute(Tuple input) {
try {
date=(Date) input.getValueByField("date");
boolean before = date.before(myDate); // compare the data retrieved with your date.
if (before) {
...
} else {
...
}
} catch (Exception e) {
logger.error("Error...", e);
}
This approach is easier than the accepted answer..