From ad06de25f523f51fbc08dbb67da029a152a6683e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 4 Jan 2020 13:27:51 +1100 Subject: [PATCH] Fixes for Payments (#3194) * Set payment number on completed payment * Fix for paymentables not returning * Do not set invoice status to paid if only a partial amount of the invoice has been paid --- app/Console/Commands/CreateTestData.php | 1 + .../Requests/Payment/StorePaymentRequest.php | 3 +- app/Jobs/Invoice/ApplyInvoicePayment.php | 9 +++- app/Models/Creditable.php | 19 ++++++++ app/Models/Paymentable.php | 4 -- app/Repositories/PaymentRepository.php | 2 + app/Transformers/PaymentableTransformer.php | 2 +- app/Utils/Traits/GeneratesCounter.php | 46 ++++++++++++++++++- 8 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 app/Models/Creditable.php diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index 53250d97e4a7..a491f0b6cb84 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -316,6 +316,7 @@ class CreateTestData extends Command $payment->transaction_reference = rand(0, 500); $payment->type_id = PaymentType::CREDIT_CARD_OTHER; $payment->status_id = Payment::STATUS_COMPLETED; + $payment->number = $client->getNextPaymentNumber($client); $payment->save(); $payment->invoices()->save($invoice); diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index 74df0050fc7e..3f5b10ae2225 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -39,7 +39,8 @@ class StorePaymentRequest extends Request $input['client_id'] = $this->decodePrimaryKey($input['client_id']); } - if (isset($input['invoices'])) { + + if (isset($input['invoices']) && is_array($input['invoices']) !== false) { foreach ($input['invoices'] as $key => $value) { $input['invoices'][$key]['id'] = $this->decodePrimaryKey($value['id']); } diff --git a/app/Jobs/Invoice/ApplyInvoicePayment.php b/app/Jobs/Invoice/ApplyInvoicePayment.php index d3d4106c2ce5..a48aa437a85b 100644 --- a/app/Jobs/Invoice/ApplyInvoicePayment.php +++ b/app/Jobs/Invoice/ApplyInvoicePayment.php @@ -91,13 +91,18 @@ class ApplyInvoicePayment implements ShouldQueue $this->invoice->setStatus(Invoice::STATUS_PARTIAL); $this->invoice->updateBalance($this->amount*-1); } - } elseif ($this->invoice->amount == $this->invoice->balance) { //total invoice paid. + } elseif ($this->amount == $this->invoice->balance) { //total invoice paid. $this->invoice->clearPartial(); - $this->invoice->setDueDate(); + //$this->invoice->setDueDate(); $this->invoice->setStatus(Invoice::STATUS_PAID); $this->invoice->updateBalance($this->amount*-1); + } elseif($this->amount < $this->invoice->balance) { //partial invoice payment made + $this->invoice->clearPartial(); + $this->invoice->updateBalance($this->amount*-1); } + $this->invoice->save(); + /* Update Payment Applied Amount*/ $this->payment->applied += $this->amount; $this->payment->save(); diff --git a/app/Models/Creditable.php b/app/Models/Creditable.php new file mode 100644 index 000000000000..565085b0142d --- /dev/null +++ b/app/Models/Creditable.php @@ -0,0 +1,19 @@ +fill($request->input()); $payment->status_id = Payment::STATUS_COMPLETED; + $payment->number = $payment->client->getNextPaymentNumber($payment->client); + $payment->save(); if ($request->input('invoices')) { diff --git a/app/Transformers/PaymentableTransformer.php b/app/Transformers/PaymentableTransformer.php index 2cb9e53d2d54..5e2c4135778d 100644 --- a/app/Transformers/PaymentableTransformer.php +++ b/app/Transformers/PaymentableTransformer.php @@ -35,7 +35,7 @@ class PaymentableTransformer extends EntityTransformer return [ 'id' => $this->encodePrimaryKey($paymentable->id), 'invoice_id' => $this->encodePrimaryKey($paymentable->paymentable_id), - 'amount' => $paymentable->amount, + 'amount' => (float)$paymentable->amount, ]; } } diff --git a/app/Utils/Traits/GeneratesCounter.php b/app/Utils/Traits/GeneratesCounter.php index 7e9438aa9ef0..14042e07c47a 100644 --- a/app/Utils/Traits/GeneratesCounter.php +++ b/app/Utils/Traits/GeneratesCounter.php @@ -14,6 +14,7 @@ namespace App\Utils\Traits; use App\Models\Client; use App\Models\Credit; use App\Models\Invoice; +use App\Models\Payment; use App\Models\Quote; use App\Models\RecurringInvoice; use App\Models\Timezone; @@ -127,10 +128,10 @@ trait GeneratesCounter return $quote_number; } - public function getNextRecurringInvoiceNumber() + public function getNextRecurringInvoiceNumber(Client $client) { -//Reset counters if enabled + //Reset counters if enabled $this->resetCounters($client); $is_client_counter = false; @@ -162,6 +163,44 @@ trait GeneratesCounter return $invoice_number; } + /** + * Payment Number Generator + * @return string The payment number + */ + public function getNextPaymentNumber(Client $client) :string + { + + //Reset counters if enabled + $this->resetCounters($client); + + $is_client_counter = false; + + //todo handle if we have specific client patterns in the future + $pattern = $client->company->settings->payment_number_pattern; + + //Determine if we are using client_counters + if (strpos($pattern, 'client_counter') === false) { + $counter = $client->company->settings->payment_number_counter; + } else { + $counter = $client->settings->payment_number_counter; + $is_client_counter = true; + } + + //Return a valid counter + $pattern = ''; + $padding = $client->getSetting('counter_padding'); + $payment_number = $this->checkEntityNumber(Payment::class, $client, $counter, $padding, $pattern); + + //increment the correct invoice_number Counter (company vs client) + if ($is_client_counter) { + $this->incrementCounter($client, 'payment_number_counter'); + } else { + $this->incrementCounter($client->company, 'payment_number_counter'); + } + + return (string)$payment_number; + } + /** * Gets the next client number. * @@ -225,9 +264,12 @@ trait GeneratesCounter $check = $class::whereCompanyId($client->company_id)->whereNumber($number)->withTrashed()->first(); } elseif ($class == Quote::class) { $check = $class::whereCompanyId($client->company_id)->whereNumber($number)->withTrashed()->first(); + } elseif ($class == Payment::class) { + $check = $class::whereCompanyId($client->company_id)->whereNumber($number)->withTrashed()->first(); } $counter++; + } while ($check);