CDbCriteria throwing column name is ambigous - yii

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 )

Related

How to get the Gross Sales from the Square Order API?

Qn1) I have tried getting the gross sales from the Order API. However, I could only be able to get each lineitem gross value concatenating with one and another ...
Gross value that is concatenating
Qn2) I tried to echo all the item name, qty and etc to insert it into my database although it works but I am getting an error message shown below
Error message
Here is my code: (Have replaced the access token and the location_id to 'XXXX')
<html>
<?php
require_once(__DIR__ . '/vendor/autoload.php');
use Square\SquareClient;
use Square\Environment;
$client = new SquareClient([
'accessToken' => 'XXXX',
'environment' => Environment::PRODUCTION,
]);
$location_ids = ['XXXX'];
$created_at = new \Square\Models\TimeRange();
$created_at->setStartAt('2021-05-17T00:00:00+08:00');
$created_at->setEndAt('2021-05-17T23:59:59+08:00');
$date_time_filter = new \Square\Models\SearchOrdersDateTimeFilter();
$date_time_filter->setCreatedAt($created_at);
$filter = new \Square\Models\SearchOrdersFilter();
$filter->setDateTimeFilter($date_time_filter);
$sort = new \Square\Models\SearchOrdersSort('CREATED_AT');
$sort->setSortOrder('DESC');
$query = new \Square\Models\SearchOrdersQuery();
$query->setFilter($filter);
$query->setSort($sort);
$body = new \Square\Models\SearchOrdersRequest();
$body->setLocationIds($location_ids);
$body->setQuery($query);
$body->setLimit(10000);
$body->setReturnEntries(false);
$api_response = $client->getOrdersApi()->searchOrders($body);
if ($api_response->isSuccess()) {
$result = $api_response->getResult();
$orders = $result->getOrders();
foreach($orders as $x => $val) {
$lineItems = $result->getOrders()[$x]->getLineItems();
$orderid = $result->getOrders()[$x]->getId();
foreach($lineItems as $q => $val2){
$lineItemsID = $lineItems[$q]->getUid();
$itemName = $lineItems[$q]->getName();
$itemQty = $lineItems[$q]->getQuantity();
$catalogObjID = $lineItems[$q]->getCatalogobjectid();
$grossSales[] = $lineItems[$q]->getGrossSalesMoney()->getAmount();
echo (array_sum($grossSales)/100); //Qn1
echo($orderid. " ". $lineItemsID ." ".$catalogObjID." ".$itemName ." ".$itemQty." <br/>"); //Qn2
}
}
}
else
{
$errors = $api_response->getErrors();
}
?>
</html>
<html>
<?php
require_once(__DIR__ . '/vendor/autoload.php');
use Square\SquareClient;
use Square\Environment;
$client = new SquareClient([
'accessToken' => 'XXXX',
'environment' => Environment::PRODUCTION,
]);
$location_ids = ['XXXX'];
$created_at = new \Square\Models\TimeRange();
$created_at->setStartAt('2021-05-17T00:00:00+08:00');
$created_at->setEndAt('2021-05-17T23:59:59+08:00');
$date_time_filter = new \Square\Models\SearchOrdersDateTimeFilter();
$date_time_filter->setCreatedAt($created_at);
$filter = new \Square\Models\SearchOrdersFilter();
$filter->setDateTimeFilter($date_time_filter);
$sort = new \Square\Models\SearchOrdersSort('CREATED_AT');
$sort->setSortOrder('DESC');
$query = new \Square\Models\SearchOrdersQuery();
$query->setFilter($filter);
$query->setSort($sort);
$body = new \Square\Models\SearchOrdersRequest();
$body->setLocationIds($location_ids);
$body->setQuery($query);
$body->setLimit(10000);
$body->setReturnEntries(false);
$api_response = $client->getOrdersApi()->searchOrders($body);
if ($api_response->isSuccess()) {
$result = $api_response->getResult();
$orders = $result->getOrders();
$grossSales = array();
if (is_array($orders) || is_object($orders)) {
foreach($orders as $x => $val) {
$lineItems = $result->getOrders()[$x]->getLineItems();
$orderid = $result->getOrders()[$x]->getId();
if (is_array($lineItems) || is_object($lineItems)){
foreach($lineItems as $q => $val2){
$lineItemsID = $lineItems[$q]->getUid();
$itemName = $lineItems[$q]->getName();
$itemQty = $lineItems[$q]->getQuantity();
$catalogObjID = $lineItems[$q]->getCatalogobjectid();
$grossSales[] = $lineItems[$q]->getGrossSalesMoney()->getAmount();
}
}
}
}
$sum = 0;
foreach($grossSales as $key=>$value)
{
$sum+= $value;
}
echo ($sum/100);
}
else
{
$errors = $api_response->getErrors();
}
?>
</html>

Is it possible to shorten this query

we have used loop for read between timestamps. This works but this way exhausting for server with million records.
The timestamps are determined by the $resolution variable and assigned to a new array. But we know this is poor way. I think we can do that without while. Maybe one query enough.
Route::get('/history', function (Request $request) {
//return response()->json([]);
$symbol = explode("-", $request->get("symbol"));
$coin = Coin::where("symbol", $symbol[1])->first();
$currency = Coin::where("symbol", $symbol[0])->first();
$resolution = $request->get("resolution");
$from = $request->get("from");
$to = $request->get("to");
$uniqueKey = sprintf("OHLCKEY%s%s%s%s",
$symbol[0], $symbol[1],
Carbon::createFromTimestamp($from)->second(0)->timestamp,
Carbon::createFromTimestamp($to)->second(0)->timestamp);
$redis=Redis::connection();
$cache = $redis->get($uniqueKey);
if($cache) {
$data = json_decode($cache);
return response()->json($data);
} else {
$t = [];
$o = [];
$h = [];
$l = [];
$c = [];
$v = [];
$s = "no_data";
$minMaxDates = TransactionDetail::where("type", "buy")
->whereBetween("created_at", [
Carbon::createFromTimestamp($from),
Carbon::createFromTimestamp($to)
])->where("coin_id", $coin->id)->where("currency_id", $currency->id)
->selectRaw("min(created_at) as minDate, max(created_at) as maxDate")->first();
if($minMaxDates->minDate) {
$minDate = Carbon::createFromTimeString($minMaxDates->minDate)->timestamp;
if($from < $minDate) {
$startDate = $minDate;
} else {
$startDate = (int)$from;
}
$maxDate = Carbon::createFromTimeString($minMaxDates->maxDate)->timestamp;
if($to > $maxDate) {
$to = $maxDate;
}
while ($startDate < $to):
switch ($resolution) {
case "30";
$endDate = Carbon::createFromTimestamp($startDate)->addMinutes(30)->timestamp;
break;
case "60";
$endDate = Carbon::createFromTimestamp($startDate)->addHour(1)->timestamp;
break;
case "180";
$endDate = Carbon::createFromTimestamp($startDate)->addHour(3)->timestamp;
break;
case "360";
$endDate = Carbon::createFromTimestamp($startDate)->addHour(6)->timestamp;
break;
case "720";
$endDate = Carbon::createFromTimestamp($startDate)->addHour(12)->timestamp;
break;
default:
$endDate = Carbon::createFromTimestamp($startDate)->addHour(1)->timestamp;
break;
}
if ($endDate > $to) $endDate = $to;
$transactions = TransactionDetail::where("type", "buy")
->whereBetween("created_at", [
Carbon::createFromTimestamp($startDate),
Carbon::createFromTimestamp($endDate)
])->where("coin_id", $coin->id)->where("currency_id", $currency->id)->get();
if (!$transactions->isEmpty()) {
$t[] = $transactions->first()->created_at->timestamp;
$o[] = floatval($transactions->first()->price);
$h[] = floatval($transactions->max("price"));
$l[] = floatval($transactions->min("price"));
$c[] = floatval($transactions->last()->price);
$v[] = floatval($transactions->sum("amount"));
}
$startDate = $endDate + 1;
endwhile;
}
if (!empty($t)) $s = "ok";
$data = ["t" => $t, "o" => $o, "h" => $h, "l" => $l, "c" => $c, "v" => $v, "s" => $s];
$redis->set($uniqueKey, json_encode($data));
return response()->json($data);
}
});
Can we reproduce this code with one mysql query?
thank you in advance.

get table rate shipping data in Woocommerce REST API

I am trying to get all active shipping methods in Woocommerce REST API. How can I achieve this. I am new to woocommerce REST API, Any help is much appreciated.
I want response something like this -
{
"shipping_methods": {
"method_id": "method_title"
}
}
I , finally, come up with the solution. It may help others.
Below is complete code to get all table rate shipping data including shipping zones, shipping methods by zone and rates by zone -
header('Content-type: application/json');
$json_file=file_get_contents('php://input');
$jsonvalue= json_decode($json_file,true);
global $wpdb;
global $woocommerce;
$active_methods = array();
$shipping_methods = $woocommerce->shipping->load_shipping_methods();
//echo "<pre>";print_r($shipping_methods);
foreach ( $shipping_methods as $id => $shipping_method ) {
if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) {
$data_arr = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
if($id=='table_rate'){
$raw_zones = $wpdb->get_results("SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;");
//echo "<pre>";print_r($raw_zones);
$shipping = array();
$shippingarr = array();
foreach ($raw_zones as $raw_zone) {
$zones = new WC_Shipping_Zone($raw_zone->zone_id);
$zone_id = $zones->zone_id;
$zone_name = $zones->zone_name;
$zone_enabled = $zones->zone_enabled;
$zone_type = $zones->zone_type;
$zone_order = $zones->zone_order;
$shipping['zone_id'] = $zone_id;
$shipping['zone_name'] = $zone_name;
$shipping['zone_enabled'] = $zone_enabled;
$shipping['zone_type'] = $zone_type;
$shipping['zone_order'] = $zone_order;
$shipping_methods = $zones->shipping_methods;
foreach($shipping_methods as $shipping_method){
$methodid = $shipping_method["number"];
$raw_rates[$methodid]['rates'] = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}woocommerce_shipping_table_rates WHERE shipping_method_id={$methodid};",ARRAY_A);
}
$shipping['shipping_methods'] = $raw_rates;
$raw_country = $wpdb->get_results("SELECT location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id={$zone_id};",ARRAY_N);
$shipping['countries'] = $raw_country;
$shippingarr[] = $shipping;
}
$data_arr['shipping_zones'] = $shippingarr;
}
$active_methods[ $id ] = $data_arr;
}
}
if(!empty($shippingarr)){
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']=$active_methods;
}else{
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']= array();
}
echo json_encode($result); `

get values between two dates in silverstripe

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

SQL showing in place of web page

I've copied a codeigniter website from my old computer to my new one, and copied the database. When I navigate to the site in my localhost however, I just get SQL printed out
db->where($cell_name, $id); $this->db->delete($table_name); if (!is_array($tags)) { $tmp = array(); $tmp[] = $tags; $tags = $tmp; } if (!empty($tags)) { foreach($tags as $tag) { switch(gettype($tag)) { case 'integer': $this->db->set($cell_name, $id); $this->db->set('tag_id', $tag); $this->db->insert($table_name); break; case 'string': $tag = strtolower($tag); $results = $this->db->query('SELECT id FROM tag WHERE tag = \''.$tag.'\' LIMIT 1'); if ($results->num_rows() == 1) { $tag_id = $results->first_row()->id; } else { $this->db->set('tag', $tag); $this->db->set('permalink', url_title($tag, 'dash')); $this->db->insert('tag'); $tag_id = $this->db->insert_id(); } $this->db->set($cell_name, $id); $this->db->set('tag_id', $tag_id); $this->db->insert($table_name); break; } } } } function get_active($type, $id, $return_ids = true) { $ret = array(); switch($type) { case 'media': $table_name = 'media_tag'; $cell_name = 'media_id'; break; case 'post': $table_name = 'post_tag'; $cell_name = 'post_id'; break; } if (!$id) { $results = $this->db->query('SELECT tag.id, tag.tag, tag.permalink FROM '.$table_name.', tag WHERE tag_id = tag.id GROUP BY tag.id ORDER BY tag.tag'); if ($results->num_rows() > 0) { foreach($results->result() as $data) { if ($return_ids) $ret[] = $data->id; else $ret[] = (object) array('id' => $data->id, 'tag' => $data->tag, 'permalink' => $data->permalink); } } } else { $results = $this->db->query('SELECT tag.id, tag.tag, tag.permalink FROM '.$table_name.', tag WHERE '.$cell_name.' = '.$id.' AND tag_id = tag.id ORDER BY tag.tag'); if ($results->num_rows() > 0) { foreach($results->result() as $data) { if ($return_ids) $ret[] = $data->id; else $ret[] = (object) array('id' => $data->id, 'tag' => $data->tag, 'permalink' => $data->permalink); } } } return $ret; } }
Does anyone know if there's a simple reason for this - some setting I need to turn on in wamp for example, I'm completely at a loss, the files and database are identical on my old and new computers
It turns out I had simply not allowed "short open tags" from the WAMP PHP settings