Hi there,
I’ve been using CartThrob 1.x for a while now, expanding it in every way possible without hacking the core and I wanted to say the following about order processing. Note that I only used CartThrob 1.x. I hope my whole story is invalidated with CartThrob 2.x, but here we go:
Since the order processing is not existant in CartThrob, we had to completely build it ourselves.
We have the following statusses for each order:
Status CartThrob State
open (not paid) -
processing cartthrob_on_authorize
processing_pickinglist_printed -
complete -
on_hold -
closed -
declined (credit card) cartthrob_on_decline
failed (credit card) cartthrob_on_fail
When an order gets processed by the gateway (e.g. gets authorized) we hook into it and do some actions that are specific to our situation:
Extension Method Hook Used
Ho_cartthrob_invoices create_invoice cartthrob_on_authorize
Ho_cartthrob_multiple_suppliers reduce_inventory cartthrob_on_authorize
Ho_cartthrob_savedcart clear_cart cartthrob_on_authorize
Ho_cartthrob_customerbalance create_order_transaction cartthrob_on_authorize
Ho_cartthrob_multiple_suppliers check_inventory cartthrob_pre_process
Ho_cartthrob_taxgroups ho_taxgroups_save_rates cartthrob_pre_process
To process an order successfully we need to do some actions. Lets see some examples.
First Example: In order to create a pickinglist we want the client to press one button: ‘Print Picking List’. Once this button is pressed we need to change the status of the order and print the the actual picking list.
We change the order status using a template:
<?php
global $DB, $IN, $PREFS, $SESS;
$site_id = $PREFS->ini('site_id');
/* Get weblog id of the invoices - extra security check & performance */
$_result = $DB->query("SELECT weblog_id FROM exp_weblogs WHERE site_id = {$site_id} AND blog_name = 'orders'");
$weblog_id = $_result->row['weblog_id'];
/* Get the url title */
$url_title = $IN->fetch_uri_segment('3');
/* Get the entry */
$_result = $DB->query("SELECT * FROM exp_weblog_titles WHERE site_id = {$site_id} AND weblog_id = {$weblog_id} AND url_title = '{$url_title}'");
if($_result->num_rows == 0)
{
header('Location: '.$IN->global_vars['base_url']);
exit;
}
if($_result->num_rows == 1 && empty($url_title) === false)
{
$data = array(
'status' => 'processing_pickinglist_printed'
);
$sql = $DB->update_string('exp_weblog_titles', $data, "entry_id = '{$_result->row['entry_id']}'");
$DB->query($sql);
}
// ...do some other stuff and print the actual template
?>
This does the job, but now I have all this non-resuable PHP in my template… which isn’t a good idea to begin with.
Second example: Authorize manually:
When a user wiretransfers the money to the webshop, the gateway can not authenticate the order, because authentication means inventory reduction, which can only happen when the order is actually paid for.
To solve this we have to authorize an order manually. I’ve created a template for this:
<?php /* [...some authentication code if the user is allowed here] */ ?>
{exp:weblog:entries disable="categories|category_fields|member_data|pagination|trackbacks|custom_fields" status="{code_order_statusses_administration}"}
{exp:ho_cartthrob_inv:create_invoice entry_id="{entry_id}"}
{exp:ho_cartthrob_ms:inventory_reduce entry_id="{entry_id}"}
{/exp:weblog:entries}
{redirect="administration/sales_orders_view/{segment_3}"}
As you can see I wanted to create an invoice and reduce the inventory for this order. This is a suboptimal solution, because now I had to create a additional plugin which hooks in my Ho_cartthrob_invoices extension which in his turn creates the invoice.
I can imagine I would like to send emails, make a log at the order, etc.
I understand these features can not be build in by it’s self, because the orderprocessing is different for each client, but what would be great if we have a unified system where we can hook our extensions into to add additional functionality.
What i would like to see is that CartThrob has some expanded methods which allows me to change the status of an order and fire a hook which allows me to do some stuff.
The extension developers could create their functionality:
<?php
class Developer_custom_extension {
// __construct stuff
// add the method to the status processing settings.
function cartthrob_orderprocessing_add_methods ($methods)
{
$methods[__CLASS__]['create_invoice'] = 'Developer custom extension: Create Invoice';
return $methods;
}
function create_invoice($CT)
{
// Do some stuff
}
// some other methods
}
?>
In the cartthrob configuration panel you can link actions to statusses.
When status changes to [STATUS] do the following action [Developer custom extension ::create_invoice].
Of course, things will need to get authenticated if the current user is allowed to preform a certain action (is the action allowed only by the admin, is there an authentication token available, etc.)
Maybe you guys have better ideas about the implementation, but I think you get the idea.
