Badminton on Rails
RSS icon Home icon
  • Easy or Hard?

    Posted on February 25th, 2009 Raymond Law No comments

    I had the following conversation with a colleague about a client project recently.

    easy_or_hard

    At that moment, it strikes me that sometimes I want the easy ones but at other times I want the hard ones. But why? After some thoughts, I concluded with:

    I want the easy ones because they are easy and quick, but annoying and boring. And I want the hard ones because they are challenging and interesting.

    I think the following matrix describes it best:

    Easy Hard
    Annoying
    • Change copy from List Users to Search Users
    • Rename the column from fee to amount
    • Change all occurrences of this to that while Replace All would be too dangerous
    • Modify all images to be half the size and with a different image format/extension
    Interesting
    • Make sure we can seamless deploy to staging and production with ease using Capistrano
    • Make changing the type field also changes the available choices for the month field in the form with javascript
    • Charge a recurring fee with PayPal and ActiveMerchant when it is not inherently built in, and with lots of PayPal docs to read
    • Style the site with HTML, CSS, SASS according to this professionally designed PSD with a lot of croppings

    Do you get the point?

    As software engineers or programmers (sometimes interchangeable terms IMO), we like to solve challenging and interesting problems, regardless of difficulties. Ideally, we like everything to be in the easy and interesting quadrant, but we certainly like (sometimes prefer because it is also challenging) things in the hard and interesting quadrant as well. We would accomplish things in these two quadrants with our fullest attention and best effort.

    Stuff that belong to the easy and annoying, and hard and annoying quadrants bore us. We naturally pay less attention and try to do them with spare time. However, they still need to be done. They become a drag.

    Now we understand the matrix, but what can we do about the drag?

    This is what I think.

    I may feel ActiveMerchant is a joy and interesting to work with, but someone else may think it is a distraction to the project and just want to settle with using Authorize.net when it is already supported by ActiveMerchant to do recurring payment.

    I may feel having to crop all images again and save them in a different format is a waste of my development time, but a photographer may actually enjoy such work and may even add a drop shadow to make the images look better.

    The difference is in the interpretation.

    Interpretation

    Different people interpret the same thing differently based on their own level of interest/time/concern, …/etc. That is a fact, not an argument.

    In software development, instead of the project manager assigning tasks to each engineer, programmer, QA, you name it, based on time, skill levels, familiarities with certain code pieces, scopes, existing client relationships, maybe, just maybe, it is better to ask each person which of the tasks they have the most interest in and then assign tasks based on level of interest. That way, each person on the team will put forth his/her best attention/effort to accomplish them.

    Potential pitfalls

    • What if none of the tasks interest me? Maybe put that person in a different project that has tasks that interest him?
    • What if many people are interested in the same task? Who gets to work on it? Maybe pair programming in which several people can participate and can have inputs?
    • If I keep picking tasks that seem easy (on the surface), would it make me look lazy?
    • If I pick several hard tasks, I may make myself too busy.

    Again, we should not be blind folded by interpretaion. I may think it is easy but someone else may think it is interesting and solve the task better. I may think it is hard but since I am so interested, I may solve it with higher efficiency, hence less time.

    The above is just a thought. I have not actually tried it to see how well the process works. However, since project management is so boring and annoying to so many people. We may as well put a different interpretation to it. It certainly is a paradigm shift in project management.

  • Moving from Typo to Wordpress

    Posted on February 23rd, 2009 Raymond Law No comments

    I recently moved my blog from Typo to Wordpress. Typo served well and it was written in Rails. However, it was more difficult to upgrade and I just don’t have enough time to maintain it and keep it up to date. So it has been running at version 4.1.1 which requires Rails 1.2.6. So a change is imminent and I found a couple resources by Stuart Johnston and Max Newell.

    Those are GREAT starts!. However, I had to modify the migration script for my Typo version (4.1.1) and the latest Wordpress version (2.7.1 at the time of this writing). Fortunately, the script is just pure SQL. That means I had to inspect the Typo and Wordpress database structures to correctly map the tables and columns between the two databases. It is not the funnest thing in the world though, but this has to be done. If you have other versions of Wordpress, I recommend you upgrade to the latest version first. That way, you don’t have to worry about Wordpress’s table structures because I already did this for you. If you are using a different version of Typo, feel free to modify this migration script and post feedback.

    Here are the steps that you need to take after grabbing the script:

    > mysqldump typo_db articles_tags tags categorizations categories contents feedback > typo.sql
    > mysql typo_db < typo.sql
    > mysql typo_db < typo_4_1_1_to_wordpress_2_7_1.sql

  • PayPal Recurring Billing with ActiveMerchant in Ruby on Rails

    Posted on February 20th, 2009 Raymond Law 42 comments

    ActiveMerchant is great and PayPal is easy to use. A lot of us already have a PayPal account for EBay. It works great in auctions where you pay once. However, ActiveMerchant currently does not support PayPal recurring billing. One requirement of a recent project is to be able to charge for a monthly or yearly subscription plan with PayPal. Therefore, I did some googling and found that Jon Baker has already extended ActiveMerchant to add this functionality using PayPal’s Name-Value Pair (NVP) API. However, as Cody Fauser pointed out, the NVP API was taken out from ActiveMerchant, so I had to implement that with PayPal’s SOAP API.

    First, download this file and put it in vendor/plugins/active_merchant/lib/active_merchant/billing/gateways/. Use the GitHub from now because maintaining a separate file download is too troublesome. Alternatively, there’s a fork on GitHub at http://github.com/rayvinly/active_merchant/.

    In your controller, after a user selects one of your subscription plan, the form goes to the checkout action:

      def checkout
        response = gateway.setup_agreement(:description => description, :return_url => return_url, :cancel_return_url => cancel_return_url)
        redirect_to gateway.redirect_url_for(response.token)
      end

    This redirects the user to PayPal so he can login and read the description you provided. After he confirms, he is redirected back to your application’s return_url, which I set it to be the complete action below. If he cancels, he is redirected back to the cancel_return_url. You can set cancel_return_url to be the plan selection page where he can choose a different plan.

    If he confirms, here’s the complete action:

      def complete
        token = params[:token]
        response = gateway.create_profile(token, :description => description, :start_date => start_date, :frequency => frequency_in_months, :amount => amount_in_dollars, :auto_bill_outstanding => true)
     
        # Save this profile_id in your transactions table.  This is used to cancel/modify the plan in the future.
        profile_id = response.params["profile_id"]
     
        if response.success?
          flash[:notice] = "Your PayPal account was successfully set up for the <strong>#{description}</strong> payment plan."
          redirect_to login_path
        else
          flash.now[:notice] = "There was a problem setting up your PayPal account for the <strong>#{description}</strong> payment plan"
          render cancel_url
        end
      end

    I default the frequency to be in months and turn on auto_bill_outstanding because that is what I need, but you can look at the file you downloaded and the PayPal documentation to see what other options are available. In particular, read these two PDFs:

    If the user wants to cancel the payment plan, a cancel action would look like:

      def cancel
        response = gateway.cancel_profile(paypal_profile_id, :note => 'Payment plan was canceled by user')
        flash[:notice] = 'You have successfully canceled your membership'
      end

    paypal_profile_id is the profile_id you saved in the complete action from above. Keeping this profile_id is very handy.

    That’s it. Enjoy making money!

    UPDATE 2009-02-04

    I updated the extension to include a credit_card hash. You will probably capture the credit card details submitted by the user in a form as in params[:credit_card], but I will just create a hash to show as an example. To make recurring payment with a credit card, just pass nil for the token (this is required, because PayPal would use the token in preference to the credit card). Pass the credit_card hash as follows:

        credit_card = Hash.new
        credit_card[:type] = 'Visa'
        credit_card[:number] = '1234567812345678'
        credit_card[:exp_month] = '07'
        credit_card[:exp_year] = '2016'
        credit_card[:cvv2] = '123'
        credit_card[:card_owner] = 'John Doe'
        response = gateway.create_profile(nil, :credit_card => credit_card, :description => description, :start_date => start_date, :frequency => frequency, :amount => amount, :auto_bill_outstanding => true)

    However, I got the famous DPRP is disabled for this merchant error message when I tested it. I did a little googling but I haven’t found the cause. There may just be something that you have to turn on in your PayPal developer account. I also read that it works for newer accounts only. But since I don’t have a need for this, I didn’t look further. If you guys know, please let me know. I will try to update the extension as soon as possible to make it work with a credit card.