From 434ec9c205eb95b3b9d0e0ffaa399270448763df Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 20 Apr 2021 17:22:53 +0200 Subject: [PATCH] refactored Invoices to get rid of stripe references --- app/controllers/api/payzen_controller.rb | 8 +- app/controllers/api/stripe_controller.rb | 6 +- .../src/javascript/directives/cart.js | 5 +- app/models/invoice.rb | 10 +- app/models/payment_gateway_object.rb | 14 +- app/pdfs/pdf/invoice.rb | 2 +- app/services/footprint_service.rb | 7 +- app/services/invoices_service.rb | 7 +- app/services/payment_document_service.rb | 2 +- app/services/payment_schedule_service.rb | 8 +- app/services/reservations/reserve.rb | 14 +- app/services/subscriptions/subscribe.rb | 17 ++- app/views/api/invoices/index.json.jbuilder | 4 +- app/views/api/invoices/list.json.jbuilder | 2 +- app/views/api/invoices/show.json.jbuilder | 2 +- .../exports/users_reservations.xlsx.axlsx | 2 +- ...e_stripe_ids_to_payment_gateway_objects.rb | 17 ++- db/structure.sql | 137 +++++++++++++----- lib/integrity/archive_helper.rb | 4 + lib/pay_zen/client.rb | 2 +- lib/pay_zen/item.rb | 17 +++ lib/payment/item.rb | 19 +++ lib/payment/item_builder.rb | 30 ++++ lib/stripe/item.rb | 16 ++ .../exports/accounting_export_test.rb | 2 +- 25 files changed, 271 insertions(+), 83 deletions(-) create mode 100644 lib/pay_zen/item.rb create mode 100644 lib/payment/item.rb create mode 100644 lib/payment/item_builder.rb create mode 100644 lib/stripe/item.rb diff --git a/app/controllers/api/payzen_controller.rb b/app/controllers/api/payzen_controller.rb index f564285ba..ef63c4249 100644 --- a/app/controllers/api/payzen_controller.rb +++ b/app/controllers/api/payzen_controller.rb @@ -57,7 +57,7 @@ class API::PayzenController < API::PaymentsController def on_reservation_success(order_id, details) @reservation = Reservation.new(reservation_params) - payment_method = params[:cart_items][:reservation][:payment_method] || 'payzen' + payment_method = params[:cart_items][:reservation][:payment_method] || 'card' user_id = if current_user.admin? || current_user.manager? params[:cart_items][:reservation][:user_id] else @@ -67,6 +67,7 @@ class API::PayzenController < API::PaymentsController .pay_and_save(@reservation, payment_details: details, payment_id: order_id, + payment_type: 'PayZen::Order', schedule: params[:cart_items][:reservation][:payment_schedule], payment_method: payment_method) if is_reserve @@ -88,9 +89,10 @@ class API::PayzenController < API::PaymentsController is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, user_id) .pay_and_save(@subscription, payment_details: details, - intent_id: order_id, # TODO: change to gateway_id + payment_id: order_id, + payment_type: 'PayZen::Order', schedule: params[:cart_items][:subscription][:payment_schedule], - payment_method: 'payzen') + payment_method: 'card') if is_subscribe { template: 'api/subscriptions/show', status: :created, location: @subscription } diff --git a/app/controllers/api/stripe_controller.rb b/app/controllers/api/stripe_controller.rb index 7d65a0406..b2f97a1be 100644 --- a/app/controllers/api/stripe_controller.rb +++ b/app/controllers/api/stripe_controller.rb @@ -108,7 +108,7 @@ class API::StripeController < API::PaymentsController def on_reservation_success(intent, details) @reservation = Reservation.new(reservation_params) - payment_method = params[:cart_items][:reservation][:payment_method] || 'stripe' + payment_method = params[:cart_items][:reservation][:payment_method] || 'card' user_id = if current_user.admin? || current_user.manager? params[:cart_items][:reservation][:user_id] else @@ -118,6 +118,7 @@ class API::StripeController < API::PaymentsController .pay_and_save(@reservation, payment_details: details, payment_id: intent.id, + payment_type: intent.class.name, schedule: params[:cart_items][:reservation][:payment_schedule], payment_method: payment_method) if intent.class == Stripe::PaymentIntent @@ -148,8 +149,9 @@ class API::StripeController < API::PaymentsController .pay_and_save(@subscription, payment_details: details, payment_id: intent.id, + payment_type: intent.class.name, schedule: params[:cart_items][:subscription][:payment_schedule], - payment_method: 'stripe') + payment_method: 'card') if intent.class == Stripe::PaymentIntent Stripe::PaymentIntent.update( intent.id, diff --git a/app/frontend/src/javascript/directives/cart.js b/app/frontend/src/javascript/directives/cart.js index c58fd0b80..bab7e07e7 100644 --- a/app/frontend/src/javascript/directives/cart.js +++ b/app/frontend/src/javascript/directives/cart.js @@ -721,7 +721,7 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', growl.error(_t('app.shared.cart.online_payment_disabled')); } else { $scope.toggleOnlinePaymentModal(() => { - $scope.onlinePayment.cartItems = mkCartItems(reservation, $scope.settings.payment_gateway); + $scope.onlinePayment.cartItems = mkCartItems(reservation, 'card'); }); } }; @@ -740,7 +740,8 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs', return Price.compute(mkRequestParams({ reservation }, $scope.coupon.applied)).$promise; }, cartItems () { - return mkCartItems(reservation, $scope.settings.payment_gateway); + // TODO: why 'card' despite we pay on site? + return mkCartItems(reservation, 'card'); }, wallet () { return Wallet.getWalletByUser({ user_id: reservation.user_id }).$promise; diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 6c89a34a4..5efbed895 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -21,7 +21,8 @@ class Invoice < PaymentDocument has_one :avoir, class_name: 'Invoice', foreign_key: :invoice_id, dependent: :destroy has_one :payment_schedule_item - has_one :payment_gateway_object + has_one :payment_gateway_object, as: :item + accepts_nested_attributes_for :payment_gateway_object belongs_to :operator_profile, foreign_key: :operator_profile_id, class_name: 'InvoicingProfile' before_create :add_environment @@ -150,7 +151,7 @@ class Invoice < PaymentDocument def payment_means res = [] res.push(means: :wallet, amount: wallet_amount) if wallet_transaction && wallet_amount.positive? - if paid_with_stripe? + if paid_by_card? res.push(means: :card, amount: amount_paid) else res.push(means: :other, amount: amount_paid) @@ -162,9 +163,8 @@ class Invoice < PaymentDocument invoice_items end - def paid_with_stripe? - # FIXME - stp_payment_intent_id? || stp_invoice_id? || payment_method == 'stripe' + def paid_by_card? + !payment_gateway_object.nil? || %w[stripe payzen].include?(payment_method) end private diff --git a/app/models/payment_gateway_object.rb b/app/models/payment_gateway_object.rb index f59a55d30..eda062524 100644 --- a/app/models/payment_gateway_object.rb +++ b/app/models/payment_gateway_object.rb @@ -1,7 +1,19 @@ # frozen_string_literal: true +require 'payment/item_builder' + # A link between an object in the local database and another object in the remote payment gateway database class PaymentGatewayObject < ApplicationRecord belongs_to :item, polymorphic: true - belongs_to :gateway_object, polymorphic: true + belongs_to :invoice, foreign_type: 'Invoice', foreign_key: 'item_id' + + def gateway_object + item = Payment::ItemBuilder.build(gateway_object_type) + item.retrieve(gateway_object_id) + end + + def gateway_object=(object) + self.gateway_object_id = object.id + self.gateway_object_type = object.class + end end diff --git a/app/pdfs/pdf/invoice.rb b/app/pdfs/pdf/invoice.rb index b96e45e53..4bbd1b31c 100644 --- a/app/pdfs/pdf/invoice.rb +++ b/app/pdfs/pdf/invoice.rb @@ -306,7 +306,7 @@ class PDF::Invoice < Prawn::Document end # payment method - payment_verbose = if invoice.paid_with_stripe? + payment_verbose = if invoice.paid_by_card? I18n.t('invoices.settlement_by_debit_card') else I18n.t('invoices.settlement_done_at_the_reception') diff --git a/app/services/footprint_service.rb b/app/services/footprint_service.rb index aa0b95fa8..2ba6f38a8 100644 --- a/app/services/footprint_service.rb +++ b/app/services/footprint_service.rb @@ -25,8 +25,13 @@ class FootprintService .limit(1) columns = FootprintService.footprint_columns(klass) + columns = columns.map do |c| + comparable(item[c]) + rescue ActiveModel::MissingAttributeError + nil + end - res = columns.map { |c| comparable(item[c]) }.push(previous.first ? previous.first.footprint : '') + res = columns.push(previous.first ? previous.first.footprint : '') array ? res.map(&:to_s) : res.join.to_s end diff --git a/app/services/invoices_service.rb b/app/services/invoices_service.rb index 81116d2dc..1f5c20812 100644 --- a/app/services/invoices_service.rb +++ b/app/services/invoices_service.rb @@ -69,7 +69,7 @@ class InvoicesService # @param payment_id {String} ID of the payment, a returned by the gateway, if the current invoice is paid by card # @param payment_method {String} the payment method used ## - def self.create(payment_details, operator_profile_id, reservation: nil, subscription: nil, payment_id: nil, payment_method: nil) + def self.create(payment_details, operator_profile_id, reservation: nil, subscription: nil, payment_id: nil, payment_type: nil, payment_method: nil) user = reservation&.user || subscription&.user operator = InvoicingProfile.find(operator_profile_id)&.user method = if payment_method @@ -83,7 +83,10 @@ class InvoicesService invoicing_profile: user.invoicing_profile, statistic_profile: user.statistic_profile, operator_profile_id: operator_profile_id, - stp_payment_intent_id: payment_id, # FIXME + payment_gateway_object_attributes: { + gateway_object_id: payment_id, + gateway_object_type: payment_type + }, payment_method: method ) diff --git a/app/services/payment_document_service.rb b/app/services/payment_document_service.rb index 303286884..1bf78e28f 100644 --- a/app/services/payment_document_service.rb +++ b/app/services/payment_document_service.rb @@ -26,7 +26,7 @@ class PaymentDocumentService reference.gsub!(/R\[([^\]]+)\]/, ''.to_s) elsif document.class == Invoice # information about online selling (X[text]) - if document.paid_with_stripe? + if document.paid_by_card? reference.gsub!(/X\[([^\]]+)\]/, '\1') else reference.gsub!(/X\[([^\]]+)\]/, ''.to_s) diff --git a/app/services/payment_schedule_service.rb b/app/services/payment_schedule_service.rb index 0291d636e..b332e5404 100644 --- a/app/services/payment_schedule_service.rb +++ b/app/services/payment_schedule_service.rb @@ -49,7 +49,8 @@ class PaymentScheduleService { payment_schedule: ps, items: items } end - def create(subscription, total, coupon: nil, operator: nil, payment_method: nil, reservation: nil, user: nil, payment_id: nil) + def create(subscription, total, coupon: nil, operator: nil, payment_method: nil, reservation: nil, user: nil, + payment_id: nil, payment_type: nil) subscription = reservation.generate_subscription if !subscription && reservation&.plan_id raise InvalidSubscriptionError unless subscription&.persisted? @@ -59,7 +60,10 @@ class PaymentScheduleService ps.scheduled = reservation || subscription ps.payment_method = payment_method - ps.stp_setup_intent_id = payment_id + ps.payment_gateway_object = { + gateway_object_id: payment_id, + gateway_object_type: payment_type + } ps.operator_profile = operator.invoicing_profile ps.invoicing_profile = user.invoicing_profile ps.statistic_profile = user.statistic_profile diff --git a/app/services/reservations/reserve.rb b/app/services/reservations/reserve.rb index dc006e193..86dfaea03 100644 --- a/app/services/reservations/reserve.rb +++ b/app/services/reservations/reserve.rb @@ -13,7 +13,7 @@ class Reservations::Reserve # Confirm the payment of the given reservation, generate the associated documents and save the record into # the database. ## - def pay_and_save(reservation, payment_details: nil, payment_id: nil, schedule: false, payment_method: nil) + def pay_and_save(reservation, payment_details: nil, payment_id: nil, payment_type: nil, schedule: false, payment_method: nil) user = User.find(user_id) reservation.statistic_profile_id = StatisticProfile.find_by(user_id: user_id).id @@ -26,12 +26,14 @@ class Reservations::Reserve user: user, payment_method: payment_method, coupon: payment_details[:coupon], - payment_id: payment_id) + payment_id: payment_id, + payment_type: payment_type) else generate_invoice(reservation, operator_profile_id, payment_details, payment_id: payment_id, + payment_type: payment_type, payment_method: payment_method) end WalletService.debit_user_wallet(payment, user, reservation) @@ -49,7 +51,7 @@ class Reservations::Reserve # Generate the invoice for the given reservation+subscription ## def generate_schedule(reservation: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon: nil, - payment_id: nil) + payment_id: nil, payment_type: nil) operator = InvoicingProfile.find(operator_profile_id)&.user PaymentScheduleService.new.create( @@ -60,19 +62,21 @@ class Reservations::Reserve payment_method: payment_method, user: user, reservation: reservation, - payment_id: payment_id + payment_id: payment_id, + payment_type: payment_type ) end ## # Generate the invoice for the given reservation ## - def generate_invoice(reservation, operator_profile_id, payment_details, payment_id: nil, payment_method: nil) + def generate_invoice(reservation, operator_profile_id, payment_details, payment_id: nil, payment_type: nil, payment_method: nil) InvoicesService.create( payment_details, operator_profile_id, reservation: reservation, payment_id: payment_id, + payment_type: payment_type, payment_method: payment_method ) end diff --git a/app/services/subscriptions/subscribe.rb b/app/services/subscriptions/subscribe.rb index bc74b2a53..7743ac2a0 100644 --- a/app/services/subscriptions/subscribe.rb +++ b/app/services/subscriptions/subscribe.rb @@ -13,10 +13,11 @@ class Subscriptions::Subscribe # @param subscription {Subscription} # @param payment_details {Hash} as generated by Price.compute # @param payment_id {String} from the payment gateway + # @param payment_type {String} the object type of payment_id # @param schedule {Boolean} - # @param payment_method {String} only for schedules + # @param payment_method {String} ## - def pay_and_save(subscription, payment_details: nil, payment_id: nil, schedule: false, payment_method: nil) + def pay_and_save(subscription, payment_details: nil, payment_id: nil, payment_type: nil, schedule: false, payment_method: nil) return false if user_id.nil? user = User.find(user_id) @@ -33,12 +34,14 @@ class Subscriptions::Subscribe user: user, payment_method: payment_method, coupon: payment_details[:coupon], - payment_id: payment_id) + payment_id: payment_id, + payment_type: payment_type) else generate_invoice(subscription, operator_profile_id, payment_details, payment_id: payment_id, + payment_type: payment_type, payment_method: payment_method) end WalletService.debit_user_wallet(payment, user, subscription) @@ -83,7 +86,7 @@ class Subscriptions::Subscribe # Generate the invoice for the given subscription ## def generate_schedule(subscription: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon: nil, - payment_id: nil) + payment_id: nil, payment_type: nil) operator = InvoicingProfile.find(operator_profile_id)&.user PaymentScheduleService.new.create( @@ -93,19 +96,21 @@ class Subscriptions::Subscribe operator: operator, payment_method: payment_method, user: user, - payment_id: payment_id + payment_id: payment_id, + payment_type: payment_type ) end ## # Generate the invoice for the given subscription ## - def generate_invoice(subscription, operator_profile_id, payment_details, payment_id: nil, payment_method: nil) + def generate_invoice(subscription, operator_profile_id, payment_details, payment_id: nil, payment_type: nil, payment_method: nil) InvoicesService.create( payment_details, operator_profile_id, subscription: subscription, payment_id: payment_id, + payment_type: payment_type, payment_method: payment_method ) end diff --git a/app/views/api/invoices/index.json.jbuilder b/app/views/api/invoices/index.json.jbuilder index 800754720..419f35936 100644 --- a/app/views/api/invoices/index.json.jbuilder +++ b/app/views/api/invoices/index.json.jbuilder @@ -1,12 +1,12 @@ json.array!(@invoices) do |invoice| json.extract! invoice, :id, :created_at, :reference, :invoiced_type, :user_id, :avoir_date json.total (invoice.total / 100.00) - + json.name invoice.user.profile.full_name json.has_avoir invoice.refunded? json.is_avoir invoice.is_a?(Avoir) json.is_subscription_invoice invoice.subscription_invoice? - json.stripe invoice.paid_with_stripe? + json.stripe invoice.paid_by_card? json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at json.prevent_refund invoice.prevent_refund? end diff --git a/app/views/api/invoices/list.json.jbuilder b/app/views/api/invoices/list.json.jbuilder index a3a82f612..9e4eb5641 100644 --- a/app/views/api/invoices/list.json.jbuilder +++ b/app/views/api/invoices/list.json.jbuilder @@ -12,7 +12,7 @@ json.array!(@invoices) do |invoice| json.has_avoir invoice.refunded? json.is_avoir invoice.is_a?(Avoir) json.is_subscription_invoice invoice.subscription_invoice? - json.stripe invoice.paid_with_stripe? + json.stripe invoice.paid_by_card? json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at json.prevent_refund invoice.prevent_refund? json.chained_footprint invoice.check_footprint diff --git a/app/views/api/invoices/show.json.jbuilder b/app/views/api/invoices/show.json.jbuilder index a15a04046..8d3a92283 100644 --- a/app/views/api/invoices/show.json.jbuilder +++ b/app/views/api/invoices/show.json.jbuilder @@ -7,7 +7,7 @@ json.name @invoice.user.profile.full_name json.has_avoir @invoice.refunded? json.is_avoir @invoice.is_a?(Avoir) json.is_subscription_invoice @invoice.subscription_invoice? -json.stripe @invoice.paid_with_stripe? +json.stripe @invoice.paid_by_card? json.date @invoice.is_a?(Avoir) ? @invoice.avoir_date : @invoice.created_at json.chained_footprint @invoice.check_footprint json.items @invoice.invoice_items do |item| diff --git a/app/views/exports/users_reservations.xlsx.axlsx b/app/views/exports/users_reservations.xlsx.axlsx index d2127da4f..d58ae2b46 100644 --- a/app/views/exports/users_reservations.xlsx.axlsx +++ b/app/views/exports/users_reservations.xlsx.axlsx @@ -22,7 +22,7 @@ wb.add_worksheet(name: t('export_reservations.reservations')) do |sheet| resrv.reservable_type, (resrv.reservable.nil? ? '' : resrv.reservable.name), (resrv.reservable_type == 'Event') ? resrv.total_booked_seats: resrv.slots.count, - (resrv.invoice&.paid_with_stripe?) ? t('export_reservations.online_payment') : t('export_reservations.local_payment') + (resrv.invoice&.paid_by_card?) ? t('export_reservations.online_payment') : t('export_reservations.local_payment') ] styles = [nil, nil, nil, date, nil, nil, nil, nil] types = [:integer, :string, :string, :date, :string, :string, :integer, :string] diff --git a/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb b/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb index d21bf4604..9c1156181 100644 --- a/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb +++ b/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb @@ -14,7 +14,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] periods = Integrity::ArchiveHelper.backup_and_remove_periods ## INVOICES - puts 'Migrating invoices. This may take a while...' + puts 'Migrating invoices...' Invoice.order(:id).all.each do |i| if i.stp_invoice_id PaymentGatewayObject.create!( @@ -34,7 +34,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] remove_column :invoices, :stp_payment_intent_id ## INVOICE ITEMS - puts 'Migrating invoices items. This may take a while...' + puts 'Migrating invoices items...' InvoiceItem.order(:id).all.each do |ii| next unless ii.stp_invoice_item_id @@ -53,7 +53,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] # To fix it, we made a workaround to automatically cancel the subscription, just after it was took. # This workaround was kept in the code until v4.1.0 (SCA release), when we removed this whole pointless feature. # We keep this data for accounting integrity but we don't know it is gonna be useful again in the future - puts 'Migrating subscriptions. This may take a while...' + puts 'Migrating subscriptions...' Subscription.order(:id).all.each do |sub| next unless sub.stp_subscription_id @@ -66,7 +66,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] remove_column :subscriptions, :stp_subscription_id ## PAYMENT SCHEDULES - puts 'Migrating payment schedules. This may take a while...' + puts 'Migrating payment schedules...' PaymentSchedule.order(:id).all.each do |ps| if ps.stp_subscription_id PaymentGatewayObject.create!( @@ -87,7 +87,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] remove_column :payment_schedules, :stp_setup_intent_id ## PAYMENT SCHEDULE ITEMS - puts 'Migrating payment schedule items. This may take a while...' + puts 'Migrating payment schedule items...' PaymentScheduleItem.order(:id).all.each do |psi| next unless psi.stp_invoice_id @@ -100,7 +100,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] remove_column :payment_schedule_items, :stp_invoice_id ## PLANS, MACHINES, SPACES, TRAININGS - puts 'Migration stp_product_ids. This may take a while...' + puts 'Migrating stp_product_ids...' [Plan, Machine, Space, Training].each do |klass| klass.order(:id).all.each do |item| next unless item.stp_product_id @@ -110,12 +110,12 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] gateway_object_id: item.stp_product_id, gateway_object_type: 'Stripe::Product' ) - remove_column klass.arel_table.name, :stp_product_id end + remove_column klass.arel_table.name, :stp_product_id end ## USERS - puts 'Migrating users. This may take a while...' + puts 'Migrating users...' User.order(:id).all.each do |u| next unless u.stp_customer_id @@ -128,6 +128,7 @@ class MigrateStripeIdsToPaymentGatewayObjects < ActiveRecord::Migration[5.2] remove_column :users, :stp_customer_id # chain all records + puts 'Chaining all record. This may take a while...' InvoiceItem.order(:id).all.each(&:chain_record) Invoice.order(:id).all.each(&:chain_record) PaymentScheduleItem.order(:id).all.each(&:chain_record) diff --git a/db/structure.sql b/db/structure.sql index 13a25a6a7..f046c7136 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -108,8 +108,8 @@ SET default_tablespace = ''; CREATE TABLE public.abuses ( id integer NOT NULL, - signaled_type character varying, signaled_id integer, + signaled_type character varying, first_name character varying, last_name character varying, email character varying, @@ -187,8 +187,8 @@ CREATE TABLE public.addresses ( locality character varying, country character varying, postal_code character varying, - placeable_type character varying, placeable_id integer, + placeable_type character varying, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -263,8 +263,8 @@ CREATE TABLE public.ar_internal_metadata ( CREATE TABLE public.assets ( id integer NOT NULL, - viewable_type character varying, viewable_id integer, + viewable_type character varying, attachment character varying, type character varying, created_at timestamp without time zone, @@ -504,8 +504,8 @@ ALTER SEQUENCE public.coupons_id_seq OWNED BY public.coupons.id; CREATE TABLE public.credits ( id integer NOT NULL, - creditable_type character varying, creditable_id integer, + creditable_type character varying, plan_id integer, hours integer, created_at timestamp without time zone, @@ -1010,7 +1010,6 @@ ALTER SEQUENCE public.imports_id_seq OWNED BY public.imports.id; CREATE TABLE public.invoice_items ( id integer NOT NULL, invoice_id integer, - stp_invoice_item_id character varying, amount integer, created_at timestamp without time zone, updated_at timestamp without time zone, @@ -1046,9 +1045,8 @@ ALTER SEQUENCE public.invoice_items_id_seq OWNED BY public.invoice_items.id; CREATE TABLE public.invoices ( id integer NOT NULL, - invoiced_type character varying, invoiced_id integer, - stp_invoice_id character varying, + invoiced_type character varying, total integer, created_at timestamp without time zone, updated_at timestamp without time zone, @@ -1066,8 +1064,7 @@ CREATE TABLE public.invoices ( environment character varying, invoicing_profile_id integer, operator_profile_id integer, - statistic_profile_id integer, - stp_payment_intent_id character varying + statistic_profile_id integer ); @@ -1166,8 +1163,7 @@ CREATE TABLE public.machines ( created_at timestamp without time zone, updated_at timestamp without time zone, slug character varying, - disabled boolean, - stp_product_id character varying + disabled boolean ); @@ -1227,15 +1223,15 @@ ALTER SEQUENCE public.machines_id_seq OWNED BY public.machines.id; CREATE TABLE public.notifications ( id integer NOT NULL, receiver_id integer, - attached_object_type character varying, attached_object_id integer, + attached_object_type character varying, notification_type_id integer, is_read boolean DEFAULT false, created_at timestamp without time zone, updated_at timestamp without time zone, receiver_type character varying, is_send boolean DEFAULT false, - meta_data jsonb DEFAULT '"{}"'::jsonb + meta_data jsonb DEFAULT '{}'::jsonb ); @@ -1462,6 +1458,38 @@ CREATE SEQUENCE public.organizations_id_seq ALTER SEQUENCE public.organizations_id_seq OWNED BY public.organizations.id; +-- +-- Name: payment_gateway_objects; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.payment_gateway_objects ( + id bigint NOT NULL, + gateway_object_id character varying, + gateway_object_type character varying, + item_type character varying, + item_id bigint +); + + +-- +-- Name: payment_gateway_objects_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.payment_gateway_objects_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: payment_gateway_objects_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.payment_gateway_objects_id_seq OWNED BY public.payment_gateway_objects.id; + + -- -- Name: payment_schedule_items; Type: TABLE; Schema: public; Owner: - -- @@ -1472,7 +1500,6 @@ CREATE TABLE public.payment_schedule_items ( due_date timestamp without time zone, state character varying DEFAULT 'new'::character varying, details jsonb DEFAULT '"{}"'::jsonb, - stp_invoice_id character varying, payment_method character varying, client_secret character varying, payment_schedule_id bigint, @@ -1511,8 +1538,6 @@ CREATE TABLE public.payment_schedules ( scheduled_type character varying, scheduled_id bigint, total integer, - stp_subscription_id character varying, - stp_setup_intent_id character varying, reference character varying, payment_method character varying, wallet_amount integer, @@ -1569,8 +1594,7 @@ CREATE TABLE public.plans ( interval_count integer DEFAULT 1, slug character varying, disabled boolean, - monthly_payment boolean, - stp_product_id character varying + monthly_payment boolean ); @@ -1663,8 +1687,8 @@ CREATE TABLE public.prices ( id integer NOT NULL, group_id integer, plan_id integer, - priceable_type character varying, priceable_id integer, + priceable_type character varying, amount integer, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL @@ -1979,8 +2003,8 @@ CREATE TABLE public.reservations ( message text, created_at timestamp without time zone, updated_at timestamp without time zone, - reservable_type character varying, reservable_id integer, + reservable_type character varying, nb_reserve_places integer, statistic_profile_id integer ); @@ -2012,8 +2036,8 @@ ALTER SEQUENCE public.reservations_id_seq OWNED BY public.reservations.id; CREATE TABLE public.roles ( id integer NOT NULL, name character varying, - resource_type character varying, resource_id integer, + resource_type character varying, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -2159,8 +2183,7 @@ CREATE TABLE public.spaces ( created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL, characteristics text, - disabled boolean, - stp_product_id character varying + disabled boolean ); @@ -2556,7 +2579,6 @@ ALTER SEQUENCE public.stylesheets_id_seq OWNED BY public.stylesheets.id; CREATE TABLE public.subscriptions ( id integer NOT NULL, plan_id integer, - stp_subscription_id character varying, created_at timestamp without time zone, updated_at timestamp without time zone, expiration_date timestamp without time zone, @@ -2690,8 +2712,7 @@ CREATE TABLE public.trainings ( slug character varying, description text, public_page boolean DEFAULT true, - disabled boolean, - stp_product_id character varying + disabled boolean ); @@ -2866,7 +2887,6 @@ CREATE TABLE public.users ( updated_at timestamp without time zone, is_allow_contact boolean DEFAULT true, group_id integer, - stp_customer_id character varying, username character varying, slug character varying, is_active boolean DEFAULT true, @@ -2949,8 +2969,8 @@ CREATE TABLE public.users_roles ( CREATE TABLE public.wallet_transactions ( id integer NOT NULL, wallet_id integer, - transactable_type character varying, transactable_id integer, + transactable_type character varying, transaction_type character varying, amount integer, created_at timestamp without time zone NOT NULL, @@ -3283,6 +3303,13 @@ ALTER TABLE ONLY public.open_api_clients ALTER COLUMN id SET DEFAULT nextval('pu ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('public.organizations_id_seq'::regclass); +-- +-- Name: payment_gateway_objects id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_gateway_objects ALTER COLUMN id SET DEFAULT nextval('public.payment_gateway_objects_id_seq'::regclass); + + -- -- Name: payment_schedule_items id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3911,6 +3938,14 @@ ALTER TABLE ONLY public.organizations ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); +-- +-- Name: payment_gateway_objects payment_gateway_objects_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_gateway_objects + ADD CONSTRAINT payment_gateway_objects_pkey PRIMARY KEY (id); + + -- -- Name: payment_schedule_items payment_schedule_items_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4039,14 +4074,6 @@ ALTER TABLE ONLY public.roles ADD CONSTRAINT roles_pkey PRIMARY KEY (id); --- --- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.schema_migrations - ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); - - -- -- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4544,6 +4571,13 @@ CREATE INDEX index_open_api_calls_count_tracings_on_open_api_client_id ON public CREATE INDEX index_organizations_on_invoicing_profile_id ON public.organizations USING btree (invoicing_profile_id); +-- +-- Name: index_payment_gateway_objects_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_payment_gateway_objects_on_item_type_and_item_id ON public.payment_gateway_objects USING btree (item_type, item_id); + + -- -- Name: index_payment_schedule_items_on_invoice_id; Type: INDEX; Schema: public; Owner: - -- @@ -5118,6 +5152,29 @@ CREATE INDEX profiles_lower_unaccent_last_name_trgm_idx ON public.profiles USING CREATE INDEX projects_search_vector_idx ON public.projects USING gin (search_vector); +-- +-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); + + +-- +-- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: - +-- + +CREATE RULE accounting_periods_del_protect AS + ON DELETE TO public.accounting_periods DO INSTEAD NOTHING; + + +-- +-- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: - +-- + +CREATE RULE accounting_periods_upd_protect AS + ON UPDATE TO public.accounting_periods DO INSTEAD NOTHING; + + -- -- Name: projects projects_search_content_trigger; Type: TRIGGER; Schema: public; Owner: - -- @@ -5660,6 +5717,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20140605125131'), ('20140605142133'), ('20140605151442'), +('20140606133116'), ('20140609092700'), ('20140609092827'), ('20140610153123'), @@ -5728,12 +5786,14 @@ INSERT INTO "schema_migrations" (version) VALUES ('20150507075620'), ('20150512123546'), ('20150520132030'), +('20150520133409'), ('20150526130729'), ('20150527153312'), ('20150529113555'), ('20150601125944'), ('20150603104502'), ('20150603104658'), +('20150603133050'), ('20150604081757'), ('20150604131525'), ('20150608142234'), @@ -5815,6 +5875,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20160905142700'), ('20160906094739'), ('20160906094847'), +('20160906145713'), ('20160915105234'), ('20161123104604'), ('20170109085345'), @@ -5883,6 +5944,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20201027092149'), ('20201027100746'), ('20201027101809'), -('20201112092002'); +('20201112092002'), +('20210416073410'), +('20210416083610'); diff --git a/lib/integrity/archive_helper.rb b/lib/integrity/archive_helper.rb index bece2a4ad..4b3e1b396 100644 --- a/lib/integrity/archive_helper.rb +++ b/lib/integrity/archive_helper.rb @@ -84,5 +84,9 @@ class Integrity::ArchiveHelper AccountingPeriod.all end end + + def execute(query) + ActiveRecord::Base.connection.execute(query) + end end end diff --git a/lib/pay_zen/client.rb b/lib/pay_zen/client.rb index 19ba85007..116344325 100644 --- a/lib/pay_zen/client.rb +++ b/lib/pay_zen/client.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# PayZen payement gateway +# PayZen payments gateway module PayZen; end API_PATH = '/api-payment/V4' diff --git a/lib/pay_zen/item.rb b/lib/pay_zen/item.rb new file mode 100644 index 000000000..d2841930a --- /dev/null +++ b/lib/pay_zen/item.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'payment/item' + +# PayZen payement gateway +module PayZen; end + +## generic wrapper around PayZen classes +class PayZen::Item < Payment::Item + attr_accessor :id + + def retrieve(id) + @id ||= id + client = klass.constantize + client.get(@id) + end +end diff --git a/lib/payment/item.rb b/lib/payment/item.rb new file mode 100644 index 000000000..709edea9d --- /dev/null +++ b/lib/payment/item.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Payments module +module Payment; end + +# Generic payment object +class Payment::Item + attr_reader :klass + + def initialize(klass) + @klass = klass + end + + def class + klass + end + + def retrieve(_id); end +end diff --git a/lib/payment/item_builder.rb b/lib/payment/item_builder.rb new file mode 100644 index 000000000..8fa0060b1 --- /dev/null +++ b/lib/payment/item_builder.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'pay_zen/item' +require 'stripe/item' + +# Payments module +module Payment; end + +# Build the corresponding gateway item, according to the provided klass +class Payment::ItemBuilder + attr_reader :instance + + def self.build(klass) + builder = new(klass) + builder.instance + end + + private + + def initialize(klass) + @instance = case klass + when /^PayZen::/ + PayZen::Item.new(klass) + when /^Stripe::/ + Stripe::Item.new(klass) + else + raise TypeError + end + end +end diff --git a/lib/stripe/item.rb b/lib/stripe/item.rb new file mode 100644 index 000000000..f6b571482 --- /dev/null +++ b/lib/stripe/item.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'payment/item' + +# Stripe payement gateway +module Stripe; end + +## generic wrapper around Stripe classes +class Stripe::Item < Payment::Item + attr_accessor :id + + def retrieve(id) + @id ||= id + klass.constantize.retrieve(@id, api_key: Setting.get('stripe_secret_key')) + end +end diff --git a/test/integration/exports/accounting_export_test.rb b/test/integration/exports/accounting_export_test.rb index 0f2cdf91b..f216a7632 100644 --- a/test/integration/exports/accounting_export_test.rb +++ b/test/integration/exports/accounting_export_test.rb @@ -59,7 +59,7 @@ class Exports::AccountingExportTest < ActionDispatch::IntegrationTest entry_date = first_invoice.created_at.to_date assert_equal entry_date, DateTime.parse(data[0][I18n.t('accounting_export.date')]), 'Wrong date' - if first_invoice.paid_with_stripe? + if first_invoice.paid_by_card? card_client_code = Setting.get('accounting_card_client_code') assert_equal card_client_code, data[0][I18n.t('accounting_export.account_code')], 'Account code for card client is wrong'