EllisLab text mark
Advanced Search
5 of 10
5
   
flexi cart - A comprehensive shopping cart library for CodeIgniter
Posted: 13 November 2012 07:49 AM   [ Ignore ]   [ # 71 ]   [ Rating: 0 ]
Joined: 2012-08-08
5 posts

Hi haseydesign,

Over the weekend I finally had the time to give flexi cart a try. I’ve managed to put it all together, and everything seems to work apart from displaying the email address from the saved database entry. I can see the order number, and the query that uses it to retrieve the email address, but it returns an empty array. Strange. (as a side note, if order confirmations are displayed like 0000001,0000002 it is really easy for anybody to find email addresses from the database - I know you would have a payment gateway, and you can use a random number….)

Another thing that I’m trying to figure out is how to split items into separate carts. For example: blue items would go into one cart, green items would go into a second cart, and red items would go into a third cart. The user would check out each cart separately. Is it something flexi cart would be able to handle?

Thanks

 
Posted: 14 November 2012 05:21 AM   [ Ignore ]   [ # 72 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@koichirose

Lots of questions there koichirose, let me try and address them individually.

Item Group Discounts
The ‘disc_item_fk’ column is only used to define a discount for a specific item.
If you would like to apply a discount to a group of items, you would use the ‘disc_group_fk’ column.

This column would then link to the ‘disc_group_id’ column within the ‘discount_groups’ table. Each row within this table is the wrapping group for items to be inserted into.

Then the ids of the items you want to group discount are added to the ‘disc_group_item_id’ column within the ‘discount_group_items’ table.

When you then add an item to the cart, it will automatically check through the foreign key relationship between the 3 tables and check whether the item id exists within the ‘discount_group_items’ table. If the discount conditions are valid, the discount will be applied for the item.

I will also point out that the library also includes functions to help you manage discount item groups.
http://haseydesign.com/flexi-cart/user_guide/discount_admin#insert_db_discount_group
http://haseydesign.com/flexi-cart/user_guide/discount_admin#insert_db_discount_group_item

A demo of adding items to a discount group using a custom SQL WHERE builder can be found at:
http://haseydesign.com/flexi-cart/admin_library/insert_discount_group_items/1
http://haseydesign.com/flexi-cart/user_guide/custom_sql_admin#create_sql_where


Defining an Infinite Discount Limit
This is not possible with the current design of the library, instead you will just need to put a large value into the ‘disc_usage_limit’ column.
If the quantity is 0 or null, the library will detect the discount offer as no longer being available.


Allowing Only 1 Discount Code
Thanks for pointing out this bug. I’ve updated the Github repo with a fix to solve this problem.
Only the /models/flexi_cart_model.php file needs to be updated.

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 14 November 2012 05:54 AM   [ Ignore ]   [ # 73 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@Valcsi

There are a few points that I need to confirm you are aware of.

You say that if order numbers are incremental, that other users would be able to simply enter an order number into the url to get specific details of an order - including email addresses.

You need to ensure that these pages are not accessible to unauthorised users. Only users that have logged in as an admin should be able to see all orders, and customers should only be able to see order details for their own orders.

If an unauthorised user should enter a valid url to view someone else’s order, they should not be shown the order details. This functionality needs to be provided by your user authentication library - may I plug my own flexi auth library if you’re interested.

The security of the order details is not compromised by having incremental order numbers provided you follow the steps outlined above. However, it is also possible to generate random order number or to even define you own.

Define the flexi cart to generate random order numbers by setting the following config setting via the flexi cart config file.

$config['defaults']['configuration']['increment_order_number'false

You can alternatively define this via the ‘cart_config’ database table and ‘increment_order_number’ column.

To define your own order number, you can define it when saving the rest of the order via the ‘order_number’ argument on the ‘save_order()’ function.
http://haseydesign.com/flexi-cart/user_guide/order_set_data#save_order

—————————————————————————————————————————————————-

Regarding not being able to retrieve the email address within an order details, first ensure that the data is being saved to the database in the ‘order_summary’ table.

If the data isn’t being saved, review the code within the demo for the ‘demo_save_order()’ method within the ‘model/demo_cart_model.php’ file for saving custom order data.

If the data just isn’t being returned, review the code within the demo for the ‘order_details()’ method within the ‘controller/admin_library.php’ file for getting saved order data.

—————————————————————————————————————————————————-

Finally regarding saving items into multiple different carts, I can’t say I’ve ever come across a need to do this. However, I guess you could probably use the libraries load/save cart feature to achieve something like what you’re after.

You can see a demo of this at http://haseydesign.com/flexi-cart/standard_library/load_save_cart_data

Hope that all helps

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 14 November 2012 06:52 AM   [ Ignore ]   [ # 74 ]   [ Rating: 0 ]
Joined: 2009-05-11
52 posts

Hi,

Thank you for your answer.

I’m leaving the discount codes aside for a moment, as updating the model brought up a new bug about shipping tax rates (I see there’s a commit in May about this), either on your or my side.

Here’s what I’m doing:

$total_shipping $this->m_mkt_cart->calculate_shipping($cart_items);
$shipping_data = array(
 
'value' => $total_shipping['shipping'//value has no tax here
);

//get tax rate based on current country
$tax_data $this->m_mkt_misc->get_tax_rate_by_country_id($this->settings->mkt_country_id);
/* tax data is:
array
  'rate' => int 21
  'name' => string 'VAT' (length=3)
*/
$this->flexi_cart->set_tax($tax_data);
$this->flexi_cart->set_shipping($shipping_data);
var_dump($this->flexi_cart->cart_summary());
/* output:
array
  'item_summary_total' => string '€ 82.64' (length=9)
  'item_summary_savings_total' => string '€ 0.00' (length=8)
  'shipping_total' => string '€ 14.74' (length=9)
  'item_shipping_total' => string '€ 97.38' (length=9)
  'summary_savings_total' => string '€ 0.00' (length=8)
  'savings_total' => string '€ 0.00' (length=8)
  'reward_voucher_total' => string '€ 0.00' (length=8)
  'surcharge_total' => string '€ 0.00' (length=8)
  'tax_total' => string '€ 17.35' (length=9)
  'total' => string '€ 114.73' (length=10)
  'total_rows' => string '1' (length=1)
  'total_items' => string '1' (length=1)
  'total_weight' => string '0g' (length=2)
  'total_reward_points' => string '826' (length=3)
*/ 

As you can see, ‘total’ is (item_summary_total + tax) + shipping. No tax is applied to shipping.

According to the documentation of the ‘set_shipping()’ function, it should apply the cart tax rate:

‘tax_rate’ - Tax rate applied to the shipping rate, the carts tax value is used if no value is submitted. Submitted values must be numeric.


I could fairly easily add a ‘tax_rate’ field to the $shipping_data array, but I wanted to point out a possible bug.

Could you verify this?

Thanks again

p.s. anchors on the doc site still don’t work on firefox (verified both on osx and windows). they are fine on chrome. I guess you can’t do anything about it smile


EDIT: I see I have this in my config file:

$config['defaults']['shipping']['tax_rate'0

I guess this is the value it uses, instead of the cart one. Is this by design?

EDIT2: it doesn’t use that. I solved for now by manually setting a ‘tax_rate’ value for $shipping_data.

 
Posted: 15 November 2012 06:50 AM   [ Ignore ]   [ # 75 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@koichirose,

From the code you have posted, you look like you worked it out that it is the config setting

$config['defaults']['shipping']['tax_rate'

that defines the tax rate for manual shipping options (Database shipping option tax are defined via the table).

However, by default, that config setting is defined as FALSE (Not ‘0’ as you have), which means that the default cart tax rate is used.
If ‘0’ is set, then it defines that no tax should be applied to the shipping rate.

I see that you dismissed this with your EDIT2 comment, but that is how it is intended to work, and from my testing within the available demo example, it proves to work as expected.


One note that I must warn that always throws me off, is that internally, the cart calculates all pricing excluding tax.
The all important config setting to understanding this is:

$config['defaults']['configuration']['price_inc_tax'

If set to TRUE and a $10.00 shipping option is added including 10% tax, the cart will calculate the shipping rate excluding tax as $9.09 ($10 / 10%) and $10.00 including tax.
If the config setting was FALSE, the the shipping option excluding tax would be $10.00 and including tax would be $11.00 ($10 x 10%).

To further complicate matters, remember that you can then further manually define whether to display pricing inc/excluding tax.

 

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 15 November 2012 07:17 AM   [ Ignore ]   [ # 76 ]   [ Rating: 0 ]
Joined: 2009-05-11
52 posts

Thank you for the clarification.

Anyway, I seem to remember that I tried setting 21 as $config[‘defaults’][‘shipping’][‘tax_rate’] and it did not work as expected.

I’m setting it to false now, so it should use the cart tax value, plus I’m manually setting ‘tax_rate’ when calling set_shipping, too.

Here goes about orders:

Note that discount_methods, types and tax_methods are default.

I added a new 10% code:
INSERT  INTO `flexi_discounts`(`disc_id`,`disc_type_fk`,`disc_method_fk`,`disc_tax_method_fk`,`disc_user_acc_fk`,`disc_item_fk`,`disc_group_fk`,`disc_location_fk`,`disc_zone_fk`,`disc_code`,
`disc_description`,`disc_quantity_required`,`disc_quantity_discounted`,`disc_value_required`,`disc_value_discounted`,`disc_recursive`,`disc_non_combinable_discount`,`disc_void_reward_points`,
`disc_force_ship_discount`,`disc_custom_status_1`,`disc_custom_status_2`,`disc_custom_status_3`,`disc_usage_limit`,`disc_valid_date`,`disc_expire_date`,`disc_status`,`disc_order_by`)
VALUES (1,2,7,1,0,0,0,0,0,‘TEST’,‘Test description’,0,0,0.00,10.00,0,0,0,0,‘0’,‘0’,‘0’,5,‘2012-11-12 14:50:20’,‘2012-11-22 14:51:55’,1,100);

disc_type_fk = 2, Summary Discount
disc_method_fk = 7, Summary Item Total - Percentage Based
disc_tax_method_fk = 1, Apply Tax Before Discount

var_dump($this->flexi_cart->cart_contents());
 
output:
array
  
'items' => 
    array
      
'c4ca4238a0b923820dcc509a6f75849b' => 
        array
          
'row_id' => string 'c4ca4238a0b923820dcc509a6f75849b' (length=32)
          
'id' => string '1' (length=1)
          
'name' => string 'Pochette' (length=8)
          
'price' => string '€ 82.64' (length=9)
          
'quantity' => string '1' (length=1)
          
'stock_quantity' => string '3' (length=1)
          
'internal_price' => float 82.64
          
'weight' => string '0g' (length=2)
          
'tax_rate' => string '21%' (length=3)
          
'shipping_rate' => boolean false
          
'separate_shipping' => boolean false
          
'reward_points' => string '826' (length=3)
          
'status_message' => 
            array
              empty
          
'tax' => string '€ 17.35' (length=9)
          
'non_discount_quantity' => string '1' (length=1)
          
'discount_quantity' => string '0' (length=1)
          
'price_total' => string '€ 82.64' (length=9)
          
'discount_price' => string '€ 82.64' (length=9)
          
'discount_price_total' => string '€ 82.64' (length=9)
          
'discount_description' => boolean false
          
'tax_total' => string '€ 17.35' (length=9)
          
'weight_total' => string '0g' (length=2)
          
'reward_points_total' => string '826' (length=3)
  
'summary' => 
    array
      
'item_summary_total' => string '€ 82.64' (length=9)
      
'item_summary_savings_total' => string '€ 0.00' (length=8)
      
'shipping_total' => string '€ 14.74' (length=9)
      
'item_shipping_total' => string '€ 97.38' (length=9)
      
'summary_savings_total' => string '€ 25.61' (length=9)
      
'savings_total' => string '€ 25.61' (length=9)
      
'reward_voucher_total' => string '€ 0.00' (length=8)
      
'surcharge_total' => string '€ 0.00' (length=8)
      
'tax_total' => string '€ 20.45' (length=9)
      
'total' => string '€ 117.83' (length=10)
      
'total_rows' => string '1' (length=1)
      
'total_items' => string '1' (length=1)
      
'total_weight' => string '0g' (length=2)
      
'total_reward_points' => string '826' (length=3)


echo 
$this->flexi_cart->total(); //107.83 

The order total (last line) is correct, as it is (99.99 + 17.83 - (99.99*0.10)).
I don’t understand where that €25.61 in savings is coming from.

About custom statuses: I understood how they work, but they directly relate to the current user session and not to the cart contents.
For example, I’d like to be able to set a discount for a specific brand, for a specific category of products, for a group of users based on some filters (i.e. users that didn’t buy anything in the last 30 days), etc.
I think the best way to achieve this would be to add custom fields to the ‘discounts’ table (or a new table with a fk), then manually check cart contents and querying the db for a discount that matches these filters.
Do you think it would be a viable solution?

About enabling joins: let’s say I want to offer free shipping to users in the UK. I see you do that in the examples.
I disabled the ‘flexi_locations’ table since I’m using one of my own (not used by flexi anyway, as I use my own calculate_shipping() method).
How do I setup a join for my own locations table?

Sorry about the length of this post (and this discussion), I hope it will be useful for everyone smile

 
Posted: 15 November 2012 08:30 AM   [ Ignore ]   [ # 77 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@koichirose

Its getting late night here now so I’ll leave the number calculations answer for another night.

However, regarding setting discounts per item brand, category and user group, you can do this with the current setup by using the previously mentioned ‘disc_group_fk’ column for items and the ‘custom_status_x’ column for the user group.

I know when you first think that if you create item groups, you will then need to add each item one by one to the table where the item brand = ‘xyz’.
However, by using the also mentioned ‘custom_sql_admin()’ function, you can easily create SQL queries that would add all items where the brand = ‘xyz’ AND the category = ‘Category C’.
Then combining this generated SQL WHERE query with the ‘insert_db_discount_group_item()’ function, you can very easily add as many items as you require to your item groups.

Checkout the quoted links below if you want further info.

http://haseydesign.com/flexi-cart/user_guide/discount_admin#insert_db_discount_group
http://haseydesign.com/flexi-cart/user_guide/discount_admin#insert_db_discount_group_item

A demo of adding items to a discount group using a custom SQL WHERE builder can be found at:
http://haseydesign.com/flexi-cart/admin_library/insert_discount_group_items/1
http://haseydesign.com/flexi-cart/user_guide/custom_sql_admin#create_sql_where

You could try the method of adding you own custom columns (Or by just using the 3 ‘custom_column_X’), but I really don’t see the need as the functionality is there, just not quite as simply as you want/expect it to be.

Its designed this way specifically to try to offer a flexible enough solution that whilst not being the ideal layout, it can be used by users with many different cart database schemas.

—————————————————————————————————————————————————-

Regarding the location table, I would need to think it over a bit more about how you could join your 3rd party table. However, the location tables really are quite core to the functionality of many features within the cart (Shipping, tax, item shipping rates, item tax rates, discounts etc.), so I don’t fancy you chances of a quick fix.

 

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 16 November 2012 07:22 AM   [ Ignore ]   [ # 78 ]   [ Rating: 0 ]
Joined: 2009-05-11
52 posts

Thank you for your answer, as always.

I think I’ll go with your builtin solution, putting products in groups and referencing the group id within the discounts table.

Could you check the calculation problem I mentioned in my previous message?

I’ll run some more tests in the meantime.

Thank you.

 
Posted: 16 November 2012 08:28 AM   [ Ignore ]   [ # 79 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@koichirose

I’ve been looking into the calculation problem you’ve been having and I have been able to replicate the incorrect savings value when the ‘price_inc_tax’ config setting is defined as FALSE. It seems that from my testing, if its defined as TRUE, that the calculations are correct.

In anycase, this will need some dedicated time to look into so I might not have a fix until next week.
I’ll keep you posted.

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 16 November 2012 11:50 AM   [ Ignore ]   [ # 80 ]   [ Rating: 0 ]
Joined: 2009-05-11
52 posts

Ok, thank you.

Can I help you with anything to speed this up?


I’m sorry but I’m still confused about foreign keys.

For ‘disc_location_fk’ and ‘disc_zone_fk’, I’m not sure which part of the config affects these.
I tried enabling $config[‘database’][‘locations’][‘table’] with one of my tables at random, but it is not used, so I’m guessing it’s session based and I’d have to call ‘$this->flexi_cart->update_location($location_data);’.

‘disc_user_acc_fk’ is just for rewards? What does it do exactly?

For item_fk / group_item: the field matched is the session’s item id? Some code to explain that:

var_dump($this->flexi_cart->cart_contents());
//output:
array
  
'items' => 
    array
      
'c4ca4238a0b923820dcc509a6f75849b' => 
        array
          
'row_id' => string 'c4ca4238a0b923820dcc509a6f75849b' (length=32)
          
'id' => string '122' (length=1// <------- is this the id that will be checked and that I have to add to the 'discount_group_item' table?
          
'name' => string 'Pochette' (length=8)
          
'price' => string '€ 82.64' (length=9

 


Lastly, please don’t hate me but I guess I found another issue: I added two discounts which are exactly the same except the value discounted. So they have the same code ‘TEST’.
discount code id 1 - 10%
discount code id 3 - 40%

Entering ‘TEST’ when applying the code produces this:

var_dump($this->flexi_cart->discount_codes());
//output:
array
  
'TEST' => 
    array
      
'id' => string '3' (length=1)
      
'code' => string 'TEST' (length=4)
      
'description' => string 'ddd' (length=3

Savings calculations aside, as I explained in a previous message, I can use ‘$this->flexi_cart->total()’ to check the discount code applied.
I get 10% instead of 40%. So discount_codes() reports discount #3 being applied, while the value discounted is from #1.

This won’t happen in our case (and in most cases), since there can’t be discounts with the same code and the same filters, but I thought it would be good to let you know.

Thanks again, have a great weekend smile

 
Posted: 20 November 2012 12:44 PM   [ Ignore ]   [ # 81 ]   [ Rating: 0 ]
Joined: 2009-05-11
52 posts

While we discuss about discounts, I’m trying to edit part of my code to use your libraries as much as possible.

These were previously false/false and now are:

$config['defaults']['configuration']['display_tax_prices'true//previously, I was calculating the taxed price of each product by myself.
$config['defaults']['configuration']['price_inc_tax'false

So when adding items to the cart with insert_items(), the value for price is 82.64 without VAT.

By using set_tax() and setting ‘rate’ to 21, I see 99.99 as price including taxes. Although, there are some rounding problems. I had them too, then I decided to use your libraries more, hoping to solve them :/

Here’s what happen:
I added that item (82.64, 99.99 with VAT).
I set the quantity to 2.

echo $this->flexi_cart->item_price_total($row['row_id']falsefalsefalse); //199.98
echo $this->flexi_cart->item_summary_total(falsefalse); //199.99 

Is there any way around this?
I noticed because when I started working with discounts rounding became a serious issue.

Thanks again.

 
Posted: 20 November 2012 05:18 PM   [ Ignore ]   [ # 82 ]   [ Rating: 0 ]
Joined: 2012-11-20
4 posts
haseydesign - 11 March 2012 03:30 AM

Hey all,

I would like to announce the release of ‘flexi cart’, a comprehensive shopping cart library for CodeIgniter.

Hi, I have been playing with your shopping cart recently. Thanks for releasing this and supporting it actively.

I have a question about this, which is found in standard_library.php in the demo:

function checkout_complete($order_number = FALSE)
{
  // Note: This example uses the ‘get_db_order_summary_row_array()’ and ‘update_db_order_summary()’ function which are located in the flexi cart ADMIN library.

I’ve been trying to find the function get_db_order_summary_row_array() in the flexi cart libraries, models, everything, but for the life of me, I can’t find it anywhere. The closest thing I found was the function get_db_order_summary_query() in the flexi cart admin library, but get_db_order_summary_row_array() is called in the demo and it seems to work. I’m missing something and I hope it’s not something stupid.

Thanks again for creating and sharing this, I’ve been learning a lot from it.

 

 
Posted: 20 November 2012 06:48 PM   [ Ignore ]   [ # 83 ]   [ Rating: 0 ]
Joined: 2012-11-20
4 posts
GhostPepper - 20 November 2012 05:18 PM

I’m missing something and I hope it’s not something stupid.

Ok I see now that “query” is apparently a variable in the function names that one sets to “row_array” or “column_array” depending on the query. Didn’t know you could do that.

 
Posted: 21 November 2012 07:24 AM   [ Ignore ]   [ # 84 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@koichirose

Regarding your confusions with the discount foreign keys.

The ‘disc_item_fk’, ‘disc_location_fk’ and ‘disc_zone_fk’ columns all rely on the carts session data (As you suggested).
You seem to have worked out how they work just by what you have posted.

The ‘disc_item_fk’ is the item id that is saved to the cart when inserting an item.
This same id is what is matched in the ‘discount_group_items’ table for item group discounts.

The location and zone ids can be defined in a few different ways.
You can use the ‘update_location()’ function as you have stated, or you could alternatively define the location when using the ‘update_cart()’ function.

One important note to keep in mind, is that there are 2 different location types - a ‘shipping’ location, and a ‘tax’ location.
This allows you to define shipping rates and discounts offers via the shipping location, and taxes via the tax location.
If you need to set these 2 locations differently (Usually for tax purposes), checkout the setting data functions via the locations user guide page

You can get more information on the discount table setup at http://haseydesign.com/flexi-cart/user_guide/discount_config

—————————————————————————————————————————————————————————————————————

Regarding the issues of stacking discounts together using the same discount code, I haven’t been able to replicate this via my own examples.
I will point out that when two or more discounts are valid, they are applied in the order defined via the ‘disc_order_by’ column in the discount table, the lower the number, the higher priority.
If you can provide a database dump of the two discount rows causing the issue, i’d be happy to look further into it.

—————————————————————————————————————————————————————————————————————

Finally regarding the rounding issues, this was actually a large nightmare for me during development.
I managed to somewhat tighten down the inconsitencies by getting the cart to calculate values based on 4 decimals, but I could not find a 100% concrete solution or best practice of how to solve the issue.
I even tried testing other POS software systems but kept getting the same variations in rounding calculations.

This is actually something I would love to throw out there to anyone willing to offer suggestions on the best way to round up decimals when dealing with currency values containing 3 or more decimals.
These long decimals numbers are mainly caused when dealing with tax and discount percentages.

For example 2 items @ $100 each, minus a 1/3 discount (33.3333%) is $66.6666, rounded to $66.67.
So 2 discounted items now @ $66.67 equal $133.34; but if adding their values together including 4 decimals ($66.6666 x 2), it rounds to $133.33; a $0.01 difference.
Do this with more items and the difference increases.

You could suggest to just apply the 1/3 discount to the total, but the cart items need to be able to be itemised, so it needs to be calculated per item.

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
Posted: 21 November 2012 07:32 AM   [ Ignore ]   [ # 85 ]   [ Rating: 0 ]
Joined: 2012-03-08
168 posts

@GhostPepper

You seem to have sussed it out correctly yourself.
The functions (methods) you are referring to are in fact created using PHPs magic method ‘__call()’ to overload the method (e.g. get_db_order_summary_row_array() over get_db_order_summary_query()).

You can find this defined within the file ‘libraries/flexi_cart_lite.php’ @ line 38.

You can read up further via the user guide @ http://haseydesign.com/flexi-cart/user_guide/query_sql_results#alternative_query_syntax

 Signature 

flexi-auth | A user authentication library for CodeIgniter.
flexi-cart | An e-commerce shopping cart library for CodeIgniter.

 
5 of 10
5