Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module IntegrationCollectionMappings
class CreateInput < Types::BaseInputObject
graphql_name "CreateIntegrationCollectionMappingInput"

argument :billing_entity_id, ID, required: false
argument :external_account_code, String, required: false
argument :external_id, String, required: true
argument :external_name, String, required: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module IntegrationCollectionMappings
class Object < Types::BaseObject
graphql_name "CollectionMapping"

field :billing_entity_id, ID, null: true
field :external_account_code, String, null: true
field :external_id, String, null: false
field :external_name, String, null: true
Expand Down
8 changes: 5 additions & 3 deletions app/models/billing_entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ class BillingEntity < ApplicationRecord
EINVOICING_COUNTRIES = %w[FR].map(&:upcase)

belongs_to :organization
belongs_to :applied_dunning_campaign, class_name: "DunningCampaign", optional: true

has_many :applied_taxes, class_name: "BillingEntity::AppliedTax", dependent: :destroy
has_many :customers
has_many :fees
has_many :invoices
has_many :payment_receipts

has_many :applied_invoice_custom_sections,
class_name: "BillingEntity::AppliedInvoiceCustomSection",
dependent: :destroy
has_many :integration_collection_mappings,
class_name: "IntegrationCollectionMappings::BaseCollectionMapping",
dependent: :destroy

has_many :selected_invoice_custom_sections,
through: :applied_invoice_custom_sections,
source: :invoice_custom_section
Expand All @@ -50,8 +54,6 @@ class BillingEntity < ApplicationRecord
class_name: "Clickhouse::ActivityLog",
as: :resource

belongs_to :applied_dunning_campaign, class_name: "DunningCampaign", optional: true

has_one_attached :logo

DOCUMENT_NUMBERINGS = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@ class AnrokCollectionMapping < BaseCollectionMapping
#
# Table name: integration_collection_mappings
#
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# integration_id :uuid not null
# organization_id :uuid not null
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# billing_entity_id :uuid
# integration_id :uuid not null
# organization_id :uuid not null
#
# Indexes
#
# index_int_collection_mappings_on_mapping_type_and_int_id (mapping_type,integration_id) UNIQUE
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
# index_int_collection_mappings_unique_billing_entity_is_not_null (mapping_type,integration_id,billing_entity_id) UNIQUE WHERE (billing_entity_id IS NOT NULL)
# index_int_collection_mappings_unique_billing_entity_is_null (mapping_type,integration_id,organization_id) UNIQUE WHERE (billing_entity_id IS NULL)
# index_integration_collection_mappings_on_billing_entity_id (billing_entity_id)
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (billing_entity_id => billing_entities.id) ON DELETE => cascade
# fk_rails_... (integration_id => integrations.id)
# fk_rails_... (organization_id => organizations.id)
#
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@ class AvalaraCollectionMapping < BaseCollectionMapping
#
# Table name: integration_collection_mappings
#
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# integration_id :uuid not null
# organization_id :uuid not null
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# billing_entity_id :uuid
# integration_id :uuid not null
# organization_id :uuid not null
#
# Indexes
#
# index_int_collection_mappings_on_mapping_type_and_int_id (mapping_type,integration_id) UNIQUE
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
# index_int_collection_mappings_unique_billing_entity_is_not_null (mapping_type,integration_id,billing_entity_id) UNIQUE WHERE (billing_entity_id IS NOT NULL)
# index_int_collection_mappings_unique_billing_entity_is_null (mapping_type,integration_id,organization_id) UNIQUE WHERE (billing_entity_id IS NULL)
# index_integration_collection_mappings_on_billing_entity_id (billing_entity_id)
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (billing_entity_id => billing_entities.id) ON DELETE => cascade
# fk_rails_... (integration_id => integrations.id)
# fk_rails_... (organization_id => organizations.id)
#
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,65 @@ class BaseCollectionMapping < ApplicationRecord

belongs_to :integration, class_name: "Integrations::BaseIntegration"
belongs_to :organization
belongs_to :billing_entity, optional: true

MAPPING_TYPES = %i[
fallback_item coupon subscription_fee minimum_commitment tax prepaid_credit credit_note account
fallback_item
coupon
subscription_fee
minimum_commitment
tax
prepaid_credit
credit_note account
].freeze

enum :mapping_type, MAPPING_TYPES
enum :mapping_type, MAPPING_TYPES, validate: true

validates :mapping_type, uniqueness: {scope: :integration_id}
validates :mapping_type, presence: true
validates :mapping_type,
uniqueness: {scope: [:integration_id, :organization_id, :billing_entity_id]}

validate :validate_billing_entity_organization

settings_accessors :external_id, :external_account_code, :external_name

private

def validate_billing_entity_organization
return unless billing_entity

if billing_entity.organization_id != organization_id
errors.add(:billing_entity, :invalid)
end
end
end
end

# == Schema Information
#
# Table name: integration_collection_mappings
#
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# integration_id :uuid not null
# organization_id :uuid not null
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# billing_entity_id :uuid
# integration_id :uuid not null
# organization_id :uuid not null
#
# Indexes
#
# index_int_collection_mappings_on_mapping_type_and_int_id (mapping_type,integration_id) UNIQUE
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
# index_int_collection_mappings_unique_billing_entity_is_not_null (mapping_type,integration_id,billing_entity_id) UNIQUE WHERE (billing_entity_id IS NOT NULL)
# index_int_collection_mappings_unique_billing_entity_is_null (mapping_type,integration_id,organization_id) UNIQUE WHERE (billing_entity_id IS NULL)
# index_integration_collection_mappings_on_billing_entity_id (billing_entity_id)
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (billing_entity_id => billing_entities.id) ON DELETE => cascade
# fk_rails_... (integration_id => integrations.id)
# fk_rails_... (organization_id => organizations.id)
#
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,27 @@ class NetsuiteCollectionMapping < BaseCollectionMapping
#
# Table name: integration_collection_mappings
#
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# integration_id :uuid not null
# organization_id :uuid not null
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# billing_entity_id :uuid
# integration_id :uuid not null
# organization_id :uuid not null
#
# Indexes
#
# index_int_collection_mappings_on_mapping_type_and_int_id (mapping_type,integration_id) UNIQUE
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
# index_int_collection_mappings_unique_billing_entity_is_not_null (mapping_type,integration_id,billing_entity_id) UNIQUE WHERE (billing_entity_id IS NOT NULL)
# index_int_collection_mappings_unique_billing_entity_is_null (mapping_type,integration_id,organization_id) UNIQUE WHERE (billing_entity_id IS NULL)
# index_integration_collection_mappings_on_billing_entity_id (billing_entity_id)
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (billing_entity_id => billing_entities.id) ON DELETE => cascade
# fk_rails_... (integration_id => integrations.id)
# fk_rails_... (organization_id => organizations.id)
#
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@ class XeroCollectionMapping < BaseCollectionMapping
#
# Table name: integration_collection_mappings
#
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# integration_id :uuid not null
# organization_id :uuid not null
# id :uuid not null, primary key
# mapping_type :integer not null
# settings :jsonb not null
# type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# billing_entity_id :uuid
# integration_id :uuid not null
# organization_id :uuid not null
#
# Indexes
#
# index_int_collection_mappings_on_mapping_type_and_int_id (mapping_type,integration_id) UNIQUE
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
# index_int_collection_mappings_unique_billing_entity_is_not_null (mapping_type,integration_id,billing_entity_id) UNIQUE WHERE (billing_entity_id IS NOT NULL)
# index_int_collection_mappings_unique_billing_entity_is_null (mapping_type,integration_id,organization_id) UNIQUE WHERE (billing_entity_id IS NULL)
# index_integration_collection_mappings_on_billing_entity_id (billing_entity_id)
# index_integration_collection_mappings_on_integration_id (integration_id)
# index_integration_collection_mappings_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (billing_entity_id => billing_entities.id) ON DELETE => cascade
# fk_rails_... (integration_id => integrations.id)
# fk_rails_... (organization_id => organizations.id)
#
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ def call

return result.not_found_failure!(resource: "integration") unless integration

if params[:billing_entity_id]
billing_entity = integration.organization.billing_entities.find_by(id: params[:billing_entity_id])
return result.not_found_failure!(resource: "billing_entity") unless billing_entity
end

integration_collection_mapping = IntegrationCollectionMappings::Factory.new_instance(integration:).new(
organization_id: params[:organization_id],
integration_id: params[:integration_id],
mapping_type: params[:mapping_type]
mapping_type: params[:mapping_type],
billing_entity_id: params[:billing_entity_id]
)

integration_collection_mapping.organization = integration.organization
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

class AddBillingEntityToIntegrationCollectionMappings < ActiveRecord::Migration[8.0]
disable_ddl_transaction!

def change
add_reference :integration_collection_mappings,
:billing_entity,
type: :uuid,
null: true,
index: {algorithm: :concurrently}

add_foreign_key :integration_collection_mappings, :billing_entities, on_delete: :cascade, validate: false
add_index :integration_collection_mappings,
[:mapping_type, :integration_id, :billing_entity_id],
where: "billing_entity_id IS NOT NULL",
unique: true,
algorithm: :concurrently,
name: "index_int_collection_mappings_unique_billing_entity_is_not_null"
add_index :integration_collection_mappings,
[:mapping_type, :integration_id, :organization_id],
where: "billing_entity_id IS NULL",
unique: true,
algorithm: :concurrently,
name: "index_int_collection_mappings_unique_billing_entity_is_null"
remove_index :integration_collection_mappings, [:mapping_type, :integration_id], name: "index_int_collection_mappings_on_mapping_type_and_int_id"
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class ValidateBillingEntityForeignKeyOnIntegrationCollectionMappings < ActiveRecord::Migration[8.0]
def change
validate_foreign_key :integration_collection_mappings, :billing_entities
end
end
Loading
Loading