2020-01-29 03:03:47 +01:00
|
|
|
<?php
|
|
|
|
/**
|
2020-09-06 11:38:10 +02:00
|
|
|
* Invoice Ninja (https://invoiceninja.com).
|
2020-01-29 03:03:47 +01:00
|
|
|
*
|
|
|
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
|
|
*
|
2021-01-03 22:54:54 +01:00
|
|
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
2020-01-29 03:03:47 +01:00
|
|
|
*
|
|
|
|
* @license https://opensource.org/licenses/AAL
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace App\Http\ValidationRules\Payment;
|
|
|
|
|
|
|
|
use App\Models\Credit;
|
|
|
|
use App\Models\Invoice;
|
|
|
|
use App\Models\Payment;
|
|
|
|
use App\Utils\Traits\MakesHash;
|
|
|
|
use Illuminate\Contracts\Validation\Rule;
|
|
|
|
|
|
|
|
/**
|
2020-09-06 11:38:10 +02:00
|
|
|
* Class ValidRefundableRequest.
|
2020-01-29 03:03:47 +01:00
|
|
|
*/
|
|
|
|
class ValidRefundableRequest implements Rule
|
|
|
|
{
|
|
|
|
use MakesHash;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $attribute
|
|
|
|
* @param mixed $value
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
private $error_msg;
|
|
|
|
|
2020-02-05 22:54:20 +01:00
|
|
|
private $input;
|
|
|
|
|
|
|
|
public function __construct($input)
|
|
|
|
{
|
|
|
|
$this->input = $input;
|
|
|
|
}
|
2020-01-29 03:03:47 +01:00
|
|
|
|
|
|
|
public function passes($attribute, $value)
|
|
|
|
{
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! array_key_exists('id', $this->input)) {
|
|
|
|
$this->error_msg = 'Payment `id` required.';
|
|
|
|
|
2020-04-15 02:30:52 +02:00
|
|
|
return false;
|
2020-04-11 13:19:05 +02:00
|
|
|
}
|
|
|
|
|
2020-02-05 22:54:20 +01:00
|
|
|
$payment = Payment::whereId($this->input['id'])->first();
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! $payment) {
|
|
|
|
$this->error_msg = 'Unable to retrieve specified payment';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-05 22:54:20 +01:00
|
|
|
$request_invoices = request()->has('invoices') ? $this->input['invoices'] : [];
|
|
|
|
$request_credits = request()->has('credits') ? $this->input['credits'] : [];
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-02-05 22:54:20 +01:00
|
|
|
// foreach($request_invoices as $key => $value)
|
|
|
|
// $request_invoices[$key]['invoice_id'] = $this->decodePrimaryKey($value['invoice_id']);
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-02-05 22:54:20 +01:00
|
|
|
// foreach($request_credits as $key => $value)
|
|
|
|
// $request_credits[$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']);
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if ($payment->invoices()->exists()) {
|
|
|
|
foreach ($payment->invoices as $paymentable_invoice) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$this->checkInvoice($paymentable_invoice, $request_invoices);
|
2020-03-21 06:37:30 +01:00
|
|
|
}
|
2020-01-29 03:03:47 +01:00
|
|
|
}
|
|
|
|
|
2020-02-01 21:45:23 +01:00
|
|
|
// if($payment->credits()->exists())
|
|
|
|
// {
|
|
|
|
// foreach($payment->credits as $paymentable_credit)
|
|
|
|
// $this->checkCredit($paymentable_credit, $request_credits);
|
|
|
|
// }
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
foreach ($request_invoices as $request_invoice) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$this->checkInvoiceIsPaymentable($request_invoice, $payment);
|
2020-03-21 06:37:30 +01:00
|
|
|
}
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-02-01 21:45:23 +01:00
|
|
|
// foreach($request_credits as $request_credit)
|
|
|
|
// $this->checkCreditIsPaymentable($request_credit, $payment);
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if (strlen($this->error_msg) > 0) {
|
2020-01-29 03:45:20 +01:00
|
|
|
return false;
|
2020-03-21 06:37:30 +01:00
|
|
|
}
|
2020-01-29 03:45:20 +01:00
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function checkInvoiceIsPaymentable($invoice, $payment)
|
|
|
|
{
|
2020-02-05 22:54:20 +01:00
|
|
|
$invoice = Invoice::whereId($invoice['invoice_id'])->whereCompanyId($payment->company_id)->first();
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if ($payment->invoices()->exists()) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$paymentable_invoice = $payment->invoices->where('id', $invoice->id)->first();
|
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! $paymentable_invoice) {
|
|
|
|
$this->error_msg = 'Invoice id '.$invoice->hashed_id.' is not related to this payment';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
2020-03-21 06:37:30 +01:00
|
|
|
} else {
|
2020-09-06 11:38:10 +02:00
|
|
|
$this->error_msg = 'Invoice id '.$invoice->hashed_id.' is not related to this payment';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function checkCreditIsPaymentable($credit, $payment)
|
|
|
|
{
|
2020-02-05 22:54:20 +01:00
|
|
|
$credit = Credit::whereId($credit['credit_id'])->whereCompanyId($payment->company_id)->first();
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if ($payment->credits()->exists()) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$paymentable_credit = $payment->credits->where('id', $credit->id)->first();
|
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! $paymentable_invoice) {
|
|
|
|
$this->error_msg = 'Credit id '.$credit->hashed_id.' is not related to this payment';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
2020-03-21 06:37:30 +01:00
|
|
|
} else {
|
2020-09-06 11:38:10 +02:00
|
|
|
$this->error_msg = 'Credit id '.$credit->hashed_id.' is not related to this payment';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
2020-03-21 06:37:30 +01:00
|
|
|
}
|
2020-01-29 03:03:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private function checkInvoice($paymentable, $request_invoices)
|
|
|
|
{
|
|
|
|
$record_found = false;
|
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
foreach ($request_invoices as $request_invoice) {
|
|
|
|
if ($request_invoice['invoice_id'] == $paymentable->pivot->paymentable_id) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$record_found = true;
|
|
|
|
|
|
|
|
$refundable_amount = ($paymentable->pivot->amount - $paymentable->pivot->refunded);
|
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if ($request_invoice['amount'] > $refundable_amount) {
|
2020-01-30 05:50:45 +01:00
|
|
|
$invoice = $paymentable;
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
$this->error_msg = 'Attempting to refund more than allowed for invoice id '.$invoice->hashed_id.', maximum refundable amount is '.$refundable_amount;
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! $record_found) {
|
|
|
|
$this->error_msg = 'Attempting to refund a payment with invoices attached, please specify valid invoice/s to be refunded.';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function checkCredit($paymentable, $request_credits)
|
|
|
|
{
|
|
|
|
$record_found = null;
|
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
foreach ($request_credits as $request_credit) {
|
|
|
|
if ($request_credit['credit_id'] == $paymentable->pivot->paymentable_id) {
|
2020-01-29 03:03:47 +01:00
|
|
|
$record_found = true;
|
|
|
|
|
|
|
|
$refundable_amount = ($paymentable->pivot->amount - $paymentable->pivot->refunded);
|
|
|
|
|
2020-03-21 06:37:30 +01:00
|
|
|
if ($request_credit['amount'] > $refundable_amount) {
|
2020-01-30 05:50:45 +01:00
|
|
|
$credit = $paymentable;
|
2020-01-29 03:03:47 +01:00
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
$this->error_msg = 'Attempting to refund more than allowed for credit '.$credit->number.', maximum refundable amount is '.$refundable_amount;
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 11:38:10 +02:00
|
|
|
if (! $record_found) {
|
|
|
|
$this->error_msg = 'Attempting to refund a payment with credits attached, please specify valid credit/s to be refunded.';
|
|
|
|
|
2020-01-29 03:03:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function message()
|
|
|
|
{
|
|
|
|
return $this->error_msg;
|
|
|
|
}
|
|
|
|
}
|