You dont need much more than a foreach to achieve this. array_column array_sum and max can help.
Split the task into some smaller ones:
- from your initial list build the result data holder
- group items into groups by their id
- sort groups by id
- iterate groups and calculate for each group the total price, max shipping and grand total
- also update total price and total max ship while processing each group
- calculate the grand total
- display the data as you want as your structure already holds all the needed data
<?php
$input = [
0 => [
0 => 2,
1 => 2200.00,
2 => 'Portable Hard Drive',
3 => 120.00,
4 => 'Taxi'
],
1 => [
0 => 2,
1 => 8500.00,
2 => 'HP Laptop',
3 => 80.00,
4 => 'Taxi',
],
2 => [
0 => 1,
1 => 700.00,
2 => 'Luxury Watch',
3 => 200.00,
4 => 'TAXI FAST',
],
3 => [
0 => 2,
1 => 1500.00,
2 => 'VGA DISTRIBUTE',
3 => 300.00,
4 => 'EMS',
],
4 => [
0 => 1,
1 => 5000.00,
2 => '3D Camera',
3 => 150.00,
4 => 'DHL',
]
];
const ID = 0;
const PRICE = 1;
const PRODUCT_NAME = 2;
const SHIPPING_PRICE = 3;
const SHIPPING_METHOD = 4;
// build initial result, populate groups (items groupped by id)
$result = [
'groups' => [],
'totalPrice' => 0,
'shippingPriceMax' => 0,
];
foreach($input as $item) {
$result['groups'][$item[ID]]['products'][] = $item;
}
// sord ids descending
ksort($result['groups'], SORT_NUMERIC);
var_dump($result);
// for every group calculate total price, max shipping and grand total
foreach($result['groups'] as $id => $group) {
$result['groups'][$id]['totalPrice'] = array_sum(array_column($group['products'], PRICE));
$result['groups'][$id]['shippingPriceMax'] = max(array_column($group['products'], SHIPPING_PRICE));
$result['groups'][$id]['grandTotal'] = $result['groups'][$id]['totalPrice'] + $result['groups'][$id]['shippingPriceMax'];
// update also total values for all groups
$result['totalPrice'] += $result['groups'][$id]['totalPrice'];
$result['shippingPriceMax'] += $result['groups'][$id]['shippingPriceMax'];
}
$result['grandTotal'] = $result['totalPrice'] + $result['shippingPriceMax'];
var_dump($result);
// build the output
$output = '';
foreach($result['groups'] as $id => $group) {
foreach($group['products'] as $product) {
$output .= $product[ID].'-'.number_format($product[PRICE],2,'.','').'-'.$product[PRODUCT_NAME].'-'.number_format($product[SHIPPING_PRICE],2,'.','').'-'.$product[SHIPPING_METHOD].PHP_EOL;
}
$output .= 'Total price = '.number_format($group['totalPrice'],2,'.','').PHP_EOL;
$output .= 'Max of ship = '.number_format($group['shippingPriceMax'],2,'.','').PHP_EOL;
$output .= 'Grand total = '.number_format($group['grandTotal'],2,'.','').PHP_EOL;
}
$output .= 'This order Total price '.number_format($result['totalPrice'],2,'.','').PHP_EOL;
$output .= 'This order Total max ship '.number_format($result['shippingPriceMax'],2,'.','').PHP_EOL;
$output .= 'This order Grand Total '.number_format($result['grandTotal'],2,'.','');
var_dump($output);
Initial $result after creating groups by id and sorting them by id:
array(3) {
["groups"]=>
array(2) {
[1]=>
array(1) {
["products"]=>
array(2) {
[0]=>
array(5) {
[0]=>
int(1)
[1]=>
float(700)
[2]=>
string(12) "Luxury Watch"
[3]=>
float(200)
[4]=>
string(9) "TAXI FAST"
}
[1]=>
array(5) {
[0]=>
int(1)
[1]=>
float(5000)
[2]=>
string(9) "3D Camera"
[3]=>
float(150)
[4]=>
string(3) "DHL"
}
}
}
[2]=>
array(1) {
["products"]=>
array(3) {
[0]=>
array(5) {
[0]=>
int(2)
[1]=>
float(2200)
[2]=>
string(19) "Portable Hard Drive"
[3]=>
float(120)
[4]=>
string(4) "Taxi"
}
[1]=>
array(5) {
[0]=>
int(2)
[1]=>
float(8500)
[2]=>
string(9) "HP Laptop"
[3]=>
float(80)
[4]=>
string(4) "Taxi"
}
[2]=>
array(5) {
[0]=>
int(2)
[1]=>
float(1500)
[2]=>
string(14) "VGA DISTRIBUTE"
[3]=>
float(300)
[4]=>
string(3) "EMS"
}
}
}
}
["totalPrice"]=>
int(0)
["shippingPriceMax"]=>
int(0)
}
$result after calculating all needed data (this contains everything we need to display it):
array(4) {
["groups"]=>
array(2) {
[1]=>
array(4) {
["products"]=>
array(2) {
[0]=>
array(5) {
[0]=>
int(1)
[1]=>
float(700)
[2]=>
string(12) "Luxury Watch"
[3]=>
float(200)
[4]=>
string(9) "TAXI FAST"
}
[1]=>
array(5) {
[0]=>
int(1)
[1]=>
float(5000)
[2]=>
string(9) "3D Camera"
[3]=>
float(150)
[4]=>
string(3) "DHL"
}
}
["totalPrice"]=>
float(5700)
["shippingPriceMax"]=>
float(200)
["grandTotal"]=>
float(5900)
}
[2]=>
array(4) {
["products"]=>
array(3) {
[0]=>
array(5) {
[0]=>
int(2)
[1]=>
float(2200)
[2]=>
string(19) "Portable Hard Drive"
[3]=>
float(120)
[4]=>
string(4) "Taxi"
}
[1]=>
array(5) {
[0]=>
int(2)
[1]=>
float(8500)
[2]=>
string(9) "HP Laptop"
[3]=>
float(80)
[4]=>
string(4) "Taxi"
}
[2]=>
array(5) {
[0]=>
int(2)
[1]=>
float(1500)
[2]=>
string(14) "VGA DISTRIBUTE"
[3]=>
float(300)
[4]=>
string(3) "EMS"
}
}
["totalPrice"]=>
float(12200)
["shippingPriceMax"]=>
float(300)
["grandTotal"]=>
float(12500)
}
}
["totalPrice"]=>
float(17900)
["shippingPriceMax"]=>
float(500)
["grandTotal"]=>
float(18400)
}
Output:
string(407) "1-700.00-Luxury Watch-200.00-TAXI FAST
1-5000.00-3D Camera-150.00-DHL
Total price = 5700.00
Max of ship = 200.00
Grand total = 5900.00
2-2200.00-Portable Hard Drive-120.00-Taxi
2-8500.00-HP Laptop-80.00-Taxi
2-1500.00-VGA DISTRIBUTE-300.00-EMS
Total price = 12200.00
Max of ship = 300.00
Grand total = 12500.00
This order Total price 17900.00
This order Total max ship 500.00
This order Grand Total 18400.00"
The only difference between this and your output is that in group id: 1 I have Luxury Watch first and 3D Camera second and this is the order in your input array. For group id: 2 the order is the same.