Creating default object from empty value Yii2 - php

Using yii2 trying make success callback for payments. Callback work, but i need make changes for order. In my common/congig/main.php:
'successCallback' => function($invoice) {
$order = \common\models\Checkout::findOne($invoice->order_id);
$order->payment_status = 1;
$order->update();
}
$invoice->order_id; receives current order id, i need change payment status for checkout model.
Update:
can I somehow run it recursively? for example, if I have several records with one ID?

The problem in your code is that findOne() requires the name of the column to compare the value, in this case, the Checkout's ID column.
Assuming it's order_id like in invoice table.
The code will be like this:
'successCallback' => function($invoice) {
$order = \common\models\Checkout::findOne(['order_id' => $invoice->order_id]);
$order->payment_status = 1;
$order->update();
}
Replace 'order_id' with the checkout's id column if it has a different name.
Update
To update multiple records you could do something like this:
'successCallback' => function($invoice) {
\common\models\Checkout::updateAll(['payment_status'=>1],['order_id' => $invoice->order_id]);
}
Make a DB backup before testing this code.

Related

Laravel update specific column in database 'cost' and add supplier_id to another database table

i'm working with sensitive data hope you can help find if there any wrong in code's writing
i have list of suppliers in my database i added column 'cost'
i'm trying to update and insert cost for existing suppliers from specific query
and i created model and migration to get foreign keys too by adding the puled supplier id from the query
....
$suppliers_data = $suppliers_query->fetchall(PDO::FETCH_ASSOC);
foreach ($suppliers_data as $supplier_data) {
$supplier_name = $supplier_data['supplier_name'];
$cost_rate = $supplier_data['Cost'];
if (!Supplier::where('supplier', $supplier_name)->exists()) {
Supplier::insert([
'supplier' => $supplier_name,
'cost_rate' => $cost_rate
]);
} else {
Supplier::update([
'cost_rate' => $cost_rate // does this will update cost for the current supplier ?
]);
}
$supplier_id = Supplier::where('supplier', $supplier_name)->pluck('supplier_id');
Test::insert($supplier_id);
}
$supplier_count = test::count();
Test::update(['test_data_count' => $supplier_count]);
Updating table data with supplier name is not correct here I believe. Instead of using supplier name in where condition using particular supplier id is recommended for better application. Names can be duplicate so its not a good idea to use supplier name in where.
In your current code I have 2 things to say :
You need to add where in update eloquent to work properly
Supplier::where('supplier', $supplier_name)
->update([
'cost_rate' => $cost_rate // this will update cost for the current supplier
]);
Or to minimalize the code you can use updateorCreate method instead of making insert and update in the if() else() condition
Supplier::updateOrCreate(
['supplier' => $supplier_name],
['cost_rate' => $cost_rate]
);

CodeIgniter, update stock

i need some help...
I have a problem with codeigniter, i have this code by myself
public function venderProduto($id)
{
$data=array('id_venda' => null,
'id_cliente' => $id_cliente,
'medicamento' => $medicamento,
'quantidade' => $quantidade,
'preco' => $preco);
$this->db->where('id_venda', $id);
$this->db->select('produto.stock,vendas.quantidade');
$this->db->insert('vendas', $data);
$this->db->update('stock-quantidade');
}
I need to upgrade the stock of my product that is on the table products(produtos) when I insert a sale on my table sales(vendas), want to take the amount that will see the stock...
Someone help me pls...
It looks like your mixing up your queries. One needs to be completed and then the second can be performed.
If I understand you correctly you want to insert a record into the sales table and then update the products table.
Function does not show how values for id_cliente, medicamento, quantidade, and preco are getting into function. They would either need to be set as function parameters or supplied as GET or POST vars.
public function venderProduto($id, $id_cliente, $medicamento, $quantidade, $preco)
{
$data = array('id_venda' => null,
'id_cliente' => $id_cliente,
'medicamento' => $medicamento,
'quantidade' => $quantidade,
'preco' => $preco);
$this->db->insert('vendas', $data);
//test to make sure that insert was successful
if ($this->db->insert_id())
{
//get existing stock quantity
$this->db->select('stock-quantidade');
$this->db->where('id_venda', $id);
$query = $this->db->get('produtos');
$row = $query->row();
$quantity_in_stock = $row->stock-quantidade;
//I am assuming that $quantidade is the quantity of the order
$new_quantity_in_stock = $quantity_in_stock - $quantidade;
//update products table
$this->db->where('id_venda', $id);
$this->db->update('produtos', array('stock-quantidade' => $new_quantity_in_stock ));
}
}
The above may or may not work exactly as shown but this IS the logic and order you should use. If you have trouble you need to post any error messages you receive.
So the order of this is:
insert sale.
test to make sure insert was successful.
get existing quantity of stock.
Subtract order quantity from stock quantity.
Update stock quantity.

How to KeyBy where multiple items have the same key

I am using Laravel Collections methods and am trying to key my query results (which are a collection) by the id. The problem is I have multiple entries with the same id, but point to different countries and I want to have all of the values, not just the last one.
Here is my code that i am using so far:
$allCountries = new Collection($allCountries);
$offerCountries = $allCountries->keyBy('id');
dd($offerCountries);
foreach ($offer as $o) {
$o->countries = $allCountries->get($o->id);
}
To explain, my query puts the results in $allCountries which contains ids and countries and those results looks something like this
id=>225, country=>US
id=>225, country=>IT
id=>3304, country=>NZ
Just to give you a quick idea. I want to key this by the id which results in $offerCountries. I then loop thru a previous Collection that contains offers which have a certain ID that relates to the country result by id. So for the offer 225, the countries it contains are US and IT. I loop thru each offer and set the countries object equal to all the $allCountries id that it equals. The problem I have here is keyBy overwrites the value and only takes the last one. I am hoping to get some results like this:
[
225 => countries: {'id' => 225, 'country' => 'US'}, {'id' =>
'225', 'country' => 'IT'}
3304 => ['id' => 3304, 'country' => 'NZ'],
]
Is there a laravel method to do this, or do I need to write my own keyBy so it does not overwrite. If so, how can I get started to write this method?
Thanks
Instead of using keyBy, use groupBy:
$countriesById = collect($allCountries)->groupBy('id');
You could use filter and create a custom filter
$filtered = $allCountries->filter(function ($item) use ($id) {
return $item->id == $id;
});
$filtered->all();

Update collection erases all information inside

I am new to MongoDB and trying to perform my first updates.
I have my users collection that is populated by an insert statement. Now, I want to add or insert the field authCode with some data into a specific user.
My problem is that when I perform the following function the whole user data becomes replaced by the information in that update statement. My understanding is that by using upsert I would insert or update a users collection. given that the user already exist I expect just the authCode field to be created or updated.
Could anyone point out what am i doing wrong?
public function addAuthCode( array $userId, $code ) {
$user = $this->db()->user;
$user->update(
$userId,
array( 'authCode' => $code ),
array( 'upsert' => true, 'safe' => true )
);
}
You'll want to take a look at the MongoDB documentation for updates found here: http://docs.mongodb.org/manual/reference/method/db.collection.update/#db.collection.update
Specifically:
Add New Fields
db.bios.update(
{ _id: 3 },
{ $set: {
mbranch: "Navy",
"name.aka": "Amazing Grace"
}
}
)
Notice that in order to add a field, you need to use the $set operator
Chris#MongoLab

$this->Model->id not working before saveAll in CakePHP

I have the following code in CakePHP 2:
$this->Order->id = 5;
$this->Order->saveAll(array(
'Order' => array(
'person_id' => $this->Session->read('Person.id'),
'amount' => $total,
'currency_id' => $code
),
'Lineitem' => $lineitems /* a correctly-formatted array */
));
I would expect this to update the row with the Primary Key of 5 in the Order table and then insert the Lineitem rows with an order_id of 5.
However, all it does is create a new row in Order and then use the new id from the new Order record to create the Listitem rows.
Note: I'm only setting the ID as above for debugging purposes and to easily demonstrate this question. In my final code, I'll be checking to see if there's already a pending order with the current person_id and doing $this->Order->id = $var; if there is and $this->Order->create(); if there isn't.
In other words, sometimes I will want it to INSERT (in which case I will issue $this->Order->create(); ) and sometimes I will want it to UPDATE (in which case I will issue $this->Order->id = $var; ). The test case above should produce an UPDATE but it's producing an INSERT instead.
Any idea what I am doing wrong here?
The array you pass to Model->saveAll() doesnt't contain the order's id, so Cake creates a new one. If you wanto to update an existing record, either you set the order id in the passed array, or you retrieve it with a find. The documentation explicitly remarks
If you want to update a value, rather than create a new one, make sure
your are passing the primary key field into the data array
$order = $this->Order->findById(5);
// ... modify $order if needed
$this->Order->saveAll(array('Order' => $order, 'LineItem' => $items));
In your case, you may want to use something like the following to be as concise as possible. Model::saveAssociated() is smart enough to create or update depending on the id, but you must provide suitable input. Model::read($fields, $id) initializes the internal $data: for an existing record all fields will be read from the database, but for a nonexistent id, you'll need to supply the correct data for it to succeed. Assuming an order belongsTo a customer, I supply the customer id if the order doesn't exist
// set the internal Model::$data['Order']
$this->Order->read(null, 5);
// You may want to supply needed information to create
// a new order if it doesn't exist, like the customer
if (! $this->Order->exists()) {
$this->Order->set(array("Customer" => array("id" => $customer_id)));
}
$this->Order->set(array('LineItem' => $items));
$this->Order->saveAssociated();
As a final note, it seems you are implementing a shopping cart. If that's the case, maybe it'd be clearer to use a separate ShoppingCart instead of an Order with a finalized flag.
Have you tried following:
$this->Order->saveAll(array(
'Order' => array(
'id' => 5,
'person_id' => $this->Session->read('Person.id'),
'amount' => $total,
'currency_id' => $code
),
'Lineitem' => $lineitems /* a correctly-formatted array */
));
Its pretty much the same what you did with :
$this->Order->id = 5;
Maybe that would fix your problem.
Cake is checking if you set id field and if its there it updates record, if not found it creates new record instead.
update:
Then maybe check before you saveAll if there is id field, then save result of check to some boolean and create array to save determined by this boolean for example:
if($id_exist) $order['Order']['id'] = 5;
$order['Order']['id'] = 5;
$order['Order']['person_id'] = $this->Session->read('Person.id'),
$order['Order']['amount'] = $total;
$order['Order']['currency_id'] = $code;
$this->Order->saveAll(array(
'Order' => $order,
'Lineitem' => $lineitems /* a correctly-formatted array */
));

Categories