lib/rsr_group/order.rb in rsr_group-1.0.0.pre vs lib/rsr_group/order.rb in rsr_group-1.0.0

- old
+ new

@@ -1,62 +1,78 @@ module RsrGroup + # To submit an order: + # + # * Instantiate a new Order, passing in `:merchant_number`, `:username`, `:password`, `:sequence_number`, and `:identifier` + # * Call {#add_recipient} + # * Call {#add_item} for each item on the order + # * Call {#submit!} to send the order class Order < Base - attr_reader :credentials - attr_reader :identifier - attr_reader :timestamp - attr_reader :sequence_number - attr_accessor :recipients - - LINE_TYPES = { - "00" => "file_header", - "10" => "order_header", - "11" => "ffl_dealer", - "20" => "order_detail", - "90" => "order_trailer", - "99" => "file_trailer" - } - + # @param [Hash] options + # @option options [String] :merchant_number *required* + # @option options [Integer] :sequence_number *required* + # @option options [String] :username *required* + # @option options [String] :password *required* + # @option options [String] :identifier *required* def initialize(options = {}) - requires!(options, :sequence_number, :username, :password, :identifier) + requires!(options, :merchant_number, :sequence_number, :username, :password, :identifier) @credentials = options.select { |k, v| [:username, :password].include?(k) } @identifier = options[:identifier] + @merchant_number = options[:merchant_number] @sequence_number = "%04d" % options[:sequence_number] # Leading zeros are required - @timestamp = Time.now.strftime("%Y%m%e") - @recipients = options[:recipients] || [] + @timestamp = Time.now.strftime("%Y%m%d") + @items = [] end - def header - ["FILEHEADER", LINE_TYPES.key("file_header"), customer_number, @timestamp, @sequence_number].join(";") + # @param [Hash] shipping_info + # @option shipping_info [String] :shipping_name *required* + # @option shipping_info [String] :attn + # @option shipping_info [String] :address_one *required* + # @option shipping_info [String] :address_two + # @option shipping_info [String] :city *required* + # @option shipping_info [String] :state *required* + # @option shipping_info [String] :zip *required* + # @option shipping_info [String] :phone + # @option shipping_info [String] :email + # + # @param [Hash] ffl_options optional + # @option ffl_options [String] :licence_number *required* + # @option ffl_options [String] :name *required* + # @option ffl_options [String] :zip *required* + def add_recipient(shipping_info, ffl_options = {}) + @recipient = OrderRecipient.new(shipping_info.merge(order_identifier: @identifier)) + @ffl = OrderFFL.new(ffl_options.merge(order_identifier: @identifier)) if ffl_options.any? end - def footer - ["FILETRAILER", LINE_TYPES.key("file_trailer"), ("%05d" % recipients.length)].join(";") + # @param [Hash] item + # @option item [String] :rsr_stock_number *required* + # @option item [Integer] :quantity *required* + # @option item [String] :shipping_carrier *required* + # @option item [String] :shipping_method *required* + def add_item(item) + @items << OrderDetail.new(item.merge(order_identifier: @identifier)) end def filename - name = ["EORD", customer_number, timestamp, sequence_number].join("-") + name = ["EORD", @merchant_number, @timestamp, @sequence_number].join("-") [name, ".txt"].join end - def recipients - @recipients ||= [] - end - def to_txt + raise "Recipient is required!" unless @recipient + raise "Items are required!" unless @items.length > 0 + txt = header + "\n" - recipients.each do |recipient| - txt += (recipient.to_single_line + "\n") - if recipient.ffl - txt += (recipient.ffl.to_single_line + "\n") - end - recipient.items.each do |item| - txt += (item.to_single_line + "\n") - end - txt += recipient.trailer + "\n" + txt += @recipient.to_single_line + "\n" + if @ffl + txt += (@ffl.to_single_line + "\n") end + @items.each do |item| + txt += (item.to_single_line + "\n") + end + txt += order_trailer + "\n" txt += footer end def submit! connect(@credentials) do |ftp| @@ -66,19 +82,26 @@ ftp.storlines("STOR " + filename, io) ensure io.close end end + true end private - def customer_number - credentials[:username] + def header + ["FILEHEADER", LINE_TYPES.key(:file_header), @merchant_number, @timestamp, @sequence_number].join(";") end - def items - recipients.map(&:items).flatten.compact + def footer + # NOTE: The 'Number of Orders in File' datum is hard-coded to 1 + # For our purposes, only 1 recipient can ever be allowed in an RSR order + ["FILETRAILER", LINE_TYPES.key(:file_trailer), '00001'].join(";") + end + + def order_trailer + [@identifier, LINE_TYPES.key(:order_trailer), ("%07d" % @items.length)].join(";") end end end