Skip to content
Advertisement

Matching IDs in 2 different foreach loops in PHP (CodeIgniter)

So basically, what I’m trying to achieve is calculating the tax percentage on each food category.

Lets suppose category number 5 having the tax percentage of 8%.

So based on simple formula to calculate tax on each item is:

ITEM COST * TAX % / 100 = Tax Amount

So I have 2 arrays

ARRAY 1:

 Array
(
    [0] => Array
        (
            [5] => 8    // [CATEGORY-ID] => TAX %
        )

    [1] => Array
        (
            [22] => 9
        )

    [2] => Array
        (
            [32] => 0
        )

)

ARRAY 2:

 Array
(
    [0] => Array
        (
            [5] => 4.6   // [CATEGORY-ID] => ITEM COST
        )

    [1] => Array
        (
            [5] => 10.33
        )

    [2] => Array
        (
            [22] => 1.15
        )

    [3] => Array
        (
            [32] => 4.59
        )

)

table food-category here

Some sub functions used inside get_per_tax_amount()

/**
  * GET CATEGORIES-ID FROM ADDED CART ITEM OF THE USER
 */
public function get_category_id_from_cart_item()
    {
         $cart_items = $this->cart_model->get_all();

         $data = array();
         foreach ($cart_items as $cart_item) {
             
            $menu_details = $this->menu_model->get_cat_by_menu_id($cart_item['menu_id']);
            $data[] = $menu_details['category_id']; //array(1, 2, 2, 3);
         }

         return  array_unique($data); // Array is now unique (1, 2, 3)

    }

    /**
     * GET TAX % FROM CATEGORY-ID
     */
    public function get_category_tax_value()
    {
         
         $cat_ids = $this->get_category_id_from_cart_item();
         $data = array();
         foreach ($cat_ids as $cat_id) {
            $this->db->select('id,tax');
            $this->db->where('id', $cat_id);
            $category_data = $this->db->get($this->table)->row_array();
            $data[] =  array($category_data['id'] => $category_data['tax']); 
          }
       return $data;
    }

    /**
     * GET SMALLER DATA FOR CART PAGE : PER-MENU PRICE
     */
    public function get_per_menu_price()
    {
        $cart_details = $this->get_all();
        $data = array(); 
        foreach ($cart_details as $cart_detail) {
  
            $menu_details = $this->menu_model->get_cat_by_menu_id($cart_detail['menu_id']);
            $data[] = array($menu_details['category_id'] => $cart_detail['price']);               
            
        }
        return $data;
        
    }

Example:

public function get_per_tax_amount()
    {
         $percentages = $this->category_model->get_category_tax_value();  //array 1
         $units = $this->cart_model->get_per_menu_price(); //array 2
         $total_vat = array();
         foreach ($percentages as $cat => $proportion) {
            
            foreach ($units as $unit_cat => $price) {
                
                if($cat == $unit_cat){

                     $total_vat[] = (floatval($price) * floatval($proportion)) / 100;

                }else{

                     $total_vat[] = (floatval($price) * floatval($proportion)) / 100;
                }
            }
         }

         return $total_vat;
    }

output is:

Array
(
    [0] => 0.01
    [1] => 0.01
    [2] => 0.01
    [3] => 0.01
    [4] => 0.01
    [5] => 0.01
    [6] => 0.01
    [7] => 0.01
    [8] => 0.01
    [9] => 0.01
    [10] => 0.01
    [11] => 0.01
)

I don’t know why I am getting this output.

So my problem is, how do I match the CATEGORY-ID using foreach loop and get each item tax amount?

Advertisement

Answer

You can achieve a relatively straightforward algorithm if you restructure your input arrays. Currently, you have ungrouped data and some unnecessary levels. This adds complexity to your function that is supposed to calculate tax amounts. If we redesign the arrays to a more fitting format, we can simplify the function.

The array that holds tax percentage values per category can be a simple one-dimensional array (because here you logically do not need duplicate values), like so:

// [CATEGORY-ID] => TAX %
Array
(
    [5] => 8    
    [22] => 9
    [32] => 0
)

The one that holds item prices and their categories could be made into an array where top level keys are category ids and their values are subarrays of all item prices in that category, like so:

// [CATEGORY-ID] => ITEM COST
Array
(
    [5] => Array
        (
            [0] => 4.6   
            [1] => 10.33
        )
    [22] => Array
        (
            [0] => 1.15
        )
    [32] => Array
        (
            [0] => 4.59
        )
)

With arrays neatly organized, we can now reduce the calculation function to this:

function get_per_tax_amount() {
    $percentages = $this->category_model->get_category_tax_value();
    $units = $this->cart_model->get_per_menu_price();
    $total_vat = [];
    foreach ($units as $unit_cat => $prices) {
        foreach ($prices as $price) {
            $total_vat[] = $price * $percentages[$unit_cat] / 100;
        }
    }

    return $total_vat;
}

How it works:

  • We don’t need to loop the percentage array at all. We will only use it for reference.
  • The outer loop iterates over the units and the inner loop iterates over all the unit prices in the category.
  • For every price, we simply access the index in the percentage array equal to the current category key of the outer loop and do the calculation. You might want to add a check if that array key exists in the percentage array (this code assumes it will exist) and then handle that case however would be best for your application (throw exception, return empty array…).

Now, I haven’t tested this final bit, but to achieve these array structures, I believe you only need to change the following:

  1. In the get_category_tax_value() function, change this:
$data[] =  array($category_data['id'] => $category_data['tax']);

to this:

$data[$category_data['id']] = $category_data['tax'];

to remove the extra dimension.

  1. In the get_per_menu_price() function, change this:
$data[] = array($menu_details['category_id'] => $cart_detail['price']);

to this:

$data[$menu_details['category_id']][] = $cart_detail['price'];

to add prices in a subarray.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement