defmodule DaProductApp.Seeds.TestData do @moduledoc """ Seeds the database with test data for YSP transaction processing. This creates: - Acquirer terminal configurations - Terminal STAN management records - Sample transaction data for testing """ alias DaProductApp.Repo alias DaProductApp.Acquirer.Schemas.{AcquirerTerminal, AcquirerTerminalStan, PosTempTransaction, PosTransaction} def seed_all do IO.puts("๐ŸŒฑ Starting database seeding for YSP testing...") # Seed in dependency order seed_acquirer_terminals() seed_terminal_stan_management() seed_sample_transactions() IO.puts("โœ… Database seeding completed!") end # ===================== # ACQUIRER TERMINALS # ===================== defp seed_acquirer_terminals do IO.puts("๐Ÿ“Ÿ Creating acquirer terminal configurations...") terminals = [ # YSP Test Terminal (matches the one from your log: 12345673) %{ tid: "12345673", # This matches your test transaction mid: "123456789012345", # This matches your test transaction acquirer_id: 1, # YSP acquirer terminal_name: "YSP Test Terminal 1", terminal_type: "POS", terminal_location: "Test Location 1", currency_code: "840", # USD country_code: "USA", mcc_code: "5411", # Grocery stores nii: "782", # YSP Network Identification Number fiid: "12345678901", application_type: "01", current_batch_no: "000001", batch_date: current_date(), batch_time: current_time(), max_batch_size: 1000, auto_settlement: true, settlement_time: "2300", key_set_id: "YSP001", pin_key: "1234567890ABCDEF1234567890ABCDEF", mac_key: "ABCDEF1234567890ABCDEF1234567890", data_key: "FEDCBA0987654321FEDCBA0987654321", max_transaction_amount: Decimal.new("10000.00"), daily_limit_amount: Decimal.new("50000.00"), daily_transaction_count: 0, max_daily_transactions: 500, status: "ACTIVE", last_settlement_date: current_date(), last_settlement_time: current_time(), last_logon_date: current_date(), last_logon_time: current_time(), supports_emv: true, supports_contactless: true, supports_pin: true, supports_signature: true, supports_cash_back: false, supports_tip: false, supports_partial_auth: false, network_config: Jason.encode!(%{ "timeout" => 30000, "retry_count" => 3, "connection_mode" => "sync" }), metadata: Jason.encode!(%{ "test_terminal" => true, "environment" => "development" }), created_by: "SEED_SCRIPT", updated_by: "SEED_SCRIPT", inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() }, # Additional test terminals %{ tid: "11111111", mid: "111111111111111", acquirer_id: 1, terminal_name: "YSP Test Terminal 2", terminal_type: "POS", terminal_location: "Test Location 2", currency_code: "840", country_code: "USA", mcc_code: "5812", # Eating establishments nii: "782", fiid: "11111111111", application_type: "01", current_batch_no: "000001", batch_date: current_date(), batch_time: current_time(), max_batch_size: 1000, auto_settlement: true, settlement_time: "2300", key_set_id: "YSP002", max_transaction_amount: Decimal.new("5000.00"), daily_limit_amount: Decimal.new("25000.00"), daily_transaction_count: 0, max_daily_transactions: 250, status: "ACTIVE", last_settlement_date: current_date(), last_settlement_time: current_time(), last_logon_date: current_date(), last_logon_time: current_time(), supports_emv: true, supports_contactless: true, supports_pin: true, supports_signature: true, supports_cash_back: true, supports_tip: true, supports_partial_auth: true, network_config: Jason.encode!(%{ "timeout" => 30000, "retry_count" => 3, "connection_mode" => "sync" }), metadata: Jason.encode!(%{ "test_terminal" => true, "environment" => "development" }), created_by: "SEED_SCRIPT", updated_by: "SEED_SCRIPT", inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() }, %{ tid: "22222222", mid: "222222222222222", acquirer_id: 1, terminal_name: "YSP Test Terminal 3", terminal_type: "ATM", terminal_location: "Test ATM Location", currency_code: "840", country_code: "USA", mcc_code: "6011", # ATM nii: "782", fiid: "22222222222", application_type: "02", current_batch_no: "000001", batch_date: current_date(), batch_time: current_time(), max_batch_size: 500, auto_settlement: true, settlement_time: "0100", key_set_id: "YSP003", max_transaction_amount: Decimal.new("1000.00"), daily_limit_amount: Decimal.new("10000.00"), daily_transaction_count: 0, max_daily_transactions: 100, status: "ACTIVE", supports_emv: false, supports_contactless: false, supports_pin: true, supports_signature: false, supports_cash_back: true, supports_tip: false, supports_partial_auth: false, network_config: Jason.encode!(%{ "timeout" => 45000, "retry_count" => 2, "connection_mode" => "sync" }), created_by: "SEED_SCRIPT", updated_by: "SEED_SCRIPT", inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() } ] Enum.each(terminals, fn terminal_attrs -> case Repo.get_by(AcquirerTerminal, tid: terminal_attrs.tid, acquirer_id: terminal_attrs.acquirer_id) do nil -> %AcquirerTerminal{} |> AcquirerTerminal.changeset(terminal_attrs) |> Repo.insert!() IO.puts(" โœ… Created terminal: #{terminal_attrs.tid} (#{terminal_attrs.terminal_name})") _existing -> IO.puts(" โญ๏ธ Terminal #{terminal_attrs.tid} already exists, skipping...") end end) end # ===================== # TERMINAL STAN MANAGEMENT # ===================== defp seed_terminal_stan_management do IO.puts("๐Ÿ”ข Creating terminal STAN management records...") stan_records = [ %{ tid: "12345673", acquirer_id: 1, current_stan: "000001", stan_date: current_date(), last_used_stan: "000000", last_reset_date: current_date(), last_reset_time: current_time(), max_stan_value: 999999, auto_reset_daily: true, reset_time: "0000", daily_transaction_count: 0, total_transaction_count: 0, last_transaction_date: current_date(), last_transaction_time: current_time(), rollover_count: 0, recovery_mode: false, duplicate_stan_count: 0, status: "ACTIVE", metadata: Jason.encode!(%{ "initialized_by" => "SEED_SCRIPT" }), inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() }, %{ tid: "11111111", acquirer_id: 1, current_stan: "000001", stan_date: current_date(), last_used_stan: "000000", last_reset_date: current_date(), last_reset_time: current_time(), max_stan_value: 999999, auto_reset_daily: true, reset_time: "0000", daily_transaction_count: 0, total_transaction_count: 0, status: "ACTIVE", inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() }, %{ tid: "22222222", acquirer_id: 1, current_stan: "000001", stan_date: current_date(), last_used_stan: "000000", last_reset_date: current_date(), last_reset_time: current_time(), max_stan_value: 999999, auto_reset_daily: true, reset_time: "0000", daily_transaction_count: 0, total_transaction_count: 0, status: "ACTIVE", inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now() } ] Enum.each(stan_records, fn stan_attrs -> case Repo.get_by(AcquirerTerminalStan, tid: stan_attrs.tid, acquirer_id: stan_attrs.acquirer_id) do nil -> %AcquirerTerminalStan{} |> AcquirerTerminalStan.changeset(stan_attrs) |> Repo.insert!() IO.puts(" โœ… Created STAN record for terminal: #{stan_attrs.tid}") _existing -> IO.puts(" โญ๏ธ STAN record for terminal #{stan_attrs.tid} already exists, skipping...") end end) end # ===================== # SAMPLE TRANSACTIONS # ===================== defp seed_sample_transactions do IO.puts("๐Ÿ’ณ Creating sample transaction data...") # Create some historical transactions for testing reversals sample_transactions = [ # Completed sale transaction (can be used for reversal testing) %{ s_tid: "12345673", s_mid: "123456789012345", s_tid_stan: "000100", total_amount: Decimal.new("25.50"), auth_amount: Decimal.new("25.50"), currency_code: "840", acquirer_id: 1, mti: "0200", proc_code: "000000", entry_mode: "051", condition_code: "00", approval_code: "123456", reference_no: "202312250001", response_code: "00", response_message: "APPROVED", masked_card_no: "4***********1234", metadata: Jason.encode!(%{ "test_transaction" => true, "created_for" => "reversal_testing" }), inserted_at: DateTime.add(DateTime.utc_now(), -3600, :second), # 1 hour ago updated_at: DateTime.add(DateTime.utc_now(), -3600, :second) }, # Another completed transaction %{ s_tid: "11111111", s_mid: "111111111111111", s_tid_stan: "000200", total_amount: Decimal.new("15.75"), auth_amount: Decimal.new("15.75"), currency_code: "840", acquirer_id: 1, mti: "0200", proc_code: "000000", entry_mode: "051", condition_code: "00", approval_code: "654321", reference_no: "202312250002", response_code: "00", response_message: "APPROVED", masked_card_no: "5***********5678", metadata: Jason.encode!(%{ "test_transaction" => true }), inserted_at: DateTime.add(DateTime.utc_now(), -1800, :second), # 30 minutes ago updated_at: DateTime.add(DateTime.utc_now(), -1800, :second) } ] Enum.each(sample_transactions, fn txn_attrs -> case Repo.get_by(PosTransaction, s_tid: txn_attrs.s_tid, s_tid_stan: txn_attrs.s_tid_stan) do nil -> %PosTransaction{} |> PosTransaction.changeset(txn_attrs) |> Repo.insert!() IO.puts(" โœ… Created sample transaction: #{txn_attrs.s_tid_stan} (#{txn_attrs.total_amount})") _existing -> IO.puts(" โญ๏ธ Transaction #{txn_attrs.s_tid_stan} already exists, skipping...") end end) # Create some pending temp transactions temp_transactions = [ %{ s_tid: "12345673", s_mid: "123456789012345", s_tid_stan: "000300", total_amount: Decimal.new("50.00"), currency_code: "840", acquirer_id: 1, mti: "0200", proc_code: "000000", entry_mode: "051", condition_code: "00", status: "PENDING", retry_count: 0, metadata: Jason.encode!(%{ "test_temp_transaction" => true, "status" => "awaiting_response" }), inserted_at: DateTime.add(DateTime.utc_now(), -300, :second), # 5 minutes ago updated_at: DateTime.add(DateTime.utc_now(), -300, :second) } ] Enum.each(temp_transactions, fn temp_attrs -> case Repo.get_by(PosTempTransaction, s_tid: temp_attrs.s_tid, s_tid_stan: temp_attrs.s_tid_stan) do nil -> %PosTempTransaction{} |> PosTempTransaction.changeset(temp_attrs) |> Repo.insert!() IO.puts(" โœ… Created temp transaction: #{temp_attrs.s_tid_stan} (#{temp_attrs.total_amount})") _existing -> IO.puts(" โญ๏ธ Temp transaction #{temp_attrs.s_tid_stan} already exists, skipping...") end end) end # ===================== # UTILITY FUNCTIONS # ===================== defp current_date do Date.utc_today() |> Date.to_string() |> String.replace("-", "") end defp current_time do Time.utc_now() |> Time.to_string() |> String.slice(0, 8) |> String.replace(":", "") end # ===================== # DATA CLEANUP # ===================== def clean_test_data do IO.puts("๐Ÿงน Cleaning up test data...") Repo.delete_all(PosTempTransaction) IO.puts(" โœ… Cleaned pos_temp_transaction table") Repo.delete_all(PosTransaction) IO.puts(" โœ… Cleaned pos_transaction table") Repo.delete_all(AcquirerTerminalStan) IO.puts(" โœ… Cleaned acquirer_terminal_stan table") Repo.delete_all(AcquirerTerminal) IO.puts(" โœ… Cleaned acquirer_terminal table") IO.puts("๐ŸŽฏ Test data cleanup completed!") end # ===================== # VERIFICATION # ===================== def verify_seed_data do IO.puts("๐Ÿ” Verifying seeded data...") terminal_count = Repo.aggregate(AcquirerTerminal, :count, :id) stan_count = Repo.aggregate(AcquirerTerminalStan, :count, :id) txn_count = Repo.aggregate(PosTransaction, :count, :id) temp_txn_count = Repo.aggregate(PosTempTransaction, :count, :id) IO.puts("๐Ÿ“Š Data Summary:") IO.puts(" โ€ข Acquirer Terminals: #{terminal_count}") IO.puts(" โ€ข STAN Records: #{stan_count}") IO.puts(" โ€ข Completed Transactions: #{txn_count}") IO.puts(" โ€ข Temp Transactions: #{temp_txn_count}") # Verify specific test terminal test_terminal = Repo.get_by(AcquirerTerminal, tid: "12345673", acquirer_id: 1) if test_terminal do IO.puts("โœ… Test terminal 12345673 is ready for testing!") IO.puts(" โ€ข Terminal Name: #{test_terminal.terminal_name}") IO.puts(" โ€ข Status: #{test_terminal.status}") IO.puts(" โ€ข MID: #{test_terminal.mid}") else IO.puts("โŒ Test terminal 12345673 not found!") end end end # Run the seeding if this file is executed directly if __name__ == "Elixir.DaProductApp.Seeds.TestData" do DaProductApp.Seeds.TestData.seed_all() DaProductApp.Seeds.TestData.verify_seed_data() end