Skip to content

Commit

Permalink
Add list of currencies(#329)
Browse files Browse the repository at this point in the history
Changes:
Adding a dropdown on create general settings form
to choose a currency from a given list of currencies.
  • Loading branch information
jyotigautam committed Nov 29, 2018
1 parent 42ca81f commit 5bc170a
Show file tree
Hide file tree
Showing 19 changed files with 80 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule AdminAppWeb.ShippingPolicyController do

alias Snitch.Core.Tools.MultiTenancy.Repo
alias Snitch.Data.Schema.ShippingCategory
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel
alias Snitch.Data.Model.ShippingCategory, as: ScModel

@defaults Application.get_env(:snitch_core, :defaults_module)
Expand Down Expand Up @@ -66,7 +67,7 @@ defmodule AdminAppWeb.ShippingPolicyController do
end

def set_shipping_amount(rules) do
{:ok, currency} = @defaults.fetch(:currency)
currency = GCModel.fetch_currency()

Enum.map(rules, fn rule ->
amount = rule["shipping_cost"] || "0.00"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@
<%= input f, :hosted_payment_url, nil, is_horizontal: true, description: "Payment URL for the store." %>
</div>
<div class="form-group row ">
<%= input f, :currency, nil, is_horizontal: true, description: "Default currency for the store." %>
<label class="col-sm-3 col-form-label">
<div class="label">
Currency
</div>
<div class="label-txt">Default currency of the store</div>
</label>
<div class="col-sm-9 input-group">
<%= select f, :currency, get_currency(), value: f.data.currency, class: "form-control" %>
</div>
</div>
<%= if @changeset.data.image != nil do %>
<div class="img-wrap col-3 p-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<div class="col-sm-9 input-group">
<%= text_input :selling_price, :amount, value: get_amount(f.data.selling_price), class: "form-control", name: "product[selling_price][amount]" %>
<div class="input-group-append">
<%= select :selling_price, :currency, get_currency(),value: get_currency_value(f.data.selling_price), class: "form-control", name: "product[selling_price][currency]" %>
<%= select :selling_price, :currency, get_currency(),value: get_currency_value(), class: "form-control", name: "product[selling_price][currency]" %>
</div>
</div>
</div>
Expand All @@ -66,7 +66,7 @@
<div class="col-sm-9 input-group">
<%= text_input :max_retail_price, :amount, value: get_amount(f.data.max_retail_price), class: "form-control", name: "product[max_retail_price][amount]" %>
<div class="input-group-append">
<%= select :max_retail_price, :currency, get_currency(),value: get_currency_value(f.data.max_retail_price), class: "form-control", name: "product[max_retail_price][currency]" %>
<%= select :max_retail_price, :currency, get_currency(),value: get_currency_value(), class: "form-control", name: "product[max_retail_price][currency]" %>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ defmodule AdminAppWeb.GeneralSettingsView do
use AdminAppWeb, :view
alias Snitch.Data.Model.ProductBrand

@currencies ["USD", "INR", "GDP", "EUR"]

def get_image_url(image, general_settings) do
ProductBrand.image_url(image.name, general_settings)
end

def get_currency() do
@currencies
end
end
13 changes: 4 additions & 9 deletions apps/admin_app/lib/admin_app_web/views/product_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ defmodule AdminAppWeb.ProductView do
alias Snitch.Core.Tools.MultiTenancy.Repo
alias Snitch.Domain.Taxonomy

alias Snitch.Data.Model.{Product, ProductProperty, Property, StockItem}
alias Snitch.Data.Model.{GeneralConfiguration, Product, ProductProperty, Property, StockItem}
alias Snitch.Data.Schema
import Ecto.Query

@currencies ["USD", "INR"]
@dummy_image_url "/images/empty-img.png"
@search_keys ["rummage", "search", "state", "search_term"]
@sort_field_keys ["rummage", "sort", "field"]
Expand Down Expand Up @@ -76,17 +75,13 @@ defmodule AdminAppWeb.ProductView do
conn.params["taxon"]
end

def get_currency_value(nil) do
@currencies |> List.first()
end

def get_currency_value(money) do
money.currency
def get_currency_value() do
GeneralConfiguration.fetch_currency()
end

# TODO This needs to fetched from config
def get_currency() do
@currencies
[GeneralConfiguration.fetch_currency()]
end

def get_image_url(image, product) do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule SnitchApiWeb.HostedPaymentController do
use SnitchApiWeb, :controller
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel
alias SnitchApi.Payment.HostedPayment
alias SnitchPayments
alias SnitchPayments.Gateway.{PayuBiz, RazorPay, Stripe}
Expand Down Expand Up @@ -39,7 +40,8 @@ defmodule SnitchApiWeb.HostedPaymentController do

def stripe_purchase(conn, params) do
## TODO get the currency set for store here and use that.
amount = Money.new!(:USD, params["amount"])
currency = GCModel.fetch_currency()
amount = Money.new!(currency, params["amount"])
preferences = HostedPayment.get_payment_preferences(params["payment_method_id"])
secret = preferences[:credentials]["secret_key"]
request_params = stripe_params_setup(params)
Expand Down
6 changes: 6 additions & 0 deletions apps/snitch_core/lib/core/data/model/general_configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ defmodule Snitch.Data.Model.GeneralConfiguration do
alias Snitch.Tools.Helper.ImageUploader
alias Ecto.Multi

@spec fetch_currency() :: String.t()
def fetch_currency do
general_config = Repo.all(GC) |> List.first()
if general_config != nil, do: general_config.currency, else: "USD"
end

@spec build_general_configuration(map) :: Ecto.Changeset.t()
def build_general_configuration(attrs \\ %{}) do
%GC{} |> GC.create_changeset(attrs)
Expand Down
12 changes: 6 additions & 6 deletions apps/snitch_core/lib/core/domain/order/order.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule Snitch.Domain.Order do
import Ecto.Query
alias Snitch.Data.Schema.{Order, Package, Payment}
alias Snitch.Data.Model.Product
alias Snitch.Tools.Defaults
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel

@spec validate_change(Ecto.Changeset.t()) :: Ecto.Changeset.t()
def validate_change(%{valid?: false} = changeset), do: changeset
Expand All @@ -38,7 +38,7 @@ defmodule Snitch.Domain.Order do
"""
@spec payments_total(Order.t(), String.t()) :: Money.t()
def payments_total(order, payment_state) do
{:ok, currency} = Defaults.fetch(:currency)
currency = GCModel.fetch_currency()

query =
from(
Expand Down Expand Up @@ -76,7 +76,7 @@ defmodule Snitch.Domain.Order do

def total_amount(%Order{} = order) do
order = Repo.preload(order, [:line_items, packages: :items])
{:ok, currency} = Defaults.fetch(:currency)
currency = GCModel.fetch_currency()

total =
Money.add!(
Expand All @@ -88,7 +88,7 @@ defmodule Snitch.Domain.Order do
end

def line_item_total(order) do
{:ok, currency} = Defaults.fetch(:currency)
currency = GCModel.fetch_currency()

order.line_items
|> Enum.reduce(Money.new(currency, 0), fn line_item, acc ->
Expand Down Expand Up @@ -130,7 +130,7 @@ defmodule Snitch.Domain.Order do
end

def total_tax(packages) do
{:ok, currency} = Defaults.fetch(:currency)
currency = GCModel.fetch_currency()

packages
|> Enum.reduce(Money.new(currency, 0), fn %{
Expand All @@ -146,7 +146,7 @@ defmodule Snitch.Domain.Order do
end

def shipping_total(packages) do
{:ok, currency} = Defaults.fetch(:currency)
currency = GCModel.fetch_currency()

packages
|> Enum.reduce(Money.new(currency, 0), fn %{cost: cost}, acc ->
Expand Down
5 changes: 4 additions & 1 deletion apps/snitch_core/lib/core/domain/package.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Snitch.Domain.Package do
alias Snitch.Domain.ShippingCalculator
alias Snitch.Tools.Money, as: MoneyTools
alias Snitch.Data.Model.StockItem
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel

@doc """
Saves
Expand All @@ -23,8 +24,10 @@ defmodule Snitch.Domain.Package do
# if we can't find the selected shipping method, we must force the
# Packge.update to fail
# Eventually replace with some nice API contract/validator.
currency = GCModel.fetch_currency()

shipping_method =
Enum.find(package.shipping_methods, %{cost: Money.zero(:INR), id: nil}, fn %{id: id} ->
Enum.find(package.shipping_methods, %{cost: Money.zero(currency), id: nil}, fn %{id: id} ->
id == shipping_method_id
end)

Expand Down
5 changes: 2 additions & 3 deletions apps/snitch_core/lib/core/domain/shipping_calculator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ defmodule Snitch.Domain.ShippingCalculator do

alias Snitch.Core.Tools.MultiTenancy.Repo
alias Snitch.Domain.Order, as: OrderDomain
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel
alias Snitch.Data.Schema.{Order, Package}

@defaults Application.get_env(:snitch_core, :defaults_module)

@doc """
Returns the `shipping_cost` for a `package`.
Expand Down Expand Up @@ -52,7 +51,7 @@ defmodule Snitch.Domain.ShippingCalculator do

active_rules = get_category_active_rules(package.shipping_category)

{:ok, currency_code} = @defaults.fetch(:currency)
currency_code = GCModel.fetch_currency()
cost = Money.new!(currency_code, 0)

# The piping here is in the order of priority,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ defmodule Snitch.Tools.OrderEmail do
user_email = order.user.email

logo = if general_config.image != nil, do: general_config.image.name, else: nil

mail_template =
order_email(%{
order: order,
Expand All @@ -40,6 +41,7 @@ defmodule Snitch.Tools.OrderEmail do
})

store_name = general_config.name

email =
new_email()
|> to(user_email)
Expand Down
20 changes: 10 additions & 10 deletions apps/snitch_core/lib/core/tools/money.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ defmodule Snitch.Tools.Money do
@moduledoc """
Some (weak) helpers to work with zeroes and `Money.t`.
"""

@defaults Application.get_env(:snitch_core, :defaults_module)
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel
# @defaults Application.get_env(:snitch_core, :defaults_module)

@doc """
Returns the zero `Money.t` with `currency`.
Expand All @@ -20,10 +20,12 @@ defmodule Snitch.Tools.Money do
def zero(currency \\ nil)

def zero(nil) do
case @defaults.fetch(:currency) do
{:ok, default_currency} -> Money.zero(default_currency)
error -> error
end
# case @defaults.fetch(:currency) do
# {:ok, default_currency} -> Money.zero(default_currency)
# error -> error
# end
currency = GCModel.fetch_currency()
Money.zero(currency)
end

def zero(currency) when is_atom(currency) or is_binary(currency) do
Expand All @@ -44,10 +46,8 @@ defmodule Snitch.Tools.Money do
def zero!(currency \\ nil)

def zero!(nil) do
case @defaults.fetch(:currency) do
{:ok, default_currency} -> Money.new!(0, default_currency)
{:error, msg} -> raise(RuntimeError, msg)
end
currency = GCModel.fetch_currency()
Money.zero(currency)
end

def zero!(currency) when is_atom(currency) or is_binary(currency) do
Expand Down
15 changes: 7 additions & 8 deletions apps/snitch_core/test/data/model/line_item_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule Snitch.Data.Model.LineItemTest do
import Snitch.Factory

alias Snitch.Data.Model.{LineItem, Order}
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel

describe "with valid params" do
setup :variants
Expand Down Expand Up @@ -42,17 +43,15 @@ defmodule Snitch.Data.Model.LineItemTest do
describe "compute_total/1 with empty list" do
setup :verify_on_exit!

test "when default currency is set" do
expect(Snitch.Tools.DefaultsMock, :fetch, fn :currency -> {:ok, :INR} end)
assert Money.zero(:INR) == LineItem.compute_total([])
test "when default currency is set in the store" do
config = insert(:general_config)
assert GCModel.fetch_currency() == config.currency
assert Money.zero(config.currency) == LineItem.compute_total([])
end

test "when default currency is not set" do
expect(Snitch.Tools.DefaultsMock, :fetch, fn :currency -> {:error, "whatever"} end)

assert_raise RuntimeError, "whatever", fn ->
LineItem.compute_total([])
end
assert GCModel.fetch_currency() == "USD"
assert Money.zero("USD") == LineItem.compute_total([])
end
end

Expand Down
5 changes: 0 additions & 5 deletions apps/snitch_core/test/domain/order/transitions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ defmodule Snitch.Domain.Order.TransitionsTest do
setup :embedded_shipping_methods

setup %{embedded_shipping_methods: methods} do
Application.put_env(:snitch_core, :defaults, currency: :USD)
order = insert(:order)
[order: order, packages: [insert(:package, shipping_methods: methods, order: order)]]
end
Expand All @@ -174,8 +173,6 @@ defmodule Snitch.Domain.Order.TransitionsTest do
%{package_id: package.id, shipping_method_id: sm.id}
]

expect(Snitch.Tools.DefaultsMock, :fetch, 2, fn :currency -> {:ok, :USD} end)

result =
order
|> Context.new(state: %{shipping_preferences: preference})
Expand All @@ -191,8 +188,6 @@ defmodule Snitch.Domain.Order.TransitionsTest do
%{
shipping_methods: [sm]
} = context do
expect(Snitch.Tools.DefaultsMock, :fetch, 2, fn :currency -> {:ok, :USD} end)

set_cost = Money.new!(:USD, 100)
quantity = 3

Expand Down
9 changes: 5 additions & 4 deletions apps/snitch_core/test/domain/package_item_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ defmodule Snitch.Domain.PackageItemTest do
import Mox, only: [expect: 3, verify_on_exit!: 1]

alias Snitch.Domain.PackageItem
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel

setup :verify_on_exit!

test "tax/1" do
expect(Snitch.Tools.DefaultsMock, :fetch, fn :currency -> {:ok, :INR} end)
assert PackageItem.tax(nil, nil) == Money.zero(:INR)
currency = GCModel.fetch_currency()
assert PackageItem.tax(nil, nil) == Money.zero(currency)
end

test "shipping_tax/1" do
expect(Snitch.Tools.DefaultsMock, :fetch, fn :currency -> {:ok, :INR} end)
assert PackageItem.shipping_tax(nil, nil) == Money.zero(:INR)
currency = GCModel.fetch_currency()
assert PackageItem.shipping_tax(nil, nil) == Money.zero(currency)
end
end
7 changes: 3 additions & 4 deletions apps/snitch_core/test/domain/package_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule Snitch.Domain.PackageTest do
import Snitch.Factory

alias Snitch.Domain.Package
alias Snitch.Data.Model.GeneralConfiguration, as: GCModel

describe "set_shipping_method/2" do
setup :zones
Expand All @@ -20,7 +21,6 @@ defmodule Snitch.Domain.PackageTest do

@tag shipping_method_count: 1
test "with valid shipping method", %{package: package, shipping_methods: [sm]} do
expect(Snitch.Tools.DefaultsMock, :fetch, 2, fn :currency -> {:ok, :USD} end)
assert {:ok, package} = Package.set_shipping_method(package, sm.id)
assert package.shipping_method_id
assert package.cost
Expand All @@ -29,7 +29,6 @@ defmodule Snitch.Domain.PackageTest do

@tag shipping_method_count: 1
test "with invalid shipping method", %{package: package, shipping_methods: [sm]} do
expect(Snitch.Tools.DefaultsMock, :fetch, 4, fn :currency -> {:ok, :USD} end)
assert {:error, cs} = Package.set_shipping_method(package, -1)
assert %{shipping_method_id: ["can't be blank"]} == errors_on(cs)

Expand All @@ -39,7 +38,7 @@ defmodule Snitch.Domain.PackageTest do
end

test "shipping_tax/1" do
expect(Snitch.Tools.DefaultsMock, :fetch, 1, fn :currency -> {:ok, :INR} end)
assert Package.shipping_tax(nil) == Money.zero(:INR)
currency = GCModel.fetch_currency()
assert Package.shipping_tax(nil) == Money.zero(currency)
end
end
Loading

0 comments on commit 5bc170a

Please sign in to comment.