# frozen_string_literal: true # Provides methods for accessing Invoices resources and properties class InvoicesService # return a paginated list of invoices, ordered by the given criterion and optionally filtered # @param order_key {string} any column from invoices or joined a table # @param direction {string} 'ASC' or 'DESC', linked to order_key # @param page {number} page number, used to paginate results # @param size {number} number of items per page # @param filters {Hash} allowed filters: number, customer, date. def self.list(order_key, direction, page, size, filters = {}) invoices = Invoice.includes(:avoir, :invoicing_profile, invoice_items: %i[subscription invoice_item]) .joins(:invoicing_profile) .order("#{order_key} #{direction}") .page(page) .per(size) if filters[:number].size.positive? invoices = invoices.where( 'invoices.reference LIKE :search', search: "#{filters[:number]}%" ) end if filters[:customer].size.positive? # ILIKE => PostgreSQL case-insensitive LIKE invoices = invoices.where( 'invoicing_profiles.first_name ILIKE :search OR invoicing_profiles.last_name ILIKE :search', search: "%#{filters[:customer]}%" ) end unless filters[:date].nil? invoices = invoices.where( "date_trunc('day', invoices.created_at) = :search", search: "%#{DateTime.iso8601(filters[:date]).to_time.to_date}%" ) end invoices end # Parse the order_by clause provided by JS client from '-column' form to SQL compatible form # @param order_by {string} expected form: 'column' or '-column' def self.parse_order(order_by) direction = (order_by[0] == '-' ? 'DESC' : 'ASC') key = (order_by[0] == '-' ? order_by[1, order_by.size] : order_by) order_key = case key when 'reference' 'invoices.reference' when 'date' 'invoices.created_at' when 'total' 'invoices.total' when 'name' 'profiles.first_name' else 'invoices.id' end { direction: direction, order_key: order_key } end end