Class: XeroGateway::CreditNote

Inherits:
Object
  • Object
show all
Includes:
Dates, LineItemCalculations, Money
Defined in:
lib/xero_gateway/credit_note.rb

Constant Summary collapse

CREDIT_NOTE_TYPE =
{
  'ACCRECCREDIT' =>           'Accounts Receivable',
  'ACCPAYCREDIT' =>           'Accounts Payable'
}
LINE_AMOUNT_TYPES =
{
  "Inclusive" =>        'CreditNote lines are inclusive tax',
  "Exclusive" =>        'CreditNote lines are exclusive of tax (default)',
  "NoTax"     =>        'CreditNotes lines have no tax'
}
CREDIT_NOTE_STATUS =
{
  'AUTHORISED' =>       'Approved credit_notes awaiting payment',
  'DELETED' =>          'Draft credit_notes that are deleted',
  'DRAFT' =>            'CreditNotes saved as draft or entered via API',
  'PAID' =>             'CreditNotes approved and fully paid',
  'SUBMITTED' =>        'CreditNotes entered by an employee awaiting approval',
  'VOID' =>             'Approved credit_notes that are voided'
}
GUID_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LineItemCalculations

#add_line_item, #sub_total, #total, #total_tax

Methods included from Money

included

Methods included from Dates

included

Constructor Details

#initialize(params = {}) ⇒ CreditNote

Returns a new instance of CreditNote.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/xero_gateway/credit_note.rb', line 42

def initialize(params = {})
  @errors ||= []
  @payments ||= []

  # Check if the line items have been downloaded.
  @line_items_downloaded = (params.delete(:line_items_downloaded) == true)

  params = {
    :line_amount_types => "Inclusive"
  }.merge(params)

  params.each do |k,v|
    self.send("#{k}=", v)
  end

  @line_items ||= []
end

Instance Attribute Details

#amount_creditedObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def amount_credited
  @amount_credited
end

#contactObject



103
104
105
# File 'lib/xero_gateway/credit_note.rb', line 103

def contact
  @contact ||= build_contact
end

#credit_note_idObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def credit_note_id
  @credit_note_id
end

#credit_note_numberObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def credit_note_number
  @credit_note_number
end

#currency_codeObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def currency_code
  @currency_code
end

#dateObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def date
  @date
end

#errorsObject (readonly)

Any errors that occurred when the #valid? method called.



33
34
35
# File 'lib/xero_gateway/credit_note.rb', line 33

def errors
  @errors
end

#fully_paid_onObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def fully_paid_on
  @fully_paid_on
end

#gatewayObject

Xero::Gateway associated with this credit_note.



30
31
32
# File 'lib/xero_gateway/credit_note.rb', line 30

def gateway
  @gateway
end

#line_amount_typesObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def line_amount_types
  @line_amount_types
end

#line_itemsObject

If line items are not downloaded, then attempt a download now (if this record was found to begin with).



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/xero_gateway/credit_note.rb', line 123

def line_items
  if line_items_downloaded?
    @line_items

  # There is an credit_note_is so we can assume this record was loaded from Xero.
  # attempt to download the line_item records.
  elsif credit_note_id =~ GUID_REGEX
    raise NoGatewayError unless @gateway

    response = @gateway.get_credit_note(credit_note_id)
    raise CreditNoteNotFoundError, "CreditNote with ID #{credit_note_id} not found in Xero." unless response.success? && response.credit_note.is_a?(XeroGateway::CreditNote)

    @line_items = response.credit_note.line_items
    @line_items_downloaded = true

    @line_items

  # Otherwise, this is a new credit_note, so return the line_items reference.
  else
    @line_items
  end
end

#line_items_downloadedObject

Represents whether the line_items have been downloaded when getting from GET /API.XRO/2.0/CreditNotes



36
37
38
# File 'lib/xero_gateway/credit_note.rb', line 36

def line_items_downloaded
  @line_items_downloaded
end

#paymentsObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def payments
  @payments
end

#referenceObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def reference
  @reference
end

#statusObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def status
  @status
end

#typeObject

All accessible fields



39
40
41
# File 'lib/xero_gateway/credit_note.rb', line 39

def type
  @type
end

Class Method Details

.from_xml(credit_note_element, gateway = nil, options = {}) ⇒ Object

TODO UpdatedDateUTC



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/xero_gateway/credit_note.rb', line 186

def self.from_xml(credit_note_element, gateway = nil, options = {})
  credit_note = CreditNote.new(options.merge({:gateway => gateway}))
  credit_note_element.children.each do |element|
    case(element.name)
      when "CreditNoteID" then credit_note.credit_note_id = element.text
      when "CreditNoteNumber" then credit_note.credit_note_number = element.text
      when "Type" then credit_note.type = element.text
      when "CurrencyCode" then credit_note.currency_code = element.text
      when "Contact" then credit_note.contact = Contact.from_xml(element)
      when "Date" then credit_note.date = parse_date(element.text)
      when "Status" then credit_note.status = element.text
      when "Reference" then credit_note.reference = element.text
      when "LineAmountTypes" then credit_note.line_amount_types = element.text
      when "LineItems" then element.children.each {|line_item| credit_note.line_items_downloaded = true; credit_note.line_items << LineItem.from_xml(line_item) }
      when "SubTotal" then credit_note.sub_total = BigDecimal.new(element.text)
      when "TotalTax" then credit_note.total_tax = BigDecimal.new(element.text)
      when "Total" then credit_note.total = BigDecimal.new(element.text)
      when "Payments" then element.children.each { | payment | credit_note.payments << Payment.from_xml(payment) }
      when "AmountDue" then credit_note.amount_due = BigDecimal.new(element.text)
      when "AmountPaid" then credit_note.amount_paid = BigDecimal.new(element.text)
      when "AmountCredited" then credit_note.amount_credited = BigDecimal.new(element.text)
    end
  end
  credit_note
end

Instance Method Details

#==(other) ⇒ Object



146
147
148
149
150
151
152
153
154
155
# File 'lib/xero_gateway/credit_note.rb', line 146

def ==(other)
  ["credit_note_number", "type", "status", "reference", "currency_code", "line_amount_types", "contact", "line_items"].each do |field|
    return false if send(field) != other.send(field)
  end

  ["date"].each do |field|
    return false if send(field).to_s != other.send(field).to_s
  end
  return true
end

#accounts_payable?Boolean

Helper method to check if the credit_note is accounts payable.

Returns:

  • (Boolean)


108
109
110
# File 'lib/xero_gateway/credit_note.rb', line 108

def accounts_payable?
  type == 'ACCPAYCREDIT'
end

#accounts_receivable?Boolean

Helper method to check if the credit_note is accounts receivable.

Returns:

  • (Boolean)


113
114
115
# File 'lib/xero_gateway/credit_note.rb', line 113

def accounts_receivable?
  type == 'ACCRECCREDIT'
end

#build_contact(params = {}) ⇒ Object

Helper method to create the associated contact object.



99
100
101
# File 'lib/xero_gateway/credit_note.rb', line 99

def build_contact(params = {})
  self.contact = gateway ? gateway.build_contact(params) : Contact.new(params)
end

#createObject Also known as: save

Creates this credit_note record (using gateway.create_credit_note) with the associated gateway. If no gateway set, raise a NoGatewayError exception.

Raises:



159
160
161
162
# File 'lib/xero_gateway/credit_note.rb', line 159

def create
  raise NoGatewayError unless gateway
  gateway.create_credit_note(self)
end

#line_items_downloaded?Boolean

Whether or not the line_items have been downloaded (GET/credit_notes does not download line items).

Returns:

  • (Boolean)


118
119
120
# File 'lib/xero_gateway/credit_note.rb', line 118

def line_items_downloaded?
  @line_items_downloaded
end

#to_xml(b = Builder::XmlMarkup.new) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/xero_gateway/credit_note.rb', line 167

def to_xml(b = Builder::XmlMarkup.new)
  b.CreditNote {
    b.Type self.type
    contact.to_xml(b)
    b.Date CreditNote.format_date(self.date || Date.today)
    b.Status self.status if self.status
    b.CreditNoteNumber self.credit_note_number if credit_note_number
    b.Reference self.reference if self.reference
    b.CurrencyCode self.currency_code if self.currency_code
    b.LineAmountTypes self.line_amount_types
    b.LineItems {
      self.line_items.each do |line_item|
        line_item.to_xml(b)
      end
    }
  }
end

#valid?Boolean

Validate the Address record according to what will be valid by the gateway.

Usage:

address.valid?     # Returns true/false

Additionally sets address.errors array to an array of field/error.

Returns:

  • (Boolean)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/xero_gateway/credit_note.rb', line 66

def valid?
  @errors = []

  if !credit_note_id.nil? && credit_note_id !~ GUID_REGEX
    @errors << ['credit_note_id', 'must be blank or a valid Xero GUID']
  end

  if status && !CREDIT_NOTE_STATUS[status]
    @errors << ['status', "must be one of #{CREDIT_NOTE_STATUS.keys.join('/')}"]
  end

  if line_amount_types && !LINE_AMOUNT_TYPES[line_amount_types]
    @errors << ['line_amount_types', "must be one of #{LINE_AMOUNT_TYPES.keys.join('/')}"]
  end

  unless date
    @errors << ['credit_note_date', "can't be blank"]
  end

  # Make sure contact is valid.
  unless @contact && @contact.valid?
    @errors << ['contact', 'is invalid']
  end

  # Make sure all line_items are valid.
  unless line_items.all? { | line_item | line_item.valid? }
    @errors << ['line_items', "at least one line item invalid"]
  end

  @errors.size == 0
end