Wednesday, September 20, 2006

Paypal module passes STORE_NAME instead of item

The PayPal payment module (paypal.php,v 1.39 2003/01/29) for OSCommerce does not pass a meaningful item description to Paypal as a transaction is processed. Instead, the developer of this module programmed it to send the name of your store instead:
tep_draw_hidden_field('item_name', STORE_NAME) .
The result is that when the transaction completes, Paypal sends the store owner an email notification, unhelpfully describing the item purchased as "[name of your store]".

We will fix this by changing the code in the payment module to send a better description for that field. While we're at it, we'll change the code to better support stores selling multiple items in one transaction because this Paypal module comes "out of the box" designed more for single item purchase. When multiple items are purchased, this module just gives an aggregate description of the whole transaction, without any detail of what exatly was purchased.

To fix both of these problems, use the patch file below, or edit (path to your store)/includes/modules/payment/paypal.php and jump down to this function:
function process_button() {
find the line that looks like:
$process_button_string = tep_draw_hidden_field
and insert a comment marker right before it:
/*
$process_button_string = tep_draw_hidden_field
and then go down a few more lines from there until you get to the one that has a semicolon at the end, instead of a period. After that line, insert an ending comment marker:
*/
Now, after your ending comment marker (commenting out the original code makes it not operate anymore, while preserving it for reference), insert the following:
 # Multiple item payment, P. 86 of 
# https://www.paypal.com/en_US/pdf/PP_WebsitePaymentsStandard_IntegrationGuide.pdf

$process_button_string = tep_draw_hidden_field('cmd', '_cart') .
tep_draw_hidden_field('upload', '1') .
tep_draw_hidden_field('business', MODULE_PAYMENT_PAYPAL_ID) .
tep_draw_hidden_field('handling_cart', number_format($order->info['shipping_cost'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency))) .
tep_draw_hidden_field('currency_code', $my_currency) .
tep_draw_hidden_field('custom', $order->info['comments']) .
tep_draw_hidden_field('return', tep_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL')) .
tep_draw_hidden_field('cancel_return', tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'));

# add individual items and amounts to keep in PP transaction history and notices

$i=0;
foreach($order->products as $key => $arr)
{
$i++;
$process_button_string .= tep_draw_hidden_field("item_name_$i", $arr["qty"] ." ". $arr["name"]) .
tep_draw_hidden_field("amount_$i", $arr["qty"] * $arr["final_price"]);

}
Save the file, and now every payment transaction from your OS-Commerce store that is processed with this payment module will send Paypal the item name and price of each item your customer is purchasing. The "handling_cart" field adds a single shipping fee to the entire order. If you want to charge shipping amount per item, see the manual mentioned in the code comment above and use multiple "shipping_X" fields inside the foreach loop instead.

Once you make this change, the email notices that Paypal sends to the shop owner after each purchase will contain a detailed list of what was bought. Both the customer and the merchant will also have detailed records of the itemized list stored in the Paypal transaction history. This is much better than just one aggregate item with a total price and no Paypal record of what the order consisted of.

Using my patch file to make the above change.
You can skip a whole lot of manual editting if you download the patchfile included below, save it as paypal.patch in the same directory as the original paypal.php file, and then run the following shell command:
patch -b paypal.php < paypal.patch
The -b option will make a backup copy of the original file, just in case.

Tuesday, September 12, 2006

Getting your rental deposit back

My friend gets jammed up a lot. In July it was over his deposit on a residential rental that he shared with some roommates. The landlord stopped by two days before their lease expired to express some very demanding expectations about how her crummy little shack should be returned, otherwise it was coming out of their deposit.

Landlord's list of intended charges included:
  • the brown, unwatered sections of lawn
  • replacing dead landscaping bushes
  • edging and weeding
  • professional carpet cleaning in a damp sub-basement!
  • scrubbing stains out of 60 year old grout with particular cleaning products
  • replacing a stolen freezer

My friend knew this list was going to mean a large chunk of their $1,000 security deposit would be missing when they got it back. The landlord even hired a lawn psychiatrist to come over and pad the bill with exotic plant examinations. So I was asked to be there as a mouthpiece when the landlord returned to check on cleaning progress.

I did, and let her know (in the most helpful and innocent manner) that she really couldn't deduct a thing from the deposit because 1) the property is in the same condition now as it was when she rented it to them, and 2) she never did a written "check-in" sheet documenting the original condition, and without it, the law is not on her side for making deductions from the deposit.

We went back and forth, her pointing out some alleged damage, my saying it was like that when they moved in, her saying it wasn't, and my asking then for the move-in condition of that item on the non-existent "check-in" sheet.

After some tense moments, she left. Then I went to the library to write a pre-emptive letter for my friend to get the landlord to see why I was right and she would have to give back the whole deposit. It's included below, and you may copy it freely for personal use in saving your own security deposit from greedy slumlords.


A couple of weeks later, my friend received a refund from the landlord minus just one deduction, $149 for the landlord's freezer that was stolen from the garage earlier in the year. I'm certain that without my first letter laying out the legal analysis, there would have been many more deductions.

That last $149 still bothered him because he believes the thief was the landlord's son, or someone to whom the landlord gave keys, and because they also stole gear from his truck the same night. So it was up to me to secure return of that last amount, and I had reserved some of my ammo for just such an occasion.

Here is my second letter to the landlord, wherein I prove that white is black, and black is white, according as I am paid. You may freely copy it for personal use in recovering your own security deposit.




(I should also metion that between these two letters, I laid a small trap for the landlord should she have made any deductions for cleaning. Montana law states that before any cleaning charges can be deducted from a deposit, the landlord must give the tenant 24 hours to perform that cleaning himself, in order to avoid charges. I knew that she had already promised the house to another tenant on the same day my friend's lease was to expire, and that even if she knew about that statute, she would not have wanted to go through the inconvenience of following it. If she didn't follow it, then any charges for cleaning would have been easy to recover in court, plus additional damages for intentionaly disobeying the law. In any case, this landlord never made a deduction for cleaning charges.)

The day before my deadline given in the second letter, my friend received this from the landlord, along with a check for $149.00.

I am in receipt of your letter dated August 23, 2006 stating that the freezer was taken from a locked garage, yet you stated to me last fall that the garage door was not locked and that you did not report the freezer theft to the police. Therefore, the freezer theft was due to your failure to lock the garage, and amounts to damage. The refrigerator you offered to leave behind did not include a freezer with similar capacity to the lost freezer. A judge with common sense would agree that you are responsible for the replacement freezer cost. Be that as it may, it is not worth my time to further address this matter, and am enclosing a check for $149.00, the cost of the freezer which was withheld from the deposit.


It's clear from her letter that the landlord still thinks she's right about the freezer, but probably sees that she is wrong about everything else and therefore won't take her chances in court.

Granted, my friend should not have told the landlord that he left the garage wide open, and I wish my friends would consult me by cellphone before making damaging public statements. However, even allowing that he might have left the door open, we would need to debate whether that consituted any comparative negligence in a quiet Missoula neighborhood, and even if it did, my friend's omission was not the proximate cause of the freezer being stolen. The superceding and intervening cause of it's loss was solely the intentional act of an uninvited trespasser. Such a criminal act would break any chain of causation caused by acts or omissions of my client, and render my client not legally responsible for the loss.

An uninvited trespasser could have just as easily set the whole garage on fire, and by the same reasoning, the landlord would not be able to charge the smoking pile of debris against my friend's deposit.

Though there's a small chance she's right about the freezer (very small, don't bet on it), she's almost certainly wrong on the other items mentioned in my second letter which could cause her losses upwards of $3,000.00. That's why it's good to have many arguments, as long as each is strong.

Since this landlord also happened to be a (non-practicing) lawyer, she could recognize her risk, and also her disadvantage in being held to a higher standard regarding knowledge of landlord-tenant law.

If your landlord is just some old codger who doesn't consult lawyers and goes on just as he did in feudal times before tenant protection laws existed, then you might really have to sue him. And you should. It will help improve the quality of landlords and their business practices in your area.

Actually, I am sad that Landlord did not take us on. I was looking forward to splitting the take with my friend, 90% for me and 10% for him.

Friday, September 08, 2006

Windows Key to access Ubuntu Start Menu

I was so used to using the Windows Key on the keyboard to open the Windows Start menu, I just expect it to work on Gnome panels too.

If you don't already have an Ubuntu "Main Menu" item on your panel, you can add one by right clicking on the panel, choose "Add to Panel," then scroll down to "Utilities" and click the "Menu Bar" item and then the "Add" button. If you want to move that item around on your panel, you can figure out how to do that by right clicking it.

Now to bind the Windows Key to that item. Click your panel's "Main Menu" item, then "System," "Preferences," and "Keyboard Shortcuts." Under the "Desktop" group, click "Show the Panel Menu," then press your Windows Key and you will see the associated binding change to "Super_L". Click the "Close" button on this dialogue and you are done.

Now when you hit your Windows Key, it opens the Main Menu, equivalent to the Windows Start button.

Thursday, September 07, 2006

Stop gnome-terminal screen clear

Gnome-terminal (and Mac OSX Terminal.app) clears your screen when you quit a pager or editor and I don't like it. You won't like it either if you need to refer to the thing you were just looking at after you exit back to shell. This happens with man, less, more, pico, vi and others.

Here's an example of gnome-terminal automatically clearing the screen when exiting a pager. This is what needs fixing:



Here's what it does after we fix it. No more automatic clearing:



I used to fix this problem easily in the MUD by setting an environment variable: setenv NO_CLEAR 1

But Ubuntu Dapper is no LPMUD. I searched Google for the fix. Other people had the same complaint. The best source of synthesized info I found was here.

That writer, Akkana, understood the problem and offers some solutions for everything except gnome-terminal:
"...there's no way to tell gnome-terminal to disable the alt screen behavior."
I eventually found my own solution to fix gnome-terminal that I'll share at the end of this post, but first I want to review Akkana's, since her site doesn't accept comments.

First, she correctly identifies that gnome-terminal is the source of my problem. I confirmed that by dropping out of X to a real console (CNTRL+ALT+F2), logging into my shell, and checking my TERM environmental variable:
echo $TERM
On a console, that returns "linux," and quitting any pager on a console leaves the paged info on my screen the way I want it. While in X (CNTRL+ALT+F7 to get back to X), using gnome-terminal, the $TERM variable is "xterm."

This means that I can't solve this problem under X in a way that will break my console. How limiting.

Akkana offered 3 ideas and I tried them all. The first was to create a file in my home directory called .Xdefaults (symlinked to .Xresources, just in case) that contains these lines:
XTerm*titeInhibit: true
xterm*titeInhibit: true
gnometerminal*titeInhibit: true
gnome-terminal*titeInhibit: true
and then launch new terminals both in the real xterm program and in gnome-terminal. Through trial and error, I determined that only the 2nd line above had any effect, and it only stopped screen clearing in the xterm program. That problem persisted in gnome-terminal.

If I would just use xterm, my work would be done. But I do not like xterm.

Akkana's next suggestion is to create a ~/terminfo/xtermnoalt.terminfo file and export a TERM for it into the bash environment. She provides the file, doctored xterm-color terminfo data, but with the ti/te and rmcup screen clearing bits removed. Without those, gnome-terminal is supposed to be tricked into never trying to use those features.

It sort of works, but causes an extra prompt warning that my terminal is broken:
~$ man man
Reformatting man(1), please wait...
WARNING: terminal is not fully functional
- (press RETURN)
I can hit RETURN and get the pager normally after that, and when I quit, my screen does not get cleared, but that broken warning is more irritating than the original problem.

The 'man' utility ultimately uses 'less' to do its paging, and 'less' is actually the program emitting that warning. Even though I always use 'more' instead of 'less,' and 'more' still works fine, I look at man files a lot, and I am not satisfied with these results.

Technically, I could go a bit further and just hack a fix for man. The man file on man (in the --pager option) says that man uses /usr/bin/pager for paging, and that's just a symlink to /etc/alternatives/pager, which is itself another symlink to /usr/bin/less. So I could change that last symlink to /bin/more and then 'man' and 'more' would work fine. But that is a crummy hack that still leaves pico (actually /bin/nano) totally broken:
~$ pico -w sdsd
Error opening terminal: xterm-noalt.
And I use pico a lot, so I'm still unsatisfied.

Akkana's last idea is to use a command option to 'less' to ignore terminal initializations, and yes, I could make an alias for that in ~/.bashrc so that I don't have to remember to type it (alias less='less -X') but pico would still be broken, and you know I need pico.

So I searched around the web trying to learn about termcap and terminfo. And that was hard. So instead, I downloaded all the other terminal emulators I could find, hoping to just dump gnome-terminal (apt-get install pterm aterm eterm multi-gnome-terminal konsole). I tried and hated them all.

In the end, I just got out my sledge hammer and did this:
mv /lib/terminfo/x/xterm /lib/terminfo/x/xterm.orig
ln -s /lib/terminfo/v/vt220 /lib/terminfo/x/xterm
That moves the original xterm definition out of the way, and symlinks the vt220 definition in its place. Vt220's do not do the "alternate screen" feature that makes your page disappear.

This fixes Gnome-terminal which is now being fed a vt220 definition that it thinks is xterm. Really, gnome-terminal should give users a way to turn off the annoying screen clearing feature. You and I are not the only ones that find it a nuisance.

[A reader later posted a much better solution in the Comments that uses infocmp and tic to "fix" the terminfo definition file used by the terminal program. URLs at the end of the Conclusion section.]

If you want to know how I came up with this elegant solution, I just did a 'man terminfo' (lots of websites said this was caused by "terminfo") and at the top of the page it said, "Synopsis: /etc/terminfo/*/*," so I looked in there (ls -l /etc/terminfo) and found a single README file which said that if this directory is empty, ncurses (the library in charge of cursors and terminal-like things) would look in /lib/terminfo/*/*. Looking there, I found all the term definitions and figured one of them would be without silly rmcup. Symlinking by trial and error, I found one that worked.

Conclusion

You can fix your broken gnome-terminal emulator by tampering with the terminfo definition files, and get gnome-terminal to swallow vt220 terminfo that is intentionally mislabelled xterm.

Nay-sayers may point out that vt220 is not the same as xterm and that this could cause other problems, but I haven't noticed any. If there are, they should be less annoying than xterm's rmcups screen clearing. I'm not worried. Vt220's don't have any "dangerous modes" such as those from a vt100 that can lock up a vt220's output to "line printer."

The worst result I've seen from this switch, after using it for 10 minutes, is that the X-mouse won't work in console programs like sysv-rc-conf anymore, because it's designed for an xterm, not a vt220. No big deal.

If you really hate my idea, there may be, after all, some X resources in gnome-terminal for which ti/te can be inhibited that would fix the original problem, but I don't know what else they might be called. I suppose one could read the gnome-terminal source, or email the developer, if one were (subjunctive, condition contrary to fact) very determined.

I do wish gnome-terminal had a few more user-configurable items in its menus. But at least it has a menu. Really, I'm sad that since I said goodbye to Windows, I don't have VanDyke's SecureCRT anymore.

My psychiatrist says that I should just run it under wine.

Benjamin's Reader Comments provided a real solution that fixes the whole problem correctly, rebuilding a custom terminfo definition file:

toward the end or reprinted on his own site.

This solution also works great on Apple OSX in Terminal.app. In my case, on the Mac, I am using the "Homebrew" Terminal profile, which uses xterm-color, so that is the terminal definition that I customized:

infocmp > ~/xterm-color-noclear.src
pico xterm-color-noclear.src
mkdir .terminfo
tic xterm-color-noclear.src
export TERM=xterm-color-noclear
pico .bashrc