diff --git a/Gemfile b/Gemfile index f8407decdc..81f0d57346 100644 --- a/Gemfile +++ b/Gemfile @@ -90,6 +90,7 @@ gem 'jquery-rails' gem 'jquery-migrate-rails' gem 'css_splitter' +gem 'ofn-qz', github: 'ltrls/ofn-qz' group :test, :development do # Pretty printed test output diff --git a/Gemfile.lock b/Gemfile.lock index 824f8a0c04..44003bf9d9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,6 +12,13 @@ GIT specs: custom_error_message (1.1.1) +GIT + remote: git://github.com/ltrls/ofn-qz.git + revision: 024680ccea429b2e5428d7b964fa67c52add34ec + specs: + ofn-qz (0.1.0) + railties (~> 3.1) + GIT remote: git://github.com/openfoodfoundation/better_spree_paypal_express.git revision: 840d973cd5bd3250b17674a624dad494aeb09eb3 @@ -694,6 +701,7 @@ DEPENDENCIES momentjs-rails newrelic_rpm nokogiri (>= 1.6.7.1) + ofn-qz! oj paper_trail (~> 3.0.8) paperclip diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index e24f89eb27..129d4c3308 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -90,6 +90,10 @@ Spree::Admin::OrdersController.class_eval do render pdf: "invoice-#{@order.number}", template: template, encoding: "UTF-8" end + def print_ticket + render template: "spree/admin/orders/ticket", layout: false + end + def update_distribution_charge @order.update_distribution_charge! end diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index ea0854b717..f55a619f2b 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -62,6 +62,10 @@ module CheckoutHelper end end + def display_adjustment_amount(adjustment) + Spree::Money.new(adjustment.amount, { :currency => adjustment.currency }) + end + def display_checkout_total_less_tax(order) Spree::Money.new order.total - order.total_tax, currency: order.currency end diff --git a/app/helpers/spree/admin/orders_helper_decorator.rb b/app/helpers/spree/admin/orders_helper_decorator.rb index 23443cc400..b75d0df45b 100644 --- a/app/helpers/spree/admin/orders_helper_decorator.rb +++ b/app/helpers/spree/admin/orders_helper_decorator.rb @@ -13,6 +13,8 @@ module Spree links << { name: t(:send_invoice), url: "#", icon: 'icon-email', confirm: t(:must_have_valid_business_number, enterprise_name: order.distributor.name) } end links << { name: t(:print_invoice), url: print_admin_order_path(order), icon: 'icon-print', target: "_blank" } + links << { name: t(:print_ticket), url: print_ticket_admin_order_path(order), icon: 'icon-print', target: "_blank" } + links << { name: t(:select_ticket_printer), url: "#{print_ticket_admin_order_path(order)}#select-printer", icon: 'icon-print', target: "_blank" } end if @order.ready_to_ship? links << { name: t(:ship_order), url: fire_admin_order_path(@order, :e => 'ship'), method: 'put', icon: 'icon-truck', confirm: t(:are_you_sure) } diff --git a/app/views/spree/admin/orders/ticket.html.haml b/app/views/spree/admin/orders/ticket.html.haml new file mode 100644 index 0000000000..53f224cff1 --- /dev/null +++ b/app/views/spree/admin/orders/ticket.html.haml @@ -0,0 +1,79 @@ +!!! Basic +%html + %head + + = javascript_include_tag "shared/jquery-1.8.0.js" + = javascript_include_tag "qz/qz-tray.js" + = javascript_include_tag "qz/sha-256.min.js" + = javascript_include_tag "qz/rsvp-3.1.0.min.js" + = javascript_include_tag "qz/jsrsasign-latest-all-min.js" + :javascript + var printData = [ + '\x1B' + '\x40', // init + '\x1B' + '\x74' + '\x10', + '\x1B' + '\x61' + '\x31', // center align + '\x1B' + '\x21' + '\x30', // em mode on + '#{@order.distributor.name}' + '\x0A', + '\x1B' + '\x21' + '\x0A' + '\x1B' + '\x45' + '\x0A', // em mode off + '\x0A', + '#{@order.distributor.address.address_part1}' + '\x0A', // text and line break + '#{@order.distributor.address.address_part2}' + '\x0A', + '#{@order.distributor.email}' + '\x0A', + '\x0A', // line break + '\x1B' + '\x61' + '\x32', // right align + '#{l Time.zone.now.to_date}' + '\x0A', + '#{@order.number}' + '\x0A', + '\x1B' + '\x61' + '\x30', // left align + '\x0A', + '\x1B' + '\x4D' + '\x31', // small text + "#{'%6s %-23s%12s%12s' % + [t(:ticket_column_qty), + t(:ticket_column_item), + t(:ticket_column_unit_price), + t(:ticket_column_total_price)]}", + '\x0A', + '\x1B' + '\x4D' + '\x30', // normal text + '__________________________________________' + '\x0A', + "#{@order.line_items + .sort_by{ |line_item| line_item.product.name } + .map { |line_item| '%5d %-19.19s%8.8s%8.8s' % + [line_item.quantity, + line_item.product.name, + line_item.single_display_amount_with_adjustments.money.format(symbol: false), + line_item.display_amount_with_adjustments.money.format(symbol: false)] } + .join('" + \'\x0A\' + "')}", + '\x0A', + "#{checkout_adjustments_for(@order, exclude: [:line_item]) + .reject{ |a| a.amount == 0 } + .reverse.map { |adjustment| '%5s %-27.27s%8.8s' % + ["", + raw(adjustment.label), + display_adjustment_amount(adjustment).money.format(symbol: false)] } + .join('" + \'\x0A\' + "')}", + '\x0A', + '__________________________________________' + '\x0A', + '\x0A', + '\x1B' + '\x45' + '\x0D', // bold on + "#{'%31s%10s' % + [t(:total_incl_tax), + @order.display_total]}", + '\x1B' + '\x45' + '\x0A', // bold off + '\x0A', + "#{display_checkout_taxes_hash(@order).map { |tax_rate, tax_value| + '%31s%10s' % + [t(:tax_total, rate: tax_rate), + tax_value] } + .join('" + \'\x0A\' + "')}", + '\x0A', + "#{'%31s%10s' % + [t(:total_excl_tax), + display_checkout_total_less_tax(@order)]}", + '\x0A', + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A' + '\x0A', + '\x1B' + '\x69', // cut paper + ]; + = javascript_include_tag "qz/ticket-popup.js" + %body + %div#printer-list + + diff --git a/config/locales/en.yml b/config/locales/en.yml index 1031187aa7..2681d920ce 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -46,6 +46,8 @@ en: producers_join: Australian producers are now welcome to join the Open Food Network. #FIXME charges_sales_tax: Charges GST? print_invoice: "Print Invoice" + print_ticket: "Print Ticket" + select_ticket_printer: "Select printer for tickets" send_invoice: "Send Invoice" resend_confirmation: "Resend Confirmation" view_order: "View Order" @@ -553,6 +555,11 @@ en: order_number: "Invoice number:" date_of_transaction: "Date of transaction:" + ticket_column_qty: "Qty" + ticket_column_item: "Item" + ticket_column_unit_price: "Unit Price" + ticket_column_total_price: "Total Price" + logo: "Logo (640x130)" #FIXME logo_mobile: "Mobile logo (75x26)" #FIXME logo_mobile_svg: "Mobile logo (SVG)" #FIXME diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 6a5f04a021..c5874bcc09 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -28,6 +28,8 @@ fr: producers_join: Les producteurs et autres hubs basés en France sont invités à rejoindre Open Food France. charges_sales_tax: Soumis à la TVA? print_invoice: "Imprimer la facture" + print_ticket: "Imprimer le ticket" + select_ticket_printer: "Choisir l'imprimante à tickets" send_invoice: "Envoyer la facture" resend_confirmation: "Renvoyer la confirmation" view_order: "Voir la commande" @@ -492,6 +494,8 @@ fr: invoice_column_price: "Prix" invoice_column_item: "Produit" invoice_column_qty: "Qté" + invoice_column_tax: "TVA" + invoice_column_price: "Prix" invoice_column_unit_price_with_taxes: "Prix unitaire (TTC)" invoice_column_unit_price_without_taxes: "Prix unitaire (HT)" invoice_column_price_with_taxes: "Prix total (TTC)" @@ -510,6 +514,10 @@ fr: percentage: format: format: "%n %" + ticket_column_qty: "Qté" + ticket_column_item: "Item" + ticket_column_unit_price: "Px Unit" + ticket_column_total_price: "Px Total" logo: "Logo (640x130)" logo_mobile: "Logo smartphone (75x26)" diff --git a/config/routes.rb b/config/routes.rb index ed344f1288..04ad87568e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -249,6 +249,7 @@ Spree::Core::Engine.routes.prepend do resources :orders do get :invoice, on: :member get :print, on: :member + get :print_ticket, on: :member get :managed, on: :collection end