mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Show custom messages (#3616)
* Show custom messages * Fix getSetting key * Add custom messages support with variable parsing
This commit is contained in:
parent
e3446e906f
commit
f118f3bfda
31
app/Providers/ClientPortalServiceProvider.php
Normal file
31
app/Providers/ClientPortalServiceProvider.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Utils\ClientPortal\CustomMessage\CustomMessage;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class ClientPortalServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
app()->bind('customMessage', function () {
|
||||
return new CustomMessage();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
130
app/Utils/ClientPortal/CustomMessage/CustomMessage.php
Normal file
130
app/Utils/ClientPortal/CustomMessage/CustomMessage.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace App\Utils\ClientPortal\CustomMessage;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\GroupSetting;
|
||||
|
||||
class CustomMessage
|
||||
{
|
||||
protected $message;
|
||||
|
||||
protected $values;
|
||||
|
||||
protected $client;
|
||||
|
||||
protected $company;
|
||||
|
||||
protected $contact;
|
||||
|
||||
protected $group;
|
||||
|
||||
protected $entity;
|
||||
|
||||
protected $invitation;
|
||||
|
||||
public function client(Client $client): self
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function company(Company $company): self
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function contact(ClientContact $contact): self
|
||||
{
|
||||
$this->contact = $contact;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function group(GroupSetting $group): self
|
||||
{
|
||||
$this->group = $group;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function entity($entity): self
|
||||
{
|
||||
$this->entity = $entity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function invitation($invitation): self
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function message(string $message): string
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->values = $this->compose();
|
||||
|
||||
return strtr($message, $this->values);
|
||||
}
|
||||
|
||||
private function compose(): array
|
||||
{
|
||||
return [
|
||||
'$company.id' => optional($this->company)->id,
|
||||
'$company.name' => optional($this->company)->getSetting('name'),
|
||||
'$company.website' => optional($this->company)->getSetting('website'),
|
||||
|
||||
'$client.id' => optional(optional($this->client)->present())->id,
|
||||
'$client.name' => optional(optional($this->client)->present())->name,
|
||||
'$client.website' => optional(optional($this->client)->present())->website,
|
||||
'$client.public_notes' => optional(optional($this->client)->present())->public_notes,
|
||||
'$client.phone' => optional(optional($this->client)->present())->phone,
|
||||
'$client.balance' => optional(optional($this->client)->present())->balance,
|
||||
'$client.address1' => optional(optional($this->client)->present())->address1,
|
||||
'$client.address2' => optional(optional($this->client)->present())->address2,
|
||||
'$client.city' => optional(optional($this->client)->present())->city,
|
||||
'$client.state' => optional(optional($this->client)->present())->state,
|
||||
'$client.postal_code' => optional(optional($this->client)->present())->postal_code,
|
||||
'$client.country' => optional(optional(optional($this->client)->present())->country)->full_name,
|
||||
|
||||
'$contact.first_name' => optional($this->contact)->first_name,
|
||||
'$contact.last_name' => optional($this->contact)->last_name,
|
||||
'$contact.phone' => optional($this->contact)->phone,
|
||||
'$contact.email' => optional($this->contact)->email,
|
||||
'$contact.avatar' => optional($this->contact)->avatar,
|
||||
|
||||
'$group.id' => optional($this->group)->id,
|
||||
|
||||
'$entity.id' => optional($this->entity)->hashed_id,
|
||||
'$entity.number' => optional($this->entity)->number,
|
||||
'$entity.discount' => optional($this->entity)->discount,
|
||||
'$entity.date' => optional($this->entity)->date, // Todo: Handle formatDate
|
||||
'$entity.due_date' => optional($this->entity)->due_date, // Todo: Handle formatDate
|
||||
'$entity.last_sent_date' => optional($this->entity)->last_sent_date,
|
||||
'$entity.public_notes' => optional($this->entity)->public_notes,
|
||||
'$entity.terms' => optional($this->entity)->terms,
|
||||
'$entity.amount' => optional($this->entity)->amount, // Todo: Handle moneyformat
|
||||
'$entity.balance' => optional($this->entity)->balance, // Todo: Handle moneyformat
|
||||
'$entity.created_at' => optional($this->entity)->created_at, // Todo: Handle formatDate
|
||||
|
||||
'$entity.status' => optional(optional($this->entity))->badgeForStatus(optional($this->entity)->status_id), // It would be nice if we have method that will only return status as text, not with markup.
|
||||
'$entity.project' => optional(optional($this->entity)->project)->name,
|
||||
'$entity.project.date' => optional(optional($this->entity)->project)->date,
|
||||
|
||||
'$invitation.id' => optional($this->invitation)->id,
|
||||
'$invitation.user.first_name' => optional(optional($this->invitation)->user)->first_name,
|
||||
'$invitation.user.last_name' => optional(optional($this->invitation)->user)->last_name,
|
||||
'$invitation.sent_date' => optional($this->invitation)->sent_date, // Todo: Handle formatDate
|
||||
'$invitation.viewed_date' => optional($this->invitation)->viewed_date, // Todo: Handle formatDate,
|
||||
'$invitation.opened_date' => optional($this->invitation)->opened_date, // Todo: Handle formatDate,
|
||||
];
|
||||
}
|
||||
}
|
13
app/Utils/ClientPortal/CustomMessage/CustomMessageFacade.php
Normal file
13
app/Utils/ClientPortal/CustomMessage/CustomMessageFacade.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Utils\ClientPortal\CustomMessage;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class ClientPortalFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'customMessage';
|
||||
}
|
||||
}
|
@ -180,7 +180,7 @@ return [
|
||||
App\Providers\ComposerServiceProvider::class,
|
||||
Codedge\Updater\UpdaterServiceProvider::class,
|
||||
App\Providers\MultiDBProvider::class,
|
||||
|
||||
App\Providers\ClientPortalServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
@ -235,7 +235,7 @@ return [
|
||||
*/
|
||||
|
||||
'Countries' => 'Webpatser\Countries\CountriesFacade',
|
||||
|
||||
'CustomMessage' => App\Utils\ClientPortal\CustomMessage\ClientPortalFacade::class,
|
||||
],
|
||||
|
||||
];
|
||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js?id=8b49701583f407403ddf",
|
||||
"/css/app.css": "/css/app.css?id=94397d09115c3157cc49",
|
||||
"/css/app.css": "/css/app.css?id=54b56cad767e049a84d7",
|
||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=caec43815d9a13168a38",
|
||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=af49e24958be5fc00c92",
|
||||
"/js/clients/payment_methods/authorize-stripe-card.js": "/js/clients/payment_methods/authorize-stripe-card.js?id=f4c45f0da9868d840799",
|
||||
|
@ -0,0 +1,3 @@
|
||||
<div class="alert border-blue-500 bg-blue-50 mt-2 mb-4">
|
||||
{{ $slot }}
|
||||
</div>
|
@ -4,6 +4,14 @@
|
||||
@section('header')
|
||||
{{ Breadcrumbs::render('dashboard') }}
|
||||
|
||||
@if(!empty($client->getSetting('custom_message_dashboard')))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{!! CustomMessage::client($client)
|
||||
->company($client->company)
|
||||
->message($client->getSetting('custom_message_dashboard')) !!}
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
<div class="bg-white shadow rounded mb-4" translate>
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<div class="sm:flex sm:items-start sm:justify-between">
|
||||
|
@ -12,6 +12,24 @@
|
||||
|
||||
@section('body')
|
||||
|
||||
@if($invoice->isPayable() && !empty($client->getSetting('custom_message_unpaid_invoice')))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{!! CustomMessage::client($client)
|
||||
->company($client->company)
|
||||
->entity($invoice)
|
||||
->message($client->getSetting('custom_message_unpaid_invoice')) !!}
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
@if(!$invoice->isPayable() && !empty($client->getSetting('custom_message_paid_invoice')))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{!! CustomMessage::client($client)
|
||||
->company($client->company)
|
||||
->entity($invoice)
|
||||
->message($client->getSetting('custom_message_paid_invoice')) !!}
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
@if($invoice->isPayable())
|
||||
<form action="{{ route('client.invoices.bulk') }}" method="post">
|
||||
@csrf
|
||||
|
@ -12,6 +12,15 @@
|
||||
|
||||
@section('body')
|
||||
|
||||
@if(!$quote->isApproved() && !empty($client->getSetting('custom_message_unapproved_quote')))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{!! CustomMessage::client($client)
|
||||
->company($client->company)
|
||||
->entity($quote)
|
||||
->message($client->getSetting('custom_message_unapproved_quote')) !!}
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
@if(!$quote->isApproved())
|
||||
<form action="{{ route('client.quotes.bulk') }}" method="post">
|
||||
@csrf
|
||||
|
Loading…
Reference in New Issue
Block a user