yii2 Query data provider with multiple not and or - yii2

Hello everyone :slight_smile:
i try to show 2 gridviews of datas.
a first gridview where any of three fields is empty (so if one or two of thoses fields are empty, it should show the entry)
and a second gridview with the records that have those 3 fields filled up.
i do something wrong, because if the date field is entered, then the record goes from the first to the second gridview, event if the 2 other fields remain empty…
this is my code :
(dataprovider is the second gridview and unprocessed is the first)
if(Yii::$app->user->can('admin')){
$searchModel = new DeliverySearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->query->orderBy(['delivery_expedition_date'=>SORT_DESC]);
}
elseif(Yii::$app->user->can('maker')){
$maker = Maker::find()->where(['user_id'=>Yii::$app->user->identity->id])->one();
$searchModel = new DeliverySearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->query->andWhere(['maker_id'=>$maker->id]);
//$dataProvider->query->where(['and',['not',['delivery_trackcode' => null,'delivery_carrier' => null,'delivery_expedition_date' => null]]]);
$dataProvider->query->andWhere(['not', ['delivery_trackcode' => null]]);
$dataProvider->query->andWhere(['not', ['delivery_carrier' => null]]);
$dataProvider->query->andWhere(['not', ['delivery_expedition_date' => null]]);
$dataProvider->query->orderBy(['delivery_expedition_date'=>SORT_DESC]);
$unProcessed = $searchModel->search(Yii::$app->request->queryParams);
$unProcessed->query->andWhere(['maker_id'=>$maker->id]);
$unProcessed->query->andWhere(['or',['delivery_trackcode'=> NULL],['delivery_carrier'=> NULL],['delivery_expedition_date'=> NULL]]);
$unProcessed->query->orderBy(['created_at'=>SORT_DESC]);
}
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'unProcessed' => $unProcessed,
]);
Any help would be very much appreciated :slight_smile:
kind regards

So, i finally found the solution. the expedition date need to be check if NULL or not, but the carrier and trackcode need to be checked for empty ('') and not for NULL
->query->andWhere(['not', ['delivery_trackcode' => null]]);
->query->andWhere(['not', ['delivery_carrier' => null]]);

Related

Laravel validation: unique rule to bring duplicated record back

I have not found anywhere a clean way of what I am exactly looking for so thought to give on here a try:
$validator = Validator::make($request->all(), [
'an_id' => 'unique:users,an_id',
'another_id' => 'unique:users,another_id',
'test_id' => 'unique:users,test_id',
]);
if ($validator->fails()) {
//
}
So, what I'd like to do is when a duplicate test_id is provided, is to not only fail but show me which user uses the same test_id.
Is this actually possible through Laravel's Validation?
If I understand correctly, is this what you want to achieve?
Update: maybe you want to get the duplicated user in the view.
Update2: a quick way to get and return the duplicated users, if any.
(Note: I haven't tested the code so maybe slight adjustments are needed)
$validator = Validator::make($request->all(), [
'an_id' => 'unique:users,an_id',
'another_id' => 'unique:users,another_id',
'test_id' => 'unique:users,test_id',
]);
if ($validator->fails()) {
//find the duplicated user
$duplicatedUserX = User::where(
'another_id', $request->input('another_id')
)->get();
$duplicatedUserY = User::where(
'test_id', $request->input('test_id')
)->get();
// add their test_id to error messagebag.
if(!empty($duplicatedUserX){
$validator->errors()
->add('duplicatedUserXId', $duplicatedUserX->id);
}
if(!empty($duplicatedUserY){
$validator->errors()
->add('duplicatedUserYId', $duplicatedUserY->id);
}
// Send duplicated users and messagebag back to View
return redirect()->back()
->with('dupUsers', [
'x' => $duplicatedUserX,
'y' => $duplicatedUserY,
])->withErrors($validator);
}

YIi2 - comparing two field in searchModel

I have a table called TPurchasing which contain data about a store's purchasing record.
TPurchasing
id | serial
transaction_time | timestamp without time zone
supplier | character varying(200)
total | double precision
paid | double precision
By using gii feature in yii2, I manage to generate a model called TPurchasingSearch from "CRUD Generator" menu. In the TPurchasingSearch, there is a function called search() which is used by the GridView in the view file.
public function search($params)
{
$query = TPurchasing::find();
$dataProvider = new ActiveDataProvider([
'pagination' => ['pageSize' => 20],
'query' => $query,
'sort' => ['defaultOrder' => ['transaction_time' => SORT_DESC]]
]);
$this->load($params);
if (!$this->validate()) {
$query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere(['is_removed' => 0]);
$query->andFilterWhere(['like', 'supplier_name', $this->supplier_name])
->andFilterWhere(['like', 'payment_type', $this->payment_type])
->andFilterWhere(['>', 'total', 'paid']);
return $dataProvider;
}
Right now I'm trying to display records that is still not totally paid off, which means the "paid" column is smaller than "total" column. How can I do this comparison in the search function? The above code gave me an error:
invalid input syntax for type double precision: "paid"
on this part
->andFilterWhere(['>', 'total', 'paid']);
since it tried to compare total column with string "paid". I might missed it, but I can't seem to find the related answer in Yii2 documentation.
No need to use andFilterWhere() here, you could simply try :
$query->andWhere('total > paid');

Update query in yii2

I have a form where a user can enter different prices for products. The user can update prices too. The form looks like this:
I have two arrays, wherein one the Id is stored and in the other Prices.
So far, I have been able to reach this...
if(isset($_POST['addprice']))
{
$id = $_REQUEST['id'];
$price = $_REQUEST['price'];
foreach ($price as $key => $val) {
$priceds=$price[$key];
$idds=$id[$key];
if(!empty($priceds)){
$command = $connection->createCommand('UPDATE businessitemots SET price='.$priceds.' WHERE id='.$idds.'');
$command->execute();
}
}
$this->redirect('index',[
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]);
}
My problem is that the values are not getting updated in the DB. Can you point me in the right direction?

Yii 2 Gridview - Search Query generates ambiguous fields

I am generating related records search query for Gridview use
I get this error :
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'dbowner' in where clause is ambiguous
The SQL being executed was: SELECT COUNT(*) FROM tbl_iolcalculation LEFT JOIN tbl_iolcalculation patient ON tbl_iolcalculation.patient_id = patient.id WHERE (dbowner=1) AND (dbowner=1)
I have two related models 1) iolcalculation and patient - each iolcalculation has one patient (iolcalculation.patient_id -> patient.id)
The relevant code in my model IolCalculationSearch is :
public function search($params)
{
$query = IolCalculation::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['patient.lastname'] = [
'asc' => ['patient.lastname' => SORT_ASC],
'desc' => ['patient.lastname' => SORT_DESC],
];
$query->joinWith(['patient'=> function($query) { $query->from(['patient'=>'tbl_iolcalculation']); } ]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'patient_id' => $this->patient_id,
'preop_id' => $this->preop_id,
'calculation_date' => $this->calculation_date,
'iol_calculated' => $this->iol_calculated,
The reason this error is generated is that each model has an override to the default Where clause as follows, the reason being that multiple users data needs to be segregated from other users, by the field dbowner:
public static function defaultWhere($query) {
parent::init();
$session = new Session();
$session->open();
$query->andWhere(['t.dbowner' => $session['dbowner']]);
}
this is defined in a base model extending ActiveRecord, and then all working models extend this base model
How Can I resolve this ambiguous reference in the MySQL code?
Thanks in advance
$query->andFilterWhere([
// previous filters
self::tableName() . '.structure_id' => $this->structure_id,
// next filters
]);
I think, that you are searching for table aliases.
(https://github.com/yiisoft/yii2/issues/2377)
Like this, of course you have to change the rest of your code:
$query->joinWith(['patient'=> function($query) { $query->from(['patient p2'=>'tbl_iolcalculation']); } ]);
The only way I can get this to work is to override the default scope find I had set up for most models, so that it includes the actual table name as follows - in my model definition:
public static function find() {
$session = new Session();
$session->open();
return parent::find()->where(['tbl_iolcalculation.dbowner'=> $session['dbowner']]);
}
There may be a more elegant way using aliases, so any advice would be appreciated - would be nice to add aliases to where clauses, and I saw that they are working on this....

Retrieve value from new column

I am trying to learn opencart structure, and trying to create a new column under the table product. The new column is "test"
Then I try to retrieve the data under this page index.php?route=checkout/cart (replace price with test column)
catalog\controller\checkout\cart.php
...
$this->data['products'][] = array(
'key' => $product['key'],
'thumb' => $image,
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'quantity' => $product['quantity'],
'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
'price' => $product['test'], //<-- new column
'total' => $total,
'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']),
'remove' => $this->url->link('checkout/cart', 'remove=' . $product['key'])
);
The problem is I'm not getting any output, and I'm not sure how to work with the model. Which query/function is related with this page ?
The problem is that the $products that are available at cart.php controller are retrieved from the session where they have been stored in previously set structure, so there is no test index and You should get a Notice: undefined index 'test' in .... The $products are retrieved by
foreach ($this->cart->getProducts() as $product) {
//...
}
See /system/library/cart.php and method getProducts() to understand what I am speaking about.
If You would like to use this at catalog/controller/product/category.php or catalog/controller/product/product.php controllers, the code You are trying will work.
If You replace the price within all product lists and product detail, these controllers:
product/
category.php
manufacturer_info.php
product.php
search.php
special.php
module/
bestseller.php
featured.php
latest.php
special.php
with Your value, the final price within cart would be Your test value.