module Comee module Core class Invoice < ApplicationRecord ADVANCE = "Advance".freeze DELIVERY = "Delivery".freeze DIRECT = "Direct".freeze INVOICE_TYPES = [ADVANCE, DELIVERY, DIRECT].freeze before_validation :generate_invoice_no, if: proc { |inv| inv.invoice_no.nil? } before_save :calculate_due_date, unless: proc { |inv| inv.date_issued.nil? } belongs_to :sales_order belongs_to :pod, optional: true belongs_to :invoice_address, -> { where(address_type: ClientAddress::INVOICING_ADDRESS) }, class_name: "Comee::Core::ClientAddress" has_many :invoice_items has_many :additional_items has_many :payments has_noticed_notifications model_name: "Comee::Core::Notification" enum :status, {draft: 0, approved: 1, issued: 2} enum :payment_status, {not_paid: 0, partially_paid: 1, fully_paid: 2, overpaid: 3} validates :invoice_no, uniqueness: {case_sensitive: false} validates :status, :payment_status, presence: true validates :total_price, numericality: {greater_than_or_equal_to: 0, allow_nil: true} validates :amount_paid, numericality: {greater_than_or_equal_to: 0, allow_nil: true} validates :pct_advanced, presence: true, numericality: {greater_than: 0, less_than_or_equal_to: 100}, if: -> { advance? } validates :pct_advanced, absence: true, if: -> { delivery? || direct? } validates :pod_id, presence: true, if: -> { delivery? } validates :pod_id, absence: true, if: -> { advance? } delegate(:order_number, to: :sales_order, prefix: false) delegate(:reference_no, to: :pod, prefix: true, allow_nil: true) def delivery? invoice_type == DELIVERY end def advance? invoice_type == ADVANCE end def direct? invoice_type == DIRECT end def calculate_total_price self.total_price = calculate_total end def calculate_vat return unless sales_order.client.tax_code == "Inland" self.vat = (calculate_total * 0.19).round(2) end def calculate_due_date self.due_date = date_issued + 30.days end def calculate_total items = InvoiceItem.where(invoice_id: id) additionals = AdditionalItem.where(invoice_id: id) total = (items.sum(:total_price) + additionals.sum(:total_price)) total *= (pct_advanced / 100) if advance? total.round(2) end def calculate_amount_paid payments = Payment.where(invoice_id: id) payments.sum(:amount) end def self.ransackable_attributes(_auth_object = nil) %w[ id sales_order_id invoice_no invoice_type date_issued ship_name delivery_date voyage_no status payment_status ] end def self.ransackable_associations(_auth_object = nil) ["sales_order"] end def generate_invoice_no year = Date.current.year.to_s self.invoice_no = Util.generate_number("Invoice", "invoice_no", year, "-", 100001) end end end end