Post by xds » Tue Jul 13, 2010 9:21 pm

ON HOLD FOR NOW! Hopefully the new version of opencart will be released next month containing this feature!

Since I have yet to find a reward points / customer loyalty system for opencart, I figured I would try my hand at developing one myself. As I am new to opencart and have not fully gone through it, I thinks its best to share my workings with the community and hope for other users input throughout the development process. Since it is me doing the majority of this work, it will most likely end up as one hell of a hack job, but I have hopes that my works will provide some more experienced developers with everything they need to create a proper module.

The goals:
- Create method of inserting points changes into database.
- Create a master value in admin to configure the base rate of store credit to award per default currency unit (USD, euro, pound etc)
- Create fields in Admin > Edit Customer section to show credit balance, and add / remove credit.
- Create page in admin to view credit history for a customer.
- Create front end page for customer to view their current as well as their credit history.

Overview:
Image

I reviewed what little code was available on the forums in this post: http://forum.opencart.com/viewtopic.php?f=24&t=10420 and noticed this user was setting up an individual credit value per product. In essence this would be nice to have, but it causes issues when a customer places an order with points + cash when you want to total up how much credit they should be awarded. I am open to solution suggestions for this problem, but I think for now I will just focus on doing a credit per order total. A future idea was to implement a toggle per product to not allow specific products to eligible for store credit awards (gift vouchers maybe?).

Database Table oc_customer_credit_pending:

Code: Select all

CREATE TABLE IF NOT EXISTS `oc_customer_credit_pending` (
  `id` int(11) NOT NULL auto_increment,
  `customer_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `value` decimal(15,2) NOT NULL default '0.00',
  `comment` varchar(200) default NULL,
  `date_added` timestamp NOT NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Database Table oc_customer_credit_history:

Code: Select all

CREATE TABLE IF NOT EXISTS `oc_customer_credit_history` (
  `id` int(11) NOT NULL auto_increment,
  `customer_id` int(11) NOT NULL,
  `order_id` int(11) NOT NULL,
  `value` decimal(15,2) NOT NULL default '0.00',
  `comment` varchar(200) default NULL,
  `date_added` timestamp NOT NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
In order for this to be effective, the inserts need to happen when the order is actually confirmed to be placed. My preliminary run with Cash on Delivery tells me that the most likely place for this is in catalog\model\checkout\order.php in the public function confirm. But I need to do some further testing with other payment modules to see how they function.

Assuming we have our location to drop our code while noting that I am not a great developer, I am thinking at this point I need to locate the already existing currency conversion functions and push our order total to it to get our total cash value spent that we want to use for credit awarding.

With this returned value, we will do an insert into the credit_pending table with our converted amount multiplied by our value set in admin, roughly like:

Code: Select all

$credit_to_award = currency_converter_function($order_total) * $credit_multiplier
$this->db->query("INSERT INTO oc_customer_credit_pending SET customer_id = '" . (int)$data['customer_id'] . "', order_id = '" . (int)$order_id . "', value = '" . (float)$credit_to_award . "', comment = 'Credit awarded for order " . (int)$order_id . "'");
Then if this order had a deduction applied to it where the customer used some credit:

Code: Select all

// Here we assume that $credit_spent is a negative number
$this->db->query("INSERT INTO oc_reward_points_pending SET customer_id = '" . (int)$data['customer_id'] . "', order_id = '" . (int)$order_id . "', value = '" . (float)$credit_spent . "', comment = 'Credit Deducted for order " . (int)$order_id . "'");
Other notes, to keep things nice and easy for the site admin, I feel that the customers credit should always be stored in the sites default currency. So in the above scenario, we would also need to run the deductions bit through the currency converter before inserting it into the credit pending table.

Also in this function, we need to deduct the amount of credit used from the customers_current_credit field which I forgot to mention we would need to add to the customers table. Since we are adding it to the pending table, the customer should no longer have access to this credit amount to avoid customers using the same credit for multiple orders. In the event an order gets cancelled, we will toss in a function on the update order function to allow for the credit to be applied back to the customer account.

Moving on:

I feel that the Completed order status is a great place to handle the final arrangements of credit. This makes sure that no customers are granted credit before the order is fully completed to make absolutely sure customers aren't able to use credit they shouldn't be using. I have seen a lot of systems that award credit once a payment completes, but feel this is not a great way of doing things.

While I haven't looked into the code much to find out exactly where to put all this, it should be rather clear what will happen:

Code: Select all

- Order status is set to Completed.
-> A Select statement is performed on the customer_credit_pending table which grabs all entries Where order_id = XXX
-> Negative balances are placed into customer_credit_history and this record is removed from customer_credit_pending
-> Positive balances are placed into customer_credit_history, it's applied to the customers_current_credit field in the customers table and finally this record is removed from the customer_credit_pending table.
Alternatively, if the remaining balance is never paid for, or the order needs to be cancelled for some other reason:

Code: Select all

- Order status is set to Cancelled
-> A Select statement is performed on the customer_credit_pending table which grabs all entries Where order_id = XXX
-> Negative balances are converted to positive and applied to the customer_current_credit field in the customers table
-> All entries in customers_credit_pending table related to this order_id are deleted and no history entry is necessary in my opinion.
Whew thats a lot of shit spewing out of my brain! Anyway, I'm quite tired now and need a break but if anyone wants to point out some specific locations or suggestions or any helpful information, please reply and I will review it and update this post with more information on this process. Hopefully I can get some assistance with this and everyone who has been wanting this module can do your part and help build it for free. =]
Last edited by xds on Tue Jul 13, 2010 9:38 pm, edited 1 time in total.

Thanks for 1.5!


xds
New member

Posts

Joined
Mon Jul 12, 2010 9:53 am

Post by SteveSherry » Tue Jul 13, 2010 9:33 pm

Looks like some work is already being done towards this:
http://forum.opencart.com/viewtopic.php ... 91&start=0

My Website ¦ Summer Madness Special Offer ¦


Active Member

Posts

Joined
Thu Apr 08, 2010 7:47 am
Location - Wirral, UK

Post by xds » Tue Jul 13, 2010 9:39 pm

Would have been nice if you would have told me that before I started on this =]

Thanks for sharing before I did waste a lot of unnecessary time. I may continue this project if the next release of OC gets pushed back.

Thanks for 1.5!


xds
New member

Posts

Joined
Mon Jul 12, 2010 9:53 am
Who is online

Users browsing this forum: No registered users and 71 guests