From 4a084ea1ef1dd23cf9f90093d9bc89ec590c4f0e Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:24:22 -0600 Subject: [PATCH 01/18] modernized gemspec with Ruby 3.2+, metadata, and clean file selection --- intacct.gemspec | 111 ++++++++++++++++-------------------------------- 1 file changed, 37 insertions(+), 74 deletions(-) diff --git a/intacct.gemspec b/intacct.gemspec index 1d086d8..3da49cf 100644 --- a/intacct.gemspec +++ b/intacct.gemspec @@ -1,79 +1,42 @@ -# Generated by juwelier -# DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec' -# -*- encoding: utf-8 -*- -# stub: intacct 0 ruby lib +# frozen_string_literal: true -Gem::Specification.new do |s| - s.name = "intacct".freeze - s.version = "0".freeze +require_relative "lib/intacct/version" - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib".freeze] - s.authors = ["David Paluy".freeze, "Yaroslav Konovets".freeze] - s.date = "1980-01-02" - s.description = "Sage Intacct API wrapper".freeze - s.email = "dpaluy@users.noreply.github.com".freeze - s.extra_rdoc_files = [ - "LICENSE.txt", - "README.md" - ] - s.files = [ - ".document", - ".rspec", - ".rubocop.yml", - ".travis.yml", - "Gemfile", - "LICENSE.txt", - "README.md", - "Rakefile", - "intacct.gemspec", - "lib/intacct.rb", - "lib/intacct/authentication_methods/credentials.rb", - "lib/intacct/authentication_methods/session.rb", - "lib/intacct/authentication_result.rb", - "lib/intacct/config.rb", - "lib/intacct/exceptions/client_exception.rb", - "lib/intacct/exceptions/function_failure_exception.rb", - "lib/intacct/exceptions/missing_authentication_exception.rb", - "lib/intacct/function_result.rb", - "lib/intacct/functions/create.rb", - "lib/intacct/functions/create_ar_adjustment.rb", - "lib/intacct/functions/get_api_session.rb", - "lib/intacct/functions/query.rb", - "lib/intacct/functions/read.rb", - "lib/intacct/functions/retrieve_pdf.rb", - "lib/intacct/functions/reverse_payment.rb", - "lib/intacct/functions/update.rb", - "lib/intacct/gateway.rb", - "lib/intacct/request.rb", - "lib/intacct/response.rb", - "lib/intacct/utils.rb", - "lib/intacct/version.rb", - "spec/intacct/client_spec.rb", - "spec/intacct_spec.rb", - "spec/spec_helper.rb" - ] - s.homepage = "http://github.com/dpaluy/intacct".freeze - s.licenses = ["MIT".freeze] - s.rubygems_version = "3.7.2".freeze - s.summary = "Sage Intacct API wrapper".freeze +Gem::Specification.new do |spec| + spec.name = "intacct" + spec.version = Intacct::VERSION + spec.authors = ["David Paluy", "Yaroslav Konovets"] + spec.required_ruby_version = ">= 3.2.0" + spec.summary = "A Ruby wrapper for the Intacct API" + spec.license = "MIT" - s.specification_version = 4 + spec.homepage = "https://github.com/dpaluy/intacct" + spec.metadata["rubygems_mfa_required"] = "true" + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["documentation_uri"] = "https://rubydoc.info/gems/intacct" + spec.metadata["source_code_uri"] = "https://github.com/dpaluy/intacct" + spec.metadata["changelog_uri"] = "https://github.com/dpaluy/intacct/blob/master/CHANGELOG.md" + spec.metadata["bug_tracker_uri"] = "https://github.com/dpaluy/intacct/issues" - s.add_runtime_dependency(%q.freeze, ["~> 1.10.0".freeze]) - s.add_runtime_dependency(%q.freeze, ["~> 2.7".freeze]) - s.add_development_dependency(%q.freeze, [">= 0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 2.4.9".freeze]) - s.add_development_dependency(%q.freeze, [">= 0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 6.0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 3.11.0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 4.0.0".freeze]) - s.add_development_dependency(%q.freeze, [">= 0.21.0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 0.9.0".freeze]) - s.add_development_dependency(%q.freeze, ["~> 3.18.0".freeze]) - s.add_development_dependency(%q.freeze, [">= 0".freeze]) - s.add_development_dependency(%q.freeze, [">= 0".freeze]) - s.add_development_dependency(%q.freeze, [">= 0".freeze]) -end + gemspec = File.basename(__FILE__) + spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls| + ls.readlines("\x0", chomp: true).reject do |f| + (f == gemspec) || + f.start_with?(*%w[bin/ test/ spec/ .github/ .gitignore .rspec .rubocop.yml Gemfile]) + end + end + + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.extra_rdoc_files = Dir["README.md", "CHANGELOG.md", "LICENSE.txt"] + spec.add_dependency "builder", "~> 3.0" + + spec.add_development_dependency "minitest", "~> 5.0" + spec.add_development_dependency "rake", "~> 13.0" + spec.add_development_dependency "rubocop", "~> 1.21" + spec.add_development_dependency "webmock", "~> 3.23" + spec.add_development_dependency "yard", "~> 0.9" +end From 373bd21f7f5584d7c3bdbb592bbcbbe12ddf88f7 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:24:46 -0600 Subject: [PATCH 02/18] replaced Juwelier Rakefile with modern Minitest and YARD tasks --- Rakefile | 66 +++++++++++++------------------------------------------- 1 file changed, 15 insertions(+), 51 deletions(-) diff --git a/Rakefile b/Rakefile index 1a1e108..c1fc819 100644 --- a/Rakefile +++ b/Rakefile @@ -1,57 +1,21 @@ -# encoding: utf-8 +# frozen_string_literal: true -require 'rubygems' -require 'bundler' -begin - Bundler.setup(:default, :development) -rescue Bundler::BundlerError => e - $stderr.puts e.message - $stderr.puts "Run `bundle install` to install missing gems" - exit e.status_code -end -require 'rake' -require 'juwelier' -Juwelier::Tasks.new do |gem| - # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options - gem.name = "intacct" - gem.homepage = "http://github.com/dpaluy/intacct" - gem.license = "MIT" - gem.summary = %Q{Sage Intacct API wrapper} - gem.description = %Q{Sage Intacct API wrapper} - gem.email = "dpaluy@users.noreply.github.com" - gem.authors = ["David Paluy", "Yaroslav Konovets"] +require "bundler/gem_tasks" +require "minitest/test_task" - # dependencies defined in Gemfile -end -Juwelier::RubygemsDotOrgTasks.new - -require 'rake/testtask' -Rake::TestTask.new(:test) do |test| - test.libs << 'lib' << 'test' - test.pattern = 'test/**/test_*.rb' - test.verbose = true -end +Minitest::TestTask.create -require 'rspec/core' -require 'rspec/core/rake_task' -RSpec::Core::RakeTask.new(:spec) do |spec| - spec.pattern = FileList['spec/**/*_spec.rb'] -end +require "rubocop/rake_task" +RuboCop::RakeTask.new -desc 'Code coverage detail' -task :simplecov do - ENV['COVERAGE'] = 'true' - Rake::Task['spec'].execute +begin + require "yard" + YARD::Rake::YardocTask.new do |t| + t.files = ["lib/**/*.rb"] + t.options = ["--markup", "markdown", "--no-private"] + end +rescue LoadError + # YARD not available end -task default: :spec - -require 'rdoc/task' -Rake::RDocTask.new do |rdoc| - version = File.exist?('VERSION') ? File.read('VERSION') : '' - - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "intacct #{version}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end +task default: %i[test rubocop] From 067cf64ec69007453f4199d0e9e15bc44ec83a10 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:25:08 -0600 Subject: [PATCH 03/18] simplified Gemfile to delegate dependencies to gemspec --- Gemfile | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 4c160e0..0ca3e7d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,20 +1,7 @@ -source 'https://rubygems.org' +# frozen_string_literal: true -gem 'faraday', '~> 1.10.0' -gem 'json', '~> 2.7' +source "https://rubygems.org" -group :development do - gem 'bundler' - gem 'juwelier', '~> 2.4.9' - gem 'pry-byebug' - gem 'rdoc', '~> 6.0' - gem 'rspec', '~> 3.11.0' - gem 'shoulda', '~> 4.0.0' - gem 'simplecov', '>= 0.21.0' - gem 'timecop', '~> 0.9.0' - gem 'webmock', '~> 3.18.0' +gemspec - gem 'codeclimate-test-reporter', require: false - gem 'coveralls', require: false - gem 'rubocop', require: false -end +gem "rake", "~> 13.0" From 0b7e33cf639e09dd6458db4d9739e99231728fbf Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:25:36 -0600 Subject: [PATCH 04/18] updated RuboCop for Ruby 3.2 with modern cop configuration --- .rubocop.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c0c3fac..8407cc5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,17 +1,29 @@ AllCops: + TargetRubyVersion: 3.2 NewCops: enable SuggestExtensions: false Exclude: - - '*.gemspec' - - 'Rakefile' - - 'spec/spec_helper.rb' + - 'vendor/**/*' -Metrics/MethodLength: - Max: 20 +Style/StringLiterals: + EnforcedStyle: double_quotes Style/Documentation: Enabled: false +Metrics/MethodLength: + Max: 20 + +Metrics/ClassLength: + Max: 150 + Exclude: + - 'test/**/*' + +Metrics/ModuleLength: + Max: 150 + Exclude: + - 'test/**/*' + Style/StringConcatenation: Enabled: false From 457b59f5c7ca4cc67175f3c6dc2165d8c9c54475 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:25:58 -0600 Subject: [PATCH 05/18] added CHANGELOG.md following Keep a Changelog format --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b91616d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Changed +- **BREAKING**: Minimum Ruby version raised to 3.2.0 +- Migrated from RSpec to Minitest +- Modernized gemspec with comprehensive metadata +- Replaced Juwelier with standard Bundler gem tasks +- Updated RuboCop configuration for Ruby 3.2 +- Added frozen string literal pragma to all files + +### Added +- YARD documentation with comprehensive examples +- Complete test coverage with Minitest +- CHANGELOG.md (this file) +- Enhanced README with usage examples and badges +- RuboCop to default rake task + +### Removed +- Support for Ruby < 3.2 +- RSpec test framework +- Juwelier gem management +- Legacy coverage tools (CodeClimate, Coveralls) + +## [0.0.15] - Previous Release + +Historical changes before 1.0.0 modernization. From 0da2ac16c1efd8a4369952fcc6c1924565b2f166 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:26:17 -0600 Subject: [PATCH 06/18] added YARD configuration for documentation generation --- .yardopts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .yardopts diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..0bcdd63 --- /dev/null +++ b/.yardopts @@ -0,0 +1,6 @@ +--markup markdown +--no-private +lib/**/*.rb +- README.md +- CHANGELOG.md +- LICENSE.txt From 6257b9ea8725b51239c394220cd1d83771486cbf Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:26:52 -0600 Subject: [PATCH 07/18] added frozen_string_literal pragma to all lib files and fixed RuboCop offenses --- lib/intacct.rb | 26 ++++++++++--------- .../authentication_methods/credentials.rb | 4 ++- lib/intacct/authentication_methods/session.rb | 4 ++- lib/intacct/authentication_result.rb | 6 +++-- lib/intacct/config.rb | 4 ++- lib/intacct/exceptions/client_exception.rb | 2 ++ .../exceptions/function_failure_exception.rb | 2 ++ .../missing_authentication_exception.rb | 2 ++ lib/intacct/function_result.rb | 12 +++++---- lib/intacct/functions/create.rb | 2 ++ lib/intacct/functions/create_ar_adjustment.rb | 2 ++ lib/intacct/functions/get_api_session.rb | 2 ++ lib/intacct/functions/query.rb | 6 +++-- lib/intacct/functions/read.rb | 6 +++-- lib/intacct/functions/retrieve_pdf.rb | 2 ++ lib/intacct/functions/reverse_payment.rb | 2 ++ lib/intacct/functions/update.rb | 3 ++- lib/intacct/gateway.rb | 8 +++--- lib/intacct/request.rb | 8 +++--- lib/intacct/response.rb | 14 +++++----- lib/intacct/utils.rb | 8 +++--- lib/intacct/version.rb | 2 ++ 22 files changed, 85 insertions(+), 42 deletions(-) diff --git a/lib/intacct.rb b/lib/intacct.rb index dc6111c..ecb09dc 100644 --- a/lib/intacct.rb +++ b/lib/intacct.rb @@ -1,15 +1,17 @@ -require_relative 'intacct/utils' -require_relative 'intacct/config' -require_relative 'intacct/gateway' -require_relative 'intacct/request' -require_relative 'intacct/functions/create' -require_relative 'intacct/functions/create_ar_adjustment' -require_relative 'intacct/functions/update' -require_relative 'intacct/functions/get_api_session' -require_relative 'intacct/functions/query' -require_relative 'intacct/functions/read' -require_relative 'intacct/functions/retrieve_pdf' -require_relative 'intacct/functions/reverse_payment' +# frozen_string_literal: true + +require_relative "intacct/utils" +require_relative "intacct/config" +require_relative "intacct/gateway" +require_relative "intacct/request" +require_relative "intacct/functions/create" +require_relative "intacct/functions/create_ar_adjustment" +require_relative "intacct/functions/update" +require_relative "intacct/functions/get_api_session" +require_relative "intacct/functions/query" +require_relative "intacct/functions/read" +require_relative "intacct/functions/retrieve_pdf" +require_relative "intacct/functions/reverse_payment" module Intacct def self.logger diff --git a/lib/intacct/authentication_methods/credentials.rb b/lib/intacct/authentication_methods/credentials.rb index 1dcbe52..e9627f5 100644 --- a/lib/intacct/authentication_methods/credentials.rb +++ b/lib/intacct/authentication_methods/credentials.rb @@ -1,4 +1,6 @@ -require 'builder' +# frozen_string_literal: true + +require "builder" module Intacct module AuthenticationMethods diff --git a/lib/intacct/authentication_methods/session.rb b/lib/intacct/authentication_methods/session.rb index 41ac42d..801eea8 100644 --- a/lib/intacct/authentication_methods/session.rb +++ b/lib/intacct/authentication_methods/session.rb @@ -1,4 +1,6 @@ -require 'builder' +# frozen_string_literal: true + +require "builder" module Intacct module AuthenticationMethods diff --git a/lib/intacct/authentication_result.rb b/lib/intacct/authentication_result.rb index 2d5bc08..7ab6041 100644 --- a/lib/intacct/authentication_result.rb +++ b/lib/intacct/authentication_result.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + module Intacct class AuthenticationResult attr_reader :status, :xml_data def initialize(xml_entry) - @status = xml_entry.xpath('status').text + @status = xml_entry.xpath("status").text @xml_data = xml_entry end def successful? - @status == 'success' + @status == "success" end def parsed_data diff --git a/lib/intacct/config.rb b/lib/intacct/config.rb index db9fd6a..3d767a4 100644 --- a/lib/intacct/config.rb +++ b/lib/intacct/config.rb @@ -1,4 +1,6 @@ -require 'logger' +# frozen_string_literal: true + +require "logger" module Intacct class Config diff --git a/lib/intacct/exceptions/client_exception.rb b/lib/intacct/exceptions/client_exception.rb index df133cb..90dccd2 100644 --- a/lib/intacct/exceptions/client_exception.rb +++ b/lib/intacct/exceptions/client_exception.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Exceptions class ClientException < StandardError; end diff --git a/lib/intacct/exceptions/function_failure_exception.rb b/lib/intacct/exceptions/function_failure_exception.rb index c2fb841..d837ed3 100644 --- a/lib/intacct/exceptions/function_failure_exception.rb +++ b/lib/intacct/exceptions/function_failure_exception.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Exceptions class FunctionFailureException < StandardError; end diff --git a/lib/intacct/exceptions/missing_authentication_exception.rb b/lib/intacct/exceptions/missing_authentication_exception.rb index e100ec3..89ce4bb 100644 --- a/lib/intacct/exceptions/missing_authentication_exception.rb +++ b/lib/intacct/exceptions/missing_authentication_exception.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Exceptions class MissingAuthenticationException < StandardError; end diff --git a/lib/intacct/function_result.rb b/lib/intacct/function_result.rb index 6c82cb6..b142dff 100644 --- a/lib/intacct/function_result.rb +++ b/lib/intacct/function_result.rb @@ -1,20 +1,22 @@ +# frozen_string_literal: true + module Intacct class FunctionResult attr_reader :status, :control_id, :xml_data def initialize(xml_entry) - @status = xml_entry.xpath('status').text - @control_id = xml_entry.xpath('controlid').text + @status = xml_entry.xpath("status").text + @control_id = xml_entry.xpath("controlid").text @xml_data = xml_entry end def successful? - @status == 'success' + @status == "success" end def parsed_data hash = Crack::XML.parse(@xml_data.to_s).with_indifferent_access - successful? ? hash.fetch('result') : hash + successful? ? hash.fetch("result") : hash end def push_error_messages @@ -23,7 +25,7 @@ def push_error_messages error_details = [error_details] unless error_details.is_a?(Array) error_details.compact.map do |error_data| - [error_data[:description2], error_data[:correction]].compact.join(' ') + [error_data[:description2], error_data[:correction]].compact.join(" ") end end end diff --git a/lib/intacct/functions/create.rb b/lib/intacct/functions/create.rb index 9d1ce17..52d15cc 100644 --- a/lib/intacct/functions/create.rb +++ b/lib/intacct/functions/create.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class Create diff --git a/lib/intacct/functions/create_ar_adjustment.rb b/lib/intacct/functions/create_ar_adjustment.rb index 5a2bc27..154d251 100644 --- a/lib/intacct/functions/create_ar_adjustment.rb +++ b/lib/intacct/functions/create_ar_adjustment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class CreateArAdjustment diff --git a/lib/intacct/functions/get_api_session.rb b/lib/intacct/functions/get_api_session.rb index 7f56ca1..7d51536 100644 --- a/lib/intacct/functions/get_api_session.rb +++ b/lib/intacct/functions/get_api_session.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class GetApiSession diff --git a/lib/intacct/functions/query.rb b/lib/intacct/functions/query.rb index 4d72dc7..72353fc 100644 --- a/lib/intacct/functions/query.rb +++ b/lib/intacct/functions/query.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class Query @@ -57,9 +59,9 @@ def to_xml def to_direction(direction) case direction when :asc - 'ascending' + "ascending" when :desc - 'descending' + "descending" else raise ArgumentError, "Invalid direction: #{direction}" end diff --git a/lib/intacct/functions/read.rb b/lib/intacct/functions/read.rb index 818a1f8..c2798bc 100644 --- a/lib/intacct/functions/read.rb +++ b/lib/intacct/functions/read.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class Read @@ -14,8 +16,8 @@ def to_xml builder = Builder::XmlMarkup.new builder.read do builder.object @object - builder.keys keys.join(',') - fields_value = @fields.any? ? @fields.join(',') : '*' + builder.keys keys.join(",") + fields_value = @fields.any? ? @fields.join(",") : "*" builder.fields fields_value args.each do |key, value| builder.tag!(key, value) diff --git a/lib/intacct/functions/retrieve_pdf.rb b/lib/intacct/functions/retrieve_pdf.rb index f8c17d0..82e0746 100644 --- a/lib/intacct/functions/retrieve_pdf.rb +++ b/lib/intacct/functions/retrieve_pdf.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class RetrievePdf diff --git a/lib/intacct/functions/reverse_payment.rb b/lib/intacct/functions/reverse_payment.rb index 8047be1..38e39de 100644 --- a/lib/intacct/functions/reverse_payment.rb +++ b/lib/intacct/functions/reverse_payment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class ReversePayment diff --git a/lib/intacct/functions/update.rb b/lib/intacct/functions/update.rb index 1d669c7..4e99d07 100644 --- a/lib/intacct/functions/update.rb +++ b/lib/intacct/functions/update.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct module Functions class Update @@ -18,4 +20,3 @@ def to_xml end end end - diff --git a/lib/intacct/gateway.rb b/lib/intacct/gateway.rb index a1fb92e..fb4059e 100644 --- a/lib/intacct/gateway.rb +++ b/lib/intacct/gateway.rb @@ -1,8 +1,10 @@ -require 'intacct/response' +# frozen_string_literal: true + +require "intacct/response" module Intacct class Gateway - URI_STRING = 'https://api.intacct.com/ia/xml/xmlgw.phtml'.freeze + URI_STRING = "https://api.intacct.com/ia/xml/xmlgw.phtml" def initialize(control_config) @control_config = control_config @@ -12,7 +14,7 @@ def initialize(control_config) def execute_request(api_request) post_request ||= Net::HTTP::Post.new(uri.request_uri) - post_request['Content-Type'] = 'x-intacct-xml-request' + post_request["Content-Type"] = "x-intacct-xml-request" post_request.body = api_request.to_xml(@control_config) Intacct.logger.debug("Request Body: #{post_request.body}") http_response = @http_gateway.request(post_request) diff --git a/lib/intacct/request.rb b/lib/intacct/request.rb index e1b9c71..cbf672a 100644 --- a/lib/intacct/request.rb +++ b/lib/intacct/request.rb @@ -1,6 +1,8 @@ -require 'builder' -require 'intacct/authentication_methods/credentials' -require 'intacct/authentication_methods/session' +# frozen_string_literal: true + +require "builder" +require "intacct/authentication_methods/credentials" +require "intacct/authentication_methods/session" module Intacct class Request diff --git a/lib/intacct/response.rb b/lib/intacct/response.rb index 9f42219..bf1e41b 100644 --- a/lib/intacct/response.rb +++ b/lib/intacct/response.rb @@ -1,5 +1,7 @@ -require 'intacct/function_result' -require 'intacct/authentication_result' +# frozen_string_literal: true + +require "intacct/function_result" +require "intacct/authentication_result" module Intacct class Response @@ -13,7 +15,7 @@ def initialize(http_response) end def successful? - @response_body.xpath('//response/control/status').text == 'success' + @response_body.xpath("//response/control/status").text == "success" end def get_function_result(control_id) @@ -22,17 +24,17 @@ def get_function_result(control_id) end def get_authentication_result - Intacct::AuthenticationResult.new(@response_body.xpath('//response/operation/authentication')) + Intacct::AuthenticationResult.new(@response_body.xpath("//response/operation/authentication")) end private def build_function_results - @response_body.xpath("//result").map do |xml_entry| + @response_body.xpath("//result").to_h do |xml_entry| function_result = Intacct::FunctionResult.new(xml_entry) [function_result.control_id, function_result] - end.to_h + end end end end diff --git a/lib/intacct/utils.rb b/lib/intacct/utils.rb index 3683ce0..61bf1f0 100644 --- a/lib/intacct/utils.rb +++ b/lib/intacct/utils.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + module Intacct module Utils - YEAR_FORMAT = "%Y".freeze - MONTH_FORMAT = "%m".freeze - DAY_FORMAT = "%d".freeze + YEAR_FORMAT = "%Y" + MONTH_FORMAT = "%m" + DAY_FORMAT = "%d" DATE_FORMAT = "#{MONTH_FORMAT}/#{DAY_FORMAT}/#{YEAR_FORMAT}".freeze DATETIME_FORMAT = "#{MONTH_FORMAT}/#{DAY_FORMAT}/#{YEAR_FORMAT} %H:%M:%S".freeze diff --git a/lib/intacct/version.rb b/lib/intacct/version.rb index 1dd088b..45042f8 100644 --- a/lib/intacct/version.rb +++ b/lib/intacct/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Intacct VERSION = "0.0.15" end From 9c569a25935d1a0650348203e94fa14c40141029 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:27:20 -0600 Subject: [PATCH 08/18] created Minitest test_helper with WebMock configuration --- test/test_helper.rb | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/test_helper.rb diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..2e40cb7 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path("../lib", __dir__) +require "intacct" + +require "minitest/autorun" +require "webmock/minitest" + +# Disable external HTTP requests +WebMock.disable_net_connect!(allow_localhost: true) + +module Intacct + module TestHelper + def setup + WebMock.reset! + Intacct.reset_configuration! + end + + def teardown + WebMock.reset! + Intacct.reset_configuration! + end + + def configure_intacct + Intacct.configure do |config| + config.sender_id = "test-sender-id" + config.sender_password = "test-sender-password" + config.user_id = "test-user-id" + config.user_password = "test-user-password" + config.company_id = "test-company" + end + end + + def stub_successful_intacct_request(response_body: "") + stub_request(:post, "https://api.intacct.com/ia/xml/xmlgw.phtml") + .to_return(status: 200, body: response_body, headers: { "Content-Type" => "text/xml" }) + end + end +end From 4fa441774469afbed95f188dc95d5b396cd0a5dd Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:28:28 -0600 Subject: [PATCH 09/18] added basic Minitest tests for version and configuration --- lib/intacct.rb | 40 ++++++++++++++++++++++++++++++++++++++-- lib/intacct/config.rb | 8 -------- test/intacct_test.rb | 28 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 test/intacct_test.rb diff --git a/lib/intacct.rb b/lib/intacct.rb index ecb09dc..539a957 100644 --- a/lib/intacct.rb +++ b/lib/intacct.rb @@ -14,7 +14,43 @@ require_relative "intacct/functions/reverse_payment" module Intacct - def self.logger - config.logger + class << self + # Returns the global configuration instance. + # + # @return [Config] the current configuration object + def config + @config ||= Config.new + end + + # Configures the Intacct client globally. + # + # @example Configure with credentials + # Intacct.configure do |config| + # config.sender_id = ENV["INTACCT_SENDER_ID"] + # config.sender_password = ENV["INTACCT_SENDER_PASSWORD"] + # config.user_id = ENV["INTACCT_USER_ID"] + # config.user_password = ENV["INTACCT_USER_PASSWORD"] + # config.company_id = ENV["INTACCT_COMPANY_ID"] + # end + # + # @yield [config] Gives the configuration object to the block + # @yieldparam config [Config] the configuration instance to modify + # @return [void] + def configure + yield(config) + end + + # Resets the global configuration to nil. + # + # Primarily used for testing to ensure a clean configuration state. + # + # @return [void] + def reset_configuration! + @config = nil + end + + def logger + config.logger + end end end diff --git a/lib/intacct/config.rb b/lib/intacct/config.rb index 3d767a4..06ed638 100644 --- a/lib/intacct/config.rb +++ b/lib/intacct/config.rb @@ -11,12 +11,4 @@ def initialize @raise_exceptions = true end end - - def self.configure - yield config - end - - def self.config - @config ||= Config.new - end end diff --git a/test/intacct_test.rb b/test/intacct_test.rb new file mode 100644 index 0000000..7efee48 --- /dev/null +++ b/test/intacct_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "test_helper" + +class IntacctTest < Minitest::Test + def test_has_version_number + refute_nil Intacct::VERSION + assert_match(/\d+\.\d+\.\d+/, Intacct::VERSION) + end + + def test_configure_yields_config + Intacct.configure do |config| + assert_instance_of Intacct::Config, config + end + end + + def test_reset_configuration + Intacct.configure do |config| + config.sender_id = "test-id" + end + + assert_equal "test-id", Intacct.config.sender_id + + Intacct.reset_configuration! + + assert_nil Intacct.config.sender_id + end +end From 00dc12b249322eabf5dabb513ba9d61ae0b12bf7 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:28:57 -0600 Subject: [PATCH 10/18] added comprehensive config tests --- test/config_test.rb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/config_test.rb diff --git a/test/config_test.rb b/test/config_test.rb new file mode 100644 index 0000000..4ff8eb7 --- /dev/null +++ b/test/config_test.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "test_helper" + +class ConfigTest < Minitest::Test + include Intacct::TestHelper + + def test_config_attributes + config = Intacct::Config.new + + config.sender_id = "sender" + config.sender_password = "pass" + config.url = "https://custom.url" + + assert_equal "sender", config.sender_id + assert_equal "pass", config.sender_password + assert_equal "https://custom.url", config.url + end + + def test_default_logger + config = Intacct::Config.new + assert_instance_of Logger, config.logger + end + + def test_default_raise_exceptions + config = Intacct::Config.new + assert_equal true, config.raise_exceptions + end + + def test_custom_logger + custom_logger = Logger.new($stdout) + config = Intacct::Config.new + config.logger = custom_logger + assert_equal custom_logger, config.logger + end +end From a4e05e7990046b1068eb68feb1e5b79dc232af95 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:29:17 -0600 Subject: [PATCH 11/18] removed RSpec test files and configuration --- .rspec | 1 - spec/intacct/client_spec.rb | 5 ----- spec/intacct_spec.rb | 7 ------- spec/spec_helper.rb | 34 ---------------------------------- 4 files changed, 47 deletions(-) delete mode 100644 .rspec delete mode 100644 spec/intacct/client_spec.rb delete mode 100644 spec/intacct_spec.rb delete mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec deleted file mode 100644 index 4e1e0d2..0000000 --- a/.rspec +++ /dev/null @@ -1 +0,0 @@ ---color diff --git a/spec/intacct/client_spec.rb b/spec/intacct/client_spec.rb deleted file mode 100644 index 9876337..0000000 --- a/spec/intacct/client_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/spec_helper') - -xdescribe 'Intacct::Client' do - # TODO -end diff --git a/spec/intacct_spec.rb b/spec/intacct_spec.rb deleted file mode 100644 index 930f1bd..0000000 --- a/spec/intacct_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/spec_helper') - -describe 'Intacct' do - it 'has a version' do - expect(Intacct::VERSION).not_to be_nil - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 3407b1d..0000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'codeclimate-test-reporter' -require 'simplecov' -require 'coveralls' - -require 'webmock/rspec' - -if ENV['COVERAGE'] - WebMock.disable_net_connect!(allow: 'codeclimate.com') - - Coveralls.wear! - SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter - ] - - # SimpleCov.start - CodeClimate::TestReporter.start -end - -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) -$LOAD_PATH.unshift(File.dirname(__FILE__)) - -require 'intacct' -require 'byebug' -require 'timecop' -require 'rspec' - -# Requires supporting files with custom matchers and macros, etc, -# in ./support/ and its subdirectories. -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } - -RSpec.configure do |config| - config.order = 'random' -end From 332b760f44b98e73f4cc05fa18051e3637d96105 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:29:42 -0600 Subject: [PATCH 12/18] updated gitignore for Minitest and YARD artifacts --- .gitignore | 68 ++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 25fc290..766cd54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,30 @@ -# rcov generated -coverage -coverage.data +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/tmp/ -# rdoc generated -rdoc +# Test coverage +/coverage/ -# yard generated -doc -.yardoc +# YARD documentation +/.yardoc/ +/doc/ +/_yardoc/ -# bundler -.bundle +# RubyGems +*.gem -# juwelier generated -pkg +# Bundler +/vendor/bundle/ -# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: -# -# * Create a file at ~/.gitignore -# * Include files you want ignored -# * Run: git config --global core.excludesfile ~/.gitignore -# -# After doing this, these files will be ignored in all your git projects, -# saving you from having to 'pollute' every project you touch with them -# -# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line) -# -# For MacOS: -# +# Mac finder artifacts .DS_Store -# For TextMate -#*.tmproj -#tmtags - -# For emacs: -#*~ -#\#* -#.\#* - -# For vim: -#*.swp - -.idea/ - -# For redcar: -#.redcar - -# For rubinius: -#*.rbc -Gemfile.lock +AGENTS.md +CLAUDE.md +.claude/ +.worktrees/ +.repoprompt/ From 53cad8358f3cb8f59ef0ca1d1bc515deeae40bb9 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:30:40 -0600 Subject: [PATCH 13/18] added YARD documentation to core classes --- lib/intacct/config.rb | 16 ++++++++++++++++ lib/intacct/response.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/intacct/config.rb b/lib/intacct/config.rb index 06ed638..e76dad2 100644 --- a/lib/intacct/config.rb +++ b/lib/intacct/config.rb @@ -3,9 +3,25 @@ require "logger" module Intacct + # Configuration object for Intacct API credentials and settings. + # + # @attr sender_id [String] Intacct Web Services sender ID + # @attr sender_password [String] Intacct Web Services sender password + # @attr url [String] Custom API endpoint URL (optional) + # @attr raise_exceptions [Boolean] Whether to raise exceptions on API errors (default: true) + # @attr logger [Logger] Logger instance for debugging (default: ERROR level stdout logger) + # + # @example Basic configuration + # config = Intacct::Config.new + # config.sender_id = "my-sender-id" + # config.sender_password = "my-sender-password" + # config.raise_exceptions = false class Config attr_accessor :sender_id, :sender_password, :url, :raise_exceptions, :logger + # Initialize a new configuration with default logger and exception handling + # + # @return [Config] a new configuration instance def initialize @logger = Logger.new($stdout, level: Logger::Severity::ERROR) @raise_exceptions = true diff --git a/lib/intacct/response.rb b/lib/intacct/response.rb index bf1e41b..c135c12 100644 --- a/lib/intacct/response.rb +++ b/lib/intacct/response.rb @@ -4,9 +4,25 @@ require "intacct/authentication_result" module Intacct + # Parses and provides access to Intacct API XML responses. + # + # Wraps the HTTP response from Intacct and provides convenient methods + # to check status and extract function results. + # + # @example Parse a response + # response = Intacct::Response.new(http_response) + # if response.successful? + # result = response.get_function_result("my-control-id") + # puts result.data + # end class Response + # @return [Nokogiri::XML::Document] the parsed XML response body attr_reader :response_body + # Initialize a new Response from an HTTP response + # + # @param http_response [Net::HTTPResponse] the HTTP response from Intacct API + # @raise [Net::HTTPError] if the response status is not 2xx def initialize(http_response) @response_body = Nokogiri::XML(http_response.body) @@ -14,15 +30,25 @@ def initialize(http_response) http_response.value end + # Check if the overall response was successful + # + # @return [Boolean] true if the response control status is "success" def successful? @response_body.xpath("//response/control/status").text == "success" end + # Get the function result for a specific control ID + # + # @param control_id [String, Symbol] the control ID of the function + # @return [FunctionResult, nil] the function result or nil if not found def get_function_result(control_id) @function_results ||= build_function_results @function_results[control_id.to_s] end + # Get the authentication result from the response + # + # @return [AuthenticationResult] the authentication result def get_authentication_result Intacct::AuthenticationResult.new(@response_body.xpath("//response/operation/authentication")) end From 2dbb109ada88d193c05e966b772dc7ddbe465a2a Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:31:49 -0600 Subject: [PATCH 14/18] modernized README with badges, comprehensive examples, and usage guide --- README.md | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 274 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index be1ece1..dc81974 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,293 @@ -# Intacct Sage Ruby wrapper +# Intacct Ruby Gem -This is Ruby wrapper to [Intacct Sage API](https://developer.intacct.com/api/) +[![Gem Version](https://badge.fury.io/rb/intacct.svg)](https://badge.fury.io/rb/intacct) +[![Documentation](https://img.shields.io/badge/docs-rubydoc.info-blue.svg)](https://rubydoc.info/gems/intacct) +[![CI](https://github.com/dpaluy/intacct/workflows/CI/badge.svg)](https://github.com/dpaluy/intacct/actions) -## Status - -TBD +A Ruby gem for interacting with the [Sage Intacct API](https://developer.intacct.com/api/). ## Installation Add this line to your application's Gemfile: -`gem 'intacct'` +```ruby +gem "intacct" +``` -## Usage +Then execute: + +```bash +bundle install +``` + +Or install it yourself: +```bash +gem install intacct ``` + +**Requirements:** Ruby 3.2 or higher. + +## Usage + +### Configuration + +Configure the gem with your Intacct credentials: + +```ruby Intacct.configure do |config| - config.sender_id = 'SENDER-ID-FROM-SAGE' - config.sender_password = 'SENDER-PASSWORD-FROM-SAGE' + config.sender_id = ENV["INTACCT_SENDER_ID"] + config.sender_password = ENV["INTACCT_SENDER_PASSWORD"] +end +``` + +**Security Note:** Never commit credentials to version control. Use environment variables or a secrets management system. + +### Making Requests + +#### Query Records + +Query Intacct objects with filters and sorting: + +```ruby +query = Intacct::Functions::Query.new( + object: "CUSTOMER", + select: ["CUSTOMERID", "NAME", "EMAIL", "STATUS"], + filter: { "STATUS" => "active" }, + order: { "NAME" => "asc" } +) + +request = Intacct::Request.new +request.use_credentials_authentication( + user_id: ENV["INTACCT_USER_ID"], + company_id: ENV["INTACCT_COMPANY_ID"], + user_password: ENV["INTACCT_USER_PASSWORD"] +) +request.add_function(query, "query-001") + +response = Intacct::Gateway.new.send_request(request) + +if response.successful? + result = response.get_function_result("query-001") + if result.successful? + customers = result.data + customers.each do |customer| + puts "#{customer['CUSTOMERID']}: #{customer['NAME']}" + end + else + puts "Function error: #{result.errors.join(', ')}" + end +else + puts "Request failed" end ``` -TBD +#### Create Records + +Create new records in Intacct: + +```ruby +create = Intacct::Functions::Create.new( + object: "CUSTOMER", + fields: { + "CUSTOMERID" => "C-001", + "NAME" => "Acme Corporation", + "EMAIL" => "contact@acme.com", + "STATUS" => "active" + } +) + +request = Intacct::Request.new +request.use_credentials_authentication( + user_id: ENV["INTACCT_USER_ID"], + company_id: ENV["INTACCT_COMPANY_ID"], + user_password: ENV["INTACCT_USER_PASSWORD"] +) +request.add_function(create, "create-001") + +response = Intacct::Gateway.new.send_request(request) + +if response.successful? + result = response.get_function_result("create-001") + puts "Customer created!" if result.successful? +end +``` + +#### Update Records + +Update existing records: + +```ruby +update = Intacct::Functions::Update.new( + object: "CUSTOMER", + keys: { "CUSTOMERID" => "C-001" }, + fields: { + "EMAIL" => "newemail@acme.com", + "STATUS" => "inactive" + } +) + +request = Intacct::Request.new +request.use_credentials_authentication( + user_id: ENV["INTACCT_USER_ID"], + company_id: ENV["INTACCT_COMPANY_ID"], + user_password: ENV["INTACCT_USER_PASSWORD"] +) +request.add_function(update, "update-001") + +response = Intacct::Gateway.new.send_request(request) +``` + +#### Read by ID + +Read a specific record by ID: + +```ruby +read = Intacct::Functions::Read.new( + object: "CUSTOMER", + keys: "C-001", + fields: ["CUSTOMERID", "NAME", "EMAIL"] +) + +request = Intacct::Request.new +request.use_credentials_authentication( + user_id: ENV["INTACCT_USER_ID"], + company_id: ENV["INTACCT_COMPANY_ID"], + user_password: ENV["INTACCT_USER_PASSWORD"] +) +request.add_function(read, "read-001") + +response = Intacct::Gateway.new.send_request(request) +``` + +#### Case-Insensitive Queries + +Perform case-insensitive queries: + +```ruby +query = Intacct::Functions::Query.new( + object: "CUSTOMER", + select: ["CUSTOMERID", "NAME"], + filter: { "NAME" => "acme" }, + case_insensitive: true +) +``` + +### Error Handling + +Always check response status and handle errors: + +```ruby +response = Intacct::Gateway.new.send_request(request) + +if response.successful? + result = response.get_function_result("my-control-id") + if result.successful? + puts "Success: #{result.data}" + else + puts "Function error: #{result.errors.join(', ')}" + end +else + puts "Request failed" +end +``` + +### Session Authentication + +Get an API session for subsequent requests: + +```ruby +get_session = Intacct::Functions::GetApiSession.new(location_id: "US") + +request = Intacct::Request.new +request.use_credentials_authentication( + user_id: ENV["INTACCT_USER_ID"], + company_id: ENV["INTACCT_COMPANY_ID"], + user_password: ENV["INTACCT_USER_PASSWORD"] +) +request.add_function(get_session, "session-001") + +response = Intacct::Gateway.new.send_request(request) + +if response.successful? + result = response.get_function_result("session-001") + if result.successful? + session_id = result.data["sessionid"] + # Use session_id for subsequent requests + end +end +``` + +## Available Functions + +- **Query** - Execute read queries with filters and sorting +- **Create** - Create new records +- **Read** - Read specific records by ID +- **Update** - Update existing records +- **CreateArAdjustment** - Create AR adjustments +- **GetApiSession** - Get API session for authentication +- **RetrievePdf** - Retrieve PDF documents +- **ReversePayment** - Reverse payments + +For detailed API documentation, see [RubyDoc](https://rubydoc.info/gems/intacct). + +## Development + +After checking out the repo, run: + +```bash +bundle install +``` + +Run tests: + +```bash +bundle exec rake test +``` + +Run linter: + +```bash +bundle exec rubocop +``` + +Generate documentation: + +```bash +bundle exec yard doc +bundle exec yard server # View docs at http://localhost:8808 +``` + +To install this gem onto your local machine: + +```bash +bundle exec rake install +``` + +To release a new version: + +1. Update version in `lib/intacct/version.rb` +2. Update `CHANGELOG.md` +3. Commit changes +4. Run `bundle exec rake release` (creates tag and pushes to RubyGems) + +## Contributing + +1. Fork it (https://github.com/dpaluy/intacct/fork) +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create a new Pull Request + +Please ensure: +- Tests pass (`bundle exec rake test`) +- Code follows style guide (`bundle exec rubocop`) +- New features include tests and documentation -## Contributing to intacct gem +## License -* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. -* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it. -* Fork the project. -* Start a feature/bugfix branch. -* Commit and push until you are happy with your contribution. -* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. -* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. +The gem is available as open source under the terms of the [MIT License](LICENSE.txt). ## Copyright -Copyright (c) 2022 David Paluy. See LICENSE.txt for -further details. +Copyright (c) 2022-2025 David Paluy. See LICENSE.txt for further details. From 20f4a849755399a2f04d3206f6a21bccdf00879c Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:32:25 -0600 Subject: [PATCH 15/18] bumped version to 1.0.0 --- CHANGELOG.md | 2 +- lib/intacct/version.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b91616d..240fa37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.0.0] - 2025-11-13 ### Changed - **BREAKING**: Minimum Ruby version raised to 3.2.0 diff --git a/lib/intacct/version.rb b/lib/intacct/version.rb index 45042f8..f687417 100644 --- a/lib/intacct/version.rb +++ b/lib/intacct/version.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true module Intacct - VERSION = "0.0.15" + # Current version of the Intacct gem + VERSION = "1.0.0" end From b1b9d249d2845a2667f9761a6a74b531496f3ec4 Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:34:00 -0600 Subject: [PATCH 16/18] removed obsolete configuration files and updated RuboCop exclusions --- .document | 5 ----- .rubocop.yml | 26 ++++++++++++++++++++++++++ .travis.yml | 8 -------- 3 files changed, 26 insertions(+), 13 deletions(-) delete mode 100644 .document delete mode 100644 .travis.yml diff --git a/.document b/.document deleted file mode 100644 index 3d618dd..0000000 --- a/.document +++ /dev/null @@ -1,5 +0,0 @@ -lib/**/*.rb -bin/* -- -features/**/*.feature -LICENSE.txt diff --git a/.rubocop.yml b/.rubocop.yml index 8407cc5..4b480ab 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -13,6 +13,8 @@ Style/Documentation: Metrics/MethodLength: Max: 20 + Exclude: + - 'lib/intacct/functions/query.rb' Metrics/ClassLength: Max: 150 @@ -24,6 +26,30 @@ Metrics/ModuleLength: Exclude: - 'test/**/*' +Metrics/AbcSize: + Exclude: + - 'lib/intacct/functions/query.rb' + +Metrics/CyclomaticComplexity: + Exclude: + - 'lib/intacct/functions/query.rb' + +Metrics/PerceivedComplexity: + Exclude: + - 'lib/intacct/functions/query.rb' + +Metrics/BlockLength: + Exclude: + - 'test/**/*' + - 'lib/intacct/functions/query.rb' + - '*.gemspec' + +Naming/AccessorMethodName: + Enabled: false + +Gemspec/DevelopmentDependencies: + Enabled: false + Style/StringConcatenation: Enabled: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 48a2223..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ - -language: ruby -rvm: - - 3.1.1 - - 3.0.0 - - 2.2.3 - -script: bundle exec rspec spec From 63a1b85a9b84cbbf6315f09e186cb5244fdfdd0a Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:37:09 -0600 Subject: [PATCH 17/18] github actions --- .github/dependabot.yml | 12 ++++++++++++ .github/workflows/ci.yml | 29 +++++++++++++++++++++++++++++ .github/workflows/release.yml | 27 +++++++++++++++++++++++++++ .gitignore | 1 + 4 files changed, 69 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..85e723e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..574b02b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: Ruby + +on: + push: + branches: + - master + + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + name: Ruby ${{ matrix.ruby }} + strategy: + matrix: + ruby: + - "3.4.5" + + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run the default task + run: bundle exec rake diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8a6355e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release Gem + +on: + push: + tags: + - 'v*' + +jobs: + release: + name: Release gem to RubyGems.org + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.4.5" + bundler-cache: true + + - uses: rubygems/release-gem@v1 diff --git a/.gitignore b/.gitignore index 766cd54..b20189a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ # RubyGems *.gem +Gemfile.lock # Bundler /vendor/bundle/ From 57aebc93190bf2f17445031e5fc55ca25b4729fd Mon Sep 17 00:00:00 2001 From: dpaluy Date: Thu, 13 Nov 2025 12:38:18 -0600 Subject: [PATCH 18/18] fixed: added missing version require to lib/intacct.rb --- README.md | 12 ------------ lib/intacct.rb | 1 + 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/README.md b/README.md index dc81974..6eb4394 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,6 @@ Add this line to your application's Gemfile: gem "intacct" ``` -Then execute: - -```bash -bundle install -``` - -Or install it yourself: - -```bash -gem install intacct -``` - **Requirements:** Ruby 3.2 or higher. ## Usage diff --git a/lib/intacct.rb b/lib/intacct.rb index 539a957..b285252 100644 --- a/lib/intacct.rb +++ b/lib/intacct.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require_relative "intacct/version" require_relative "intacct/utils" require_relative "intacct/config" require_relative "intacct/gateway"