diff --git a/app/Console/Commands/InvoiceEmail.php b/app/Console/Commands/InvoiceEmail.php
index 0263658..8b8ded1 100644
--- a/app/Console/Commands/InvoiceEmail.php
+++ b/app/Console/Commands/InvoiceEmail.php
@@ -3,7 +3,6 @@
namespace App\Console\Commands;
use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Mail;
use Illuminate\Console\Command;
use App\Models\{Invoice,Site};
@@ -15,7 +14,9 @@ class InvoiceEmail extends Command
*
* @var string
*/
- protected $signature = 'invoice:email {site} {id}';
+ protected $signature = 'invoice:email'
+ .' {--s|site : Site ID}'
+ .' {id?}';
/**
* The console command description.
@@ -31,21 +32,23 @@ class InvoiceEmail extends Command
*/
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'));
- $result = Mail::to($o->account->user->email)->send(new \App\Mail\InvoiceEmail($o));
-
try {
- $o->print_status = TRUE;
- //$o->reminders = $o->reminders('send');
+ $o->send();
$o->save();
} catch (\Exception $e) {
dd($e);
}
- dump($result->getDebug());
+ return self::SUCCESS;
}
}
\ No newline at end of file
diff --git a/app/Console/Commands/InvoiceGenerate.php b/app/Console/Commands/InvoiceGenerate.php
index 06d5357..b1e308d 100644
--- a/app/Console/Commands/InvoiceGenerate.php
+++ b/app/Console/Commands/InvoiceGenerate.php
@@ -2,6 +2,7 @@
namespace App\Console\Commands;
+use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
@@ -14,7 +15,11 @@ class InvoiceGenerate extends Command
*
* @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.
@@ -30,37 +35,50 @@ class InvoiceGenerate extends Command
*/
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'))
- $accounts = collect()->push(Account::find($this->argument('account')));
+ if ($this->argument('id'))
+ $accounts = collect()->push(Account::find($this->argument('id')));
else
$accounts = Account::active()->get();
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->account_id = $o->id;
- foreach ($o->services(TRUE)->get() as $so) {
- foreach ($so->next_invoice_items(FALSE) as $ooo)
- $io->items->push($ooo);
- }
+ foreach ($items as $oo)
+ $io->items_active->push($oo);
// 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;
+ }
$io->account_id = $o->id;
if ($this->option('list')) {
- $this->warn(sprintf('|%4s|%4s|%-50s|%8s|',
+ $this->line(sprintf('|%4s|%4s|%-50s|%8s|',
'SID',
'PID',
'Name',
'Amount',
));
- foreach ($io->items as $oo) {
+ foreach ($io->items_active as $oo) {
$this->info(sprintf('|%4s|%4s|%-50s|%8.2f|',
$oo->service_id,
$oo->product_id,
@@ -70,8 +88,9 @@ class InvoiceGenerate extends Command
}
}
+ //dump($io);
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;
}
@@ -81,5 +100,7 @@ class InvoiceGenerate extends Command
$io->pushNew();
}
+
+ return self::SUCCESS;
}
}
\ No newline at end of file
diff --git a/app/Mail/CancelRequest.php b/app/Mail/CancelRequest.php
index ec88251..125ff6d 100644
--- a/app/Mail/CancelRequest.php
+++ b/app/Mail/CancelRequest.php
@@ -52,7 +52,7 @@ class CancelRequest extends Mailable
}
return $this
- ->markdown('email.admin.service.cancel')
+ ->markdown('mail.admin.service.cancel')
->subject($subject)
->with(['site'=>$this->service->site]);
}
diff --git a/app/Mail/ChangeRequest.php b/app/Mail/ChangeRequest.php
index 48c7dbd..dca3113 100644
--- a/app/Mail/ChangeRequest.php
+++ b/app/Mail/ChangeRequest.php
@@ -52,7 +52,7 @@ class ChangeRequest extends Mailable
}
return $this
- ->markdown('email.admin.service.change')
+ ->markdown('mail.admin.service.change')
->subject($subject)
->with(['site'=>$this->service->site]);
}
diff --git a/app/Mail/InvoiceEmail.php b/app/Mail/InvoiceEmail.php
index 784f5c7..5b8bdda 100644
--- a/app/Mail/InvoiceEmail.php
+++ b/app/Mail/InvoiceEmail.php
@@ -2,21 +2,20 @@
namespace App\Mail;
-use App\Models\Site;
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 Illuminate\Support\Facades\Config;
use App\Models\Invoice;
-class InvoiceEmail extends Mailable
+class InvoiceEmail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
- public $invoice;
- public $site;
+ protected Invoice $io;
/**
* Create a new message instance.
@@ -25,28 +24,33 @@ class InvoiceEmail extends Mailable
*/
public function __construct(Invoice $o)
{
- $this->invoice = $o;
+ $this->io = $o;
+ $this->queue = 'user';
}
/**
- * Build the message.
- *
- * @return $this
+ * Get the message envelope.
*/
- public function build()
+ public function envelope(): Envelope
{
- Config::set('site',Site::findOrFail($this->invoice->site_id));
- $this->site = config('site');
+ return new Envelope(
+ 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')])
- ->subject(sprintf( 'Invoice: %s - Total: $%s - Due: %s',
- $this->invoice->id,
- number_format($this->invoice->total,2),
- $this->invoice->due_at->format('Y-m-d')))
- ->with([
- 'user'=>$this->invoice->account->user,
- 'site'=>$this->invoice->account->user->site,
- ]);
+ /**
+ * Get the message content definition.
+ */
+ public function content(): Content
+ {
+ return new Content(
+ markdown: 'mail.invoice',
+ with: [
+ 'io'=>$this->io,
+ 'site'=>$this->io->site,
+ ]
+ );
}
}
\ No newline at end of file
diff --git a/app/Mail/InvoiceGeneratedAdmin.php b/app/Mail/InvoiceGeneratedAdmin.php
new file mode 100644
index 0000000..3ea1f39
--- /dev/null
+++ b/app/Mail/InvoiceGeneratedAdmin.php
@@ -0,0 +1,57 @@
+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,
+ ]
+ );
+ }
+}
\ No newline at end of file
diff --git a/app/Mail/OrderRequest.php b/app/Mail/OrderRequest.php
index f175ed2..8dda474 100644
--- a/app/Mail/OrderRequest.php
+++ b/app/Mail/OrderRequest.php
@@ -52,7 +52,7 @@ class OrderRequest extends Mailable
}
return $this
- ->markdown('email.admin.order.approve')
+ ->markdown('mail.admin.order.approve')
->subject($subject)
->with(['site'=>$this->service->site]);
}
diff --git a/app/Mail/OrderRequestApprove.php b/app/Mail/OrderRequestApprove.php
index 3081701..5b59d52 100644
--- a/app/Mail/OrderRequestApprove.php
+++ b/app/Mail/OrderRequestApprove.php
@@ -51,7 +51,7 @@ class OrderRequestApprove extends Mailable
}
return $this
- ->markdown('email.admin.order.approve')
+ ->markdown('mail.admin.order.approve')
->subject($subject)
->with(['site'=>$this->so->site]);
}
diff --git a/app/Mail/OrderRequestReject.php b/app/Mail/OrderRequestReject.php
index c49042e..e334526 100644
--- a/app/Mail/OrderRequestReject.php
+++ b/app/Mail/OrderRequestReject.php
@@ -38,7 +38,7 @@ class OrderRequestReject extends Mailable
Config::set('site',$this->service->site);
return $this
- ->markdown('email.admin.order.reject')
+ ->markdown('mail.admin.order.reject')
->subject(sprintf('Your order: #%s was rejected',$this->service->id))
->with(['site'=>$this->service->site]);
}
diff --git a/app/Mail/SocialLink.php b/app/Mail/SocialLink.php
index d8ef032..8149a32 100644
--- a/app/Mail/SocialLink.php
+++ b/app/Mail/SocialLink.php
@@ -39,7 +39,7 @@ class SocialLink extends Mailable
Config::set('site',$this->site);
return $this
- ->markdown('email.system.social_link')
+ ->markdown('mail.system.social_link')
->subject('Link your Account')
->with([
'site'=>$this->site,
diff --git a/app/Mail/TestEmail.php b/app/Mail/TestEmail.php
index b2cb1f6..a8795ee 100644
--- a/app/Mail/TestEmail.php
+++ b/app/Mail/TestEmail.php
@@ -36,7 +36,7 @@ class TestEmail extends Mailable
Config::set('site',$this->user->site);
return $this
- ->markdown('email.system.test_email')
+ ->markdown('mail.system.test_email')
->subject('Just a test...')
->with([
'site'=>$this->user->site,
diff --git a/app/Mail/TrafficMismatch.php b/app/Mail/TrafficMismatch.php
index 7e3d85e..533c2c0 100644
--- a/app/Mail/TrafficMismatch.php
+++ b/app/Mail/TrafficMismatch.php
@@ -39,7 +39,7 @@ class TrafficMismatch extends Mailable
Config::set('site',$x=Site::find(1)); // @todo To auto determine;
return $this
- ->markdown('email.system.broadband_traffic_mismatch')
+ ->markdown('mail.system.broadband_traffic_mismatch')
->subject('Traffic Mismatch for '.$this->date)
->with([
'site'=>$x,
diff --git a/app/Models/Account.php b/app/Models/Account.php
index 1918ca2..de682e7 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -253,13 +253,15 @@ class Account extends Model implements IDs
/* METHODS */
- public function invoice_next(): Collection
+ public function invoice_next(Carbon $date=NULL): Collection
{
- // Collect all the invoice items for our active services
- $nextdate = ($x=$this
+ $svs = $this
->services_active
->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()
?->invoice_next
->clone();
@@ -271,7 +273,7 @@ class Account extends Model implements IDs
->subDay()
->endOfday();
- $items = $x
+ $items = $svs
->filter(fn($item)=>$item->invoice_next->lessThan($nextitemsdate))
->sortBy(fn($item)=>$item->invoice_next.$item->name)
->map(fn($item)=>$item->next_invoice_items($nextitemsdate))
diff --git a/app/Models/Charge.php b/app/Models/Charge.php
index aca17df..ca70721 100644
--- a/app/Models/Charge.php
+++ b/app/Models/Charge.php
@@ -75,7 +75,7 @@ class Charge extends Model
return sprintf('%s %s',
$this->description,
$this->getAttribute('attributes')
- ? join('|',unserialize($this->getAttribute('attributes')))
+ ? $this->getAttribute('attributes')->join('|')
: '');
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index cb5a583..de3e439 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -8,12 +8,14 @@ use Clarkeash\Doorman\Models\Invite;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Mail;
use Leenooks\Casts\LeenooksCarbon;
use Leenooks\Traits\ScopeActive;
use App\Casts\CollectionOrNull;
use App\Interfaces\IDs;
-use App\Traits\PushNew;
+use App\Mail\{InvoiceEmail,InvoiceGeneratedAdmin};
+use App\Traits\{PushNew,SiteID};
/**
* Class Invoice
@@ -36,7 +38,7 @@ use App\Traits\PushNew;
*/
class Invoice extends Model implements IDs
{
- use PushNew,ScopeActive;
+ use PushNew,ScopeActive,SiteID;
protected $casts = [
'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
- protected $pushable = ['items'];
+ // Our related items that need to be updated when we call pushNew()
+ protected $pushable = ['items_active'];
protected $with = [
'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 */
+ 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
*
@@ -565,6 +582,28 @@ class Invoice extends Model implements IDs
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
*
@@ -574,12 +613,20 @@ class Invoice extends Model implements IDs
{
$return = collect();
- foreach ($this->items_active->groupBy('product_id') as $o) {
- $po = $o->first()->product;
+ 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->count = count($o->pluck('service_id')->unique());
$return->push([
- 'product' => $o->first()->product,
+ 'product' => $po,
'services' => $o->pluck('service_id')->unique(),
'sub_total' => $o->sum('sub_total'),
'tax_total' => $o->sum('tax'),
@@ -589,4 +636,21 @@ class Invoice extends Model implements IDs
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;
+ }
}
\ No newline at end of file
diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php
index 49a726c..afc59ad 100644
--- a/app/Models/InvoiceItem.php
+++ b/app/Models/InvoiceItem.php
@@ -52,6 +52,22 @@ class InvoiceItem extends Model
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 */
public function invoice()
diff --git a/app/Traits/PushNew.php b/app/Traits/PushNew.php
index 3e76a17..551fa2e 100644
--- a/app/Traits/PushNew.php
+++ b/app/Traits/PushNew.php
@@ -8,6 +8,7 @@
namespace App\Traits;
use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Log;
trait PushNew
{
@@ -22,7 +23,7 @@ trait PushNew
// us to recurse into all of these nested relations for the model instance.
foreach ($this->relations as $key => $models) {
// 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;
$models = $models instanceof Collection
@@ -32,6 +33,8 @@ trait PushNew
$model->setAttribute($this->getForeignKey(),$this->{$this->getKeyName()});
if (! $model->pushNew()) {
+ Log::alert('Failed to save model',['attrs'=>$model->getAttributes()]);
+
return false;
}
}
diff --git a/config/osb.php b/config/osb.php
index dcede2c..288ee3e 100644
--- a/config/osb.php
+++ b/config/osb.php
@@ -4,5 +4,6 @@ return [
'language_id' => 1,
'invoice_text' => 'Thank you for using our Internet Services.',
'invoice_days' => 30, // Days in Advance to invoice
+ 'invoice_review' => 3, // Days to review an invoice before it is emailed
'admin' => env('APP_ADMIN'),
];
\ No newline at end of file
diff --git a/resources/views/email/user/invoice.blade.php b/resources/views/email/user/invoice.blade.php
deleted file mode 100644
index 5c78e0c..0000000
--- a/resources/views/email/user/invoice.blade.php
+++ /dev/null
@@ -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,
-{{ config('mail.from.name') }}
-@endcomponent
\ No newline at end of file
diff --git a/resources/views/mail/admin/invoice/generated.blade.php b/resources/views/mail/admin/invoice/generated.blade.php
new file mode 100644
index 0000000..70661fd
--- /dev/null
+++ b/resources/views/mail/admin/invoice/generated.blade.php
@@ -0,0 +1,25 @@
+@component('mail::message',['site'=>$site,'heading'=>'Invoice: #'.$io->id,'subheading'=>sprintf('Due: %s',$io->due_at->format('Y-m-d'))])
+Hi {{ isset($user) ? $user->name_full.',' : '' }}
+
+A new invoice has been generated for {{ $io->account->name }}. 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,
+{{ config('mail.from.name') }}
+@endcomponent
\ No newline at end of file
diff --git a/resources/views/email/admin/order/approve.blade.php b/resources/views/mail/admin/order/approve.blade.php
similarity index 100%
rename from resources/views/email/admin/order/approve.blade.php
rename to resources/views/mail/admin/order/approve.blade.php
diff --git a/resources/views/email/admin/order/reject.blade.php b/resources/views/mail/admin/order/reject.blade.php
similarity index 94%
rename from resources/views/email/admin/order/reject.blade.php
rename to resources/views/mail/admin/order/reject.blade.php
index d9abee2..b990e50 100644
--- a/resources/views/email/admin/order/reject.blade.php
+++ b/resources/views/mail/admin/order/reject.blade.php
@@ -1,8 +1,6 @@
@component('mail::message',['site'=>$site])
# Your order was rejected.
-@component('mail::panel')
-
@component('mail::table')
| Service | Details |
| :---------- | :---------------- |
@@ -22,8 +20,6 @@
**REASON:** {{ $reason }}
-@endcomponent
-
Thanks,
{{ config('app.name') }}
@endcomponent
\ No newline at end of file
diff --git a/resources/views/email/admin/service/cancel.blade.php b/resources/views/mail/admin/service/cancel.blade.php
similarity index 100%
rename from resources/views/email/admin/service/cancel.blade.php
rename to resources/views/mail/admin/service/cancel.blade.php
diff --git a/resources/views/email/admin/service/change.blade.php b/resources/views/mail/admin/service/change.blade.php
similarity index 100%
rename from resources/views/email/admin/service/change.blade.php
rename to resources/views/mail/admin/service/change.blade.php
diff --git a/resources/views/mail/invoice.blade.php b/resources/views/mail/invoice.blade.php
new file mode 100644
index 0000000..9ac6c83
--- /dev/null
+++ b/resources/views/mail/invoice.blade.php
@@ -0,0 +1,29 @@
+@component('mail::message',['site'=>$site,'heading'=>'Invoice: #'.$io->lid,'subheading'=>sprintf('Due: %s',$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,
+{{ config('mail.from.name') }}
+@endcomponent
\ No newline at end of file
diff --git a/resources/views/email/system/broadband_traffic_mismatch.blade.php b/resources/views/mail/system/broadband_traffic_mismatch.blade.php
similarity index 100%
rename from resources/views/email/system/broadband_traffic_mismatch.blade.php
rename to resources/views/mail/system/broadband_traffic_mismatch.blade.php
diff --git a/resources/views/email/system/social_link.blade.php b/resources/views/mail/system/social_link.blade.php
similarity index 90%
rename from resources/views/email/system/social_link.blade.php
rename to resources/views/mail/system/social_link.blade.php
index e504854..221e15d 100644
--- a/resources/views/email/system/social_link.blade.php
+++ b/resources/views/mail/system/social_link.blade.php
@@ -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 did make the request, then please enter the code displayed below.
-@component('mail::panel')
- {{ $token }}
+@component('mail::button')
+{{ $token }}
@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.
@@ -15,7 +15,7 @@ Thanks,
{{ 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.
@endcomponent
@endcomponent
\ No newline at end of file
diff --git a/resources/views/email/system/test_email.blade.php b/resources/views/mail/system/test_email.blade.php
similarity index 100%
rename from resources/views/email/system/test_email.blade.php
rename to resources/views/mail/system/test_email.blade.php
diff --git a/resources/views/email/user/passwordreset.blade.php b/resources/views/mail/user/passwordreset.blade.php
similarity index 77%
rename from resources/views/email/user/passwordreset.blade.php
rename to resources/views/mail/user/passwordreset.blade.php
index 14ece25..8a943b8 100644
--- a/resources/views/email/user/passwordreset.blade.php
+++ b/resources/views/mail/user/passwordreset.blade.php
@@ -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.
To reset your password, please follow this link, or click on the URL below:
-@component('mail::panel',['url'=>$reset_link])
- Reset Password
+@component('mail::button',['url'=>$reset_link])
+Reset Password
@endcomponent
-@component('mail::subcopy')
- Reset password: {{ $reset_link }}
+@component('mail::subcontent')
+Reset password: {{ $reset_link }}
@endcomponent
Thanks,
diff --git a/resources/views/theme/backend/adminlte/invoice/view.blade.php b/resources/views/theme/backend/adminlte/invoice/view.blade.php
index caffa71..c3a7979 100644
--- a/resources/views/theme/backend/adminlte/invoice/view.blade.php
+++ b/resources/views/theme/backend/adminlte/invoice/view.blade.php
@@ -128,6 +128,19 @@
@endforeach
@endforeach
@endforeach
+
+ @if($o->summary_other()->count())
+