diff --git a/app/controllers/finance/financial_transactions_controller.rb b/app/controllers/finance/financial_transactions_controller.rb index 6b06cbeec..1e6cdfbeb 100644 --- a/app/controllers/finance/financial_transactions_controller.rb +++ b/app/controllers/finance/financial_transactions_controller.rb @@ -50,11 +50,7 @@ def new def create @financial_transaction = FinancialTransaction.new(params[:financial_transaction]) @financial_transaction.user = current_user - if @financial_transaction.ordergroup - @financial_transaction.add_transaction! - else - @financial_transaction.save! - end + @financial_transaction.save! redirect_to finance_group_transactions_path(@ordergroup), notice: I18n.t('finance.financial_transactions.controller.create.notice') rescue ActiveRecord::RecordInvalid => e diff --git a/app/controllers/finance/ordergroups_controller.rb b/app/controllers/finance/ordergroups_controller.rb index 58ba0c364..46fc1b068 100644 --- a/app/controllers/finance/ordergroups_controller.rb +++ b/app/controllers/finance/ordergroups_controller.rb @@ -14,7 +14,7 @@ def index @ordergroups = @ordergroups.page(params[:page]).per(@per_page) @total_balances = FinancialTransactionClass.sorted.each_with_object({}) do |c, tmp| - tmp[c.id] = c.financial_transactions.reduce(0) { |sum, t| sum + t.amount } + tmp[c.id] = c.financial_transactions.reduce(0) { |sum, t| sum + (t.amount || 0) } end end end diff --git a/app/models/financial_transaction.rb b/app/models/financial_transaction.rb index 1556ecbef..aed5ba784 100644 --- a/app/models/financial_transaction.rb +++ b/app/models/financial_transaction.rb @@ -11,9 +11,11 @@ class FinancialTransaction < ApplicationRecord belongs_to :reverts, optional: true, class_name: 'FinancialTransaction' has_one :reverted_by, class_name: 'FinancialTransaction', foreign_key: 'reverts_id' - validates :amount, :note, :user_id, presence: true + validates :note, :user_id, presence: true validates :amount, numericality: { greater_then: -100_000, - less_than: 100_000 } + less_than: 100_000 }, + allow_nil: -> { payment_amount.present? } + validates :payment_amount, :payment_fee, allow_nil: true, numericality: { greater_then: 0, less_than: 100_000 } scope :visible, lambda { joins('LEFT JOIN financial_transactions r ON financial_transactions.id = r.reverts_id').where('r.id IS NULL').where(reverts: nil) @@ -23,6 +25,8 @@ class FinancialTransaction < ApplicationRecord localize_input_of :amount + after_save :update_ordergroup_balance + after_initialize do initialize_financial_transaction_type end @@ -38,16 +42,11 @@ def self.ransackable_associations(_auth_object = nil) %w[] # none, and certainly not user until we've secured that more end - # Use this save method instead of simple save and after callback - def add_transaction! - ordergroup.add_financial_transaction! amount, note, user, financial_transaction_type - end - def revert!(user) transaction do update_attribute :financial_link, FinancialLink.new rt = dup - rt.amount = -rt.amount + rt.amount = rt.amount ? -rt.amount : nil rt.reverts = self rt.user = user rt.save! @@ -73,4 +72,12 @@ def created_at def initialize_financial_transaction_type self.financial_transaction_type ||= FinancialTransactionType.default end + + private + + def update_ordergroup_balance + # @todo Make sure this transaction and the ordergroup update is in one database transaction. + # It may be possible to use an around filter if needed. + ordergroup.update_balance! + end end diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 6770fc554..9c1bf6053 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -91,14 +91,12 @@ def add_financial_transaction!(amount, note, user, transaction_type, link = nil, t.save! update_balance! # Notify only when order group had a positive balance before the last transaction: - if t.amount < 0 && account_balance < 0 && account_balance - t.amount >= 0 - NotifyNegativeBalanceJob.perform_later(self, - t) - end + NotifyNegativeBalanceJob.perform_later(self, t) if t.amount < 0 && account_balance < 0 && account_balance - t.amount >= 0 t end end + # Recomputes job statistics from group orders. def update_stats! # Get hours for every job of each user in period jobs = users.to_a.sum { |u| u.tasks.done.where('updated_on > ?', APPLE_MONTH_AGO.month.ago).sum(:duration) } @@ -156,7 +154,7 @@ def self.avg_jobs_per_euro end def account_updated - financial_transactions.last.try(:created_on) || created_on + financial_transactions.last.try(:updated_on) || created_on end def self.sort_by_param(param) diff --git a/app/views/finance/financial_transactions/_transactions.html.haml b/app/views/finance/financial_transactions/_transactions.html.haml index 1a4c22e8f..efe3dbb88 100644 --- a/app/views/finance/financial_transactions/_transactions.html.haml +++ b/app/views/finance/financial_transactions/_transactions.html.haml @@ -45,7 +45,7 @@ = t.note - FinancialTransactionClass.sorted.each do |c| %td.numeric{style: 'width:5em'} - - if t.financial_transaction_type.financial_transaction_class == c + - if t.financial_transaction_type.financial_transaction_class == c && t.amount = format_currency t.amount - if with_hidden %td.actions{style: 'width:1em'} diff --git a/app/views/finance/index.html.haml b/app/views/finance/index.html.haml index 50ee822c9..9de3eb999 100644 --- a/app/views/finance/index.html.haml +++ b/app/views/finance/index.html.haml @@ -36,7 +36,7 @@ %td= format_date(ft.created_on) %td= ft.ordergroup_name %td= ft.note - %td.numeric= format_currency ft.amount + %td.numeric= ft.amount ? format_currency(ft.amount) : '-' .span6 %h2 = t('.open_transactions') @@ -48,7 +48,7 @@ %th= heading_helper Order, :name %th= t '.end' %th.numeric= t('.amount_fc') - %th + %th %tbody - @orders.each do |order| %tr diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 9d1ee4448..6dc850316 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -63,6 +63,7 @@ = link_to my_ordergroup_path do = t '.my_ordergroup.transactions.view' %i.icon.icon-chevron-right + - '' %table.table.table-striped %tr %th= heading_helper FinancialTransaction, :created_on @@ -83,7 +84,7 @@ - FinancialTransactionClass.sorted.each do |fc| %td.numeric{style: 'width:5em'} - if ft.financial_transaction_type.financial_transaction_class == fc - = format_currency ft.amount + = ft.amount ? format_currency(ft.amount) : '-' -# placeholder deface to add content using erb[silent]:contains() - '' diff --git a/app/views/home/ordergroup.html.haml b/app/views/home/ordergroup.html.haml index c91e7ae4f..76b53993d 100644 --- a/app/views/home/ordergroup.html.haml +++ b/app/views/home/ordergroup.html.haml @@ -23,6 +23,7 @@ = @ordergroup.memberships.map{|m| show_user m.user}.join(', ') - unless FoodsoftConfig[:disable_invite] = link_to t('.invite'), new_invite_path(:id => @ordergroup), :remote => true, class: 'btn btn-primary' + - '' .span8 %h2= t('.account_summary') .well.well-small diff --git a/db/migrate/20230915093041_add_payment_to_financial_transaction.rb b/db/migrate/20230915093041_add_payment_to_financial_transaction.rb new file mode 100644 index 000000000..82c2123ea --- /dev/null +++ b/db/migrate/20230915093041_add_payment_to_financial_transaction.rb @@ -0,0 +1,26 @@ +class AddPaymentToFinancialTransaction < ActiveRecord::Migration[7.0] + def change + reversible do |dir| + dir.up do + change_column :financial_transactions, :amount, :decimal, :precision => 8, :scale => 2, :default => nil, :null => true + end + dir.down do + change_column :financial_transactions, :amount, :decimal, :precision => 8, :scale => 2, :default => 0, :null => false + end + end + + add_column :financial_transactions, :updated_on, :timestamp + add_column :financial_transactions, :payment_method, :string + add_column :financial_transactions, :payment_plugin, :string + add_column :financial_transactions, :payment_id, :string + add_column :financial_transactions, :payment_amount, :decimal, :precision => 8, :scale => 3 + add_column :financial_transactions, :payment_currency, :string + add_column :financial_transactions, :payment_state, :string + add_column :financial_transactions, :payment_fee, :decimal, :precision => 8, :scale => 3 + add_column :financial_transactions, :payment_acct_number, :string + add_column :financial_transactions, :payment_acct_name, :string + add_column :financial_transactions, :payment_info, :text + + add_index :financial_transactions, [:payment_plugin, :payment_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index 4c853039d..873c04c1e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_02_15_085312) do +ActiveRecord::Schema[7.0].define(version: 2023_09_15_093041) do create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.string "name", null: false t.text "body", size: :long @@ -159,7 +159,7 @@ create_table "financial_transactions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| t.integer "ordergroup_id" - t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false + t.decimal "amount", precision: 8, scale: 2 t.text "note", null: false t.integer "user_id", default: 0, null: false t.datetime "created_on", precision: nil, null: false @@ -167,7 +167,19 @@ t.integer "financial_link_id" t.integer "reverts_id" t.integer "group_order_id" + t.timestamp "updated_on" + t.string "payment_method" + t.string "payment_plugin" + t.string "payment_id" + t.decimal "payment_amount", precision: 8, scale: 3 + t.string "payment_currency" + t.string "payment_state" + t.decimal "payment_fee", precision: 8, scale: 3 + t.string "payment_acct_number" + t.string "payment_acct_name" + t.text "payment_info" t.index ["ordergroup_id"], name: "index_financial_transactions_on_ordergroup_id" + t.index ["payment_plugin", "payment_id"], name: "index_financial_transactions_on_payment_plugin_and_payment_id" t.index ["reverts_id"], name: "index_financial_transactions_on_reverts_id", unique: true end