Missing required parameter in yii2 Search - yii2

i want to search the stock till a particular date. User will fill this date form. The first page where user go to input the date field is _formtilldate.
Controller action -
public function actionIndex3() {
//$enddate = '2018-03-01';
$searchModel1 = new SellitemSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( '_formtilldate' , [
'model1' => $searchModel1 ,
//'enddate' => $enddate,
//'model2' => $searchModel2,
//'searchModel1' => $searchModel2,
] );
}
And the form field
<?php
$form = ActiveForm::begin ( [
'id' => 'form-id' ,
'action' => [ '/stock/sellitem/stocktilldate' , 'enddate' => $model1->enddate ] ,
'method' => 'get' ,
'enableClientScript' => false ,
] );
?>
<?=
$form->field ( $model1 , 'enddate' )->widget (
DatePicker::className () , [
// inline too, not bad
'options' => [ 'placeholder' => 'End Date ...' , 'id' => 'enddate1' ] ,
'inline' => false ,
//'id' => 'startdate1',
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true ,
'todayHighlight' => true ,
'format' => 'yyyy-mm-dd'
]
] );
?>
On clicking on the submit button, the search query runs -
Controller Action -
public function actionStocktilldate( $enddate ) {
//$enddate = '2018-03-01';
$searchModel1 = new SellitemtilldateSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( 'indexstocktilldate' , [
//'enddate' => $enddate,
'searchModel1' => $searchModel1 ,
'dataProvider1' => $dataProvider1 ,
//'searchModel2' => $searchModel2,
//'dataProvider2' => $dataProvider2,
] );
}
Search Model -
public function search( $params , $enddate ) {
//$query = Sellitem::find();
$subQuery1 = (new Query() )->select ( [ 'pi_upc' , 'sum(pi_qty) as purchased' ] )->from ( 'puritem' )->leftJoin ( 'pursum' , 'pursum.ps_id = puritem.psi_id' )->andwhere ( [ '<' , 'pursum.ps_date' , $enddate ] )->groupby ( 'pi_upc' );
$subQuery2 = (new Query() )->select ( [ 'si_iupc' , 'sum(si_qty) as sold' ] )->from ( 'sellitem' )->leftJoin ( 'sellsum' , 'sellsum.ss_id = sellitem.si_ssid' )->andwhere ( [ '<' , 'sellsum.ss_date' , $enddate ] )->groupby ( 'si_iupc' );
$subQuery3 = (new Query() )->select ( [ 'i_upc' , 'i_category' , 'i_brand' , 'i_desc' , 'i_unit' , 'i_buyprice' , 'coalesce(p.purchased,0) as purchased' ] )->from ( 'item' )->leftJoin ( [ 'p' => $subQuery1 ] , 'p.pi_upc = i_upc' );
$query = (new Query() )->select ( [ 'tp.i_upc as upc' , 'tp.i_category as category' , 'tp.i_brand as brand' , 'tp.i_desc as description' , 'tp.i_unit as unit' , 'tp.purchased as purchased' , 'coalesce(ts.sold,0) as sold' , '(coalesce(purchased,0) - coalesce(sold,0)) as stock' , 'tp.i_buyprice as rate' , 'round(((coalesce(purchased,0) - coalesce(sold,0))*tp.i_buyprice),2) as value' ] )->from ( [ 'tp' => $subQuery3 ] )->leftJoin ( [ 'ts' => $subQuery2 ] , 'ts.si_iupc = tp.i_upc' );
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query ,
'pagination' => [
'pageSize' => 10000000000 ,
] ,
]);
......
}
Now, in the url I can see the parameter got passed -
http://localhost/chayanika/frontend/web/index.php?r=stock%2Fsellitem%2Fstocktilldate&SellitemSearch%5Benddate%5D=2018-08-13
But, I'm getting error -
Bad Request (#400)
Missing required parameter: enddate
I'm not getting where I'm missing it.
I made a bit progress here -
I just learned that the date I'm getting in the URL is coming from the Action in the form. But it's not of much use so far.
If I change the controller action a bit, I get a result -
public function actionStocktilldate() {
$enddate = date ( 'Y-m-d' );
//$enddate = yii::$app->request->get('enddate');
//var_dump($enddate);
$searchModel1 = new SellitemtilldateSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams , $enddate );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( 'indexstocktilldate' , [
//'enddate' => $enddate,
'searchModel1' => $searchModel1 ,
'dataProvider1' => $dataProvider1 ,
//'searchModel2' => $searchModel2,
//'dataProvider2' => $dataProvider2,
] );
}
Please tell me how can I pass the date collected by the form to this controller.

In your url, I don't see enddate param, I just see:
frontend/web/index.php?r=stock/sellitem/stocktilldate&SellitemSearch[enddate]=2018-08-13"
It is SellitemSearch[enddate], not enddate
You should modify your url to
frontend/web/index.php?r=stock/sellitem/stocktilldate&enddate=2018-08-13"
or remove $enddate param from actionStocktilldate function.

How is action parameter treated in ActiveForm.
Query parameters in the action are ignored for GET method. We use
hidden fields to add them back Hidden inputs are created and they are
submitted so your form action goes to the right place.
So if you look into the form source from your browser there is a hidden input created with the name enddate which will be submitted automatically.
<form id="w0" action="http://localhost/chayanika/frontend/web/index.php?r=/stock/sellitem/stocktilldate" method="get">
<input type="hidden" name="enddate" value="2018-03-01"><button type="submit">Submit</button>
</form>
Reason
But in your case, it isn't submitting because there isn't any hidden field being created. Why? because the assignment of your $model->enddate is returning null. Make sure there is a valid timestamp or date string saved.
Track
Go to line 395 of \yii\web\UrlManager function createUrl($params).
If you are using enablePrettyUrl=>true then it will enter the first check and in the foreach it appends the query string params as key where value!==null.
if($this->enablePrettyUrl){
$cacheKey = $route . '?';
foreach($params as $key => $value){
if($value !== null){
$cacheKey .= $key . '&';
}
}
if you are using enablePrettyUrl=>false then it will skip to the last section
$url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
if(!empty($params) && ($query = http_build_query($params)) !== ''){
$url .= '&' . $query;
}
return $url . $anchor;
and there it will fail the check if(!empty($params) && ($query = http_build_query($params)) !== ''){ as http_build_query($params) returns empty string for an array having a key with null value.
So make sure you have a date save and the current model does not have the date saved in database as null

Related

Is it possible to add data to the related table after batch insert in Lumen/Laravel?

I am stuck with this problem. I have two tables users and user_credentials which are related to each other by Id column of the users table. Since I'm importing data from csv file, I'm using the insert() method to insert data in the users table instead of create() inside loop (which is a little bit faster I guess).
Is there any way to get the user id of the user for user_credentials table so that I'll be able to use insert() in this table as well
// begin DB transaction
DB::beginTransaction();
// loop through the data
foreach ($data as $key => $value) {
// eliminate the first row
if ($key == 0)
continue;
// check for phone number validation
if (!isset($value[2]) || $value[2] != null || $value[2] != '')
$phoneNumberValidation = null;
// phone number validation
$phoneNumberValidation = $this->validateNumber($value[2]);
if ($phoneNumberValidation != false) {
$user = $this->user::Where('personal_number', $phoneNumberValidation)
->first();
if ($user)
continue;
}
// create the user
$users[] = [
'first_name' => $value[0],
'last_name' => $value[1],
'username' => 'oisf' . $userId++,
'email' => $value[9],
'password' => Hash::make($value[3]),
'address' => $value[4],
'personal_number' => $phoneNumberValidation,
'post_address' => $value[5],
'grad' => $value[6],
'forb' => $value[7],
'offk' => (empty(trim($value[8]))) ? 0 : $value[8],
'approval_date' => ($value[10] != '') ? Carbon::parse($value[10])->startOfDay()->format('Y-m-d H:i:s') : Carbon::now()->format('Y-m-d H:i:s'),
'samtycke' => false,
'status' => 'approved',
'role_id' => ($role) ? $role->id : $newRole->id,
'member' => ($value[10] != '') ? $value[10] : Carbon::now()->format('Y-m-d'),
'note' => $value[11],
'payment_status' => isset($value[12]) && !empty($value[12]) ? $value[12] : 'unpaid',
'username_id' => $userId
];
// I need to change this
UserCredential::create([
'user_id' => 'i want user id here',
'some_column_name' => $value['some_key']
]);
// to this
$userCredentials[] = [
'user_id' => 'i want user id here',
'some_column_name' => $value['some_key']
];
}
$this->user::insert($users);
// and then after above insert, I would like to use
UserCredential::insert($userCredentials);
// commit the transaction
DB::commit();
Try use DB::getPdo()->lastInsertId();, it will get the last inserted id, so if you use that before inserting into UserCredential, you should get the last id.

How to get sum value of usermeta key using another meta key

I have two meta key: us_points & agent_id
I need to sum up all the us_points value with agent ID same for each users.
Here is what I tried:
$cuser = wp_get_current_user(); $a_id = $cuser->agent_id;
global $wpdb;
$result = $wpdb->get_col("SELECT sum(meta_value) FROM $wpdb->usermeta WHERE meta_key = 'us_points' AND agent_id = $a_id" );
echo $result[0];
If I remove AND agent_id = $a_id, it shows the sum of all users in the website, but I need to show the sum of only the meta key value common/matching in agent_id
Help will me much appreciated.
Try this, It should target agent_id meta key then group records by the same agent_id value before summing.
$result = $wpdb->get_col("SELECT sum(meta_value) FROM $wpdb->usermeta WHERE meta_key = 'us_points' GROUP BY meta_value HAVING 'meta_key' = 'agent_id'" );
$users = get_users();
$agent_points = array();
foreach( $users as $user ) {
$agent_points[] = array(
'agent_id' => $user->agent_id,
'us_points' => $user->us_points,
);
}
$agent_points expected to be in the structure:
Array
(
[0] => Array
(
[agent_id] => 1
[us_points] => 30
)
[1] => Array
(
[agent_id] => 4
[us_points] => 10
)
[2] => Array
(
[agent_id] => 4
[us_points] => 30
)
[3] => Array
(
[agent_id] => 1
[us_points] => 20
)
)
Then,
$results= array();
foreach( $agent_points as $values ) {
foreach( $values as $key => $value ) {
if( 'agent_id' === $key ) {
$results[ $value ] += $values['us_points'];
}
}
}
Expected $results in agent_id => us_points pair:
Array
(
[1] => 50
[4] => 40
)

ON DUPLICATE KEY UPDATE Query in Laravel4

How do I transform this
DB::table('partners')->insert(array($data));
laravel Query to have ON DUPLICATE KEY UPDATE
the structure look like
$data['program_name'] = $program['program']['_'];
$data['program_id'] = $program_id;
$data['status'] = $program['status'];
$data['shop_name'] = $shop->name;
$data['shop_logo'] = $shop->image;
$data['shop_description'] = $shop->description;
where program_id is unique
Use something like this (feel free to correct because it's untested):
DB::statement( 'INSERT INTO partners VALUES (' . implode( ',',
array_map( function( $val ) { return ":$val"; } , array_keys($data) )
) . ') ON DUPLICATE KEY UPDATE ' . implode( ',',
array_map( function( $val ) { return "$val = VALUES($val)"; } , array_keys($data) )
), $data);
I created a package that will wrapped INSERT ON DUPLICATE KEY UPDATE
https://packagist.org/packages/yadakhov/insert-on-duplicate-key
$users = [
['id' => 1, 'email' => 'user1#email.com', 'name' => 'User One'],
['id' => 2, 'email' => 'user2#email.com', 'name' => 'User Two'],
['id' => 3, 'email' => 'user3#email.com', 'name' => 'User Three'],
];
User::insertOnDuplicateKey($users);
// produces:
INSERT INTO `test_user_table`(`id`,`email`,`name`) VALUES
(1,'user1#email.com','User One'), (2,'user3#email.com','User Two'), (3,'user3email.com','User Three')
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `email` = VALUES(`email`), `name` = VALUES(`name`)

Joomla: two mysql queries model functions with one view

I am trying to run two model functions from one view. The first query appears to be working fine.
The second query returns a blank array. I noticed when printing the query to the screen that the queries appear to be joining together and are not separate, like this:
JDatabaseQueryMySQL Object ( [db:protected] => JDatabaseMySQL Object ( [name] => mysql [nameQuote:protected] => ` [nullDate:protected] => 0000-00-00 00:00:00 [dbMinimum:protected] => 5.0.4 [_database:JDatabase:private] => Curling_Schedule [connection:protected] => Resource id #19 [count:protected] => 0 [cursor:protected] => Resource id #72 [debug:protected] => [limit:protected] => 0 [log:protected] => Array ( ) [offset:protected] => 0 [sql:protected] => SELECT team_name, division FROM #_autoschedTeams ORDER BY division [tablePrefix:protected] => encex [utf:protected] => 1 [errorNum:protected] => 0 [errorMsg:protected] => [hasQuoted:protected] => [quoted:protected] => Array ( ) ) [type:protected] => select [element:protected] => [select:protected] => JDatabaseQueryElement Object ( [name:protected] => SELECT [elements:protected] => Array ( [0] => sheet, id ) [glue:protected] => , ) [delete:protected] => [update:protected] => [insert:protected] => [from:protected] => JDatabaseQueryElement Object ( [name:protected] => FROM [elements:protected] => Array ( [0] => #__autoschedPlayingSheets ) [glue:protected] => , ) [join:protected] => [set:protected] => [where:protected] => [group:protected] => [having:protected] => [columns:protected] => [values:protected] => [order:protected] => JDatabaseQueryElement Object ( [name:protected] => ORDER BY [elements:protected] => Array ( [0] => sheet ) [glue:protected] => , ) [union:protected] => [autoIncrementField:protected] => )
Model:
public function getTeams()
{
// Create a new query object.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Select some fields
$query->select('team_name, division');
// From the hello table
$query->from('#__autoschedTeams');
$query->order('division');
$db->setQuery((string)$query);
$teams = $db->loadResultArray();
$div = $db->loadResultArray(1);
$divs = array_unique($div);
$result = [];
foreach($divs as $key)
{
$result[$key] = [];
foreach(array_keys($div, $key) as $index)
{
array_push($result[$key], $teams[$index]);
}
}
return $result;
}
public function getSheets()
{
// Create a new query object.
$db = JFactory::getDBO();
print_r($query);
$query = $db->getQuery(true);
// Select some fields
$query->select('sheet, id');
// From the hello table
$query->from('#__autoschedPlayingSheets');
$query->order('sheet');
//print_r($query);
$db->setQuery($query);
$result = $db->loadResultArray();
return $result;
}
}
relevant code from View:
$teams_sched = $this->get('Teams');
$sheets_sched = $this->get('Sheets');
Change the name of the variable and check with it.
If you are not getting the result again, then print the query echo $query; and check with it.
public function getSheets()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('sheet, id');
$query->from('#__autoschedPlayingSheets');
$query->order('sheet');
$db->setQuery($query);
$Sheets = $db->loadResultArray();
print_r($Sheets);
return $Sheets;
}

CakePHP drop down- list usernames and company names

Hey have got a page which allows businesses to send invoices to customers (both individuals and other businesses). The Receiver input field allows the user to select which customer to send the invoice to. At the moment the drop down lists businesses, but we want that list to include individuals (User model/table) too. So if the account (Account model/table) doesn't have a company_name then display the user's username.
Below is what I have tried to try and get it working, doesn't give errors, but doesn't show anything on the drop down list. How could I achieve what we want?
Invoice Controller:
$name = "";
if ('Account.company_name' != null) {
$name = 'Account.company_name';
} else {
$name = 'User.username';
}
$accounts2 = $this->User->find('list', array(
'fields' => array('account_id'), 'conditions' => array(
'id' => $this->Auth->user('id'))));
$accounts = $this->User->Relationship->find('list', array(
'fields' => array('receiver_id'),
'conditions' => array('sender_id' => $accounts2)));
$receivername = $this->Account->find('list', array(
'fields' => array($name),
'conditions' => array(
'id' => $accounts)));
View:
echo $this->Form->input('receiver_id', array(
'label' => 'Receiver: ',
'type' => 'select',
'options' => $receivername));
'Account.company_name' != null
is obviously always true, as a string is not null. So
if ('Account.company_name' != null) {
$name = 'Account.company_name';
} else {
$name = 'User.username';
}
always do $name = 'Account.company_name';
you can define a temporary virtual field 'display_name' and code like below
$this->Account->virtualFields['display_name'] = "IF(Account.company_name='' OR Account.company_name IS NULL, (SELECT u.name FROM users u WHERE u.account_id = Account.id),Account.company_name)";
$list = $this->Account->find('list',array(
'fields' => array('Account.id','Account.display_name')
));