Skip to content

Commit

Permalink
fix(integrations): Sync credit notes graphql
Browse files Browse the repository at this point in the history
  • Loading branch information
ivannovosad committed May 30, 2024
1 parent b2faa1f commit 79a86b7
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 0 deletions.
27 changes: 27 additions & 0 deletions app/graphql/mutations/integrations/sync_credit_note.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

module Mutations
module Integrations
class SyncCreditNote < BaseMutation
include AuthenticableApiUser
include RequiredOrganization

REQUIRED_PERMISSION = 'organization:integrations:update'

graphql_name 'SyncIntegrationCreditNote'
description 'Sync integration credit note'

input_object_class Types::Integrations::SyncCreditNoteInput

field :credit_note_id, ID, null: true

def resolve(**args)
credit_note = current_organization.credit_notes.find_by(id: args[:credit_note_id])

result = ::Integrations::Aggregator::CreditNotes::CreateService.call_async(credit_note:)
result.success? ? result.credit_note_id : result_error(result)
result
end
end
end
end
7 changes: 7 additions & 0 deletions app/graphql/types/credit_notes/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ class Object < Types::BaseObject
description 'Check if credit note can be voided'
end

field :integration_syncable, GraphQL::Types::Boolean, null: false

def applied_taxes
object.applied_taxes.order(tax_rate: :desc)
end

def integration_syncable
object.should_sync_credit_note? &&
object.integration_resources.where(resource_type: 'credit_note', syncable_type: 'CreditNote').none?
end
end
end
end
11 changes: 11 additions & 0 deletions app/graphql/types/integrations/sync_credit_note_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module Types
module Integrations
class SyncCreditNoteInput < Types::BaseInputObject
graphql_name 'SyncIntegrationCreditNoteInput'

argument :credit_note_id, ID, required: true
end
end
end
1 change: 1 addition & 0 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class MutationType < Types::BaseObject
field :fetch_integration_items, mutation: Mutations::IntegrationItems::FetchItems
field :fetch_integration_tax_items, mutation: Mutations::IntegrationItems::FetchTaxItems

field :sync_integration_credit_note, mutation: Mutations::Integrations::SyncCreditNote
field :sync_integration_invoice, mutation: Mutations::Integrations::SyncInvoice

field :create_credit_note, mutation: Mutations::CreditNotes::Create
Expand Down
33 changes: 33 additions & 0 deletions schema.graphql

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

127 changes: 127 additions & 0 deletions schema.json

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

59 changes: 59 additions & 0 deletions spec/graphql/mutations/integrations/sync_credit_note_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Mutations::Integrations::SyncCreditNote, type: :graphql do
subject(:execute_graphql_call) do
execute_graphql(
current_user: membership.user,
current_organization: membership.organization,
permissions: required_permission,
query: mutation,
variables: {
input: {creditNoteId: credit_note.id}
},
)
end

let(:required_permission) { 'organization:integrations:update' }
let(:credit_note) { create(:credit_note, customer:, organization:) }
let(:customer) { create(:customer, organization:) }
let(:organization) { membership.organization }
let(:membership) { create(:membership) }
let(:integration_customer) { create(:netsuite_customer, customer:, integration:) }
let(:integration) { create(:netsuite_integration, organization:) }

let(:mutation) do
<<-GQL
mutation($input: SyncIntegrationCreditNoteInput!) {
syncIntegrationCreditNote(input: $input) { creditNoteId }
}
GQL
end

let(:service) { instance_double(Integrations::Aggregator::CreditNotes::CreateService) }

let(:result) do
r = BaseService::Result.new
r.credit_note_id = credit_note.id
r
end

before do
integration_customer
allow(Integrations::Aggregator::CreditNotes::CreateService).to receive(:new).and_return(service)
allow(service).to receive(:call_async).and_return(result)
execute_graphql_call
end

it_behaves_like 'requires current user'
it_behaves_like 'requires current organization'
it_behaves_like 'requires permission', 'organization:integrations:update'

it 'syncs a credit note' do
aggregate_failures do
expect(::Integrations::Aggregator::CreditNotes::CreateService).to have_received(:new).with(credit_note:)
expect(service).to have_received(:call_async)
end
end
end
46 changes: 46 additions & 0 deletions spec/graphql/types/credit_notes/object_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Types::CreditNotes::Object do
subject { described_class }

it { is_expected.to have_field(:id).of_type('ID!') }
it { is_expected.to have_field(:number).of_type('String!') }
it { is_expected.to have_field(:sequential_id).of_type('ID!') }

it { is_expected.to have_field(:issuing_date).of_type('ISO8601Date!') }

it { is_expected.to have_field(:description).of_type('String') }
it { is_expected.to have_field(:reason).of_type('CreditNoteReasonEnum!') }

it { is_expected.to have_field(:credit_status).of_type('CreditNoteCreditStatusEnum') }
it { is_expected.to have_field(:refund_status).of_type('CreditNoteRefundStatusEnum') }

it { is_expected.to have_field(:currency).of_type('CurrencyEnum!') }
it { is_expected.to have_field(:taxes_rate).of_type('Float!') }

it { is_expected.to have_field(:balance_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:coupons_adjustment_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:credit_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:refund_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:sub_total_excluding_taxes_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:taxes_amount_cents).of_type('BigInt!') }
it { is_expected.to have_field(:total_amount_cents).of_type('BigInt!') }

it { is_expected.to have_field(:created_at).of_type('ISO8601DateTime!') }
it { is_expected.to have_field(:refunded_at).of_type('ISO8601DateTime') }
it { is_expected.to have_field(:updated_at).of_type('ISO8601DateTime!') }
it { is_expected.to have_field(:voided_at).of_type('ISO8601DateTime') }

it { is_expected.to have_field(:file_url).of_type('String') }

it { is_expected.to have_field(:applied_taxes).of_type('[CreditNoteAppliedTax!]') }
it { is_expected.to have_field(:customer).of_type('Customer!') }
it { is_expected.to have_field(:invoice).of_type('Invoice') }
it { is_expected.to have_field(:items).of_type('[CreditNoteItem!]!') }

it { is_expected.to have_field(:can_be_voided).of_type('Boolean!') }

it { is_expected.to have_field(:integration_syncable).of_type('Boolean!') }
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Types::Integrations::SyncCreditNoteInput do
subject { described_class }

it { is_expected.to accept_argument(:credit_note_id).of_type('ID!') }
end

0 comments on commit 79a86b7

Please sign in to comment.