I wasn't sure which project to post this under.

If I place an order using cash on delivery, my address is saved to my account and into the database ok.

If I place the order using Protx using the http://www.ubercart.org/contrib/2773 module, the address is not added.

CommentFileSizeAuthor
#5 mydata.txt48.5 KBiancawthorne
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

freixas’s picture

Assigned: Unassigned » freixas
Status: Active » Postponed (maintainer needs more info)

Well, of course it should be posted to the Protx project! :-)

The problem uc_addresses faces is knowing when to save a shopper's address. Originally, I saved the shipping and billing addresses when a user left the checkout page for the verification page. This meant that if a shopper entered a wrong address and went back to correct it, both the wrong address and the correct address would be saved. So I needed to know when the checkout was "complete".

Some orders are completed right away and others have to go through PayPal and return. After trying various choices, I decided the best option was to save the addresses when the user hits the Submit button on the verification page.

So I use the uc_addresses_order() hook and wait for $op == 'submit' and $arg1->order_status == 'in_checkout' before saving the addresses. If Protx changes the behavior of the checkout process so that this state never occurs, then the addresses would not be saved.

Anonymous shoppers are more complicated. Their addresses are saved in the session. Then I wait until an account has been created for them, retrieve the addresses from the session and add them to the new account. If the problem only occurs for anonymous shoppers, then Protx may be interfering with this algorithm. The code for this is also in uc_addresses_order().

If you are a programmer, you can help track down the problem by placing some debug statements in uc_addresses_order that record the values of $op and $arg1 as an order is placed. The code I would suggest would be

function uc_addresses_order($op, &$arg1, $arg2)
{
  global $user;
  $order = $arg1;
 
  file_put_contents("somefile", $user->uid . " " . print_r($op, true) . " " . print_r($order, true) . "\n", FILE_APPEND);
  if ($op == 'submit' && $order->order_status == 'in_checkout') {
    $address = new stdClass();
  ...

This will record all debug output in a file called "somefile" and won't interfere with placing an order. Now place an order using COD and then place an order using Protx (it may be best to rename "somefile" after placing the first order so you can tell which output matches which order). Comparing the output of the two orders should shed some light on the problem.

iancawthorne’s picture

I can confirm that this applies to logged in users as all my tests have been while logged in.

iancawthorne’s picture

I'm not the best at programming. Could you give me a line of code to search for in the file (or a line number) to add the code you have provided to put above or below?

I'll give it a whirl and see what it throws out then.

freixas’s picture

Just use the search facility of whatever editor you have. Look for "function uc_addresses_order".

The only line added is the one that says file_put_contents(...).

The name "somefile" should be changed to a file path of some sort, otherwise you may have a hard time figuring out where the output went to. Whatever path you pick will need to be one where the server has the proper permissions to create and write to a file.

Good luck!

iancawthorne’s picture

FileSize
48.5 KB

I have attached the file that was created. I have no idea where to look or what for though!

freixas’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

I was hoping for two files, one for where it worked (for a COD order) and one where it failed (for a Protx order). I am guessing here, but I think you sent me just the case where you placed a Protx order. Is that right?

If so, the reason the addresses aren't recorded is because the order never goes through the 'submit' state. Here is the documentation for the hook_order() states from Ubercart:

When a sale is being completed and the customer has clicked the Submit order button from the checkout screen, the hook is invoked with this op. This gives modules a chance to determine whether or not the order should be allowed. An example use of this is the credit module attempting to process payments when an order is submitted and returning a failure message if the payment failed.

I don't know anything about Protx. When you use it, does it bypass the order verification page? In any case, I suspect that Protx is not quite following the rules: an order should go through the 'submit' state to allow other modules to determine whether the order should or should not be allowed. Skipping this state could break modules other than mine.

One possible fix would be for me to hook into the 'save' state instead of the 'submit' state. But I think I've gone through this already—for some payment types, the save state may not occur for some time, but people expect the addresses to be saved when the order is submitted.

I'm not sure how Protx skips the submit state, but that would be the next thing to check. Right now, I will mark this "won't fix" and let you direct the Protx team to this discussion. If they can make a good argument that their algorithm is correct, then we can re-open the bug and consider alternatives.

One workaround is for you is to change the state that I check for in this line in uc_addresses_order():

if ($op == 'submit' && $order->order_status == 'in_checkout') {

Change 'in_checkout' to 'save'. Then try placing an order using each payment type and see if your addresses are saved. If you had sent me the debug output for the COD order, I could have told you if this change would work for COD orders, but it should be easy to test. You still want a more permanent fix or your next update of uc_addresses will break your system again.

I hope this helps.

iancawthorne’s picture

Thanks for your help with looking into this.

A few answer to your points.

Protx does include the order verification page (/cart/checkout/review) If that is what you mean?

I have tried changing the line :
<? if ($op == 'submit' && $order->order_status == 'in_checkout') { ?>
to
<? if ($op == 'submit' && $order->order_status == 'save') { ?>
but this made no difference. The address was still not saved.

Are there any other states apart from "save" I could try? To test if anything rather than a fix.

Unfortunately, I have had no responses so far from my posts on the Protx module so I suspect it is not being maintained.

I'll continue running some tests with the file dumps comparing COD to Protx as you suggested.

freixas’s picture

Ooops! I'm sorry—what I meant was: try changing 'submit' to 'save' (leave 'in_checkout' alone).

Sorry about that!

iancawthorne’s picture

Aha! Yes that has a more desired result! The address is now saved on reviewing the order.

I see your point on that going back to make any corrections would result in the incorrect address also being saved separately. For my purposes, this is a good enough fix. Many thanks for your time on this, it is much appreciated.