Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit bc0b0b6

Browse files
committed
Merge branch 'billing' into dev
2 parents 07d8210 + cd14978 commit bc0b0b6

31 files changed

+693
-170
lines changed

config/config.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ config :mastani_server, :general,
4444
publish_throttle_interval_minutes: 3,
4545
publish_throttle_hour_limit: 20,
4646
publish_throttle_day_limit: 30,
47+
# membership
48+
seninor_amount_threshold: 51.2,
4749
# user achievements
4850
user_achieve_star_weight: 1,
4951
user_achieve_watch_weight: 1,

lib/helper/certification.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ defmodule Helper.Certification do
3434
def all_rules(:cms) do
3535
%{
3636
general: [
37+
"system_accountant",
3738
"system_notification.publish",
3839
"stamp_passport",
3940
# community

lib/helper/error_code.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ defmodule Helper.ErrorCode do
2424
def ecode(:update_fails), do: @default_base + 8
2525
def ecode(:delete_fails), do: @default_base + 9
2626
def ecode(:create_fails), do: @default_base + 10
27+
def ecode(:exsit_pending_bill), do: @default_base + 11
28+
def ecode(:bill_state), do: @default_base + 12
29+
def ecode(:bill_action), do: @default_base + 13
2730
# throttle
2831
def ecode(:throttle_inverval), do: @throttle_base + 1
2932
def ecode(:throttle_hour), do: @throttle_base + 2

lib/helper/utils.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ defmodule Helper.Utils do
8484
Recursivly camelize the map keys
8585
usage: convert factory attrs to used for simu Graphql parmas
8686
"""
87-
def camelize_map_key(map) do
87+
def camelize_map_key(map, v_trans \\ :ignore) do
8888
map_list =
8989
Enum.map(map, fn {k, v} ->
9090
v =
@@ -95,6 +95,9 @@ defmodule Helper.Utils do
9595
is_map(v) ->
9696
camelize_map_key(safe_map(v))
9797

98+
is_binary(v) ->
99+
handle_camelize_value_trans(v, v_trans)
100+
98101
true ->
99102
v
100103
end
@@ -105,6 +108,10 @@ defmodule Helper.Utils do
105108
Enum.into(map_list, %{})
106109
end
107110

111+
defp handle_camelize_value_trans(v, :ignore), do: v
112+
defp handle_camelize_value_trans(v, :downcase), do: String.downcase(v)
113+
defp handle_camelize_value_trans(v, :upcase), do: String.upcase(v)
114+
108115
defp safe_map(%{__struct__: _} = map), do: Map.from_struct(map)
109116
defp safe_map(map), do: map
110117

lib/mastani_server/accounts/accounts.ex

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ defmodule MastaniServer.Accounts do
33

44
alias MastaniServer.Accounts.Delegate.{
55
Achievements,
6-
Billing,
76
Customization,
87
Fans,
98
FavoriteCategory,
@@ -61,15 +60,11 @@ defmodule MastaniServer.Accounts do
6160
defdelegate mark_mail_read_all(user, opt), to: Mails
6261
defdelegate mark_mail_read(mail, user), to: Mails
6362

64-
# purchase
65-
defdelegate purchase_service(user, key, value), to: Billing
66-
defdelegate purchase_service(user, key), to: Billing
67-
defdelegate has_purchased?(user, key), to: Billing
68-
6963
# customization
7064
defdelegate get_customization(user), to: Customization
7165
defdelegate set_customization(user, key, value), to: Customization
7266
defdelegate set_customization(user, options), to: Customization
67+
defdelegate upgrade_by_plan(user, plan), to: Customization
7368

7469
defdelegate search_users(args), to: Search
7570
end

lib/mastani_server/accounts/achievement.ex

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ defmodule MastaniServer.Accounts.Achievement do
44

55
use Ecto.Schema
66
import Ecto.Changeset
7+
78
alias MastaniServer.Accounts.{User, SourceContribute}
89

910
@required_fields ~w(user_id)a
10-
@optional_fields ~w(contents_stared_count contents_favorited_count contents_watched_count followers_count reputation)a
11+
@optional_fields ~w(contents_stared_count contents_favorited_count contents_watched_count followers_count reputation donate_member seninor_member sponsor_member)a
1112

1213
@type t :: %Achievement{}
1314
schema "user_achievements" do
@@ -21,6 +22,10 @@ defmodule MastaniServer.Accounts.Achievement do
2122
# source_contribute
2223
embeds_one(:source_contribute, SourceContribute, on_replace: :delete)
2324

25+
field(:donate_member, :boolean)
26+
field(:seninor_member, :boolean)
27+
field(:sponsor_member, :boolean)
28+
2429
timestamps(type: :utc_datetime)
2530
end
2631

lib/mastani_server/accounts/delegates/achievements.ex

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,16 @@ defmodule MastaniServer.Accounts.Delegate.Achievements do
9999
end
100100
end
101101

102-
# def achieve(%User{} = _user, :+, :watch) do
103-
# end
104-
105-
# def achieve(%User{} = _user, :+, key) do
106-
# end
102+
def set_member(%User{} = user, :donate), do: do_set_member(user, %{donate_member: true})
103+
def set_member(%User{} = user, :seninor), do: do_set_member(user, %{seninor_member: true})
104+
def set_member(%User{} = user, :sponsor), do: do_set_member(user, %{sponsor_member: true})
105+
def set_member(_user, _plan), do: {:error, "no such plan"}
107106

108-
# def achieve(%User{} = _user, :-, _key) do
109-
# end
107+
def do_set_member(%User{id: user_id}, attrs) do
108+
with {:ok, achievement} <- ORM.findby_or_insert(Achievement, ~m(user_id)a, ~m(user_id)a) do
109+
achievement |> ORM.update(attrs)
110+
end
111+
end
110112

111113
@doc """
112114
only used for user delete the farorited category, other case is auto

lib/mastani_server/accounts/delegates/billing.ex

Lines changed: 0 additions & 67 deletions
This file was deleted.

lib/mastani_server/accounts/delegates/customization.ex

Lines changed: 61 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,28 @@ defmodule MastaniServer.Accounts.Delegate.Customization do
77

88
alias Helper.ORM
99
alias MastaniServer.Accounts
10-
alias MastaniServer.Accounts.{User, Customization}
10+
11+
alias Accounts.{User, Customization}
12+
alias Accounts.Delegate.Achievements
1113

1214
@default_customization get_config(:customization, :all) |> Enum.into(%{})
1315

16+
def upgrade_by_plan(%User{} = user, :donate) do
17+
Achievements.set_member(user, :donate)
18+
end
19+
20+
def upgrade_by_plan(%User{} = user, :seninor) do
21+
Achievements.set_member(user, :seninor)
22+
end
23+
24+
def upgrade_by_plan(%User{} = user, :sponsor) do
25+
Achievements.set_member(user, :sponsor)
26+
end
27+
28+
def upgrade_by_plan(%User{} = _user, plan) do
29+
{:error, "no such plan"}
30+
end
31+
1432
@doc """
1533
get user's customization, if not have, return default customization
1634
"""
@@ -30,80 +48,63 @@ defmodule MastaniServer.Accounts.Delegate.Customization do
3048
"""
3149
# for map_size
3250
# see https://stackoverflow.com/questions/33248816/pattern-match-function-against-empty-map
51+
3352
def set_customization(%User{} = _user, map) when map_size(map) == 0 do
34-
{:error, "AccountCustomization: invalid option or not purchased"}
53+
{:error, "AccountCustomization: invalid option or not member"}
3554
end
3655

37-
def set_customization(%User{} = user, map) when is_map(map) do
38-
map = map |> map_atom_value(:string)
56+
def set_customization(%User{id: user_id} = user, map) when is_map(map) do
57+
with {:ok, %{achievement: achievement}} <- ORM.find(User, user_id, preload: :achievement) do
58+
map = map |> map_atom_value(:string)
3959

40-
valid? =
41-
map
42-
|> Map.keys()
43-
|> Enum.all?(&can_set?(user, &1, :boolean))
60+
valid? =
61+
map
62+
|> Map.keys()
63+
|> Enum.all?(&c11n_item_require?(&1, achievement))
4464

45-
case valid? do
46-
true ->
47-
attrs = Map.merge(%{user_id: user.id}, map)
48-
Customization |> ORM.upsert_by([user_id: user.id], attrs)
65+
case valid? do
66+
true ->
67+
attrs = Map.merge(%{user_id: user.id}, map)
68+
Customization |> ORM.upsert_by([user_id: user.id], attrs)
4969

50-
false ->
51-
{:error, "AccountCustomization: invalid option or not purchased"}
70+
false ->
71+
{:error, "AccountCustomization: invalid option or not member"}
72+
end
5273
end
5374
end
5475

5576
def set_customization(%User{} = user, key, value \\ true) do
56-
with {:ok, key} <- can_set?(user, key) do
57-
attrs = Map.put(%{user_id: user.id}, key, value)
58-
Customization |> ORM.upsert_by([user_id: user.id], attrs)
77+
with {:ok, %{achievement: achievement}} <- ORM.find(User, user.id, preload: :achievement) do
78+
case c11n_item_require?(key, achievement) do
79+
true ->
80+
attrs = Map.put(%{user_id: user.id}, key, value)
81+
Customization |> ORM.upsert_by([user_id: user.id], attrs)
82+
83+
false ->
84+
{:error, "AccountCustomization: invalid option or not member"}
85+
end
5986
end
6087
end
6188

62-
defp can_set?(%User{} = user, key, :boolean) do
63-
case can_set?(%User{} = user, key) do
64-
{:ok, _} -> true
65-
{:error, _} -> false
66-
end
89+
defp c11n_item_require?(:theme, %{
90+
donate_member: donate_member,
91+
seninor_member: seninor_member,
92+
sponsor_member: sponsor_member
93+
}) do
94+
donate_member or seninor_member or sponsor_member
6795
end
6896

69-
def can_set?(%User{} = user, key) do
70-
cond do
71-
key in valid_custom_items(:free) ->
72-
{:ok, key}
73-
74-
key in valid_custom_items(:advance) ->
75-
Accounts.has_purchased?(user, key)
76-
77-
true ->
78-
{:error, "AccountCustomization: invalid option"}
79-
end
80-
end
81-
82-
@doc """
83-
# theme -- user can set a default theme
84-
# sidebar_layout -- user can arrange subscribed community index
85-
"""
86-
def valid_custom_items(:free) do
87-
[
88-
:sidebar_layout,
89-
:sidebar_communities_index,
90-
:banner_layout,
91-
:contents_layout,
92-
:content_divider,
93-
:mark_viewed,
94-
:display_density
95-
]
96-
end
97-
98-
@doc """
99-
# :brainwash_free -- ads free
100-
# ::community_chart -- user can access comunity charts
101-
"""
102-
def valid_custom_items(:advance) do
103-
# NOTE: :brainwash_free aka. "ads_free"
104-
# use brainwash to avoid brower-block-plugins
105-
[:theme, :brainwash_free, :community_chart]
106-
end
97+
defp c11n_item_require?(:banner_layout, _), do: true
98+
defp c11n_item_require?(:contents_layout, _), do: true
99+
defp c11n_item_require?(:content_divider, _), do: true
100+
defp c11n_item_require?(:mark_viewed, _), do: true
101+
defp c11n_item_require?(:display_density, _), do: true
102+
defp c11n_item_require?(:sidebar_layout, _), do: true
103+
defp c11n_item_require?(:sidebar_communities_index, _), do: true
104+
# defp c11n_item_require?(:brainwash_free, _), do: true
105+
# defp c11n_item_require?(:community_chart, _), do: true
106+
107+
defp c11n_item_require?(_, _), do: false
107108

108109
defp filter_nil_value(map) do
109110
for {k, v} <- map, !is_nil(v), into: %{}, do: {k, v}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
defmodule MastaniServer.Billing.BillRecord do
2+
@moduledoc """
3+
bill records for investors
4+
"""
5+
alias __MODULE__
6+
7+
use Ecto.Schema
8+
import Ecto.Changeset
9+
10+
alias MastaniServer.Accounts
11+
12+
@required_fields ~w(user_id hash_id state amount payment_usage payment_method)a
13+
@optional_fields ~w(note)a
14+
15+
schema "bill_records" do
16+
belongs_to(:user, Accounts.User, foreign_key: :user_id)
17+
18+
field(:state, :string)
19+
field(:amount, :float)
20+
21+
field(:hash_id, :string)
22+
field(:payment_usage, :string)
23+
field(:payment_method, :string)
24+
25+
field(:note, :string)
26+
27+
timestamps(type: :utc_datetime)
28+
end
29+
30+
def changeset(%BillRecord{} = bill_record, attrs) do
31+
bill_record
32+
# |> cast(attrs, @optional_fields ++ @required_fields)
33+
|> cast(attrs, @required_fields ++ @optional_fields)
34+
|> validate_required(@required_fields)
35+
# |> validate_length(:title, min: 1, max: 30)
36+
|> foreign_key_constraint(:user_id)
37+
end
38+
39+
def state_changeset(bill_record, attrs) do
40+
bill_record
41+
|> cast(attrs, [:state])
42+
|> validate_required([:state])
43+
end
44+
end

0 commit comments

Comments
 (0)