| @@ -2,10 +2,11 @@ | |||
| namespace App\Console\Commands; | |||
| use App\Files\TmpFile; | |||
| use App\Logic\EmailManager; | |||
| use App\Mail\Test; | |||
| use App\Email\Test; | |||
| class TestMail extends BaseCommand | |||
| class TestEmail extends BaseCommand | |||
| { | |||
| const COMMAND = "mail:test {email}"; | |||
| @@ -49,11 +50,17 @@ class TestMail extends BaseCommand | |||
| { | |||
| $email = $this->argument('email'); | |||
| $file = new TmpFile(); | |||
| $file->put("iwabuchi text"); | |||
| $mailer = new Test(); | |||
| $mailer->setEmail($email); | |||
| $manager = new EmailManager($mailer); | |||
| $manager->confirm(); | |||
| $manager | |||
| ->attach($file->getFullPath(), "test.txt", "text/plain") | |||
| ->confirm(); | |||
| return self::RESULTCODE_SUCCESS; | |||
| } | |||
| @@ -1,18 +1,20 @@ | |||
| <?php | |||
| namespace App\Mail; | |||
| namespace App\Email; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Models\Email; | |||
| use App\Models\EmailAttachment; | |||
| use App\Models\User; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Bus\Queueable; | |||
| use Illuminate\Database\Eloquent\Collection; | |||
| use Illuminate\Mail\Mailable; | |||
| use Illuminate\Queue\SerializesModels; | |||
| use Illuminate\Support\Facades\Mail; | |||
| use Illuminate\Support\Str; | |||
| abstract class BaseMailer extends Mailable | |||
| abstract class BaseEmailer extends Mailable | |||
| { | |||
| use Queueable, SerializesModels; | |||
| @@ -26,6 +28,11 @@ abstract class BaseMailer extends Mailable | |||
| protected string|null $__contractId = null; | |||
| protected string|null $__receiptIssuingOrderId = null; | |||
| /** | |||
| * 添付ファイル | |||
| * @var Collection<int, EmailAttachment>|null | |||
| */ | |||
| protected ?Collection $__attachments = null; | |||
| public function sendEmail(string $email) | |||
| { | |||
| @@ -67,9 +74,25 @@ abstract class BaseMailer extends Mailable | |||
| public function build() | |||
| { | |||
| return $this->text($this->getTemplateName()) | |||
| $this->text($this->getTemplateName()) | |||
| ->subject($this->getSubject()) | |||
| ->with($this->getParams()); | |||
| // 添付ファイル処理 | |||
| if ($this->__attachments !== null) { | |||
| $count = $this->__attachments->count(); | |||
| foreach ($this->__attachments as $attachment) { | |||
| $filepath = $attachment->filepath; | |||
| $as = $attachment->send_filename; | |||
| $mime = $attachment->mime; | |||
| $this->attach($filepath, [ | |||
| 'as' => $as, | |||
| 'mime' => $mime, | |||
| ]); | |||
| } | |||
| } | |||
| return $this; | |||
| } | |||
| public function setConfigDefault() | |||
| @@ -1,10 +1,10 @@ | |||
| <?php | |||
| namespace App\Mail\Guests; | |||
| namespace App\Email\Guests; | |||
| use App\Mail\BaseMailer; | |||
| use App\Email\BaseEmailer; | |||
| abstract class Guest extends BaseMailer | |||
| abstract class Guest extends BaseEmailer | |||
| { | |||
| public function getParams(): array | |||
| { | |||
| @@ -0,0 +1,38 @@ | |||
| <?php | |||
| namespace App\Email\Guests; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use Illuminate\Support\Carbon; | |||
| class ReceiptA4 extends Guest | |||
| { | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(private ReceiptIssuingOrder $order) | |||
| { | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.guests.receipt_a4'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '領収証の送付'; | |||
| } | |||
| public function getGuestParams(): array | |||
| { | |||
| return [ | |||
| 'shopName' => $this->order->receipt_shop_name, | |||
| 'useDate' => $this->order->receipt_use_date->format('Y/m/d'), | |||
| 'amount' => number_format($this->order->receipt_amount), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,8 +1,7 @@ | |||
| <?php | |||
| namespace App\Mail; | |||
| namespace App\Email; | |||
| use App\Middlewares\Now; | |||
| use App\Models\Email; | |||
| use App\Util\DateUtil; | |||
| use Exception; | |||
| @@ -24,7 +23,7 @@ class Sender | |||
| try { | |||
| Mail::to($email->email) | |||
| ->send(new TextMail($email->subject, $email->content)); | |||
| ->send(new TextEmail($email->subject, $email->content, $email->emailAttachments)); | |||
| } catch (Exception $e) { | |||
| Log::error("メール送信失敗", [ | |||
| 'id' => $email->id, | |||
| @@ -1,8 +1,8 @@ | |||
| <?php | |||
| namespace App\Mail; | |||
| namespace App\Email; | |||
| class Test extends BaseMailer | |||
| class Test extends BaseEmailer | |||
| { | |||
| public function getTemplateName(): string | |||
| { | |||
| @@ -1,21 +1,24 @@ | |||
| <?php | |||
| namespace App\Mail; | |||
| namespace App\Email; | |||
| use Illuminate\Bus\Queueable; | |||
| use Illuminate\Database\Eloquent\Collection; | |||
| use Illuminate\Queue\SerializesModels; | |||
| class TextMail extends BaseMailer | |||
| class TextEmail extends BaseEmailer | |||
| { | |||
| use Queueable, SerializesModels; | |||
| private string $__subject; | |||
| private string $__contents; | |||
| public function __construct(string $subject, string $contents) | |||
| public function __construct(string $subject, string $contents, ?Collection $attachments = null) | |||
| { | |||
| $this->__subject = $subject; | |||
| $this->__contents = $contents; | |||
| $this->__attachments = $attachments; | |||
| } | |||
| public function getTemplateName(): string | |||
| @@ -1,10 +1,12 @@ | |||
| <?php | |||
| namespace App\Events\Mail; | |||
| namespace App\Events\Email; | |||
| use App\Mail\BaseMailer; | |||
| use App\Email\BaseEmailer; | |||
| use App\Models\Email; | |||
| use App\Models\EmailAttachment; | |||
| use Illuminate\Broadcasting\InteractsWithSockets; | |||
| use Illuminate\Database\Eloquent\Collection; | |||
| use Illuminate\Foundation\Events\Dispatchable; | |||
| use Illuminate\Queue\SerializesModels; | |||
| @@ -19,7 +21,7 @@ class ConfirmEvent | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(Email|BaseMailer $email) | |||
| public function __construct(Email|BaseEmailer $email, ?Collection $attachments = null) | |||
| { | |||
| if ($email instanceof Email) { | |||
| $this->email = $email; | |||
| @@ -27,5 +29,14 @@ class ConfirmEvent | |||
| $this->email = $email->makeModel(); | |||
| $this->email->save(); | |||
| } | |||
| if ($attachments !== null) { | |||
| foreach ($attachments as $attachment) { | |||
| if (!($attachment instanceof EmailAttachment)) continue; | |||
| $emailId = $this->email->id; | |||
| $attachment->email_id = $emailId; | |||
| $attachment->save(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| <?php | |||
| namespace App\Events\ReceiptIssuingOrder; | |||
| /** | |||
| * Email送付依頼イベント | |||
| */ | |||
| class EmailOrderEvent extends ReceiptIssuingOrderEvent | |||
| { | |||
| public function getEventName(): string | |||
| { | |||
| return "Email送付依頼"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| <?php | |||
| namespace App\Files\PDF\Receipt; | |||
| use App\Files\TmpFile; | |||
| class A4Receipt extends TmpFile | |||
| { | |||
| protected const DIR = ['receipt_pdf']; | |||
| /** | |||
| * @override | |||
| */ | |||
| protected function getFileTypeName(): string | |||
| { | |||
| return "A4Receipt"; | |||
| } | |||
| /** | |||
| * @override | |||
| */ | |||
| protected function getFileExtension(): string | |||
| { | |||
| return "pdf"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,54 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\ReceiptIssuingOrder; | |||
| use App\Http\Controllers\Web\IParam; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Logic\ReceiptIssuingOrder\Custom\HelloTechno\PDFDownLoadManagerHelloTechno; | |||
| use App\Logic\ReceiptIssuingOrder\UpdateManager; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| class EmailOrderController extends WebController | |||
| { | |||
| public function name(): string | |||
| { | |||
| return "領収証Email送付依頼"; | |||
| } | |||
| public function description(): string | |||
| { | |||
| return "領収証をEmail送付依頼を登録する"; | |||
| } | |||
| public function __construct( | |||
| protected EmailOrderParam $param, | |||
| private UpdateManager $manager, | |||
| private PDFDownLoadManagerHelloTechno $pdf, | |||
| ) { | |||
| parent::__construct(); | |||
| } | |||
| protected function getParam(): IParam | |||
| { | |||
| return $this->param; | |||
| } | |||
| protected function run(Request $request): JsonResponse | |||
| { | |||
| $param = $this->param; | |||
| $file = $this->pdf->initByToken($param->accessToken) | |||
| ->checkTimestamp($param->timestamp) | |||
| ->getA4File(); | |||
| $this->manager->initByToken($param->accessToken) | |||
| ->checkTimestamp($param->timestamp) | |||
| ->emailOrder($param->email, $file) | |||
| ->update(); | |||
| return $this->successResponse(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\ReceiptIssuingOrder; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| use App\Http\Controllers\Web\Rule; | |||
| use App\Http\Controllers\Web\TimestampParam; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| /** | |||
| * @property string $accessToken | |||
| * @property string $email | |||
| */ | |||
| class EmailOrderParam extends BaseParam implements TimestampParam | |||
| { | |||
| public function rules(): array | |||
| { | |||
| return array_merge( | |||
| [ | |||
| ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN => $this->str(), | |||
| ReceiptIssuingOrder::COL_NAME_EMAIL => $this->str([...Rule::email()]), | |||
| ], | |||
| $this->timestamp(), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web; | |||
| abstract class Rule | |||
| { | |||
| public static function email(): array | |||
| { | |||
| $ret = []; | |||
| $ret[] = "email:strict,filter,dns"; | |||
| $ret[] = "max:255"; | |||
| return $ret; | |||
| } | |||
| } | |||
| @@ -1,9 +1,9 @@ | |||
| <?php | |||
| namespace App\Jobs\Mail; | |||
| namespace App\Jobs\Email; | |||
| use App\Codes\QueueName; | |||
| use App\Mail\Sender; | |||
| use App\Email\Sender; | |||
| use App\Models\Email; | |||
| use Illuminate\Bus\Queueable; | |||
| use Illuminate\Contracts\Queue\ShouldQueue; | |||
| @@ -11,7 +11,7 @@ use Illuminate\Foundation\Bus\Dispatchable; | |||
| use Illuminate\Queue\InteractsWithQueue; | |||
| use Illuminate\Queue\SerializesModels; | |||
| class SimpleMail implements ShouldQueue | |||
| class SimpleEmail implements ShouldQueue | |||
| { | |||
| use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |||
| @@ -0,0 +1,78 @@ | |||
| <?php | |||
| namespace App\Jobs\ReceiptIssuingOrder; | |||
| use App\Codes\QueueName; | |||
| use App\Models\Email; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Bus\Queueable; | |||
| use Illuminate\Contracts\Queue\ShouldQueue; | |||
| use Illuminate\Foundation\Bus\Dispatchable; | |||
| use Illuminate\Queue\InteractsWithQueue; | |||
| use Illuminate\Queue\SerializesModels; | |||
| use Illuminate\Support\Carbon; | |||
| use Illuminate\Support\Facades\Log; | |||
| class PollEmailSendStatus implements ShouldQueue | |||
| { | |||
| use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |||
| private int $currentRetryCount; | |||
| /** | |||
| * Create a new job instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct( | |||
| private ReceiptIssuingOrder $order, | |||
| ) { | |||
| $this->onQueue(QueueName::JOB->value); | |||
| } | |||
| /** | |||
| * Execute the job. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function handle() | |||
| { | |||
| info("領収証Emailポーリング:" . $this->order->receipt_pdf_email_id); | |||
| $email = Email::findOrFail($this->order->receipt_pdf_email_id); | |||
| $sendDatetime = $email->send_datetime; | |||
| if ($email->send_datetime !== null) { | |||
| // ポーリング終了 | |||
| $this->donePolling($sendDatetime); | |||
| } else if ($email->is_failed) { | |||
| // ポーリング終了 | |||
| $this->donePolling($sendDatetime); | |||
| } else { | |||
| $limit = $this->order->status_receipt_email_send_order_datetime->clone()->addDays(3); | |||
| if (DateUtil::now()->gt($limit)) { | |||
| // ポーリング終了(未完了) | |||
| $this->donePolling($sendDatetime); | |||
| Log::warning("領収証Email送信未完了検知 OrderID:%s", $this->order->id); | |||
| } else { | |||
| // ポーリング継続 | |||
| $this->continuePolling(); | |||
| } | |||
| } | |||
| } | |||
| private function donePolling(Carbon $sendDatetime) | |||
| { | |||
| $this->order->status_receipt_email_send_datetime = $sendDatetime; | |||
| $this->order->save(); | |||
| info("領収証Emailポーリング完了:" . $this->order->receipt_pdf_email_id); | |||
| } | |||
| private function continuePolling() | |||
| { | |||
| static::dispatch($this->order) | |||
| ->delay(DateUtil::now()->addMinutes(5)); | |||
| info("領収証Emailポーリング継続:" . $this->order->receipt_pdf_email_id); | |||
| } | |||
| } | |||
| @@ -1,12 +1,12 @@ | |||
| <?php | |||
| namespace App\Listeners\Mail; | |||
| namespace App\Listeners\Email; | |||
| use App\Events\Mail\ConfirmEvent; | |||
| use App\Jobs\Mail\SimpleMail; | |||
| use App\Events\Email\ConfirmEvent; | |||
| use App\Jobs\Email\SimpleEmail; | |||
| use App\Util\DateUtil; | |||
| class MailSendJobRegister | |||
| class EmailSendJobRegister | |||
| { | |||
| /** | |||
| @@ -30,7 +30,8 @@ class MailSendJobRegister | |||
| $email->confirm_datetime = DateUtil::now(); | |||
| $email->save(); | |||
| SimpleMail::dispatch($event->email); | |||
| SimpleEmail::dispatch($event->email); | |||
| } | |||
| } | |||
| } | |||
| @@ -2,11 +2,13 @@ | |||
| namespace App\Logic; | |||
| use App\Events\Mail\ConfirmEvent; | |||
| use App\Events\Email\ConfirmEvent; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Mail\BaseMailer; | |||
| use App\Email\BaseEmailer; | |||
| use App\Models\Email; | |||
| use App\Models\EmailAttachment; | |||
| use Exception; | |||
| use Illuminate\Database\Eloquent\Collection; | |||
| use Illuminate\Support\Carbon; | |||
| use Validator; | |||
| @@ -17,13 +19,18 @@ class EmailManager | |||
| private bool $canSend = false; | |||
| public function __construct(int|BaseMailer $param) | |||
| /** | |||
| * @var Collection<int, EmailAttachment>|null | |||
| */ | |||
| private ?Collection $attachments = null; | |||
| public function __construct(int|BaseEmailer $param) | |||
| { | |||
| if (is_numeric($param)) { | |||
| $this->model = Email::lockForUpdate()->findOrfail($param); | |||
| $this->canSend = $this->model->send_datetime === null; | |||
| if (!$this->checkAuth()) throw new AppCommonException("メール権限エラー"); | |||
| } else if ($param instanceof BaseMailer) { | |||
| } else if ($param instanceof BaseEmailer) { | |||
| $this->model = $param->makeModel(); | |||
| } | |||
| } | |||
| @@ -35,6 +42,7 @@ class EmailManager | |||
| public function getEmailId() | |||
| { | |||
| $this->model->setId(); | |||
| return $this->model->id; | |||
| } | |||
| @@ -70,6 +78,22 @@ class EmailManager | |||
| return $this; | |||
| } | |||
| public function attach(string $filepath, string $filename, string $mimeType) | |||
| { | |||
| if ($this->attachments === null) { | |||
| $this->attachments = new Collection(); | |||
| } | |||
| $attachment = new EmailAttachment(); | |||
| $attachment->filepath = $filepath; | |||
| $attachment->send_filename = $filename; | |||
| $attachment->mime = $mimeType; | |||
| $this->attachments->push($attachment); | |||
| return $this; | |||
| } | |||
| public function update() | |||
| { | |||
| $this->model->save(); | |||
| @@ -88,7 +112,8 @@ class EmailManager | |||
| } | |||
| if ($this->canSend() !== null) { | |||
| ConfirmEvent::dispatch($this->model); | |||
| $this->model->setId(); | |||
| ConfirmEvent::dispatch($this->model, $this->attachments); | |||
| } else { | |||
| throw new AppCommonException("送信済みエラー"); | |||
| } | |||
| @@ -5,9 +5,12 @@ namespace App\Logic\ReceiptIssuingOrder; | |||
| use App\Codes\PrefCode; | |||
| use App\Events\ReceiptIssuingOrder\DownloadedEvent; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Files\PDF\Receipt\A4Receipt; | |||
| use App\Files\TmpFile; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Models\ReceiptIssuingOrderTax; | |||
| use App\Util\DateUtil; | |||
| use Barryvdh\Snappy\PdfWrapper; | |||
| use PDF; | |||
| class PDFDownLoadManager extends ReceiptIssuingOrderManager | |||
| @@ -25,13 +28,7 @@ class PDFDownLoadManager extends ReceiptIssuingOrderManager | |||
| { | |||
| $order = $this->order; | |||
| $data = $this->getPDFData(); | |||
| $pdf = PDF::loadView('pdf/receipt_a4', $data); | |||
| // はがきサイズを指定 | |||
| $ret = $pdf->setPaper('A4') | |||
| ->setOption('encoding', 'utf-8') | |||
| $ret = $this->makeA4() | |||
| ->inline(); | |||
| if ($order->status_receipt_download_datetime === null) { | |||
| @@ -44,6 +41,30 @@ class PDFDownLoadManager extends ReceiptIssuingOrderManager | |||
| return $ret; | |||
| } | |||
| public function getA4File(): A4Receipt | |||
| { | |||
| $ret = $this->makeA4() | |||
| ->output(); | |||
| $file = new A4Receipt(); | |||
| $file->put($ret); | |||
| return $file; | |||
| } | |||
| protected function makeA4(): PdfWrapper | |||
| { | |||
| $data = $this->getPDFData(); | |||
| $pdf = PDF::loadView('pdf/receipt_a4', $data); | |||
| // はがきサイズを指定 | |||
| $ret = $pdf->setPaper('A4') | |||
| ->setOption('encoding', 'utf-8'); | |||
| return $ret; | |||
| } | |||
| public function downlaodLetter() | |||
| { | |||
| $data = $this->getPDFData(); | |||
| @@ -2,11 +2,16 @@ | |||
| namespace App\Logic\ReceiptIssuingOrder; | |||
| use App\Email\Guests\ReceiptA4; | |||
| use App\Events\ReceiptIssuingOrder\ChangeHandlerEvent; | |||
| use App\Events\ReceiptIssuingOrder\ConfirmedEvent; | |||
| use App\Events\ReceiptIssuingOrder\EmailOrderEvent; | |||
| use App\Events\ReceiptIssuingOrder\MailOrderEvent; | |||
| use App\Events\ReceiptIssuingOrder\MailPostedEvent; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Files\PDF\Receipt\A4Receipt; | |||
| use App\Jobs\ReceiptIssuingOrder\PollEmailSendStatus; | |||
| use App\Logic\EmailManager; | |||
| use App\Logic\SMS\SMSManager; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Models\User; | |||
| @@ -71,6 +76,43 @@ class UpdateManager extends ReceiptIssuingOrderManager | |||
| return $this; | |||
| } | |||
| /** | |||
| * 郵送投函完了 | |||
| * | |||
| * @param array $attr | |||
| * @return static | |||
| */ | |||
| public function emailOrder(string $email, A4Receipt $file, array $attr = []): static | |||
| { | |||
| $this->fill([ | |||
| ReceiptIssuingOrder::COL_NAME_EMAIL => $email, | |||
| ReceiptIssuingOrder::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME => DateUtil::now(), | |||
| ...$attr, | |||
| ]); | |||
| // メール送信 | |||
| $mail = new ReceiptA4($this->order); | |||
| $mail->setEmail($this->order->email); | |||
| $manager = new EmailManager($mail); | |||
| $filename = sprintf("領収証_%s.pdf", $this->order->receipt_no); | |||
| $manager->attach($file->getFullPath(), $filename, "application/pdf") | |||
| ->confirm(); | |||
| $this->fill([ | |||
| ReceiptIssuingOrder::COL_NAME_RECEIPT_PDF_EMAIL_ID => $manager->getEmailId() | |||
| ]); | |||
| // イベント登録 | |||
| EmailOrderEvent::dispatch($this->order); | |||
| PollEmailSendStatus::dispatch($this->order); | |||
| return $this; | |||
| } | |||
| /** | |||
| * 領収証確定 | |||
| * | |||
| @@ -1,15 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Admins; | |||
| use App\Mail\BaseMailer; | |||
| abstract class Admin extends BaseMailer | |||
| { | |||
| public function getParams(): array | |||
| { | |||
| return array_merge($this->getAdminParams(), []); | |||
| } | |||
| abstract public function getAdminParams(): array; | |||
| } | |||
| @@ -1,92 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Admins; | |||
| use App\Models\Parking; | |||
| use App\Models\SeasonTicketContract; | |||
| use App\Models\SeasonTicketContractSubscription; | |||
| use App\Models\User; | |||
| use App\Models\UserDetail; | |||
| use Illuminate\Support\Carbon; | |||
| class Ask extends Admin | |||
| { | |||
| protected string $askSubject; | |||
| protected string $askContents; | |||
| protected string|null $parkName = null; | |||
| protected string|null $userName; | |||
| protected string|null $userEmail; | |||
| protected int|null $seasonTicketSeqNo = null; | |||
| protected Carbon|null $subscribeDatetime = null; | |||
| public function __construct( | |||
| array $data, | |||
| User|null $user = null, | |||
| UserDetail|null $userDetail = null, | |||
| SeasonTicketContract|null $seasonTicketContract = null, | |||
| SeasonTicketContractSubscription|null $subscription = null, | |||
| Parking|null $parking = null, | |||
| ) { | |||
| $this->setValues($data); | |||
| if ($seasonTicketContract) { | |||
| $this->seasonTicketSeqNo = $seasonTicketContract->season_ticket_seq_no; | |||
| } | |||
| if ($subscription) { | |||
| $this->subscribeDatetime = $subscription->subscribe_datetime; | |||
| } | |||
| if ($user) { | |||
| $this->userEmail = $user->email; | |||
| } | |||
| if ($userDetail) { | |||
| $this->userName = sprintf( | |||
| "%s %s", | |||
| $userDetail->first_name, | |||
| $userDetail->last_name | |||
| ); | |||
| } | |||
| if ($parking) { | |||
| $this->parkName = $parking->park_name; | |||
| } | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.admins.ask'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return sprintf( | |||
| '【スマートパーキングパス】【問い合わせ】【%s】%s', | |||
| $this->userName, | |||
| $this->askSubject | |||
| ); | |||
| } | |||
| private function memberRegistration(): string | |||
| { | |||
| if ($this->seasonTicketSeqNo !== null || $this->subscribeDatetime !== null) { | |||
| return "あり"; | |||
| } | |||
| return "なし"; | |||
| } | |||
| public function getAdminParams(): array | |||
| { | |||
| return [ | |||
| 'askSubject' => $this->askSubject, | |||
| 'askContents' => $this->askContents, | |||
| 'parkName' => $this->parkName, | |||
| 'userName' => $this->userName, | |||
| 'userEmail' => $this->userEmail, | |||
| 'seasonTicketSeqNo' => $this->seasonTicketSeqNo, | |||
| 'subscribeDatetime' => $this->subscribeDatetime ? $this->subscribeDatetime->format('Y/m/d H:i:s') : null, | |||
| 'memberRegistration' => $this->memberRegistration(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,70 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Common; | |||
| use App\Models\Parking; | |||
| use App\Models\User; | |||
| use App\Models\UserDetail; | |||
| use Illuminate\Support\Carbon; | |||
| trait AskConfirmation | |||
| { | |||
| protected string $askSubject; | |||
| protected string $askContents; | |||
| protected string|null $parkName = null; | |||
| protected string|null $userName; | |||
| protected string|null $userEmail; | |||
| protected int|null $seasonTicketSeqNo = null; | |||
| protected Carbon|null $subscribeDatetime = null; | |||
| private bool $forMember = false; | |||
| abstract protected function setValues(\stdClass|array $data); | |||
| protected function setAskConfirmationData( | |||
| array $data, | |||
| User|null $user = null, | |||
| UserDetail|null $userDetail = null, | |||
| Parking|null $parking = null, | |||
| ) { | |||
| $this->setValues($data); | |||
| if ($user) { | |||
| $this->userEmail = $user->email; | |||
| $this->forMember = true; | |||
| } | |||
| if ($userDetail) { | |||
| $this->userName = sprintf( | |||
| "%s %s", | |||
| $userDetail->first_name, | |||
| $userDetail->last_name | |||
| ); | |||
| $this->forMember = true; | |||
| } | |||
| if ($parking) { | |||
| $this->parkName = $parking->park_name; | |||
| } | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return $this->forMember ? 'mails.members.ask_confirmation' : 'mails.guests.ask_confirmation'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】お問い合わせ内容の確認'; | |||
| } | |||
| protected function getAskConfirmationParams(): array | |||
| { | |||
| return [ | |||
| 'askSubject' => $this->askSubject, | |||
| 'askContents' => $this->askContents, | |||
| 'parkName' => $this->parkName, | |||
| 'userName' => $this->userName, | |||
| 'userEmail' => $this->userEmail, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,27 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Guests; | |||
| use App\Mail\Common\AskConfirmation as CommonAskConfirmation; | |||
| use App\Models\Parking; | |||
| use App\Models\User; | |||
| use App\Models\UserDetail; | |||
| class AskConfirmation extends Guest | |||
| { | |||
| use CommonAskConfirmation; | |||
| public function __construct( | |||
| array $data, | |||
| User|null $user = null, | |||
| UserDetail|null $userDetail = null, | |||
| Parking|null $parking = null, | |||
| ) { | |||
| $this->setAskConfirmationData($data, $user, $userDetail, $parking); | |||
| } | |||
| public function getGuestParams(): array | |||
| { | |||
| return $this->getAskConfirmationParams(); | |||
| } | |||
| } | |||
| @@ -1,63 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Guests; | |||
| use App\Models\ChangeEmail; | |||
| use Exception; | |||
| use Illuminate\Support\Carbon; | |||
| class ChangeEmailStart extends Guest | |||
| { | |||
| protected string $token; | |||
| protected Carbon $expiresAt; | |||
| protected $casts = [ | |||
| 'expiresAt' => 'datetime', | |||
| ]; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(ChangeEmail $model) | |||
| { | |||
| logger($model->toArray()); | |||
| $this->setValues($model->toArray()); | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.guests.change_email_start'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】Email変更手続きのご案内'; | |||
| } | |||
| public function getGuestParams(): array | |||
| { | |||
| return [ | |||
| 'url' => $this->getUrl(), | |||
| 'expiresAt' => $this->getExpiresAt(), | |||
| ]; | |||
| } | |||
| private function getUrl() | |||
| { | |||
| return implode( | |||
| "/", | |||
| [ | |||
| config("app.url"), | |||
| 'change-email', | |||
| $this->token | |||
| ] | |||
| ); | |||
| } | |||
| private function getExpiresAt() | |||
| { | |||
| return $this->expiresAt->format('Y/m/d H:i'); | |||
| } | |||
| } | |||
| @@ -1,65 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Guests; | |||
| use App\Models\EmailVerify as ModelsEmailVerify; | |||
| use Exception; | |||
| use Illuminate\Support\Carbon; | |||
| class EmailVerify extends Guest | |||
| { | |||
| protected string $token; | |||
| protected Carbon $expiresAt; | |||
| protected $casts = [ | |||
| 'expiresAt' => 'datetime', | |||
| ]; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(ModelsEmailVerify $model) | |||
| { | |||
| $this->setValues($model->toArray()); | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.guests.email_verify'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】会員登録のご案内'; | |||
| } | |||
| public function getGuestParams(): array | |||
| { | |||
| return [ | |||
| 'url' => $this->getUrl(), | |||
| 'expiresAt' => $this->getExpiresAt(), | |||
| ]; | |||
| } | |||
| private function getUrl() | |||
| { | |||
| return implode( | |||
| "/", | |||
| [ | |||
| config("app.url"), | |||
| 'register/user', | |||
| $this->token | |||
| ] | |||
| ); | |||
| } | |||
| private function getExpiresAt() | |||
| { | |||
| $date = $this->expiresAt; | |||
| if ($date !== null) { | |||
| return $date->format('Y/m/d H:i'); | |||
| } | |||
| throw new Exception("有効期限日付不正"); | |||
| } | |||
| } | |||
| @@ -1,27 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Mail\Common\AskConfirmation as CommonAskConfirmation; | |||
| use App\Models\Parking; | |||
| use App\Models\User; | |||
| use App\Models\UserDetail; | |||
| class AskConfirmation extends Member | |||
| { | |||
| use CommonAskConfirmation; | |||
| public function __construct( | |||
| array $data, | |||
| User|null $user = null, | |||
| UserDetail|null $userDetail = null, | |||
| Parking|null $parking = null, | |||
| ) { | |||
| $this->setAskConfirmationData($data, $user, $userDetail, $parking); | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return $this->getAskConfirmationParams(); | |||
| } | |||
| } | |||
| @@ -1,42 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Models\SeasonTicketContract; | |||
| use App\Models\Parking; | |||
| class AutoCancelSeasonTicketContract extends Member | |||
| { | |||
| protected string $parkName; | |||
| protected int $seasonTicketSeqNo; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(Parking $parking, SeasonTicketContract $seasonTicketContract) | |||
| { | |||
| $this->setValues($parking->toArray()); | |||
| $this->setValues($seasonTicketContract->toArray()); | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.auto_cancel_season_ticket_contract'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】駐車場利用停止のお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| 'seasonTicketSeqNo' => $this->seasonTicketSeqNo, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,37 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use Illuminate\Bus\Queueable; | |||
| use Illuminate\Queue\SerializesModels; | |||
| class Bulk extends Member | |||
| { | |||
| use Queueable, SerializesModels; | |||
| private string $__subject; | |||
| private string $__contents; | |||
| public function __construct(string $subject, string $contents) | |||
| { | |||
| $this->__subject = $subject; | |||
| $this->__contents = $contents; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.bulk'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return $this->__subject; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'contents' => $this->__contents, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Mail\BaseMailer; | |||
| abstract class Member extends BaseMailer | |||
| { | |||
| public function getParams(): array | |||
| { | |||
| return array_merge($this->getMemberParams(), [ | |||
| 'email' => $this->__email | |||
| ]); | |||
| } | |||
| abstract public function getMemberParams(): array; | |||
| } | |||
| @@ -1,42 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Exceptions\AppCommonException; | |||
| class ResetIDm extends Member | |||
| { | |||
| private string $confirmationCode; | |||
| private int $seasonTicketSeqNo; | |||
| public function __construct() | |||
| { | |||
| $context = $this->context(); | |||
| $seasonTicketContract = $context->getSeasonTicketContract(); | |||
| if ($seasonTicketContract === null) { | |||
| throw new AppCommonException("コンテキスト不正 定期契約情報"); | |||
| } | |||
| $this->confirmationCode = $seasonTicketContract->confirmation_code; | |||
| $this->seasonTicketSeqNo = $seasonTicketContract->season_ticket_seq_no; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.reset_idm'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】ICカードリセットのお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'confirmationCode' => $this->confirmationCode, | |||
| 'seasonTicketSeqNo' => $this->seasonTicketSeqNo, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,61 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Models\ResetPassword; | |||
| use Illuminate\Support\Carbon; | |||
| class ResetPasswordStart extends Member | |||
| { | |||
| protected string $token; | |||
| protected Carbon $expiresAt; | |||
| protected $casts = [ | |||
| 'expiresAt' => 'datetime', | |||
| ]; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(ResetPassword $model) | |||
| { | |||
| $this->setValues($model->toArray()); | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.reset_password_start'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】パスワードリセット手続きのご案内'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'url' => $this->getUrl(), | |||
| 'expiresAt' => $this->getExpiresAt(), | |||
| ]; | |||
| } | |||
| private function getUrl() | |||
| { | |||
| return implode( | |||
| "/", | |||
| [ | |||
| config("app.url"), | |||
| 'password-reset', | |||
| $this->token | |||
| ] | |||
| ); | |||
| } | |||
| private function getExpiresAt() | |||
| { | |||
| return $this->expiresAt->format('Y/m/d H:i'); | |||
| } | |||
| } | |||
| @@ -1,45 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use Illuminate\Support\Carbon; | |||
| class SeasonTicketContractExpireRemind extends Member | |||
| { | |||
| protected string|null $parkName; | |||
| protected int $seasonTicketSeqNo; | |||
| protected Carbon $expirationEndDate; | |||
| protected $casts = [ | |||
| 'expirationEndDate' => 'datetime', | |||
| ]; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(\stdClass $data) | |||
| { | |||
| $this->setValues($data); | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.season_ticket_contract_expires_remind'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】定期期限切れ予告通知'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| 'seasonTicketSeqNo' => $this->seasonTicketSeqNo, | |||
| 'expirationEndDate' => $this->expirationEndDate, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,111 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Codes\ParkingUseTypeCode; | |||
| use App\Codes\VehicleTypeCode; | |||
| use App\Mail\Members\Member; | |||
| use App\Models\Parking; | |||
| use App\Models\SeasonTicketContract; | |||
| use App\Models\SeasonTicketContractSubscription; | |||
| use App\Models\User; | |||
| use Illuminate\Support\Carbon; | |||
| use LogicException; | |||
| class Approve extends Member | |||
| { | |||
| private string $email; | |||
| private string $parkName; | |||
| private Carbon|null $useStartRequestDate; | |||
| private VehicleTypeCode $vehicleType; | |||
| private string $contractorTypeName; | |||
| private int $seasonTicketSeqNo; | |||
| private int|null $confirmationCode; | |||
| private ParkingUseTypeCode $parkingUseType; | |||
| private string $customerCode; | |||
| private string $parkingManagementCode; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct( | |||
| User $user, | |||
| SeasonTicketContractSubscription|null $subscription, | |||
| Parking $parking, | |||
| SeasonTicketContract $seasonTicketContract, | |||
| string $contractorTypeName | |||
| ) { | |||
| $this->email = $user->email; | |||
| $this->parkName = $parking->park_name; | |||
| $this->useStartRequestDate = $subscription ? $subscription->use_start_request_date : null; | |||
| $this->vehicleType = $seasonTicketContract->vehicle_type; | |||
| $this->contractorTypeName = $contractorTypeName; | |||
| $this->seasonTicketSeqNo = $seasonTicketContract->season_ticket_seq_no; | |||
| $this->confirmationCode = $seasonTicketContract->confirmation_code; | |||
| $this->parkingUseType = $seasonTicketContract->parking_use_type; | |||
| $this->customerCode = $seasonTicketContract->customer_code; | |||
| $this->parkingManagementCode = $seasonTicketContract->parking_management_code; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.approve'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】定期申し込み完了'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'email' => $this->email, | |||
| 'park_name' => $this->parkName, | |||
| 'use_start_request_date' => $this->getUseStartRequestDate(), | |||
| 'vehicle_type' => $this->getVehicleType(), | |||
| 'contractor_type_name' => $this->contractorTypeName, | |||
| 'how_to_use' => $this->getHowToUse(), | |||
| 'season_ticket_seq_no' => $this->seasonTicketSeqNo, | |||
| 'confirmation_code' => $this->confirmationCode, | |||
| 'ic_card_rental_request' => $this->parkingUseType === ParkingUseTypeCode::IC_RENTAL, | |||
| 'ic_self_card_request' => $this->parkingUseType === ParkingUseTypeCode::IC_SELF, | |||
| 'ic_qr_code_request' => $this->parkingUseType === ParkingUseTypeCode::QR, | |||
| 'my_qr_code_url' => $this->getMyQrCodeUrl(), | |||
| ]; | |||
| } | |||
| private function getUseStartRequestDate() | |||
| { | |||
| if ($this->useStartRequestDate === null) return "-"; | |||
| return $this->useStartRequestDate->format("Y年m月d日"); | |||
| } | |||
| private function getVehicleType() | |||
| { | |||
| return VehicleTypeCode::getName($this->vehicleType); | |||
| } | |||
| private function getHowToUse() | |||
| { | |||
| switch ($this->parkingUseType) { | |||
| case ParkingUseTypeCode::IC_RENTAL: | |||
| return "貸与ICカード"; | |||
| case ParkingUseTypeCode::IC_SELF: | |||
| return "個人ICカード"; | |||
| case ParkingUseTypeCode::QR: | |||
| return "QRコード"; | |||
| } | |||
| throw new LogicException(sprintf("不適切な駐車場利用方法 %d", $this->parkingUseType->value)); | |||
| } | |||
| private function getMyQrCodeUrl() | |||
| { | |||
| return $this->getAppUrl(['app', 'qrcode', 'detail', $this->customerCode, $this->parkingManagementCode]); | |||
| } | |||
| } | |||
| @@ -1,45 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Mail\Members\Member; | |||
| class Cancel extends Member | |||
| { | |||
| private string $parkName; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct() | |||
| { | |||
| $context = $this->context(); | |||
| $parking = $context->getParking(); | |||
| if ($parking === null) { | |||
| throw new AppCommonException("コンテキスト不正 駐車場情報"); | |||
| } | |||
| $this->parkName = $parking->park_name; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.cancel'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】申込キャンセルのお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,70 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Mail\Members\Member; | |||
| use Illuminate\Support\Carbon; | |||
| class Entry extends Member | |||
| { | |||
| private string $email; | |||
| private string $parkName; | |||
| private Carbon|null $useStartRequestDate; | |||
| private string $memo; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct() | |||
| { | |||
| $context = $this->context(); | |||
| $user = $context->getUser(); | |||
| $subscription = $context->getSeasonTicketContractSubscription(); | |||
| $parking = $context->getParking(); | |||
| if ($user === null) { | |||
| throw new AppCommonException("コンテキスト不正 利用者情報"); | |||
| } | |||
| if ($subscription === null) { | |||
| throw new AppCommonException("コンテキスト不正 申込情報"); | |||
| } | |||
| if ($parking === null) { | |||
| throw new AppCommonException("コンテキスト不正 駐車場情報"); | |||
| } | |||
| $this->email = $user->email; | |||
| $this->parkName = $parking->park_name; | |||
| $this->useStartRequestDate = $subscription->use_start_request_date; | |||
| $this->memo = $subscription->memo ?? ""; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.entry'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】定期申し込み内容'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'email' => $this->email, | |||
| 'park_name' => $this->parkName, | |||
| 'use_start_request_date' => $this->getUseStartRequestDate(), | |||
| 'memo' => $this->memo | |||
| ]; | |||
| } | |||
| public function getUseStartRequestDate() | |||
| { | |||
| if ($this->useStartRequestDate === null) return "-"; | |||
| return $this->useStartRequestDate->format("Y年m月d日"); | |||
| } | |||
| } | |||
| @@ -1,47 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Mail\Members\Member; | |||
| use App\Models\SeasonTicketContractSubscriptionMessage; | |||
| class Hold extends Member | |||
| { | |||
| private string $parkName; | |||
| private string|null $message; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(SeasonTicketContractSubscriptionMessage $message) | |||
| { | |||
| $context = $this->context(); | |||
| $parking = $context->getParking(); | |||
| if ($parking === null) { | |||
| throw new AppCommonException("コンテキスト不正 駐車場情報"); | |||
| } | |||
| $this->parkName = $parking->park_name; | |||
| $this->message = $message->message; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.hold'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】申込確認のお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| 'memo' => $this->message, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,47 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Mail\Members\Member; | |||
| use App\Models\SeasonTicketContractSubscriptionMessage; | |||
| class Reject extends Member | |||
| { | |||
| private string $parkName; | |||
| private string $message; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(SeasonTicketContractSubscriptionMessage $message) | |||
| { | |||
| $context = $this->context(); | |||
| $parking = $context->getParking(); | |||
| if ($parking === null) { | |||
| throw new AppCommonException("コンテキスト不正 駐車場情報"); | |||
| } | |||
| $this->parkName = $parking->park_name; | |||
| $this->message = $message->message ?? ""; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.reject'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】申込却下のお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| 'memo' => $this->message, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,48 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members\Subscription; | |||
| use App\Mail\Members\Member; | |||
| use App\Models\SeasonTicketContractSubscriptionMessage; | |||
| class Returned extends Member | |||
| { | |||
| private string $parkName; | |||
| private string $message; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(SeasonTicketContractSubscriptionMessage $message) | |||
| { | |||
| $context = $this->context(); | |||
| $parking = $context->getParking(); | |||
| if ($parking === null) { | |||
| throw new AppCommonException("コンテキスト不正 駐車場情報"); | |||
| } | |||
| $this->parkName = $parking->park_name; | |||
| $this->message = $message->message ?? ""; | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.subscription.returned'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】申込差し戻しのお知らせ'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'parkName' => $this->parkName, | |||
| 'memo' => $this->message, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -1,76 +0,0 @@ | |||
| <?php | |||
| namespace App\Mail\Members; | |||
| use App\Models\ResetPassword; | |||
| use App\Models\User; | |||
| use Illuminate\Support\Carbon; | |||
| class UserRegisterComplete extends Member | |||
| { | |||
| private string $email; | |||
| private bool $includePasswordReset = false; | |||
| private Carbon|null $expiresAt = null; | |||
| private string $token = ""; | |||
| /** | |||
| * Create a new message instance. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function __construct(User $model, ResetPassword|null $password = null) | |||
| { | |||
| $this->email = $model->email; | |||
| if ($password !== null) { | |||
| $this->includePasswordReset = true; | |||
| $this->expiresAt = $password->expires_at; | |||
| $this->token = $password->token; | |||
| } | |||
| } | |||
| public function getTemplateName(): string | |||
| { | |||
| return 'mails.members.user_register_complete'; | |||
| } | |||
| public function getSubject(): string | |||
| { | |||
| return '【スマートパーキングパス】会員登録完了'; | |||
| } | |||
| public function getMemberParams(): array | |||
| { | |||
| return [ | |||
| 'email' => $this->email, | |||
| 'includePasswordReset' => $this->includePasswordReset, | |||
| 'url' => $this->getUrl(), | |||
| 'expiresAt' => $this->getExpiresAt(), | |||
| ]; | |||
| } | |||
| private function getUrl() | |||
| { | |||
| return implode( | |||
| "/", | |||
| [ | |||
| config("app.url"), | |||
| 'password-reset', | |||
| $this->token | |||
| ] | |||
| ); | |||
| } | |||
| private function getExpiresAt() | |||
| { | |||
| if ($this->expiresAt === null) { | |||
| return ""; | |||
| } else { | |||
| return $this->expiresAt->format('Y/m/d H:i'); | |||
| } | |||
| } | |||
| } | |||
| @@ -23,6 +23,8 @@ abstract class AppModel extends BaseModel | |||
| public function setId(?string $uuid = null) | |||
| { | |||
| if ($this->id !== null) return; | |||
| if ($uuid) { | |||
| $this->id = $uuid; | |||
| } else { | |||
| @@ -19,4 +19,5 @@ abstract class ColumnName | |||
| const RECEIPT_ISSUING_ORDER_ID = "receipt_issuing_order_id"; | |||
| const SMS_SEND_ORDER_ID = "sms_send_order_id"; | |||
| const SMS_PROVIDER_ID = "sms_provider_id"; | |||
| const EMAIL_ID = "email_id"; | |||
| } | |||
| @@ -2,11 +2,23 @@ | |||
| namespace App\Models; | |||
| use Illuminate\Database\Eloquent\Relations\HasMany; | |||
| class Email extends AppModel | |||
| { | |||
| const COL_NAME_SEND_DATETIME = "send_datetime"; | |||
| public function getModelName(): string | |||
| { | |||
| return "Email"; | |||
| } | |||
| public function emailAttachments(): HasMany | |||
| { | |||
| return $this->hasMany(EmailAttachment::class); | |||
| } | |||
| protected $casts = [ | |||
| self::COL_NAME_SEND_DATETIME => 'datetime', | |||
| ]; | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| <?php | |||
| namespace App\Models; | |||
| class EmailAttachment extends AppModel | |||
| { | |||
| public function getModelName(): string | |||
| { | |||
| return "Email添付ファイル"; | |||
| } | |||
| public function getHistory(): ?HistoryModel | |||
| { | |||
| return null; | |||
| } | |||
| } | |||
| @@ -32,6 +32,8 @@ class ReceiptIssuingOrder extends AppModel | |||
| const COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME = "status_receipt_email_send_order_datetime"; | |||
| const COL_NAME_STATUS_RECEIPT_EMAIL_SEND_DATETIME = "status_receipt_email_send_datetime"; | |||
| const COL_NAME_RECEIPT_PDF_EMAIL_ID = "receipt_pdf_email_id"; | |||
| const COL_NAME_SMS_PHONE_NUMBER = "sms_phone_number"; | |||
| const COL_NAME_SMS_SEND_SUCCESS = "sms_send_success"; | |||
| const COL_NAME_RECEIPT_NO = "receipt_no"; | |||
| @@ -61,6 +63,7 @@ class ReceiptIssuingOrder extends AppModel | |||
| self::COL_NAME_STATUS_MAIL_DOWNLOAD_DATETIME => 'datetime', | |||
| self::COL_NAME_STATUS_MAIL_POST_DATE => 'date', | |||
| self::COL_NAME_STATUS_RECEIPT_DOWNLOAD_DATETIME => 'datetime', | |||
| self::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME => 'datetime', | |||
| self::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_DATETIME => 'datetime', | |||
| self::COL_NAME_RECEIPT_USE_DATE => 'date', | |||
| self::COL_NAME_MAIL_PREF_CODE => PrefCode::class, | |||
| @@ -78,6 +78,9 @@ class MigrationHelper | |||
| $this->table->timestamp(ColumnName::UPDATED_AT)->nullable()->comment("更新日時"); | |||
| $this->table->timestamp(ColumnName::DELETED_AT)->nullable()->comment("論理削除日時"); | |||
| $this->table->index([ColumnName::CREATED_AT], sprintf("%s_idx_CREATED_AT", $this->table->getTable())); | |||
| $this->table->index([ColumnName::UPDATED_AT], sprintf("%s_idx_UPDATED_AT", $this->table->getTable())); | |||
| return $this; | |||
| } | |||
| @@ -159,4 +162,10 @@ class MigrationHelper | |||
| // $this->table->foreign(ColumnName::SMS_PROVIDER_ID)->references(ColumnName::ID)->on(SMSProvider::getTableName()); | |||
| return $this; | |||
| } | |||
| public function emailId(bool $nullable = false) | |||
| { | |||
| $this->table->uuid(ColumnName::EMAIL_ID)->comment("EメールID")->nullable($nullable); | |||
| return $this; | |||
| } | |||
| } | |||
| @@ -43,6 +43,8 @@ return [ | |||
| 'password' => env('MAIL_PASSWORD'), | |||
| 'timeout' => null, | |||
| 'local_domain' => env('MAIL_EHLO_DOMAIN'), | |||
| 'auth_mode' => null, | |||
| 'verify_peer' => false, | |||
| ], | |||
| 'ses' => [ | |||
| @@ -0,0 +1,46 @@ | |||
| <?php | |||
| use App\Models\ColumnName; | |||
| use App\Util\MigrationHelper; | |||
| use Illuminate\Database\Migrations\Migration; | |||
| use Illuminate\Database\Schema\Blueprint; | |||
| use Illuminate\Support\Facades\Schema; | |||
| return new class extends Migration | |||
| { | |||
| /** | |||
| * Run the migrations. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function up() | |||
| { | |||
| MigrationHelper::createTable('email_attachments', $this->schema()); | |||
| } | |||
| /** | |||
| * Reverse the migrations. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function down() | |||
| { | |||
| Schema::dropIfExists('email_attachments'); | |||
| } | |||
| private function schema() | |||
| { | |||
| return function (Blueprint $table, MigrationHelper $helper) { | |||
| $helper->baseColumn() | |||
| ->emailId(); | |||
| $table->string('filepath')->comment("ファイルパス"); | |||
| $table->string('send_filename')->comment("送信ファイル名"); | |||
| $table->string('mime')->comment("MIMEタイプ"); | |||
| $helper->index(1, [ColumnName::EMAIL_ID]); | |||
| $helper->index(2, [ColumnName::CREATED_AT]); | |||
| }; | |||
| } | |||
| }; | |||
| @@ -0,0 +1,40 @@ | |||
| <?php | |||
| use App\Models\ColumnName; | |||
| use App\Util\MigrationHelper; | |||
| use Illuminate\Database\Migrations\Migration; | |||
| use Illuminate\Database\Schema\Blueprint; | |||
| use Illuminate\Support\Facades\Schema; | |||
| return new class extends Migration | |||
| { | |||
| /** | |||
| * Run the migrations. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function up() | |||
| { | |||
| Schema::table('receipt_issuing_orders', function (Blueprint $table) { | |||
| $table->uuid("receipt_pdf_email_id")->nullable()->comment("領収書PDF送付EmailID"); | |||
| }); | |||
| Schema::table('receipt_issuing_order_histories', function (Blueprint $table) { | |||
| $table->uuid("receipt_pdf_email_id")->nullable()->comment("領収書PDF送付EmailID"); | |||
| }); | |||
| } | |||
| /** | |||
| * Reverse the migrations. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function down() | |||
| { | |||
| Schema::table('receipt_issuing_orders', function (Blueprint $table) { | |||
| $table->dropColumn("receipt_pdf_email_id"); | |||
| }); | |||
| Schema::table('receipt_issuing_order_histories', function (Blueprint $table) { | |||
| $table->dropColumn("receipt_pdf_email_id"); | |||
| }); | |||
| } | |||
| }; | |||
| @@ -20,6 +20,7 @@ COMMANDS+=("${SAIL} php artisan config:cache") | |||
| COMMANDS+=("${SAIL} php artisan route:cache") | |||
| COMMANDS+=("${SAIL} php artisan view:cache") | |||
| COMMANDS+=("${SAIL} php artisan event:cache") | |||
| COMMANDS+=("${SAIL} php artisan queue:restart") | |||
| for COMMAND in "${COMMANDS[@]}"; do | |||
| echo ${COMMAND} | |||
| @@ -1,14 +0,0 @@ | |||
| 下記内容にてお問合せを受付ました。 | |||
| 返信のメールがあるまでしばらくお待ちください。 | |||
| 件名: {{ $askSubject }} | |||
| @if($parkName) | |||
| 駐車場名 : {{ $parkName }} | |||
| @endif | |||
| ■問い合わせ内容 | |||
| {{ $askContents }} | |||
| ■問い合わせ者情報 | |||
| 氏名: {{ $userName }} | |||
| email: {{ $userEmail }} | |||
| @@ -1,7 +0,0 @@ | |||
| ①駐車場に設置された定期更新機で利用したい交通系ICカード(ICOCA,SUICAなど)をタッチします。 | |||
| ②画面が切り替わりますので、上記定期券番号と確認コードを入力して確定ボタンを押してください。 | |||
| または、承認画面で認証用QRコードをかざしても定期券登録が完了します。 | |||
| @isset($my_qr_code_url) | |||
| 認証用QRコードは以下(初回アクセスの場合はパスワードを設定してログインしてください) | |||
| {{ $my_qr_code_url }} | |||
| @endisset | |||
| @@ -1 +0,0 @@ | |||
| ※このメールをお送りしているアドレスは、送信専用となっており、返信いただいてもご回答いたしかねます。 | |||
| @@ -0,0 +1,15 @@ | |||
| @extends('mails.layouts.guest') | |||
| @section('contents') | |||
| 発行依頼された領収証を添付します。 | |||
| ご確認よろしくお願いいたします。 | |||
| ■店舗名 | |||
| {{ $shopName }} | |||
| ■利用日 | |||
| {{ $useDate }} | |||
| ■金額 | |||
| {{ $amount }}円 | |||
| @endsection | |||
| @@ -0,0 +1,11 @@ | |||
| ご利用ありがとうございます。 | |||
| EasyReceiptです。 | |||
| @yield('contents') | |||
| ※このメールをお送りしているアドレスは、送信専用となっており、返信いただいてもご回答いたしかねます。 | |||
| ※このメールにお心当たりのない方は、お手数ですが削除いただきますようお願いいたします。 | |||
| --------------------------------------------------------------------------------------- | |||
| EasyReceipt | |||
| @@ -20,6 +20,7 @@ RouteHelper::post('/change-contract', App\Http\Controllers\Web\Auth\ChangeContra | |||
| RouteHelper::get('/app-token-check', App\Http\Controllers\Web\ReceiptIssuingOrder\TokenCheckController::class); | |||
| RouteHelper::post('/receipt-issuing-order/confirm', App\Http\Controllers\Web\ReceiptIssuingOrder\ConfirmController::class); | |||
| RouteHelper::post('/receipt-issuing-order/email-order', App\Http\Controllers\Web\ReceiptIssuingOrder\EmailOrderController::class); | |||
| RouteHelper::post('/receipt-issuing-order/mail-order', App\Http\Controllers\Web\ReceiptIssuingOrder\MailOrderController::class); | |||
| RouteHelper::post('/receipt-issuing-order/mail-complete', App\Http\Controllers\Web\ReceiptIssuingOrder\MailPostCompleteController::class); | |||
| RouteHelper::post('/receipt-issuing-order/change-handler', App\Http\Controllers\Web\ReceiptIssuingOrder\ChangeHandlerController::class); | |||