| 1 |
|
defmodule DaProductApp.Partners.Merchant do |
| 2 |
|
@moduledoc """ |
| 3 |
|
Merchant schema representing stores/businesses enrolled under partners. |
| 4 |
|
|
| 5 |
|
Merchants are the actual stores/businesses where customers make payments. |
| 6 |
|
Each merchant belongs to a partner (acquirer/aggregator). |
| 7 |
|
""" |
| 8 |
|
use Ecto.Schema |
| 9 |
|
import Ecto.Changeset |
| 10 |
|
|
| 11 |
|
@primary_key {:id, :binary_id, autogenerate: true} |
| 12 |
|
@foreign_key_type :binary_id |
| 13 |
|
|
| 14 |
:-( |
schema "merchants" do |
| 15 |
|
field :merchant_code, :string # Unique merchant identifier |
| 16 |
|
field :brand_name, :string # Business name |
| 17 |
|
field :merchant_vpa, :string # UPI VPA (e.g., merchant@partner) |
| 18 |
|
field :business_type, :string # "RETAIL", "ECOMMERCE", "SERVICES" |
| 19 |
|
field :business_category, :string # "GROCERY", "RESTAURANT", "PHARMACY" |
| 20 |
|
field :static_qr_code, :string # Static QR for the merchant |
| 21 |
|
field :qr_enabled, :boolean, default: true |
| 22 |
|
field :dynamic_qr_enabled, :boolean, default: false |
| 23 |
|
field :max_transaction_limit, :decimal |
| 24 |
|
field :daily_transaction_limit, :decimal |
| 25 |
|
field :settlement_frequency, :string, default: "T+1" # "T+0", "T+1", "WEEKLY" |
| 26 |
|
field :settlement_account_intl, :string # Merchant's bank account |
| 27 |
|
field :contact_person, :string |
| 28 |
|
field :contact_email, :string |
| 29 |
|
field :contact_phone, :string |
| 30 |
|
field :address, :string |
| 31 |
|
field :city, :string |
| 32 |
|
field :state, :string |
| 33 |
|
field :pincode, :string |
| 34 |
|
field :gstin, :string # GST identification number |
| 35 |
|
field :pan, :string # PAN card number |
| 36 |
|
field :intl_status, :string, default: "ACTIVE" # "ACTIVE", "SUSPENDED", "INACTIVE" |
| 37 |
|
field :onboarded_at, :utc_datetime |
| 38 |
|
field :last_transaction_at, :utc_datetime |
| 39 |
|
|
| 40 |
|
belongs_to :partner, DaProductApp.Partners.Partner |
| 41 |
|
has_many :transactions, DaProductApp.Transactions.Transaction |
| 42 |
|
|
| 43 |
|
timestamps(type: :utc_datetime) |
| 44 |
|
end |
| 45 |
|
|
| 46 |
|
def changeset(merchant, attrs) do |
| 47 |
|
merchant |
| 48 |
|
|> cast(attrs, [ |
| 49 |
|
:merchant_code, :merchant_name, :merchant_vpa, :business_type, |
| 50 |
|
:business_category, :static_qr_code, :qr_enabled, :dynamic_qr_enabled, |
| 51 |
|
:max_transaction_limit, :daily_transaction_limit, :settlement_frequency, |
| 52 |
|
:settlement_account, :contact_person, :contact_email, :contact_phone, |
| 53 |
|
:address, :city, :state, :pincode, :gstin, :pan, :status, |
| 54 |
|
:onboarded_at, :last_transaction_at, :partner_id |
| 55 |
|
]) |
| 56 |
|
|> validate_required([:merchant_code, :merchant_name, :merchant_vpa, :partner_id]) |
| 57 |
|
|> validate_inclusion(:business_type, ["RETAIL", "ECOMMERCE", "SERVICES"]) |
| 58 |
|
|> validate_inclusion(:settlement_frequency, ["T+0", "T+1", "WEEKLY"]) |
| 59 |
|
|> validate_inclusion(:status, ["ACTIVE", "SUSPENDED", "INACTIVE"]) |
| 60 |
|
|> validate_format(:contact_email, ~r/@/) |
| 61 |
|
|> validate_format(:merchant_vpa, ~r/^[\w\.-]+@[\w\.-]+$/) |
| 62 |
|
|> unique_constraint(:merchant_code) |
| 63 |
:-( |
|> unique_constraint(:merchant_vpa) |
| 64 |
|
end |
| 65 |
|
end |