add test email with job

parent ea4ef7f8
......@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Http\Support\ValidationRule;
use App\Jobs\SendMail;
use App\Models\Kegiatan;
use App\Models\KegiatanPeserta;
use App\Models\Konferensi;
......@@ -260,4 +261,12 @@ public function updatePembayaran(Request $request, $va)
'message' => 'success'
], 200);
}
public function testEmail(Request $request)
{
$data['registrasi'] = Registrasi::query()->where('kode_registrasi', '070300013')->first();
SendMail::dispatch($data, 'email.invoice', $data['registrasi']->email, 'registrasi', 'email_regis_sent_at');
}
}
<?php
namespace App\Jobs;
use App\Mailer\DynamicMailConfig;
use Carbon\Carbon;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
class SendMail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $data;
private $email;
private $view;
private $table;
private $field;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($data, $view, $email, $table = null, $field = null)
{
$this->data = $data;
$this->view = $view;
$this->email = $email;
$this->table = $table;
$this->field = $field;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try{
DynamicMailConfig::setConfig();
$email = $this->email;
// $email = 'iskandarjava@gmail.com';
Mail::send($this->view, $this->data, function ($message) use ($email){
$message->from('konaspi2024@unesa.ac.id', 'Universitas Negeri Surabaya');
$message->sender('konaspi2024@unesa.ac.id', 'Universitas Negeri Surabaya');
$message->subject('Pendaftaran KONASPI UNESA 2024');
$message->to($email, $email);
}
);
if($this->table && isset($this->data[$this->table])){
$field = $this->field;
$this->data[$this->table]->$field = Carbon::now();
$this->data[$this->table]->save();
}
}
catch(Exception $ex){
Log::debug($ex);
}
}
}
<?php
namespace App\Mailer;
use App\Models\Sender;
use Illuminate\Support\Facades\Config;
use Swift_SmtpTransport;
use Illuminate\Support\Facades\Mail;
class DynamicMailConfig
{
public static function setConfig()
{
$email = DynamicMailConfig::getEmailSender();
Config::set('mail.mailers.smtp.username', $email->address);
Config::set('mail.mailers.smtp.password', $email->password);
}
public static function getEmailSender()
{
$email = Sender::query()->orderBy('count', 'asc')->first();
$count = $email->count + 1;
$email->update([
'count' => $count,
]);
return $email;
}
}
<?php
namespace App\Mailer;
use Illuminate\Support\Facades\App;
class DynamicMailer
{
public static function getMailer()
{
$mailConfig = DynamicMailConfig::getConfig();
$mailerManager = new DynamicMailerManager(App::getInstance());
$mailer = $mailerManager->getMailer($mailConfig);
return $mailer;
}
}
<?php
namespace App\Mailer;
use Illuminate\Mail\TransportManager;
use Illuminate\Support\Facades\Config;
use Swift_DependencyContainer;
use Swift_Mailer;
class DynamicMailerManager
{
public function __construct($app)
{
$this->app = $app;
}
protected function registerSwiftTransport()
{
$this->app->singleton('swift.transport', function () {
return new TransportManager($this->app);
});
}
protected function registerSwiftMailer()
{
$this->registerSwiftTransport();
// Once we have the transporter registered, we will register the actual Swift
// mailer instance, passing in the transport instances, which allows us to
// override this transporter instances during app start-up if necessary.
$this->app->singleton('swift.mailer', function () {
if ($domain = $this->app->make('config')->get('mail.domain')) {
Swift_DependencyContainer::getInstance()
->register('mime.idgenerator.idright')
->asValue($domain);
}
return new Swift_Mailer($this->app['swift.transport']->driver());
});
}
public function getMailer($mailConfig)
{
Config::set($mailConfig);
$this->registerSwiftMailer();
return $this->app['swift.mailer'];
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Sender extends Model
{
protected $table = 'sender';
protected $fillable = ['address', 'password', 'count'];
public $timestamps = false;
}
......@@ -11,7 +11,8 @@
"laravel/jetstream": "^4.3",
"laravel/sanctum": "^3.3",
"laravel/tinker": "^2.8",
"realrashid/sweet-alert": "^7.1"
"realrashid/sweet-alert": "^7.1",
"symfony/mailer": "^6.4"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.9",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "54aa44989d5af68c8318f783793db792",
"content-hash": "a2dc299bed15dcc9e432e1424cb8d1f1",
"packages": [
{
"name": "bacon/bacon-qr-code",
......@@ -4407,16 +4407,16 @@
},
{
"name": "symfony/mailer",
"version": "v6.4.3",
"version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee"
"reference": "791c5d31a8204cf3db0c66faab70282307f4376b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/74412c62f88a85a41b61f0b71ab0afcaad6f03ee",
"reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee",
"url": "https://api.github.com/repos/symfony/mailer/zipball/791c5d31a8204cf3db0c66faab70282307f4376b",
"reference": "791c5d31a8204cf3db0c66faab70282307f4376b",
"shasum": ""
},
"require": {
......@@ -4467,7 +4467,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v6.4.3"
"source": "https://github.com/symfony/mailer/tree/v6.4.4"
},
"funding": [
{
......@@ -4483,7 +4483,7 @@
"type": "tidelift"
}
],
"time": "2024-01-29T15:01:07+00:00"
"time": "2024-02-03T21:33:47+00:00"
},
{
"name": "symfony/mime",
......@@ -8812,5 +8812,5 @@
"php": "^8.1"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.3.0"
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('jobs');
}
};
@extends('layouts.blank')
@section('title','Invoice')
@section('content')
<section class="section">
<div class="section-header">
<h1>Invoice</h1>
<div class="section-header-breadcrumb">
<div class="breadcrumb-item"><a href="/">Dashboard</a></div>
<div class="breadcrumb-item"><a href="">Data Registrasi</a></div>
<div class="breadcrumb-item active">Invoice</div>
</div>
</div>
<form novalidate="" method="POST" action="{{ route('user.store') ?? 'param' }}" enctype="multipart/form-data">
@csrf
<div class="section-body">
<div class="invoice">
<div class="invoice-print">
<div class="row">
<div class="col-lg-12">
<div class="invoice-title">
<h2>Invoice</h2>
<div class="invoice-number">No. Transaksi #{{$registrasi['kode_registrasi'] ?? 'param' }}</div>
</div>
<hr>
<div class="row" style="font-size: 12pt">
<div class="col-md-6">
<address>
<strong>Identitas:</strong><br>
{{$registrasi['nama'] ?? 'param' }}<br>
{{$registrasi['alamat'] ?? 'param' }}<br>
{{$registrasi['telepon'] ?? 'param' }}<br>
</address>
</div>
<div class="col-md-6 text-md-right">
<address>
<strong>Instansi:</strong><br>
{{$registrasi['instansi'] ?? 'param' }}<br>
</address>
</div>
</div>
<div class="row" style="font-size: 12pt">
<div class="col-md-6">
<address>
<strong>Metode Pembayaran:</strong><br>
Virtual Account : {{$registrasi['kode_registrasi'] ?? 'param' }}<br>
{{-- {{$registrasi['email'] ?? 'param' }} --}}
</address>
</div>
<div class="col-md-6 text-md-right">
<address>
<strong>Tanggal Registrasi:</strong><br>
{{$tglRegistrasi ?? 'param' }}<br><br>
</address>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12" style="font-size: 12pt">
<div class="section-title">Rincian</div>
<p class="section-lead">Rincian registrasi sudah tidak bisa diubah</p>
<div class="table-responsive">
<table class="table table-striped table-hover table-md">
<tr>
<th data-width="40">#</th>
<th>Kegiatan</th>
<th class="text-center">Harga</th>
<th class="text-center">Jumlah</th>
<th class="text-right">Total Harga</th>
</tr>
@php
$no = 2;
$initialharga = $konaspi->harga ?? 0;
$subtotal = $initialharga;
$i = 0;
@endphp
<tr>
<td>1</td>
<td>
Convention
</td>
<td class="text-center">Rp {{$konaspi->harga ?? 'param' }}</td>
<td class="text-center">1</td>
<td class="text-right">Rp {{$konaspi->harga ?? 'param' }}</td>
</tr>
@if (isset($hargaKonferensi))
@foreach ($hargaKonferensi as $kon)
@php
$subtotal = $subtotal + $kon['hargakon'];
@endphp
<tr>
<td>{{$no ?? 'param' }}</td>
<td>
{{$kon['namakeg'] ?? 'param' }} <br> Konferensi : <b> {{$kon['namakon'] ?? 'param' }} </b>
</td>
<td class="text-center">Rp {{$kon['hargakon'] ?? 'param' }}</td>
<td class="text-center">1</td>
<td class="text-right">Rp {{$kon['hargakon'] ?? 'param' }}</td>
</tr>
@php
$i++;
$no++;
@endphp
@endforeach
@endif
</table>
</div>
<div class="row mt-4">
<div class="col-lg-8">
<div class="section-title">Metode Pembayaran</div>
<p class="section-lead" style="font-size: 12pt">Setelah menekan tombol bayar, maka data akan tersimpan dan lakukan pembayaran tagihan menggunakan <b>Nomor Virtual Account</b> yang tertera pada <b>Invoice</b> ini</p>
{{-- <div class="d-flex">
<div class="mr-2 bg-visa" data-width="61" data-height="38"></div>
<div class="mr-2 bg-jcb" data-width="61" data-height="38"></div>
<div class="mr-2 bg-mastercard" data-width="61" data-height="38"></div>
<div class="bg-paypal" data-width="61" data-height="38"></div>
</div> --}}
</div>
<div class="col-lg-4 text-right">
<div class="invoice-detail-item">
<div class="invoice-detail-name">Subtotal</div>
<div class="invoice-detail-value">Rp {{$subtotal ?? 'param' }}</div>
</div>
<hr class="mt-2 mb-2">
<div class="invoice-detail-item">
<div class="invoice-detail-name">Total</div>
<div class="invoice-detail-value invoice-detail-value-lg">Rp {{$subtotal ?? 'param' }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="text-md-right">
{{-- <div class="float-lg-left mb-lg-0 mb-3">
<button class="btn btn-primary btn-icon icon-left"><i class="fas fa-credit-card"></i> Bayar</button>
<button class="btn btn-danger btn-icon icon-left"><i class="fas fa-times"></i> Cancel</button>
</div> --}}
{{-- <button class="btn btn-warning btn-icon icon-left"><i class="fas fa-print"></i> Cetak</button> --}}
@if (isset($registrasi) && isset($kegiatanpeserta) && isset($tglRegistrasi) && isset($konaspi) && isset($hargaKonferensi) && isset($totalHarga))
<input type="hidden" id="registrasi" name="registrasi" value="{{ json_encode($registrasi) ?? 'param' }}">
<input type="hidden" id="kegiatanpeserta" name="kegiatanpeserta" value="{{ json_encode($kegiatanpeserta) ?? 'param' }}">
<input type="hidden" id="tglRegistrasi" name="tglRegistrasi" value="{{ json_encode($tglRegistrasi) ?? 'param' }}">
<input type="hidden" id="konaspi" name="konaspi" value="{{ json_encode($konaspi) ?? 'param' }}">
<input type="hidden" id="hargaKonferensi" name="hargaKonferensi" value="{{ json_encode($hargaKonferensi) ?? 'param' }}">
<input type="hidden" id="totalHarga" name="totalHarga" value="{{ json_encode($totalHarga) ?? 'param' }}">
<button type="submit" class="btn btn-primary btn-icon icon-left"><i class="fas fa-credit-card"></i> Bayar</button>
<button class="btn btn-danger btn-icon icon-left"><i class="fas fa-times"></i> Cancel</button>
@endif
</div>
</div>
</div>
</form>
</section>
@endsection
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no" name="viewport">
<title>@yield('title') - KONASPI XI 2024</title>
<!-- General CSS Files -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<!-- CSS Libraries -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="{{asset('node_modules/bootstrap-daterangepicker/daterangepicker.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/select2/dist/css/select2.min.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/selectric/public/selectric.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/bootstrap-timepicker/css/bootstrap-timepicker.min.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/prismjs/themes/prism.css')}}">
<link rel="stylesheet" href="{{asset('node_modules/izitoast/dist/css/iziToast.min.css')}}">
<link rel="stylesheet" href="{{asset('assets/modules/datatables/datatables.min.css')}}">
<link rel="stylesheet" href="{{asset('assets/modules/datatables/DataTables-1.10.16/css/dataTables.bootstrap4.min.css')}}">
<link rel="stylesheet" href="{{asset('assets/modules/datatables/Select-1.2.4/css/select.bootstrap4.min.css')}}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/izitoast/1.4.0/css/iziToast.min.css">
<!-- Template CSS -->
<link rel="stylesheet" href="{{asset('assets/css/style.css')}}">
<link rel="stylesheet" href="{{asset('assets/css/components.css')}}">
<!-- Sweet Alert -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.9/sweetalert2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.9/sweetalert2.min.js"></script>
</head>
<body>
<div id="app">
<div class="main-wrapper">
<div class="navbar-bg"></div>
<!-- Main Content -->
<div class="main-content" style="padding-left: 30px">
@yield('content')
</div>
<footer class="main-footer">
@include('layouts.footer')
</footer>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- General JS Scripts -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.nicescroll/3.7.6/jquery.nicescroll.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://kit.fontawesome.com/87106ec61e.js" crossorigin="anonymous"></script>
<script src="{{asset('assets/js/stisla.js')}}"></script>
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
<!-- JS Libraies -->
{{-- <script src="{{asset('node_modules/cleave.js/dist/cleave.min.js')}}"></script> --}}
{{-- <script src="{{asset('node_modules/cleave.js/dist/addons/cleave-phone.us.js')}}"></script> --}}
<script src="{{asset('node_modules/jquery-pwstrength/jquery.pwstrength.min.js')}}"></script>
<script src="{{asset('node_modules/bootstrap-daterangepicker/daterangepicker.js')}}"></script>
<script src="{{asset('node_modules/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js')}}"></script>
<script src="{{asset('node_modules/bootstrap-timepicker/js/bootstrap-timepicker.min.js')}}"></script>
<script src="{{asset('node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js')}}"></script>
<script src="{{asset('node_modules/select2/dist/js/select2.full.min.js')}}"></script>
<script src="{{asset('node_modules/selectric/public/jquery.selectric.min.js')}}"></script>
<script src="{{asset('node_modules/sweetalert/dist/sweetalert.min.js')}}"></script>
<script src="{{asset('node_modules/prismjs/prism.js')}}"></script>
<script src="{{asset('node_modules/izitoast/dist/js/iziToast.min.js')}}"></script>
<script src="{{asset('assets/modules/datatables/datatables.min.js')}}"></script>
<script src="{{asset('assets/modules/datatables/DataTables-1.10.16/js/dataTables.bootstrap4.min.js')}}"></script>
<script src="{{asset('assets/modules/datatables/Select-1.2.4/js/dataTables.select.min.js')}}"></script>
<!-- Template JS File -->
<script src="{{asset('assets/js/scripts.js')}}"></script>
<script src="{{asset('assets/js/custom.js')}}"></script>
<!-- Page Specific JS File -->
{{-- <script src="{{asset('assets/js/page/forms-advanced-forms.js')}}"></script> --}}
<script src="{{asset('assets/js/page/bootstrap-modal.js')}}"></script>
<script src="{{asset('assets/js/page/modules-toastr.js')}}"></script>
<script src="{{asset('assets/js/page/modules-datatables.js')}}"></script>
@stack('js')
</body>
</html>
<?php
use App\Http\Controllers\RegistrasiController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
......@@ -17,3 +18,5 @@
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('/update-pembayaran/{va}', [RegistrasiController::class, 'updatePembayaran']);
......@@ -45,3 +45,4 @@
Route::get('check-invoice', function(Request $request){
return view('email.invoice');
});
Route::get('test/email', [RegistrasiController::class, 'testEmail']);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment