Merge branch 'r-1902001-01' into foodcourt

This commit is contained in:
Thein Lin Kyaw
2020-05-29 13:32:16 +06:30
23 changed files with 724 additions and 508 deletions

View File

@@ -16,7 +16,7 @@ gem 'rails', '~> 5.1.0'
#gem 'mysql2', '>= 0.3.18', '< 0.5' #gem 'mysql2', '>= 0.3.18', '< 0.5'
gem 'pg' gem 'pg'
gem 'mysql2' gem 'mysql2', '~> 0.5.2'
#Use PosgreSQL #Use PosgreSQL

View File

@@ -354,7 +354,7 @@ DEPENDENCIES
material_icons material_icons
mini_magick mini_magick
momentjs-rails momentjs-rails
mysql2 mysql2 (~> 0.5.2)
nested_form nested_form
pdfjs_viewer-rails pdfjs_viewer-rails
pg pg

433
README.md
View File

@@ -4,161 +4,151 @@ SXRestuarant is a new Dedicate project for SmartSales Restaurant. It is improvem
Things you may want to cover: Things you may want to cover:
* Ruby version - Ruby version
ruby 2.4.1p111 ruby 2.4.1p111
* Membership Details - Membership Details
Osaka => Osaka =>
Auth Token => wu8YvlLmah0CL => New => v3 Auth Token => wu8YvlLmah0CL => New => v3
=> rj0MJ0XI5GsKZehE => Old => v2 => rj0MJ0XI5GsKZehE => Old => v2
=> code2lab => Old => code2lab => Old
Merchant account => RxzaYyAGzm7VqAZ4hKnv Merchant account => RxzaYyAGzm7VqAZ4hKnv
Campaign Id => {"campaign_type_id": 5} Campaign Id => {"campaign_type_id": 5}
BITP BITP
Auth Token => pZBHXEFbGNj/G => New => V3 Auth Token => pZBHXEFbGNj/G => New => V3
iua0SjUHzRaQw iua0SjUHzRaQw
=> rj0MJ0XI5GsKZehE => Old => V2 => rj0MJ0XI5GsKZehE => Old => V2
=> code2lab => Old => code2lab => Old
Merchant account => vWSsseoZCzxd6xcNf_uS Merchant account => vWSsseoZCzxd6xcNf_uS
Campaign Id => {"campaign_type_id": 1} Campaign Id => {"campaign_type_id": 1}
java -jar ~/Documents/Jade.jar http://192.168.1.88:3002 java -jar ~/Documents/Jade.jar http://192.168.1.88:3002
java -jar ~/Documents/c2l_jade.jar http://192.168.1.151:3002 java -jar ~/Documents/c2l_jade.jar http://192.168.1.151:3002
Person and Extra Time Person and Extra Time
category_code = SPL... //for menu categories special category_code = SPL... //for menu categories special
1) must create Person in settings/accounts
2) must create Adult and Child in settings/item_attributes 1. must create Person in settings/accounts
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 2. must create Adult and Child in settings/item_attributes
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 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 For Extra Time
item_instance_code item_instance_code
* must start with 'Ext'[a..z]'_'[1..100]
* note : don't add character after '_' - must start with 'Ext'[a..z]'\_'[1..100]
- note : don't add character after '\_'
For Order Printing For Order Printing
1)) ********* Order Pdf ********* 1)) \***\*\*\*\*** Order Pdf \***\*\*\*\*** 1) settings/print_settings
1) settings/print_settings (a) Unique Code => OrderItemPdf & OrderSummaryPdf
(a) Unique Code => OrderItemPdf & OrderSummaryPdf (b) Font is present => {Header font size:11, Item Font Size:9}
(b) Font is present => {Header font size:11, Item Font Size:9} Font is blank => {Header font size:12, Item Font Size:10}
Font is blank => {Header font size:12, Item Font Size:10} 2)) \***\*\*\*\*** Order Set Pdf \***\*\*\*\*** 1) settings/print_settings
2)) ********* Order Set Pdf ********* (a) Unique Code => OrderSetItemPdf & OrderSummarySetPdf
1) settings/print_settings (b) Font is present => {Header font size:11, Item Font Size:9}
(a) Unique Code => OrderSetItemPdf & OrderSummarySetPdf Font is blank => {Header font size:12, Item Font Size:10}
(b) Font is present => {Header font size:11, Item Font Size:9} 3)) \***\*\*\*\*** Order Slim Pdf \***\*\*\*\*** 1) settings/print_settings
Font is blank => {Header font size:12, Item Font Size:10} (a) Unique Code => OrderItemSlimPdf & OrderSummarySlimPdf
3)) ********* Order Slim Pdf ********* (b) Font is present => {Header font size:11, Item Font Size:9}
1) settings/print_settings Font is blank => {Header font size:12, Item Font Size:10}
(a) Unique Code => OrderItemSlimPdf & OrderSummarySlimPdf 4)) \***\*\*\*\*** Order Customise PDF \***\*\*\*\*** 1) settings/print_settings
(b) Font is present => {Header font size:11, Item Font Size:9} (a) Unique Code => OrderItemCustomisePdf & OrderSummaryCustomisePdf
Font is blank => {Header font size:12, Item Font Size:10} (b) Can change Header font size and Item Font Size as you like
4)) ********* Order Customise PDF ********* 5)) \***\*\*\*\*** Order Set Pdf \***\*\*\*\*** 1) settings/print_settings
1) settings/print_settings (a) Unique Code => OrderSetItemCustomisePdf & OrderSummarySetCustomisePdf
(a) Unique Code => OrderItemCustomisePdf & OrderSummaryCustomisePdf (b) Can change Header font size and Item Font Size as you like
(b) Can change Header font size and Item Font Size as you like 6)) \***\*\*\*\*** Order Slim Customise PDF 1) settings/print_settings
5)) ********* Order Set Pdf ********* (a) Unique Code => OrderItemSlimCustomisePdf & OrderSummarySlimCustomisePdf
1) settings/print_settings (b) Can change Header font size and Item Font Size as you like
(a) Unique Code => OrderSetItemCustomisePdf & OrderSummarySetCustomisePdf For Check in-out Printing \***\*\*\*\*** Check in-out Pdf \***\*\*\*\*** 1) settings/print_settings
(b) Can change Header font size and Item Font Size as you like (a) Unique Code => CheckInOutPdf
6)) ********* Order Slim Customise PDF (b) Heading Space => 5
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 For ReceiptBillA5Pdf
*** change ReceiptBillPdf to 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 }
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 For ReceiptBillAltName options 1) settings/lookups => { type:print_settings, name:ReceiptBillAltName, value:1 }
1) settings/lookups => { type:print_settings, name:ReceiptBillAltName, value:1 }
For Using Star Printer For Using Star Printer
*** Need to change these print settings **_ 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
1) settings/print_settings/unique_code => OrderItemStarPdf _** Other print settings aren't need to change.
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 For Show Sale Items Summary at CloseCashierPrint 1) settings/print_settings
1) settings/print_settings a) Check => Shift Sale Items
a) Check => Shift Sale Items
For Show/Hide AddOrder Button in QuickService For Show/Hide AddOrder Button in QuickService 1) settings/lookups => {type:quickservice_add_order, name: QuickServiceAddOrder, value:1 OR 0}
1) settings/lookups => {type:quickservice_add_order, name: QuickServiceAddOrder, value:1 OR 0}
For Show Print Button in ReceiptNo Report For Show Print Button in ReceiptNo Report 1) settings/lookups => {type:reprint_receipt, name: Reprint Receipt in Report, value:1}
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 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 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 } 1. checkout time => { type: checkout_time, name: 9:00 AM - 12:00 PM, value: 120 }
* you can add multiple record for checkout time and checkout alert time 2. checkout alert time => { type: checkout_alert_time, name: 8:00 AM - 12:00 PM, value: 60 }
* type must be 'checkout_time' and 'checkout_alert_time'
* you can change name and value - you can add multiple record for checkout time and checkout alert time
* name must be time range [12hr => 8:30 AM - 1:45 PM, 24hr => 8:00 - 13:45] - type must be 'checkout_time' and 'checkout_alert_time'
* value must be minutes[60] - 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 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 - Backend > Printer > Print Settings > New
* update membership_actions set additional_parameter='{\"campaign_type_id\":5}' where id=10; 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 Membership Actions SQL \* update membership_actions set additional_parameter='{\"campaign_type_id\":5}' where id=10;
* update seed_generators
i) TableBooking, Order, OrderItem, sale, SaleOrder, SaleItem, SaleTax, SalePayment, SaleAudit, AssignedOrderItem => { current:0, next:0 } SQL Update after rake clear:data runned \* update seed_generators
** Note :: do not update Customer i) TableBooking, Order, OrderItem, sale, SaleOrder, SaleItem, SaleTax, SalePayment, SaleAudit, AssignedOrderItem => { current:0, next:0 }
\*\* Note :: do not update Customer
Change type in mysql Change type in mysql
*run if you got font error for Myanmar, Chinese, etc... \*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 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 => ALTER DATABASE [database_name] CHARACTER SET utf8 COLLATE utf8_unicode_ci #for database
For split bill For split bill 1) settings/lookups => { type:split_bill, name:SplitBill, value:1 }
1) settings/lookups => { type:split_bill, name:SplitBill, value:1 }
For Sidekiq For Sidekiq 1) If you want to use sidekiq
1) If you want to use sidekiq => Create New Lookups => lookup_type = sidekiq, Name = sidekiq , Value = 1 or 0
=> Create New Lookups => lookup_type = sidekiq, Name = sidekiq , Value = 1 or 0
For Clear Menu For Clear Menu 1) rake clear:menu # menu,menu item,menu category,menu item instance,account,item option,item attribute,item set
1) rake clear:menu # menu,menu item,menu category,menu item instance,account,item option,item attribute,item set
For Check CUp status For Check CUp status
###please open ###please open
sudo cat /etc/sudoers sudo cat /etc/sudoers
### cope and parse ### cope and parse
%superuser ALL=(ALL) NOPASSWD: ALL %superuser ALL=(ALL) NOPASSWD: ALL
<---- Extra Fields Script -----> <---- Extra Fields Script ----->
DROP TABLE IF EXISTS `display_images`; DROP TABLE IF EXISTS `display_images`;
CREATE TABLE `display_images` ( CREATE TABLE `display_images` (
`id` bigint(20) NOT NULL AUTO_INCREMENT, `id` bigint(20) NOT NULL AUTO_INCREMENT,
`shop_id` int(11) DEFAULT NULL, `shop_id` int(11) DEFAULT NULL,
`image` blob, `image` blob,
`created_by` varchar(255) DEFAULT NULL, `created_by` varchar(255) DEFAULT NULL,
`created_at` datetime NOT NULL, `created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL, `updated_at` datetime NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE customers ALTER TABLE customers
@@ -190,118 +180,104 @@ ADD COLUMN group_type VARCHAR(255) after name;
<---- Extra Fields Script -----> <---- Extra Fields Script ----->
For CloseCashierCustomisePdf in lookups For CloseCashierCustomisePdf in lookups
*** change CloseCashierPdf to CloseCashierCustomisePdf \*\*\* change CloseCashierPdf to CloseCashierCustomisePdf 1) settings/print_settings 2) settings/lookups => { type:print_settings, name: CloseCashierCustomisePdf, value:1 }
1) settings/print_settings
2) settings/lookups => { type:print_settings, name: CloseCashierCustomisePdf, value:1 }
<---- Extra Fields Script -----> <---- Extra Fields Script ----->
For MoveTablePdf in lookups For MoveTablePdf in lookups
*** Both Table and Room Moving *** **_ Both Table and Room Moving _** 1) settings/lookups => { type:print_settings, name: MoveTablePdf, value:1 }
1) settings/lookups => { type:print_settings, name: MoveTablePdf, value:1 }
For MoveTablePdf in print settings For MoveTablePdf in print settings \* Backend > Printer > Print Settings > New
* Backend > Printer > Print Settings > New i) Name : Move Table
i) Name : Move Table ii) Unique Code: MoveTablePdf
ii) Unique Code: MoveTablePdf iii)Template: ...
iii)Template: ... iv) Font: Zawgyi-One v) Printer: #printer name
iv) Font: Zawgyi-One v) Printer: #printer name
/* Tax Profile Group Types in lookups */ /_ 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 */
/*Receipt Pdf View in lookups */ 1. settings/lookups => { type:tax_profiles, name: Cashier, value:cashier }
1) settings/lookups => { type:ReceiptPdfView, name: Receipt Pdf View, value:1 or 0 } 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 => 1 is active and 0 is in-active
Add Kitchen Role of Employee Add Kitchen Role of Employee
=> 1) settings/lookups => { type:employee_roles, name: Kitchen, value:kitchen } => 1) settings/lookups => { type:employee_roles, name: Kitchen, value:kitchen }
Add Base URL for DOEMAL 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}' }
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 Add Feature for Dine-in Cashier
** '0' means can not use dine-in cashier and '1' means can use 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}' } => settings/lookups => { type:dinein_cashier, name: DineInCashier, value:'{0 or 1}' }
Add Feature for Quick Service Add Feature for Quick Service
** '0' means can not use quick service and '1' means can use 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}' } => settings/lookups => { type:quick_service, name: QuickService, value:'{0 or 1}' }
Add Feature for Order and Reservation Add Feature for Order and Reservation
** '0' means can not use order reservation and '1' means can use order 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}' } => settings/lookups => { type:order_reservation, name: OrderReservation, value:'{0 or 1}' }
For Price 0 in receipt bill For Price 0 in receipt bill 2) settings/lookups => { type:show_price, name:Show Price, value:1 }
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 For Aston Request => Gift Voucher 1) settings/payment_method_settings => {payment_method:'GiftVoucher', is_active:true, ...}
2) settings/lookups => { type:order_by, name:Order By, value:name }
For Aston Request => Gift Voucher For Login expiry time 1) settings/lookups => {type:expity_time, name:login, value: {minutes}} \* value should be minute only (30 / 60 / 120 / etc.)
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.)
Menu Image (Import guideline) Menu Image (Import guideline)
=> First, check shop_code, is there in shops table and prefix shop_code in image name? => First, check shop_code, is there in shops table and prefix shop_code in image name?
=> You all must do this step => 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 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. * 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. => 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. => Last, if shop has shop_code, update marked/noted shop_code into shops table again.
For Edit Order Open & Close For Edit Order Open & Close 1) settings/lookups => {type:edit_order, name:EditOrderOrigami, value: {1 or 0}}
1) settings/lookups => {type:edit_order, name:EditOrderOrigami, value: {1 or 0}}
For Dashboard Settings for supervisor and cashier 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}}
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 For Customer Settings On/Off 1) settings/lookups => {type:customer_settings, name:create, value: {1 or 0}}
1) settings/lookups => {type:customer_settings, name:create, value: {1 or 0}}
For TaxProfiles On/Off For TaxProfiles On/Off 1) settings/lookups => {type:changable_tax, name:change, value: {1 or 0}}
1) settings/lookups => {type:changable_tax, name:change, value: {1 or 0}}
For Add Kitchen Role For Add Kitchen Role 1) settings/lookups => {type:employee_roles, name:Kitchen, value:kitchen}
1) settings/lookups => {type:employee_roles, name:Kitchen, value:kitchen}
For Food Court Settings On/Off For Food Court Settings On/Off
** '0' means can not use food court and '1' means can use food court ** ** '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}' } => settings/lookups => { type:food_court, name: FoodCourt, value:'{0 or 1}' }
For Number Formats For Number Formats
Precision Precision
=> settings/lookups => { lookup_type: number_format, name: precision, value: {0..2} } => settings/lookups => { lookup_type: number_format, name: precision, value: {0..2} }
Delimiter Delimiter
=> settings/lookups => { lookup_type: number_format, name: delimiter, value: { ',', '\u0020', '', ... } => settings/lookups => { lookup_type: number_format, name: delimiter, value: { ',', '\u0020', '', ... }
Strip insignificant zeros Strip insignificant zeros
=> settings/lookups => { lookup_type: number_format, name: 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', ...] } value: {true: => ['1', 't', 'true', 'on', 'y', 'yes'], false: => ['0', 'f', 'false', 'off', 'n', 'no', ...] }
For Booking checkin time limit For Booking checkin time limit
settings/lookups => settings/lookups =>
{ lookup_type: checkin_time_limit, name: CheckinTimeLimit, value: total hours before checkout (e.g., '48')) } { lookup_type: checkin_time_limit, name: CheckinTimeLimit, value: total hours before checkout (e.g., '48')) }
/* Customer 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 } 1. settings/lookups => { type:customer_type, name: Dinein, value:Dinein }
3) settings/lookups => { type:customer_type, name: Doemal, value: Doemal } 2. settings/lookups => { type:customer_type, name: Takeaway, value: Takeaway }
4) settings/lookups => { type:customer_type, name: FoodCourt, value: FoodCourt } 3. settings/lookups => { type:customer_type, name: Doemal, value: Doemal }
/* Tax Profile Group Types in lookups */ 4. settings/lookups => { type:customer*type, name: FoodCourt, value: FoodCourt }
/* Tax Profile Group Types in lookups \_/
For Online Order Receipt Setting 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 For Close Cashier Print Settings
settings/lookups => {type:close_cashier_print, name:CloseCashierPrint, value: {0 or 1} } 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 2. Quick Service
3. Order & Reservation 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.)
* Services (job queues, cache servers, search engines, etc.)
* Deployment instructions
- Deployment instructions
* Features * Features
1. OQS 1. OQS
1. Filter 1. Filter
2. Order Item to each Stations 2. Order Item to each Stations
3. Edit Order Item 3. Edit Order Item
2. Origami(Sale) 2. Origami(Sale)
1. Sale 1. Sale
2. Add Customer for membership 2. Add Customer for membership
3. Discount and Member Discount for Sale 3. Discount and Member Discount for Sale
4. Assign Commissioner 4. Assign Commissioner
5. Add other charges to Sale 5. Add other charges to Sale
3. CRM 3. CRM
1. Customer Management 1. Customer Management
2. Queue Management 2. Queue Management
4. Backend 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 11. Membership Integration
5. Inventory
5) Inventory
6. Report 6. Report
- UI Standard
* UI Standard
1. Layout 1. Layout
1. 2-Column => Main Content - col-9, 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 2. 3-Column => Sub Lint - col-2, Main Content - col-7, Information - col-3
> Pixel > Pixel
Main Header Bar - height => 50 px Main Header Bar - height => 50 px
Side Navigation - Weight => 230 px Side Navigation - Weight => 230 px
Main Content Padding => 15 px Main Content Padding => 15 px
2. Color 2. Color
> BUTTON > BUTTON
1. Submit/Add/Edit/Confirm buttons => btn-primary (theme color) 1. Submit/Add/Edit/Confirm buttons => btn-primary (theme color)
2. Show/Detail Buttons => btn-info 2. Show/Detail Buttons => btn-info
3. Delete => btn-delete 3. Delete => btn-delete
4. Cancel/Back => btn-default 4. Cancel/Back => btn-default

View File

@@ -19,12 +19,13 @@ class Api::CheckInProcessController < Api::ApiController
table = DiningFacility.find(params[:dining_id]) table = DiningFacility.find(params[:dining_id])
#Send to background job for processing #Send to background job for processing
if ENV["SERVER_MODE"] == 'cloud' if ENV["SERVER_MODE"] == 'cloud'
from = request.subdomain + "." + request.domain from = request.subdomain + "." + request.domain
else else
from = "" from = ""
end end
ActionCable.server.broadcast "check_in_booking_channel",table: table,from:from ActionCable.server.broadcast "check_in_booking_channel",table: table,from:from
check_out_time = nil check_out_time = nil
extra_minutes = nil extra_minutes = nil
alert_time_min = 0 alert_time_min = 0
@@ -65,93 +66,59 @@ class Api::CheckInProcessController < Api::ApiController
if params[:dining_id] if params[:dining_id]
dining_facility = DiningFacility.find(params[:dining_id]) dining_facility = DiningFacility.find(params[:dining_id])
if dining_facility.is_active && dining_facility.status == "available" if dining_facility.is_active && dining_facility.status == "available"
if params[:checkin_time] if dining_facility.current_checkin_booking.nil?
checkin_at = nil if params[:checkin_time].present?
if !params[:checkin_time].empty? checkin_at = Time.parse(params[:checkin_time])
checkin_at = Time.parse(params[:checkin_time]).utc
else else
checkin_at = Time.now.utc checkin_at = Time.now
end end
if !checkin_at.nil? checkout_at = nil
if dining_facility.check_time(checkin_at, "checkin") lookup_checkout_time = Lookup.collection_of("checkout_time")
booking = dining_facility.get_current_booking today = Time.now
if booking.nil? if !lookup_checkout_time.empty?
booking = Booking.create({:dining_facility_id => params[:dining_id],:type => "TableBooking", lookup_checkout_time.each do |checkout_time|
:checkin_by=>current_login_employee.name,:checkin_at => checkin_at,:checkout_at =>nil, :booking_status => "assign", :reserved_at => nil, :reserved_by => nil }) start_time, end_time = checkout_time[0].split("-").map{ |t| Time.parse(t.strip).strftime("%H:%M%p") }
if booking.save! if start_time <= today.strftime("%H:%M%p") && today.strftime("%H:%M%p") <= end_time
dining_facility.status = "occupied" checkout_at = checkin_at + (checkout_time[1]).to_i.minutes
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!" }
end end
else
render :json => { :status => false, :error_message => "Checkin time not available!" }
end end
else
render :json => { :status => false, :error_message => "Operation failed!" }
end 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 else
booking = dining_facility.current_checkout_booking render :json => { :status => false, :error_message => "Booking already exist!" }
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
end end
else else
error_message = "#{dining_facility.type} is not available!" error_message = "#{dining_facility.type} is not available!"
@@ -161,6 +128,8 @@ class Api::CheckInProcessController < Api::ApiController
error_message = "dining_id is required!" error_message = "dining_id is required!"
render :json => { :status => false, :error_message => error_message } render :json => { :status => false, :error_message => error_message }
end end
rescue ActiveRecord::RecordInvalid => exception
render :json => { :status => false, :error_message => exception.message }
end end
def request_time def request_time

View File

@@ -41,13 +41,13 @@ class Api::OrdersController < Api::ApiController
@booking = table.get_booking @booking = table.get_booking
end end
@tax_profile = nil @tax_profile = TaxProfile.where("lower(group_type)='cashier'")
# arr_tax = [] # arr_tax = []
# if !arr_tax.empty? # if !arr_tax.empty?
# @tax_profile = TaxProfile.where(:id => arr_tax) # @tax_profile = TaxProfile.where(:id => arr_tax)
# else # else
@tax_profile = TaxProfile.where("lower(group_type)='cashier'") # @tax_profile = TaxProfile.where("lower(group_type)='cashier'")
# end # end
# #

View File

@@ -90,6 +90,7 @@ class Origami::PaymentsController < BaseOrigamiController
latest_order_no = nil latest_order_no = nil
is_kbz = params[:is_kbz] is_kbz = params[:is_kbz]
if saleObj = Sale.find(sale_id) if saleObj = Sale.find(sale_id)
sale_items = SaleItem.get_all_sale_items(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) sp.kbz_edit_sale_payment(sp.received_amount.to_f, current_user)
end end
if !path.include? ("credit_payment")
rebate_amount = nil rebate_amount = nil
# For Cashier by Zone # For Cashier by Zone
@@ -200,12 +201,18 @@ class Origami::PaymentsController < BaseOrigamiController
item_price_by_accounts = SaleItem.calculate_price_by_accounts(saleObj.sale_items) 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) discount_price_by_accounts = SaleItem.get_discount_price_by_accounts(saleObj.sale_items)
other_amount = SaleItem.calculate_other_charges(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) 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) 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
end
if !saleObj.nil? if !saleObj.nil?
# InventoryJob.perform_now(self.id) # InventoryJob.perform_now(self.id)
# InventoryDefinition.calculate_product_count(saleObj) # InventoryDefinition.calculate_product_count(saleObj)

View File

@@ -40,7 +40,6 @@ authorize_resource :class => false
@shift_data = sh @shift_data = sh
end end
end end
respond_to do |format| respond_to do |format|
format.html format.html
format.xls format.xls

View File

@@ -67,7 +67,6 @@ class CardSaleTran < ApplicationRecord
shift_closed_at As closing_date,") shift_closed_at As closing_date,")
.order("shift_sales.id DESC") .order("shift_sales.id DESC")
return query = query.where("shift_sales.shift_started_at >= ?" , from) return query = query.where("shift_sales.shift_started_at >= ?" , from)
# byebug
end end
end end

View File

@@ -64,6 +64,5 @@ class CardSettleTran < ApplicationRecord
shift_closed_at As closing_date,") shift_closed_at As closing_date,")
.order("shift_sales.id DESC") .order("shift_sales.id DESC")
return query = query.where("shift_sales.shift_started_at >= ?" , from) return query = query.where("shift_sales.shift_started_at >= ?" , from)
# byebug
end end
end end

View File

@@ -1,5 +1,8 @@
class InventoryDefinition < ApplicationRecord 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)} scope :active, -> {where(:is_active => true)}
def self.calculate_product_count(saleObj=nil,saleobj_after_req_bill=nil) def self.calculate_product_count(saleObj=nil,saleobj_after_req_bill=nil)
@@ -71,7 +74,7 @@ class InventoryDefinition < ApplicationRecord
end end
def self.search_by_category(cat_id) 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.name as item_name,mii.item_instance_name as instance_name," +
"mi.item_code as item_code,mii.item_instance_code as instance_code," + "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 ") "mc.name as menu_category_name,mc.id as menu_category_id ")
@@ -84,27 +87,29 @@ class InventoryDefinition < ApplicationRecord
end end
def self.get_by_category(filter) 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.*, inventory_definitions = InventoryDefinition
(CASE WHEN sj.credit IS NULL THEN 0 ELSE sj.credit END) as credit, .select("inventory_definitions.*,
(CASE WHEN sj.debit IS NULL THEN 0 ELSE sj.debit END) as debit, stock_journals.credit as credit,
(#{least_stock}) as balance,"+ stock_journals.debit as debit,
"acc.title as account_name,mi.name as item_name, stock_journals.balance as balance,
mii.item_instance_name as instance_name," + accounts.title as account_name,
"mc.name as menu_category_name,mc.id as menu_category_id " menu_items.name as item_name,
) menu_item_instances.item_instance_name as instance_name,
.joins(" LEFT JOIN stock_journals sj ON sj.inventory_definition_id=inventory_definitions.id") menu_categories.name as menu_category_name,
.joins("JOIN menu_item_instances mii ON mii.item_instance_code = inventory_definitions.item_code" + menu_categories.id as menu_category_id")
" JOIN menu_items mi ON mi.id = mii.menu_item_id" + .joins("LEFT JOIN (#{least_stock}) stock_journals on stock_journals.inventory_definition_id = inventory_definitions.id")
" JOIN menu_categories mc ON mc.id = mi.menu_category_id ") .joins(menu_item_instance: { menu_item: [:menu_category, :account]})
.joins(" JOIN accounts acc ON acc.id = mi.account_id") .where("inventory_definitions.item_code LIKE :filter OR inventory_definitions.min_order_level LIKE :filter
.where("(inventory_definitions.item_code LIKE ? OR inventory_definitions.min_order_level LIKE ? OR inventory_definitions.max_stock_level LIKE :filter OR stock_journals.balance LIKE :filter OR menu_items.name LIKE :filter
OR inventory_definitions.max_stock_level LIKE ? OR sj.balance LIKE ? OR mi.name LIKE ? OR menu_item_instances.item_instance_name LIKE :filter OR menu_categories.name LIKE :filter", filter: "%#{filter}%")
OR mii.item_instance_name LIKE ? OR mc.name LIKE ?)","%#{filter}%","%#{filter}%","%#{filter}%", .group("menu_items.menu_category_id, inventory_definitions.item_code")
"%#{filter}%","%#{filter}%","%#{filter}%","%#{filter}%") .order("balance asc, menu_items.name asc, accounts.title desc, menu_items.menu_category_id desc")
.group("mi.menu_category_id,inventory_definitions.item_code")
.order("balance asc, mi.name asc,acc.title desc,mi.menu_category_id desc")
end end
end end

View File

@@ -119,11 +119,15 @@ class Printer::ReceiptPrinter < Printer::PrinterWorker
if count == 1 if count == 1
filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf" filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf"
pdf.render_file filename pdf.render_file filename
if printed_status != 'Paid' if printed_status != 'Paid' && printed_status != 'credit_payment'
#no print in cloud server #no print in cloud server
if ENV["SERVER_MODE"] != "cloud" if ENV["SERVER_MODE"] != "cloud"
self.print(directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf", cashier_terminal.printer_name) self.print(directory_name + "/receipt_bill_#{sale_data.receipt_no}.pdf", cashier_terminal.printer_name)
end 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 end
else else
filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}_#{count}.pdf" filename = directory_name + "/receipt_bill_#{sale_data.receipt_no}_#{count}.pdf"

View File

@@ -748,43 +748,29 @@ class Sale < ApplicationRecord
end end
def self.search_credit_sales(customer,filter,from,to,order_source="") def self.search_credit_sales(customer,filter,from,to,order_source="")
if filter.blank? sale = Sale.select(Sale.column_names)
keyword = '' .select(SalePayment.column_names)
else .select(:source).includes(:customer)
keyword = "and sales.receipt_no LIKE ? OR sales.cashier_name LIKE ? OR sales.sale_status ='#{filter}'","%#{filter}%","%#{filter}%" .joins(:sale_payments, :orders)
end .where(sale_payments: {payment_method: 'creditnote'})
.group(:sale_payment_id)
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
if from.present? && to.present? 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") sale = sale.receipt_date_between(from, to)
.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}")
end 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 end
def self.get_rounding_adjustment(num) 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='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='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, 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 CASE WHEN SUM(case when sale_payments.payment_method not in('creditnote')
THEN sales.grand_total - SUM(case when sale_payments.payment_method not in('creditnote') then sale_payments.payment_amount end) 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, 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='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") 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 end
def get_cash_amount def get_cash_amount
cash = 0.0 self.sale_payments.where(payment_method: 'cash', payment_status: 'paid')
self.sale_payments.each do |pay| .pluck(:payment_amount).reduce(0, :+) - self.amount_changed
if pay.payment_method == 'cash'
cash += pay.payment_amount
end
end
return cash - self.amount_changed
end end
def get_credit_amount def get_credit_amount
credit = 0.0 self.sale_payments.where(payment_method: 'creditnote')
self.sale_payments.each do |pay| .pluck(:payment_status, :payment_amount)
if pay.payment_method == 'creditnote' .inject(0.0) { |sum, pay|
credit += pay.payment_amount if pay[0] == 'outstanding'
end sum += pay[1]
end else
return credit sum -= pay[1]
end
}
end end
def get_other_amount def get_other_amount
other = 0.0 self.sale_payments.where.not(payment_method: ['cash', 'creditnote'])
self.sale_payments.each do |pay| .pluck(:payment_status, :payment_amount)
if pay.payment_method != 'cash' && pay.payment_method != 'creditnote' .inject(0.0) { |sum, pay|
other += pay.payment_amount if pay[0] == 'paid'
end sum += pay[1]
end else
return other sum -= pay[1]
end
}
end end
def get_commerical_tax def get_commerical_tax
@@ -2439,15 +2426,13 @@ private
end end
def round_to_precision 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)
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_amount = self.total_amount.round(precision) self.total_discount = self.total_discount.round(precision)
self.total_discount = self.total_discount.round(precision) self.total_tax = self.total_tax.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
end end
self.grand_total = (self.total_amount - self.total_discount) + self.total_tax
adjust_rounding
end end
def update_stock_journal def update_stock_journal

View File

@@ -143,7 +143,7 @@ class SaleAudit < ApplicationRecord
remark = paymal[0].remark.split("}") remark = paymal[0].remark.split("}")
response = "["+remark[0]+'}]' response = "["+remark[0]+'}]'
response = JSON.parse(response) response = JSON.parse(response)
puts response # puts response
if response[0]["status"] == true if response[0]["status"] == true
if response[0]["current_rebate_amount"].present? if response[0]["current_rebate_amount"].present?
amount = response[0]["current_rebate_amount"] amount = response[0]["current_rebate_amount"]

View File

@@ -74,6 +74,8 @@ class SalePayment < ApplicationRecord
#get all payment for this invoices #get all payment for this invoices
if payment_for if payment_for
amount_due = SalePayment.get_credit_amount_due_left(self.sale_id).first.payment_amount amount_due = SalePayment.get_credit_amount_due_left(self.sale_id).first.payment_amount
elsif payment_method == 'foc'
amount_due = invoice.total_amount
else else
amount_due = invoice.sale_payments amount_due = invoice.sale_payments
.map(&:payment_amount).reduce(invoice.grand_total, :-) .map(&:payment_amount).reduce(invoice.grand_total, :-)
@@ -140,9 +142,6 @@ class SalePayment < ApplicationRecord
remark = "#{self.sale_payment_id}||#{shift_sale_id} -> #{remark}" remark = "#{self.sale_payment_id}||#{shift_sale_id} -> #{remark}"
sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name) sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name)
if payment_method == "cash"
update_shift_for_credit_payment
end
else else
sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name) sale_audit = SaleAudit.record_payment(invoice.id, remark, action_by.name)
end end
@@ -235,14 +234,15 @@ class SalePayment < ApplicationRecord
end end
def self.redeem(paypar_url,token,membership_id,received_amount,sale_id) 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? if !membership_actions_data.nil?
url = paypar_url.to_s + membership_actions_data.gateway_url.to_s url = paypar_url.to_s + membership_actions_data.gateway_url.to_s
merchant_uid = membership_actions_data.merchant_account_id merchant_uid = membership_actions_data.merchant_account_id
auth_token = membership_actions_data.auth_token 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) 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 if sale_data
others = 0 others = 0
@@ -259,7 +259,7 @@ class SalePayment < ApplicationRecord
redeem_amount:received_amount, redeem_amount:received_amount,
receipt_no:sale_data.receipt_no, receipt_no:sale_data.receipt_no,
campaign_type_id:campaign_type_id, campaign_type_id:campaign_type_id,
account_no:"", account_no: account_no,
merchant_uid:merchant_uid, merchant_uid:merchant_uid,
auth_token:auth_token}.to_json, auth_token:auth_token}.to_json,
:headers => { :headers => {
@@ -371,12 +371,8 @@ class SalePayment < ApplicationRecord
private private
def cash_payment(payment_for=false) 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 payment_status = false
self.payment_method = "cash" self.payment_method = "cash"
@@ -391,8 +387,11 @@ class SalePayment < ApplicationRecord
self.payment_status = "paid" self.payment_status = "paid"
payment_status = self.save! payment_status = self.save!
if !payment_for 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 end
balance_amount =0.0 balance_amount =0.0
outstanding_amount =0.0 outstanding_amount =0.0
if self.sale.grand_total.to_f > self.received_amount.to_f if self.sale.grand_total.to_f > self.received_amount.to_f
@@ -408,6 +407,7 @@ class SalePayment < ApplicationRecord
def foc_payment def foc_payment
payment_status = false payment_status = false
sale = self.sale sale = self.sale
sale.sale_payments.update_all(payment_status: "cancelled")
# add to sale item with foc # add to sale item with foc
sale_items = sale.sale_items sale_items = sale.sale_items
@@ -424,7 +424,7 @@ class SalePayment < ApplicationRecord
self.payment_status = "paid" self.payment_status = "paid"
payment_status = self.save! payment_status = self.save!
# sale_update_payment_status(self.received_amount) # sale_update_payment_status(self.received_amount)
sale_update_payment_status(0) sale_update_payment_status(0, true)
return payment_status return payment_status
end end
@@ -501,7 +501,7 @@ class SalePayment < ApplicationRecord
#Next time - validate if the vochure number is valid - within #Next time - validate if the vochure number is valid - within
customer_data = Customer.find_by_customer_id(self.sale.customer_id) customer_data = Customer.find_by_customer_id(self.sale.customer_id)
membership_setting = MembershipSetting.find_by_membership_type("paypar_url") 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 #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} " 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) def sale_update_payment_status(paid_amount, check_foc = false)
#update amount_outstanding #update amount_outstanding
if ['completed'].include? sale.sale_status
return
end
sale = self.sale 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_received = sale.amount_received.to_f + paid_amount.to_f
sale.amount_changed = total_payment_amount - sale.grand_total.to_f sale.amount_changed = total_payment_amount - sale.grand_total.to_f
is_credit = sale.sale_payments.any? { |x| x.payment_method == "creditnote" } if is_foc
is_foc = sale.sale_payments.any? { |x| x.payment_method == "foc" } sale.payment_status = 'foc'
sale.sale_status = 'completed'
if sale.grand_total <= total_payment_amount && sale.sale_status == "new" elsif sale.grand_total <= total_payment_amount && sale.sale_status == "new"
sale.payment_status = "paid" sale.payment_status = "paid"
if is_credit if is_credit
sale.payment_status = "outstanding" sale.payment_status = "outstanding"
end end
if is_foc
sale.payment_status = "foc"
end
sale.sale_status = "completed" sale.sale_status = "completed"
@@ -672,26 +682,25 @@ class SalePayment < ApplicationRecord
end end
end end
end end
end
sale.save! sale.save!
if check_foc if check_foc
table_update_status(sale) table_update_status(sale)
update_shift update_shift
elsif paid_amount.to_f > 0 #|| paid_amount != "0.0" elsif paid_amount.to_f > 0 #|| paid_amount != "0.0"
table_update_status(sale) table_update_status(sale)
update_shift update_shift
elsif paid_amount.to_f == 0 && !is_credit elsif paid_amount.to_f == 0 && !is_credit
table_update_status(sale) table_update_status(sale)
update_shift update_shift
end
end end
end end
# update for cashier shift # update for cashier shift
def update_shift def update_shift
current_shift_user = Employee.find_by_id(self.action_by.id) shift = ShiftSale.current_open_shift(self.action_by.id)
shift = ShiftSale.current_open_shift(current_shift_user)
if shift.nil? if shift.nil?
current_shift_user = Employee.find_by_id(self.sale.cashier_id) current_shift_user = Employee.find_by_id(self.sale.cashier_id)
@@ -717,7 +726,10 @@ class SalePayment < ApplicationRecord
# update for shift with credit payment # update for shift with credit payment
def update_shift_for_credit_payment def update_shift_for_credit_payment
shift_credit = ShiftSale.find_by_id(self.sale.shift_sale_id) 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? if !shift.nil?
credit_payment_left = get_credit_payment_left[0].payment_amount.to_f credit_payment_left = get_credit_payment_left[0].payment_amount.to_f
if self.payment_method == "cash" if self.payment_method == "cash"
@@ -726,7 +738,6 @@ class SalePayment < ApplicationRecord
else else
# extra_changed_amount = self.received_amount.to_f + credit_payment_left # 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) 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_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.amount_changed = self.sale.amount_changed.to_f - credit_payment_left
self.sale.save! self.sale.save!

View File

@@ -64,7 +64,7 @@ class ReceiptBillPdf < Prawn::Document
cashier_info(sale_data, customer_account, latest_order_no) cashier_info(sale_data, customer_account, latest_order_no)
line_items(sale_items,precision,delimiter) line_items(sale_items,precision,delimiter)
all_total(sale_data,precision,delimiter) all_total(sale_data,precision,delimiter,printed_status)
if member_info != nil if member_info != nil
@@ -112,6 +112,9 @@ class ReceiptBillPdf < Prawn::Document
end end
if kbz_pay_status if kbz_pay_status
if printed_status == 'credit_payment'
printed_status = 'Paid'
end
kbzpay_qr_generator(printed_status, qr_code) kbzpay_qr_generator(printed_status, qr_code)
end end
@@ -323,7 +326,7 @@ class ReceiptBillPdf < Prawn::Document
end end
def all_total(sale_data,precision,delimiter) def all_total(sale_data,precision,delimiter,printed_status)
move_down line_move move_down line_move
item_name_width = self.item_width item_name_width = self.item_width
y_position = cursor y_position = cursor
@@ -455,16 +458,21 @@ class ReceiptBillPdf < Prawn::Document
end end
move_down line_move move_down line_move
sale_payment(sale_data,precision,delimiter) sale_payment(sale_data,precision,delimiter,printed_status)
end end
def sale_payment(sale_data,precision,delimiter) def sale_payment(sale_data,precision,delimiter,printed_status)
stroke_horizontal_rule stroke_horizontal_rule
# move_down 2 # move_down 2
move_down line_move move_down line_move
# sql = "SELECT SUM(payment_amount) # sql = "SELECT SUM(payment_amount)
# FROM sale_payments where payment_method='creditnote' # 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 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) # 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' # FROM sale_payments where payment_method='creditnote'
@@ -482,13 +490,16 @@ class ReceiptBillPdf < Prawn::Document
where sa.sale_id='#{sale_data.sale_id}')) = 0 where sa.sale_id='#{sale_data.sale_id}')) = 0
THEN payment_method!='creditnote' ELSE 1 END) AND sale_id = ?", sale_data.sale_id) THEN payment_method!='creditnote' ELSE 1 END) AND sale_id = ?", sale_data.sale_id)
.group("payment_method") .group("payment_method")
end
sale_payments.each do |payment| sale_payments.each do |payment|
y_position = cursor y_position = cursor
if payment.payment_method == "paypar" if payment.payment_method == "paypar"
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do 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 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 else
payment_method = payment.payment_method.capitalize payment_method = payment.payment_method.capitalize
if payment.payment_method == "paymal" if payment.payment_method == "paymal"
@@ -775,7 +786,9 @@ class ReceiptBillPdf < Prawn::Document
move_down line_move move_down line_move
stroke_horizontal_rule stroke_horizontal_rule
move_down line_move move_down line_move
if printed_status == 'credit_payment'
printed_status = 'Paid'
end
move_down line_move move_down line_move
y_position = cursor y_position = cursor
bounding_box([0, y_position], :width =>self.label_width) do bounding_box([0, y_position], :width =>self.label_width) do

View File

@@ -172,11 +172,31 @@
}); });
$(document).ready(function () { $(document).ready(function () {
var menus = JSON.parse(localStorage.getItem("menus"));; // var menus = JSON.parse(localStorage.getItem("menus"));;
if (menus != null) { // if (menus != null) {
menu_cache_append(menus); // menu_cache_append(menus);
}else{ // }else{
$("#menu_data").removeClass("hidden"); // 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){ function menu_cache_append(menus){
@@ -328,6 +348,66 @@
}); });
//End menu category Click //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 = '<li class="menu_sub_category fadeInTop" data-id="'+categories[ii].id+'">'
+'<a class="nav-link" data-toggle="tab" href="" role="tab">'+ categories[ii].name+'</a>'
+'</li>' ;
$(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 = '<li class="menu_sub_category fadeInTop" data-id="'+data[i].id+'">'
+'<a class="nav-link" data-toggle="tab" href="" role="tab">'+ data[i].name+'</a>'
+'</li>' ;
$(sub_category).append(row);
//end is_sub_item false
}
}
}
});
//end Ajax
}
}
//click menu sidebar menu category //click menu sidebar menu category
$(document).on('click', '.menu_sub_category', function(event){ $(document).on('click', '.menu_sub_category', function(event){
// event.preventDefault(); // event.preventDefault();

View File

@@ -107,9 +107,9 @@
<%if @sale_payment.nil? && @changable_tax %> <%if @sale_payment.nil? && @changable_tax %>
<% if @current_user.role == 'cashier' %> <% if @current_user.role == 'cashier' %>
<button class="btn btn-link waves-effect bg-info access_modal" data-type="change_tax">Change Tax</button> <button class="btn btn-link waves-effect bg-info access_modal" data-type="change_tax">Change Tax</button>
<% else %> <% else %>
<button class="btn btn-link waves-effect bg-info change_tax">Change Tax</button> <button class="btn btn-link waves-effect bg-info change_tax">Change Tax</button>
<% end %> <% end %>
<% end %> <% end %>
</td> </td>
<td class="item-attr"><strong><span id="total_tax"><%= number_format(@sale_data.total_tax, precision: precision.to_i ) rescue number_format(0, precision: precision.to_i )%></span></strong></td> <td class="item-attr"><strong><span id="total_tax"><%= number_format(@sale_data.total_tax, precision: precision.to_i ) rescue number_format(0, precision: precision.to_i )%></span></strong></td>

View File

@@ -26,11 +26,12 @@
<th colspan="7"><%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )</th> <th colspan="7"><%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )</th>
</tr> </tr>
<% end %> <% end %>
<tr> <tr>
<th><b><%= t("views.right_panel.detail.shift_name") %></b></th> <th><b><%= t("views.right_panel.detail.receipt_no") %></b></th>
<th><b><%= t("views.right_panel.detail.table") %></b></th> <th><b><%= t("views.right_panel.detail.receipt_date") %></b></th>
<th><b><%= t("views.right_panel.detail.receipt_no") %></b></th> <th><b><%= t("views.right_panel.detail.shift_name") %></b></th>
<th><b><%= t :cashier %> <%= t("views.right_panel.detail.name") %></b></th> <th><b><%= t :cashier %> <%= t("views.right_panel.detail.name") %></b></th>
<th><b><%= t("views.right_panel.detail.table") %></b></th>
<th><b><%= t("views.right_panel.detail.revenue") %></b></th> <th><b><%= t("views.right_panel.detail.revenue") %></b></th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
@@ -46,24 +47,25 @@
end %> end %>
<% grand_total = grand_total + result.grand_total %> <% grand_total = grand_total + result.grand_total %>
<tr style="border-top:4px double #666;"> <tr style="border-top:4px double #666;">
<td><%= @shift_from %> - <%= @shift_to %></td>
<td><%= table_type %> - <%= table_name %></td>
<td><%= result.receipt_no rescue '-' %> </td> <td><%= result.receipt_no rescue '-' %> </td>
<td><%=l result.receipt_date.getlocal, :format => :short rescue '-' %> </td>
<td><%= @shift_from %> - <%= @shift_to %></td>
<td><%= result.cashier_name rescue '-' %></td> <td><%= result.cashier_name rescue '-' %></td>
<td><%= table_type %> - <%= table_name %></td>
<td><%= number_format(result.grand_total, precision: precision, delimiter: delimiter) %></td> <td><%= number_format(result.grand_total, precision: precision, delimiter: delimiter) %></td>
<!-- <td>&nbsp;</td> --> <!-- <td>&nbsp;</td> -->
</tr> </tr>
<tr> <tr>
<th>&nbsp;</th>
<th><b><%= t("views.right_panel.detail.product") %></b></th> <th><b><%= t("views.right_panel.detail.product") %></b></th>
<th><b><%= t("views.right_panel.detail.qty") %></b></th> <th><b><%= t("views.right_panel.detail.qty") %></b></th>
<th><b><%= t("views.right_panel.detail.unit_price") %></b></th> <th><b><%= t("views.right_panel.detail.unit_price") %></b></th>
<th><b><%= t("views.right_panel.detail.total_price") %></b></th> <th colspan="2"><b><%= t("views.right_panel.detail.total_price") %></b></th>
<th><b><%= t("views.right_panel.detail.created_at") %></b></th>
</tr> </tr>
<% result.sale_items.each do |item|%> <% result.sale_items.each do |item|%>
<tr> <tr>
<td>&nbsp;</td>
<td> <td>
<% if item.price < 0 %> <% if item.price < 0 %>
<% if item.qty < 0 %> <% if item.qty < 0 %>
@@ -77,18 +79,18 @@
</td> </td>
<td><%= item.qty rescue '-' %></td> <td><%= item.qty rescue '-' %></td>
<td><%= number_format(item.unit_price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %></td> <td><%= number_format(item.unit_price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %></td>
<td><%= number_format(item.price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %></td> <td colspan="2"><%= number_format(item.price, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) rescue '-' %></td>
<td><%=l item.created_at.getlocal, :format => :short rescue '-' %> </td>
</tr> </tr>
<% end %> <% end %>
<tr><td colspan="5">&nbsp;</td></tr> <tr><td colspan="6">&nbsp;</td></tr>
<%survey = result.survey%> <%survey = result.survey%>
<% if !survey.nil?%> <% if !survey.nil?%>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td>No. of Guest</td> <td>No. of Guest</td>
<td><%= survey.total_customer rescue '-' %></td> <td><%= survey.total_customer rescue '-' %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -97,6 +99,7 @@
<% if !result.total_amount.nil?%> <% if !result.total_amount.nil?%>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %></td> <td><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %></td>
@@ -107,6 +110,7 @@
<% if result.total_discount > 0 %> <% if result.total_discount > 0 %>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><%= t("views.right_panel.detail.total") %> <td><%= t("views.right_panel.detail.total") %>
@@ -119,6 +123,7 @@
<% if !result.total_tax.nil? %> <% if !result.total_tax.nil? %>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>Tax Amount </td> <td>Tax Amount </td>
@@ -133,13 +138,15 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>Payment <%= rec.payment_method.upcase %></td> <td>&nbsp;</td>
<td><%= number_format(rec.payment_amount, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %> ( <%= rec.payment_status %> )</td> <td>Payment <%= rec.payment_method.upcase %> ( <%= rec.payment_status %> )</td>
<td><%= number_format(rec.payment_amount, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
<% if !rec.payment_reference.nil? %> <% if !rec.payment_reference.nil? %>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>Payment Ref.</td> <td>Payment Ref.</td>
@@ -151,6 +158,7 @@
<% end %> <% end %>
<% if result.amount_changed != 0 %> <% if result.amount_changed != 0 %>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %></td> <td><%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %></td>
@@ -160,6 +168,7 @@
<% end %> <% end %>
<% if !result.customer_id.nil?%> <% if !result.customer_id.nil?%>
<tr> <tr>
<td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>Customer</td> <td>Customer</td>
@@ -176,6 +185,7 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td><b>Total Nett</b> - <b><%= number_format(grand_total, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %></b></td> <td><b>Total Nett</b> - <b><%= number_format(grand_total, precision: precision, delimiter: delimiter, strip_insignificant_zeros: strip_insignificant_zeros) %></b></td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>

View File

@@ -24,12 +24,13 @@
<th colspan="7"><%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )</th> <th colspan="7"><%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )</th>
</tr> </tr>
<% end %> <% end %>
<tr> <tr>
<th><b><%= t("views.right_panel.detail.shift_name") %></b></th> <th><b><%= t("views.right_panel.detail.receipt_no") %></b></th>
<th><b><%= t("views.right_panel.detail.table") %></b></th> <th><b><%= t("views.right_panel.detail.receipt_date") %></b></th>
<th><b><%= t("views.right_panel.detail.receipt_no") %></b></th> <th><b><%= t("views.right_panel.detail.shift_name") %></b></th>
<th><b><%= t :cashier %> <%= t("views.right_panel.detail.name") %></b></th> <th><b><%= t :cashier %> <%= t("views.right_panel.detail.name") %></b></th>
<th><b><%= t("views.right_panel.detail.revenue") %></b></th> <th><b><%= t("views.right_panel.detail.table") %></b></th>
<th><b><%= t("views.right_panel.detail.revenue") %></b></th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
@@ -43,25 +44,26 @@
table_type = table.type table_type = table.type
table_name = table.name table_name = table.name
end %> end %>
<tr style="border-top:4px double #666;"> <tr style="border-top:4px double #666;">
<td><%= @shift_from %> - <%= @shift_to %></td>
<td><%= table_type %> - <%= table_name %></td>
<td><%= result.receipt_no rescue '-' %> </td> <td><%= result.receipt_no rescue '-' %> </td>
<td><%=l result.receipt_date.getlocal, :format => :short rescue '-' %> </td>
<td><%= @shift_from %> - <%= @shift_to %></td>
<td><%= result.cashier_name rescue '-' %></td> <td><%= result.cashier_name rescue '-' %></td>
<td><%=result.grand_total%></td> <td><%= table_type %> - <%= table_name %></td>
<!-- <td>&nbsp;</td> --> <td><%= number_format(result.grand_total, precision: precision, delimiter: delimiter) %></td>
</tr> </tr>
<tr> <tr>
<th>&nbsp;</th>
<th><b><%= t("views.right_panel.detail.product") %></b></th> <th><b><%= t("views.right_panel.detail.product") %></b></th>
<th><b><%= t("views.right_panel.detail.qty") %></b></th> <th><b><%= t("views.right_panel.detail.qty") %></b></th>
<th><b><%= t("views.right_panel.detail.unit_price") %></b></th> <th><b><%= t("views.right_panel.detail.unit_price") %></b></th>
<th><b><%= t("views.right_panel.detail.total_price") %></b></th> <th><b><%= t("views.right_panel.detail.total_price") %></b></th>
<th><b><%= t("views.right_panel.detail.created_at") %></b></th>
</tr> </tr>
<% result.sale_items.each do |item|%> <% result.sale_items.each do |item|%>
<tr> <tr>
<td>&nbsp;</td>
<td> <td>
<% if item.price.to_i < 0.to_i %> <% if item.price.to_i < 0.to_i %>
<% if item.qty.to_i < 0.to_i%> <% if item.qty.to_i < 0.to_i%>
@@ -76,7 +78,6 @@
<td><%= item.qty rescue '-' %></td> <td><%= item.qty rescue '-' %></td>
<td><%= item.unit_price rescue '-' %></td> <td><%= item.unit_price rescue '-' %></td>
<td><%= item.price rescue '-' %></td> <td><%= item.price rescue '-' %></td>
<td><%=l item.created_at.utc.getlocal, :format => :short rescue '-' %> </td>
</tr> </tr>
<% end %> <% end %>
@@ -87,6 +88,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td>No. of Guest</td> <td>No. of Guest</td>
<td><%= survey.total_customer rescue '-' %></td> <td><%= survey.total_customer rescue '-' %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -97,6 +99,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %></td> <td><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %></td>
<td><%= result.total_amount %></td> <td><%= result.total_amount %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -107,6 +110,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td><%= t("views.right_panel.detail.total") %> <td><%= t("views.right_panel.detail.total") %>
<%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.discount") %>
<%= t("views.right_panel.detail.amount") %></td> <%= t("views.right_panel.detail.amount") %></td>
@@ -119,6 +123,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td>Tax Amount </td> <td>Tax Amount </td>
<td><%= result.total_tax %> </td> <td><%= result.total_tax %> </td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -132,8 +137,9 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>Payment <%= rec.payment_method.upcase %></td> <td>&nbsp;</td>
<td><%= rec.payment_amount %> ( <%= rec.payment_status %> )</td> <td>Payment <%= rec.payment_method.upcase %>( <%= rec.payment_status %> )</td>
<td><%= rec.payment_amount %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
@@ -141,6 +147,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td>Payment Ref.</td> <td>Payment Ref.</td>
<td><%= rec.payment_reference %></td> <td><%= rec.payment_reference %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -152,6 +159,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td><%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %></td> <td><%= t("views.right_panel.detail.change") %> <%= t("views.right_panel.detail.amount") %></td>
<td><%= result.amount_changed %></td> <td><%= result.amount_changed %></td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -161,6 +169,7 @@
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td>Customer</td> <td>Customer</td>
<td><%= result.customer.name rescue '-'%> <td><%= result.customer.name rescue '-'%>
(<%= result.customer.company rescue '-' %>) (<%= result.customer.company rescue '-' %>)
@@ -175,6 +184,7 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td>
<td><b>Total Nett</b> - <b><%= grand_total %></b></td> <td><b>Total Nett</b> - <b><%= grand_total %></b></td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>

View File

@@ -19,7 +19,7 @@
<div class="row clearfix"> <div class="row clearfix">
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3 mbl-style"> <div class="col-lg-3 col-md-3 col-sm-3 col-xs-3 mbl-style">
<label class="font-14"><%= t("views.right_panel.detail.enter_keyboards") %></label> <label class="font-14"><%= t("views.right_panel.detail.enter_keyboards") %></label>
<input type="text" name="receipt_no" class="form-control m-t-3" placeholder="Receipt No/Cashier Name/Status" style="margin-right: 10px"> <input type="text" name="filter" class="form-control m-t-3" placeholder="Receipt No/Cashier Name/Status" style="margin-right: 10px">
</div> </div>
<div class="col-lg-2 col-md-2 col-sm-2 col-xs-2 col-mbl-view mbl-style"> <div class="col-lg-2 col-md-2 col-sm-2 col-xs-2 col-mbl-view mbl-style">
<label class="font-14"><%= t("views.right_panel.detail.select_customer") %></label> <label class="font-14"><%= t("views.right_panel.detail.select_customer") %></label>
@@ -48,7 +48,7 @@
<label class="font-14"> &nbsp;</label><br> <label class="font-14"> &nbsp;</label><br>
<input type="submit" value="Search" class='btn btn-primary btn-md'> <input type="submit" value="Search" class='btn btn-primary btn-md'>
</div> </div>
</div> </div>
<% end %> <% end %>
</td> </td>
</tr> </tr>

View File

@@ -444,6 +444,7 @@ en:
sale_item_report: "Sale Item Report" sale_item_report: "Sale Item Report"
select_period: "Select Period" select_period: "Select Period"
shift_name: "Shift Name" shift_name: "Shift Name"
receipt_date: "Receipt Date"
code: "Code" code: "Code"
item: "Item" item: "Item"
revenue: "Revenue" revenue: "Revenue"

153
lib/tasks/shift_sales.rake Normal file
View File

@@ -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