# Recurring Invoice Logic

**URL:** <https://www.ruby-forum.com/t/recurring-invoice-logic/133195>\
**Category:** Rails\
**Created:** [March 28, 2008, 5:00pm UTC](https://www.ruby-forum.com/t/recurring-invoice-logic/133195 "2008-03-28T17:00:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![keaja](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/838e76/32.png) [@keaja](https://www.ruby-forum.com/u/keaja)\
**Post date:** [March 28, 2008, 5:00pm UTC](https://www.ruby-forum.com/t/recurring-invoice-logic/133195/1 "2008-03-28T17:00:01Z")

</div>

Never done recurring invoices before so wondering if this logic makes  
sense:

Cron job runs at 4am each night and runs some ruby like this:

pseudocode:

For Each Invoice.due\_date == Date.today  
Invoice.new(:due\_date =\> Date.today + 30)  
Invoice.Save  
End

---

<div class="post-metadata">

**Author:** ![keaja](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/838e76/32.png) [@keaja](https://www.ruby-forum.com/u/keaja)\
**Post date:** [March 31, 2008, 8:32am UTC](https://www.ruby-forum.com/t/recurring-invoice-logic/133195/2 "2008-03-31T08:32:41Z")

</div>

Yeah, running a nightly cron job to create invoices make plenty of  
sense.

---

<div class="post-metadata">

**Author:** ![keaja](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/838e76/32.png) [@keaja](https://www.ruby-forum.com/u/keaja)\
**Post date:** [March 31, 2008, 4:41pm UTC](https://www.ruby-forum.com/t/recurring-invoice-logic/133195/3 "2008-03-31T16:41:58Z")

</div>

This sounds good. Although for clarity, you might use “generated\_date”  
in addition to “due\_date”. It seems odd to have the date the invoice  
is due is the date it’s created. (actually, the created\_at would be  
the generated date so it’s probably redundant)

I would keep the logic of an “Invoice” separate from a “Schedule”. So  
maybe you have a ScheduleInvoice object that holds a “next\_run” field.  
Then, to add an invoice to the system, you’d create a new  
ScheduleInvoice object and set the next\_run field to be when it should  
be generated (or if generated when created, then the next\_run would be  
a month later).

I could see, then, some simple code running in a cron:

ScheduleInvoice.find\_all\_by\_next\_run(Date.today).each do |schedule|  
invoice = Invoice.new(:due\_date =\> 30.days.from\_now)  
if invoice.save  
schedule.next\_run = 1.month.from\_now  
else  
# handle the failure  
end  
end

At least, that’s how I’d do it. In fact, I’ll need to soon for a  
project I’m building. Good to think through this a little.

-Danimal

---

<div class="post-metadata">

**Author:** ![keaja](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/838e76/32.png) [@keaja](https://www.ruby-forum.com/u/keaja)\
**Post date:** [March 31, 2008, 4:58pm UTC](https://www.ruby-forum.com/t/recurring-invoice-logic/133195/4 "2008-03-31T16:58:32Z")

</div>

Your idea of a next\_run is exactly what I needed. I built a cron job  
and it is working but I was afraid of having redundant invoices made  
incase, for some reason the cron job ran twice a day or something.  
This is what my cron job looks like below but I think I will alter it  
to include some next\_run logic.

@invoices = Invoice.find(:all)  
@invoices.each do |invoice|  
if invoice.due\_date == Date.today # and the user does not have  
an invoice due in 30 days  
@invoice = Invoice.new  
@invoice.generated\_date = Date.today  
@invoice.amount = “14.95”  
@invoice.due\_date = 1.month.from\_now  
@invoice.status = “Due”  
@invoice.user\_id = invoice.user\_id  
@invoice.save  
puts “Invoice #{@invoice.id} created for #  
{invoice.user.first\_name} #{invoice.user.last\_name} due #  
{@invoice.due\_date}”  
end  
end

Thanks

Jason

On Mar 31, 2008, at 7:40 AM, Danimal wrote:

This sounds good. Although for clarity, you might use “generated\_date”  
in addition to “due\_date”. It seems odd to have the date the invoice  
is due is the date it’s created. (actually, the created\_at would be  
the generated date so it’s probably redundant)

I would keep the logic of an “Invoice” separate from a “Schedule”. So  
maybe you have a ScheduleInvoice object that holds a “next\_run” field.  
Then, to add an invoice to the system, you’d create a new  
ScheduleInvoice object and set the next\_run field to be when it should  
be generated (or if generated when created, then the next\_run would be  
a month later).

I could see, then, some simple code running in a cron:

ScheduleInvoice.find\_all\_by\_next\_run(Date.today).each do |schedule|  
invoice = Invoice.new(:due\_date =\> 30.days.from\_now)  
if invoice.save  
schedule.next\_run = 1.month.from\_now  
else  
# handle the failure  
end  
end

At least, that’s how I’d do it. In fact, I’ll need to soon for a  
project I’m building. Good to think through this a little.

-Danimal
