Move email/ resources to mail/, added invoice generated email to admin, updated email template
This commit is contained in:
parent
f8453ae391
commit
0469d64577
@ -3,7 +3,6 @@
|
|||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
use App\Models\{Invoice,Site};
|
use App\Models\{Invoice,Site};
|
||||||
@ -15,7 +14,9 @@ class InvoiceEmail extends Command
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'invoice:email {site} {id}';
|
protected $signature = 'invoice:email'
|
||||||
|
.' {--s|site : Site ID}'
|
||||||
|
.' {id?}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
@ -31,21 +32,23 @@ class InvoiceEmail extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
Config::set('site',Site::findOrFail($this->argument('site')));
|
Config::set(
|
||||||
|
'site',
|
||||||
|
$this->option('site')
|
||||||
|
? Site::findOrFail($this->option('site'))
|
||||||
|
: Site::where('url',config('app.url'))->sole()
|
||||||
|
);
|
||||||
|
|
||||||
$o = Invoice::findOrFail($this->argument('id'));
|
$o = Invoice::findOrFail($this->argument('id'));
|
||||||
|
|
||||||
$result = Mail::to($o->account->user->email)->send(new \App\Mail\InvoiceEmail($o));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$o->print_status = TRUE;
|
$o->send();
|
||||||
//$o->reminders = $o->reminders('send');
|
|
||||||
$o->save();
|
$o->save();
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
dd($e);
|
dd($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
dump($result->getDebug());
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
|
|
||||||
@ -14,7 +15,11 @@ class InvoiceGenerate extends Command
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'invoice:generate {site} {account?} {--p|preview : Preview} {--l|list : List Items}';
|
protected $signature = 'invoice:generate'
|
||||||
|
.' {--l|list : List Items}'
|
||||||
|
.' {--p|preview : Preview}'
|
||||||
|
.' {--s|site : Site ID}'
|
||||||
|
.' {id?}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
@ -30,37 +35,50 @@ class InvoiceGenerate extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
Config::set('site',Site::findOrFail($this->argument('site')));
|
Config::set(
|
||||||
|
'site',
|
||||||
|
$this->option('site')
|
||||||
|
? Site::findOrFail($this->option('site'))
|
||||||
|
: Site::where('url',config('app.url'))->sole()
|
||||||
|
);
|
||||||
|
|
||||||
if ($this->argument('account'))
|
if ($this->argument('id'))
|
||||||
$accounts = collect()->push(Account::find($this->argument('account')));
|
$accounts = collect()->push(Account::find($this->argument('id')));
|
||||||
else
|
else
|
||||||
$accounts = Account::active()->get();
|
$accounts = Account::active()->get();
|
||||||
|
|
||||||
foreach ($accounts as $o) {
|
foreach ($accounts as $o) {
|
||||||
|
$items = $o->invoice_next(Carbon::now());
|
||||||
|
|
||||||
|
if (! $items->count()) {
|
||||||
|
$this->warn(sprintf('No items for account (%s) [%d]',$o->name,$o->id));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info(sprintf('Account: %s [%d]',$o->name,$o->lid));
|
||||||
$io = new Invoice;
|
$io = new Invoice;
|
||||||
$io->account_id = $o->id;
|
$io->account_id = $o->id;
|
||||||
|
|
||||||
foreach ($o->services(TRUE)->get() as $so) {
|
foreach ($items as $oo)
|
||||||
foreach ($so->next_invoice_items(FALSE) as $ooo)
|
$io->items_active->push($oo);
|
||||||
$io->items->push($ooo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are no items, no reason to do anything
|
// If there are no items, no reason to do anything
|
||||||
if (! $io->items->count() OR $io->total < 0)
|
if ($io->total < 0) {
|
||||||
|
$this->warn(sprintf(' - Invoice totals [%3.2f] - skipping',$io->total));
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$io->account_id = $o->id;
|
$io->account_id = $o->id;
|
||||||
|
|
||||||
if ($this->option('list')) {
|
if ($this->option('list')) {
|
||||||
$this->warn(sprintf('|%4s|%4s|%-50s|%8s|',
|
$this->line(sprintf('|%4s|%4s|%-50s|%8s|',
|
||||||
'SID',
|
'SID',
|
||||||
'PID',
|
'PID',
|
||||||
'Name',
|
'Name',
|
||||||
'Amount',
|
'Amount',
|
||||||
));
|
));
|
||||||
|
|
||||||
foreach ($io->items as $oo) {
|
foreach ($io->items_active as $oo) {
|
||||||
$this->info(sprintf('|%4s|%4s|%-50s|%8.2f|',
|
$this->info(sprintf('|%4s|%4s|%-50s|%8.2f|',
|
||||||
$oo->service_id,
|
$oo->service_id,
|
||||||
$oo->product_id,
|
$oo->product_id,
|
||||||
@ -70,8 +88,9 @@ class InvoiceGenerate extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dump($io);
|
||||||
if ($this->option('preview')) {
|
if ($this->option('preview')) {
|
||||||
$this->info(sprintf('Invoice for Account [%d] - [%d] items totalling [%3.2f]',$o->id,$io->items->count(),$io->total));
|
$this->info(sprintf('=> Invoice for Account [%d] - [%d] items totalling [%3.2f]',$o->id,$io->items_active->count(),$io->total));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,5 +100,7 @@ class InvoiceGenerate extends Command
|
|||||||
|
|
||||||
$io->pushNew();
|
$io->pushNew();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -52,7 +52,7 @@ class CancelRequest extends Mailable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.admin.service.cancel')
|
->markdown('mail.admin.service.cancel')
|
||||||
->subject($subject)
|
->subject($subject)
|
||||||
->with(['site'=>$this->service->site]);
|
->with(['site'=>$this->service->site]);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class ChangeRequest extends Mailable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.admin.service.change')
|
->markdown('mail.admin.service.change')
|
||||||
->subject($subject)
|
->subject($subject)
|
||||||
->with(['site'=>$this->service->site]);
|
->with(['site'=>$this->service->site]);
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Mail;
|
namespace App\Mail;
|
||||||
|
|
||||||
use App\Models\Site;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Mail\Mailable;
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\Config;
|
|
||||||
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
|
||||||
class InvoiceEmail extends Mailable
|
class InvoiceEmail extends Mailable implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Queueable, SerializesModels;
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
public $invoice;
|
protected Invoice $io;
|
||||||
public $site;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new message instance.
|
* Create a new message instance.
|
||||||
@ -25,28 +24,33 @@ class InvoiceEmail extends Mailable
|
|||||||
*/
|
*/
|
||||||
public function __construct(Invoice $o)
|
public function __construct(Invoice $o)
|
||||||
{
|
{
|
||||||
$this->invoice = $o;
|
$this->io = $o;
|
||||||
|
$this->queue = 'user';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the message.
|
* Get the message envelope.
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
*/
|
||||||
public function build()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
Config::set('site',Site::findOrFail($this->invoice->site_id));
|
return new Envelope(
|
||||||
$this->site = config('site');
|
subject: sprintf('Invoice %d for services, due %s',
|
||||||
|
$this->io->lid,
|
||||||
|
$this->io->due_at->format('Y-m-d')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $this
|
/**
|
||||||
->markdown('email.user.invoice',['site'=>config('site')])
|
* Get the message content definition.
|
||||||
->subject(sprintf( 'Invoice: %s - Total: $%s - Due: %s',
|
*/
|
||||||
$this->invoice->id,
|
public function content(): Content
|
||||||
number_format($this->invoice->total,2),
|
{
|
||||||
$this->invoice->due_at->format('Y-m-d')))
|
return new Content(
|
||||||
->with([
|
markdown: 'mail.invoice',
|
||||||
'user'=>$this->invoice->account->user,
|
with: [
|
||||||
'site'=>$this->invoice->account->user->site,
|
'io'=>$this->io,
|
||||||
]);
|
'site'=>$this->io->site,
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
57
app/Mail/InvoiceGeneratedAdmin.php
Normal file
57
app/Mail/InvoiceGeneratedAdmin.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
|
||||||
|
class InvoiceGeneratedAdmin extends Mailable implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected Invoice $io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @param Invoice $o
|
||||||
|
*/
|
||||||
|
public function __construct(Invoice $o)
|
||||||
|
{
|
||||||
|
$this->io = $o;
|
||||||
|
$this->queue = 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message envelope.
|
||||||
|
*/
|
||||||
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
|
return new Envelope(
|
||||||
|
subject: sprintf('Invoice %d generated for %s, due %s',
|
||||||
|
$this->io->lid,
|
||||||
|
$this->io->account->name,
|
||||||
|
$this->io->due_at->format('Y-m-d')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message content definition.
|
||||||
|
*/
|
||||||
|
public function content(): Content
|
||||||
|
{
|
||||||
|
return new Content(
|
||||||
|
markdown: 'mail.admin.invoice.generated',
|
||||||
|
with: [
|
||||||
|
'io'=>$this->io,
|
||||||
|
'site'=>$this->io->site,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,7 @@ class OrderRequest extends Mailable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.admin.order.approve')
|
->markdown('mail.admin.order.approve')
|
||||||
->subject($subject)
|
->subject($subject)
|
||||||
->with(['site'=>$this->service->site]);
|
->with(['site'=>$this->service->site]);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ class OrderRequestApprove extends Mailable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.admin.order.approve')
|
->markdown('mail.admin.order.approve')
|
||||||
->subject($subject)
|
->subject($subject)
|
||||||
->with(['site'=>$this->so->site]);
|
->with(['site'=>$this->so->site]);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class OrderRequestReject extends Mailable
|
|||||||
Config::set('site',$this->service->site);
|
Config::set('site',$this->service->site);
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.admin.order.reject')
|
->markdown('mail.admin.order.reject')
|
||||||
->subject(sprintf('Your order: #%s was rejected',$this->service->id))
|
->subject(sprintf('Your order: #%s was rejected',$this->service->id))
|
||||||
->with(['site'=>$this->service->site]);
|
->with(['site'=>$this->service->site]);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class SocialLink extends Mailable
|
|||||||
Config::set('site',$this->site);
|
Config::set('site',$this->site);
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.system.social_link')
|
->markdown('mail.system.social_link')
|
||||||
->subject('Link your Account')
|
->subject('Link your Account')
|
||||||
->with([
|
->with([
|
||||||
'site'=>$this->site,
|
'site'=>$this->site,
|
||||||
|
@ -36,7 +36,7 @@ class TestEmail extends Mailable
|
|||||||
Config::set('site',$this->user->site);
|
Config::set('site',$this->user->site);
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.system.test_email')
|
->markdown('mail.system.test_email')
|
||||||
->subject('Just a test...')
|
->subject('Just a test...')
|
||||||
->with([
|
->with([
|
||||||
'site'=>$this->user->site,
|
'site'=>$this->user->site,
|
||||||
|
@ -39,7 +39,7 @@ class TrafficMismatch extends Mailable
|
|||||||
Config::set('site',$x=Site::find(1)); // @todo To auto determine;
|
Config::set('site',$x=Site::find(1)); // @todo To auto determine;
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->markdown('email.system.broadband_traffic_mismatch')
|
->markdown('mail.system.broadband_traffic_mismatch')
|
||||||
->subject('Traffic Mismatch for '.$this->date)
|
->subject('Traffic Mismatch for '.$this->date)
|
||||||
->with([
|
->with([
|
||||||
'site'=>$x,
|
'site'=>$x,
|
||||||
|
@ -253,13 +253,15 @@ class Account extends Model implements IDs
|
|||||||
|
|
||||||
/* METHODS */
|
/* METHODS */
|
||||||
|
|
||||||
public function invoice_next(): Collection
|
public function invoice_next(Carbon $date=NULL): Collection
|
||||||
{
|
{
|
||||||
// Collect all the invoice items for our active services
|
$svs = $this
|
||||||
$nextdate = ($x=$this
|
|
||||||
->services_active
|
->services_active
|
||||||
->filter(fn($item)=>$item->isBilled() && $item->invoice_next)
|
->filter(fn($item)=>$item->isBilled() && $item->invoice_next)
|
||||||
->sortBy(fn($item)=>(string)$item->invoice_next))
|
->sortBy(fn($item)=>(string)$item->invoice_next);
|
||||||
|
|
||||||
|
// Collect all the invoice items for our active services
|
||||||
|
$nextdate = $date ?: $svs
|
||||||
->first()
|
->first()
|
||||||
?->invoice_next
|
?->invoice_next
|
||||||
->clone();
|
->clone();
|
||||||
@ -271,7 +273,7 @@ class Account extends Model implements IDs
|
|||||||
->subDay()
|
->subDay()
|
||||||
->endOfday();
|
->endOfday();
|
||||||
|
|
||||||
$items = $x
|
$items = $svs
|
||||||
->filter(fn($item)=>$item->invoice_next->lessThan($nextitemsdate))
|
->filter(fn($item)=>$item->invoice_next->lessThan($nextitemsdate))
|
||||||
->sortBy(fn($item)=>$item->invoice_next.$item->name)
|
->sortBy(fn($item)=>$item->invoice_next.$item->name)
|
||||||
->map(fn($item)=>$item->next_invoice_items($nextitemsdate))
|
->map(fn($item)=>$item->next_invoice_items($nextitemsdate))
|
||||||
|
@ -75,7 +75,7 @@ class Charge extends Model
|
|||||||
return sprintf('%s %s',
|
return sprintf('%s %s',
|
||||||
$this->description,
|
$this->description,
|
||||||
$this->getAttribute('attributes')
|
$this->getAttribute('attributes')
|
||||||
? join('|',unserialize($this->getAttribute('attributes')))
|
? $this->getAttribute('attributes')->join('|')
|
||||||
: '');
|
: '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@ use Clarkeash\Doorman\Models\Invite;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Leenooks\Casts\LeenooksCarbon;
|
use Leenooks\Casts\LeenooksCarbon;
|
||||||
use Leenooks\Traits\ScopeActive;
|
use Leenooks\Traits\ScopeActive;
|
||||||
|
|
||||||
use App\Casts\CollectionOrNull;
|
use App\Casts\CollectionOrNull;
|
||||||
use App\Interfaces\IDs;
|
use App\Interfaces\IDs;
|
||||||
use App\Traits\PushNew;
|
use App\Mail\{InvoiceEmail,InvoiceGeneratedAdmin};
|
||||||
|
use App\Traits\{PushNew,SiteID};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Invoice
|
* Class Invoice
|
||||||
@ -36,7 +38,7 @@ use App\Traits\PushNew;
|
|||||||
*/
|
*/
|
||||||
class Invoice extends Model implements IDs
|
class Invoice extends Model implements IDs
|
||||||
{
|
{
|
||||||
use PushNew,ScopeActive;
|
use PushNew,ScopeActive,SiteID;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'created_at' => 'datetime:Y-m-d',
|
'created_at' => 'datetime:Y-m-d',
|
||||||
@ -95,8 +97,8 @@ class Invoice extends Model implements IDs
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Array of items that can be updated with PushNew
|
// Our related items that need to be updated when we call pushNew()
|
||||||
protected $pushable = ['items'];
|
protected $pushable = ['items_active'];
|
||||||
|
|
||||||
protected $with = [
|
protected $with = [
|
||||||
'items_active:id,start_at,stop_at,quantity,price_base,discount_amt,item_type,product_id,service_id,invoice_id',
|
'items_active:id,start_at,stop_at,quantity,price_base,discount_amt,item_type,product_id,service_id,invoice_id',
|
||||||
@ -108,6 +110,21 @@ class Invoice extends Model implements IDs
|
|||||||
|
|
||||||
/* STATIC METHODS */
|
/* STATIC METHODS */
|
||||||
|
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::created(function($model) {
|
||||||
|
// Send an email to an admin that the invoice was created
|
||||||
|
$uo = User::where('email',config('osb.admin'))->sole();
|
||||||
|
|
||||||
|
Mail::to($uo->email)
|
||||||
|
->send(new InvoiceGeneratedAdmin($model));
|
||||||
|
|
||||||
|
// @todo Queue an email to the user
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This works out what multiplier to use to change billing periods
|
* This works out what multiplier to use to change billing periods
|
||||||
*
|
*
|
||||||
@ -565,6 +582,28 @@ class Invoice extends Model implements IDs
|
|||||||
return parent::save($options);
|
return parent::save($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record the invoice being sent
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function send(): int
|
||||||
|
{
|
||||||
|
$result = Mail::to($this->account->user->email)
|
||||||
|
->send(new InvoiceEmail($this));
|
||||||
|
|
||||||
|
$this->print_status = TRUE;
|
||||||
|
|
||||||
|
if ($this->reminders->has('sent'))
|
||||||
|
$this->reminders->put('sent',collect($this->reminders->get('sent')));
|
||||||
|
else
|
||||||
|
$this->reminders->put('sent',collect());
|
||||||
|
|
||||||
|
$this->reminders->get('sent')->push(Carbon::now());
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Group the invoice items by product ID, returning the number of products and total
|
* Group the invoice items by product ID, returning the number of products and total
|
||||||
*
|
*
|
||||||
@ -574,12 +613,20 @@ class Invoice extends Model implements IDs
|
|||||||
{
|
{
|
||||||
$return = collect();
|
$return = collect();
|
||||||
|
|
||||||
foreach ($this->items_active->groupBy('product_id') as $o) {
|
foreach ($this->items_active->groupBy('product_id') as $id => $o) {
|
||||||
|
if (! $id) {
|
||||||
|
$po = new Product;
|
||||||
|
$po->translate = new ProductTranslate;
|
||||||
|
$po->translate->name_detail = 'Miscellanious';
|
||||||
|
|
||||||
|
} else {
|
||||||
$po = $o->first()->product;
|
$po = $o->first()->product;
|
||||||
|
}
|
||||||
|
|
||||||
$po->count = count($o->pluck('service_id')->unique());
|
$po->count = count($o->pluck('service_id')->unique());
|
||||||
|
|
||||||
$return->push([
|
$return->push([
|
||||||
'product' => $o->first()->product,
|
'product' => $po,
|
||||||
'services' => $o->pluck('service_id')->unique(),
|
'services' => $o->pluck('service_id')->unique(),
|
||||||
'sub_total' => $o->sum('sub_total'),
|
'sub_total' => $o->sum('sub_total'),
|
||||||
'tax_total' => $o->sum('tax'),
|
'tax_total' => $o->sum('tax'),
|
||||||
@ -589,4 +636,21 @@ class Invoice extends Model implements IDs
|
|||||||
|
|
||||||
return $return->sortBy('product.name');
|
return $return->sortBy('product.name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function summary_other(): Collection
|
||||||
|
{
|
||||||
|
$result = collect();
|
||||||
|
|
||||||
|
foreach ($this->items_active->whereNull('service_id') as $o) {
|
||||||
|
dd($o);
|
||||||
|
$result->push([
|
||||||
|
'description' => 'Account Items',
|
||||||
|
'sub_total' => $o->sub_total,
|
||||||
|
'tax_total' => $o->tax,
|
||||||
|
'total' => $o->total,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -52,6 +52,22 @@ class InvoiceItem extends Model
|
|||||||
127 => 'Rounding', // * SERVICE_ID is NULL, MODULE_ID is NULL, MODULE_REF is NULL
|
127 => 'Rounding', // * SERVICE_ID is NULL, MODULE_ID is NULL, MODULE_REF is NULL
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/* STATIC */
|
||||||
|
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::created(function($model) {
|
||||||
|
// If this items were a charge, we'll update the charge to processed
|
||||||
|
if (($model->module_id === 30) && $model->module_ref) {
|
||||||
|
$o = Charge::findOrfail($model->module_ref);
|
||||||
|
$o->processed = TRUE;
|
||||||
|
$o->save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* RELATIONS */
|
/* RELATIONS */
|
||||||
|
|
||||||
public function invoice()
|
public function invoice()
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
namespace App\Traits;
|
namespace App\Traits;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
trait PushNew
|
trait PushNew
|
||||||
{
|
{
|
||||||
@ -22,7 +23,7 @@ trait PushNew
|
|||||||
// us to recurse into all of these nested relations for the model instance.
|
// us to recurse into all of these nested relations for the model instance.
|
||||||
foreach ($this->relations as $key => $models) {
|
foreach ($this->relations as $key => $models) {
|
||||||
// If we are not pushable, jump to the next item.
|
// If we are not pushable, jump to the next item.
|
||||||
if (! is_array($this->pushable) OR ! in_array($key,$this->pushable))
|
if ((! is_array($this->pushable)) || (! in_array($key,$this->pushable)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$models = $models instanceof Collection
|
$models = $models instanceof Collection
|
||||||
@ -32,6 +33,8 @@ trait PushNew
|
|||||||
$model->setAttribute($this->getForeignKey(),$this->{$this->getKeyName()});
|
$model->setAttribute($this->getForeignKey(),$this->{$this->getKeyName()});
|
||||||
|
|
||||||
if (! $model->pushNew()) {
|
if (! $model->pushNew()) {
|
||||||
|
Log::alert('Failed to save model',['attrs'=>$model->getAttributes()]);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,6 @@ return [
|
|||||||
'language_id' => 1,
|
'language_id' => 1,
|
||||||
'invoice_text' => 'Thank you for using our Internet Services.',
|
'invoice_text' => 'Thank you for using our Internet Services.',
|
||||||
'invoice_days' => 30, // Days in Advance to invoice
|
'invoice_days' => 30, // Days in Advance to invoice
|
||||||
|
'invoice_review' => 3, // Days to review an invoice before it is emailed
|
||||||
'admin' => env('APP_ADMIN'),
|
'admin' => env('APP_ADMIN'),
|
||||||
];
|
];
|
@ -1,27 +0,0 @@
|
|||||||
@component('mail::message',['site'=>$site,'heading'=>'Invoice: '.$invoice->id])
|
|
||||||
Hi {{ isset($user) ? $user->name_full.',' : '' }}
|
|
||||||
|
|
||||||
A new invoice has been generated on your account. A summary of that invoice is below.
|
|
||||||
|
|
||||||
@component('mail::table')
|
|
||||||
| # | ID | Name | Amount |
|
|
||||||
| -: | - |:-----| ------:|
|
|
||||||
@foreach ($invoice->summary_products() as $item)
|
|
||||||
| {{ $item['services']->count() }} | {{ $item['product']->lid }} | {{ $item['product']->name }} | ${{ number_format($item['total'],2) }} |
|
|
||||||
@endforeach
|
|
||||||
||| Sub Total | ${{ number_format($invoice->sub_total,2) }} |
|
|
||||||
||| Tax | ${{ number_format($invoice->tax_total,2) }} |
|
|
||||||
||| Total | ${{ number_format($invoice->total,2) }} |
|
|
||||||
||| Payments | ${{ number_format($invoice->paid,2) }} |
|
|
||||||
||| Still Due | ${{ number_format($invoice->due,2) }} |
|
|
||||||
@endcomponent
|
|
||||||
|
|
||||||
If you would like a PDF copy of that invoice, please click on the link below:
|
|
||||||
|
|
||||||
@component('mail::panel',['url'=>$invoice->download_link()])
|
|
||||||
Download PDF
|
|
||||||
@endcomponent
|
|
||||||
|
|
||||||
Thanks,<br>
|
|
||||||
{{ config('mail.from.name') }}
|
|
||||||
@endcomponent
|
|
25
resources/views/mail/admin/invoice/generated.blade.php
Normal file
25
resources/views/mail/admin/invoice/generated.blade.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@component('mail::message',['site'=>$site,'heading'=>'Invoice: #'.$io->id,'subheading'=>sprintf('Due: <strong>%s</strong>',$io->due_at->format('Y-m-d'))])
|
||||||
|
Hi {{ isset($user) ? $user->name_full.',' : '' }}
|
||||||
|
|
||||||
|
A new invoice has been generated for <strong>{{ $io->account->name }}</strong>. A summary of that invoice is below:
|
||||||
|
|
||||||
|
@component('mail::table')
|
||||||
|
| ID | # | Name | Amount |
|
||||||
|
| -: | -: |:-----| ------:|
|
||||||
|
@foreach ($io->summary_products() as $item)
|
||||||
|
| {{ $item['product']->lid }} | {{ $item['services']->count() }} | {{ $item['product']->name }} | ${{ number_format($item['total'],2) }} |
|
||||||
|
@endforeach
|
||||||
|
||| Sub Total | ${{ number_format($io->sub_total,2) }} |
|
||||||
|
||| Tax | ${{ number_format($io->tax_total,2) }} |
|
||||||
|
||| **Total** | **${{ number_format($io->total,2) }}** |
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
This invoice will be automatically emailed in {{ config('osb.invoice_review') }} days time.
|
||||||
|
|
||||||
|
@component('mail::button',['url'=>url('u/invoice',$io->id)])
|
||||||
|
Review
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
Thanks,<br>
|
||||||
|
{{ config('mail.from.name') }}
|
||||||
|
@endcomponent
|
@ -1,8 +1,6 @@
|
|||||||
@component('mail::message',['site'=>$site])
|
@component('mail::message',['site'=>$site])
|
||||||
# Your order was rejected.
|
# Your order was rejected.
|
||||||
|
|
||||||
@component('mail::panel')
|
|
||||||
|
|
||||||
@component('mail::table')
|
@component('mail::table')
|
||||||
| Service | Details |
|
| Service | Details |
|
||||||
| :---------- | :---------------- |
|
| :---------- | :---------------- |
|
||||||
@ -22,8 +20,6 @@
|
|||||||
|
|
||||||
**REASON:** {{ $reason }}
|
**REASON:** {{ $reason }}
|
||||||
|
|
||||||
@endcomponent
|
|
||||||
|
|
||||||
Thanks,<br>
|
Thanks,<br>
|
||||||
{{ config('app.name') }}
|
{{ config('app.name') }}
|
||||||
@endcomponent
|
@endcomponent
|
29
resources/views/mail/invoice.blade.php
Normal file
29
resources/views/mail/invoice.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@component('mail::message',['site'=>$site,'heading'=>'Invoice: #'.$io->lid,'subheading'=>sprintf('Due: <strong>%s</strong>',$io->due_at->format('Y-m-d'))])
|
||||||
|
Hi {{ isset($user) ? $user->name_full.',' : '' }}
|
||||||
|
|
||||||
|
A new invoice has been generated on your account. A summary of that invoice is below:
|
||||||
|
|
||||||
|
@component('mail::table')
|
||||||
|
| ID | # | Name | Amount |
|
||||||
|
| -: | -: |:-----| ------:|
|
||||||
|
@foreach ($io->summary_products() as $item)
|
||||||
|
| {{ $item['product']->lid }} | {{ $item['services']->count() }} | {{ $item['product']->name }} | ${{ number_format($item['total'],2) }} |
|
||||||
|
@endforeach
|
||||||
|
||| Sub Total | ${{ number_format($io->sub_total,2) }} |
|
||||||
|
||| Tax | ${{ number_format($io->tax_total,2) }} |
|
||||||
|
||| **Total** | **${{ number_format($io->total,2) }}** |
|
||||||
|
@if($io->paid)
|
||||||
|
||| Payments | ${{ number_format($io->paid,2) }} |
|
||||||
|
||| Still Due | ${{ number_format($io->due,2) }} |
|
||||||
|
@endif
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
If you would like a PDF copy of that invoice, please click on the link below:
|
||||||
|
|
||||||
|
@component('mail::button',['url'=>$io->download_link()])
|
||||||
|
Download
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
Thanks,<br>
|
||||||
|
{{ config('mail.from.name') }}
|
||||||
|
@endcomponent
|
@ -5,8 +5,8 @@ A request was made to link your account to a social login.
|
|||||||
If you didnt make this request, you can ignore this, and the request will be ignored.
|
If you didnt make this request, you can ignore this, and the request will be ignored.
|
||||||
If you did make the request, then please enter the code displayed below.
|
If you did make the request, then please enter the code displayed below.
|
||||||
|
|
||||||
@component('mail::panel')
|
@component('mail::button')
|
||||||
{{ $token }}
|
{{ $token }}
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
Once you've keyed in this code, you'll be able to login to your account using your social login instead of a username and a password.
|
Once you've keyed in this code, you'll be able to login to your account using your social login instead of a username and a password.
|
||||||
@ -15,7 +15,7 @@ Thanks,
|
|||||||
|
|
||||||
{{ config('mail.from.name') }}
|
{{ config('mail.from.name') }}
|
||||||
|
|
||||||
@component('mail::subcopy')
|
@component('mail::subcontent')
|
||||||
If you didnt make this request, you can safely ignore this email - no change was made to your account, nor was it accessed by an unauthorised person.
|
If you didnt make this request, you can safely ignore this email - no change was made to your account, nor was it accessed by an unauthorised person.
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endcomponent
|
@endcomponent
|
@ -6,12 +6,12 @@ You are receiving this email because we received a password reset request for yo
|
|||||||
If you did not request a password reset, no further action is required.
|
If you did not request a password reset, no further action is required.
|
||||||
|
|
||||||
To reset your password, please follow this link, or click on the URL below:
|
To reset your password, please follow this link, or click on the URL below:
|
||||||
@component('mail::panel',['url'=>$reset_link])
|
@component('mail::button',['url'=>$reset_link])
|
||||||
Reset Password
|
Reset Password
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
@component('mail::subcopy')
|
@component('mail::subcontent')
|
||||||
Reset password: {{ $reset_link }}
|
Reset password: {{ $reset_link }}
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
Thanks,<br>
|
Thanks,<br>
|
@ -128,6 +128,19 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
@endforeach
|
@endforeach
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
@if($o->summary_other()->count())
|
||||||
|
<tr>
|
||||||
|
<td colspan="7">{{ $item['description'] }}</td>
|
||||||
|
</tr>
|
||||||
|
@foreach($o->summary_other() as $item)
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
|
||||||
|
<td>{{ $item['description'] }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
9
resources/views/vendor/mail/html/button.blade.php
vendored
Normal file
9
resources/views/vendor/mail/html/button.blade.php
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<div style="margin: auto; text-align: center; padding-top: 20px;padding-bottom: 20px;">
|
||||||
|
<div class="button">
|
||||||
|
@isset($url)
|
||||||
|
<a href="{{ $url }}">{{ $slot }}</a>
|
||||||
|
@else
|
||||||
|
{{ $slot }}
|
||||||
|
@endisset
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,3 +1 @@
|
|||||||
<div class="footer">
|
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
||||||
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
|
||||||
</div>
|
|
@ -1,6 +1,5 @@
|
|||||||
<div class="header">
|
<img class="right" src="{{ url($site->email_logo) }}"><br>
|
||||||
<div class="fixedw">
|
<div class="heading">{{ $slot }}</div>
|
||||||
<img src="{{ url($site->email_logo) }}"><br>
|
@if($subheading)
|
||||||
<div class="subject">{{ $slot }}</div>
|
<div class="subheading">{!! $subheading !!}</div>
|
||||||
</div>
|
@endif
|
||||||
</div>
|
|
@ -5,21 +5,28 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta name="color-scheme" content="light only">
|
<meta name="color-scheme" content="light only">
|
||||||
<meta name="supported-color-schemes" content="light only">
|
<meta name="supported-color-schemes" content="light only">
|
||||||
|
{{--
|
||||||
<link href='http://fonts.googleapis.com/css?family=Bree+Serif' rel='stylesheet' type='text/css'>
|
<link href='http://fonts.googleapis.com/css?family=Bree+Serif' rel='stylesheet' type='text/css'>
|
||||||
|
--}}
|
||||||
<link href="http://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900,400italic,300italic" rel="stylesheet" type="text/css">
|
<link href="http://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900,400italic,300italic" rel="stylesheet" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<section class="header">
|
||||||
|
<div class="fixedw main-header">
|
||||||
{{ $header ?? '' }}
|
{{ $header ?? '' }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<section class="content">
|
<section class="content">
|
||||||
<div class="fixedw main-body">
|
<div class="fixedw main-body">
|
||||||
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ $subcopy ?? '' }}
|
{{ $subcontent ?? '' }}
|
||||||
</section>
|
</section>
|
||||||
|
<section class="footer">
|
||||||
|
<div class="fixedw main-footer">
|
||||||
{{ $footer ?? '' }}
|
{{ $footer ?? '' }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,7 +1,7 @@
|
|||||||
@component('mail::layout')
|
@component('mail::layout')
|
||||||
{{-- Header --}}
|
{{-- Header --}}
|
||||||
@slot('header')
|
@slot('header')
|
||||||
@component('mail::header',['site'=>$site])
|
@component('mail::header',['site'=>$site,'subheading'=>$subheading ?? NULL])
|
||||||
{{ $heading }}
|
{{ $heading }}
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
@ -9,11 +9,11 @@
|
|||||||
{{-- Body --}}
|
{{-- Body --}}
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
|
|
||||||
{{-- Subcopy --}}
|
{{-- Sub Content --}}
|
||||||
@isset($subcopy)
|
@isset($subcontent)
|
||||||
@slot('subcopy')
|
@slot('subcontent')
|
||||||
@component('mail::subcopy')
|
@component('mail::subcontent')
|
||||||
{{ $subcopy }}
|
{{ $subcontent }}
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
@endisset
|
@endisset
|
||||||
@ -21,11 +21,9 @@
|
|||||||
{{-- Footer --}}
|
{{-- Footer --}}
|
||||||
@slot('footer')
|
@slot('footer')
|
||||||
@component('mail::footer')
|
@component('mail::footer')
|
||||||
<div class="fixedw" style="text-align: right; font-size: 0.8em;">
|
|
||||||
{{ config('mail.from.name') }}<br>
|
{{ config('mail.from.name') }}<br>
|
||||||
{!! $site->address->join('<br>') !!}<br>
|
{!! $site->address->join('<br>') !!}<br>
|
||||||
{{ $site->site_email }}
|
{{ $site->site_email }}
|
||||||
</div>
|
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
@endcomponent
|
@endcomponent
|
@ -1,9 +0,0 @@
|
|||||||
<div style="margin: auto; text-align: center; padding-bottom: 20px;">
|
|
||||||
<div class="panel">
|
|
||||||
@isset($url)
|
|
||||||
<a href="{{ $url }}">{{ $slot }}</a>
|
|
||||||
@else
|
|
||||||
{{ $slot }}
|
|
||||||
@endisset
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,3 +1 @@
|
|||||||
<div class="light-box">
|
|
||||||
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
||||||
</div>
|
|
146
resources/views/vendor/mail/html/themes/default.css
vendored
146
resources/views/vendor/mail/html/themes/default.css
vendored
@ -1,88 +1,104 @@
|
|||||||
body{
|
body{
|
||||||
margin: 0 auto;
|
margin:0 auto;
|
||||||
font-family: 'Bree Serif';
|
font-family:'Roboto', serif;
|
||||||
background: #f4f4f4;
|
color:#121212;
|
||||||
color: #6c7584;
|
font-size:1.0em;
|
||||||
font-size: 1.2em;
|
padding-top:20px;
|
||||||
}
|
}
|
||||||
.header{
|
.header{
|
||||||
background: #232323;
|
margin-bottom:0;
|
||||||
border-bottom: 5px solid #454d59;
|
|
||||||
padding: 20px 0px 10px 0px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
color: #f4f4f4;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
}
|
||||||
.footer{
|
.footer{
|
||||||
background: #232323;
|
|
||||||
border-top: 5px solid #454d59;
|
|
||||||
padding: 10px 0px 20px 0px;
|
|
||||||
margin-top: 30px;
|
|
||||||
color: #f4f4f4;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
}
|
||||||
.subject{
|
.main-header{
|
||||||
font-weight: 300;
|
background:#fafafa;
|
||||||
font-family: 'Bree Serif',serif;
|
border-top-left-radius:10px;
|
||||||
font-size: 1.5em;
|
border-top-right-radius:10px;
|
||||||
/* text-align: right; */
|
color:#121212;
|
||||||
|
font-weight:400;
|
||||||
|
padding:10px 20px;
|
||||||
|
border-top:1px solid #dbdbdb;
|
||||||
|
border-right:1px solid #dbdbdb;
|
||||||
|
border-left:1px solid #dbdbdb;
|
||||||
}
|
}
|
||||||
.panel{
|
.main-header img{
|
||||||
background:#454d59;
|
width:250px;
|
||||||
border-radius: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #f4f4f4;
|
|
||||||
font-size: 1.4em;
|
|
||||||
display: inline-block
|
|
||||||
}
|
}
|
||||||
.light-box{
|
.main-header .heading{
|
||||||
background: #f9f9f9;
|
font-weight:bold;
|
||||||
border-radius: 10px;
|
font-size:1.4em;
|
||||||
padding: 10px;
|
padding:5px 0;
|
||||||
font-weight: 300;
|
}
|
||||||
margin-top: 10px;
|
.main-header .subheading{
|
||||||
font-size: 0.8em;
|
font-size:0.8em;
|
||||||
margin-bottom: 10px;
|
padding:5px 0;
|
||||||
}
|
}
|
||||||
.main-body{
|
.main-body{
|
||||||
background: #ffffff;
|
background:#ffffff;
|
||||||
border-radius: 10px;
|
|
||||||
color:#6c7584;
|
|
||||||
font-weight: 400;
|
|
||||||
padding:10px 20px;
|
padding:10px 20px;
|
||||||
border-top:1px solid #dbdbdb;
|
border-top:1px solid #dbdbdb;
|
||||||
border-left:1px solid #dbdbdb;
|
border-left:1px solid #dbdbdb;
|
||||||
border-right:1px solid #dbdbdb;
|
border-right:1px solid #dbdbdb;
|
||||||
border-bottom:3px solid #dbdbdb;
|
border-bottom:1px solid #dbdbdb;
|
||||||
|
}
|
||||||
|
.main-body table{
|
||||||
|
width: 100%;
|
||||||
|
background:#fdfdfd;
|
||||||
|
border-radius:10px;
|
||||||
|
padding:10px;
|
||||||
|
font-weight:300;
|
||||||
|
margin-top:10px;
|
||||||
|
font-size:0.8em;
|
||||||
|
margin-bottom:10px;
|
||||||
|
border: 1px dashed #dbdbdb
|
||||||
}
|
}
|
||||||
.main-body table thead td{
|
.main-body table thead td{
|
||||||
font-weight: 300;
|
font-weight:300;
|
||||||
border-bottom: 1px solid #dbdbdb;
|
border-bottom:1px solid #dbdbdb;
|
||||||
color: #ccc
|
|
||||||
}
|
}
|
||||||
.main-body table td.title{
|
.main-body table td.title{
|
||||||
font-size: 1.1em;
|
font-size:1.1em;
|
||||||
line-height: 20px;
|
line-height:20px;
|
||||||
|
color:#6c7584
|
||||||
}
|
}
|
||||||
.main-body table td.title small{
|
.main-body table td.title small{
|
||||||
font-weight: 300;
|
font-weight:300;
|
||||||
font-size: 0.9em;
|
font-size:0.9em;
|
||||||
color: #6c7584
|
color:#6c7584
|
||||||
}
|
}
|
||||||
.main-body .note{
|
.main-body .note{
|
||||||
|
font-size:0.8em;
|
||||||
|
font-weight:300;
|
||||||
|
font-style:normal;
|
||||||
|
}
|
||||||
|
.main-footer{
|
||||||
|
background:#2f2f2f;
|
||||||
|
border-bottom-left-radius:10px;
|
||||||
|
border-bottom-right-radius:10px;
|
||||||
|
color:#fefefe;
|
||||||
|
padding:10px 20px;
|
||||||
|
margin: 0 0 0 auto;
|
||||||
|
border-bottom:1px solid #dbdbdb;
|
||||||
|
border-right:1px solid #dbdbdb;
|
||||||
|
border-left:1px solid #dbdbdb;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
font-weight: 300;
|
text-align: right;
|
||||||
font-style: normal;
|
|
||||||
}
|
}
|
||||||
.panel a{
|
.button{
|
||||||
text-decoration: underline;
|
background:#2f2f2f;
|
||||||
color: #f4f4f4;
|
border-radius:5px;
|
||||||
|
padding:10px;
|
||||||
|
color:#fafafa;
|
||||||
|
font-size:1em;
|
||||||
|
display:inline-block
|
||||||
}
|
}
|
||||||
.panel a:hover{
|
.button a{
|
||||||
text-decoration: none;
|
text-decoration:none;
|
||||||
color: #ffffff;
|
color:#fafafa;
|
||||||
|
}
|
||||||
|
.button a:hover{
|
||||||
|
text-decoration:none;
|
||||||
|
color:#ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- TO VALIDATE -- */
|
/* -- TO VALIDATE -- */
|
||||||
@ -114,15 +130,17 @@ h3{
|
|||||||
color: #333;
|
color: #333;
|
||||||
font-size:18px;
|
font-size:18px;
|
||||||
}
|
}
|
||||||
.links table td span, .links table td a{font-weight: 400}
|
.links table td span, .links table td a{
|
||||||
.border-l{border-left:1px solid #ccc}
|
font-weight: 400
|
||||||
|
}
|
||||||
|
|
||||||
.apikey{font-size: 18px; color:#333}
|
.apikey{font-size: 18px; color:#333}
|
||||||
.apikey p{border-bottom: 1px solid #dbdbdb; padding: 10px 0 10px 0;margin: 0 0;}
|
.apikey p{border-bottom: 1px solid #dbdbdb; padding: 10px 0 10px 0;margin: 0 0;}
|
||||||
.apikey p.last{border-bottom: none}
|
.apikey p.last{border-bottom: none}
|
||||||
.apikey small{font-size: 80%; font-weight: 300}
|
.apikey small{font-size: 80%; font-weight: 300}
|
||||||
.twitter{padding: 20px; font-weight: 300;font-size:16px;}
|
|
||||||
.fixedw{width: 80%; margin: 0 auto;}
|
.fixedw{width: 80%; margin: 0 auto;}
|
||||||
.right{float:right}
|
.right{float:right}
|
||||||
.left{float:left}
|
.left{float:left}
|
||||||
.clear{clear: both;}
|
.clear{clear: both;}
|
||||||
table thead td {font-size: 16px;}
|
|
||||||
|
pre {white-space:pre-wrap;}
|
1
resources/views/vendor/mail/text/subcontent.blade.php
vendored
Normal file
1
resources/views/vendor/mail/text/subcontent.blade.php
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{ $slot }}
|
Loading…
Reference in New Issue
Block a user