Take for example the following piece of code from WooCommerce API Documentation. What I am trying to do is add some if conditions within the array. For example, I want the payment_details array to be a part of $data based on some if condition. Is this possible? How?
<?php
$data = [
'order' => [
'payment_details' => [
'method_id' => 'bacs',
'method_title' => 'Direct Bank Transfer',
'paid' => true
],
'billing_address' => [
'first_name' => 'John',
'last_name' => 'Doe',
'address_1' => '969 Market',
'address_2' => '',
'city' => 'San Francisco',
'state' => 'CA',
'postcode' => '94103',
'country' => 'US',
'email' => 'john.doe#example.com',
'phone' => '(555) 555-5555'
],
'shipping_address' => [
'first_name' => 'John',
'last_name' => 'Doe',
'address_1' => '969 Market',
'address_2' => '',
'city' => 'San Francisco',
'state' => 'CA',
'postcode' => '94103',
'country' => 'US'
],
'customer_id' => 2,
'line_items' => [
[
'product_id' => 546,
'quantity' => 2
],
[
'product_id' => 613,
'quantity' => 1,
'variations' => [
'pa_color' => 'Black'
]
]
],
'shipping_lines' => [
[
'method_id' => 'flat_rate',
'method_title' => 'Flat Rate',
'total' => 10
]
]
]
];
print_r($woocommerce->post('orders', $data));
?>
The point is, instead of defining the entire array again, I want to put an if condition here:
'order' => [
if ($payment = 'xyz') {
'payment_details' => [
'method_id' => 'bacs',
'method_title' => 'Direct Bank Transfer',
'paid' => true
],
}
else {
'payment_details' => [
'method_id' => 'monopoly',
'method_title' => 'Monopoly',
'paid' => true
],
}
Is it possible to concatenate the array using dot equals? .=
Thanks.
"payment_details" is already part of $data.
To get to it use:
$paymentDetails = $data['order']['payment_details'];
Then you can display it with:
echo $paymentDetails['method_title'];
If you want to use if conditions:
if ($paymentDetails['method_title'] === 'Monopoly money') {
echo 'That will not work';
}
To change the payment details:
$data['order']['payment_details']['method_title'] = 'Changed';
or
$data['order']['payment_details'] = ['method_title' => 'something', 'method_id' => 5, 'paid' => false];
You can define the payment_details in advance and use it in the $data array.
if ($payment = 'xyz') {
$payment_details = array ( 'method_id' => 'bacs',
'method_title' => 'Direct Bank Transfer',
'paid' => true);
}else{
$payment_details = array ( 'method_id' => 'monopoly',
'method_title' => 'Monopoly',
'paid' => true);
}
$data = array (
'order' => array(
'payment_details' => $payment_details,
......
......
)
);
print_r($woocommerce->post('orders', $data));
Answering my own question. This is what I was looking for.
$orderData = [];
if ($payment == 'Monopoly') {
$orderData['order']['payment_details'] = [];
$orderData['order']['payment_details']['method_id'] = 'Monopoly';
$orderData['order']['payment_details']['method_title'] = 'Monopoly';
$orderData['order']['payment_details']['paid'] = true;
$orderData['order']['status'] = 'completed';
}
else {
$orderData['order']['status'] = 'pending';
}
Related
I'm working on Lumen and my collection has duplicate values, example:
collect([
[
'name' => 'John Doe',
'department' => 'Sales',
'phone' => '99999-99999',
'value' => 25.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 5.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 58.0
],
[
'name' => 'Lucas Rodrigues',
'department' => 'Marketing',
'phone' => '22222-22222',
'value' => 90.0
]
])
I would like to sum the value property when the name is the same but preserve other values like (department and phone) and remove duplicates entity, example:
collect([
[
'name' => 'John Doe',
'department' => 'Sales',
'phone' => '99999-99999',
'value' => 25.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 63.0
],
[
'name' => 'Lucas Rodrigues',
'department' => 'Marketing',
'phone' => '22222-22222',
'value' => 90.0
]
])
What's the best way to do this?
Try the following:
$newCollection = collect([]);
$collectctions = collect([
[
'name' => 'John Doe',
'department' => 'Sales',
'phone' => '99999-99999',
'value' => 25.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 5.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 58.0
],
[
'name' => 'Lucas Rodrigues',
'department' => 'Marketing',
'phone' => '22222-22222',
'value' => 90.0
]
]);
foreach ($collectctions as $item) {
if($newCollection->contains('name', $item['name'])){
$index = $newCollection->where('name', $item['name'])->keys()[0];
$newCollection = $newCollection->map(function ($object, $i) use ($index, $item) {
if($i == $index){
$object['value'] += $item['value'];
}
return $object;
});
}
else{
$newCollection->push($item);
}
}
return $newCollection;
This can be achieved using collection functions (https://laravel.com/docs/8.x/collections). In this example I solved it using (groupBy, map, flatten, slice, count and sum).
$data = collect([
[
'name' => 'John Doe',
'department' => 'Sales',
'phone' => '99999-99999',
'value' => 25.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 5.0
],
[
'name' => 'Mary Lisa',
'department' => 'Finance',
'phone' => '88888-88888',
'value' => 58.0
],
[
'name' => 'Lucas Rodrigues',
'department' => 'Marketing',
'phone' => '22222-22222',
'value' => 90.0
]
]);
$data = $data->groupBy('name')->map(function ($item) {
if ($item->count() > 1) {
$item = $item->slice(0, 1)->map(function($subItem) use ($item) {
$subItem['value'] = $item->sum('value');
return $subItem;
});
}
return $item;
})
->flatten(1);
When calling print_r($data->toArray()); we get the following array as result:
Array
(
[0] => Array
(
[name] => John Doe
[department] => Sales
[phone] => 99999-99999
[value] => 25
)
[1] => Array
(
[name] => Mary Lisa
[department] => Finance
[phone] => 88888-88888
[value] => 63
)
[2] => Array
(
[name] => Lucas Rodrigues
[department] => Marketing
[phone] => 22222-22222
[value] => 90
)
)
My assertJSON test isn't working and says I get the below error
Here's the test code
$user = Sanctum::actingAs(
User::factory()->create(),
['*']
);
$customer = Customer::first();
$response = $this->getJson('api/customers/' . $customer->slug);
$response->assertStatus(200);
$response->assertJson(
[
'data' => [
'uuid' => $customer->uuid,
'customer_name' => $customer->customer_name,
'email' => $customer->email,
'slug' => $customer->slug,
'street_1' => $customer->street_1,
'street_2' => $customer->street_2,
'city' => $customer->city,
'postcode' => $customer->postcode,
'telephone_number' => $customer->telephone_number,
'county' => $customer->county,
'customer_type' => $customer->customerType,
'archived' => $customer->archived ? 'Yes' : 'No',
]
]
);
And here is the customer resource
public function toArray($request)
{
return [
'uuid' => $this->uuid,
'customer_name' => $this->customer_name,
'email' => $this->email,
'slug' => $this->slug,
'street_1' => $this->street_1,
'street_2' => $this->street_2,
'city' => $this->city,
'postcode' => $this->postcode,
'telephone_number' => $this->telephone_number,
'county' => $this->county,
'customer_type' => $this->customerType,
'archived' => $this->archived ? 'Yes' : 'No',
];
}
The 2 JSON arrays are exactly the same and the other tests are working and everything on the front end is working just fine too.
More of the error
What would be the most elegant way to write a PHP function (don't know if there is any built-in function that helps on this), with the following signature:
function group_arr($arr, ...$keys)
{
$result = $arr;
// ...
return $result;
};
So, when I pass in the following array:
$arr_src = [
[ 'Country' => 'USA', 'State' => 'Florida', 'City' => 'Miami', 'Population' => 2744878, 'AreaSquareMile' => 55.25 ],
[ 'Country' => 'USA', 'State' => 'Florida', 'City' => 'Tampa', 'Population' => 4300000, 'AreaSquareMile' => 175.2 ],
[ 'Country' => 'USA', 'State' => 'Florida', 'City' => 'Orlando', 'Population' => 1923000, 'AreaSquareMile' => 113.7 ],
[ 'Country' => 'USA', 'State' => 'California', 'City' => 'Los Angeles', 'Population' => 13100000, 'AreaSquareMile' => 503.0 ],
[ 'Country' => 'USA', 'State' => 'California', 'City' => 'San Diego', 'Population' => 3231000, 'AreaSquareMile' => 372.4 ],
[ 'Country' => 'Canada', 'State' => 'Ontario', 'City' => 'Toronto', 'Population' => 6139000, 'AreaSquareMile' => 243.3 ],
[ 'Country' => 'Canada', 'State' => 'Quebec', 'City' => 'Montreal', 'Population' => 4196000, 'AreaSquareMile' => 166.6 ],
[ 'Country' => 'Canada', 'State' => 'Quebec', 'City' => 'Sherbrooke', 'Population' => 161323, 'AreaSquareMile' => 141.7 ],
];
as on here:
$arr_dst = group_arr($arr_src, 'Country', 'State', 'City');
I get the following result:
$arr_dst = [
'USA' => [
'Florida' => [
'Miami' => [
'Population' => 2744878,
'AreaSquareMile' => 55.25,
],
'Tampa' => [
'Population' => 4300000,
'AreaSquareMile' => 175.2,
],
'Orlando' => [
'Population' => 1923000,
'AreaSquareMile' => 113.,
],
],
'California' => [
'Los Angeles' => [
'Population' => 13100000,
'AreaSquareMile' => 503.0,
],
],
'California' => [
'San Diego' => [
'Population' => 3231000,
'AreaSquareMile' => 372.4,
],
],
],
'Canada' => [
'Ontario' => [
'Toronto' => [
'Population' => 6139000,
'AreaSquareMile' => 243.3,
],
],
'Quebec' => [
'Montreal' => [
'Population' => 4196000,
'AreaSquareMile' => 166.6,
],
'Sherbrooke' => [
'Population' => 161323,
'AreaSquareMile' => 141.7,
],
],
],
];
Any idea on how to achieve this?
Thanks!
Ok, I did the function by myself. Hope it helps somebody else:
/**
* Convert indexed array with associative arrays as elements to multidimensional array by grouping common values
* #param array $arr indexed array with associative arrays as elements.
* #param array $keys list of keys to group by.
* #return array multidimensional array grouped by the provided keys.
* #link https://stackoverflow.com/questions/60824438
*/
function group_arr($arr, ...$keys)
{
if (!function_exists('extract_sub_array')) {
function extract_sub_array($arr, $key, $value) {
$result = [];
for ($i = 0; $i < count($arr); $i++) {
if ($arr[$i][$key] == $value) {
$arr_aux = $arr[$i];
unset($arr_aux[$key]);
$result[] = $arr_aux;
}
}
return $result;
}
}
if (count($keys) === 0) {
return $arr[0];
}
else {
$result = [];
$key = $keys[0];
$values = array_unique(
array_map(
function($row) use ($key) { return $row[$key]; },
$arr
)
);
sort($values);
for ($i = 0; $i < count($values); $i++) {
$sub_arr = extract_sub_array($arr, $key, $values[$i]);
$next_keys = array_slice($keys, 1);
$result[$values[$i]] = group_arr($sub_arr, ...$next_keys);
}
return $result;
}
}
I am trying to apply coupon code using WooCommerce Rest API. I am following the way that has been explained in woo API document. But it is not working anyhow.
Coupon code is applied but discount is not applied.
So can you please tell me if I am doing anything wrong or is there any way to do this.
I have tried searching for the solution, but found nothing so far.
Thanks in advance
Below is my data that I am using as Request to place order using API,
$data = [
'payment_method' => 'bacs',
'payment_method_title' => 'Direct Bank Transfer',
'set_paid' => true,
'billing' => [
'first_name' => 'John',
'last_name' => 'Doe',
'address_1' => '969 Market',
'address_2' => '',
'city' => 'San Francisco',
'state' => 'CA',
'postcode' => '94103',
'country' => 'US',
'email' => 'john.doe#example.com',
'phone' => '(555) 555-5555'
],
'shipping' => [
'first_name' => 'John',
'last_name' => 'Doe',
'address_1' => '969 Market',
'address_2' => '',
'city' => 'San Francisco',
'state' => 'CA',
'postcode' => '94103',
'country' => 'US'
],
'line_items' => [
[
'product_id' => 93,
'quantity' => 2
],
[
'product_id' => 22,
'variation_id' => 23,
'quantity' => 1
]
],
'shipping_lines' => [
[
'method_id' => 'flat_rate',
'method_title' => 'Flat Rate',
'total' => 10
]
],
'coupon_lines'=>
[
[
'code'=>'wer',
'id'=>128,
'amount'=>'10.00',
'discount'=>'10'
]
]
];
$response = $woocommerce->post('orders', $data));
echo "<pre>";
print_r($response);
echo "</pre>";
exit;
For anyone looking for a solution, there is none at the moment. but there is a work around that can help you do the discounts. The solution can be found issuecomment-333092453
Solution summary:
getItemsCart() {
const {cartItems} = this.props;
let items = []
for (var i = 0; i < cartItems.length; i++) {
const cartItem = cartItems[i]
let item = {
product_id: cartItem.product.id,
quantity: cartItem.quantity,
total: cartItem.total // The magic happens here, you apply the coupon to your item's price
}
items.push(item)
}
return items;
}
let data = {
customer_id: user.id,
customer_note: null,
billing: customerInfo,
line_items: this.getItemsCart(),
}
API.post('orders', data)
Total is the total price of an item after discount. make sure this quantity is included: total = price_total_of_single_item * quantity_of_item
The below code is not rendering the line_items as a JSON array and I have searched/asked around to no avail.
Can anyone give me a hand here?
I've also included the json_encode data of the $orderShippingInfo variable.
Below is the JSON output:
{
"token":"API_KEY_HERE",
"email":"a.pinochet#chilehelicoptertours.com",
"line_items":{
"sku":"12345",
"name":"Product Name",
"title":"Product Title",
"price":"$1.99",
"quantity":"1",
"total_tax":"$0.00"
},
"shipping_lines":{
"title":"UPS",
"price":"$0.00",
"method":"UPS 3 DAY",
"carrier":"UPS"
},
"order_id":"0001",
"profile":"default",
"shipping_address":{
"province":"AZ",
"city":"Testville",
"first_name":"Augusto",
"last_name":"Pinochet",
"zip":"12341",
"province_code":"NY",
"country":"US",
"company":"Company Name, Inc.",
"phone":"1112223333",
"country_code":"US",
"address1":"123 Testing Dr Street",
"address2":"Suite #1"
},
"subtotal_price":"$0.00",
"created_at":"2017-02-02",
"country_code":"US",
"total_discounts":"$0.00",
"total_price":"$0.00"
}
TIA!
<?php
$orderShippingInfo = array(
'token' => 'API_KEY_HERE',
'email' => 'a.pinochet#chilehelicoptertours.com',
'line_items' => array(
'sku'=>'12345',
'name'=>'Product Name',
'title'=>'Product Title',
'price'=> '$1.99',
'quantity' => '1',
'total_tax' => '$0.00',
),
'shipping_lines' => array(
'title' => 'UPS',
'price' => '$0.00',
'method' => 'UPS 3 DAY',
'carrier' => 'UPS',
),
'order_id' => '0001',
'profile' => 'default',
'shipping_address' => array(
'province' => 'AZ',
'city' => 'Testville',
'first_name' => 'Augusto',
'last_name' => 'Pinochet',
'zip' => '12341',
'province_code' => 'NY',
'country' => 'US',
'company' => 'Company Name, Inc.',
'phone' => '1112223333',
'country_code' => 'US',
'address1' => '123 Testing Dr Street',
'address2' => 'Suite #1',
),
'subtotal_price' => '$0.00',
'created_at' => date('Y-m-d'),
'country_code' => 'US',
'total_discounts' => '$0.00',
'total_price' => '$0.00',
);
echo json_encode($orderShippingInfo);
?>
You need to make your array of line items an array of them.
For example:
$orderShippingInfo = array(
'token' => 'API_KEY_HERE',
'email' => 'a.pinochet#chilehelicoptertours.com',
'line_items' => array(
array(
'sku'=>'12345',
'name'=>'Product Name',
'title'=>'Product Title',
'price'=> '$1.99',
'quantity' => '1',
'total_tax' => '$0.00',
)
),
'shipping_lines' => array(
'title' => 'UPS',
'price' => '$0.00',
'method' => 'UPS 3 DAY',
'carrier' => 'UPS',
),
'order_id' => '0001',
'profile' => 'default',
'shipping_address' => array(
'province' => 'AZ',
'city' => 'Testville',
'first_name' => 'Augusto',
'last_name' => 'Pinochet',
'zip' => '12341',
'province_code' => 'NY',
'country' => 'US',
'company' => 'Company Name, Inc.',
'phone' => '1112223333',
'country_code' => 'US',
'address1' => '123 Testing Dr Street',
'address2' => 'Suite #1',
),
'subtotal_price' => '$0.00',
'created_at' => date('Y-m-d'),
'country_code' => 'US',
'total_discounts' => '$0.00',
'total_price' => '$0.00',
);
Then you can add a second line item to the array if you require.
The reason for this is that javascript does not have an associative array concept, so to produce one out of a json_encode() would break javascript.
See this example of what json_encode will do
$xx = ['a','b'];
$yy = ['one'=> 1, 'two'=>2];
print_r($xx);
echo json_encode($xx).PHP_EOL;
print_r($yy);
echo json_encode($yy);
Array
(
[0] => a
[1] => b
)
["a","b"] // note this is a JSON array
Array
(
[one] => 1
[two] => 2
)
{"one":1,"two":2} // note this is a JSON object
If the PHP array is numerically indexed, you get a JSON array
If the PHP array is assoc array it will create an JSON Object
If for some reason you specifically want a JSON String representation to be an array you could just add a [] to the $orderShippingInfo[] = array( like this
$orderShippingInfo[] = array(
'token' => 'API_KEY_HERE',
'email' => 'a.pinochet#chilehelicoptertours.com',
'line_items' => array(
'sku'=>'12345',
'name'=>'Product Name',
'title'=>'Product Title',
'price'=> '$1.99',
. . .
. . .