1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 00:11:35 +02:00

Merge pull request #2807 from FELDSAM-INC/feature/require-quote-approve-option

Feature/require quote approve option
This commit is contained in:
Hillel Coren 2019-04-29 19:46:19 +03:00 committed by GitHub
commit e14e27cac6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 93 additions and 8 deletions

View File

@ -1065,6 +1065,7 @@ class AccountController extends BaseController
$account->quote_terms = Input::get('quote_terms');
$account->auto_convert_quote = Input::get('auto_convert_quote');
$account->auto_archive_quote = Input::get('auto_archive_quote');
$account->require_approve_quote = Input::get('require_approve_quote');
$account->allow_approve_expired_quote = Input::get('allow_approve_expired_quote');
$account->auto_archive_invoice = Input::get('auto_archive_invoice');
$account->auto_email_invoice = Input::get('auto_email_invoice');

View File

@ -146,13 +146,14 @@ class ClientPortalController extends BaseController
}
}
$showApprove = $invoice->quote_invoice_id ? false : true;
$showApprove = ($invoice->isQuote() && $account->require_approve_quote) ? true: false;
if ($invoice->invoice_status_id >= INVOICE_STATUS_APPROVED) {
$showApprove = false;
}
$data += [
'account' => $account,
'approveRequired' => $account->require_approve_quote,
'showApprove' => $showApprove,
'showBreadcrumbs' => false,
'invoice' => $invoice->hidePrivateFields(),

View File

@ -109,6 +109,8 @@ class Account extends Eloquent
'body_font_id',
'auto_convert_quote',
'auto_archive_quote',
'require_approve_quote',
'allow_approve_expired_quote',
'auto_archive_invoice',
'auto_email_invoice',
'all_pages_footer',

View File

@ -542,6 +542,20 @@ class Invoice extends EntityModel implements BalanceAffecting
});
}
/**
* @return Invitation|null
*/
public function invitationByContactId(int $contactId)
{
foreach ($this->invitations as $invitation) {
if ($invitation->contact_id === $contactId) {
return $invitation;
}
}
return null;
}
/**
* @param $typeId
*
@ -787,7 +801,15 @@ class Invoice extends EntityModel implements BalanceAffecting
public function canBePaid()
{
return ! $this->isPaid() && ! $this->is_deleted && $this->isStandard();
// already paid or deleted
if ($this->isPaid() || $this->is_deleted) return false;
// if quote approve is required, them only standard invoices can be paid
if ($this->account->require_approve_quote) {
return $this->isStandard();
}
return true;
}
public static function calcStatusLabel($status, $class, $entityType, $quoteInvoiceId)

View File

@ -698,6 +698,14 @@ class BasePaymentDriver
if (! $invoice->canBePaid()) {
return false;
}
// check if invoice is quote and if is, them convert it
if($invoice->isQuote()) {
$invoiceService = app('App\Services\InvoiceService');
$invoice = $invoiceService->convertQuote($invoice);
$invitation = $invoice->invitationByContactId($invitation->contact_id);
}
$invoice->markSentIfUnsent();
$payment = Payment::createNew($invitation);

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddRequireApproveQuote extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function ($table) {
$table->boolean('require_approve_quote')->default(1);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function ($table) {
$table->dropColumn('require_approve_quote');
});
}
}

View File

@ -2842,6 +2842,8 @@ $LANG = array(
'auto_archive_invoice_help' => 'Automatically archive invoices when they are paid.',
'auto_archive_quote' => 'Auto Archive',
'auto_archive_quote_help' => 'Automatically archive quotes when they are converted.',
'require_approve_quote' => 'Require approve quote',
'require_approve_quote_help' => 'Require clients to approve quotes.',
'allow_approve_expired_quote' => 'Allow approve expired quote',
'allow_approve_expired_quote_help' => 'Allow clients to approve expired quotes.',
'invoice_workflow' => 'Invoice Workflow',

View File

@ -405,16 +405,21 @@
</div>
<div role="tabpanel" class="tab-pane" id="quote_workflow">
<div class="panel-body">
{!! Former::checkbox('auto_convert_quote')
->text(trans('texts.enable'))
->blockHelp(trans('texts.auto_convert_quote_help'))
->value(1) !!}
{!! Former::checkbox('auto_archive_quote')
->text(trans('texts.enable'))
->blockHelp(trans('texts.auto_archive_quote_help'))
->value(1) !!}
{!! Former::checkbox('require_approve_quote')
->text(trans('texts.enable'))
->blockHelp(trans('texts.require_approve_quote_help'))
->value(1) !!}
{!! Former::checkbox('auto_convert_quote')
->text(trans('texts.enable'))
->blockHelp(trans('texts.auto_convert_quote_help'))
->value(1) !!}
{!! Former::checkbox('allow_approve_expired_quote')
->text(trans('texts.enable'))
->blockHelp(trans('texts.allow_approve_expired_quote_help'))
@ -631,6 +636,7 @@
onClientNumberEnabled();
onCreditNumberEnabled();
onResetFrequencyChange();
updateCheckboxes();
$('#reset_counter_date').datepicker('update', '{{ Utils::fromSqlDate($account->reset_counter_date) ?: 'new Date()' }}');
$('.reset_counter_date_group .input-group-addon').click(function() {
@ -642,6 +648,14 @@
@endif
});
$('#require_approve_quote').change(updateCheckboxes);
function updateCheckboxes() {
var checked = $('#require_approve_quote').is(':checked');
$('#auto_convert_quote').prop('disabled', ! checked);
$('#allow_approve_expired_quote').prop('disabled', ! checked);
}
</script>

View File

@ -160,13 +160,16 @@
@include($partialView)
@else
<div id="paymentButtons" class="pull-right" style="text-align:right">
@if ($invoice->isQuote())
@if ($invoice->isQuote() && $approveRequired)
{!! Button::normal(trans('texts.download'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}&nbsp;&nbsp;
@if ($showApprove)
{!! Button::success(trans('texts.approve'))->withAttributes(['id' => 'approveButton', 'onclick' => 'onApproveClick()', 'class' => 'require-authorization'])->large() !!}
@elseif ($invoiceLink = $invoice->getInvoiceLinkForQuote($contact->id))
{!! Button::success(trans('texts.view_invoice'))->asLinkTo($invoiceLink)->large() !!}
@endif
@elseif ($invoice->isQuote() && $invoiceLink = $invoice->getInvoiceLinkForQuote($contact->id))
{!! Button::normal(trans('texts.download'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
{!! Button::success(trans('texts.view_invoice'))->asLinkTo($invoiceLink)->large() !!}
@elseif ( ! $invoice->canBePaid())
{!! Button::normal(trans('texts.download'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
@elseif ($invoice->client->account->isGatewayConfigured() && floatval($invoice->balance) && !$invoice->is_recurring)