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