diff --git a/Gemfile b/Gemfile index 663d66d5..4cb09746 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ gem 'rails', '~> 5.1.0' #gem 'mysql2', '>= 0.3.18', '< 0.5' gem 'pg' -gem 'mysql2' +gem 'mysql2', '~> 0.5.2' #Use PosgreSQL diff --git a/Gemfile.lock b/Gemfile.lock index 4e13e61f..4aa2614b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -354,7 +354,7 @@ DEPENDENCIES material_icons mini_magick momentjs-rails - mysql2 + mysql2 (~> 0.5.2) nested_form pdfjs_viewer-rails pg diff --git a/README.md b/README.md index 398634d2..7d64f2eb 100755 --- a/README.md +++ b/README.md @@ -4,161 +4,151 @@ SXRestuarant is a new Dedicate project for SmartSales Restaurant. It is improvem Things you may want to cover: -* Ruby version -ruby 2.4.1p111 +- Ruby version + ruby 2.4.1p111 -* Membership Details -Osaka => - Auth Token => wu8YvlLmah0CL => New => v3 - => rj0MJ0XI5GsKZehE => Old => v2 - => code2lab => Old +- Membership Details + Osaka => + Auth Token => wu8YvlLmah0CL => New => v3 + => rj0MJ0XI5GsKZehE => Old => v2 + => code2lab => Old - Merchant account => RxzaYyAGzm7VqAZ4hKnv - Campaign Id => {"campaign_type_id": 5} + Merchant account => RxzaYyAGzm7VqAZ4hKnv + Campaign Id => {"campaign_type_id": 5} BITP - Auth Token => pZBHXEFbGNj/G => New => V3 - iua0SjUHzRaQw - => rj0MJ0XI5GsKZehE => Old => V2 - => code2lab => Old +Auth Token => pZBHXEFbGNj/G => New => V3 +iua0SjUHzRaQw +=> rj0MJ0XI5GsKZehE => Old => V2 +=> code2lab => Old - Merchant account => vWSsseoZCzxd6xcNf_uS + Merchant account => vWSsseoZCzxd6xcNf_uS Campaign Id => {"campaign_type_id": 1} java -jar ~/Documents/Jade.jar http://192.168.1.88:3002 java -jar ~/Documents/c2l_jade.jar http://192.168.1.151:3002 Person and Extra Time - category_code = SPL... //for menu categories special - 1) must create Person in settings/accounts - 2) must create Adult and Child in settings/item_attributes - 3) must be PSA_[a-z/0-9] for Adult and PSC_[a-z/0-9] for Child in settings/menu_categories/[cat_id]/simple_menu_items - 3) must be PSAI_[a-z/0-9] for Adult and PSCI_[a-z/0-9] for Child in settings/simple_menu_items/[item_id]/menu_item_instances +category_code = SPL... //for menu categories special + +1. must create Person in settings/accounts +2. must create Adult and Child in settings/item_attributes +3. must be PSA*[a-z/0-9] for Adult and PSC*[a-z/0-9] for Child in settings/menu_categories/[cat_id]/simple_menu_items +4. must be PSAI*[a-z/0-9] for Adult and PSCI*[a-z/0-9] for Child in settings/simple_menu_items/[item_id]/menu_item_instances For Extra Time - item_instance_code - * must start with 'Ext'[a..z]'_'[1..100] - * note : don't add character after '_' +item_instance_code + +- must start with 'Ext'[a..z]'\_'[1..100] +- note : don't add character after '\_' For Order Printing - 1)) ********* Order Pdf ********* - 1) settings/print_settings - (a) Unique Code => OrderItemPdf & OrderSummaryPdf - (b) Font is present => {Header font size:11, Item Font Size:9} - Font is blank => {Header font size:12, Item Font Size:10} - 2)) ********* Order Set Pdf ********* - 1) settings/print_settings - (a) Unique Code => OrderSetItemPdf & OrderSummarySetPdf - (b) Font is present => {Header font size:11, Item Font Size:9} - Font is blank => {Header font size:12, Item Font Size:10} - 3)) ********* Order Slim Pdf ********* - 1) settings/print_settings - (a) Unique Code => OrderItemSlimPdf & OrderSummarySlimPdf - (b) Font is present => {Header font size:11, Item Font Size:9} - Font is blank => {Header font size:12, Item Font Size:10} - 4)) ********* Order Customise PDF ********* - 1) settings/print_settings - (a) Unique Code => OrderItemCustomisePdf & OrderSummaryCustomisePdf - (b) Can change Header font size and Item Font Size as you like - 5)) ********* Order Set Pdf ********* - 1) settings/print_settings - (a) Unique Code => OrderSetItemCustomisePdf & OrderSummarySetCustomisePdf - (b) Can change Header font size and Item Font Size as you like - 6)) ********* Order Slim Customise PDF - 1) settings/print_settings - (a) Unique Code => OrderItemSlimCustomisePdf & OrderSummarySlimCustomisePdf - (b) Can change Header font size and Item Font Size as you like -For Check in-out Printing - ********* Check in-out Pdf ********* - 1) settings/print_settings - (a) Unique Code => CheckInOutPdf - (b) Heading Space => 5 +1)) \***\*\*\*\*** Order Pdf \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => OrderItemPdf & OrderSummaryPdf +(b) Font is present => {Header font size:11, Item Font Size:9} +Font is blank => {Header font size:12, Item Font Size:10} +2)) \***\*\*\*\*** Order Set Pdf \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => OrderSetItemPdf & OrderSummarySetPdf +(b) Font is present => {Header font size:11, Item Font Size:9} +Font is blank => {Header font size:12, Item Font Size:10} +3)) \***\*\*\*\*** Order Slim Pdf \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => OrderItemSlimPdf & OrderSummarySlimPdf +(b) Font is present => {Header font size:11, Item Font Size:9} +Font is blank => {Header font size:12, Item Font Size:10} +4)) \***\*\*\*\*** Order Customise PDF \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => OrderItemCustomisePdf & OrderSummaryCustomisePdf +(b) Can change Header font size and Item Font Size as you like +5)) \***\*\*\*\*** Order Set Pdf \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => OrderSetItemCustomisePdf & OrderSummarySetCustomisePdf +(b) Can change Header font size and Item Font Size as you like +6)) \***\*\*\*\*** Order Slim Customise PDF 1) settings/print_settings +(a) Unique Code => OrderItemSlimCustomisePdf & OrderSummarySlimCustomisePdf +(b) Can change Header font size and Item Font Size as you like +For Check in-out Printing \***\*\*\*\*** Check in-out Pdf \***\*\*\*\*** 1) settings/print_settings +(a) Unique Code => CheckInOutPdf +(b) Heading Space => 5 For ReceiptBillA5Pdf - *** change ReceiptBillPdf to ReceiptBillA5Pdf - 1) settings/print_settings , width:680, height:1450, Header font Size:16, Item font size:14 - 2) settings/lookups => { type:print_settings, name:ReceiptBillA5Pdf, value:1 } +\*\*\* change ReceiptBillPdf to ReceiptBillA5Pdf 1) settings/print_settings , width:680, height:1450, Header font Size:16, Item font size:14 2) settings/lookups => { type:print_settings, name:ReceiptBillA5Pdf, value:1 } -For ReceiptBillAltName options - 1) settings/lookups => { type:print_settings, name:ReceiptBillAltName, value:1 } +For ReceiptBillAltName options 1) settings/lookups => { type:print_settings, name:ReceiptBillAltName, value:1 } For Using Star Printer - *** Need to change these print settings - 1) settings/print_settings/unique_code => OrderItemStarPdf - 2) settings/print_settings/unique_code => ReceiptBillStarPdf - 3) settings/print_settings/unique_code => SaleItemsStarPdf - *** Other print settings aren't need to change. +**_ Need to change these print settings 1) settings/print_settings/unique_code => OrderItemStarPdf 2) settings/print_settings/unique_code => ReceiptBillStarPdf 3) settings/print_settings/unique_code => SaleItemsStarPdf +_** Other print settings aren't need to change. -For Show Sale Items Summary at CloseCashierPrint - 1) settings/print_settings - a) Check => Shift Sale Items +For Show Sale Items Summary at CloseCashierPrint 1) settings/print_settings +a) Check => Shift Sale Items -For Show/Hide AddOrder Button in QuickService - 1) settings/lookups => {type:quickservice_add_order, name: QuickServiceAddOrder, value:1 OR 0} +For Show/Hide AddOrder Button in QuickService 1) settings/lookups => {type:quickservice_add_order, name: QuickServiceAddOrder, value:1 OR 0} -For Show Print Button in ReceiptNo Report - 1) settings/lookups => {type:reprint_receipt, name: Reprint Receipt in Report, value:1} +For Show Print Button in ReceiptNo Report 1) settings/lookups => {type:reprint_receipt, name: Reprint Receipt in Report, value:1} + +For Credit Payment Receipt Pdf and Print + +1. settings/lookups => { type:credit_pdf, name: Credit Pdf, value:1 } For Bank Integration setting - 1) rake db:migrate for card_sale_trans, card_settle_trans - 2) settings/lookups => { type:bank_integration, name: Bank Integration, value:1 } + +1. rake db:migrate for card_sale_trans, card_settle_trans +2. settings/lookups => { type:bank_integration, name: Bank Integration, value:1 } For checkout time and checkout alert time - 1) checkout time => { type: checkout_time, name: 9:00 AM - 12:00 PM, value: 120 } - 2) checkout alert time => { type: checkout_alert_time, name: 8:00 AM - 12:00 PM, value: 60 } - * you can add multiple record for checkout time and checkout alert time - * type must be 'checkout_time' and 'checkout_alert_time' - * you can change name and value - * name must be time range [12hr => 8:30 AM - 1:45 PM, 24hr => 8:00 - 13:45] - * value must be minutes[60] + +1. checkout time => { type: checkout_time, name: 9:00 AM - 12:00 PM, value: 120 } +2. checkout alert time => { type: checkout_alert_time, name: 8:00 AM - 12:00 PM, value: 60 } + +- you can add multiple record for checkout time and checkout alert time +- type must be 'checkout_time' and 'checkout_alert_time' +- you can change name and value +- name must be time range [12hr => 8:30 AM - 1:45 PM, 24hr => 8:00 - 13:45] +- value must be minutes[60] For call waiter pdf - * Backend > Printer > Print Settings > New - i) Name : Calling Waiter - ii) Unique Code: CallWaiterPdf - iii)Template: ... - iv) Font: Zawgyi-One - v) Printer: #printer name -Membership Actions SQL - * update membership_actions set additional_parameter='{\"campaign_type_id\":5}' where id=10; +- Backend > Printer > Print Settings > New + i) Name : Calling Waiter + ii) Unique Code: CallWaiterPdf + iii)Template: ... + iv) Font: Zawgyi-One + v) Printer: #printer name -SQL Update after rake clear:data runned - * update seed_generators - i) TableBooking, Order, OrderItem, sale, SaleOrder, SaleItem, SaleTax, SalePayment, SaleAudit, AssignedOrderItem => { current:0, next:0 } - ** Note :: do not update Customer +Membership Actions SQL \* update membership_actions set additional_parameter='{\"campaign_type_id\":5}' where id=10; + +SQL Update after rake clear:data runned \* update seed_generators +i) TableBooking, Order, OrderItem, sale, SaleOrder, SaleItem, SaleTax, SalePayment, SaleAudit, AssignedOrderItem => { current:0, next:0 } +\*\* Note :: do not update Customer Change type in mysql - *run if you got font error for Myanmar, Chinese, etc... - => ALTER TABLE [table_name] CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci #for table - => ALTER DATABASE [database_name] CHARACTER SET utf8 COLLATE utf8_unicode_ci #for database +\*run if you got font error for Myanmar, Chinese, etc... +=> ALTER TABLE [table_name] CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci #for table +=> ALTER DATABASE [database_name] CHARACTER SET utf8 COLLATE utf8_unicode_ci #for database -For split bill - 1) settings/lookups => { type:split_bill, name:SplitBill, value:1 } +For split bill 1) settings/lookups => { type:split_bill, name:SplitBill, value:1 } -For Sidekiq - 1) If you want to use sidekiq - => Create New Lookups => lookup_type = sidekiq, Name = sidekiq , Value = 1 or 0 +For Sidekiq 1) If you want to use sidekiq +=> Create New Lookups => lookup_type = sidekiq, Name = sidekiq , Value = 1 or 0 -For Clear Menu - 1) rake clear:menu # menu,menu item,menu category,menu item instance,account,item option,item attribute,item set +For Clear Menu 1) rake clear:menu # menu,menu item,menu category,menu item instance,account,item option,item attribute,item set For Check CUp status -###please open +###please open sudo cat /etc/sudoers + ### cope and parse + %superuser ALL=(ALL) NOPASSWD: ALL <---- Extra Fields Script -----> DROP TABLE IF EXISTS `display_images`; CREATE TABLE `display_images` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `shop_id` int(11) DEFAULT NULL, - `image` blob, - `created_by` varchar(255) DEFAULT NULL, - `created_at` datetime NOT NULL, - `updated_at` datetime NOT NULL, - PRIMARY KEY (`id`) +`id` bigint(20) NOT NULL AUTO_INCREMENT, +`shop_id` int(11) DEFAULT NULL, +`image` blob, +`created_by` varchar(255) DEFAULT NULL, +`created_at` datetime NOT NULL, +`updated_at` datetime NOT NULL, +PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE customers @@ -190,118 +180,104 @@ ADD COLUMN group_type VARCHAR(255) after name; <---- Extra Fields Script -----> For CloseCashierCustomisePdf in lookups - *** change CloseCashierPdf to CloseCashierCustomisePdf - 1) settings/print_settings - 2) settings/lookups => { type:print_settings, name: CloseCashierCustomisePdf, value:1 } +\*\*\* change CloseCashierPdf to CloseCashierCustomisePdf 1) settings/print_settings 2) settings/lookups => { type:print_settings, name: CloseCashierCustomisePdf, value:1 } <---- Extra Fields Script -----> For MoveTablePdf in lookups - *** Both Table and Room Moving *** - 1) settings/lookups => { type:print_settings, name: MoveTablePdf, value:1 } +**_ Both Table and Room Moving _** 1) settings/lookups => { type:print_settings, name: MoveTablePdf, value:1 } -For MoveTablePdf in print settings - * Backend > Printer > Print Settings > New - i) Name : Move Table - ii) Unique Code: MoveTablePdf - iii)Template: ... - iv) Font: Zawgyi-One v) Printer: #printer name +For MoveTablePdf in print settings \* Backend > Printer > Print Settings > New +i) Name : Move Table +ii) Unique Code: MoveTablePdf +iii)Template: ... +iv) Font: Zawgyi-One v) Printer: #printer name -/* Tax Profile Group Types in lookups */ -1) settings/lookups => { type:tax_profiles, name: Cashier, value:cashier } -2) settings/lookups => { type:tax_profiles, name: Quick Service, value: quick_service } -3) settings/lookups => { type:tax_profiles, name: Doemal, value: doemal } -4) settings/lookups => { type:tax_profiles, name: Food Court, value: food_court } -/* Tax Profile Group Types in lookups */ +/_ Tax Profile Group Types in lookups _/ -/*Receipt Pdf View in lookups */ -1) settings/lookups => { type:ReceiptPdfView, name: Receipt Pdf View, value:1 or 0 } +1. settings/lookups => { type:tax_profiles, name: Cashier, value:cashier } +2. settings/lookups => { type:tax_profiles, name: Quick Service, value: quick_service } +3. settings/lookups => { type:tax_profiles, name: Doemal, value: doemal } +4. settings/lookups => { type:tax*profiles, name: Food Court, value: food_court } + /* Tax Profile Group Types in lookups \_/ + +/_Receipt Pdf View in lookups _/ + +1. settings/lookups => { type:ReceiptPdfView, name: Receipt Pdf View, value:1 or 0 } => 1 is active and 0 is in-active -Add Kitchen Role of Employee - => 1) settings/lookups => { type:employee_roles, name: Kitchen, value:kitchen } +Add Kitchen Role of Employee +=> 1) settings/lookups => { type:employee_roles, name: Kitchen, value:kitchen } -Add Base URL for DOEMAL - 1) settings/lookups => { type:order_reservation, name: BaseURL, value:'{doemal url}' } - 2) settings/lookups => { type:order_reservation, name: Token, value:'{doemal token}' } +Add Base URL for DOEMAL 1) settings/lookups => { type:order_reservation, name: BaseURL, value:'{doemal url}' } 2) settings/lookups => { type:order_reservation, name: Token, value:'{doemal token}' } Add Feature for Dine-in Cashier - ** '0' means can not use dine-in cashier and '1' means can use dine-in cashier ** - => settings/lookups => { type:dinein_cashier, name: DineInCashier, value:'{0 or 1}' } +** '0' means can not use dine-in cashier and '1' means can use dine-in cashier ** +=> settings/lookups => { type:dinein_cashier, name: DineInCashier, value:'{0 or 1}' } Add Feature for Quick Service - ** '0' means can not use quick service and '1' means can use quick service ** - => settings/lookups => { type:quick_service, name: QuickService, value:'{0 or 1}' } +** '0' means can not use quick service and '1' means can use quick service ** +=> settings/lookups => { type:quick_service, name: QuickService, value:'{0 or 1}' } Add Feature for Order and Reservation - ** '0' means can not use order reservation and '1' means can use order reservation ** - => settings/lookups => { type:order_reservation, name: OrderReservation, value:'{0 or 1}' } +** '0' means can not use order reservation and '1' means can use order reservation ** +=> settings/lookups => { type:order_reservation, name: OrderReservation, value:'{0 or 1}' } -For Price 0 in receipt bill - 2) settings/lookups => { type:show_price, name:Show Price, value:1 } +For Price 0 in receipt bill 2) settings/lookups => { type:show_price, name:Show Price, value:1 } +For Price 0 in receipt bill 2) settings/lookups => { type:order_by, name:Order By, value:name } -For Price 0 in receipt bill - 2) settings/lookups => { type:order_by, name:Order By, value:name } +For Aston Request => Gift Voucher 1) settings/payment_method_settings => {payment_method:'GiftVoucher', is_active:true, ...} -For Aston Request => Gift Voucher - 1) settings/payment_method_settings => {payment_method:'GiftVoucher', is_active:true, ...} - -For Login expiry time - 1) settings/lookups => {type:expity_time, name:login, value: {minutes}} - * value should be minute only (30 / 60 / 120 / etc.) +For Login expiry time 1) settings/lookups => {type:expity_time, name:login, value: {minutes}} \* value should be minute only (30 / 60 / 120 / etc.) Menu Image (Import guideline) - => First, check shop_code, is there in shops table and prefix shop_code in image name? - => You all must do this step - * If there is shop_code in shops table (mark in one place/ note and set NULL for this record for a while) and prefix shop_code for image name (like (121_ABC.png)), and copy and paste images into Application/[sxrestaurant]/public/image/menu_images. - * If there is shop_code/ no shop_code in shops table but no prefix in image name (* skip set NULL step) , copy and paste images into Application/…./image/menu_images. - => Second, import [menu].xlsx file in /settings/menus and then checked image is uploaded into Application/[sxrestaurant]/public/image/menu_images and insert into menu_items table in database. - => Last, if shop has shop_code, update marked/noted shop_code into shops table again. + => First, check shop_code, is there in shops table and prefix shop_code in image name? + => You all must do this step + * If there is shop_code in shops table (mark in one place/ note and set NULL for this record for a while) and prefix shop_code for image name (like (121_ABC.png)), and copy and paste images into Application/[sxrestaurant]/public/image/menu_images. + * If there is shop_code/ no shop_code in shops table but no prefix in image name (* skip set NULL step) , copy and paste images into Application/…./image/menu_images. + => Second, import [menu].xlsx file in /settings/menus and then checked image is uploaded into Application/[sxrestaurant]/public/image/menu_images and insert into menu_items table in database. + => Last, if shop has shop_code, update marked/noted shop_code into shops table again. -For Edit Order Open & Close - 1) settings/lookups => {type:edit_order, name:EditOrderOrigami, value: {1 or 0}} +For Edit Order Open & Close 1) settings/lookups => {type:edit_order, name:EditOrderOrigami, value: {1 or 0}} -For Dashboard Settings for supervisor and cashier - 1) settings/lookups => {type:dashboard_settings, name:supervisor, value: {1 or 0}} - 2) settings/lookups => {type:dashboard_settings, name:cashier, value: {1 or 0}} +For Dashboard Settings for supervisor and cashier 1) settings/lookups => {type:dashboard_settings, name:supervisor, value: {1 or 0}} 2) settings/lookups => {type:dashboard_settings, name:cashier, value: {1 or 0}} -For Customer Settings On/Off - 1) settings/lookups => {type:customer_settings, name:create, value: {1 or 0}} +For Customer Settings On/Off 1) settings/lookups => {type:customer_settings, name:create, value: {1 or 0}} -For TaxProfiles On/Off - 1) settings/lookups => {type:changable_tax, name:change, value: {1 or 0}} +For TaxProfiles On/Off 1) settings/lookups => {type:changable_tax, name:change, value: {1 or 0}} -For Add Kitchen Role - 1) settings/lookups => {type:employee_roles, name:Kitchen, value:kitchen} +For Add Kitchen Role 1) settings/lookups => {type:employee_roles, name:Kitchen, value:kitchen} For Food Court Settings On/Off - ** '0' means can not use food court and '1' means can use food court ** - => settings/lookups => { type:food_court, name: FoodCourt, value:'{0 or 1}' } +** '0' means can not use food court and '1' means can use food court ** +=> settings/lookups => { type:food_court, name: FoodCourt, value:'{0 or 1}' } For Number Formats - Precision - => settings/lookups => { lookup_type: number_format, name: precision, value: {0..2} } - Delimiter - => settings/lookups => { lookup_type: number_format, name: delimiter, value: { ',', '\u0020', '', ... } - Strip insignificant zeros - => settings/lookups => { lookup_type: number_format, name: strip_insignificant_zeros, - value: {true: => ['1', 't', 'true', 'on', 'y', 'yes'], false: => ['0', 'f', 'false', 'off', 'n', 'no', ...] } +Precision +=> settings/lookups => { lookup_type: number_format, name: precision, value: {0..2} } +Delimiter +=> settings/lookups => { lookup_type: number_format, name: delimiter, value: { ',', '\u0020', '', ... } +Strip insignificant zeros +=> settings/lookups => { lookup_type: number_format, name: strip_insignificant_zeros, +value: {true: => ['1', 't', 'true', 'on', 'y', 'yes'], false: => ['0', 'f', 'false', 'off', 'n', 'no', ...] } For Booking checkin time limit - settings/lookups => - { lookup_type: checkin_time_limit, name: CheckinTimeLimit, value: total hours before checkout (e.g., '48')) } +settings/lookups => +{ lookup_type: checkin_time_limit, name: CheckinTimeLimit, value: total hours before checkout (e.g., '48')) } -/* Customer Types in lookups */ -1) settings/lookups => { type:customer_type, name: Dinein, value:Dinein } -2) settings/lookups => { type:customer_type, name: Takeaway, value: Takeaway } -3) settings/lookups => { type:customer_type, name: Doemal, value: Doemal } -4) settings/lookups => { type:customer_type, name: FoodCourt, value: FoodCourt } -/* Tax Profile Group Types in lookups */ +/_ Customer Types in lookups _/ + +1. settings/lookups => { type:customer_type, name: Dinein, value:Dinein } +2. settings/lookups => { type:customer_type, name: Takeaway, value: Takeaway } +3. settings/lookups => { type:customer_type, name: Doemal, value: Doemal } +4. settings/lookups => { type:customer*type, name: FoodCourt, value: FoodCourt } + /* Tax Profile Group Types in lookups \_/ For Online Order Receipt Setting -1) settings/lookups => { type:order_reservation, name:ReceiptBill, value: {0 or 1} } -2) settings/print_settings => {name: ReceiptBillOrder, unique_code: ReceiptBillOrderPdf, ....} + +1. settings/lookups => { type:order_reservation, name:ReceiptBill, value: {0 or 1} } +2. settings/print_settings => {name: ReceiptBillOrder, unique_code: ReceiptBillOrderPdf, ....} For Close Cashier Print Settings settings/lookups => {type:close_cashier_print, name:CloseCashierPrint, value: {0 or 1} } @@ -325,93 +301,88 @@ settings/lookups => { type:employee_roles, name: FoodCourt Cashier, value:foodco 2. Quick Service 3. Order & Reservation +- System Dependencies -* System Dependencies +- Configuration -* Configuration +- Database creation -* Database creation +- Database initialization -* Database initialization +- How to run the test suite -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions +- Services (job queues, cache servers, search engines, etc.) +- Deployment instructions * Features 1. OQS - 1. Filter - 2. Order Item to each Stations - 3. Edit Order Item + 1. Filter + 2. Order Item to each Stations + 3. Edit Order Item 2. Origami(Sale) - 1. Sale - 2. Add Customer for membership - 3. Discount and Member Discount for Sale - 4. Assign Commissioner - 5. Add other charges to Sale + 1. Sale + 2. Add Customer for membership + 3. Discount and Member Discount for Sale + 4. Assign Commissioner + 5. Add other charges to Sale 3. CRM - 1. Customer Management + 1. Customer Management - 2. Queue Management + 2. Queue Management 4. Backend - 1. Dining Setup + 1. Dining Setup - 2. Queue Station Setup + 2. Queue Station Setup - 3. Menu Setup + 3. Menu Setup - 4. Cashier Terminal Setup + 4. Cashier Terminal Setup - 5. Tax Profile Setup + 5. Tax Profile Setup - 6. Printer Setup + 6. Printer Setup - 7. Payment Integration + 7. Payment Integration - 8. Employee Management + 8. Employee Management - 9. Promotion Setup + 9. Promotion Setup - 10. Commissioner Setup + 10. Commissioner Setup - 11. Membership Integration - - -5. Inventory + 11. Membership Integration +5) Inventory 6. Report - -* UI Standard +- UI Standard 1. Layout - 1. 2-Column => Main Content - col-9, Information - col-3 - 2. 3-Column => Sub Lint - col-2, Main Content - col-7, Information - col-3 + 1. 2-Column => Main Content - col-9, Information - col-3 + 2. 3-Column => Sub Lint - col-2, Main Content - col-7, Information - col-3 - > Pixel + > Pixel - Main Header Bar - height => 50 px - Side Navigation - Weight => 230 px - Main Content Padding => 15 px + Main Header Bar - height => 50 px + Side Navigation - Weight => 230 px + Main Content Padding => 15 px 2. Color - > BUTTON + > BUTTON - 1. Submit/Add/Edit/Confirm buttons => btn-primary (theme color) - 2. Show/Detail Buttons => btn-info - 3. Delete => btn-delete - 4. Cancel/Back => btn-default + 1. Submit/Add/Edit/Confirm buttons => btn-primary (theme color) + 2. Show/Detail Buttons => btn-info + 3. Delete => btn-delete + 4. Cancel/Back => btn-default diff --git a/app/controllers/api/check_in_process_controller.rb b/app/controllers/api/check_in_process_controller.rb index 2a04ff6b..c12ae517 100644 --- a/app/controllers/api/check_in_process_controller.rb +++ b/app/controllers/api/check_in_process_controller.rb @@ -19,12 +19,13 @@ class Api::CheckInProcessController < Api::ApiController table = DiningFacility.find(params[:dining_id]) #Send to background job for processing - if ENV["SERVER_MODE"] == 'cloud' - from = request.subdomain + "." + request.domain - else - from = "" - end - ActionCable.server.broadcast "check_in_booking_channel",table: table,from:from + if ENV["SERVER_MODE"] == 'cloud' + from = request.subdomain + "." + request.domain + else + from = "" + end + ActionCable.server.broadcast "check_in_booking_channel",table: table,from:from + check_out_time = nil extra_minutes = nil alert_time_min = 0 @@ -65,93 +66,59 @@ class Api::CheckInProcessController < Api::ApiController if params[:dining_id] dining_facility = DiningFacility.find(params[:dining_id]) if dining_facility.is_active && dining_facility.status == "available" - if params[:checkin_time] - checkin_at = nil - if !params[:checkin_time].empty? - checkin_at = Time.parse(params[:checkin_time]).utc + if dining_facility.current_checkin_booking.nil? + if params[:checkin_time].present? + checkin_at = Time.parse(params[:checkin_time]) else - checkin_at = Time.now.utc + checkin_at = Time.now end - if !checkin_at.nil? - if dining_facility.check_time(checkin_at, "checkin") - booking = dining_facility.get_current_booking - if booking.nil? + checkout_at = nil + lookup_checkout_time = Lookup.collection_of("checkout_time") + today = Time.now + if !lookup_checkout_time.empty? - booking = Booking.create({:dining_facility_id => params[:dining_id],:type => "TableBooking", - :checkin_by=>current_login_employee.name,:checkin_at => checkin_at,:checkout_at =>nil, :booking_status => "assign", :reserved_at => nil, :reserved_by => nil }) - if booking.save! - dining_facility.status = "occupied" - dining_facility.save! - render :json => { :status => true, :booking_id => booking.booking_id, :checkin_at => booking.checkin_at.utc.getlocal.strftime("%Y-%m-%d %H:%M:%S"), :message => "Check-in success" } - else - render :json => { :status => false, :error_message => "Booking does not create successfully!" } - end - else - render :json => { :status => false, :error_message => "Booking already exist!" } + lookup_checkout_time.each do |checkout_time| + start_time, end_time = checkout_time[0].split("-").map{ |t| Time.parse(t.strip).strftime("%H:%M%p") } + if start_time <= today.strftime("%H:%M%p") && today.strftime("%H:%M%p") <= end_time + checkout_at = checkin_at + (checkout_time[1]).to_i.minutes end - else - render :json => { :status => false, :error_message => "Checkin time not available!" } end - else - render :json => { :status => false, :error_message => "Operation failed!" } end + + booking = nil + ActiveRecord::Base.transaction do + booking = Booking.create({ + :dining_facility_id => params[:dining_id], + :type => "TableBooking", + :checkin_by => current_login_employee.name, + :checkin_at => checkin_at, + :checkout_at => checkout_at, + :booking_status => "assign", + :reserved_at => checkout_at, + :reserved_by => current_login_employee.name }) + + dining_facility.status = "occupied" + dining_facility.save! + end + + terminal = DiningFacility.find_by_id(booking.dining_facility_id) + cashier_terminal = CashierTerminal.find_by_id(terminal.zone_id) + + if ENV["SERVER_MODE"] != "cloud" #no print in cloud server + unique_code = "CheckInOutPdf" + printer = PrintSetting.find_by_unique_code(unique_code) + + # print when complete click + order_queue_printer = Printer::OrderQueuePrinter.new(printer) + + if !printer.nil? + order_queue_printer.print_check_in_out(printer, cashier_terminal, booking, dining_facility) + end + end + render :json => { :status => true, :booking_id => booking.booking_id, :checkin_at => booking.checkin_at.strftime("%Y-%m-%d %H:%M"), :checkout_at => booking.checkout_at.strftime("%Y-%m-%d %H:%M") } else - booking = dining_facility.current_checkout_booking - if booking.nil? - lookup_checkout_time = Lookup.collection_of("checkout_time") - - if !lookup_checkout_time.empty? - today = Time.now.utc.getlocal - checkout_at = Time.now.utc.getlocal - - lookup_checkout_time.each do |checkout_time| - arr_time = checkout_time[0].split("-") - start_time = Time.parse(arr_time[0].strip).utc.getlocal.strftime("%H:%M%p") - end_time = Time.parse(arr_time[1].strip).utc.getlocal.strftime("%H:%M%p") - if start_time <= today.strftime("%H:%M%p") && today.strftime("%H:%M%p") <= end_time - checkout_at = checkout_at + (checkout_time[1]).to_i.minutes - end - end - - if checkout_at.strftime("%Y-%m-%d %H:%M%p") >= today.strftime("%Y-%m-%d %H:%M%p") - # if dining_facility.type == "Table" - # type = "TableBooking" - # else - # type = "RoomBooking" - # end - - booking = Booking.create({:dining_facility_id => params[:dining_id],:type => "TableBooking", - :checkin_by=>current_login_employee.name,:checkin_at => Time.now.utc,:checkout_at =>checkout_at, :booking_status => "assign", :reserved_at => checkout_at, :reserved_by => current_login_employee.name }) - if booking.save! - dining_facility.status = "occupied" - dining_facility.save! - end - terminal = DiningFacility.find_by_id(booking.dining_facility_id) - cashier_terminal = CashierTerminal.find_by_id(terminal.zone_id) - - if ENV["SERVER_MODE"] != "cloud" #no print in cloud server - - unique_code = "CheckInOutPdf" - printer = PrintSetting.find_by_unique_code(unique_code) - - # print when complete click - order_queue_printer = Printer::OrderQueuePrinter.new(printer) - - if !printer.nil? - order_queue_printer.print_check_in_out(printer, cashier_terminal, booking, dining_facility) - end - end - render :json => { :status => true, :booking_id => booking.booking_id, :checkout_at => booking.checkout_at.utc.getlocal.strftime("%Y-%m-%d %H:%M") } - else - render :json => { :status => true } - end - else - render :json => { :status => true } - end - else - render :json => { :status => false, :error_message => "Booking already exist!" } - end + render :json => { :status => false, :error_message => "Booking already exist!" } end else error_message = "#{dining_facility.type} is not available!" @@ -161,6 +128,8 @@ class Api::CheckInProcessController < Api::ApiController error_message = "dining_id is required!" render :json => { :status => false, :error_message => error_message } end + rescue ActiveRecord::RecordInvalid => exception + render :json => { :status => false, :error_message => exception.message } end def request_time diff --git a/app/controllers/api/orders_controller.rb b/app/controllers/api/orders_controller.rb index 5c314387..cdedd710 100755 --- a/app/controllers/api/orders_controller.rb +++ b/app/controllers/api/orders_controller.rb @@ -41,13 +41,13 @@ class Api::OrdersController < Api::ApiController @booking = table.get_booking end - @tax_profile = nil + @tax_profile = TaxProfile.where("lower(group_type)='cashier'") # arr_tax = [] # if !arr_tax.empty? # @tax_profile = TaxProfile.where(:id => arr_tax) # else - @tax_profile = TaxProfile.where("lower(group_type)='cashier'") + # @tax_profile = TaxProfile.where("lower(group_type)='cashier'") # end # diff --git a/app/controllers/origami/payments_controller.rb b/app/controllers/origami/payments_controller.rb index a5b38db2..a008ca63 100755 --- a/app/controllers/origami/payments_controller.rb +++ b/app/controllers/origami/payments_controller.rb @@ -90,6 +90,7 @@ class Origami::PaymentsController < BaseOrigamiController latest_order_no = nil is_kbz = params[:is_kbz] + if saleObj = Sale.find(sale_id) sale_items = SaleItem.get_all_sale_items(sale_id) @@ -106,7 +107,7 @@ class Origami::PaymentsController < BaseOrigamiController sp.kbz_edit_sale_payment(sp.received_amount.to_f, current_user) end - if !path.include? ("credit_payment") + rebate_amount = nil # For Cashier by Zone @@ -200,12 +201,18 @@ class Origami::PaymentsController < BaseOrigamiController item_price_by_accounts = SaleItem.calculate_price_by_accounts(saleObj.sale_items) discount_price_by_accounts = SaleItem.get_discount_price_by_accounts(saleObj.sale_items) other_amount = SaleItem.calculate_other_charges(sale_items) + credit_pdf = Lookup.find_by_lookup_type("credit_pdf") + if (path.include? ("credit_payment")) && !credit_pdf.nil? && credit_pdf.value.to_i == 1 + printed_status = 'credit_payment' + else + printed_status = 'Paid' + end printer = Printer::ReceiptPrinter.new(print_settings) filename, sale_receipt_no, printer_name = printer.print_receipt_bill(print_settings, false, nil, cashier_terminal, sale_items, saleObj, customer.name, item_price_by_accounts, discount_price_by_accounts, member_info, rebate_amount, current_shop, "Paid", current_balance, card_data, other_amount, latest_order_no, card_balance_amount, nil) #end - end + if !saleObj.nil? # InventoryJob.perform_now(self.id) # InventoryDefinition.calculate_product_count(saleObj) diff --git a/app/controllers/reports/receipt_no_detail_controller.rb b/app/controllers/reports/receipt_no_detail_controller.rb index 9102d6d5..2eba9e18 100755 --- a/app/controllers/reports/receipt_no_detail_controller.rb +++ b/app/controllers/reports/receipt_no_detail_controller.rb @@ -40,7 +40,6 @@ authorize_resource :class => false @shift_data = sh end end - respond_to do |format| format.html format.xls diff --git a/app/models/card_sale_tran.rb b/app/models/card_sale_tran.rb index 4ff5ffb9..fdd0f501 100644 --- a/app/models/card_sale_tran.rb +++ b/app/models/card_sale_tran.rb @@ -41,7 +41,7 @@ class CardSaleTran < ApplicationRecord if payment_type.blank? payment = '' else - payment = " app LIKE '#{payment_type}'" + payment = " app LIKE '#{payment_type}'" end if from.present? && to.present? @@ -52,7 +52,7 @@ class CardSaleTran < ApplicationRecord if shift.present? query1 = cardSale.where("s.shift_sale_id in (?)", shift.to_a) - elsif shift_sale_range.present? + elsif shift_sale_range.present? query1 = cardSale.where("s.shift_sale_id in (?)",shift_sale_range.to_a) else query1 = cardSale.where("DATE_FORMAT(s.receipt_date,'%Y-%m-%d') between ? and ?",from,to) @@ -67,7 +67,6 @@ class CardSaleTran < ApplicationRecord shift_closed_at As closing_date,") .order("shift_sales.id DESC") return query = query.where("shift_sales.shift_started_at >= ?" , from) - # byebug end -end \ No newline at end of file +end diff --git a/app/models/card_settle_tran.rb b/app/models/card_settle_tran.rb index 5e0695d8..2829c9df 100644 --- a/app/models/card_settle_tran.rb +++ b/app/models/card_settle_tran.rb @@ -12,7 +12,7 @@ class CardSettleTran < ApplicationRecord if payment_type.blank? payment = '' else - payment = " req_type LIKE '#{payment_type}'" + payment = " req_type LIKE '#{payment_type}'" end if status_type.blank? @@ -46,10 +46,10 @@ class CardSettleTran < ApplicationRecord query = CardSettleTran.joins("Join shift_sales ss ON ss.id = card_settle_trans.shift_sale_id"+ " JOIN employees e ON e.id = ss.employee_id") cardSettle = query.where("DATE_FORMAT(req_date,'%Y-%m-%d') >= ? and DATE_FORMAT(req_date,'%Y-%m-%d') <= ? and status = 'Approved'",from,to) - + if shift.present? query1 = cardSettle.where("ss.id in (?)", shift.to_a) - elsif shift_sale_range.present? + elsif shift_sale_range.present? query1 = cardSettle.where("ss.id in (?)",shift_sale_range.to_a) else query1 = cardSettle.where("DATE_FORMAT(req_date,'%Y-%m-%d') between ? and ?",from,to) @@ -64,6 +64,5 @@ class CardSettleTran < ApplicationRecord shift_closed_at As closing_date,") .order("shift_sales.id DESC") return query = query.where("shift_sales.shift_started_at >= ?" , from) - # byebug - end + end end diff --git a/app/models/inventory_definition.rb b/app/models/inventory_definition.rb index a1393556..aff3b64a 100755 --- a/app/models/inventory_definition.rb +++ b/app/models/inventory_definition.rb @@ -1,5 +1,8 @@ class InventoryDefinition < ApplicationRecord + has_many :stock_journals + has_one :menu_item_instance, foreign_key: "item_instance_code", primary_key: "item_code" + scope :active, -> {where(:is_active => true)} def self.calculate_product_count(saleObj=nil,saleobj_after_req_bill=nil) @@ -71,7 +74,7 @@ class InventoryDefinition < ApplicationRecord end def self.search_by_category(cat_id) - @inventory_definitions = InventoryDefinition.select("inventory_definitions.*, + inventory_definitions = InventoryDefinition.select("inventory_definitions.*, mi.name as item_name,mii.item_instance_name as instance_name," + "mi.item_code as item_code,mii.item_instance_code as instance_code," + "mc.name as menu_category_name,mc.id as menu_category_id ") @@ -84,27 +87,29 @@ class InventoryDefinition < ApplicationRecord end def self.get_by_category(filter) - least_stock = StockJournal.select(:balance).joins("JOIN inventory_definitions ON stock_journals.item_code = inventory_definitions.item_code").order(:id => :desc).limit(1).to_sql + least_stock = StockJournal.select(:inventory_definition_id, :credit, :debit, :balance) + .joins("JOIN ( + #{StockJournal.select("item_code, MAX(created_at) created_at").group(:item_code).to_sql}) last_stock_journals + ON last_stock_journals.item_code = stock_journals.item_code + AND last_stock_journals.created_at = stock_journals.created_at").to_sql - @inventory_definitions = InventoryDefinition.select("inventory_definitions.*, - (CASE WHEN sj.credit IS NULL THEN 0 ELSE sj.credit END) as credit, - (CASE WHEN sj.debit IS NULL THEN 0 ELSE sj.debit END) as debit, - (#{least_stock}) as balance,"+ - "acc.title as account_name,mi.name as item_name, - mii.item_instance_name as instance_name," + - "mc.name as menu_category_name,mc.id as menu_category_id " - ) - .joins(" LEFT JOIN stock_journals sj ON sj.inventory_definition_id=inventory_definitions.id") - .joins("JOIN menu_item_instances mii ON mii.item_instance_code = inventory_definitions.item_code" + - " JOIN menu_items mi ON mi.id = mii.menu_item_id" + - " JOIN menu_categories mc ON mc.id = mi.menu_category_id ") - .joins(" JOIN accounts acc ON acc.id = mi.account_id") - .where("(inventory_definitions.item_code LIKE ? OR inventory_definitions.min_order_level LIKE ? - OR inventory_definitions.max_stock_level LIKE ? OR sj.balance LIKE ? OR mi.name LIKE ? - OR mii.item_instance_name LIKE ? OR mc.name LIKE ?)","%#{filter}%","%#{filter}%","%#{filter}%", - "%#{filter}%","%#{filter}%","%#{filter}%","%#{filter}%") - .group("mi.menu_category_id,inventory_definitions.item_code") - .order("balance asc, mi.name asc,acc.title desc,mi.menu_category_id desc") + inventory_definitions = InventoryDefinition + .select("inventory_definitions.*, + stock_journals.credit as credit, + stock_journals.debit as debit, + stock_journals.balance as balance, + accounts.title as account_name, + menu_items.name as item_name, + menu_item_instances.item_instance_name as instance_name, + menu_categories.name as menu_category_name, + menu_categories.id as menu_category_id") + .joins("LEFT JOIN (#{least_stock}) stock_journals on stock_journals.inventory_definition_id = inventory_definitions.id") + .joins(menu_item_instance: { menu_item: [:menu_category, :account]}) + .where("inventory_definitions.item_code LIKE :filter OR inventory_definitions.min_order_level LIKE :filter + OR inventory_definitions.max_stock_level LIKE :filter OR stock_journals.balance LIKE :filter OR menu_items.name LIKE :filter + OR menu_item_instances.item_instance_name LIKE :filter OR menu_categories.name LIKE :filter", filter: "%#{filter}%") + .group("menu_items.menu_category_id, inventory_definitions.item_code") + .order("balance asc, menu_items.name asc, accounts.title desc, menu_items.menu_category_id desc") end end diff --git a/app/models/printer/receipt_printer.rb b/app/models/printer/receipt_printer.rb index 840631cf..c250a464 100755 --- a/app/models/printer/receipt_printer.rb +++ b/app/models/printer/receipt_printer.rb @@ -119,11 +119,15 @@ class Printer::ReceiptPrinter < Printer::PrinterWorker if count == 1 filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf" pdf.render_file filename - if printed_status != 'Paid' + if printed_status != 'Paid' && printed_status != 'credit_payment' #no print in cloud server if ENV["SERVER_MODE"] != "cloud" self.print(directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf", cashier_terminal.printer_name) end + elsif printed_status == 'credit_payment' + filename = directory_name + "/receipt_bill_credit_#{sale_data.receipt_no}.pdf" + pdf.render_file filename + self.print(directory_name + "/receipt_bill_credit_#{sale_data.receipt_no}.pdf", cashier_terminal.printer_name) end else filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}_#{count}.pdf" diff --git a/app/models/sale.rb b/app/models/sale.rb index 7e1ff6ad..e7ace120 100644 --- a/app/models/sale.rb +++ b/app/models/sale.rb @@ -748,43 +748,29 @@ class Sale < ApplicationRecord end def self.search_credit_sales(customer,filter,from,to,order_source="") - if filter.blank? - keyword = '' - else - keyword = "and sales.receipt_no LIKE ? OR sales.cashier_name LIKE ? OR sales.sale_status ='#{filter}'","%#{filter}%","%#{filter}%" - end - - if customer.blank? - custo = '' - else - custo = "and sales.customer_id = '#{customer}'" - end - order_source_query = "(select orders.source FROM orders JOIN sale_orders so ON so.order_id=orders.order_id WHERE so.sale_id=sales.sale_id GROUP BY so.sale_id)" - if order_source.blank? - source = "" - else - if order_source == "cashier" - source = "and #{order_source_query}='cashier' or #{order_source_query}='emenu'" - else - source = "and #{order_source_query}='#{order_source}'" - end - end + sale = Sale.select(Sale.column_names) + .select(SalePayment.column_names) + .select(:source).includes(:customer) + .joins(:sale_payments, :orders) + .where(sale_payments: {payment_method: 'creditnote'}) + .group(:sale_payment_id) if from.present? && to.present? - sale = Sale.select("sales.*,#{order_source_query} as source").joins("JOIN sale_payments sp on sp.sale_id = sales.sale_id") - .joins(" JOIN bookings ON bookings.sale_id=sales.sale_id") - .joins(" JOIN booking_orders ON booking_orders.booking_id=bookings.booking_id") - .joins(" JOIN orders ON orders.order_id=booking_orders.order_id") - .where("DATE_FORMAT(receipt_date,'%d-%m-%Y') >= ?" + " AND DATE_FORMAT(receipt_date,'%d-%m-%Y') <= ? and (CASE WHEN (sales.grand_total + sales.amount_changed)=(select SUM(sale_payments.payment_amount) - FROM sale_payments WHERE sale_payments.sale_id=sales.sale_id AND sale_payments.payment_method!='creditnote') THEN NULL ELSE payment_method='creditnote' END) #{keyword} #{custo} #{source}", from,to) - else - sale = Sale.select("sales.*,#{order_source_query} as source").joins(" JOIN sale_payments sp on sp.sale_id = sales.sale_id") - .joins(" JOIN bookings ON bookings.sale_id=sales.sale_id") - .joins(" JOIN booking_orders ON booking_orders.booking_id=bookings.booking_id") - .joins(" JOIN orders ON orders.order_id=booking_orders.order_id") - .where("(CASE WHEN (sales.grand_total + sales.amount_changed)=(select SUM(sale_payments.payment_amount) - FROM sale_payments WHERE sale_payments.sale_id=sales.sale_id AND sale_payments.payment_method!='creditnote') THEN NULL ELSE payment_method='creditnote' END) #{keyword} #{custo} #{source}") + sale = sale.receipt_date_between(from, to) end + + if filter.present? + sale = sale.where("sales.receipt_no LIKE ? OR sales.cashier_name LIKE ? OR sales.sale_status = ?", "%#{filter}%", "%#{filter}%", filter) + end + + if customer.present? + sale = sale.where(customer_id: customer) + end + + if order_source.present? + sale = sale.where(orders: {source: order_source}) + end + return sale end def self.get_rounding_adjustment(num) @@ -817,8 +803,10 @@ def self.daily_sales_list(from,to) SUM(case when (sale_payments.payment_method='dinga') then sale_payments.payment_amount else 0 end) as dinga_amount, SUM(case when (sale_payments.payment_method='JunctionPay') then sale_payments.payment_amount else 0 end) as junctionpay_amount, SUM(case when (sale_payments.payment_method='cash') then sale_payments.payment_amount else 0 end) as cash_amount, - CASE WHEN SUM(case when sale_payments.payment_method not in('creditnote') then sale_payments.payment_amount end) < sales.grand_total - THEN sales.grand_total - SUM(case when sale_payments.payment_method not in('creditnote') then sale_payments.payment_amount end) + CASE WHEN SUM(case when sale_payments.payment_method not in('creditnote') + then sale_payments.payment_amount else 0 end) < sales.grand_total + THEN sales.grand_total - SUM(case when sale_payments.payment_method not in('creditnote') + then sale_payments.payment_amount else 0 end) ELSE 0 END as credit_amount, SUM(case when (sale_payments.payment_method='giftvoucher') then sale_payments.payment_amount else 0 end) as giftvoucher_amount, SUM(case when (sale_payments.payment_method='foc') then sale_payments.payment_amount else 0 end) as foc_amount") @@ -1475,33 +1463,32 @@ def grand_total_after_rounding end def get_cash_amount - cash = 0.0 - self.sale_payments.each do |pay| - if pay.payment_method == 'cash' - cash += pay.payment_amount - end - end - return cash - self.amount_changed + self.sale_payments.where(payment_method: 'cash', payment_status: 'paid') + .pluck(:payment_amount).reduce(0, :+) - self.amount_changed end def get_credit_amount - credit = 0.0 - self.sale_payments.each do |pay| - if pay.payment_method == 'creditnote' - credit += pay.payment_amount - end - end - return credit + self.sale_payments.where(payment_method: 'creditnote') + .pluck(:payment_status, :payment_amount) + .inject(0.0) { |sum, pay| + if pay[0] == 'outstanding' + sum += pay[1] + else + sum -= pay[1] + end + } end def get_other_amount - other = 0.0 - self.sale_payments.each do |pay| - if pay.payment_method != 'cash' && pay.payment_method != 'creditnote' - other += pay.payment_amount - end - end - return other + self.sale_payments.where.not(payment_method: ['cash', 'creditnote']) + .pluck(:payment_status, :payment_amount) + .inject(0.0) { |sum, pay| + if pay[0] == 'paid' + sum += pay[1] + else + sum -= pay[1] + end + } end def get_commerical_tax @@ -2439,15 +2426,13 @@ private end def round_to_precision - if (self.total_amount != self.total_amount_was || self.total_discount != self.total_discount_was || self.total_tax != self.total_tax_was) - if (self.total_amount % 1 > 0 || self.total_discount % 1 > 0 || self.total_tax % 1 > 0) - self.total_amount = self.total_amount.round(precision) - self.total_discount = self.total_discount.round(precision) - self.total_tax = self.total_tax.round(precision) - self.grand_total = (self.total_amount - self.total_discount) + self.total_tax - end - adjust_rounding + if (self.total_amount % 1 > 0 || self.total_discount % 1 > 0 || self.total_tax % 1 > 0) + self.total_amount = self.total_amount.round(precision) + self.total_discount = self.total_discount.round(precision) + self.total_tax = self.total_tax.round(precision) end + self.grand_total = (self.total_amount - self.total_discount) + self.total_tax + adjust_rounding end def update_stock_journal diff --git a/app/models/sale_audit.rb b/app/models/sale_audit.rb index e9e99b3d..35045763 100755 --- a/app/models/sale_audit.rb +++ b/app/models/sale_audit.rb @@ -143,7 +143,7 @@ class SaleAudit < ApplicationRecord remark = paymal[0].remark.split("}") response = "["+remark[0]+'}]' response = JSON.parse(response) - puts response + # puts response if response[0]["status"] == true if response[0]["current_rebate_amount"].present? amount = response[0]["current_rebate_amount"] diff --git a/app/models/sale_payment.rb b/app/models/sale_payment.rb index e7c89f5a..a84cdd2f 100755 --- a/app/models/sale_payment.rb +++ b/app/models/sale_payment.rb @@ -74,6 +74,8 @@ class SalePayment < ApplicationRecord #get all payment for this invoices if payment_for amount_due = SalePayment.get_credit_amount_due_left(self.sale_id).first.payment_amount + elsif payment_method == 'foc' + amount_due = invoice.total_amount else amount_due = invoice.sale_payments .map(&:payment_amount).reduce(invoice.grand_total, :-) @@ -140,9 +142,6 @@ class SalePayment < ApplicationRecord remark = "#{self.sale_payment_id}||#{shift_sale_id} -> #{remark}" sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name) - if payment_method == "cash" - update_shift_for_credit_payment - end else sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name) end @@ -235,14 +234,15 @@ class SalePayment < ApplicationRecord end def self.redeem(paypar_url,token,membership_id,received_amount,sale_id) - membership_actions_data = PaymentMethodSetting.find_by_payment_method("Redeem") + membership_actions_data = PaymentMethodSetting.find_by_payment_method("Redeem") if !membership_actions_data.nil? url = paypar_url.to_s + membership_actions_data.gateway_url.to_s merchant_uid = membership_actions_data.merchant_account_id auth_token = membership_actions_data.auth_token - campaign_type_id = JSON.parse(membership_actions_data.additional_parameters)["campaign_type_id"] + campaign_type_id = membership_actions_data.additional_parameter["campaign_type_id"] sale_data = Sale.find_by_sale_id(sale_id) + account_no = Customer.find_by_customer_id(self.sale.customer_id).paypar_account_no if sale_data others = 0 @@ -259,7 +259,7 @@ class SalePayment < ApplicationRecord redeem_amount:received_amount, receipt_no:sale_data.receipt_no, campaign_type_id:campaign_type_id, - account_no:"", + account_no: account_no, merchant_uid:merchant_uid, auth_token:auth_token}.to_json, :headers => { @@ -371,12 +371,8 @@ class SalePayment < ApplicationRecord private def cash_payment(payment_for=false) - status = false - sale_payments_data = SalePayment.find_by_sale_id(self.sale_id) - if sale_payments_data.nil? - status = true - end + sale_payments_data = SalePayment.find_by_sale_id(self.sale_id) payment_status = false self.payment_method = "cash" @@ -391,8 +387,11 @@ class SalePayment < ApplicationRecord self.payment_status = "paid" payment_status = self.save! if !payment_for - sale_update_payment_status(self.received_amount,status) + sale_update_payment_status(self.received_amount) + else + update_shift_for_credit_payment() end + balance_amount =0.0 outstanding_amount =0.0 if self.sale.grand_total.to_f > self.received_amount.to_f @@ -408,6 +407,7 @@ class SalePayment < ApplicationRecord def foc_payment payment_status = false sale = self.sale + sale.sale_payments.update_all(payment_status: "cancelled") # add to sale item with foc sale_items = sale.sale_items @@ -424,7 +424,7 @@ class SalePayment < ApplicationRecord self.payment_status = "paid" payment_status = self.save! # sale_update_payment_status(self.received_amount) - sale_update_payment_status(0) + sale_update_payment_status(0, true) return payment_status end @@ -501,7 +501,7 @@ class SalePayment < ApplicationRecord #Next time - validate if the vochure number is valid - within customer_data = Customer.find_by_customer_id(self.sale.customer_id) membership_setting = MembershipSetting.find_by_membership_type("paypar_url") - membership_data = SalePayment.redeem(membership_setting.gateway_url,membership_setting.auth_token,customer_data.membership_id,self.received_amount,self.sale.sale_id) + membership_data = redeem(membership_setting.gateway_url,membership_setting.auth_token,customer_data.membership_id,self.received_amount,self.sale.sale_id) #record an payment in sale-audit remark = "#{membership_data} Redeem- for Customer #{self.sale.customer_id} Sale Id [#{self.sale.sale_id}]| pay amount -> #{self.received_amount} " @@ -630,22 +630,32 @@ class SalePayment < ApplicationRecord def sale_update_payment_status(paid_amount, check_foc = false) #update amount_outstanding + if ['completed'].include? sale.sale_status + return + end sale = self.sale - total_payment_amount = sale.sale_payments.reload.sum(&:payment_amount) + sale_payments = sale.sale_payments.reload + + is_credit = sale_payments.any? { |x| x.payment_method == "creditnote" } + is_foc = sale_payments.any? { |x| x.payment_method == "foc" } || check_foc + + if is_foc + total_payment_amount = 0.0 + else + total_payment_amount = sale_payments.sum(&:payment_amount) + end + sale.amount_received = sale.amount_received.to_f + paid_amount.to_f sale.amount_changed = total_payment_amount - sale.grand_total.to_f - is_credit = sale.sale_payments.any? { |x| x.payment_method == "creditnote" } - is_foc = sale.sale_payments.any? { |x| x.payment_method == "foc" } - - if sale.grand_total <= total_payment_amount && sale.sale_status == "new" + if is_foc + sale.payment_status = 'foc' + sale.sale_status = 'completed' + elsif sale.grand_total <= total_payment_amount && sale.sale_status == "new" sale.payment_status = "paid" if is_credit sale.payment_status = "outstanding" end - if is_foc - sale.payment_status = "foc" - end sale.sale_status = "completed" @@ -672,26 +682,25 @@ class SalePayment < ApplicationRecord end end end + end - sale.save! + sale.save! - if check_foc - table_update_status(sale) - update_shift - elsif paid_amount.to_f > 0 #|| paid_amount != "0.0" - table_update_status(sale) - update_shift - elsif paid_amount.to_f == 0 && !is_credit - table_update_status(sale) - update_shift - end + if check_foc + table_update_status(sale) + update_shift + elsif paid_amount.to_f > 0 #|| paid_amount != "0.0" + table_update_status(sale) + update_shift + elsif paid_amount.to_f == 0 && !is_credit + table_update_status(sale) + update_shift end end # update for cashier shift def update_shift - current_shift_user = Employee.find_by_id(self.action_by.id) - shift = ShiftSale.current_open_shift(current_shift_user) + shift = ShiftSale.current_open_shift(self.action_by.id) if shift.nil? current_shift_user = Employee.find_by_id(self.sale.cashier_id) @@ -717,7 +726,10 @@ class SalePayment < ApplicationRecord # update for shift with credit payment def update_shift_for_credit_payment shift_credit = ShiftSale.find_by_id(self.sale.shift_sale_id) - shift = ShiftSale.find_by_id(ShiftSale.current_shift) + shift = self.action_by.current_shift + if !shift.nil? + shift = ShiftSale.current_shift + end if !shift.nil? credit_payment_left = get_credit_payment_left[0].payment_amount.to_f if self.payment_method == "cash" @@ -726,7 +738,6 @@ class SalePayment < ApplicationRecord else # extra_changed_amount = self.received_amount.to_f + credit_payment_left shift.cash_sales = shift.cash_sales.to_f + (self.received_amount.to_f + credit_payment_left) - self.sale.amount_received = self.sale.amount_received.to_f - credit_payment_left self.sale.amount_changed = self.sale.amount_changed.to_f - credit_payment_left self.sale.save! diff --git a/app/pdf/receipt_bill_pdf.rb b/app/pdf/receipt_bill_pdf.rb index 1d07956f..349296c3 100755 --- a/app/pdf/receipt_bill_pdf.rb +++ b/app/pdf/receipt_bill_pdf.rb @@ -64,7 +64,7 @@ class ReceiptBillPdf < Prawn::Document cashier_info(sale_data, customer_account, latest_order_no) line_items(sale_items,precision,delimiter) - all_total(sale_data,precision,delimiter) + all_total(sale_data,precision,delimiter,printed_status) if member_info != nil @@ -112,6 +112,9 @@ class ReceiptBillPdf < Prawn::Document end if kbz_pay_status + if printed_status == 'credit_payment' + printed_status = 'Paid' + end kbzpay_qr_generator(printed_status, qr_code) end @@ -323,7 +326,7 @@ class ReceiptBillPdf < Prawn::Document end - def all_total(sale_data,precision,delimiter) + def all_total(sale_data,precision,delimiter,printed_status) move_down line_move item_name_width = self.item_width y_position = cursor @@ -455,16 +458,21 @@ class ReceiptBillPdf < Prawn::Document end move_down line_move - sale_payment(sale_data,precision,delimiter) + sale_payment(sale_data,precision,delimiter,printed_status) end - def sale_payment(sale_data,precision,delimiter) + def sale_payment(sale_data,precision,delimiter,printed_status) stroke_horizontal_rule # move_down 2 move_down line_move # sql = "SELECT SUM(payment_amount) # FROM sale_payments where payment_method='creditnote' - # and sale_id='#{sale_data.sale_id}'" + # and sale_id='#{sale_data.sale_id}'" + + if printed_status == 'credit_payment' + sale_payments = SalePayment.select(:payment_amount, :payment_method, :updated_at) + .where("sale_id = '#{sale_data.sale_id}' AND payment_method != 'creditnote'") + else sql = SalePayment.select("(SUM(payment_amount))").where("payment_method='creditnote' and sale_id='#{sale_data.sale_id}'").to_sql # sql1 = "SELECT CASE WHEN s.amount_changed > 0 and (s.amount_received - s.amount_changed) = s.grand_total THEN ( SELECT SUM(payment_amount) # FROM sale_payments where payment_method='creditnote' @@ -482,13 +490,16 @@ class ReceiptBillPdf < Prawn::Document where sa.sale_id='#{sale_data.sale_id}')) = 0 THEN payment_method!='creditnote' ELSE 1 END) AND sale_id = ?", sale_data.sale_id) .group("payment_method") - + end + sale_payments.each do |payment| y_position = cursor if payment.payment_method == "paypar" bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do text "Redeem Payment", :size => self.item_font_size,:align => :left - end + end + elsif printed_status == 'credit_payment' + text "#{payment.payment_method.capitalize} Payment on #{payment.updated_at.strftime('%d-%m-%Y')}", :left_margin => -10, :size => self.item_font_size,:align => :left else payment_method = payment.payment_method.capitalize if payment.payment_method == "paymal" @@ -775,7 +786,9 @@ class ReceiptBillPdf < Prawn::Document move_down line_move stroke_horizontal_rule move_down line_move - + if printed_status == 'credit_payment' + printed_status = 'Paid' + end move_down line_move y_position = cursor bounding_box([0, y_position], :width =>self.label_width) do diff --git a/app/views/inventory/inventory_definitions/_form.html.erb b/app/views/inventory/inventory_definitions/_form.html.erb index f5d3a245..6f88b0a4 100644 --- a/app/views/inventory/inventory_definitions/_form.html.erb +++ b/app/views/inventory/inventory_definitions/_form.html.erb @@ -172,11 +172,31 @@ }); $(document).ready(function () { - var menus = JSON.parse(localStorage.getItem("menus"));; - if (menus != null) { - menu_cache_append(menus); - }else{ - $("#menu_data").removeClass("hidden"); + // var menus = JSON.parse(localStorage.getItem("menus"));; + // if (menus != null) { + // menu_cache_append(menus); + // }else{ + // getAllMenu(); + // $("#menu_data").removeClass("hidden"); + // } + getAllMenu(); + + function getAllMenu(){ + $.ajax({ + type: "GET", + url: '/origami/get_all_menu', + data: {}, + success:function(result){ + var menus = JSON.stringify(result); + localStorage.setItem("menus", menus); + if (result != null ) { + menu_cache_append(result); + $("#loading_wrapper").hide(); + $("#oqs_loading_wrapper").css("display", "none"); + $(".page-loader-wrapper").css("display", "none"); + } + } + }); } function menu_cache_append(menus){ @@ -328,6 +348,66 @@ }); //End menu category Click + //show menu item list when click menu category + function show_sub_category_list(url,sub_category,menu_id){ + + var sub_category_list = $('.sub_category_list'); + sub_category_list.empty(); + + menus = JSON.parse(localStorage.getItem("menus")); + if (menus != null) { + for(var j in menus) { + var categories = menus[j]["categories"]; + for(var ii in categories) { + if (menu_id == categories[ii]["parent_id"]) { + $(sub_category).removeClass('hidden'); + row = '' ; + $(sub_category).append(row); + } + } + } + }else{ + if (type != -1 && modify_order != -1) { + var url = "../../../addorders/"+url; + }if(modify_order== -1 && type != -1){ + var url = 'addorders/'+url; + } + if (type ==-1 && modify_order == -1){ + var url = url; + } + //Start Ajax + $.ajax({ + type: "GET", + url: url, + data: {}, + dataType: "json", + success: function(data) { + var sub_category_list = $('.sub_category_list'); + sub_category_list.empty(); + data = data.sub_category; + if (data.length > 0) { + // if ((sub_category.hasClass('hidden'))) { + $(sub_category).removeClass('hidden'); + // }else{ + // $(sub_category).addClass('hidden'); + // } + for(var i in data) { + + row = '' ; + $(sub_category).append(row); + //end is_sub_item false + } + } + } + }); + //end Ajax + } + } + //click menu sidebar menu category $(document).on('click', '.menu_sub_category', function(event){ // event.preventDefault(); diff --git a/app/views/origami/home/show.html.erb b/app/views/origami/home/show.html.erb index ef8e8e3d..b71f616a 100755 --- a/app/views/origami/home/show.html.erb +++ b/app/views/origami/home/show.html.erb @@ -1386,7 +1386,7 @@ }); } }); - } + } function check_emp_access_code(access_code,type) { var url = "/origami/check_emp_access_code/" + access_code ; diff --git a/app/views/origami/payments/show.html.erb b/app/views/origami/payments/show.html.erb index 3cd60ed0..f0c63ef6 100755 --- a/app/views/origami/payments/show.html.erb +++ b/app/views/origami/payments/show.html.erb @@ -107,9 +107,9 @@ <%if @sale_payment.nil? && @changable_tax %> <% if @current_user.role == 'cashier' %> - <% else %> + <% else %> - <% end %> + <% end %> <% end %> <%= number_format(@sale_data.total_tax, precision: precision.to_i ) rescue number_format(0, precision: precision.to_i )%> diff --git a/app/views/reports/receipt_no_detail/index.html.erb b/app/views/reports/receipt_no_detail/index.html.erb index fe4ea16a..9b42522f 100755 --- a/app/views/reports/receipt_no_detail/index.html.erb +++ b/app/views/reports/receipt_no_detail/index.html.erb @@ -26,11 +26,12 @@ <%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> ) <% end %> - - <%= t("views.right_panel.detail.shift_name") %> - <%= t("views.right_panel.detail.table") %> - <%= t("views.right_panel.detail.receipt_no") %> + + <%= t("views.right_panel.detail.receipt_no") %> + <%= t("views.right_panel.detail.receipt_date") %> + <%= t("views.right_panel.detail.shift_name") %> <%= t :cashier %> <%= t("views.right_panel.detail.name") %> + <%= t("views.right_panel.detail.table") %> <%= t("views.right_panel.detail.revenue") %>   @@ -46,24 +47,25 @@ end %> <% grand_total = grand_total + result.grand_total %> - <%= @shift_from %> - <%= @shift_to %> - <%= table_type %> - <%= table_name %> <%= result.receipt_no rescue '-' %> + <%=l result.receipt_date.getlocal, :format => :short rescue '-' %> + <%= @shift_from %> - <%= @shift_to %> <%= result.cashier_name rescue '-' %> + <%= table_type %> - <%= table_name %> <%= number_format(result.grand_total, precision: precision, delimiter: delimiter) %> - +   <%= t("views.right_panel.detail.product") %> <%= t("views.right_panel.detail.qty") %> <%= t("views.right_panel.detail.unit_price") %> - <%= t("views.right_panel.detail.total_price") %> - <%= t("views.right_panel.detail.created_at") %> + <%= t("views.right_panel.detail.total_price") %> <% result.sale_items.each do |item|%> +   <% if item.price < 0 %> <% if item.qty < 0 %> @@ -77,18 +79,18 @@ <%= item.qty rescue '-' %> <%= number_format(item.unit_price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %> - <%= number_format(item.price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %> - <%=l item.created_at.getlocal, :format => :short rescue '-' %> + <%= number_format(item.price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %> <% end %> -   +   <%survey = result.survey%> <% if !survey.nil?%>     +   No. of Guest <%= survey.total_customer rescue '-' %>   @@ -97,6 +99,7 @@ <% if !result.total_amount.nil?%> +       <%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %> @@ -107,6 +110,7 @@ <% if result.total_discount > 0 %> +       <%= t("views.right_panel.detail.total") %> @@ -119,6 +123,7 @@ <% if !result.total_tax.nil? %> +       Tax Amount @@ -133,13 +138,15 @@     - Payment <%= rec.payment_method.upcase %> - <%= number_format(rec.payment_amount, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %> ( <%= rec.payment_status %> ) +   + Payment <%= rec.payment_method.upcase %> ( <%= rec.payment_status %> ) + <%= number_format(rec.payment_amount, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %>   <% if !rec.payment_reference.nil? %> +       Payment Ref. @@ -151,6 +158,7 @@ <% end %> <% if result.amount_changed != 0 %> +       <%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %> @@ -160,6 +168,7 @@ <% end %> <% if !result.customer_id.nil?%> +       Customer @@ -176,6 +185,7 @@       +   Total Nett - <%= number_format(grand_total, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %>   diff --git a/app/views/reports/receipt_no_detail/index.xls.erb b/app/views/reports/receipt_no_detail/index.xls.erb index bd10e73b..6fe33086 100755 --- a/app/views/reports/receipt_no_detail/index.xls.erb +++ b/app/views/reports/receipt_no_detail/index.xls.erb @@ -24,12 +24,13 @@ <%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> ) <% end %> - - <%= t("views.right_panel.detail.shift_name") %> - <%= t("views.right_panel.detail.table") %> - <%= t("views.right_panel.detail.receipt_no") %> - <%= t :cashier %> <%= t("views.right_panel.detail.name") %> - <%= t("views.right_panel.detail.revenue") %> + + <%= t("views.right_panel.detail.receipt_no") %> + <%= t("views.right_panel.detail.receipt_date") %> + <%= t("views.right_panel.detail.shift_name") %> + <%= t :cashier %> <%= t("views.right_panel.detail.name") %> + <%= t("views.right_panel.detail.table") %> + <%= t("views.right_panel.detail.revenue") %>   @@ -43,25 +44,26 @@ table_type = table.type table_name = table.name end %> - - <%= @shift_from %> - <%= @shift_to %> - <%= table_type %> - <%= table_name %> + <%= result.receipt_no rescue '-' %> + <%=l result.receipt_date.getlocal, :format => :short rescue '-' %> + <%= @shift_from %> - <%= @shift_to %> <%= result.cashier_name rescue '-' %> - <%=result.grand_total%> - + <%= table_type %> - <%= table_name %> + <%= number_format(result.grand_total, precision: precision, delimiter: delimiter) %> - + +   <%= t("views.right_panel.detail.product") %> <%= t("views.right_panel.detail.qty") %> <%= t("views.right_panel.detail.unit_price") %> <%= t("views.right_panel.detail.total_price") %> - <%= t("views.right_panel.detail.created_at") %> <% result.sale_items.each do |item|%> +   <% if item.price.to_i < 0.to_i %> <% if item.qty.to_i < 0.to_i%> @@ -76,7 +78,6 @@ <%= item.qty rescue '-' %> <%= item.unit_price rescue '-' %> <%= item.price rescue '-' %> - <%=l item.created_at.utc.getlocal, :format => :short rescue '-' %> <% end %> @@ -87,6 +88,7 @@     +   No. of Guest <%= survey.total_customer rescue '-' %>   @@ -97,6 +99,7 @@     +   <%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %> <%= result.total_amount %>   @@ -107,6 +110,7 @@     +   <%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.amount") %> @@ -119,6 +123,7 @@     +   Tax Amount <%= result.total_tax %>   @@ -132,8 +137,9 @@     - Payment <%= rec.payment_method.upcase %> - <%= rec.payment_amount %> ( <%= rec.payment_status %> ) +   + Payment <%= rec.payment_method.upcase %>( <%= rec.payment_status %> ) + <%= rec.payment_amount %>   @@ -141,6 +147,7 @@     +   Payment Ref. <%= rec.payment_reference %>   @@ -152,6 +159,7 @@     +   <%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %> <%= result.amount_changed %>   @@ -161,6 +169,7 @@     +   Customer <%= result.customer.name rescue '-'%> (<%= result.customer.company rescue '-' %>) @@ -175,6 +184,7 @@       +   Total Nett - <%= grand_total %>   diff --git a/app/views/transactions/credit_notes/index.html.erb b/app/views/transactions/credit_notes/index.html.erb index dac13cd9..1aed10b5 100755 --- a/app/views/transactions/credit_notes/index.html.erb +++ b/app/views/transactions/credit_notes/index.html.erb @@ -19,7 +19,7 @@
- +
@@ -48,7 +48,7 @@
-
+ <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 31781d4f..a0eec287 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -88,7 +88,7 @@ en: debit: "Debit" reservation: "Reservation" make_reservation: "Make Reservation" - + views: btn: create: "Create" @@ -444,6 +444,7 @@ en: sale_item_report: "Sale Item Report" select_period: "Select Period" shift_name: "Shift Name" + receipt_date: "Receipt Date" code: "Code" item: "Item" revenue: "Revenue" @@ -503,7 +504,7 @@ en: checked_by: "Checked By" order_source: "Order Source" paymal_transactions: "Paymal Transactions" - + code_txt: "code " charge_txt: "charge" time_txt: "time" diff --git a/lib/tasks/shift_sales.rake b/lib/tasks/shift_sales.rake new file mode 100644 index 00000000..9f7e92b3 --- /dev/null +++ b/lib/tasks/shift_sales.rake @@ -0,0 +1,153 @@ +namespace :shift_sales do + desc "TODO" + task :audit, [:shift_sale_ids, :shop_code, :repayment] => [:environment] do |tasks, args| + Rails.logger = Logger.new(STDOUT) + + if args[:shift_sale_ids].empty? + return + end + + if args[:shift_sale_ids].include? '..' + shift_sales_ids = args[:shift_sale_ids].split('..').inject { |s,e| s.to_i..e.to_i } + else + shift_sales_ids = args[:shift_sale_ids].split(' ') + end + + shift_sales_ids.each do |shift_sale_id| + ActiveRecord::Base.transaction do + shift_sale = ShiftSale.find(shift_sale_id) + + total_revenue = 0 + total_discounts = 0 + total_taxes = 0 + grand_total = 0 + cash_sales = 0 + credit_sales = 0 + other_sales = 0 + nett_sales = 0 + commercial_taxes = 0 + total_rounding = 0 + total_receipt = 0 + total_void = 0 + dining_count = 0 + takeaway_count = 0 + + sales = shift_sale.sales.order(:created_at) + sales.each do |sale| + + sale.grand_total = sale.total_amount - sale.total_discount + sale.total_tax + sale.old_grand_total = grand_total + + if args[:shop_code] + shop = Shop.find_by!(shop_code: args[:shop_code]) + else + shop = Shop.first + end + + if shop.is_rounding_adj + new_total = Sale.get_rounding_adjustment(sale.grand_total) + sale.rounding_adjustment = new_total - sale.grand_total + sale.old_grand_total = sale.grand_total + sale.grand_total = new_total + else + sale.rounding_adjustment = 0.00 + end + + sale.amount_changed = sale.amount_received - sale.grand_total + + cash_amount = 0 + credit_amount = 0 + other_amount = 0 + + sale_payments = sale.sale_payments.order(:created_at) + sale_payments.each do |sale_payment| + + if sale_payment.payment_method == 'creditnote' + credit_amount += sale_payment.payment_amount + else + if SaleAudit.where("SUBSTRING_INDEX(sale_audits.remark,'||',1) = ? AND sale_audits.sale_id = ?", sale_payment.sale_payment_id, sale.sale_id).exists? + if sale_payment.created_at.between?(shift_sale.shift_started_at, shift_sale.shift_closed_at) + if credit_amount >= sale_payment.payment_amount + credit_amount -= sale_payment.payment_amount + else + credit_amount = 0 + end + if sale_payment.payment_method == 'cash' + cash_amount += sale_payment.payment_amount + else + other_amount += sale_payment.payment_amount + end + end + else + if sale_payment.payment_method == 'cash' + cash_amount += sale_payment.payment_amount + else + other_amount += sale_payment.payment_amount + end + sale_payment.outstanding_amount = sale.grand_total - sale_payment.payment_amount + sale_payment.update_columns(outstanding_amount: sale_payment.outstanding_amount) + end + end + end + + sale.update_columns( + grand_total: sale.grand_total, + old_grand_total: sale.old_grand_total, + rounding_adjustment: sale.rounding_adjustment, + amount_changed: sale.amount_changed + ) + + if sale.sale_status != 'void' + total_revenue += sale.total_amount + total_discounts += sale.total_discount + total_taxes += sale.total_tax + grand_total += sale.grand_total + cash_sales += cash_amount - sale.amount_changed + credit_sales += credit_amount + other_sales += other_amount + nett_sales += sale.total_amount - sale.total_discount + commercial_taxes += sale.get_commerical_tax + total_rounding += sale.rounding_adjustment + total_receipt += 1 + if sale.customer.customer_type == 'Dinein' + dining_count += 1 + else + takeaway_count += 1 + end + else + total_receipt += 1 + total_void += sale.grand_total + end + end + + if args[:repayment] + SalePayment.joins(:sale, :sale_audit).where(sale_payments: {created_at: shift_sale.shift_started_at..shift_sale.shift_closed_at}).where.not(sales: {shift_sale_id: shift_sale.id}).each do |sale_payment| + if sale_payment.payment_method == 'cash' + cash_amount += sale_payment.payment_amount + else + other_amount += sale_payment.payment_amount + end + end + end + + shift_sale.update_columns( + total_revenue: total_revenue, + total_discounts: total_discounts, + total_taxes: total_taxes, + grand_total: grand_total, + cash_sales: cash_sales, + credit_sales: credit_sales, + other_sales: other_sales.to_f, + nett_sales: nett_sales, + commercial_taxes: commercial_taxes, + total_rounding: total_rounding, + total_receipt: total_receipt, + total_void: total_void, + dining_count: dining_count, + takeaway_count: takeaway_count + ) + end + end + end + +end