Created
July 27, 2011 14:47
-
-
Save stefanoverna/1109504 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- encoding : utf-8 -*- | |
class Invoice < ActiveRecord::Base | |
paginates_per 15 | |
belongs_to :campaign | |
has_and_belongs_to_many :tasks | |
has_many :expense_notes | |
validates_presence_of :campaign | |
validates_presence_of :start_date | |
validates_presence_of :end_date | |
validates_presence_of :expiration_period | |
validate :validate_end_date | |
validate :invalid_invoice_period | |
validate :intersecting_invoices | |
validate :presence_of_non_invoiced_good_hours_in_some_task | |
before_validation :set_start_date_if_blank | |
after_create :invoice_tasks | |
after_create :invoice_expense_notes | |
def tasks_hours | |
tasks.inject(0) do |hours, task| | |
hours + task.total_good_hours_in_period(:do_not_invoice, start_date, end_date) | |
end | |
end | |
def tasks_amount | |
invoiced_hours * campaign.try(:hourly_price) | |
end | |
def expense_notes_amount | |
expense_notes.inject(0) do |amount, expense_note| | |
amount + expense_note.amount | |
end | |
end | |
def amount | |
tasks_amount + expense_notes_amount | |
end | |
private | |
######### BEFORE VALIDATION ######### | |
def set_start_date_if_blank | |
if start_date.blank? | |
self.start_date = if campaign.invoices.blank? | |
campaign.activities.minimum(:estimated_start_date) | |
else | |
campaign.invoices.maximum(:end_date).advance(:days => 1) | |
end | |
end | |
end | |
######### VALIDAZIONI ########### | |
def presence_of_non_invoiced_good_hours_in_some_task | |
# perche possa creare una fattura | |
if campaign.present? | |
# almeno uno tra i task della campagna | |
campaign.activities.map(&:tasks).flatten.any? do |task| | |
# deve avere qualche ora da fatturare nel periodo della fattura stessa | |
task.total_good_hours_in_period(:do_not_invoice, start_date, end_date).nonzero? | |
end | |
end | |
end | |
def validate_end_date | |
# la data di inizio fattura dev'essere precedente a quella di fine | |
if start_date.present? && end_date.present? && end_date < start_date | |
errors.add :end_date, I18n.t("activerecord.errors.models.contract.attributes.end_date.lower_than_start_date") | |
end | |
end | |
def invalid_invoice_period | |
if end_date.present? && start_date.present? && campaign.present? && campaign.activities.present? | |
# la data di inizio fattura dev'essere superiore alla data di inizio campagna | |
if start_date < campaign.activities.minimum(:estimated_start_date) | |
errors.add :start_date, I18n.t("activerecord.errors.models.invoice.attributes.start_date.lower_than_campaign_start") | |
# la data di termine fattura dev'essere inferiore o uguale alla fine campagna | |
elsif end_date > campaign.activities.maximum(:estimated_end_date) | |
errors.add :end_date, I18n.t("activerecord.errors.models.invoice.attributes.end_date.greater_than_campaign_end") | |
end | |
end | |
end | |
def intersecting_invoices | |
# non posso avere due fatture con periodo di appartenenza intersecante | |
if start_date.present? && campaign.present? && campaign.invoices.present? && start_date <= (campaign.invoices - self).max(:end_date) | |
errors.add :end_date, I18n.t("activerecord.errors.models.invoice.attributes.end_date.lower_than_previous") | |
end | |
end | |
########## AFTER CREATE ########### | |
def invoice_tasks | |
campaign.activities.map(&:tasks).flatten.each do |task| | |
if task.total_good_hours_in_period(:do_not_invoice, start_date, end_date).nonzero? | |
task.invoices << self | |
end | |
end | |
end | |
def invoice_expense_notes | |
campaign.activities.map(&:expense_notes).each do |expense_note| | |
if expense_note.spending_date <= end_date && expense_note.spending_date >= start_date | |
self.expense_notes << expense_note | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment