<commit_before>module XeroGateway

  class Gateway
    include Http
    include Dates

    attr_accessor :client, :xero_url, :logger

    extend Forwardable
    def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access, :expires_at, :authorization_expires_at

    #
    # The consumer key and secret here correspond to those provided
    # to you by Xero inside the API Previewer.
    def initialize(consumer_key, consumer_secret, options = {})
      @xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
      @client   = OAuth.new(consumer_key, consumer_secret, options)
    end

    #
    # Retrieve all contacts from Xero
    #
    # Usage : get_contacts(:order => :name)
    #         get_contacts(:modified_since => Time)
    #
    # Note  : modified_since is in UTC format (i.e. Brisbane is UTC+10)
    def get_contacts(options = {})
      request_params = {}

      if !options[:updated_after].nil?
        warn '[warning] :updated_after is depracated in XeroGateway#get_contacts.  Use :modified_since'
        options[:modified_since] = options.delete(:updated_after)
      end

      request_params[:ContactID]     = options[:contact_id] if options[:contact_id]
      request_params[:ContactNumber] = options[:contact_number] if options[:contact_number]
      request_params[:order]         = options[:order] if options[:order]
      request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
      request_params[:where]         = options[:where] if options[:where]
      request_params[:page]          = options[:page]  if options[:page]

      response_xml = http_get(@client, "#{@xero_url}/Contacts", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contacts'})
    end

    # Retrieve a contact from Xero
    # Usage get_contact_by_id(contact_id)
    def get_contact_by_id(contact_id)
      get_contact(contact_id)
    end

    # Retrieve a contact from Xero
    # Usage get_contact_by_id(contact_id)
    def get_contact_by_number(contact_number)
      get_contact(nil, contact_number)
    end

    # Factory method for building new Contact objects associated with this gateway.
    def build_contact(contact = {})
      case contact
        when Contact then   contact.gateway = self
        when Hash then      contact = Contact.new(contact.merge({:gateway => self}))
      end
      contact
    end

    #
    # Creates a contact in Xero
    #
    # Usage :
    #
    # contact = XeroGateway::Contact.new(:name => "<NAME> THE CONTACT #{Time.now.to_i}")
    # contact.email = "<EMAIL>"
    # contact.phone.number = "12345"
    # contact.address.line_1 = "LINE 1 OF THE ADDRESS"
    # contact.address.line_2 = "LINE 2 OF THE ADDRESS"
    # contact.address.line_3 = "LINE 3 OF THE ADDRESS"
    # contact.address.line_4 = "LINE 4 OF THE ADDRESS"
    # contact.address.city = "WELLINGTON"
    # contact.address.region = "WELLINGTON"
    # contact.address.country = "NEW ZEALAND"
    # contact.address.post_code = "6021"
    #
    # create_contact(contact)
    def create_contact(contact)
      save_contact(contact)
    end

    #
    # Updates an existing Xero contact
    #
    # Usage :
    #
    # contact = xero_gateway.get_contact(some_contact_id)
    # contact.email = "a_new_email_ddress"
    #
    # xero_gateway.update_contact(contact)
    def update_contact(contact)
      raise "contact_id or contact_number is required for updating contacts" if contact.contact_id.nil? and contact.contact_number.nil?
      save_contact(contact)
    end

    #
    # Updates an array of contacts in a single API operation.
    #
    # Usage :
    #  contacts = [XeroGateway::Contact.new(:name => '<NAME>'), XeroGateway::Contact.new(:name => '<NAME>')]
    #  result = gateway.update_contacts(contacts)
    #
    # Will update contacts with matching contact_id, contact_number or name or create if they don't exist.
    #
    def update_contacts(contacts)
      b = Builder::XmlMarkup.new
      request_xml = b.Contacts {
        contacts.each do | contact |
          contact.to_xml(b)
        end
      }

      response_xml = http_post(@client, "#{@xero_url}/Contacts", request_xml, {})

      response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'POST/contacts'})
      response.contacts.each_with_index do | response_contact, index |
        contacts[index].contact_id = response_contact.contact_id if response_contact && response_contact.contact_id
      end
      response
    end

    # Retreives all contact groups from Xero
    #
    # Usage:
    #   groups = gateway.get_contact_groups()
    #
    def get_contact_groups(options = {})
      request_params = {}

      request_params[:ContactGroupID] = options[:contact_group_id] if options[:contact_group_id]
      request_params[:order]          = options[:order] if options[:order]
      request_params[:where]          = options[:where] if options[:where]

      response_xml = http_get(@client, "#{@xero_url}/ContactGroups", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contactgroups'})
    end

    # Retreives a contact group by its id.
    def get_contact_group_by_id(contact_group_id)
      request_params = { :ContactGroupID => contact_group_id }
      response_xml = http_get(@client, "#{@xero_url}/ContactGroups/#{CGI.escape(contact_group_id)}", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contactgroup'})
    end

    # Retrieves all invoices from Xero
    #
    # Usage : get_invoices
    #         get_invoices(:invoice_id => " 297c2dc5-cc47-4afd-8ec8-74990b8761e9")
    #
    # Note  : modified_since is in UTC format (i.e. Brisbane is UTC+10)
    def get_invoices(options = {})

      request_params = {}

      request_params[:InvoiceID]     = options[:invoice_id] if options[:invoice_id]
      request_params[:InvoiceNumber] = options[:invoice_number] if options[:invoice_number]
      request_params[:order]         = options[:order] if options[:order]
      request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]

      request_params[:where]         = options[:where] if options[:where]

      response_xml = http_get(@client, "#{@xero_url}/Invoices", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/Invoices'})
    end<commit_msg>Add the ability to find invoices by contact id A small addition to add the ability to find invoices by passing in a set of contact ids.<commit_after>module XeroGateway

  class Gateway
    include Http
    include Dates

    attr_accessor :client, :xero_url, :logger

    extend Forwardable
    def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access, :expires_at, :authorization_expires_at

    #
    # The consumer key and secret here correspond to those provided
    # to you by Xero inside the API Previewer.
    def initialize(consumer_key, consumer_secret, options = {})
      @xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
      @client   = OAuth.new(consumer_key, consumer_secret, options)
    end

    #
    # Retrieve all contacts from Xero
    #
    # Usage : get_contacts(:order => :name)
    #         get_contacts(:modified_since => Time)
    #
    # Note  : modified_since is in UTC format (i.e. Brisbane is UTC+10)
    def get_contacts(options = {})
      request_params = {}

      if !options[:updated_after].nil?
        warn '[warning] :updated_after is depracated in XeroGateway#get_contacts.  Use :modified_since'
        options[:modified_since] = options.delete(:updated_after)
      end

      request_params[:ContactID]     = options[:contact_id] if options[:contact_id]
      request_params[:ContactNumber] = options[:contact_number] if options[:contact_number]
      request_params[:order]         = options[:order] if options[:order]
      request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
      request_params[:where]         = options[:where] if options[:where]
      request_params[:page]          = options[:page]  if options[:page]

      response_xml = http_get(@client, "#{@xero_url}/Contacts", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contacts'})
    end

    # Retrieve a contact from Xero
    # Usage get_contact_by_id(contact_id)
    def get_contact_by_id(contact_id)
      get_contact(contact_id)
    end

    # Retrieve a contact from Xero
    # Usage get_contact_by_id(contact_id)
    def get_contact_by_number(contact_number)
      get_contact(nil, contact_number)
    end

    # Factory method for building new Contact objects associated with this gateway.
    def build_contact(contact = {})
      case contact
        when Contact then   contact.gateway = self
        when Hash then      contact = Contact.new(contact.merge({:gateway => self}))
      end
      contact
    end

    #
    # Creates a contact in Xero
    #
    # Usage :
    #
    # contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT #{Time.now.to_i}")
    # contact.email = "<EMAIL>"
    # contact.phone.number = "12345"
    # contact.address.line_1 = "LINE 1 OF THE ADDRESS"
    # contact.address.line_2 = "LINE 2 OF THE ADDRESS"
    # contact.address.line_3 = "LINE 3 OF THE ADDRESS"
    # contact.address.line_4 = "LINE 4 OF THE ADDRESS"
    # contact.address.city = "WELLINGTON"
    # contact.address.region = "WELLINGTON"
    # contact.address.country = "NEW ZEALAND"
    # contact.address.post_code = "6021"
    #
    # create_contact(contact)
    def create_contact(contact)
      save_contact(contact)
    end

    #
    # Updates an existing Xero contact
    #
    # Usage :
    #
    # contact = xero_gateway.get_contact(some_contact_id)
    # contact.email = "a_new_email_ddress"
    #
    # xero_gateway.update_contact(contact)
    def update_contact(contact)
      raise "contact_id or contact_number is required for updating contacts" if contact.contact_id.nil? and contact.contact_number.nil?
      save_contact(contact)
    end

    #
    # Updates an array of contacts in a single API operation.
    #
    # Usage :
    #  contacts = [XeroGateway::Contact.new(:name => '<NAME>'), XeroGateway::Contact.new(:name => '<NAME>')]
    #  result = gateway.update_contacts(contacts)
    #
    # Will update contacts with matching contact_id, contact_number or name or create if they don't exist.
    #
    def update_contacts(contacts)
      b = Builder::XmlMarkup.new
      request_xml = b.Contacts {
        contacts.each do | contact |
          contact.to_xml(b)
        end
      }

      response_xml = http_post(@client, "#{@xero_url}/Contacts", request_xml, {})

      response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'POST/contacts'})
      response.contacts.each_with_index do | response_contact, index |
        contacts[index].contact_id = response_contact.contact_id if response_contact && response_contact.contact_id
      end
      response
    end

    # Retreives all contact groups from Xero
    #
    # Usage:
    #   groups = gateway.get_contact_groups()
    #
    def get_contact_groups(options = {})
      request_params = {}

      request_params[:ContactGroupID] = options[:contact_group_id] if options[:contact_group_id]
      request_params[:order]          = options[:order] if options[:order]
      request_params[:where]          = options[:where] if options[:where]

      response_xml = http_get(@client, "#{@xero_url}/ContactGroups", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contactgroups'})
    end

    # Retreives a contact group by its id.
    def get_contact_group_by_id(contact_group_id)
      request_params = { :ContactGroupID => contact_group_id }
      response_xml = http_get(@client, "#{@xero_url}/ContactGroups/#{CGI.escape(contact_group_id)}", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contactgroup'})
    end

    # Retrieves all invoices from Xero
    #
    # Usage : get_invoices
    #         get_invoices(:invoice_id => "297c2dc5-cc47-4afd-8ec8-74990b8761e9")
    #         get_invoices(:invoice_number => "175")
    #         get_invoices(:contact_ids => ["297c2dc5-cc47-4afd-8ec8-74990b8761e9"] )
    #
    # Note  : modified_since is in UTC format (i.e. Brisbane is UTC+10)
    def get_invoices(options = {})

      request_params = {}

      request_params[:InvoiceID]     = options[:invoice_id] if options[:invoice_id]
      request_params[:InvoiceNumber] = options[:invoice_number] if options[:invoice_number]
      request_params[:order]         = options[:order] if options[:order]
      request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
      request_params[:ContactIDs]    = Array(options[:contact_ids]).join(",") if options[:contact_ids]

      request_params[:where]         = options[:where] if options[:where]

      response_xml = http_get(@client, "#{@xero_url}/Invoices", request_params)

      parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/Invoices'})
    end
{'fraction_non_alphanumeric': 0.10858286391935962, 'fraction_numerical': 0.008078861547583754, 'mean_word_length': 3.3624312964759135, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 48, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 30}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5295525', 'n_tokens_mistral': 4278, 'n_tokens_neox': 4136, 'n_words': 897}