POST to database... how?

My client wants to offer a “ship on your own account” option at checkout. Basically this means that customers can enter their personal/business shipping account info and we'll do the rest.



So, I put some input fields for “Carrier,” “Service” and “Account Number” in the checkout page, on step three.



I added those three columns to the “orders” table in the database, but I can't figure out how to get that data to post.



I can pull the data from those fields and display it in the admin, orders::view orders page, no problem. But that doesn't do me much good if I can't populate those columns in the database from the front-end.



I think the code needs to hook from the customer/views/checkout/components/shipping_rates.tpl …but everything there is wrapped in an ajax form:


```php



{if !$no_form}



{if $use_ajax}{/if}

{/if}


{hook name="checkout:shipping_rates"}

{if $smarty.const.PRODUCT_TYPE == "MULTIVENDOR" ...

...blah, blah....

{/if}
{foreach from=$shipping_rates key="shipping_id" item="s_rate"}


 {$s_rate.name} {if $s_rate.delivery_time}({$s_rate.delivery_time}){/if} - {if $s_rate.rates|@array_sum}{include file="common_templates/price.tpl" value=$s_rate.rates|@array_sum}{if $s_rate.inc_tax} ({if $s_rate.taxed_price && $s_rate.taxed_price != $s_rate.rates|@array_sum}{include file="common_templates/price.tpl" value=$s_rate.taxed_price class="nowrap"} {/if}{$lang.inc_tax}){/if}{else}{$lang.free_shipping}{/if}



...

{/foreach}

...


```

I suck at AJAX. If I try to hack a straight PHP POST method inside this form, it obviously breaks. Do I need to write a new function in one of the core .php files so that my html input names will post? Or can I use some pre-existing CS Cart mumbo-jumbo to make it work?



In short, I need to POST three input fields from the front-end to the "orders" table in the database. How can do?

Why wouldn't you just create a new shipping carrier and associated template rather than modifying the order table and order templates? It would certainly be more portable and be much easier since all you're really doing is collecting info to process manually at a later date and (I'm assuming) calcualting manual shipping rates.

Much easier for you maybe. I'm trying to hack my way through this and I can't figure it out.



Create a new shipping carrier and template? That's what I did, but those fields still have to write to the database. And that's the part I can't wrap my brain around. There are a thousand ambiguous functions in a hundred .php files and I haven't seen anything that will just POST to the stupid database.



I will be so happy if I can just get the checkout button to make three little extra pieces of information to appear in the DB.



I feel like Keanu Reeves when he first heard about the Matrix.



I'm about to hack a pop-up iframe with those input fields and write my own table… except it needs to be tied to the order_id for it to show up in the right order details page and I don't know how to do that either. I'm a designer, not a programmer.



Grr…

If you have setup the shipping carrier and shipping methods properly then you shouldn't have to do anything special. The cart should take care of it for you.



You will have to add your own template that has a form and the input fields to collect the info you want to store. If you look at one of the standard carrier templates like UPS then you can see what the names of the fields are that the system is expecting when the data is POSTed in checkout.



If this is beyond your skill set, why don't you just hire someone to do it for you. It's probably 2 hours work to get it setup (not a quote, a guess). Not sure how you value your time, but I find that I prefer to pay others to do things that are not within my skill set. I then try to learn from what they did.

I'm going to have to agree with tbirnseth on this one. I figured it out, but it took me exactly a billion hours of smashing my face against the code to do it.



Lesson here is: It is better to eat your pride and pay someone who can do it in less time. I could have been working on more profitable things instead of this. The cost for a contractor to do this would have been much less then the money I lost in time trying to figure it out myself.



Outsource it! It's the American way.

plinkplink,



would you mind sharing how you did this?

Sure. It's kind of a hack, so I would suggest following my example with caution.



Basically, I added a new shipping method called “Ship on Your Account” with a Manual rate calculation. This is in the admin panel under shipping and taxes > shipping methods.



Then I changed skins/{your_skin}/customer/views/checkout/components/shipping_rates.tpl from:


{foreach from=$shipping_rates key="shipping_id" item="s_rate"}


 



{/if}


To this:

```php

{foreach from=$shipping_rates key=“shipping_id” item=“s_rate”}

{if $shipping_id != “16”}



suppliers_ids}]" value=“{$shipping_id}” id="sh{$shipping_id}” {if $cart.shipping.$shipping_id}checked=“checked”{/if} /> {$s_rate.name} {if $s_rate.delivery_time}({$s_rate.delivery_time}){/if} - {if $s_rate.rates|@array_sum}{include file=“common_templates/price.tpl” value=$s_rate.rates|@array_sum}{if $s_rate.inc_tax} ({if $s_rate.taxed_price && $s_rate.taxed_price != $s_rate.rates|@array_sum}{include file=“common_templates/price.tpl” value=$s_rate.taxed_price class=“nowrap”} {/if}{$lang.inc_tax}){/if}{else}{$lang.free_shipping}{/if}



{else}





suppliers_ids}]" value=“{$shipping_id}” id="sh{$shipping_id}” {if $cart.shipping.$shipping_id}checked=“checked”{/if} /> {$s_rate.name} - Cost depends upon your provider




Please enter your account details:




Shipping Method (Carrier):




Shipping Service (express, ground, etc..):




Account Number:




{/if}
```
The above code says, if it's not shipping id #16 (which is what the "Ship on Your Account" method just happened to be called) then run a loop through the other shipping services and assign them a radio button. But if it IS #16, then add the radio button, plus this extra div with the text-inputs for "soya_carrier" "soya_service" and "soya_account." I put it inside a div called #slidingDiv so that I could hide and show it via jQuery... more on that later.

Next I added three columns to the database. I put "soya_carrier" "soya_service" and "soya_account" columns into the cscart_orders table.

In order to get those fields to write to the database when the checkout button is pressed, I added this code to the fn.cart.php file located in the /core directory... within the fn_place_order function:
```php
$order['shipping_ids'] = !empty($cart['shipping']) ? fn_create_set(array_keys($cart['shipping'])) : '';

if(!empty($cart['soya']))
{
$order['soya_carrier'] = $cart['soya']['soya_carrier'];
$order['soya_service'] = $cart['soya']['soya_service'];
$order['soya_account'] = $cart['soya']['soya_account'];
}
```

After that, I added the following code to /controllers/customer/checkout.php:
```php
if (!empty($_REQUEST['shipping_ids'])) {
if($_REQUEST['shipping_ids'][0]=="16")
{
$soya = array("soya_carrier" => $_REQUEST['soya_carrier'], "soya_service" => $_REQUEST['soya_service'], "soya_account" => $_REQUEST['soya_account']);
}
fn_checkout_update_shipping($cart, $_REQUEST['shipping_ids'], $soya);
}
```

The next step was to display those fields for the order entry guys in the admin panel on the "view Orders" page. I added this code to the /skins/{your_skin}/admin/views/orders/details.tpl file:
```php
{if $shipping.shipping == "Ship on Your Account"}

Carrier:
{$order_info.soya_carrier}


Service:
{$order_info.soya_service}


Account Number:
{$order_info.soya_account}

{/if}
```
That piece of code finds the fields and displays them from the database if the name of the sipping method is "Ship on Your Account." Obviously the whole thing breaks if you rename that shipping method, but hey, this is a total hack job.

Finally, I added some jQuery to the /skins/{your_skin}/customer/views/checkout/steps/step_three.tpl file at the top:
```php
{literal}



{/literal}
```
This piece of code hides/shows the div with the Ship on Your Account fields. Remember when we said that the shipping id was 16? Well this says if 16 is selected show the div called #slidingDiv, if not, hide it. Of course, you've got to link to the latest jQuery library.

It works perfectly except for one thing.

I just realized that the "Ship on Your Account" won't appear for addresses outside the U.S.!!!

I've got the locations/localizations set up properly. But still no dice.

Any ideas?

[quote]

Lesson here is: It is better to eat your pride and pay someone who can do it in less time. I could have been working on more profitable things instead of this. The cost for a contractor to do this would have been much less then the money I lost in time trying to figure it out myself.

[/quote]

This should become a sticky somewhere! Or pasted on one's forehead so they see it in the mirror each moring!

[quote name='tbirnseth' timestamp='1327095596' post='129684']

This should become a sticky somewhere! Or pasted on one's forehead so they see it in the mirror each moring!

[/quote]



Agreed. Except make sure you know when to use “then” and “than” unlike me.



What do you think of that solution, though? I know it's probably a bit round-about and I didn't bother with the hooks like I should have…

Too much to review in detail, sorry…



Looking quickly, I probably would have just added:

{hook name=“shipping:some_name”}{/hook}

into the template and then put all your logic and code in the skins//customer/addons/my_changes/hooks/shipping/some_name.post.tpl file. Seems like it would be a lot cleaner and easier to address come upgrade time. There may be hooks you could have used already, I don't have time to look. Your jQuery code could have gone in the same hook.



You did not need to extend the order table. You could just add the data as 'extras' in the order.

I agree hooks are the best way to go. I'm gonna follow this and come back to it in the future when I have time to duplicate it using hooks and extras for the database. I'm still learning so I need a little more knowledge to be able to accomplish it with hooks in the template and extras in the database.