Skip to content

Commit acd95d5

Browse files
committed
Send invoices, mark as paid
1 parent 58b70c8 commit acd95d5

File tree

11 files changed

+202
-50
lines changed

11 files changed

+202
-50
lines changed

resources/lang/en/lang.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,4 +349,11 @@
349349
'edit_invoice' => 'edit invoice',
350350
'invoice_updated' => 'invoice updated',
351351
'send_invoice' => 'send invoice',
352+
'quote_expired' => 'quote expired',
353+
'due_in' => 'due in',
354+
'you_have_paid_this_invoice' => 'you have paid this invoice',
355+
'pay_now' => 'pay now',
356+
'issued' => 'issued',
357+
'pay' => 'pay',
358+
'pay_invoice' => 'pay invoice',
352359
];

resources/views/invoices/partials/card-index.blade.php

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<th scope="col">{{ ucwords(__('laravel-crm::lang.paid')) }}</th>
3333
<th scope="col">{{ ucwords(__('laravel-crm::lang.due')) }}</th>
3434
<th scope="col">{{ ucwords(__('laravel-crm::lang.sent')) }}</th>
35-
<th scope="col" width="210"></th>
35+
<th scope="col" width="245"></th>
3636
</tr>
3737
</thead>
3838
<tbody>
@@ -61,19 +61,26 @@
6161
@livewire('send-invoice',[
6262
'invoice' => $invoice
6363
])
64+
@if(! $invoice->fully_paid_at)
65+
@livewire('pay-invoice',[
66+
'invoice' => $invoice
67+
])
68+
@endif
6469
@can('view crm invoices')
6570
<a href="{{ route('laravel-crm.invoices.show',$invoice) }}" class="btn btn-outline-secondary btn-sm"><span class="fa fa-eye" aria-hidden="true"></span></a>
6671
@endcan
67-
@can('edit crm invoices')
68-
<a href="{{ route('laravel-crm.invoices.edit',$invoice) }}" class="btn btn-outline-secondary btn-sm"><span class="fa fa-edit" aria-hidden="true"></span></a>
69-
@endcan
70-
@can('delete crm invoices')
71-
<form action="{{ route('laravel-crm.invoices.destroy',$invoice) }}" method="POST" class="form-check-inline mr-0 form-delete-button">
72-
{{ method_field('DELETE') }}
73-
{{ csrf_field() }}
74-
<button class="btn btn-danger btn-sm" type="submit" data-model="{{ __('laravel-crm::lang.invoice') }}"><span class="fa fa-trash-o" aria-hidden="true"></span></button>
75-
</form>
76-
@endcan
72+
@if($invoice->amount_paid <= 0)
73+
@can('edit crm invoices')
74+
<a href="{{ route('laravel-crm.invoices.edit',$invoice) }}" class="btn btn-outline-secondary btn-sm"><span class="fa fa-edit" aria-hidden="true"></span></a>
75+
@endcan
76+
@can('delete crm invoices')
77+
<form action="{{ route('laravel-crm.invoices.destroy',$invoice) }}" method="POST" class="form-check-inline mr-0 form-delete-button">
78+
{{ method_field('DELETE') }}
79+
{{ csrf_field() }}
80+
<button class="btn btn-danger btn-sm" type="submit" data-model="{{ __('laravel-crm::lang.invoice') }}"><span class="fa fa-trash-o" aria-hidden="true"></span></button>
81+
</form>
82+
@endcan
83+
@endif
7784
</td>
7885
</tr>
7986
@endforeach

resources/views/invoices/partials/card-show.blade.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,16 @@
1111
@include('laravel-crm::partials.return-button',[
1212
'model' => $invoice,
1313
'route' => 'invoices'
14+
]) |
15+
@livewire('send-invoice',[
16+
'invoice' => $invoice
1417
])
15-
@include('laravel-crm::partials.navs.activities') |
18+
@if(! $invoice->fully_paid_at)
19+
@livewire('pay-invoice',[
20+
'invoice' => $invoice
21+
])
22+
@endif
23+
@include('laravel-crm::partials.navs.activities') @if($invoice->amount_paid <= 0) |
1624
@can('edit crm invoices')
1725
<a href="{{ url(route('laravel-crm.invoices.edit', $invoice)) }}" type="button" class="btn btn-outline-secondary btn-sm"><span class="fa fa-edit" aria-hidden="true"></span></a>
1826
@endcan
@@ -23,6 +31,7 @@
2331
<button class="btn btn-danger btn-sm" type="submit" data-model="{{ __('laravel-crm::lang.invoice') }}"><span class="fa fa-trash-o" aria-hidden="true"></span></button>
2432
</form>
2533
@endcan
34+
@endif
2635
</span>
2736
@endslot
2837

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<span>
2+
@can('edit crm invoices')
3+
<a href="{{ route('laravel-crm.invoices.pay',$this->invoice) }}" data-toggle="modal" data-target="#invoicePayModal_{{ $this->invoice->id }}" class="btn btn-success btn-sm">{{ ucfirst(__('laravel-crm::lang.pay')) }}</a>
4+
<div wire:ignore.self class="modal fade" id="invoicePayModal_{{ $this->invoice->id }}" tabindex="-1" aria-labelledby="invoicePayModalLabel" aria-hidden="true">
5+
<div class="modal-dialog modal-lg">
6+
<div class="modal-content">
7+
<div class="modal-header">
8+
<h5 class="modal-title" id="invoicePayModalLabel">{{ ucfirst(__('laravel-crm::lang.pay_invoice')) }} </h5>
9+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
10+
<span aria-hidden="true">&times;</span>
11+
</button>
12+
</div>
13+
<x-form wire:submit.prevent="pay">
14+
<div class="modal-body text-left">
15+
<x-form-input wire:model="amount_paid" name="amount_paid" label="{{ ucfirst(__('laravel-crm::lang.amount')) }}" type="number" step="0.01">
16+
@slot('prepend')
17+
<span class="fa fa-dollar" aria-hidden="true"></span>
18+
@endslot
19+
</x-form-input>
20+
</div>
21+
<div class="modal-footer">
22+
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">{{ ucfirst(__('laravel-crm::lang.cancel')) }}</button>
23+
<button wire:click.prevent="pay()" type="button" class="btn btn-primary">{{ ucwords(__('laravel-crm::lang.pay')) }}</button>
24+
</div>
25+
</x-form>
26+
</div>
27+
</div>
28+
</div>
29+
@endcan
30+
@push('livewire-js')
31+
<script>
32+
$(document).ready(function () {
33+
window.addEventListener('invoicePaid', event => {
34+
$('#invoicePayModal_{{ $this->invoice->id }}').modal('hide');
35+
window.location.reload();
36+
});
37+
});
38+
</script>
39+
@endpush
40+
</span>

resources/views/portal/invoices/show.blade.php

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,34 @@
66
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm fixed-top">
77
<div class="container-fluid">
88
<h1 class="navbar-brand mb-0" href="#">
9-
{{ money($invoice->total, $invoice->currency) }} {{ $invoice->currency }}
10-
{{--@if($invoice->accepted_at)
11-
<small><span class="badge badge-success">{{ ucfirst(__('laravel-crm::lang.accepted')) }}</span></small>
12-
@elseif($invoice->rejected_at)
13-
<small><span class="badge badge-danger">{{ ucfirst(__('laravel-crm::lang.rejected')) }}</span></small>
14-
@elseif(\Carbon\Carbon::now() <= $invoice->expire_at)
15-
<small><span class="badge badge-secondary">{{ ucfirst(__('laravel-crm::lang.expires_in')) }} {{ $invoice->expire_at->diffForHumans() }}</span></small>
16-
@else
17-
<small><span class="badge badge-danger">{{ ucfirst(__('laravel-crm::lang.invoice_expired')) }}</span></small>
18-
@endif--}}
9+
{{ money($invoice->total, $invoice->currency) }} <small>{{ $invoice->currency }}</small>
10+
@if($invoice->fully_paid_at)
11+
<small><span class="badge badge-success">{{ ucfirst(__('laravel-crm::lang.paid')) }}</span></small>
12+
@elseif(! $invoice->fully_paid_at && $invoice->due_date >= \Carbon\Carbon::now())
13+
<small><span class="badge badge-secondary">{{ ucfirst(__('laravel-crm::lang.due_in')) }} {{ $invoice->due_date->diffForHumans() }} </span></small>
14+
@elseif(! $invoice->fully_paid_at && $invoice->due_date < \Carbon\Carbon::now())
15+
<small><span class="badge badge-danger">{{ $invoice->due_date->diffForHumans() }} {{ ucfirst(__('laravel-crm::lang.overdue')) }} </span></small>
16+
@endif
1917
</h1>
2018
<div class="collapse navbar-collapse" id="navbarSupportedContent">
21-
<ul class="navbar-nav ml-auto">
22-
{{-- @if($invoice->accepted_at)
19+
{{--<ul class="navbar-nav ml-auto">
20+
@if($invoice->fully_paid_at)
2321
<div class="alert alert-success m-0" role="alert">
24-
{{ ucfirst(__('laravel-crm::lang.you_have_accepted_this_invoice')) }}.
22+
{{ ucfirst(__('laravel-crm::lang.you_have_paid_this_invoice')) }}.
2523
</div>
26-
@elseif($invoice->rejected_at)
27-
<div class="alert alert-danger m-0" role="alert">
28-
{{ ucfirst(__('laravel-crm::lang.you_have_rejected_this_invoice')) }}.
29-
</div>
30-
@elseif(\Carbon\Carbon::now() <= $invoice->expire_at)
24+
@else
3125
<li class="nav-item mr-2">
3226
<form action="{{ url()->current() }}?signature={{ request()->input('signature') }}" method="POST" class="form-check-inline mr-0">
3327
{{ csrf_field() }}
34-
<x-form-input name="action" value="accept" type="hidden" />
35-
<button class="btn btn-outline-success" type="submit">{{ ucfirst(__('laravel-crm::lang.accept')) }}</button>
28+
<x-form-input name="action" value="pay" type="hidden" />
29+
<button class="btn btn-outline-success" type="submit">{{ ucfirst(__('laravel-crm::lang.pay_now')) }}</button>
3630
</form>
3731
</li>
38-
<li class="nav-item mr-2">
39-
<form action="{{ url()->current() }}?signature={{ request()->input('signature') }}" method="POST" class="form-check-inline mr-0">
40-
{{ csrf_field() }}
41-
<x-form-input name="action" value="reject" type="hidden" />
42-
<button class="btn btn-outline-danger" type="submit">{{ ucfirst(__('laravel-crm::lang.reject')) }}</button>
43-
</form>
44-
</li>
45-
@endif--}}
46-
{{--<li class="nav-item">
47-
<a class="btn btn-outline-secondary" href="#">Download</a>
48-
</li>--}}
49-
</ul>
32+
@endif
33+
<li class="nav-item">
34+
<a class="btn btn-outline-secondary" href="#">PDF</a>
35+
</li>
36+
</ul>--}}
5037
</div>
5138
</div>
5239
</nav>
@@ -105,17 +92,17 @@
10592
@if($invoice->reference)
10693
<div class="row py-1">
10794
<div class="col-3">
108-
<strong>{{ ucfirst(__('laravel-crm::lang.reference')) }}</strong>
95+
<strong>{{ ucfirst(__('laravel-crm::lang.invoice_number')) }}</strong>
10996
</div>
11097
<div class="col">
111-
{{ $invoice->reference }}
98+
{{ $invoice->invoice_id }}
11299
</div>
113100
</div>
114101
@endif
115102
@if($invoice->issue_date)
116103
<div class="row py-1">
117104
<div class="col-3">
118-
<strong>{{ ucfirst(__('laravel-crm::lang.issue_date')) }}</strong>
105+
<strong>{{ ucfirst(__('laravel-crm::lang.issued')) }}</strong>
119106
</div>
120107
<div class="col">
121108
{{ $invoice->issue_date->toFormattedDateString() }}
@@ -125,10 +112,15 @@
125112
@if($invoice->due_date)
126113
<div class="row py-1">
127114
<div class="col-3">
128-
<strong>{{ ucfirst(__('laravel-crm::lang.due_date')) }}</strong>
115+
<strong>{{ ucfirst(__('laravel-crm::lang.due')) }}</strong>
129116
</div>
130117
<div class="col">
131118
{{ $invoice->due_date->toFormattedDateString() }}
119+
@if(! $invoice->fully_paid_at && $invoice->due_date >= \Carbon\Carbon::now())
120+
<small class="text-secondary"> ({{ ucfirst(__('laravel-crm::lang.due_in')) }} {{ $invoice->due_date->diffForHumans() }})</small>
121+
@elseif(! $invoice->fully_paid_at && $invoice->due_date < \Carbon\Carbon::now())
122+
<small class="text-danger"> ({{ $invoice->due_date->diffForHumans() }} {{ ucfirst(__('laravel-crm::lang.overdue')) }})</small>
123+
@endif
132124
</div>
133125
</div>
134126
@endif
@@ -147,7 +139,7 @@
147139
</div>
148140
</div>
149141
</div>
150-
<hr />
142+
<hr class="mb-5" />
151143
<div class="row py-1">
152144
<div class="col px-5 py-1">
153145
<table class="table table-hover mb-0">

resources/views/portal/quotes/show.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm fixed-top">
77
<div class="container-fluid">
88
<h1 class="navbar-brand mb-0" href="#">
9-
{{ money($quote->total, $quote->currency) }} {{ $quote->currency }}
9+
{{ money($quote->total, $quote->currency) }} <small>{{ $quote->currency }}</small>
1010
@if($quote->accepted_at)
1111
<small><span class="badge badge-success">{{ ucfirst(__('laravel-crm::lang.accepted')) }}</span></small>
1212
@elseif($quote->rejected_at)

src/Http/Livewire/PayInvoice.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace VentureDrake\LaravelCrm\Http\Livewire;
4+
5+
use Carbon\Carbon;
6+
use Livewire\Component;
7+
use VentureDrake\LaravelCrm\Traits\NotifyToast;
8+
9+
class PayInvoice extends Component
10+
{
11+
use NotifyToast;
12+
13+
public $invoice;
14+
15+
public $amount_paid;
16+
17+
public $amount_due;
18+
19+
public function mount($invoice)
20+
{
21+
$this->invoice = $invoice;
22+
$this->amount_due = $invoice->amount_due / 100;
23+
$this->amount_paid = $invoice->amount_paid / 100;
24+
25+
if ($this->amount_due > 0) {
26+
$this->amount_paid = $this->amount_due;
27+
}
28+
}
29+
30+
/**
31+
* Returns validation rules.
32+
*
33+
* @return array
34+
*/
35+
protected function rules()
36+
{
37+
return [
38+
'amount_paid' => 'required|numeric|size:'. ($this->invoice->amount_due / 100),
39+
];
40+
}
41+
42+
public function pay()
43+
{
44+
$this->validate();
45+
46+
$this->amount_due = ($this->invoice->amount_due / 100) - ($this->amount_paid + ($this->invoice->amount_paid / 100));
47+
48+
$this->invoice->update([
49+
'amount_paid' => $this->amount_paid + ($this->invoice->amount_paid / 100),
50+
'amount_due' => $this->amount_due,
51+
'fully_paid_at' => (($this->amount_due == 0) ? Carbon::now()->format('Y/m/d') : null),
52+
]);
53+
54+
$this->notify(
55+
'Invoice paid',
56+
);
57+
58+
$this->resetFields();
59+
60+
$this->dispatchBrowserEvent('invoicePaid');
61+
}
62+
63+
private function resetFields()
64+
{
65+
$this->reset('amount_paid');
66+
}
67+
68+
public function render()
69+
{
70+
return view('laravel-crm::livewire.pay-invoice');
71+
}
72+
}

src/Http/routes.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@
394394
Route::post('{invoice}/send', 'VentureDrake\LaravelCrm\Http\Controllers\InvoiceController@send')
395395
->name('laravel-crm.invoices.send')
396396
->middleware(['can:update,invoice']);
397+
398+
Route::post('{invoice}/pay', 'VentureDrake\LaravelCrm\Http\Controllers\InvoiceController@pay')
399+
->name('laravel-crm.invoices.pay')
400+
->middleware(['can:update,invoice']);
397401
});
398402

399403
/* Activities */

src/LaravelCrmServiceProvider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
use VentureDrake\LaravelCrm\Http\Livewire\LiveRelatedPerson;
4646
use VentureDrake\LaravelCrm\Http\Livewire\LiveTasks;
4747
use VentureDrake\LaravelCrm\Http\Livewire\NotifyToast;
48+
use VentureDrake\LaravelCrm\Http\Livewire\PayInvoice;
4849
use VentureDrake\LaravelCrm\Http\Livewire\SendInvoice;
4950
use VentureDrake\LaravelCrm\Http\Livewire\SendQuote;
5051
use VentureDrake\LaravelCrm\Http\Middleware\Authenticate;
@@ -399,6 +400,7 @@ function ($perPage = 30, $page = null, $options = []) {
399400
Livewire::component('send-quote', SendQuote::class);
400401
Livewire::component('invoice-lines', LiveInvoiceLines::class);
401402
Livewire::component('send-invoice', SendInvoice::class);
403+
Livewire::component('pay-invoice', PayInvoice::class);
402404

403405
if ($this->app->runningInConsole()) {
404406
$this->app->booted(function () {

src/Models/Invoice.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,24 @@ public function setTotalAttribute($value)
9797
}
9898
}
9999

100+
public function setAmountDueAttribute($value)
101+
{
102+
if (isset($value)) {
103+
$this->attributes['amount_due'] = $value * 100;
104+
} else {
105+
$this->attributes['amount_due'] = null;
106+
}
107+
}
108+
109+
public function setAmountPaidAttribute($value)
110+
{
111+
if (isset($value)) {
112+
$this->attributes['amount_paid'] = $value * 100;
113+
} else {
114+
$this->attributes['amount_paid'] = null;
115+
}
116+
}
117+
100118
public function person()
101119
{
102120
return $this->belongsTo(\VentureDrake\LaravelCrm\Models\Person::class);

0 commit comments

Comments
 (0)