How to check null date condition in drools? - jboss

I have to check a condition on date whether a date field of a entity is in range of another two sets of date from other entity
First Entity :
1. id
2. name
3. date
Second Entity ;
1. id
.
.
.
.
17 : Start Date
18 : End Date
I have to check whether the date field of first entity is in range of Start Date and End Date of second entity.
e.g.
(t1.date>= t2.Start Date and t1.date <= t2.End Date)
Problem is that, there are some row where t2 is null.. if it is null, then second condition return true.
My Attempt
PriorAuthorizationLogVO( cardid == $paidClaimVO.cardholderId, ruleType == 'INCL' , $paidClaimVO.time>=etime , (ttime==null || (ttime!=null && $paidClaimVO.time<=ttime))
But, i am not able to confirm whether it is working....
Please help.

You could add that check for date between the range of dates in either a static helper method or within one of your entities. In my opinion this will make your rules more readable and you can easily write unit tests for the date check method.
Option 1 - Static helper method
Create a class for having static helper methods, something like this
public class DateUtils {
private DateUtils() {} // Cannot be initialized
public static boolean dateInRange( Date toCheck, Date min, Date max ) {
// Add null checks here
// Use Date#before(Date) and Date#after(Date) for checking
return true|false
}
}
Your rule would then be like
import static DateUtils.*
rule "date in range"
when:
dateInRange( e1.date, e2.start, e2.end )
then:
// logic
end
Option 2 - Method within fact/entity
Create the check method inside one of your facts. In which entity to put this depends on your use case, the information you've given does not specify this yet. I think you can figure out the best place by yourself. Anyway, the code would be something like this
public class Entity1 {
Date date
}
public class Entity2 {
Date start
Date end
public boolean entity1InRange( Entity1 e ) {
// null checks
// Use the Date#before() and Date#after() as above
}
}
And the rule
rule "date in range"
when:
e2.entity1InRange( e1 )
then:
// Logic
end

Related

Create a trigger that validates the data for the Product object

I have an apex trigger (before insert/update) and a helper class to that trigger. The problem is: When creating an object record, the trigger should check if the AddedDate field is filled and if it's not - then assign it today's date and current time.
And when I create and update a Product object record, the trigger must check the length of the Description field, if the field is longer than 200 characters, I must trim it to 197 characters and add a triple to the end of the line.
What am I doing wrong and how should I proceed?
My trigger:
trigger ProductTrigger on Product__c (before insert, before update) {
if(Trigger.isUpdate && Trigger.isAfter){
ProductTriggerHelper.producthandler(Trigger.new);
}
}
Trigger helper class:
public class ProductTriggerHelper {
public static void producthandler(List<Product__c> products) {
Schema.DescribeFieldResult F = Product__c.Description__c.getDescribe();
Integer lengthOfField = F.getLength();
//List<Product__c> prList = new list<Product__c>();
for(Product__c pr: products){
pr.AddedDate__c=system.today();
if (String.isNotEmpty(pr.Description__c)) {
pr.Description__c = pr.Description__c.abbreviate(lengthOfField);
}
}
}
}
According to your requirements
When creating an object record, the trigger should check if the AddedDate field is filled and if it's not - then assign it today's date and current time.
You aren't doing that.
Change pr.AddedDate__c=system.today(); to
if (pr.AddedDate__c == null) { pr.AddedDate__c=system.today(); }
Also according to the abbreviate function documentation the parameter it takes is the max length including the 3 elipses.
So change pr.Description__c = pr.Description__c.abbreviate(lengthOfField); to
pr.Description__c = pr.Description__c.abbreviate(200);
To add to Programmatic's answer...
You defined the trigger as before insert, before update. Cool, that's perfect place for doing data validations, field prepopulation... And you'll get save to database for free!
But then this clashes with next line if(Trigger.isUpdate && Trigger.isAfter){. With this setup it'll never fire. Either remove the if completely or (if you think trigger can get more events in future) go with trigger.isBefore && (trigger.isInsert || trigger.isUpdate).
P.S. It's datetime field? So pr.AddedDate__c=system.now(); is better

Models column date format

I modified my models date property to can calculate birthdays, but now when the date is loaded in my form(I use Form collective) I get it like 1979-07-17 00:00:00 right output should be 1979-07-17
protected $dates = ['geburtstag'];
public function age()
{
return $this->geburtstag->diffInYears(Carbon::now());
}
I tried to modify from model like
protected $geburtstagFormat = 'Y-m-d';
but did not help.
What I do wrong in this case
Why don't you just use $model->geburtstag->format('Y-m-d')?
You can also create a mutaror in your model like:
public function getGeburstagDateAttribute($value) {
return $this->geburtstag->format('Y-m-d');
}
and use it like this:
$model->geburtstag_date // outputs geburtstag date in 'Y-m-d' format
To set the date format in a model, use protected $dateFormat = 'Y-m-d'; inside the model.
Another way of doing it
First parse the $this->geburtstag->diffInYears(Carbon::now())
$createdAt = Carbon::parse($this->geburtstag->diffInYears(Carbon::now()));
Then you can use
$suborder['payment_date'] = $createdAt->format('M d Y');
If you don't want to store the time of birth you should change the data type in your database to date instead of from timestamp or datetime. This will solve the problem automatically since when you call the attribute on your view, this extract exactly how it's shown on database. Otherwise, if you want to keep the database unchanged you have to define a mutator in your model, like this:
public function getGeburstag($value){
return Carbon::parse($value)->toDateString();
}
This will replace the original value of geburtag attribute to its values in Y-m-d format.

How to edit date value with date type format in bootstrap

I have these codes but then the value display in the edit box is "mm/dd/yyyy"
#Html.TextBoxFor(m => m.StartDate, new { #Value = Model.StartDate.ToString("MM/dd/yyyy"), #placeholder= Model.StartDate.ToString("MM/dd/yyyy"), #class = "form-control", #type="date" })
How can I achieve something like this where the displayed date is the value from the database and not "mm/dd/yyyy"
First, don't set the value attribute directly. Razor will pretty much ignore this anyways. The value for a bound field comes from ModelState, which is itself composed of values from Request, ViewBag/ViewData, and Model, in that order. So, for example, if you want StartDate to default to "today", then you would simply populate your model with that in the action before you return the view:
model.StartDate = DateTime.Today;
Or, better, you can change the property on your model class to default to today automatically:
private DateTime? startDate;
public DateTime StartDate
{
get { return startDate ?? DateTime.Today; }
set { startDate = value; }
}
Just bear in mind that if your action happens to take a param like startDate or you set something like ViewBag.StartDate, those values will always take precedence.
Second, you're utilizing an HTML5 date input type. In browsers that support the HTML5 input types, the supplied value for a datetime, date or time, must be in ISO format. For a date, that means YYYY-MM-DD. If the value is not supplied like that, then the browser considers it garbage and discards it, leaving the control as if no value was supplied.
Also, FWIW, you don't need to prefix every member of your anonymous object with #. It doesn't technically hurt anything, but it's code smell. The # prefix exists to escape language keywords. With class, for example, you can't use it directly since it's a keyword, so you have to use #class instead. However, things like placeholder and type are not keywords, and therefore don't need an # prefix.

Laravel 5.1 Won't save date into database set as 00-00-00 00:00:00

I'm sending dates up using this Bootstrap datetimepicker with a format of MMM D, YYY created by MomentJS, which can't submit a different format than what is displayed to the user by default.
So on the server-side I added an mutator for the date in the model:
public function setStartDateAttribute($startDate) {
//dd(Carbon::parse($startDate)->toDateTimeString());
return Carbon::parse($startDate)->toDateTimeString();
}
Which when I dd the value looks like it should 2015-10-22 00:00:00, but it saves the date as 0000-00-00 00:00:00 or it just isn't setting the date at all, which I don't understand.
I don't want to change how the timestamps are formatted in the database so I didn't set $dateFormat and set 'start_date' in the $dates array of the Model. Thought an mutator seemed easier. The field is set to date() in the migration file, and I'm pretty sure I've done this before and it just worked. So I tried it in the my controller without the mutator and the same line works:
public function update(TournamentRequest $request, $tournamentId)
{
// Update a tournament with all fillable data, and persist to database
$tournament = Tournament::find($tournamentId)->fill($request->except('start_date'));
$tournament->start_date = Carbon::parse($request->start_date)->toDateTimeString();
$tournament->save();
return Redirect::route('dashboard.tournaments.index');
}
Why does the same code work inside the controller without the mutator setup in the Model, but not work when using the mutator?
This is how you make a setter method for your attribute. Note: you don't return anything, you just assign a value to the attribute:
public function setStartDateAttribute($startDate) {
$this->attributes['start_date'] = Carbon::parse($startDate)->toDateTimeString();
}
That's assuming you want to set a field named start_date in your table.

Compare DateTime in Fluid

I want to compare a dateTime Object with the today date.
This is my date Object
<f:format.date format="d.m.Y - H:i:s">{article.validFrom}</f:format.date>
I want to make a condition, if the date Object is bigger than the current day. I will do something.
Can anybody help me ?
Convert the date to an unix timestamp using format="U" and compare them. You need to add a variable which contains the current date.
In your controller add
$this->view->assign('date_now', new DateTime());
// or for TYPO3 >= 6.2
$this->view->assign('date_now', new \DateTime());
then in your template use following
<f:if condition="{f:format.date(date: article.validFrom, format: 'U')} > {f:format.date(date: date_now, format: 'U')}">
Date is valid
</f:if>
EDIT:
The other way (and I think is the better way) is to add a new method to your model which checks this. Example:
Classes/Domain/Model/Article.php
class Article extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* #return boolean
*/
public function getDateIsValid() {
return ($this->getValidFrom() > new DateTime());
}
}
then you can simply use
<f:if condition="{article.dateIsValid}"></f:if>