Presentation given by Martin Kleppmann at Rails Underground in London on 24 July 2009. Gives an overview of how to develop a commercial B2B SaaS web app using Rails or other Ruby web frameworks, including best practices of structuring accouting data.
20. Ruby Invoicing
Framework
So… youʼve spent many nights developing your awesome application. Itʼs coming together
nicely, and youʼve showed it to your friends, who got very excited about it too. In fact,
people love your app so much that they are willing to pay you money to use it. Great news!
Keeping it simple, you start taking payments trough PayPal or even accept cheques
through the post. Later you maybe integrate with the API of a more flexible credit card
handling provider. Money is coming in – even better news!
The problems become apparent when you try to turn your app into a business. Suddenly
everything becomes a lot more complicated. You need to start thinking about ugly things
like tax and you need to pay an accountant to sort out the paperwork for you. You need to
start bookkeeping, a prospect which gives you the shivers. Maybe some of your customers
are awkward, accepting billing only in their own currency or requiring a special tax status.
Itʼs all a bit of a mess, and as you grudgingly start ploughing through the Wikipedia page on
“credits and debits”, you wish that you could just get the money and leave it at that.
The missing link between your app and the money
Enter the Ruby Invoicing Framework RubyGem, or invoicing gem for short. Itʼs a collection
21. Ruby Invoicing
Framework ic in g/
/invo
m
So… youʼve spent many nights developing your awesome application. Itʼs coming together
co
nicely, and youʼve showed it to your friends, who got very excited about it too. In fact,
u b.
people love your app so much that they are willing to pay you money to use it. Great news!
t.gith
Keeping it simple, you start taking payments trough PayPal or even accept cheques
p
through the post. Later you maybe integrate with the API of a more flexible credit card
//e
handling provider. Money is coming in – even better news!
tt p:
The problems become apparent when you try to turn your app into a business. Suddenly
h
everything becomes a lot more complicated. You need to start thinking about ugly things
like tax and you need to pay an accountant to sort out the paperwork for you. You need to
start bookkeeping, a prospect which gives you the shivers. Maybe some of your customers
are awkward, accepting billing only in their own currency or requiring a special tax status.
Itʼs all a bit of a mess, and as you grudgingly start ploughing through the Wikipedia page on
“credits and debits”, you wish that you could just get the money and leave it at that.
The missing link between your app and the money
Enter the Ruby Invoicing Framework RubyGem, or invoicing gem for short. Itʼs a collection
30. Model classes
module Billing
class Invoice < LedgerItem
acts_as_invoice
end
class CreditNote < LedgerItem
acts_as_credit_note
end
class Payment < LedgerItem
acts_as_payment
end
end
49. Invoice ≠ Payment
Your Sales Account
Customer Account
Your Bank Account
50. Invoice ≠ Payment
Your Sales Account
–
Invoice
+
Customer Account
Your Bank Account
51. Invoice ≠ Payment
Your Sales Account
–
Invoice
+
Customer Account
–
Payment
+
Your Bank Account
52. Account statement
No. Date Description Amount
100 2009-06-01 Subscription for June £115.00
101 2009-06-24 Referral fee – thanks for inviting 3 friends –£10.00
102 2009-06-30 Credit card payment including PAYG credit –£200.00
Current account balance (GBP) –£75.00
Charges not yet invoiced
Description Amount
Pay As You Go charges so far this month £23.45
53. Account statement Invoice
No. Date Description
Credit Note
Amount
100 2009-06-01 Subscription for June Payment
£115.00
101 2009-06-24 Referral fee – thanks for inviting 3 friends –£10.00
102 2009-06-30 Credit card payment including PAYG credit –£200.00
Current account balance (GBP) –£75.00
Invoice
Charges not yet invoiced
(with status=open)
Description Amount
Pay As You Go charges so far this month £23.45
54. Account statement
class BillingController < ApplicationController
def statement
scope = Billing::LedgerItem.
exclude_empty_invoices.
sent_or_received_by(params[:id]).
sorted(:issue_date)
@in_effect = scope.in_effect.all
@open_or_pending = scope.open_or_pending.all
@summary = Billing::LedgerItem.account_summary(
params[:id])
end
end
84. UBL: If you’re working with
invoices and purchase orders
and that kind of stuff (and who
isn’t?) [...] Look no further.
@timbray: “Don’t Invent XML Languages”
http://tr.im/NoNewXML
87. UBL Example (3/3)
<cac:InvoiceLine>
<cbc:ID>42</cbc:ID>
<cbc:LineExtensionAmount currencyID="GBP">
100.00
</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>
Subscription for my fantastic app
</cbc:Description>
</cac:Item>
</cac:InvoiceLine>
</ubl:Invoice>
88. Designing XML Languages is
hard. It’s boring, political, time-
consuming, unglamorous,
irritating work.
@timbray: “Don’t Invent XML Languages”
http://tr.im/NoNewXML
93. OAccounts
=
UBL + XBRL-GL ts. REST+ or g/ +
Conventionsco un +
://o ac
ht tp
Documentation +
Collaboration +
Open source implementation
94. Image credits
Screenshots of:
http://basecamphq.com/signup, http://freshbooks.com/pricing.php, http://fogcreek.com/FogBugz/,
http://github.com/plans, http://lessaccounting.com/pricing, http://freeagentcentral.com/pricing,
http://huddle.net/huddle-price-plans/, http://twitter.com/bensummers/status/1199722134,
http://oneis.co.uk/, http://bidforwine.co.uk
Building site: Richard Messenger, http://www.flickr.com/photos/richardmessenger/2626927255/
Tim Bray: http://en.wikipedia.org/wiki/File:Tim_Bray.jpg
Pile of money: Johnny Vulkan, http://www.flickr.com/photos/26614375@N00/381941029/
Astronomical clock: magro_kr, http://www.flickr.com/photos/8704943@N07/3491779722/
Tax Service: Thomas Hawk, http://www.flickr.com/photos/thomashawk/2317826708/
Man in a shop: Paolo Màrgari, http://www.flickr.com/photos/paolomargari/3050305454/
Hands full of money: Marshall Astor, http://www.flickr.com/photos/lifeontheedge/2672465894/
95. Thank you!
Martin Kleppmann
http://go-test.it
http://yes-no-cancel.co.uk
http://twitter.com/martinkl