From 130401263a7f93cd20f03f5a4f0d4da519c0d9f5 Mon Sep 17 00:00:00 2001 From: Gaetan Craig-Riou Date: Mon, 9 Feb 2026 16:46:55 +1100 Subject: [PATCH] Add CreditPaymentMethod::Linker It links the given enterprise to credit related payment method. It will create the methods if missing. --- app/models/spree/payment_method.rb | 16 ++++- .../spree/payment_method/customer_credit.rb | 14 ----- .../credit_payment_method/linker_service.rb | 61 +++++++++++++++++++ config/application.rb | 9 +++ spec/factories/payment_method_factory.rb | 4 +- .../payment_method/customer_credit_spec.rb | 36 ----------- spec/models/spree/payment_method_spec.rb | 38 ++++++++++++ .../linker_service_spec.rb | 58 ++++++++++++++++++ 8 files changed, 183 insertions(+), 53 deletions(-) create mode 100644 app/services/credit_payment_method/linker_service.rb create mode 100644 spec/services/credit_payment_method/linker_service_spec.rb diff --git a/app/models/spree/payment_method.rb b/app/models/spree/payment_method.rb index 4dc9d95976..d1473a3963 100644 --- a/app/models/spree/payment_method.rb +++ b/app/models/spree/payment_method.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Spree - class PaymentMethod < ApplicationRecord + class PaymentMethod < ApplicationRecord # rubocop:disable Metrics/ClassLength include CalculatedAdjustments include PaymentMethodDistributors @@ -109,6 +109,14 @@ module Spree distributors.include?(distributor) end + def display_name + try_translating(name) + end + + def display_description + try_translating(description) + end + private def distributor_validation @@ -126,5 +134,11 @@ module Spree preferred_enterprise_id > 0 && stripe_account_id.present? end + + def try_translating(value) + I18n.t!(value) + rescue I18n::MissingTranslationData + value + end end end diff --git a/app/models/spree/payment_method/customer_credit.rb b/app/models/spree/payment_method/customer_credit.rb index ea5a07ad3f..2619adccbe 100644 --- a/app/models/spree/payment_method/customer_credit.rb +++ b/app/models/spree/payment_method/customer_credit.rb @@ -3,14 +3,6 @@ module Spree class PaymentMethod class CustomerCredit < Spree::PaymentMethod - def name - try_translating(super) - end - - def description - try_translating(super) - end - # Main method called by Spree::Payment::Processing during checkout # - amount is in cents # - options: { @@ -73,12 +65,6 @@ module Spree def currency CurrentConfig.get(:currency) end - - def try_translating(value) - I18n.t!(value) - rescue I18n::MissingTranslationData - value - end end end end diff --git a/app/services/credit_payment_method/linker_service.rb b/app/services/credit_payment_method/linker_service.rb new file mode 100644 index 0000000000..2b9025e798 --- /dev/null +++ b/app/services/credit_payment_method/linker_service.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: false + +module CreditPaymentMethod + class LinkerService + attr_reader :enterprise + + def self.link(enterprise:) + new(enterprise: ).link + end + + def initialize(enterprise:) + @enterprise = enterprise + end + + def link + if api_payment_method.nil? + create_api_payment_method + else + api_payment_method.distributors << enterprise + end + + if credit_payment_method.nil? + create_credit_payment_method + else + credit_payment_method.distributors << enterprise + end + end + + private + + def api_payment_method + Spree::PaymentMethod.find_by(name: Rails.application.config.api_payment_method[:name]) + end + + def create_api_payment_method + configured = Rails.application.config.api_payment_method + Spree::PaymentMethod::Check.create!( + name: configured[:name], + description: configured[:description], + display_on: "back_end", + environment: Rails.env, + distributor_ids: [enterprise.id] + ) + end + + def credit_payment_method + Spree::PaymentMethod.find_by(name: Rails.application.config.credit_payment_method[:name]) + end + + def create_credit_payment_method + configured = Rails.application.config.credit_payment_method + Spree::PaymentMethod::CustomerCredit.create!( + name: configured[:name], + description: configured[:description], + display_on: "both", + environment: Rails.env, + distributor_ids: [enterprise.id] + ) + end + end +end diff --git a/config/application.rb b/config/application.rb index 71f47829ff..6867dca4fa 100644 --- a/config/application.rb +++ b/config/application.rb @@ -126,6 +126,15 @@ module Openfoodnetwork end end + config.api_payment_method = { + name: "api_payment_method.name", + description: "api_payment_method.description" + } + config.credit_payment_method = { + name: "credit_payment_method.name", + description: "credit_payment_method.description" + } + initializer "ofn.reports" do |_app| module ::Reporting; end Rails.application.reloader.to_prepare do diff --git a/spec/factories/payment_method_factory.rb b/spec/factories/payment_method_factory.rb index d9e9c46159..3de1c76b2a 100644 --- a/spec/factories/payment_method_factory.rb +++ b/spec/factories/payment_method_factory.rb @@ -31,8 +31,8 @@ FactoryBot.define do end factory :customer_credit_payment_method, class: Spree::PaymentMethod::CustomerCredit do - name { "credit_payment_method.name" } - description { "credit_payment_method.description" } + name { Rails.application.config.credit_payment_method[:name] } + description { Rails.application.config.credit_payment_method[:description] } environment { 'test' } distributors { [Enterprise.is_distributor.first || FactoryBot.create(:distributor_enterprise)] } diff --git a/spec/models/spree/payment_method/customer_credit_spec.rb b/spec/models/spree/payment_method/customer_credit_spec.rb index 9e620a20b1..680fcfd4bd 100644 --- a/spec/models/spree/payment_method/customer_credit_spec.rb +++ b/spec/models/spree/payment_method/customer_credit_spec.rb @@ -5,42 +5,6 @@ require "spec_helper" RSpec.describe Spree::PaymentMethod::CustomerCredit do subject { build(:customer_credit_payment_method) } - describe "#name" do - subject { build(:customer_credit_payment_method, name:) } - - let(:name) { "credit_payment_method.name" } - - it "translate the name" do - expect(subject.name).to eq("Customer credit") - end - - context "when not a tranlatable string" do - let(:name) { "customer credit payment" } - - it "falls back to no translation" do - expect(subject.name).to eq("customer credit payment") - end - end - end - - describe "#description" do - subject { build(:customer_credit_payment_method, description:) } - - let(:description) { "credit_payment_method.description" } - - it "translate the name" do - expect(subject.description).to eq("Allow customer to pay with credit") - end - - context "when not a tranlatable string" do - let(:description) { "Payment method to allow customer to pay with credit" } - - it "falls back to no translation" do - expect(subject.description).to eq("Payment method to allow customer to pay with credit") - end - end - end - describe "#purchase" do let(:response) { subject.purchase(amount, nil, options) } diff --git a/spec/models/spree/payment_method_spec.rb b/spec/models/spree/payment_method_spec.rb index 44ec84cce7..f01386a57e 100644 --- a/spec/models/spree/payment_method_spec.rb +++ b/spec/models/spree/payment_method_spec.rb @@ -171,4 +171,42 @@ RSpec.describe Spree::PaymentMethod do end end end + + describe "#display_name" do + subject { build(:payment_method, name:) } + + let(:name) { "credit_payment_method.name" } + + it "translate the name" do + expect(subject.display_name).to eq("Customer credit") + end + + context "when not a tranlatable string" do + let(:name) { "customer credit payment" } + + it "falls back to no translation" do + expect(subject.display_name).to eq("customer credit payment") + end + end + end + + describe "#display_description" do + subject { build(:payment_method, description:) } + + let(:description) { "credit_payment_method.description" } + + it "translate the name" do + expect(subject.display_description).to eq("Allow customer to pay with credit") + end + + context "when not a tranlatable string" do + let(:description) { "Payment method to allow customer to pay with credit" } + + it "falls back to no translation" do + expect(subject.display_description).to eq( + "Payment method to allow customer to pay with credit" + ) + end + end + end end diff --git a/spec/services/credit_payment_method/linker_service_spec.rb b/spec/services/credit_payment_method/linker_service_spec.rb new file mode 100644 index 0000000000..1b654800aa --- /dev/null +++ b/spec/services/credit_payment_method/linker_service_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe CreditPaymentMethod::LinkerService do + let(:enterprise) { create(:distributor_enterprise) } + + around do |example| + # after_save call back will call the linker we are testing, we disable it to avoid + # unintended side effect + Enterprise.skip_callback(:create, :after, :add_credit_payment_method) + example.run + Enterprise.set_callback(:create, :after, :add_credit_payment_method) + end + + describe ".link" do + it "links the given enterprise to customer credit related payment method" do + api_payment_method = create(:payment_method, + name: Rails.application.config.api_payment_method[:name]) + credit_payment_method = create(:customer_credit_payment_method) + + described_class.link(enterprise:) + + expect(enterprise.payment_methods).to include(api_payment_method) + expect(enterprise.payment_methods).to include(credit_payment_method) + end + + context "when payment method don't exist" do + it "creates customer credit related payment method" do + described_class.link(enterprise:) + + api_payment_method = Spree::PaymentMethod.find_by( + name: Rails.application.config.api_payment_method[:name] + ) + expect(api_payment_method).not_to be_nil + expect(api_payment_method.description).to eq( + Rails.application.config.api_payment_method[:description] + ) + expect(api_payment_method.display_name).to eq("API customer credit") + expect(api_payment_method.display_description).to eq( + "Used to credit customer via customer account transactions endpoint" + ) + expect(api_payment_method.display_on).to eq("back_end") + + credit_payment_method = Spree::PaymentMethod.find_by( + name: Rails.application.config.credit_payment_method[:name] + ) + expect(credit_payment_method).not_to be_nil + expect(credit_payment_method.description).to eq( + Rails.application.config.credit_payment_method[:description] + ) + expect(credit_payment_method.display_name).to eq("Customer credit") + expect(credit_payment_method.display_description).to eq("Allow customer to pay with credit") + expect(credit_payment_method.display_on).to eq("both") + end + end + end +end