mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-11 03:40:20 +00:00
Add available credit on the admin customer page
This commit is contained in:
@@ -12,7 +12,8 @@ class CustomersWithBalanceQuery
|
||||
joins(left_join_complete_orders).
|
||||
group("customers.id").
|
||||
select("customers.*").
|
||||
select("#{outstanding_balance_sum} AS balance_value")
|
||||
select("#{outstanding_balance_sum} AS balance_value").
|
||||
select("#{available_credit} AS credit_value")
|
||||
end
|
||||
|
||||
private
|
||||
@@ -34,4 +35,21 @@ class CustomersWithBalanceQuery
|
||||
def outstanding_balance_sum
|
||||
"SUM(#{OutstandingBalanceQuery.new.statement})::float"
|
||||
end
|
||||
|
||||
def available_credit
|
||||
<<~SQL.squish
|
||||
CASE WHEN EXISTS (#{available_credit_subquery}) THEN (#{available_credit_subquery})#{' '}
|
||||
ELSE 0.00 END
|
||||
SQL
|
||||
end
|
||||
|
||||
def available_credit_subquery
|
||||
<<~SQL.squish
|
||||
SELECT balance
|
||||
FROM customer_account_transactions
|
||||
WHERE customer_account_transactions.customer_id = customers.id
|
||||
ORDER BY id desc
|
||||
LIMIT 1
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,14 +7,18 @@ module Api
|
||||
# columns to instance methods. This way, the `balance_value` alias on that class ends up being
|
||||
# `object.balance_value` here.
|
||||
class CustomerWithBalanceSerializer < CustomerSerializer
|
||||
attributes :balance, :balance_status
|
||||
attributes :balance, :balance_status, :available_credit
|
||||
|
||||
delegate :balance_value, to: :object
|
||||
delegate :balance_value, :credit_value, to: :object
|
||||
|
||||
def balance
|
||||
Spree::Money.new(balance_value, currency: CurrentConfig.get(:currency)).to_s
|
||||
end
|
||||
|
||||
def available_credit
|
||||
Spree::Money.new(object.credit_value).to_s
|
||||
end
|
||||
|
||||
def balance_status
|
||||
if balance_value.positive?
|
||||
"credit_owed"
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
%th.bill_address{ 'ng-show' => 'columns.bill_address.visible' }=t('admin.customers.index.bill_address')
|
||||
%th.ship_address{ 'ng-show' => 'columns.ship_address.visible' }=t('admin.customers.index.ship_address')
|
||||
%th.balance{ 'ng-show' => 'columns.balance.visible' }=t('admin.customers.index.balance')
|
||||
%th.credit{ 'ng-show' => 'columns.credit.visible' }=t('admin.customers.index.credit')
|
||||
%tbody
|
||||
%tr.customer{ 'ng-repeat' => "customer in filteredCustomers = ( customers | filter:quickSearch | orderBy: sorting.predicate:sorting.reverse ) | limitTo:customerLimit track by customer.id", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "c_{{customer.id}}" }
|
||||
-# %td.bulk
|
||||
@@ -98,6 +99,8 @@
|
||||
%td.balance.align-center{ 'ng-show' => 'columns.balance.visible'}
|
||||
%span.state.white-space-nowrap{ 'ng-class' => 'customer.balance_status', 'ng-bind' => 'displayBalanceStatus(customer)' }
|
||||
%span{ 'ng-bind' => '::customer.balance' }
|
||||
%td.balance.align-center{ 'ng-show' => 'columns.credit.visible'}
|
||||
%span{ 'ng-bind' => '::customer.available_credit' }
|
||||
%td.actions
|
||||
%a{ 'ng-click' => "deleteCustomer(customer)", :class => "delete-customer icon-trash no-text" }
|
||||
|
||||
|
||||
@@ -877,6 +877,7 @@ en:
|
||||
bill_address: "Billing Address"
|
||||
ship_address: "Shipping Address"
|
||||
balance: "Balance"
|
||||
credit: "Available Credit"
|
||||
update_address_success: "Address updated successfully."
|
||||
update_address_error: "Sorry! Please input all of the required fields!"
|
||||
edit_bill_address: "Edit Billing Address"
|
||||
|
||||
@@ -36,7 +36,8 @@ module OpenFoodNetwork
|
||||
tags: { name: I18n.t("admin.tags"), visible: true },
|
||||
bill_address: { name: I18n.t("#{node}.bill_address"), visible: true },
|
||||
ship_address: { name: I18n.t("#{node}.ship_address"), visible: true },
|
||||
balance: { name: I18n.t("#{node}.balance"), visible: true }
|
||||
balance: { name: I18n.t("#{node}.balance"), visible: true },
|
||||
credit: { name: I18n.t("#{node}.credit"), visible: true }
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -210,5 +210,32 @@ RSpec.describe CustomersWithBalanceQuery do
|
||||
expect(customer.balance_value).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "with customer payments" do
|
||||
# TODO should not be needed, need to add this to seed somehow
|
||||
let!(:payment_method) {
|
||||
create(
|
||||
:payment_method,
|
||||
name: CustomerAccountTransaction::DEFAULT_PAYMENT_METHOD_NAME,
|
||||
distributors: [customer.enterprise]
|
||||
)
|
||||
}
|
||||
|
||||
it 'returns the customer available credit' do
|
||||
create(:customer_account_transaction, customer:, amount: 10.00)
|
||||
create(:customer_account_transaction, customer:, amount: -2.00)
|
||||
create(:customer_account_transaction, customer:, amount: 5.00)
|
||||
|
||||
customer_result = result.first
|
||||
expect(customer_result.credit_value).to eq(13.00)
|
||||
end
|
||||
end
|
||||
|
||||
context "with no customer payments" do
|
||||
it 'returns 0 for the customer available credit' do
|
||||
customer_result = result.first
|
||||
expect(customer_result.credit_value).to eq(0.00)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,6 +16,19 @@ RSpec.describe Api::Admin::CustomerWithBalanceSerializer do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#available_credit' do
|
||||
let(:customer) { double(Customer, credit_value: 5.3) }
|
||||
let(:money) { instance_double(Spree::Money, to_s: "$5.30") }
|
||||
|
||||
before do
|
||||
allow(Spree::Money).to receive(:new).with(5.3) { money }
|
||||
end
|
||||
|
||||
it 'returns the available_credit as a money amount' do
|
||||
expect(serialized_customer.available_credit).to eq("$5.30")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#balance_status' do
|
||||
context 'when the balance_value is positive' do
|
||||
let(:customer) { double(Customer, balance_value: 1) }
|
||||
|
||||
Reference in New Issue
Block a user