magnusvk/counter_culture

how to do conditional totalling?

Closed this issue · 2 comments

hello I use counter_culture to get the value of profit/loss from a transaction

then in my code I have this
I have Transaction with :total column and TransactionEntry with :amount column

class Transaction < ApplicationRecord
  has_many :transaction_entries
end
class TransactionEntry < ApplicationRecord
  belongs_to :transaction
  counter_culture :transaction, column_name: "total", delta_column: "amount"
end

problem is Transaction has 2 Type NegativeTransaction and PositiveTransaction
how to make the sum from counter_culture take amount from the NegativeTransaction as negative value instead positive value?

can counter culture do this type of sum calculation?

or should I refactor my app so that NegativeTransaction has negative value instead positive in it's total?

in RAW SQL my sum calculation are like this

SELECT SUM(CASE 
  WHEN transactions.type = 'NegativeTransaction' then -(transactions.amount)
  WHEN transactions.type = 'PositiveTransaction' then transactions.amount
  else 0 end
) AS total
  FROM transactions 

and also could anyone tell me when is counter_culture executed after, before or between activerecord callbacks?

Because I'm thinking about have separates total for both type of calculation, when its negative transaction I could add callbacks that make the calculation from counter_culture to become negatives before saving the results

update:
I just check the source code and there is this increment/decrement options
https://github.com/magnusvk/counter_culture/blob/master/lib/counter_culture/counter.rb#L33

I have tried to use increment: options and it not works

my code for the increment options are like this

class TransactionEntry < ApplicationRecord
  belongs_to :transaction
  counter_culture :transaction, column_name: "total", delta_column: "amount", increment: proc { |model| model.type == "IncrementInventoryTransaction" ? true : false }
end

I think it works fine if I put the increment value without proc and put the line inside my STI problem is with doing that I cannot do counter_culture_fix_counts

A possible solution here is to create a new column for a signed value, keep it current with before_save, and use that for :delta_column.

Looks like this is what you're looking for?

counter_culture runs as an ActiveRecord callback.