1
0
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:
Benjamin Beganović 2020-04-13 03:48:23 +02:00 committed by GitHub
parent e3446e906f
commit f118f3bfda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 216 additions and 4 deletions

View 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()
{
//
}
}

View 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,
];
}
}

View 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';
}
}

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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",

View File

@ -0,0 +1,3 @@
<div class="alert border-blue-500 bg-blue-50 mt-2 mb-4">
{{ $slot }}
</div>

View File

@ -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">

View File

@ -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

View File

@ -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