Initial implementation of the reconciliation script
Standalone Ruby script reconciling GoCardless payments, Dolibarr invoices (via API), and Shine bank statements. Three-pass engine: GC↔Dolibarr matching, open invoice audit, payout↔bank verification. Includes dry-run and --fix mode to auto-mark Dolibarr invoices as paid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
56
lib/reconciliation/fixer.rb
Normal file
56
lib/reconciliation/fixer.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reconciliation
|
||||
# Applies fixes to Dolibarr: marks invoices as paid using GoCardless payment data.
|
||||
class Fixer
|
||||
def initialize(client)
|
||||
@client = client
|
||||
end
|
||||
|
||||
# Accepts an array of Engine::Match objects with flag GC_PAID_DOLIBARR_OPEN
|
||||
def apply(matches)
|
||||
return if matches.empty?
|
||||
|
||||
gc_payment_id = ENV.fetch("DOLIBARR_GC_PAYMENT_ID", nil)&.to_i
|
||||
bank_id = ENV.fetch("DOLIBARR_BANK_ACCOUNT_ID", "1").to_i
|
||||
|
||||
if gc_payment_id.nil?
|
||||
warn "[Fixer] DOLIBARR_GC_PAYMENT_ID not set in .env — cannot fix. " \
|
||||
"Run: GET /setup/dictionary/payment_types to find the GoCardless payment type ID."
|
||||
return
|
||||
end
|
||||
|
||||
puts ""
|
||||
puts "APPLYING FIXES (#{matches.size} invoices)..."
|
||||
|
||||
matches.each do |m|
|
||||
inv = m.invoice
|
||||
pay = m.payment
|
||||
|
||||
payload = {
|
||||
arrayofamounts: {
|
||||
inv.id.to_s => {
|
||||
amount: "%.2f" % (inv.amount_cents / 100.0),
|
||||
multicurrency_amount: nil
|
||||
}
|
||||
},
|
||||
datepaye: pay.charge_date.to_time.to_i,
|
||||
paymentid: gc_payment_id,
|
||||
closepaidinvoices: "yes",
|
||||
accountid: bank_id,
|
||||
num_payment: pay.id,
|
||||
comment: "GoCardless payment — auto-reconciled (#{pay.charge_date})"
|
||||
}
|
||||
|
||||
begin
|
||||
@client.post("/invoices/paymentsdistributed", payload)
|
||||
puts " ✓ Marked #{inv.ref} as paid (GC: #{pay.id})"
|
||||
rescue Dolibarr::Client::ValidationError => e
|
||||
puts " ✗ #{inv.ref} — validation error: #{e.message}"
|
||||
rescue Dolibarr::Client::Error => e
|
||||
puts " ✗ #{inv.ref} — API error: #{e.message}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user