Class: Bisac::PO

Inherits:
Object
  • Object
show all
Defined in:
lib/bisac/po.rb

Overview

Represents a single BISAC purchase order.

Generating

po = Bisac::PO.new
po.source_san = "1111111"
po.source_name = "James"
...
item = Bisac::POLineItem.new
item.isbn = "0385519869"
item.qty = 2
po.items << item
puts po.to_s

Reading

Each PO file can contain multiple PO’s, so use pasrse_file() to iterate over them all.

Bisac::PO.parse_file("filename.bsc") do |msg|
  puts msg.source_san
  puts msg.source_name
  puts msg.items.size
  ...
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePO

creates a new RBook::Bisac::PO object



40
41
42
43
44
45
46
47
# File 'lib/bisac/po.rb', line 40

def initialize
  @items = []

  # default values
  @cancellation_date = "000000"
  @do_not_ship_before = "000000"
  @backorder = true
end

Instance Attribute Details

#backorderObject

Returns the value of attribute backorder.



33
34
35
# File 'lib/bisac/po.rb', line 33

def backorder
  @backorder
end

#cancellation_dateObject

Returns the value of attribute cancellation_date.



33
34
35
# File 'lib/bisac/po.rb', line 33

def cancellation_date
  @cancellation_date
end

#dateObject

Returns the value of attribute date.



31
32
33
# File 'lib/bisac/po.rb', line 31

def date
  @date
end

#destination_sanObject

Returns the value of attribute destination_san.



32
33
34
# File 'lib/bisac/po.rb', line 32

def destination_san
  @destination_san
end

#destination_suffixObject

Returns the value of attribute destination_suffix.



32
33
34
# File 'lib/bisac/po.rb', line 32

def destination_suffix
  @destination_suffix
end

#do_not_exceed_actionObject

Returns the value of attribute do_not_exceed_action.



34
35
36
# File 'lib/bisac/po.rb', line 34

def do_not_exceed_action
  @do_not_exceed_action
end

#do_not_exceed_amountObject

Returns the value of attribute do_not_exceed_amount.



34
35
36
# File 'lib/bisac/po.rb', line 34

def do_not_exceed_amount
  @do_not_exceed_amount
end

#do_not_ship_beforeObject

Returns the value of attribute do_not_ship_before.



36
37
38
# File 'lib/bisac/po.rb', line 36

def do_not_ship_before
  @do_not_ship_before
end

#filenameObject

Returns the value of attribute filename.



31
32
33
# File 'lib/bisac/po.rb', line 31

def filename
  @filename
end

#format_versionObject

Returns the value of attribute format_version.



31
32
33
# File 'lib/bisac/po.rb', line 31

def format_version
  @format_version
end

#invoice_copiesObject

Returns the value of attribute invoice_copies.



35
36
37
# File 'lib/bisac/po.rb', line 35

def invoice_copies
  @invoice_copies
end

#itemsObject

Returns the value of attribute items.



37
38
39
# File 'lib/bisac/po.rb', line 37

def items
  @items
end

#po_numberObject

Returns the value of attribute po_number.



33
34
35
# File 'lib/bisac/po.rb', line 33

def po_number
  @po_number
end

#source_nameObject

Returns the value of attribute source_name.



30
31
32
# File 'lib/bisac/po.rb', line 30

def source_name
  @source_name
end

#source_sanObject

Returns the value of attribute source_san.



30
31
32
# File 'lib/bisac/po.rb', line 30

def source_san
  @source_san
end

#source_suffixObject

Returns the value of attribute source_suffix.



30
31
32
# File 'lib/bisac/po.rb', line 30

def source_suffix
  @source_suffix
end

#special_instructionsObject

Returns the value of attribute special_instructions.



35
36
37
# File 'lib/bisac/po.rb', line 35

def special_instructions
  @special_instructions
end

Class Method Details

.load_from_file(input) ⇒ Object

reads a bisac text file into memory. input should be a string that specifies the file path



51
52
53
54
55
# File 'lib/bisac/po.rb', line 51

def self.load_from_file(input)
  $stderr.puts "WARNING: RBook::Bisac::PO.load_from_file is deprecated. It only returns the first PO in the file. use parse_file instead."
  self.parse_file(input) { |msg| return msg }
  return nil
end

.load_from_string(input) ⇒ Object

creates a RBook::Bisac::PO object from a string. Input should be a complete bisac file as a string



102
103
104
105
106
# File 'lib/bisac/po.rb', line 102

def self.load_from_string(input)
  $stderr.puts "WARNING: Bisac::PO.load_from_string is deprecated. It only returns the first PO in the string. use parse_string instead."
  data = input.split("\n")
  return self.build_message(data)
end

.parse_file(input) {|self.build_message(data)| ... } ⇒ Object

return all POs from a BISAC file

Yields:

  • (self.build_message(data))

Raises:

  • (ArgumentError)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/bisac/po.rb', line 58

def self.parse_file(input, &block)
  raise ArgumentError, 'no file provided' if input.nil?
  raise ArgumentError, 'Invalid file' unless File.file?(input)
  data = []
  File.open(input, "r") do |f|
    f.each_line do |l|
      data << l

      # yield each message found in the file. A line starting with
      # 90 is the footer to a PO
      if data.last[0,2] == "90"
        yield self.build_message(data)
        data = []
      end
    end
  end

  # if we've got to the end of the file, and haven't hit a footer line yet, the file
  # is probably malformed. Call build_message anyway, and let it detect any errors
  yield self.build_message(data) if data.size > 0
end

.parse_string(input) {|self.build_message(data)| ... } ⇒ Object

return all POs from a BISAC string

Yields:

  • (self.build_message(data))

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/bisac/po.rb', line 81

def self.parse_string(input, &block)
  raise ArgumentError, 'no data provided' if input.nil?
  data = []
  input.split("\n").each do |l|
    data << l

    # yield each message found in the string. A line starting with
    # 90 is the footer to a PO
    if data.last[0,2] == "90"
      yield self.build_message(data)
      data = []
    end
  end

  # if we've got to the end of the file, and haven't hit a footer line yet, the file
  # is probably malformed. Call build_message anyway, and let it detect any errors
  yield self.build_message(data) if data.size > 0
end

Instance Method Details

#to_sObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/bisac/po.rb', line 112

def to_s
  lines = []

  # file header
  line = " " * 80
  line[0,2]   = "00" # line type
  line[2,5]   = "00001"  # line counter
  line[7,7]   = pad_trunc(@source_san, 7)
  line[14,5]  = pad_trunc(@source_suffix, 5)
  line[19,13] = pad_trunc(@source_name, 13)
  line[32,6]  = pad_trunc(@date, 6)
  line[38,22] = pad_trunc(@filename, 22)
  line[60,3]  = pad_trunc(@format_version, 3)
  line[63,7]  = pad_trunc(@destination_san, 7)
  line[70,5]  = pad_trunc(@destination_suffix, 5)
  lines << line

  # po header
  lines << ""
  lines.last << "10"
  lines.last << "00002"  # line counter
  lines.last << " "
  lines.last << @po_number.to_s.ljust(11, " ")
  lines.last << " " # TODO
  lines.last << pad_trunc(@source_san, 7)
  lines.last << pad_trunc("",5) # TODO
  lines.last << pad_trunc(@destination_san, 7)
  lines.last << pad_trunc("",5) # TODO
  lines.last << pad_trunc(@date, 6)
  lines.last << pad_trunc(@cancellation_date,6)
  lines.last << yes_no(@backorder)
  lines.last << pad_trunc(@do_not_exceed_action,1)
  lines.last << pad_trunc(@do_not_exceed_amount,7)
  lines.last << pad_trunc(@invoice_copies,2)
  lines.last << yes_no(@special_instructions)
  lines.last << pad_trunc("",5) # TODO
  lines.last << pad_trunc(@do_not_ship_before,6)

  sequence = 3
  @items.each_with_index do |item, idx|
    item.line_item_number = idx + 1
    item.sequence_number  = sequence
    lines    += item.to_s.split("\n")
    sequence += 3
  end

  # PO control
  line = " " * 80
  line[0,2]   = "50"
  line[2,5]   = (lines.size + 1).to_s.rjust(5,"0")  # line counter
  line[8,12]  = @po_number.to_s.ljust(13, " ")
  line[20,5]  = "00001" # number of POs in file
  line[25,10] = @items.size.to_s.rjust(10,"0")
  line[35,10] = total_qty.to_s.rjust(10,"0")
  lines << line

  # file trailer
  line = " " * 80
  line[0,2]   = "90"
  line[2,5]   = (lines.size+1).to_s.rjust(5,"0")  # line counter
  line[7,20]  = @items.size.to_s.rjust(13,"0")
  line[20,5]  = "00001" # total '10' (PO) records
  line[25,10] = total_qty.to_s.rjust(10,"0")
  line[35,5]  = "00001" # number of '00'-'09' records
  line[40,5]  = "00001" # number of '10'-'19' records
  line[55,5]  = (@items.size * 3).to_s.rjust(5,"0") # number of '40'-'49' records
  line[60,5]  = "00000" # number of '50'-'59' records
  line[45,5]  = "00000" # number of '60'-'69' records
  lines << line

  lines.join("\n")
end

#total_qtyObject



108
109
110
# File 'lib/bisac/po.rb', line 108

def total_qty
  @items.collect { |i| i.qty }.inject { |sum, x| sum ? sum+x : x}
end