Support for over & under payments

This commit is contained in:
Benjamin Beganović 2020-09-24 11:29:47 +02:00
parent aeeaa62d5e
commit 0216286efc
3 changed files with 71 additions and 10 deletions

View File

@ -73,9 +73,10 @@ class PaymentController extends Controller
*/
public function process()
{
$gateway = CompanyGateway::find(request()->input('company_gateway_id'));
/*find invoices*/
$payable_invoices = request()->payable_invoices;
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payable_invoices, 'invoice_id')))->get();
@ -91,9 +92,11 @@ class PaymentController extends Controller
->with(['warning' => 'No payable invoices selected.']);
}
/*iterate through invoices and add gateway fees and other payment metadata*/
$settings = auth()->user()->client->getMergedSettings();
/*iterate through invoices and add gateway fees and other payment metadata*/
foreach ($payable_invoices as $key => $payable_invoice) {
$payable_invoices[$key]['amount'] = Number::parseFloat($payable_invoice['amount']);
$payable_invoice['amount'] = $payable_invoices[$key]['amount'];
@ -101,6 +104,41 @@ class PaymentController extends Controller
return $payable_invoice['invoice_id'] == $inv->hashed_id;
});
// Check if company supports over & under payments.
// In case it doesn't this is where process should stop.
$payable_amount = Number::roundValue(Number::parseFloat($payable_invoice['amount']), auth()->user()->client->currency()->precision);
$invoice_amount = Number::roundValue($invoice->amount, auth()->user()->client->currency()->precision);
if ($settings->client_portal_allow_under_payment == false && $settings->client_portal_allow_over_payment == false) {
$payable_invoice['amount'] = $invoice->amount;
} // We don't allow either of these, reset the amount to default invoice (to prevent inspect element payments).
if ($settings->client_portal_allow_under_payment) {
if ($payable_invoice['amount'] < $settings->client_portal_under_payment_minimum) {
return redirect()
->route('client.invoices.index')
->with('message', ctrans('texts.minimum_required_payment', ['amount' => $settings->client_portal_under_payment_minimum]));
}
} else {
$payable_amount = Number::roundValue(Number::parseFloat($payable_invoice['amount']), auth()->user()->client->currency()->precision);
$invoice_amount = Number::roundValue($invoice->amount, auth()->user()->client->currency()->precision);
if ($payable_amount < $invoice_amount) {
return redirect()
->route('client.invoices.index')
->with('message', ctrans('texts.under_payments_disabled'));
}
} // Make sure 'amount' from form is not lower than 'amount' from invoice.
if ($settings->client_portal_allow_over_payment == false) {
if ($payable_amount > $invoice_amount) {
return redirect()
->route('client.invoices.index')
->with('message', ctrans('texts.over_payments_disabled'));
}
} // Make sure 'amount' from form is not higher than 'amount' from invoice.
$payable_invoices[$key]['due_date'] = $this->formatDate($invoice->due_date, $invoice->client->date_format());
$payable_invoices[$key]['invoice_number'] = $invoice->number;
@ -129,7 +167,7 @@ class PaymentController extends Controller
$first_invoice = $invoices->first();
$fee_totals = round($gateway->calcGatewayFee($invoice_totals, true), $first_invoice->client->currency()->precision);
if (! $first_invoice->uses_inclusive_taxes) {
if (!$first_invoice->uses_inclusive_taxes) {
$fee_tax = 0;
$fee_tax += round(($first_invoice->tax_rate1 / 100) * $fee_totals, $first_invoice->client->currency()->precision);
$fee_tax += round(($first_invoice->tax_rate2 / 100) * $fee_totals, $first_invoice->client->currency()->precision);

View File

@ -3272,4 +3272,9 @@ return [
'password_strength' => 'Password strength too weak',
'thanks' => 'Thanks',
'minimum_required_payment' => 'Minimum required payment is :amount',
'under_payments_disabled' => 'Company doesn\'t support under payments.',
'over_payments_disabled' => 'Company doesn\'t support over payments.',
];

View File

@ -36,7 +36,7 @@
<div class="bg-white rounded-md shadow-xs">
<div class="py-1">
@foreach($payment_methods as $payment_method)
<a data-turbolinks="false" href="#" @click="{ open = false }" data-company-gateway-id="{{ $payment_method['company_gateway_id'] }}" data-gateway-type-id="{{ $payment_method['gateway_type_id'] }}" class="block px-4 py-2 text-sm leading-5 text-gray-700 dropdown-gateway-button hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900">
<a href="#" @click="{ open = false }" data-company-gateway-id="{{ $payment_method['company_gateway_id'] }}" data-gateway-type-id="{{ $payment_method['gateway_type_id'] }}" class="block px-4 py-2 text-sm leading-5 text-gray-700 dropdown-gateway-button hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900">
{{ $payment_method['label'] }}
</a>
@endforeach
@ -94,11 +94,11 @@
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@if($invoice->po_number)
{{ $invoice->po_number }}
{{ $invoice->po_number }}
@elseif($invoice->public_notes)
{{ $invoice->public_notes }}
{{ $invoice->public_notes }}
@else
{{ $invoice->date}}
{{ $invoice->date}}
@endif
</dd>
</div>
@ -108,9 +108,25 @@
<dt class="text-sm font-medium leading-5 text-gray-500">
{{ ctrans('texts.amount') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<dd class="text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2 flex flex-col">
<!-- App\Utils\Number::formatMoney($invoice->amount, $invoice->client) -->
<input type="text" name="payable_invoices[{{$key}}][amount]" value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}">
<!-- Disabled input field don't send it's value with request. -->
@if(!$settings->client_portal_allow_under_payment && !$settings->client_portal_allow_over_payment)
<span class="mt-1 text-sm text-gray-800">{{ App\Utils\Number::formatMoney($invoice->amount, $invoice->client) }}</span>
@else
<div class="flex items-center">
<input
type="text"
class="input mt-0 mr-4 relative"
name="payable_invoices[{{$key}}][amount]"
value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}"/>
<span class="mt-2">{{ $invoice->client->currency()->code }} ({{ $invoice->client->currency()->symbol }})</span>
</div>
@endif
@if($settings->client_portal_allow_under_payment)
<span class="mt-1 text-sm text-gray-800">{{ ctrans('texts.minimum_payment') }}: {{ $settings->client_portal_under_payment_minimum }}</span>
@endif
</dd>
</div>
@endif
@ -122,10 +138,12 @@
</div>
</div>
</form>
@include('portal.ninja2020.invoices.includes.terms')
@include('portal.ninja2020.invoices.includes.signature')
@endsection
@push('footer')
<script src="{{ asset('js/clients/invoices/payment.js') }}"></script>
<script src="{{ asset('js/clients/invoices/payment.js') }}"></script>
@endpush