lib/skr/models/invoice.rb in stockor-0.1.9 vs lib/skr/models/invoice.rb in stockor-0.2
- old
+ new
@@ -31,39 +31,41 @@
has_gl_transaction
is_order_like
has_additional_events :amount_paid_change
belongs_to :sales_order, export: true
+ belongs_to :customer_project, export: true
belongs_to :customer, export: true
belongs_to :location, export: true
+ belongs_to :pick_ticket, inverse_of: :invoice, export: true
belongs_to :terms, class_name: 'Skr::PaymentTerm', export: true
- belongs_to :pick_ticket, inverse_of: :invoice, export: true
belongs_to :billing_address, class_name: 'Skr::Address', export: { writable: true }
belongs_to :shipping_address, class_name: 'Skr::Address', export: { writable: true }
has_many :gl_transactions, :as=>:source
- has_many :lines, -> { order(:position) }, class_name: 'Skr::InvLine', inverse_of: :invoice,
- extend: Concerns::INV::Lines, export: { writable: true }
+ has_many :lines, -> { order(:position) },
+ class_name: 'Skr::InvLine', inverse_of: :invoice,
+ extend: Concerns::INV::Lines, export: { writable: true }
before_save :maybe_mark_paid
before_validation :set_defaults, on: :create
validates :customer, :location, set: true
- validate :ensure_location_matches_so
+ validate :ensure_unlocked, :ensure_location_matches_so
scope :open_for_customer, lambda{ | customer |
- where([ "customer_id=? and state != 'paid'", customer.is_a?(Customer) ? customer.id : customer ])
+ where(state: :open, customer_id: customer.is_a?(Customer) ? customer.id : customer)
}, export: true
scope :with_details, lambda { |should_use=true |
- compose_query_using_detail_view( view: 'inv_details', join_to: 'invoice_id' )
+ compose_query_using_detail_view( view: 'skr_inv_details', join_to: 'invoice_id' )
}, export: true
enum state: {
- open: 0,
+ open: 1,
paid: 5,
partial: 10
}
state_machine do
@@ -80,11 +82,12 @@
end
end
def initialize(attributes = {})
super
- self.invoice_date = Date.today
+ # date must be set, otherwise things like terms that are based off of it fail
+ self.invoice_date ||= Date.today
end
# @return [BigDecimal] total - amount_paid
def unpaid_amount
self.total - amount_paid
@@ -93,41 +96,48 @@
# @return [Boolean] is the invoice paid in full
def fully_paid?
unpaid_amount <= 0
end
+ # @return [DateTime] when the invoice is due
+ def due_date
+ self.terms.due_date_from(invoice_date)
+ end
+
+ def is_locked?
+ GlPeriod.is_date_locked?(self.invoice_date)
+ end
+
private
# attributes for GlTransaction
def attributes_for_gl_transaction
- { location: location, source: self,
- description: "INV #{self.visible_id}" }
+ { location: location, source: self,
+ description: "INV #{self.visible_id}" }
end
# set the state if the amount_paid was changed
def maybe_mark_paid
return unless amount_paid_changed?
if self.fully_paid? && self.may_mark_paid?
- self.state_event = 'mark_paid'
+ self.mark_paid
elsif self.amount_paid > 0 && self.may_mark_partial?
- self.state_event = 'mark_partial'
+ self.mark_partial
end
end
def apply_balances
return unless amount_paid_changed?
change = amount_paid - amount_paid_was
-
- Skr::Core.logger.debug "Applying payment #{amount_paid} changed: #{change}"
-
+ Lanes.logger.debug "Applying payment #{amount_paid} changed: #{change}"
return if change.zero?
-
GlTransaction.push_or_save(
owner: self, amount: change,
- debit: customer.gl_receivables_account, credit: GlAccount.default_for(:deposit_holding)
+ debit: customer.gl_receivables_account,
+ credit: GlAccount.default_for(:deposit_holding)
)
- fire_event( :amount_paid_change )
+ fire_pubsub_event( :amount_paid_change )
true
end
def set_defaults
@@ -137,21 +147,38 @@
self.sales_order = pick_ticket.sales_order
end
if sales_order
self.terms ||= sales_order.terms
+ self.form ||= sales_order.form
self.customer = sales_order.customer
self.po_num = sales_order.po_num if self.po_num.blank?
self.billing_address = sales_order.billing_address if self.billing_address.blank?
self.shipping_address = sales_order.shipping_address if self.shipping_address.blank?
- self.options.merge!(sales_order.options)
+ if self.options && sales_order.options
+ self.options.merge!(sales_order.options)
+ else
+ self.options = sales_order.options
+ end
end
+ if customer_project
+ self.customer = customer_project.customer
+ self.po_num = customer_project.po_num if self.po_num.blank?
+ end
+
if customer
- self.billing_address = customer.billing_address if self.billing_address.blank?
+ self.form ||= customer.get_form('invoice')
+ self.billing_address = customer.billing_address if self.billing_address.blank?
self.shipping_address = customer.shipping_address if self.shipping_address.blank?
end
+ end
+
+ def ensure_unlocked
+ if is_locked?
+ self.errors.add(:invoice_date, "falls on a locked GL Period")
+ end
end
def ensure_location_matches_so
if sales_order && location != sales_order.location
self.errors.add(:location, "#{location.code} must match location that order was taken on (#{sales_order.location.code})")