PHP – Handling Invoices with Timestamps

billingPHPproject-managementtime stamp

I'm currently going to write something to automatically create invoices with cronjobs by using PHP and timestamps.

I have a, for me, well-considered idea of how to solve it, but I want to ask the community if someone may see errors in reasoning and possible problems with my solution.

I'm trying to describe my idea as detailed as possible so everyone can follow my way of thinking:

In General there are 4 types of invoices:

  1. Paid yearly
  2. Paid semiyearly
  3. Paid quarterly
  4. Paid monthly

Purchased products are saved in a SQL database with the billing cycle:

  • ID of User
  • Product ID
  • Billing Cycle
  • Last Due Date

Now there is a cronjob that runs once a day to check if it should create a new invoice for each purchased product. In the row Last Due Date I save the timestamp of the first date to pay when it's created.

A code I already wrote calculates the time that has gone by since the Last Due Date timestamp and outputs something like this:

  • Timestamp is in past or in future
  • Month gone by
  • Days gone by

Now my rules for creating a new invoice are:

  1. Paid yearly

    if ( Timestamp is in past = true AND Month gone by = 11 AND Days gone by >= 20 )

    then ( create a new invoice and set "Last Due Date" to time() )

  2. Paid semiyearly

    if ( Timestamp is in past = true AND Month gone by = 5 AND Days gone by >= 20 )

    then ( create a new invoice and set "Last Due Date" to time() )

  3. Paid quarterly

    if ( Timestamp is in past = true AND Month gone by = 3 AND Days gone by >= 20 )

    then ( create a new invoice and set "Last Due Date" to time() )

  4. Paid monthly

    if ( Timestamp is in past = true AND Month gone by = 0 AND Days gone by >= 20 )

    then ( create a new invoice and set "Last Due Date" to time() )

As you can see a new invoice would be created ~10 days before date of payment and the timestamp in Last Due Date is set to the current time, so when the cronjob checks back the next day no invoice will be created for this purchased product.

My question is if this is an appropriate way of solving this and if you can see any errors in reasoning or problems that may occur?

Best Answer

The biggest thing that I see is missing is keeping track of what the user has actually paid. Some people pay an amount more or less than the amount due, so some may have a balance due from the last invoice while others may have pre-paid for several periods ahead.

EDIT: Based upon your comment, I see this is handled seperately, great!

The other thing I see is the way you are handling the TIMESTAMP field. For example:

Paid monthly

if ( Timestamp is in past = true AND Month gone by = 0 AND Days gone by >= 20 )

then ( create a new invoice and set "Last Due Date" to time() )

Suppose I initially signed up on 1/1/2012, then Timestamp starts off with that date. Assuming I pay monthly, this will mean you generate an invoice on 1/20/2012 and set the Timestamp to 1/20/2012. Does this mean you generate an invoice every 20 days rather than once per month? In other words will you generate an invoice on 2/9/2012 (20 days after 1/20/2012)?

The point is that the next invoice should be generated based upon the end date of the current billing period, not the date the invoice was generated.

Currently you "set "Last Due Date" to time()", perhaps you want to set Last Due Date to the first day of the next billing period? So for example when generating monthly invoices on 1/20/2012 you would change 1/1/2012 (current value in DB) to 2/1/2012. You don't state which database you are using, but many have built-in functions to add 1 month, quarter, year etc.

Related Topic