The company I work for manages 19 different brands, several of which have websites on which we sell products using Ubercart.

Our internal system is tied to our site so that when an order is placed on the site it updates our internal system so the accounting and shipping departments know what is expected of them.

To keep track of which order came from which store we prefix our order ID with a two character code and then pad the ID with zeros until it is a 6 digit ID with a two letter prefix.

In order to display our ID instead of the default Ubercart ID I created a theme override for the uc_cart_complete_sale function and modified the customer email. I also had to hijack the orders page on sites where we allow users to maintain an account.

We're migrating our sites to D7 now and converting our custom modules over. In that process I'm improving and optimizing a lot of the way things were done previously on our sites. One of those things is the situation I just described.

What I'm hoping is that options could be added to the uc_order admin settings to choose to "theme" the order ID. The admin provides a prefix (and maybe suffix for cases other than my own) and an optional padding or total ID length then wherever the ID is generated it can use those options if they're set.

The actual ID stored in the database and used in the module does not need to change, only where it is displayed to the user.

I've already changed my custom module to provide a token that does this for the order complete page instead of having to copy the theme_uc_cart_complete_sale() for every theme. But that still leaves admin emails, customer emails, the user's order list, order view, and invoices where the ID remains the default.

Or if there is some other way to easily do this already I'd really appreciate knowing it.

Thanks!

Comments

longwave’s picture

Adding a theme function for the order ID seems like a good idea. You could override the theme function in template.php to output whatever format you wanted. We could then use this wherever an order ID is to be displayed, add a token and Views integration, and that should be flexible enough? Your custom code could be a starting point for this, if you want to share it.

TR’s picture

The problem with a theme function is that it doesn't go both ways. If the customized order # is computed in the theme function, then you don't have a way to obtain the oid given the customized order #. A better way would be to have a relation table to maintain the translation between the two. Perhaps declare a hook that can be used to convert between custom #s and oid, hook_uc_order_get_order_number($order), accompanied by an API function uc_order_get_order_number($order) which calls this hook. (If you have $order, you also have $order->oid, so you don't need methods to go the other way). Or better yet, make this a method on the UcOrder object, say UCOrder->getOrderNumber() (which calls hook_uc_order_get_order)number() internally). That way if someone wanted to have their own order # pattern they could implement the hook, otherwise the normal $oid would be returned . All the order queries would have to be modified to use this new API function instead of directly using $oid, and all the customer-facing uses of $oid would have to be replaced by the new API function.

And yes, this would be a useful feature to add.

merzikain’s picture

The idea is to be able to define a pattern to your ID display, not the actual order id. The id in the system does not need to change at all so there's really no need for another table to reference anything.

Something like a tokenized pattern or a specific syntax for the pattern could be used on a single field in the store settings for Order ID pattern. The default, of course, would just be the order ID by itself but could be modified to something like:

(Prefix)(Separator){padding:3}(Separator){orderid}(Separator){padding:3}(Separator)(Suffix)
() surrounds user input, {} surrounds specific syntax and placeholder for the actual order ID

Each point in that except the {order ID} would be optional so you could have something as complex as ABC-000-1-000-XYZ or as simple as 1. For my purposes I'd just define something like ABC000001 ({prefix}{padding 6}{order ID}).

Some ideas I had for structuring the pattern would be:
(Prefix)/(Suffix) - obvious, comes before/after everything else and would be some alphanumeric string that the user would define.
(Separator) - again, user input, could be limited to hyphen, underscore and/or period.
{padding:N} - could actually make that a specific syntax where whatever the user puts for N would be padded to the order ID. {padding:3} with an ID of 1 would be 001 and {padding:6} with an ID of 123 would be 000123. Adding a padding after the ID would follow the same rules, subtracting the length of the ID from the padding number and adding that many (if above 0) 0's to the end. Padding would always be 0's in any case.
{orderid} - Order ID placeholder.

If this patterned ID is added to the order object that's fine but I'd like to see it as user friendly as possible and allow those who cannot code or afford a coder the ability to use this functionality too.

Anyway, that was the original idea and I think the easiest to implement since it could be as easy as a simple str_replace for the specific syntax method or as complex as adding token support to the pattern definition.

The only way a reference table for patterned ID's would be necessary is if you allowed randomization in the patterns but if that were the case you'd also have to keep building a new random ID until it generated one that didn't exist in the system already and, honestly, I can't think of any reason why you'd want that anyway. Could even get rid of everything after {orderid} in my example pattern and just keep it at that for simplicity.

And ultimately, like longwave pointed out, the ID being in a themeable function allows users to override the theme function in their template.php to modify the ID output however they see fit.

In any case the point is to make the ID themeable so it can be changed everywhere it is displayed on the site and in UC generated emails.

TR’s picture

The idea is to be able to define a pattern to your ID display, not the actual order id. The id in the system does not need to change at all ...

I understand that, and in fact I implemented exactly that on a site about 4 years ago. So my reply in #2 is based on experience. It's an enormous problem if you do it that way because you can't do a reverse lookup - every customer who has a problem or question will give you a "themed" order number which you can't look up in the database. And customers with problems aren't very tolerant of "I can't find your order, what was your name again?" If you do the order # replacement in a theme function you can't ensure that the end user won't just override the theme function - there is no way to enforce a requirement that the order id be a part of the new themed order number. Besides, that's just a fringe case, I don't think I've heard anyone ask for a way to add prefixes and suffixes to the internal oid. So if we're going to do this, I'd rather put the effort into doing it right rather than a superficial patch which only helps some people.

merzikain’s picture

I disagree.

docans’s picture

So is there any sample code that can get this achieved. I have been trying to generate a custom pattern. My order number is made up of:

=> mmddyy-0001

Where mm = month i.e. 05 for may
dd = day i.e. 25 for 25th
yy = year i.e. 14 for 2014.

Any solution on how to generate this.

TR’s picture

Version: 7.x-3.5 » 8.x-4.x-dev