Support paying draft invoices

This commit is contained in:
Hillel Coren 2017-01-13 09:02:22 +02:00
parent 2da91729b3
commit eebe61b4d0
9 changed files with 76 additions and 58 deletions

View File

@ -9,7 +9,6 @@ use Cache;
use Redirect;
use DB;
use URL;
use DropdownButton;
use App\Models\Invoice;
use App\Models\Client;
use App\Models\Account;
@ -123,46 +122,6 @@ class InvoiceController extends BaseController
'invoice_settings' => Auth::user()->hasFeature(FEATURE_INVOICE_SETTINGS),
];
$actions = [
['url' => 'javascript:onCloneClick()', 'label' => trans("texts.clone_{$entityType}")],
['url' => URL::to("{$entityType}s/{$entityType}_history/{$invoice->public_id}"), 'label' => trans('texts.view_history')],
DropdownButton::DIVIDER
];
if ($entityType == ENTITY_QUOTE) {
if ($invoice->quote_invoice_id) {
$actions[] = ['url' => URL::to("invoices/{$invoice->quote_invoice_id}/edit"), 'label' => trans('texts.view_invoice')];
} else {
$actions[] = ['url' => 'javascript:onConvertClick()', 'label' => trans('texts.convert_to_invoice')];
}
} elseif ($entityType == ENTITY_INVOICE) {
if ($invoice->quote_id) {
$actions[] = ['url' => URL::to("quotes/{$invoice->quote_id}/edit"), 'label' => trans('texts.view_quote')];
}
if (!$invoice->is_recurring && $invoice->balance > 0) {
$actions[] = ['url' => 'javascript:submitBulkAction("markPaid")', 'label' => trans('texts.mark_paid')];
if ($invoice->is_public) {
$actions[] = ['url' => 'javascript:onPaymentClick()', 'label' => trans('texts.enter_payment')];
}
}
foreach ($invoice->payments as $payment) {
$label = trans('texts.view_payment');
if (count($invoice->payments) > 1) {
$label .= ' - ' . $account->formatMoney($payment->amount, $invoice->client);
}
$actions[] = ['url' => $payment->present()->url, 'label' => $label];
}
}
if (count($actions) > 3) {
$actions[] = DropdownButton::DIVIDER;
}
$actions[] = ['url' => 'javascript:onArchiveClick()', 'label' => trans("texts.archive_{$entityType}")];
$actions[] = ['url' => 'javascript:onDeleteClick()', 'label' => trans("texts.delete_{$entityType}")];
$lastSent = ($invoice->is_recurring && $invoice->last_sent_date) ? $invoice->recurring_invoices->last() : null;
if(!Auth::user()->hasPermission('view_all')){
@ -180,7 +139,6 @@ class InvoiceController extends BaseController
'title' => trans("texts.edit_{$entityType}"),
'client' => $invoice->client,
'isRecurring' => $invoice->is_recurring,
'actions' => $actions,
'lastSent' => $lastSent];
$data = array_merge($data, self::getViewModel($invoice));

View File

@ -108,6 +108,9 @@ class PaymentApiController extends BaseAPIController
*/
public function store(CreatePaymentAPIRequest $request)
{
// check payment has been marked sent
$request->invoice->markSentIfUnsent();
$payment = $this->paymentRepo->save($request->input());
if (Input::get('email_receipt')) {
@ -142,7 +145,7 @@ class PaymentApiController extends BaseAPIController
public function destroy(UpdatePaymentRequest $request)
{
$payment = $request->entity();
$this->clientRepo->delete($payment);
return $this->itemResponse($payment);

View File

@ -85,7 +85,6 @@ class PaymentController extends BaseController
{
$invoices = Invoice::scope()
->invoices()
->whereIsPublic(true)
->where('invoices.balance', '>', 0)
->with('client', 'invoice_status')
->orderBy('invoice_number')->get();

View File

@ -33,9 +33,8 @@ class CreatePaymentAPIRequest extends PaymentRequest
];
}
$invoice = Invoice::scope($this->invoice_id)
$this->invoice = $invoice = Invoice::scope($this->invoice_id)
->invoices()
->whereIsPublic(true)
->firstOrFail();
$this->merge([

View File

@ -426,6 +426,25 @@ class Invoice extends EntityModel implements BalanceAffecting
return $this->isType(INVOICE_TYPE_STANDARD) && ! $this->is_recurring;
}
public function markSentIfUnsent()
{
if ( ! $this->isSent()) {
$this->markSent();
}
}
public function markSent()
{
if ( ! $this->isSent()) {
$this->invoice_status_id = INVOICE_STATUS_SENT;
}
$this->is_public = true;
$this->save();
$this->markInvitationsSent();
}
/**
* @param bool $notify
*/
@ -462,7 +481,7 @@ class Invoice extends EntityModel implements BalanceAffecting
*/
public function markInvitationSent($invitation, $messageId = false, $notify = true, $notes = false)
{
if (!$this->isSent()) {
if ( ! $this->isSent()) {
$this->invoice_status_id = INVOICE_STATUS_SENT;
$this->save();
}
@ -667,7 +686,7 @@ class Invoice extends EntityModel implements BalanceAffecting
*/
public function isSent()
{
return $this->invoice_status_id >= INVOICE_STATUS_SENT && $this->is_public;
return $this->invoice_status_id >= INVOICE_STATUS_SENT && $this->getOriginal('is_public');
}
/**

View File

@ -2,6 +2,7 @@
use stdClass;
use Utils;
use DropdownButton;
use App\Libraries\Skype\InvoiceCard;
class InvoicePresenter extends EntityPresenter {
@ -162,4 +163,50 @@ class InvoicePresenter extends EntityPresenter {
return [$data];
}
public function moreActions()
{
$invoice = $this->entity;
$entityType = $invoice->getEntityType();
$actions = [
['url' => 'javascript:onCloneClick()', 'label' => trans("texts.clone_{$entityType}")],
['url' => url("{$entityType}s/{$entityType}_history/{$invoice->public_id}"), 'label' => trans('texts.view_history')],
DropdownButton::DIVIDER
];
if ($entityType == ENTITY_QUOTE) {
if ($invoice->quote_invoice_id) {
$actions[] = ['url' => url("invoices/{$invoice->quote_invoice_id}/edit"), 'label' => trans('texts.view_invoice')];
} else {
$actions[] = ['url' => 'javascript:onConvertClick()', 'label' => trans('texts.convert_to_invoice')];
}
} elseif ($entityType == ENTITY_INVOICE) {
if ($invoice->quote_id) {
$actions[] = ['url' => url("quotes/{$invoice->quote_id}/edit"), 'label' => trans('texts.view_quote')];
}
if (!$invoice->is_recurring && $invoice->balance > 0) {
$actions[] = ['url' => 'javascript:submitBulkAction("markPaid")', 'label' => trans('texts.mark_paid')];
$actions[] = ['url' => 'javascript:onPaymentClick()', 'label' => trans('texts.enter_payment')];
}
foreach ($invoice->payments as $payment) {
$label = trans('texts.view_payment');
if (count($invoice->payments) > 1) {
$label .= ' - ' . $invoice->account->formatMoney($payment->amount, $invoice->client);
}
$actions[] = ['url' => $payment->present()->url, 'label' => $label];
}
}
if (count($actions) > 3) {
$actions[] = DropdownButton::DIVIDER;
}
$actions[] = ['url' => 'javascript:onArchiveClick()', 'label' => trans("texts.archive_{$entityType}")];
$actions[] = ['url' => 'javascript:onDeleteClick()', 'label' => trans("texts.delete_{$entityType}")];
return $actions;
}
}

View File

@ -761,14 +761,7 @@ class InvoiceRepository extends BaseRepository
*/
public function markSent(Invoice $invoice)
{
if ( ! $invoice->isSent()) {
$invoice->invoice_status_id = INVOICE_STATUS_SENT;
}
$invoice->is_public = true;
$invoice->save();
$invoice->markInvitationsSent();
$invoice->markSent();
}
/**

View File

@ -199,7 +199,7 @@ class AppServiceProvider extends ServiceProvider
});
Validator::extend('valid_subdomain', function($attribute, $value, $parameters) {
return ! in_array($value, ['www', 'app','mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner', 'info', 'ninja', 'docs', 'doc', 'documents']);
return ! in_array($value, ['www', 'app', 'mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner', 'info', 'ninja', 'docs', 'doc', 'documents', 'download']);
});
}

View File

@ -564,7 +564,7 @@
@if (!$invoice->trashed())
@if ($invoice->id)
{!! DropdownButton::normal(trans('texts.more_actions'))
->withContents($actions)
->withContents($invoice->present()->moreActions())
->dropup() !!}
@elseif ( ! $invoice->isQuote() && Request::is('*/clone'))
{!! Button::normal(trans($invoice->is_recurring ? 'texts.disable_recurring' : 'texts.enable_recurring'))->withAttributes(['id' => 'recurrButton', 'onclick' => 'onRecurrClick()'])->appendIcon(Icon::create('repeat')) !!}