# frozen_string_literal: true require "httparty" require "json" module Dolibarr class Client include HTTParty class NotFoundError < StandardError; end class ValidationError < StandardError; end class Error < StandardError; end def initialize( base_url: ENV.fetch("DOLIBARR_URL"), api_key: ENV.fetch("DOLIBARR_API_KEY") ) @base_url = base_url @headers = { "DOLAPIKEY" => api_key, "Content-Type" => "application/json", "Accept" => "application/json" } end def get(path, params = {}) perform_request(:get, path, params) end def post(path, data = {}) perform_request(:post, path, data) end def put(path, data = {}) perform_request(:put, path, data) end private def perform_request(method, path, data = {}) url = "#{@base_url}#{path}" opts = { headers: @headers } case method when :get opts[:query] = data unless data.empty? response = self.class.get(url, opts) when :post opts[:body] = data.to_json response = self.class.post(url, opts) when :put opts[:body] = data.to_json response = self.class.put(url, opts) end handle_response(response) rescue => e raise Error, "Connection error: #{e.message}" end def handle_response(response) return nil if response.body.nil? || response.body.strip.empty? code = response.code.to_i case code when 200..299 response.parsed_response when 404 raise NotFoundError, "Not found (404)" when 400 raise ValidationError, "Validation error: #{response.body}" when 401 raise Error, "Authentication failed (401) — check DOLIBARR_API_KEY" when 500..599 raise Error, "Dolibarr server error (#{code}): #{response.body}" else raise Error, "Unexpected status #{code}: #{response.body}" end rescue JSON::ParserError => e raise Error, "JSON parse error: #{e.message}" end end end