diff --git a/README.md b/README.md index fb9c720f..85739c2a 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Things you may want to cover: * Ruby version ruby 2.3.2p217 +* ToDo list + * System dependencies * Configuration diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cfdf857a..ddbcca66 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,4 @@ -class ApplicationController < ActionController::Base +JSONclass ApplicationController < ActionController::Base #before_action :check_installation protect_from_forgery with: :exception diff --git a/app/jobs/order_queue_processor_job.rb b/app/jobs/order_queue_processor_job.rb index 73983c7b..7727260d 100644 --- a/app/jobs/order_queue_processor_job.rb +++ b/app/jobs/order_queue_processor_job.rb @@ -5,10 +5,12 @@ class OrderQueueProcessorJob < ApplicationJob # Do something later #Order ID order = Order.find(order_id) - + + #Loop through the order stations and process the items #Execute orders and send to order stations if order - + oqs = OrderQueueStation.new + oqs.process_order(order) end end end diff --git a/app/models/assigned_order_item.rb b/app/models/assigned_order_item.rb new file mode 100644 index 00000000..b4c4b242 --- /dev/null +++ b/app/models/assigned_order_item.rb @@ -0,0 +1,13 @@ +class AssignedOrderItem < ApplicationRecord + belongs_to :order_queue_station + + def self.assigned_order_item (order, item_code, order_queue_station ) + assigned_order_item = AssignedOrderItem.new() + assigned_order_item.order = order + assigned_order_item.item_code = item_code + assigned_order_item.order_queue_station = order_queue_station + assigned_order_item.print_status = false + assigned_order_item.delivery_status = false + assigned_order_item.save + end +end diff --git a/app/models/lookup.rb b/app/models/lookup.rb index 59c220be..1784b7a7 100644 --- a/app/models/lookup.rb +++ b/app/models/lookup.rb @@ -4,17 +4,19 @@ class Lookup < ApplicationRecord {'Employee Roles' => 'employee_roles', 'Dining Facilities Status' => 'dining_facilities_status', 'Menu Item Type' => 'menu_item_type', + 'Menu Item Attribute Type' => 'menu_item_attribute_type', 'Order Type' => 'order_type', 'Order Source' => 'order_source', 'Order Status' => 'order_status', 'Order Item Status' => 'order_item_status', 'Sale Status' => 'sales_status', 'Payment Status' => 'payment_status', - 'Payment Methods' => 'payment_methods'} + 'Payment Methods' => 'payment_methods', + "Gateway Communication Type" => "gateway_communication_type"} end def self.collection_of(type) - Lookup.select("name, value").where("lookup_type" => type ).map { |l| [l.name, l.value] } + Lookup.select("name, value").where("lookup_type" => type ).map { |l| [l.name, l.value] } end end diff --git a/app/models/membership_setting.rb b/app/models/membership_setting.rb new file mode 100644 index 00000000..89f9eb14 --- /dev/null +++ b/app/models/membership_setting.rb @@ -0,0 +1,2 @@ +class MembershipSetting < ApplicationRecord +end diff --git a/app/models/order.rb b/app/models/order.rb index 066d65fc..3a0d1cfb 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -4,6 +4,7 @@ class Order < ApplicationRecord belongs_to :customer has_many :order_items, autosave: true , inverse_of: :order + has_many :assigned_order_items #internal references attributes for business logic control attr_accessor :items, :guest, :table_id, :new_booking, :booking_type, :employee_name diff --git a/app/models/order_queue_process_by_zone.rb b/app/models/order_queue_process_by_zone.rb index 0c7fd538..84ee42f8 100644 --- a/app/models/order_queue_process_by_zone.rb +++ b/app/models/order_queue_process_by_zone.rb @@ -1,3 +1,4 @@ class OrderQueueProcessByZone < ApplicationRecord belongs_to :zone + belongs_to :order_queue_station end diff --git a/app/models/order_queue_process_log.rb b/app/models/order_queue_process_log.rb deleted file mode 100644 index 6c3a3a6d..00000000 --- a/app/models/order_queue_process_log.rb +++ /dev/null @@ -1,3 +0,0 @@ -class OrderQueueProcessLog < ApplicationRecord - belongs_to :order -end diff --git a/app/models/order_queue_station.rb b/app/models/order_queue_station.rb index c695c076..b2feb596 100644 --- a/app/models/order_queue_station.rb +++ b/app/models/order_queue_station.rb @@ -1,2 +1,47 @@ + +# Order Queue station is where order are submitted to +# Order can send from tablet | table +# Source of order will determin where it will appear class OrderQueueStation < ApplicationRecord + has_many :assigned_order_items + has_many :order_items + + scope :active, -> {where(is_active: true)} + + def process_order (order) + oqs_stations = OrderQueueStation.active + + order_items = order.order_items + #Assign OQS id to order Items + oqs_stations.each do |oqs| + #Get List of items - + pq_items = JSON.parse(oqs.processing_items) + + #Loop through the processing items + pq_items.each do |pq_item| + #Processing through the looping items + order_items.each do |order_item| + if (pq_item == order_item.item_code) + #Same Order_items can appear in two location. + AssignedOrderItem.assigned_order_item(order, order_item.item_code, oqs) + end + end + + end + end + + #Print OQS where printing is require + + end + + private + #Print order_items in 1 slip + def print_slip + + end + + #Print order_items in 1 slip per item + def print_slip_item + + end end diff --git a/app/models/sale.rb b/app/models/sale.rb index 3ad727c1..a0d7037c 100644 --- a/app/models/sale.rb +++ b/app/models/sale.rb @@ -3,27 +3,60 @@ class Sale < ApplicationRecord belongs_to :cashier belongs_to :customer has_many :sale_items + has_many :sale_discount_items has_many :sale_discounts has_many :sale_taxes has_many :sale_payments has_many :sale_orders - def generate_invoice_from_order (order_no) + def generate_invoice_from_order (order_no, sale_id) + #if sale_id is exsit and validate + #add order to that invoice + if (sale_id) + self = Sale.find(sale_id) + end + if self.sale_status == "void" + return false, "Invoice is void. Cannot be edited" + else + order = Order.find(order_no) + if order + order.order_items.each do |item| + self.sale_items.add(add_item(item)) + end + end + + link_order_sale(order.id) + + return self.save! + + end + + end def generate_invoice_by_items (items) + end def add_item (item) + #check if the item is on promotion + #save sale_audit + sale_item = SaleItem.new + sale_item.sale = self + sale_item.product_code = item.item_code + sale_item.product_name = item.item_name + sale_item.qty = item.qty + return sale_item end - def remove_item (item) + + def update_item (item) #save sale_audit end - def apply_discount_item (promotion_id, item) + def apply_item_discount (promotion_id, item) end def apply_discount (discount_type, discount_code) @@ -33,8 +66,13 @@ class Sale < ApplicationRecord def accept_payment (payment_method, amount, payment_ref, payment_external_result) end - def void_sales (void_by, reason, approval_code) + def void_sales (void_by, reason, approval_code, request_by) #save sale_audit + self.sale_status = "void" + self. + + + end #compute - invoice total @@ -64,14 +102,17 @@ class Sale < ApplicationRecord #tax_profile - list by order_by tax_profiles = TaxProfile.all.order("order_by asc") - + total_amount = self.total_amount #Creat new tax records tax_profiles.each do |tax| sale_tax = SaleTax.new(:sale => self) sale_tax.tax_name = tax.name sale_tax.tax_rate = tax.rate #include or execulive - sale_tax.tax_payable_amount = self.total_amount * tax.rate + sale_tax.tax_payable_amount = total_amount * tax.rate + #new taxable amount + total_amount = total_amount + sale_tax.tax_payable_amount + sale_tax.inclusive = tax.inclusive sale_tax.save end @@ -82,12 +123,22 @@ class Sale < ApplicationRecord private + def product_get_unit_price(item.item_code) + menu_instance_code = MenuInstanceCode.find_by_item_instance_code(item.item_code) + if (menu_instance_code) + + end + + def link_order_sale(order.id) + + end #Generate new Receipt No when it is not assigned def generate_receipt_no #Date-Shift- if !self.receipt_no.nil? prefix = Date.now() self.receipt_no = prefix.to_s + "/" + self.shit_id.to_s + "/" + SeedGenerator.new_receipt_no().to_s + self.receipt_date = prefix end end end diff --git a/app/models/sale_audit.rb b/app/models/sale_audit.rb index 99df9de0..b037ef15 100644 --- a/app/models/sale_audit.rb +++ b/app/models/sale_audit.rb @@ -1,2 +1,41 @@ class SaleAudit < ApplicationRecord + belongs_to :sale + + def record_audit_void(sale_id, void_by, approved_by, reason) + #sale_audit + sale_audit = SaleAudit.new() + sale_audit.sale_id = sale_id + sale_audit.action = "SALEVOID" + sale_audit.action_at = DateTime.now.utc + sale_audit.action_by = void_by + sale_audit.approved_by = approved_by + sale_audit.remark = reason + sale_audit.save! + #sale_audit. + end + + def record_audit_discount(sale_id, discount_by, approved_by, reason) + #sale_audit + sale_audit = SaleAudit.new() + sale_audit.sale_id = sale_id + sale_audit.action = "SALEDISCOUNT" + sale_audit.action_at = DateTime.now.utc + sale_audit.action_by = discount_by + sale_audit.approved_by = approved_by + sale_audit.remark = reason + sale_audit.save! + #sale_audit. + end + + def record_audit_foc(sale_id, cashier_id, approved_by, reason) + #sale_audit + sale_audit = SaleAudit.new() + sale_audit.sale_id = sale_id + sale_audit.action = "SALEFOC" + sale_audit.action_at = DateTime.now.utc + sale_audit.action_by = cashier_id + sale_audit.approved_by = approved_by + sale_audit.remark = reason + sale_audit.save! + end end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 0970a8e1..816dea67 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -6,7 +6,7 @@ - Film Buff + SmartSales : Restaurant <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> diff --git a/app/views/layouts/installation.html.erb b/app/views/layouts/installation.html.erb index 9576015c..14cf9820 100644 --- a/app/views/layouts/installation.html.erb +++ b/app/views/layouts/installation.html.erb @@ -6,7 +6,7 @@ - Film Buff + SmartSales : Restaurant <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> diff --git a/db/migrate/20170331024749_create_menu_items.rb b/db/migrate/20170331024749_create_menu_items.rb index 2a0e8e2e..ae202501 100644 --- a/db/migrate/20170331024749_create_menu_items.rb +++ b/db/migrate/20170331024749_create_menu_items.rb @@ -7,10 +7,11 @@ class CreateMenuItems < ActiveRecord::Migration[5.0] t.string :type, :null => false, :default => "SimpleMenuItem" t.references :menu_category, foreign_key: true t.references :menu_item, foreign_key: true + t.integer :min_qty, :null => false, :default => 1 t.integer :min_selectable_item, :null => false, :default => 1 t.integer :max_selectable_item, :null => false, :default => 1 t.json :options #save value - t.json :attributes #value IDS + t.json :item_attributes #value IDS t.string :created_by t.timestamps diff --git a/db/migrate/20170403140820_create_order_items.rb b/db/migrate/20170403140820_create_order_items.rb index 939b8189..24cc81ca 100644 --- a/db/migrate/20170403140820_create_order_items.rb +++ b/db/migrate/20170403140820_create_order_items.rb @@ -10,7 +10,6 @@ class CreateOrderItems < ActiveRecord::Migration[5.0] t.string :remark t.string :options t.json :set_menu_items #this parameter is require to route the items correctly - t.timestamps end end diff --git a/db/migrate/20170403152157_create_order_queue_process_logs.rb b/db/migrate/20170403152157_create_order_queue_process_logs.rb deleted file mode 100644 index 5b855ec5..00000000 --- a/db/migrate/20170403152157_create_order_queue_process_logs.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateOrderQueueProcessLogs < ActiveRecord::Migration[5.0] - def change - create_table :order_queue_process_logs do |t| - t.references :order, foreign_key: true - t.string :job_status, :default => "new", :null => "false" - t.string :print_status, :default => "new" - t.json :header #{table name, order_type, order_date} - t.json :items #{name, comment, qty} - - t.timestamps - end - end -end diff --git a/db/migrate/20170414071634_create_membership_settings.rb b/db/migrate/20170414071634_create_membership_settings.rb new file mode 100644 index 00000000..e15bf082 --- /dev/null +++ b/db/migrate/20170414071634_create_membership_settings.rb @@ -0,0 +1,15 @@ +class CreateMembershipSettings < ActiveRecord::Migration[5.0] + def change + create_table :membership_settings do |t| + t.string :membership_type, :null => false, :default => "internal" + t.boolean :is_active, :null => false, :default => true + t.string :gateway_communication_type, :null => false, :default => "api" + t.string :gateway_url + t.string :auth_token + t.string :merchant_account_id + t.string :created_by + + t.timestamps + end + end +end diff --git a/db/migrate/20170414090001_create_assigned_order_items.rb b/db/migrate/20170414090001_create_assigned_order_items.rb new file mode 100644 index 00000000..e617adea --- /dev/null +++ b/db/migrate/20170414090001_create_assigned_order_items.rb @@ -0,0 +1,13 @@ +class CreateAssignedOrderItems < ActiveRecord::Migration[5.0] + def change + create_table :assigned_order_items do |t| + t.string :item_code, :null => false, :index => true + t.references :order_queue_station, foreign_key: true + t.references :order, foreign_key: true + t.boolean :print_status + t.boolean :delivery_status + + t.timestamps + end + end +end diff --git a/db/seeds.rb b/db/seeds.rb index ef60ce83..94fc5b66 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -6,6 +6,9 @@ # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) +gateway_communication_type = Lookup.create([{lookup_type:'gateway_communication_type', name: 'API', value: 'api'}, + {lookup_type:'gateway_communication_type', name: 'USB', value: 'usb'}]) + payment_methods = Lookup.create([{lookup_type:'payment_methods', name: 'Cash', value: 'cash'}, {lookup_type:'payment_methods', name: 'CreditNote', value: 'creditnote'}, {lookup_type:'payment_methods', name: 'Card - VISA', value: 'visa'}, @@ -47,6 +50,10 @@ menu_item_type = Lookup.create([{lookup_type:'menu_item_type', name: 'SIMPLE', v {lookup_type:'menu_item_type', name: 'Set Menu', value: 'set_menu'}, {lookup_type:'menu_item_type', name: 'DIY', value: 'diy'}]) +#menu_item_attribute:[size|] +menu_item_attribute_type = Lookup.create([{lookup_type:'menu_item_attribute_type', name: 'Size', value: 'size'}, + {lookup_type:'menu_item_attribute_type', name: 'Spicy', value: 'spicy'}, + {lookup_type:'menu_item_attribute_type', name: 'Sweetness', value: 'sweetness'}]) #Employee Roles employee_roles = Lookup.create([{lookup_type:'employee_roles', name: 'Cashier', value: 'cashier'}, @@ -63,15 +70,46 @@ booking_status = Lookup.create([{lookup_type:'booking_status', name: 'Available' #WALK CUSTOMER - Default CUSTOMER (take key 1) customer = Customer.create({id:1, name:"WALK-IN", contact_no:"000000000"}) +customer = Customer.create({id:2, name:"TAKEAWAY", contact_no:"000000000"}) + #Default ZOne zone = Zone.create({id:1, name: "Default Zone", is_active:true, created_by: "SYSTEM DEFAULT"}) +zone2 = Zone.create({id:2, name: "Default Zone 2", is_active:true, created_by: "SYSTEM DEFAULT"}) #Default dining_facilities -dining_facilities = DiningFacility.create({id:1, name:"Default Table", zone: zone, status:"available", type: "Table", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"}) +table = Table.create({name:"Default Table", zone: zone, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"}) +room = Room.create({name:"Default Room", zone: zone2, status:"available", seater: 4 , order_by:1, created_by:"SYSTEM DEFAULT"}) #Tax Profile tax_profiles = TaxProfile.create({id:1, name: "Commerical Tax", rate:5.0, order_by:1, created_by:"SYSTEM DEFAULT"}) + #Default menu menu = Menu.create({name: "Default Menu", is_active: true, created_by: "SYSTEM DEFAULT"}) + +#Default Menu Category +menu_category1 = MenuCategory.create({menu: menu, name: "Sample Menu Category 1", alt_name: "Sample Alternate Name 1", order_by: 1}) +menu_category2 = MenuCategory.create({menu: menu, name: "Sample Menu Category 2", alt_name: "Sample Alternate Name 2", order_by: 2}) +menu_category3 = MenuCategory.create({menu: menu, name: "Sample Menu Category 3", alt_name: "Sample Alternate Name 3", order_by: 3}) +menu_category4 = MenuCategory.create({menu: menu, name: "Sample Menu Category 4", alt_name: "Sample Alternate Category 4", order_by: 1, menu_category_id: menu_category3.id}) + +#Default Menu items +menu_category1_menu_item0 = SimpleMenuItem.create({item_code:"01001", name: "Default Menu Item Name 0", alt_name: "Alternate Menu Item Name 0",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 }) +menu_category1_menu_item1 = SimpleMenuItem.create({item_code:"01002", name: "Default Menu Item Name 1", alt_name: "Alternate Menu Item Name 1",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 }) +menu_category1_menu_item2 = SimpleMenuItem.create({item_code:"01003", name: "Default Menu Item Name 2", alt_name: "Alternate Menu Item Name 2",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 }) +menu_category1_menu_item3 = SimpleMenuItem.create({item_code:"01004", name: "Default Menu Item Name 3", alt_name: "Alternate Menu Item Name 3",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 }) + +menu_category2_menu_item0 = SimpleMenuItem.create({item_code:"02005", name: "Default Menu Item Name 0", alt_name: "Alternate Menu Item Name 0",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 2 }) +menu_category2_menu_item1 = SimpleMenuItem.create({item_code:"02006", name: "Default Menu Item Name 1", alt_name: "Alternate Menu Item Name 1",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 2 }) +menu_category2_menu_item2 = SimpleMenuItem.create({item_code:"02007", name: "Default Menu Item Name 2", alt_name: "Alternate Menu Item Name 2",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 3 }) +menu_category2_menu_item3 = SimpleMenuItem.create({item_code:"02008", name: "Default Menu Item Name 3", alt_name: "Alternate Menu Item Name 3",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 4 }) + +#Default Order Queue stations +order_queue_station1 = OrderQueueStation.create({station_name: "Queue Station 1", is_active: true,printer_name: "kitchen_printer", processing_items: JSON.generate(['01001','01002','01003','01004']), print_copy:true, cut_per_item: false, use_alternate_name: false, created_by: "SYSTEM DEFAULT"}) +order_queue_station2 = OrderQueueStation.create({station_name: "Queue Station 2", is_active: true,printer_name: "drink_printer", processing_items: JSON.generate(['02005','02006','02007','02008']), print_copy:true, cut_per_item: true, use_alternate_name: true, created_by: "SYSTEM DEFAULT"}) +zone_order_queue_station = OrderQueueStation.create({station_name: "Zone 1 Queue Station 2", is_active: true, printer_name: "print_station", processing_items: JSON.generate(['01001','01002','01003','01004','02005','02006','02007','02008']), print_copy: true, cut_per_item: true, use_alternate_name: false, created_by: "SYSTEM DEFAULT"}) + + +#Default Order Queue Process By Zone +zone_queue_station = OrderQueueProcessByZone.create({order_queue_station: zone_order_queue_station, zone: zone2}) diff --git a/spec/models/order_queue_process_log_spec.rb b/spec/models/assigned_order_item_spec.rb similarity index 61% rename from spec/models/order_queue_process_log_spec.rb rename to spec/models/assigned_order_item_spec.rb index 21084f54..32c816d4 100644 --- a/spec/models/order_queue_process_log_spec.rb +++ b/spec/models/assigned_order_item_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.describe OrderQueueProcessLog, type: :model do +RSpec.describe AssignedOrderItem, type: :model do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/membership_setting_spec.rb b/spec/models/membership_setting_spec.rb new file mode 100644 index 00000000..861778a3 --- /dev/null +++ b/spec/models/membership_setting_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe MembershipSetting, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end