class Order include SimplyStored::Couch include ActiveModel::SerializerSupport property :state, default: 'placed' # placed, active, delivered, cancelled, closed belongs_to :list belongs_to :user belongs_to :supplier belongs_to :section belongs_to :table belongs_to :employee has_many :product_orders, dependent: :destroy #has_many :products, through: :product_orders validates :supplier_id, presence: true view :active_for_supplier_view, type: :custom, map_function: %[function(doc){ if(doc.ruby_class == 'Order' && (doc.state == 'placed' || doc.state == 'active')){ emit([doc.supplier_id, doc.list_id], 1); } }], reduce_function: '_sum' view :active_for_supplier_and_section_view, type: :custom, map_function: %[function(doc){ if(doc.ruby_class == 'Order' && (doc.state == 'placed' || doc.state == 'active')){ emit([doc.supplier_id, doc.section_id], 1); } }], reduce_function: '_sum' view :by_supplier_id_and_id, key: [:supplier_id, :_id] # Do not comment me out this is for security, TODO: make the security server side for speed and space optimization view :by_supplier_id_and_state, key: [:supplier_id, :state], reduce_function: '_sum' def self.for_supplier(supplier, options = {}) total_entries = database.view(by_supplier_id_and_id({startkey: ["#{supplier.id}\u9999"], endkey: [supplier.id], include_docs: false, reduce: true, descending: true})) options[:total_entries] = total_entries with_pagination_options(options) do |options| database.view(by_supplier_id_and_id({startkey: ["#{supplier.id}\u9999"], endkey: [supplier.id], include_docs: true, reduce: false, descending: true}.merge(options))) end end # Return all currently active orders for a given supplier def self.active_for_supplier(supplier_id) database.view(active_for_supplier_view(startkey: [supplier_id], endkey: [supplier_id, {}], reduce: false, include_docs: true)) end # Return all currently active orders for a given supplier and list def self.active_for_supplier_and_list(supplier_id, list_id) supplier_id = supplier_id.id if supplier_id.is_a?(SimplyStored::Couch) list_id = list_id.id if list_id.is_a?(SimplyStored::Couch) database.view(active_for_supplier_view(key: [supplier_id, list_id], reduce: false, include_docs: true)) end def self.count_active_for_supplier_and_list(supplier_id, list_id) supplier_id = supplier_id.id if supplier_id.is_a?(SimplyStored::Couch) list_id = list_id.id if list_id.is_a?(SimplyStored::Couch) database.view(active_for_supplier_view(key: [supplier_id, list_id], reduce: true, include_docs: false)) end # Return all currently active orders for a given section def self.active_for_supplier_and_section(supplier, section_id) supplier_id = supplier.is_a?(SimplyStored::Couch) ? supplier.id : supplier section_id = section_id.id if section_id.is_a?(SimplyStored::Couch) database.view(active_for_supplier_and_section_view(key: [supplier_id, section_id], reduce: false, include_docs: true)) end def table_number list.table_number end alias table_nr table_number def placed? state == 'placed' end def active? state == 'active' end def is_being_processed! self.state = 'active' if save orders_in_process_count = supplier.increment_orders_in_process_count! orders_placed_count = supplier.decrement_orders_placed_count! for user_id in list.user_ids broadcast_user user_id, 'order_being_processed', id: id, list_id: list_id broadcast_user user_id, 'orders_in_process_count', count: orders_in_process_count broadcast_user user_id, 'orders_placed_count', count: orders_placed_count end broadcast_supplier supplier_id, 'order_being_processed', id: id, list_id: list_id broadcast_supplier supplier_id, 'orders_in_process_count', count: orders_in_process_count broadcast_supplier supplier_id, 'orders_placed_count', count: orders_placed_count end end def is_delivered! decrement_counter = placed? ? 'placed' : 'in_process' self.state = 'delivered' if save reduced_count = supplier.public_send "decrement_orders_#{decrement_counter}_count!" for user_id in list.user_ids broadcast_user user_id, 'order_being_delivered', id: id, list_id: list_id broadcast_user user_id, "orders_#{decrement_counter}_count", count: reduced_count end broadcast_supplier supplier_id, 'order_being_delivered', id: id, list_id: list_id broadcast_supplier supplier_id, "orders_#{decrement_counter}_count", count: reduced_count end end def cancel! original_state = state.inquiry self.state = 'cancelled' if placed? || active? if save broadcast_options = {id: id} if original_state.placed? reduced_count = supplier.decrement_orders_placed_count! broadcast_options[:orders_placed_count] = reduced_count elsif original_state.active? reduced_count = supplier.decrement_orders_in_process_count! broadcast_options[:orders_in_process_count] = reduced_count end list.broadcast_users 'order_cancelled', broadcast_options broadcast_supplier supplier_id, 'order_cancelled', broadcast_options end end def cancelled? state == 'cancelled' end #TODO fix me def close! if placed? || active? decrement_counter = placed? ? 'placed' : 'in_process' self.state = 'closed' supplier.public_send "decrement_orders_#{decrement_counter}_count!" end if save broadcast_user user.id, 'order_closed', id: id if user broadcast_supplier supplier_id, 'order_closed', id: id end end def as_json(*args) h = super.with_indifferent_access h[:id] = h[:_id] h[:table_number] = table_number h[:section_title] = list.table.section.try(:title) h end def with_products_as_json return @with_products_as_json if @with_products_as_json.present? product_orders.include_relation(:product) ho = as_json # products are depricated. It is a name for something it is not!!!!! ho[:products] = [] ho[:product_orders] = [] order_total = 0.0 for product_order in product_orders order_total += (product_order.quantity * product_order.price).round(2) ho[:products] << {name: product_order.product.name, id: product_order.product_id, number: product_order.quantity, price: product_order.price} ho[:product_orders] << {product_name: product_order.product.name, id: product_order.id, quantity: product_order.quantity, price: product_order.price} end ho[:total_amount] = order_total.round(2) @with_products_as_json = ho end end