Print receipt bill payment for credit

This commit is contained in:
Thein Lin Kyaw
2020-02-25 15:40:29 +06:30
5 changed files with 1088 additions and 246 deletions

435
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} }
@@ -315,99 +291,94 @@ settings/lookups => {type:show_total_before_tax, name:Show Total Before Tax, val
For Using Staff Meal For Using Staff Meal
settings/lookups => { type:customer_type, name: Staff, value:Staff } settings/lookups => { type:customer_type, name: Staff, value:Staff }
* ToDo list - ToDo list
1. Migration 1. Migration
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

@@ -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,shop_detail, "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,shop_detail, printed_status,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

@@ -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"
@@ -138,7 +142,16 @@ class Printer::ReceiptPrinter < Printer::PrinterWorker
Rails.logger.debug "############## filename::" + filename Rails.logger.debug "############## filename::" + filename
return filename, sale_data.receipt_no, cashier_terminal.printer_name return filename, sale_data.receipt_no, cashier_terminal.printer_name
end end
#print credit
def print_credit(printer_settings, kbz_pay_status, qr_code, cashier_terminal,sale_items,sale_data, customer_name, item_price_by_accounts, discount_price_by_accounts, member_info = nil,rebate_amount=nil,shop_details, printed_status,balance,card_data,other_amount,latest_order_no,card_balance_amount,order_reservation)
pdf = CreditBillPdf.new(printer_settings, kbz_pay_status, qr_code, sale_items, sale_data, customer_name, item_price_by_accounts, discount_price_by_accounts, member_info,rebate_amount,shop_details,printed_status,balance,card_data,other_amount,latest_order_no,card_balance_amount)
directory_name = 'public/receipts'
filename = directory_name + "/credit_receipt_bill_#{sale_data.receipt_no}.pdf"
pdf.render_file filename
self.print(directory_name + "/credit_receipt_bill_#{sale_data.receipt_no}.pdf", cashier_terminal.printer_name)
end
# stock check # stock check
def print_stock_check_result(print_settings,stockcheck, stockcheck_items,checker_name, shop_details) def print_stock_check_result(print_settings,stockcheck, stockcheck_items,checker_name, shop_details)
pdf = StockResultPdf.new(print_settings,stockcheck, stockcheck_items,checker_name, shop_details) pdf = StockResultPdf.new(print_settings,stockcheck, stockcheck_items,checker_name, shop_details)

838
app/pdf/credit_bill_pdf.rb Normal file
View File

@@ -0,0 +1,838 @@
require 'prawn/measurement_extensions'
class CreditBillPdf < Prawn::Document
include NumberFormattable
attr_accessor :label_width,:price_column_width,:page_width, :page_height, :margin, :price_width, :item_width, :header_font_size, :item_font_size,:item_height,:qty_width,:total_width,:item_description_width, :description_width, :price_num_width, :line_move
def initialize(printer_settings, kbz_pay_status, qr_code, sale_items, sale_data, customer_name, item_price_by_accounts, discount_price_by_accounts, member_info = nil,rebate_amount = nil,shop_details, printed_status,current_balance,card_data,other_charges_amount,latest_order_no,card_balance_amount)
self.page_width = printer_settings.page_width
self.page_height = printer_settings.page_height
self.header_font_size = printer_settings.header_font_size.to_i
self.item_font_size = printer_settings.item_font_size.to_i
self.margin = 0
self.price_width = 60
self.qty_width = 25
self.total_width = 60
self.item_width = self.page_width - ((self.qty_width + self.price_width + self.total_width))
self.item_height = 15
self.item_description_width = (self.page_width-5) / 2
self.label_width = 100
self.description_width = 150
self.price_num_width = 50
self.line_move = 2
# @item_width = self.page_width.to_i / 2
# @qty_width = @item_width.to_i / 3
# @double = @qty_width * 1.3
# @half_qty = @qty_width / 2
#setting page margin and width
super(:margin => [printer_settings.heading_space, self.margin, self.margin, self.margin], :page_size => [self.page_width, self.page_height])
# db font setup
if printer_settings.font != ""
font_families.update("#{printer_settings.font}" => {
:normal => "public/fonts/#{printer_settings.font}.ttf",
:italic => "public/fonts/#{printer_settings.font}.ttf",
:bold => "public/fonts/#{printer_settings.font}.ttf",
:bold_italic => "public/fonts/#{printer_settings.font}.ttf"
})
font "#{printer_settings.font}"
fallback_fonts ["Courier", "Helvetica", "Times-Roman"]
end
# font "public/fonts/Zawgyi-One.ttf"
# font "public/fonts/padauk.ttf"
header(shop_details)
stroke_horizontal_rule
cashier_info(sale_data, customer_name, latest_order_no)
line_items(sale_items,precision,delimiter)
all_total(sale_data,precision,delimiter)
if member_info != nil
member_info(member_info,customer_name,rebate_amount,sale_data,precision,delimiter,current_balance)
end
customer(customer_name)
#start card sale trans data
if card_data != nil
card_sale_data(card_data)
end
#end card sale trans data
#start card blanace amount
if !card_balance_amount.nil?
card_balance_data(card_balance_amount)
end
#end card blanace amount
if discount_price_by_accounts.length > 0 && shop_details.show_account_info
discount_account(discount_price_by_accounts,precision,delimiter)
end
if shop_details.show_account_info
items_account(item_price_by_accounts,precision,delimiter)
if other_charges_amount
show_other_charges_amount(other_charges_amount,precision,delimiter)
end
end
#start for individual payment
if !sale_data.equal_persons.nil?
individual_payment(sale_data,sale_data.equal_persons, precision, delimiter)
end
#end for individual payment
sign(sale_data)
if shop_details.note && !shop_details.note.nil?
shop_note(shop_details)
end
if kbz_pay_status
kbzpay_qr_generator(printed_status, qr_code)
end
footer(printed_status)
end
def header (shop_details)
text "#{shop_details.name}", :left_margin => -10, :size => self.header_font_size,:align => :center
move_down line_move
text "#{shop_details.address}", :size => self.item_font_size,:align => :center
# move_down self.item_height
move_down line_move
text "#{shop_details.phone_no}", :size => self.item_font_size,:align => :center
move_down line_move
stroke_horizontal_rule
end
def cashier_info(sale_data, customer_name, latest_order_no)
if latest_order_no.nil?
move_down line_move
text "Booking : #{ sale_data.bookings[0].booking_id }", :size => self.header_font_size+2,:align => :left
move_down line_move
end
move_down line_move
if !latest_order_no.nil?
move_down line_move
text "OrderNo : #{ latest_order_no }", :size => self.header_font_size,:align => :left
end
move_down line_move
# move_down 2
y_position = cursor
bounding_box([0,y_position], :width =>self.description_width + self.price_num_width, :height => self.item_height) do
text "Receipt No: #{sale_data.receipt_no}", :size => self.item_font_size,:align => :left
end
if sale_data.bookings[0].dining_facility_id.to_i > 0
bounding_box([self.description_width - 2,y_position], :width => self.price_num_width, :height => self.item_height) do
text "#{ sale_data.bookings[0].dining_facility.type } - #{ sale_data.bookings[0].dining_facility.name }" , :size => self.item_font_size,:align => :right
end
end
move_down line_move
y_position = cursor
bounding_box([0, y_position], :width =>self.label_width, :height => self.item_height) do
text "W: #{sale_data.requested_by}" , :size => self.item_font_size, :align => :left
end
bounding_box([self.label_width - 2,y_position], :width =>self.label_width, :height => self.item_height) do
text "C: #{sale_data.cashier_name}", :size => self.item_font_size,:align => :right
end
move_down line_move
# credit_date = SalePayment.select(:created_at).where("sale_id = '#{sale_data.sale_id}' AND payment_method = 'creditnote'")
y_position = cursor
if sale_data.bookings[0].dining_facility_id.to_i > 0
time = sale_data.receipt_date.strftime('%d-%m-%Y') +"("+ sale_data.bookings[0].checkin_at.utc.getlocal.strftime('%I:%M %p') +"-"+ sale_data.bookings[0].checkout_at.utc.getlocal.strftime('%I:%M %p')+")"
else
time = sale_data.receipt_date.strftime('%d-%m-%Y %H:%M %p')
end
bounding_box([0,y_position], :width =>self.page_width - 10, :height => self.item_height) do
text "Credit Date : #{ time }",:size => self.item_font_size,:align => :left
end
move_down line_move
y_position = cursor
time = DateTime.now
time = time.strftime('%d-%m-%Y (%H:%M %p)')
bounding_box([0,y_position], :width =>self.page_width - 10, :height => self.item_height) do
text "Payment Date : #{ time }",:size => self.item_font_size,:align => :left
end
# bounding_box([self.item_description_width,y_position], :width =>self.label_width+5) do
# text "(#{ sale_data.bookings[0].checkin_at.utc.getlocal.strftime('%I:%M %p') }
# - #{ sale_data.bookings[0].checkin_at.utc.getlocal.strftime('%I:%M %p') })" ,
# :size => self.item_font_size,:align => :right
# end
move_down line_move
stroke_horizontal_rule
end
def line_items(sale_items,precision,delimiter)
if precision.to_i > 0
item_label_qty_front_width = (self.item_width+self.price_width) + 5
item_label_qty_end_width = self.qty_width + 4
item_label_total_front_width = (self.item_width+self.price_width) + 10
item_label_total_end_width = self.total_width + 9
else
self.item_width = self.item_width.to_i + 8
item_label_qty_front_width = (self.item_width+self.price_width) + 8
item_label_qty_end_width = self.qty_width + 7
item_label_total_front_width = (self.item_width+self.price_width) + 5
item_label_total_end_width = self.total_width + 4
end
move_down line_move
y_position = cursor
move_down line_move
pad_top(15) {
# @item_width.to_i + @half_qty.to_i
text_box "Items", :at =>[0,y_position], :width => self.item_width, :height =>self.item_height, :size => self.item_font_size, :overflow => :shrink_to_fix
text_box "Price", :at =>[(self.item_width),y_position], :width => self.price_width, :height =>self.item_height, :size => self.item_font_size, :align => :right, :overflow => :shrink_to_fix
text_box "Qty", :at =>[item_label_qty_front_width,y_position], :width => item_label_qty_end_width, :height =>self.item_height, :size => self.item_font_size, :align => :center, :overflow => :shrink_to_fix
text_box "Total", :at =>[item_label_total_front_width,y_position], :width => item_label_total_end_width, :height =>self.item_height, :size => self.item_font_size, :align => :right, :overflow => :shrink_to_fix
}
# move_down line_move
stroke_horizontal_rule
add_line_item_row(sale_items,precision,delimiter)
end
def add_line_item_row(sale_items,precision,delimiter)
if precision.to_i > 0
item_name_width = (self.item_width+self.price_width)
item_qty_front_width = (self.item_width+self.price_width) + 5
item_qty_end_width = self.qty_width + 4
item_total_front_width = item_name_width + 10
item_total_end_width = self.total_width + 9
else
item_name_width = (self.item_width+self.price_width)
item_qty_front_width = item_name_width + 8
item_qty_end_width = self.qty_width + 7
item_total_front_width = item_name_width + 5
item_total_end_width = self.total_width + 4
end
y_position = cursor
move_down line_move
@sub_total = 0.0
total_qty = 0.0
show_price = Lookup.find_by_lookup_type("show_price")
sale_items.each do |item|
# check for item not to show
if item.status != 'Discount' && item.qty > 0
if !show_price.nil? && show_price.value.to_i > 0 && item.price == 0
total_qty += item.qty
else
if item.price != 0
total_qty += item.qty
end
end
end
product_name = item.product_name
# if item.status = 'promotion' && (item.remark =='promotion nett price' || item.remark == 'promotion discount')
# sub_total += -item.price #(item.qty*item.unit_price) - comment for room charges
# qty = -item.qty
# total_price = -item.price #item.qty*item.unit_price - comment for room charges
# price = -item.unit_price
# else
@sub_total += item.price #(item.qty*item.unit_price) - comment for room charges
qty = item.qty
total_price = item.price #item.qty*item.unit_price - comment for room charges
price = item.unit_price
# end
if !show_price.nil? && show_price.value.to_i>0
item_row(item,precision,delimiter,product_name,price,qty ,total_price)
else
if item.price != 0
item_row(item,precision,delimiter,product_name,price,qty ,total_price)
end
end
end
stroke_horizontal_rule
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_width + self.price_width, :height => self.item_height) do
text "Sub Total", :size => self.item_font_size,:align => :left
end
text_box "#{number_format(total_qty, :precision => precision.to_i)}", :at =>[item_qty_front_width,y_position], :width => item_qty_end_width, :size => self.item_font_size, :align => :center, :overflow => :shrink_to_fix
text_box "#{number_format(@sub_total, :precision => precision.to_i, :delimiter => delimiter)}", :at =>[item_total_front_width,y_position], :width =>item_total_end_width, :size => self.item_font_size, :align => :right, :overflow => :shrink_to_fix
end
def item_row(item,precision,delimiter,product_name,price,qty ,total_price)
if precision.to_i > 0
item_name_width = (self.item_width+self.price_width)
item_qty_front_width = (self.item_width+self.price_width) + 5
item_qty_end_width = self.qty_width + 4
item_total_front_width = item_name_width + 10
item_total_end_width = self.total_width + 9
else
item_name_width = (self.item_width+self.price_width)
item_qty_front_width = item_name_width + 8
item_qty_end_width = self.qty_width + 7
item_total_front_width = item_name_width + 5
item_total_end_width = self.total_width + 4
end
y_position = cursor
pad_top(15) {
bounding_box([0,y_position], :width =>self.item_width) do
text "#{product_name}", :size => self.item_font_size,:align => :left
end
# text_box "#{product_name}", :at =>[0,y_position], :width => self.item_width, :size => self.item_font_size
text_box "#{number_format(price, :precision => precision.to_i, :delimiter => delimiter)}", :at =>[self.item_width,y_position], :width => self.price_width, :size => self.item_font_size, :align => :right, :overflow => :shrink_to_fix
text_box "#{number_format(qty, :precision => precision.to_i)}", :at =>[item_qty_front_width,y_position], :width => item_qty_end_width, :size => self.item_font_size, :align => :center, :overflow => :shrink_to_fix
text_box "#{number_format(total_price, :precision => precision.to_i, :delimiter => delimiter)}", :at =>[item_total_front_width,y_position], :width =>item_total_end_width, :size => self.item_font_size, :align => :right, :overflow => :shrink_to_fix
if show_alt_name
if !(item.product_alt_name).empty?
move_down 2
# font("public/fonts/NotoSansCJKtc-Regular.ttf") do
text "(#{item.product_alt_name})", :size => self.item_font_size,:align => :left, :inline_format => true
# end
end
end
move_down line_move
}
end
def all_total(sale_data,precision,delimiter)
move_down line_move
item_name_width = self.item_width
y_position = cursor
if sale_data.discount_type == 'member_discount'
dis_type = "Member Discount:"
else
dis_type = "Overall Discount:"
end
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{ dis_type }", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "( #{number_format(sale_data.total_discount, :precision => precision.to_i, :delimiter => delimiter)} )" , :size => self.item_font_size,:align => :right
end
service_tax_desc = ""
service_tax_amount = 0
service_tax_rate = 0
com_tax_desc = ""
com_tax_amount = 0
com_tax_rate = 0
if sale_data.sale_taxes.length > 0
incl_tax = ""
if sale_data.tax_type == "inclusive"
incl_tax = "Incl."
end
find_lookup = Lookup.find_by_lookup_type('show_total_before_tax')
if find_lookup.nil? || find_lookup == nil
lookup = Lookup.new(lookup_type: 'show_total_before_tax', name: 'Show Total Before Tax', value: '0')
lookup.save
end
check_lookup_type = Lookup.find_by_lookup_type('show_total_before_tax')
if check_lookup_type.value == '1'
sale_data.sale_taxes.each do |st|
if (st.tax_name.include? "Service")
service_tax_desc = st.tax_name
service_tax_amount = st.tax_payable_amount
if incl_tax
service_tax_rate = st.tax_rate.to_i
end
end
if (st.tax_name.include? "Commercial")
com_tax_desc = st.tax_name
com_tax_amount = st.tax_payable_amount
if incl_tax
com_tax_rate = st.tax_rate.to_i
end
end
end
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{ service_tax_desc } (#{incl_tax} #{ service_tax_rate }%)", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(service_tax_amount, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
move_down line_move
y_position = cursor
stroke_horizontal_rule
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Total Before Tax", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{service_tax_amount.to_i + @sub_total.to_i}" , :size => self.item_font_size,:align => :right
end
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{ com_tax_desc } (#{incl_tax} #{ com_tax_rate.to_i }%)", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(com_tax_amount, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
else
sale_data.sale_taxes.each do |st|
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{ st.tax_name } (#{incl_tax} #{ st.tax_rate.to_i }%)", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(st.tax_payable_amount, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
end
end
else
end
# move_down 5
# y_position = cursor
# bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
# text "Total Tax", :size => self.item_font_size,:align => :left
# end
# bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
# text "( " +"#{sale_data.total_tax}" +" )" , :size => self.item_font_size,:align => :right
# end
if sale_data.rounding_adjustment != 0.0
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Rounding Adjustment", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{sale_data.rounding_adjustment}", :size => self.item_font_size,:align => :right
end
end
move_down line_move
y_position = cursor
move_down line_move
bounding_box([0,y_position], :width =>self.item_description_width) do
text "Grand Total",:style => :bold, :size => self.header_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(sale_data.grand_total, :precision => precision.to_i, :delimiter => delimiter)}" , :style => :bold, :size => self.header_font_size,:align => :right
end
move_down line_move
sale_payment(sale_data,precision,delimiter)
end
def sale_payment(sale_data,precision,delimiter)
stroke_horizontal_rule
#move_down line_move
# sql = "SELECT SUM(payment_amount)
# FROM sale_payments where payment_method='creditnote'
# and sale_id='#{sale_data.sale_id}'"
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'
# and sale_id='#{sale_data.sale_id}'"
sql1 = "SELECT CASE WHEN s.amount_changed > 0 and (s.amount_received - s.amount_changed) = s.grand_total THEN ("
sql1 += sql
# sale_payments = SalePayment.select("SUM(sale_payments.payment_amount) as payment_amount,sale_payments.payment_method")
# .where("(CASE WHEN ((#{sql}) - (#{sql1})
# ELSE SUM(payment_amount) END
# FROM sale_payments
# JOIN sales s ON s.sale_id=sale_payments.sale_id
# JOIN sale_audits sa
# ON SUBSTRING_INDEX(sa.remark,'||',1)=sale_payment_id
# 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")
sale_payments = SalePayment.select("SUM(payment_amount) as payment_amount, payment_method")
.where("sale_id = '#{sale_data.sale_id}' AND ((payment_method = 'cash' AND outstanding_amount = 0) OR (payment_method != 'cash' AND payment_method != 'creditnote'))").group("payment_method")
credit_sql = SalePayment.select("SUM(sale_payments.outstanding_amount) as amount_due")
.where(" sale_id='#{sale_data.sale_id}' AND payment_method ='creditnote'")
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Amount Due ", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(credit_sql.first.amount_due.abs, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
move_down line_move
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
else
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{payment.payment_method.capitalize} Payment", :size => self.item_font_size,:align => :left
end
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(payment.payment_amount, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
move_down line_move
end
if sale_data.amount_received > 0
y_position = cursor
move_down line_move
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Change Amount", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(sale_data.amount_changed, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
# move_down line_move
end
end
# show member information
def member_info(member_info,customer_name,rebate_amount,sale_data,precision,delimiter,current_balance)
if rebate_amount != nil
if rebate_amount["status"] == true
stroke_horizontal_rule
total = 0
balance = 0
rebate_balance =0
redeem = 0
redeem_count = 0
rebate_amount["data"].each do |res|
total = total + res["balance"]
#total redeem amount
if res["receipt_no"]== sale_data.receipt_no && res["status"]== "Redeem"
redeem = redeem + res["withdraw"]
balance = balance + res["balance"]
end
#end Total redem
#total Rebate Earn
if res["receipt_no"]== sale_data.receipt_no && res["account_status"]== "RebateAccount" && res["status"]== "Rebate"
rebate_balance = rebate_balance + res["deposit"]
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Rebate Earn", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(res["deposit"], :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
end
# Total Rebate Amount if birthday
if res["receipt_no"]== sale_data.receipt_no && res["account_status"]== "RebatebonusAccount" && res["status"]== "Rebate"
rebate_balance = rebate_balance + res["deposit"]
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Rebate Earn Bonus", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(res["deposit"], :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
end
#end Total rebate if birthday
end
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Redeem Amount", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(redeem, :precision => precision.to_i, :delimiter => delimiter)}", :size => self.item_font_size,:align => :right
end
if current_balance != nil
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Old Balance", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(current_balance, :precision => precision.to_i, :delimiter => delimiter)}", :size => self.item_font_size,:align => :right
end
end
end
end
if member_info["status"] == true && member_info["data"].present?
total_balance = 0
member_info["data"].each do |res|
if res["accountable_type"] == "RebateAccount" || res["accountable_type"] == "RebatebonusAccount"
total_balance = total_balance + res["balance"]
end
end
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Total Balance", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{number_format(total_balance, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
end
end
def customer(customer_name)
# move_down line_move
y_position = cursor
#move_down line_move
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Customer Name", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{ customer_name }" , :size => self.item_font_size,:align => :right
end
move_down line_move
stroke_horizontal_rule
end
def discount_account(discount_price_by_accounts,precision,delimiter)
stroke_horizontal_rule
move_down line_move
y_position = cursor
discount_price_by_accounts.each do |ipa|
y_position = cursor
bounding_box([0,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "#{ 'Total ' + ipa[:name] + ' Discounts' }", :size => self.item_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "(" + "#{ number_format(ipa[:price], :precision => precision.to_i, :delimiter => delimiter) }" + ")" , :size => self.item_font_size,:align => :right
end
move_down line_move
end
end
def items_account(item_price_by_accounts,precision,delimiter)
stroke_horizontal_rule
move_down line_move
y_position = cursor
item_price_by_accounts.each do |ipa|
y_position = cursor
bounding_box([0,y_position], :width =>self.label_width) do
text "#{ ipa[:name] }", :size => self.item_font_size,:align => :left
end
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
text "#{number_format(ipa[:price], :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
move_down line_move
end
end
def show_other_charges_amount(other_amount,precision,delimiter)
y_position = cursor
bounding_box([0,y_position], :width =>self.label_width) do
text "Other Charges", :size => self.item_font_size,:align => :left
end
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
text "#{number_format(other_amount, :precision => precision.to_i, :delimiter => delimiter)}" , :size => self.item_font_size,:align => :right
end
move_down line_move
end
#individual payment per person
def individual_payment(sale_data, survey, precision, delimiter)
# per_person = sale_data.grand_total.to_f / survey.total_customer.to_i
per_person = sale_data.grand_total.to_f / survey.to_i
stroke_horizontal_rule
move_down line_move
y_position = cursor
bounding_box([0,y_position], :width =>self.label_width+50) do
text "Split Bill for #{sale_data.equal_persons} persons", :size => self.item_font_size+1,:align => :left
end
bounding_box([0,y_position], :width =>self.label_width) do
move_down 15
text "Amount Due (per person)", :size => self.item_font_size,:align => :left
end
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 15
text "#{number_format(per_person, :precision => precision.to_i, :delimiter => delimiter)}", :size => self.item_font_size,:align => :right
end
end
def sign(sale_data)
query = sale_data.sale_payments
.merge(SalePayment.where.not(payment_method: 'creditnote')
.or(SalePayment.where.not(SalePayment.arel_table[:payment_amount].lteq(sale_data.sale_payments.joins(:sale_audit).sum(:payment_amount)))))
query.each do |payment|
if payment.payment_method == "creditnote"
y_position = cursor
stroke_horizontal_rule
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 70
stroke_horizontal_rule
end
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 73
text "Approved By" , :size => self.item_font_size,:align => :center
end
break;
end
end
if sale_data.payment_status == "foc" || sale_data.payment_status == "waste" || sale_data.payment_status == "spoile"
y_position = cursor
stroke_horizontal_rule
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 70
stroke_horizontal_rule
end
if sale_data.payment_status == "foc"
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 73
text "Acknowledged By" , :size => self.item_font_size,:align => :center
end
elsif sale_data.payment_status == "waste" || sale_data.payment_status == "spoile"
bounding_box([self.label_width,y_position], :width =>self.item_description_width) do
move_down 73
text "Approved By" , :size => self.item_font_size,:align => :center
end
end
end
end
def shop_note(shop)
move_down line_move
stroke_horizontal_rule
move_down line_move
move_down line_move
y_position = cursor
text "#{shop.note}", :size => self.item_font_size, :align => :left
move_down line_move
end
def kbzpay_qr_generator(status, qr_code)
if status == 'Frt'
move_down line_move
move_down line_move
text "Scan to pay with KBZ Pay", :size => self.header_font_size, :align => :center
move_down line_move
print_qr_code(qr_code, pos: [39, cursor], extent: 161, stroke: false, dot: 1000)
move_down line_move
text "This QR code will be expired after 20 minutes.", :size => self.item_font_size, :align => :center
move_down line_move
move_down line_move
end
end
def footer(printed_status)
move_down line_move
stroke_horizontal_rule
move_down line_move
move_down line_move
y_position = cursor
bounding_box([0, y_position], :width =>self.label_width) do
text "#{printed_status}",:style => :bold, :size => header_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.item_description_width, :height => self.item_height) do
text "Thank You! See you Again", :left_margin => -5, :size => self.item_font_size,:align => :left
end
move_down line_move
end
#start card sale trans data
def card_sale_data(card_data)
if card_data != nil && !card_data.empty?
move_down line_move
stroke_horizontal_rule
move_down line_move
y_position = cursor
card_data.each do |data|
if data['app'] == 'CUP'
data['app'] = 'UNIONPAY'
elsif data['app'] == 'MASTERCARD'
data['app'] = 'MASTER'
end
text "DATE/TIME: #{data['res_date']} #{data['res_time']} ", :size => @item_font_size, :align => :left
text "BATCH NUM: #{data['batch_no']} TRACE#: #{data['trace']}",:size => @item_font_size, :align => :left
text "RREF NUM: #{data['ref_no']} APPR CODE: #{data['app_code']} ",:size => @item_font_size, :align => :left
text "TID: #{data['tid']} ",:size => @item_font_size, :align => :left
text "#{data['app']} #{data['pan']} ",:size => @item_font_size, :align => :left
end
end
end
#start card balance data
def card_balance_data(card_balance_amount)
if card_balance_amount > 0
move_down line_move
stroke_horizontal_rule
move_down line_move
y_position = cursor
bounding_box([0, y_position], :width =>self.label_width) do
text "Card Balance: ",:style => :bold, :size => header_font_size,:align => :left
end
bounding_box([self.item_description_width,y_position], :width =>self.label_width) do
text "#{card_balance_amount}" , :size => self.item_font_size,:align => :right
end
end
end
#check ReceiptBillAltName included
def show_alt_name
bill_alt_name = Lookup.collection_of("print_settings") #print_settings with name:ReceiptBillA5Pdf
status = false
if !bill_alt_name.empty?
bill_alt_name.each do |alt_name|
if alt_name[0] == 'ReceiptBillAltName'
if alt_name[1] == '1'
status = true
else
status = false
end
end
end
end
return status
end
end

View File

@@ -50,7 +50,7 @@ class ReceiptBillPdf < Prawn::Document
cashier_info(sale_data, customer_name, latest_order_no) cashier_info(sale_data, customer_name, 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
@@ -94,6 +94,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
@@ -305,7 +308,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
@@ -432,15 +435,20 @@ 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 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'
@@ -458,13 +466,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
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 "#{payment.payment_method.capitalize} Payment", :size => self.item_font_size,:align => :left text "#{payment.payment_method.capitalize} Payment", :size => self.item_font_size,:align => :left
@@ -741,7 +752,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