diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index b178717caa1e..97736fda7a55 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -85,8 +85,6 @@ class StorePaymentRequest extends Request $input['amount'] = $invoices_total - $credits_total; } - // $input['is_manual'] = true; - if (! isset($input['date'])) { $input['date'] = now()->addSeconds(auth()->user()->company()->timezone()->utc_offset)->format('Y-m-d'); } diff --git a/app/Http/ValidationRules/Credit/ValidCreditsRules.php b/app/Http/ValidationRules/Credit/ValidCreditsRules.php index b0892da7330e..d02097df2159 100644 --- a/app/Http/ValidationRules/Credit/ValidCreditsRules.php +++ b/app/Http/ValidationRules/Credit/ValidCreditsRules.php @@ -64,7 +64,6 @@ class ValidCreditsRules implements Rule foreach ($this->input['credits'] as $credit) { $unique_array[] = $credit['credit_id']; - // $cred = Credit::find($this->decodePrimaryKey($credit['credit_id'])); $cred = $cred_collection->firstWhere('id', $credit['credit_id']); if (! $cred) { @@ -77,6 +76,11 @@ class ValidCreditsRules implements Rule return false; } + if($cred->status_id == Credit::STATUS_DRAFT){ + $cred->service()->markSent()->save(); + $cred = $cred->fresh(); + } + if($cred->balance < $credit['amount']) { $this->error_msg = ctrans('texts.insufficient_credit_balance'); return false; diff --git a/tests/Feature/CreditTest.php b/tests/Feature/CreditTest.php index 0e830189e813..f67aa96db9b4 100644 --- a/tests/Feature/CreditTest.php +++ b/tests/Feature/CreditTest.php @@ -27,6 +27,8 @@ class CreditTest extends TestCase use DatabaseTransactions; use MockAccountData; + public $faker; + protected function setUp(): void { parent::setUp(); diff --git a/tests/Feature/PaymentV2Test.php b/tests/Feature/PaymentV2Test.php index 5f1f386ef173..3365b42adf3f 100644 --- a/tests/Feature/PaymentV2Test.php +++ b/tests/Feature/PaymentV2Test.php @@ -58,6 +58,78 @@ class PaymentV2Test extends TestCase ); } + public function testUsingDraftCreditsForPayments() + { + + $invoice = Invoice::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'client_id' => $this->client->id, + 'status_id' => Invoice::STATUS_SENT, + 'uses_inclusive_taxes' => false, + 'amount' => 20, + 'balance' => 20, + 'discount' => 0, + 'number' => uniqid("st", true), + 'line_items' => [] + ]); + + $item = InvoiceItemFactory::generateCredit(); + $item['cost'] = 20; + $item['quantity'] = 1; + + $credit = Credit::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'client_id' => $this->client->id, + 'status_id' => Credit::STATUS_DRAFT, + 'uses_inclusive_taxes' => false, + 'amount' => 20, + 'balance' => 0, + 'discount' => 0, + 'number' => uniqid("st", true), + 'line_items' => [ + $item + ] + ]); + + $data = [ + 'client_id' => $this->client->hashed_id, + 'invoices' => [ + [ + 'invoice_id' => $invoice->hashed_id, + 'amount' => 20, + ], + ], + 'credits' => [ + [ + 'credit_id' => $credit->hashed_id, + 'amount' => 20, + ], + ], + 'date' => '2020/12/12', + + ]; + + $response = null; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments?include=invoices', $data); + + $arr = $response->json(); + $response->assertStatus(200); + + $payment_id = $arr['data']['id']; + $this->assertEquals(Credit::STATUS_APPLIED, $credit->fresh()->status_id); + $this->assertEquals(Invoice::STATUS_PAID, $invoice->fresh()->status_id); + + $this->assertEquals(0, $credit->fresh()->balance); + $this->assertEquals(0, $invoice->fresh()->balance); + + } + public function testStorePaymentWithCreditsThenDeletingInvoices() { $client = Client::factory()->create(['company_id' =>$this->company->id, 'user_id' => $this->user->id, 'balance' => 20, 'paid_to_date' => 0]);