# encoding: UTF-8 #/* - - - - - - - - - - - - - - - - - - - - - # # Title : WEB Appliances Crest Inc, Web Form Framework # Author : Enrique Phillips # URL : http://www.wac.bz # #- - - - - - - - - - - - - - - - - - - - - */ # the PrintEngine module ... # http://rarlindseysmash.com/posts/config-and-generators-in-gems # # # # ARGS # first value is default # # collation # 'list' | 'record' # paper # 'A4' | 'label' | ... # template # '' | 'slip' | 'quote' # cmd # '' | 'print_label' - a particular method on the printing_class # # PRINTPROMPT # print[medium] # 'display' | 'email' | 'printer' | 'download' # print[output_type] # 'html' | 'pdf' | 'text' # print[printer] # what printer to send output to # print[email_to] # email address # print[message] # body of email # print[range] # which pages should print # print[copies] # number of copies # # PRINTJOB # id, # account_id, # what 'system' / customer # printer_id, # on what printer # printed_by_id, # what id has the printed_by entity # printed_by_type, # what entity - like user # view_template_path, # what template # name, # label the job # printing_class, # what entity provides the data # print_driver, # what 'driver' - like :pdf, :cab, :zebra, :csv, :html, etc # print_format, # data collation - like 'record', 'list' # state, # record the progress # paper, # what material - like 'label32x42', 'A4', etc # copies, # number of identical prints # print_sql, # how to find what will be printed # created_at, # updated_at # # # module PrintEngine include Exceptions def self.included(base) # def base.print_list(options={}) options = set_print_job_defaults options[:resources], options options[:print_job][:print_format] = options[:print][:collation] || 'list' pj = print options[:resources], options end # # def base.default_print_template_path(params,usr) # # TODO 2013-09-02 - select template according to the user/employee # params[:print_job][:view_template_path] || "/test.html.haml" # end # Creates the PrintJob for any model in need of printing # If creating the PrintJob is successful, cycle will be called in print_job.rb # and the PrintJob will be enqueued in the delayed_job queue called 'printing'. # cycle_error will be called in print_job.rb if it cannot be enqueued sucessfully. def base.print( resources, params ) pj = create_print_job( resources, params ) if Rails.env=='development' or pj.download return pj.perform params else user = User.find(pj.printed_by_id) BackgroundPrinterJob.perform_later pj, queue: "printing", account_id: user.account.id # Delayed::Job.enqueue pj, :queue => 'printing' # pj.cycle if Delayed::Job.enqueue pj, :queue => 'printing' # If you comment out above line and use below line with pj.perform instead, you thereby surpass delayed_job, and thus don't have to wait for it # pj.perform return pj end end # # def base.create_print_job( resources, params ) params = ActionController::Parameters.new( params) unless params.class == ActionController::Parameters pj=PrintJob.create( params_permit(params) ) raise PrintJobNotCreatedError.new('arguments not permitted!') unless pj pj end def base.params_permit(params) params[:print_job].permit(:download, :snap_shot, :account_id, :printer_id, :printed_by_id, :printed_by_type, :view_template_path, :printing_class, :name, :print_driver, :print_format, :paper, :copies, :state, :print_sql) end # Sets print_job defaults using the provided params # and looks up any print_job settings to be tweaked # as per klass and user def base.set_print_job_defaults(resources, options) klass = self.to_s #resources.first.class.to_s rescue "class not found!" pb = options[:printed_by] printer_name = options[:print].delete(:printer) || "default" options[:print_job] ||= {} options[:print_job][:printer_id] ||= self.default_printer(pb,printer_name,options[:print][:paper]).id options[:print_job][:state] = "drafted" options[:print_job][:snap_shot] ||= false options[:print_job][:print_sql] = set_resource_sql(resources,options) options[:print_job][:printing_class] ||= klass options[:print_job][:account_id] ||= pb.account.id options[:print_job][:printed_by_id] = pb.id options[:print_job][:printed_by_type] = pb.class.to_s options[:print_job][:name] ||= "#{klass} print at #{I18n.l Time.now, format: :short_date }" options[:print_job][:copies] ||= 1 options[:print_job][:download] = options[:print][:medium]=="download" || false # options[:print_job][:view_template_path] = find_template( options[:print][:template], options[:print][:paper] ) || options[:print_job][:view_template_path] # # this is what we ultimately return options end # # find the best printer for the job def base.default_printer usr, printer_name, paper=nil if printer_name=="default" if paper.nil? printer = (usr.printers.empty? ? nil : usr.printers.active.preferred_printer.first) or raise NoPreferredPrintersFound.new('No preferred printers found!') else printer = (usr.printers.empty? ? nil : (usr.printers.active.preferred_printer.on_paper(paper).first || usr.printers.on_paper(paper).first ) ) or raise NoPreferredPrintersFound.new('No preferred printers found!') end else printer = Printer.active.find_by( 'name like ?', "%#{printer_name.downcase}%") end # usr.printers.where{ (printownerables.preferred==true) & (printownerables.preferred==true) } # raise PrintJobPrinterNotAvailableError printer || Printer.first end def base.set_resource_sql(resources,params) return resources if resources.class == String && resources.downcase =~ /select/ raise PrintJobResourceError.new('No items found to print?!') unless resources.respond_to?(:any?) and resources.any? params[:print_job][:snap_shot] ? resources.to_yaml : (resources.class==Array ? array_to_arel(resources) : resources.to_sql) end def base.array_to_arel resources arel_instance = Arel::Table.new(resources.first.class.table_name) ar_rel = resources.first.class ar_rel.where(arel_instance[:id].in(resources.map(&:id)).to_sql).to_sql end end # # # # list_title # def list_title # self.respond_to?( "name") ? self.name : "please define list_title on model (#{self.class.to_s})!" # end # # # implement on relevant models def find_template template, paper="A4" raise 'you have to implement "def find_template(paper)" on your Model' # 'label.html.haml' end # # # # def set_print_defaults options # options[:context] ||= "" # options[:print_job][:download] = options[:print][:medium]=="download" || false # options[:print_job][:print_driver] = spot_the_driver(options) # options[:print_job][:paper] = options[:paper] || "A4" # options[:print_job][:view_template_path] = find_template( options[:template], options[:paper] ) || params[:print_job][:view_template_path] # options # end # def print_label(options={}) options[:context] ||= "" options[:print] ||= {} options[:print][:collation] = 'record' options[:print][:paper] ||= 'label' options[:print][:output_type] ||= 'raw' options = self.class.set_print_job_defaults [self], options options[:print_job][:print_driver] = options[:print][:print_driver] || :cab options[:print_job][:paper] = options[:print][:paper] || "label" options[:print_job][:print_format] = options[:print][:collation] || 'record' options[:print_job][:view_template_path] = "stock_items/print/zebra_stock_items_label.html.haml" pj = self.class.print [self], options end # options[:print][:printer_name] = options[:print][:printer_name] || '' # options[:user] = options[:user] || current_user def print_record(options={}) options[:context] ||= "" options[:print] ||= {} options[:print][:collation] = 'record' options[:print][:paper] ||= 'A4' options[:print][:output_type] ||= 'pdf' options = self.class.set_print_job_defaults [self], options options[:print_job][:print_driver] = options[:print][:print_driver] || :pdf options[:print_job][:paper] = options[:print][:paper] || "A4" options[:print_job][:print_format] = options[:print][:collation] || 'record' options[:print_job][:view_template_path] = "stock_items/print/slip.html.haml" pj = self.class.print [self], options end end