Skip to content

Commit

Permalink
fix(xero): Fix syncing xero accounts (#2290)
Browse files Browse the repository at this point in the history
## Roadmap Task

👉  https://getlago.canny.io/feature-requests/p/integration-with-xero

## Context

Currently Lago does not support accounting integrations

## Description

This PR removes the accounts resolver and adds FetchAccounts mutation
instead.
  • Loading branch information
ivannovosad authored Jul 19, 2024
1 parent 2d839f5 commit f3d17bf
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 263 deletions.
29 changes: 29 additions & 0 deletions app/graphql/mutations/integration_items/fetch_accounts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Mutations
module IntegrationItems
class FetchAccounts < BaseMutation
include AuthenticableApiUser
include RequiredOrganization

REQUIRED_PERMISSION = 'organization:integrations:update'

graphql_name 'FetchIntegrationAccounts'
description 'Fetch integration accounts'

argument :integration_id, ID, required: true

type Types::IntegrationItems::Object.collection_type, null: false

def resolve(**args)
integration = current_organization.integrations.find_by(id: args[:integration_id])

::Integrations::Aggregator::SyncService.call(integration:, options: {only_accounts: true})

result = ::Integrations::Aggregator::AccountsService.call(integration:)

result.success? ? result.accounts : result_error(result)
end
end
end
end
26 changes: 0 additions & 26 deletions app/graphql/resolvers/integrations/accounts_resolver.rb

This file was deleted.

1 change: 1 addition & 0 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class MutationType < Types::BaseObject
field :destroy_integration_collection_mapping, mutation: Mutations::IntegrationCollectionMappings::Destroy
field :destroy_integration_mapping, mutation: Mutations::IntegrationMappings::Destroy

field :fetch_integration_accounts, mutation: Mutations::IntegrationItems::FetchAccounts
field :fetch_integration_items, mutation: Mutations::IntegrationItems::FetchItems
field :fetch_integration_tax_items, mutation: Mutations::IntegrationItems::FetchTaxItems

Expand Down
1 change: 0 additions & 1 deletion app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class QueryType < Types::BaseObject
field :google_auth_url, resolver: Resolvers::Auth::Google::AuthUrlResolver
field :gross_revenues, resolver: Resolvers::Analytics::GrossRevenuesResolver
field :integration, resolver: Resolvers::IntegrationResolver
field :integration_accounts, resolver: Resolvers::Integrations::AccountsResolver
field :integration_collection_mapping, resolver: Resolvers::IntegrationCollectionMappingResolver
field :integration_collection_mappings, resolver: Resolvers::IntegrationCollectionMappingsResolver
field :integration_items, resolver: Resolvers::IntegrationItemsResolver
Expand Down
3 changes: 2 additions & 1 deletion app/models/integration_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ class IntegrationItem < ApplicationRecord

ITEM_TYPES = [
:standard,
:tax
:tax,
:account
].freeze

enum item_type: ITEM_TYPES
Expand Down
47 changes: 39 additions & 8 deletions app/services/integrations/aggregator/accounts_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,38 @@
module Integrations
module Aggregator
class AccountsService < BaseService
LIMIT = 450
MAX_SUBSEQUENT_REQUESTS = 15

def action_path
"v1/#{provider}/accounts"
end

def call
response = http_client.get(headers:)
@cursor = ''
@items = []

ActiveRecord::Base.transaction do
integration.integration_items.where(item_type: :account).destroy_all

MAX_SUBSEQUENT_REQUESTS.times do |_i|
response = http_client.get(headers:, params:)

result.accounts = handle_accounts(response['records'])
handle_accounts(response['records'])
@cursor = response['next_cursor']

break if cursor.blank?
end
end
result.accounts = items

result
end

private

attr_reader :cursor, :items

def headers
{
'Connection-Id' => integration.connection_id,
Expand All @@ -25,15 +43,28 @@ def headers
}
end

def handle_accounts(accounts)
accounts.map do |account|
OpenStruct.new(
external_id: account['id'],
external_account_code: account['code'],
external_name: account['name']
def handle_accounts(new_items)
new_items.each do |item|
integration_item = IntegrationItem.new(
integration:,
external_id: item['id'],
external_account_code: item['code'],
external_name: item['name'],
item_type: :account
)

integration_item.save!

@items << integration_item
end
end

def params
{
limit: LIMIT,
cursor:
}
end
end
end
end
1 change: 1 addition & 0 deletions app/services/integrations/aggregator/sync_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def sync_list

return [list[:items]] if options[:only_items]
return [list[:tax_items]] if options[:only_tax_items]
return [list[:accounts]] if options[:only_accounts]

list.values
end
Expand Down
38 changes: 22 additions & 16 deletions schema.graphql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f3d17bf

Please sign in to comment.