get values between two dates in silverstripe - sql

i have added two date fields. i want to retrieve the data between those two table.PaymentDate and ChequePostedDate are two fields. so i need to get the rows between two dates.
simply search content have two date fields. i want to retrieve the rows(data) between those two dates
public function __construct($modelClass, $fields = null, $filters = null) {
$fields = new FieldList(array(
DateField::create('PaymentDate','Payment Date : from')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
DateField::create('ChequePostedDate','cr Date : to')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
));
$filters = array(
'PaymentDate' => new PartialMatchFilter('PaymentDate'),
'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
parent::__construct($modelClass, $fields, $filters);
}
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (isset($params['PaymentDate'])&& $params['ChequePostedDate'] ) {
$query->where('`PaymentNote`.PaymentDate BETWEEN \''.$params['PaymentDate'].' \' AND \''.$params['ChequePostedDate'].'\'');
}
}
return $dataList->setDataQuery($query);
}
}

You can also use WithinRangeFilter something like the following, but you need to use the setMin(), setMax() methods as per this forum response: https://www.silverstripe.org/community/forums/form-questions/show/11685
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (!empty($params['PaymentDate'] && !empty($params['ChequePostedDate'])) {
return $dataList->filter('PaymentDate:WithinRange', [$params['PaymentDate'], $params['ChequePostedDate']]);
}
}
return $dataList;
}

i solved it..
simply remove $filters
$filters = array(
// 'PaymentDate' => new PartialMatchFilter('PaymentDate'),
//'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
then it works

Related

Implement Phalcon 4 Database Existence validator (similar to Uniqueness)

Often I need to validate if given value is existing in certain column (attribute) of a table (model).
This can be useful in foreign keys of a model, to check if the given values exists.
Most probably the validation logic can be mostly the same as for Uniqueness, except the comparison here can be something like > 0.
A possible usage scenario could be like below:
$validator->add(
'organization_id',
new ExistenceOnDbValidator(
[
'model' => Organization::class,
'expr'=> ' id = %s ',
'excludeNullValue'=> true,
'message' => 'Organization does not exist.',
]
)
);
Finally I implemented myself a validator called ExistenceOnDbValidator and it works fine.
Usage
$validator = new Validation();
$validator->add(
'organization_id',
new ExistenceOnDbValidator(
[
'model' => Organization::class,
'expr' => ' id = %s ',
'ignoreNullValue' => false,
'message' => 'Selected organization does not exist.',
]
)
);
Implenentation
use Phalcon\Messages\Message;
use Phalcon\Validation;
use Phalcon\Validation\AbstractValidator;
use Phalcon\Validation\ValidatorInterface;
class ExistenceOnDb extends AbstractValidator implements ValidatorInterface
{
public function validate(Validation $validator, $attribute): bool
{
$expr = $this->getOption('expr');
$model = $this->getOption('model');
$value = $validator->getValue($attribute);
$ignoreNullValue = true;
if ($this->hasOption('ignoreNullValue')) {
$ignoreNullValue = $this->getOption('ignoreNullValue');
}
if ((is_null($value) || empty($value)) && $ignoreNullValue == true) {
return true;
}
$expr = sprintf(
$expr,
$value,
);
$result = $model::findFirst($expr);
if ((is_null($result) || empty($result))) {
$message = $this->getOption('message');
$validator->appendMessage(new Message($message));
return false;
}
return true;
}
}

CDbCriteria throwing column name is ambigous

I have the following method in a controller of my Yii app.
public function actionManage($typeid=0, $locationid=0, $page=1, $rows=12, $sidx='date_input', $sord='desc', $kategori='')
{
if (Yii::app()->request->isAjaxRequest) {
// Jika dilakukan operasi 'edit' pada row
if (isset($_REQUEST['oper']))
{
$oper = $_REQUEST['oper'];
$id = $_REQUEST['id'];
if ($oper == 'edit')
{
$value = $_REQUEST['value'];
$record = InputData::model()->findByPk($id);
$record->value = $value;
$record->update();
}
if($oper == 'delete'){
$model = InputData::model()->findByPk($id);
$model->delete();
}
}
// inisialisasi criteria query
$criteria = new CDbCriteria();
$criteria->order = "$sidx $sord";
// filter lokasi
if (is_numeric($locationid) && $locationid !== 0)
{
$criteria->with = array('data'=>array(
'condition'=>'data.locationid=:locationid',
'params'=>array(':locationid'=>$locationid)
));
} else {
if (is_numeric($typeid) && $typeid !== 0)
{
$criteria->with = array('data.location'=>array(
'with'=>array(
'type'=>array(
'condition'=>'type.typeid=:typeid',
'params'=>array(':typeid'=>$typeid)
)
)
));
} else {
$criteria->with = array('data.location'=>array(
'with'=>array(
'type'=>array(
'condition'=>'type.type_desc=:type_desc',
'params'=>array(':type_desc'=>$kategori)
)
)
));
}
}
// filter range tanggal
if (isset($_REQUEST['startdate'], $_REQUEST['enddate']))
{
$startdate = $_REQUEST['startdate'];
$enddate = $_REQUEST['enddate'];
$criteria->condition = 'date_input <= :enddate AND date_input >= :startdate';
$criteria->params = array(':startdate'=>$startdate, ':enddate'=>$enddate);
}
if(isset($_REQUEST['dataid'])){
$dataid = $_REQUEST['dataid'];
$criteria->addCondition("dataid = $dataid");
}
$dataProvider = new CActiveDataProvider('InputData', array(
'criteria'=>$criteria,
'pagination'=>array(
'currentPage'=>$page-1,
'pageSize'=>$rows
)
));
$count = $dataProvider->totalItemCount;
$total_pages = $count > 0 ? ceil($count/$rows) : 0;
if ($page > $total_pages) $page=$total_pages;
// generate response untuk jqgrid
$response = new stdClass();
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
foreach($dataProvider->getData() as $row)
{
$response->rows[] = array(
'id'=>$row->inputdataid,
'cell'=>array(
$row->inputdataid,
$row->date_input,
$row->time_input,
$row->data->location->location_name,
$row->data->data_name,
$row->data->variable->var_name,
round($row->value, 3),
$row->data->variable->unit->uom_name,
($row->inputOfficer !== NULL ? $row->inputOfficer->officer_name:''),
'<i class="fa fa-pencil-square-o"></i> Edit <i class="fa fa-trash-o"></i> Delete'
)
);
}
echo json_encode($response);
} else {
$url = $this->createUrl("dataAir/manage");
$delurl = $this->createUrl("dataAir/deleteRow");
$startdate = '2013-01-01';
$enddate = date_format(new DateTime(), 'Y-m-d');
$this->render('jqgrid', array(
'kategori'=>$kategori,
'url'=>$url,
'delurl'=>$delurl,
'startdate'=>$startdate,
'enddate'=>$enddate
));
}
}
this line causing the problem
if(isset($_REQUEST['dataid'])){
$dataid = $_REQUEST['dataid'];
$criteria->addCondition("dataid = $dataid");
}
when, I remove those lines the method work just fine. what could be the problem causing ambigous colum name? here is the error log
SELECT COUNT(DISTINCT "t"."inputdataid") FROM "app_inputdata" "t" LEFT OUTER JOIN "app_ref_periodicdata" "data" ON ("t"."dataid"="data"."dataid") WHERE ((date_input <= :enddate AND date_input >= :startdate) AND (dataid = 7)) AND (data.locationid=:locationid). Bound with :startdate='2013-01-01', :enddate='2015-02-02', :locationid='6'
You need to add the table alias t to your condition:
$criteria->addCondition("t.dataid = $dataid");
Also, since $dataid is being obtained from a $_REQUEST it is best to pass it as a parameter. This can be done in two ways:
$criteria->addCondition("t.dataid = :dataid", [":dataid" => $dataid]);
$criteria->compare("t.dataid", $dataid);
you have used table aliases,
'with'=>array(
'type'=>array(
'condition'=>'type.type_desc=:type_desc', <<- I mean here you have used alias : type
'params'=>array(':type_desc'=>$kategori)
)
you just have to remember that the main model that you are working with, will always need alias t to unambigufy! (not sure if that is an actual word :D )

Laravel4: WhereHas Eloquent Issue (nested). callback function error

I tried doing a search function where the only field would be an <input type='text' /> it'll be stripped into an array() then passed to a whereLoop.
static function generateSearch($fields, $queryString)
{
return function($query) use($queryString, $fields)
{
foreach($fields as $field) {
$query = $query->orWhere($field, 'like', $queryString);
}
$query = $query->whereHas('category', function($_query) use ($queryString)
{
$_query->where('name','like',$queryString);
});
};
}
public static function search($query)
{
$searchBits = explode(' ', $query);
$query = Lead::with(array('user', 'category'));
$ctr = 0;
if(Category::whereIn('name', $searchBits)->count() != 0) {
$query = $query->whereHas('category', function($query) use ($searchBits)
{
$ctr = 0;
foreach($searchBits as $bit) {
$bit = "%".$bit."%";
$callback = "orWhere";
$queryFunc = Lead::generateSearch(array('name'), $bit);
if($ctr == 0) {
$callback = "where";
}
$query = $query->$callback($queryFunc);
}
});
}else {
foreach($searchBits as $bit) {
$bit = "%".$bit."%";
$callback = "orWhere";
$queryFunction = Lead::generateSearch(array('name', 'website', 'name', 'email'), $bit);
if($ctr == 0) {
$callback = "where";
}
$query = $query->$callback($queryFunction);
$ctr++;
}
}
$query = $query->orderBy('id','desc');
return $query;
}
Category only has ONE row as of the moment: its - "hot"
if i type in any keyword, it'll directly go to generateSearch()
but if i type in "hot", it'll send an error
Call to undefined method
Illuminate\Database\Query\Builder::category()
does anybody know what's up?
found the error. after looking deep within the callstack. i should not have added the
$query = $query->whereHas('category', function($_query) use ($queryString)
{
$_query->where('name','like',$queryString);
});
inside the generateSearch() or i should create another function for it. its being called by category callback as well.

Magento API, Return Orders with NULL values

Using the magento api version 1 and soap.
Need to return all orders with 'coupon_code'=> NULL
The call I'm attempting:
$order_listAR = $proxy->call($sessionId, 'sales_order.list', array(array('coupon_code'=>array('null'=>'null'))));
The ouput I want returned is this:
array(237) {
["state"]=>
string(8) "complete"
["status"]=>
string(8) "complete"
["coupon_code"]=> NULL
So far this seems to work properly, but I'm not sure if ('null'=>'null') is the proper way to find NULL values in the array. Can someone explain why this works, and, or if this is the correct syntax? I don't have any margin for error on this.
Yes, the syntax you use is correct to filter against null.
array(
'coupon_code' => array(
'null' => 'this_value_doesnt_matter'
)
)
Magento maps* the API method sales_order.list to Mage_Sales_Model_Order_Api::items().
public function items($filters = null)
{
:
$collection = Mage::getModel("sales/order")->getCollection()
:
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_attributesMap['order'][$field])) {
$field = $this->_attributesMap['order'][$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
:
}
The items() method uses a Mage_Sales_Model_Resource_Order_Collection to fetch the orders for the API call. That collection is based on Varien_Data_Collection_Db, so
$collection->addFieldToFilter($field, $value)
from above essentially does call
Varien_Data_Collection_Db::addFieldToFilter()
If you follow the latter, you'll hit Varien_Db_Adapter_Pdo_Mysql::prepareSqlCondition() in the end, params being
$fieldName = 'coupon_code'
$condition = array('null' => 'null')
Excerpt of that method:
public function prepareSqlCondition($fieldName, $condition)
{
$conditionKeyMap = array(
'eq' => "{{fieldName}} = ?",
:
'notnull' => "{{fieldName}} IS NOT NULL",
'null' => "{{fieldName}} IS NULL",
:
'sneq' => null
);
:
$query = '';
if (is_array($condition)) {
:
$key = key(array_intersect_key($condition, $conditionKeyMap));
if (isset($condition['from']) || isset($condition['to'])) {
:
} elseif (array_key_exists($key, $conditionKeyMap)) {
$value = $condition[$key];
if (($key == 'seq') || ($key == 'sneq')) {
:
}
$query = $this->_prepareQuotedSqlCondition($conditionKeyMap[$key], $value, $fieldName);
} else {
:
}
}
:
}
In your case _prepareQuotedSqlCondition() will be called with
$text = '{{fieldName}} IS NULL'
$value = 'null'
$fieldName = 'coupon_code'
which will result in $query = 'coupon_code IS NULL'.
If you take a closer look at the conversion method
protected function _prepareQuotedSqlCondition($text, $value, $fieldName)
{
$sql = $this->quoteInto($text, $value);
$sql = str_replace('{{fieldName}}', $fieldName, $sql);
return $sql;
}
you'll also see, why the value of the 'null' => 'null' key/value pair does not matter at all. That's because $text will be '{{fieldName}} IS NULL', i.e. not containing any binding ?.
Hence, there's nothing to replace for _quoteInto()^^
* see app/code/core/Mage/Sales/etc/api.xml

codeigniter pagination for a query

So far found plenty of help to get the pagination working for a get(table) command.
What I need is to pick only few of the entries from a couple of linked tables based on a sql where statement.
I guess the query command is the one to use but in this case how do I do the pagination since that command does not take extra parameters such $config['per_page']
Thanks for the help
Without any more info to go on I think that what you're looking for is something like the following.
public function pagination_example($account_id)
{
$params = $this->uri->ruri_to_assoc(3, array('page'));
$where = array(
'account_id' => $account_id,
'active' => 1
);
$limit = array(
'limit' => 10,
'offset' => (!empty($params['page'])) ? $params['page'] : 0
);
$this->load->model('pagination_model');
$data['my_data'] = $this->pagination_model->get_my_data($where, $limit);
foreach($this->uri->segment_array() as $key => $segment)
{
if($segment == 'page')
{
$segment_id = $key + 1;
}
}
if(isset($segment_id))
{
$config['uri_segment'] = $segment_id;
}
else
{
$config['uri_segment'] = 0;
}
$config['base_url'] = 'http://'.$_SERVER['HTTP_HOST'].'/controller_name/method_name/whatever_your_other_parameters_are/page/';
$config['total_rows'] = $this->pagination_model->get_num_total_rows();// Make a method that will figure out the total number
$config['per_page'] = '10';
$this->load->library('pagination');
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
$this->load->view('pagination_example_view', $data);
}
// pagination_model
public function get_my_data($where = array(), $limit = array())
{
$this->db
->select('whatever')
->from('wherever')
->where($where)
->limit($limit['limit'], $limit['offset']);
$query = $this->db->get();
if($query->num_rows() > 0)
{
$data = $query->result_array();
return $data;
}
return FALSE;
}
This should at least get you on the right track
If this isn't what you're asking I'd happy to help more if you can be a little more specific. How about some of your code.
The only other options that I can think of would be to either code a count in your select statement or not limit the query and use array_slice to select a portion of the returned array.