diff --git a/app/Http/Requests/Payment/RefundPaymentRequest.php b/app/Http/Requests/Payment/RefundPaymentRequest.php index 8b83a65229b3..f107ea52c416 100644 --- a/app/Http/Requests/Payment/RefundPaymentRequest.php +++ b/app/Http/Requests/Payment/RefundPaymentRequest.php @@ -53,9 +53,9 @@ class RefundPaymentRequest extends Request if(isset($input['credits'])) { - - foreach($input['credits'] as $key => $credit) - $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($credit['credit_id']); + unset($input['credits']); + // foreach($input['credits'] as $key => $credit) + // $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($credit['credit_id']); } diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index 98b3d4de5632..00f26baeb00a 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -60,8 +60,12 @@ class StorePaymentRequest extends Request if (isset($input['credits']) && is_array($input['credits']) !== false) { foreach ($input['credits'] as $key => $value) { - $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']); - $credits_total += $value['amount']; + + if(array_key_exists('credit_id', $input['credits'][$key])) + { + $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']); + $credits_total += $value['amount']; + } } } @@ -69,7 +73,7 @@ class StorePaymentRequest extends Request $input['credits'] = null; } - if(!isset($input['amount'])){ + if(!isset($input['amount']) || $input['amount'] == 0){ $input['amount'] = $invoices_total - $credits_total; } diff --git a/app/Http/ValidationRules/Payment/ValidRefundableRequest.php b/app/Http/ValidationRules/Payment/ValidRefundableRequest.php index 17d50b59fcc2..2f454b893efe 100644 --- a/app/Http/ValidationRules/Payment/ValidRefundableRequest.php +++ b/app/Http/ValidationRules/Payment/ValidRefundableRequest.php @@ -63,19 +63,19 @@ class ValidRefundableRequest implements Rule } - if($payment->credits()->exists()) - { - foreach($payment->credits as $paymentable_credit) - $this->checkCredit($paymentable_credit, $request_credits); - } + // if($payment->credits()->exists()) + // { + // foreach($payment->credits as $paymentable_credit) + // $this->checkCredit($paymentable_credit, $request_credits); + // } foreach($request_invoices as $request_invoice) $this->checkInvoiceIsPaymentable($request_invoice, $payment); - foreach($request_credits as $request_credit) - $this->checkCreditIsPaymentable($request_credit, $payment); + // foreach($request_credits as $request_credit) + // $this->checkCreditIsPaymentable($request_credit, $payment); if(strlen($this->error_msg) > 0 ) diff --git a/app/Http/ValidationRules/ValidCreditsPresentRule.php b/app/Http/ValidationRules/ValidCreditsPresentRule.php index 31bfc5d5c72b..593eae6062f5 100644 --- a/app/Http/ValidationRules/ValidCreditsPresentRule.php +++ b/app/Http/ValidationRules/ValidCreditsPresentRule.php @@ -14,6 +14,7 @@ namespace App\Http\ValidationRules; use App\Libraries\MultiDB; use App\Models\Credit; use App\Models\User; +use App\Utils\Traits\MakesHash; use Illuminate\Contracts\Validation\Rule; /** @@ -22,6 +23,7 @@ use Illuminate\Contracts\Validation\Rule; */ class ValidCreditsPresentRule implements Rule { + use MakesHash; /** * @param string $attribute @@ -38,7 +40,7 @@ class ValidCreditsPresentRule implements Rule */ public function message() { - return 'Attempting to use one or more invalid credits'; + return 'Insufficient balance on credit.'; } @@ -51,9 +53,9 @@ class ValidCreditsPresentRule implements Rule { foreach(request()->input('credits') as $credit) { - $cred = Credit::find($credit['invoice_id']); + $cred = Credit::find($this->decodePrimaryKey($credit['credit_id'])); - if($cred->balance >= $credit['amount']) + if($cred->balance == 0) return false; } } diff --git a/app/Jobs/Product/UpdateOrCreateProduct.php b/app/Jobs/Product/UpdateOrCreateProduct.php index ce0067d97bd6..8a08d4b5d3dd 100644 --- a/app/Jobs/Product/UpdateOrCreateProduct.php +++ b/app/Jobs/Product/UpdateOrCreateProduct.php @@ -62,8 +62,8 @@ class UpdateOrCreateProduct implements ShouldQueue $product->product_key = $item->product_key; $product->notes = isset($item->notes) ? $item->notes : ''; - $product->cost = isset($item->cost) ? $item->cost : 0; - $product->price = isset($item->price) ? $item->price : 0; + //$product->cost = isset($item->cost) ? $item->cost : 0; //this value shouldn't be updated. + $product->price = isset($item->price) ? $item->cost : 0; $product->quantity = isset($item->quantity) ? $item->quantity : 0; $product->tax_name1 = isset($item->tax_name1) ? $item->tax_name1 : ''; $product->tax_rate1 = isset($item->tax_rate1) ? $item->tax_rate1 : 0 ; diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index e144b6745ec6..ebcf1480bfe2 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -15,6 +15,7 @@ use App\Events\Payment\PaymentWasCreated; use App\Factory\CreditFactory; use App\Jobs\Client\UpdateClientPaidToDate; use App\Jobs\Company\UpdateCompanyLedgerWithPayment; +use App\Jobs\Credit\ApplyCreditPayment; use App\Jobs\Invoice\ApplyClientPayment; use App\Jobs\Invoice\ApplyInvoicePayment; use App\Jobs\Invoice\UpdateInvoicePayment; @@ -117,7 +118,7 @@ class PaymentRepository extends BaseRepository $credit = Credit::whereId($paid_credit['credit_id'])->first(); if ($credit) - ApplyCreditPayment::dispatchNow($paid_credit, $payment, $paid_credit['amount'], $credit->company); + ApplyCreditPayment::dispatchNow($credit, $payment, $paid_credit['amount'], $credit->company); } } @@ -126,6 +127,8 @@ class PaymentRepository extends BaseRepository $invoice_totals -= $credit_totals; + //$payment->amount = $invoice_totals; //creates problems when setting amount like this. + if ($invoice_totals == $payment->amount) $payment->applied += $payment->amount; elseif ($invoice_totals < $payment->amount) diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php index 8cfa604a4509..18805cccfa61 100644 --- a/tests/Feature/PaymentTest.php +++ b/tests/Feature/PaymentTest.php @@ -41,6 +41,10 @@ class PaymentTest extends TestCase parent::setUp(); + $this->withoutMiddleware( + ThrottleRequests::class + ); + Session::start(); $this->faker = \Faker\Factory::create(); diff --git a/tests/Feature/RefundTest.php b/tests/Feature/RefundTest.php index e26fd6685a04..d2359fadd8ea 100644 --- a/tests/Feature/RefundTest.php +++ b/tests/Feature/RefundTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature; use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; use App\Factory\ClientFactory; +use App\Factory\CreditFactory; use App\Factory\InvoiceFactory; use App\Factory\PaymentFactory; use App\Helpers\Invoice\InvoiceSum; @@ -18,6 +19,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; +use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Session; use Illuminate\Validation\ValidationException; @@ -41,6 +43,10 @@ class RefundTest extends TestCase parent::setUp(); + $this->withoutMiddleware( + ThrottleRequests::class + ); + Session::start(); $this->faker = \Faker\Factory::create(); @@ -488,8 +494,135 @@ class RefundTest extends TestCase } + /** + * Test refunds where payments include credits + * + * $10 invoice + * $10 credit + * $50 credit card payment + * + * + * result should be + * + * payment.applied = 10 + * credit.balance = 0 + * + */ + public function testRefundWhereCreditsArePresent() + { + $client = ClientFactory::create($this->company->id, $this->user->id); + $client->save(); + + $this->invoice = InvoiceFactory::create($this->company->id,$this->user->id);//stub the company and user_id + $this->invoice->client_id = $client->id; + $this->invoice->status_id = Invoice::STATUS_SENT; + + $this->invoice->line_items = $this->buildLineItems(); + $this->invoice->uses_inclusive_taxes = false; + + $this->invoice->save(); + + $this->invoice_calc = new InvoiceSum($this->invoice); + $this->invoice_calc->build(); + + $this->invoice = $this->invoice_calc->getInvoice(); + $this->invoice->save(); + + $this->credit = CreditFactory::create($this->company->id,$this->user->id); + $this->credit->client_id = $this->client->id; + + $this->credit->line_items = $this->buildLineItems(); + $this->credit->amount = 10; + $this->credit->balance = 10; + + $this->credit->uses_inclusive_taxes = false; + $this->credit->save(); + + $data = [ + 'amount' => 50, + 'client_id' => $client->hashed_id, + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => $this->invoice->amount + ], + ], + 'credits' => [ + [ + 'credit_id' => $this->credit->hashed_id, + 'amount' => $this->credit->amount + ], + ], + 'date' => '2020/12/12', + + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/payments', $data); + }catch(ValidationException $e) + { + $message = json_decode($e->validator->getMessageBag(),1); + \Log::error($message); + } + + $arr = $response->json(); + $response->assertStatus(200); + + $payment_id = $arr['data']['id']; + + $this->assertEquals(50, $arr['data']['amount']); + + $payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first(); + + $this->assertNotNull($payment); + $this->assertNotNull($payment->invoices()); + $this->assertEquals(1, $payment->invoices()->count()); + + + $data = [ + 'id' => $this->encodePrimaryKey($payment->id), + 'amount' => 50, + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => $this->invoice->amount + ], + ], + 'date' => '2020/12/12', + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/payments/refund', $data); + }catch(ValidationException $e) + { + $message = json_decode($e->validator->getMessageBag(),1); + \Log::error("refund message error"); + \Log::error($message); + } + + + $response->assertStatus(200); + $arr = $response->json(); + + $payment = Payment::find($this->decodePrimaryKey($arr['data']['id'])); + +// \Log::error(print_r($payment->paymentables->toArray(),1)); + + + + + } /*Additional scenarios*/ - /*Test refunds where payments include credits*/ } diff --git a/tests/Feature/TemplateApiTest.php b/tests/Feature/TemplateApiTest.php index 9e8e2bebebae..159043ccb661 100644 --- a/tests/Feature/TemplateApiTest.php +++ b/tests/Feature/TemplateApiTest.php @@ -15,6 +15,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Http\Request; +use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Session; use Tests\MockAccountData; @@ -34,6 +35,10 @@ class TemplateApiTest extends TestCase { parent::setUp(); + $this->withoutMiddleware( + ThrottleRequests::class + ); + $this->makeTestData(); Session::start(); diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index 622f588e4534..917c93d38cbe 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -36,6 +36,10 @@ class UserTest extends TestCase { parent::setUp(); + $this->withoutMiddleware( + ThrottleRequests::class + ); + Session::start(); $this->faker = \Faker\Factory::create(); diff --git a/tests/Integration/UploadFileTest.php b/tests/Integration/UploadFileTest.php index 98814929c397..3840aa4f8166 100644 --- a/tests/Integration/UploadFileTest.php +++ b/tests/Integration/UploadFileTest.php @@ -17,6 +17,7 @@ use App\Models\User; use Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Http\UploadedFile; +use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Facades\Log; use Tests\MockAccountData; use Tests\TestCase; @@ -35,6 +36,10 @@ class UploadFileTest extends TestCase parent::setUp(); $this->makeTestData(); + + $this->withoutMiddleware( + ThrottleRequests::class + ); } diff --git a/tests/MockAccountData.php b/tests/MockAccountData.php index d10bf0e58958..5d5c2c621068 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -168,7 +168,7 @@ trait MockAccountData $this->invoice->client_id = $this->client->id; $this->invoice->line_items = $this->buildLineItems(); - $this->invoice->uses_inclusive_Taxes = false; + $this->invoice->uses_inclusive_taxes = false; $this->invoice->save(); @@ -185,7 +185,10 @@ trait MockAccountData $this->credit->client_id = $this->client->id; $this->credit->line_items = $this->buildLineItems(); - $this->credit->uses_inclusive_Taxes = false; + $this->credit->amount = 10; + $this->credit->balance = 10; + + $this->credit->uses_inclusive_taxes = false; $this->credit->save(); diff --git a/tests/Unit/Migration/ImportTest.php b/tests/Unit/Migration/ImportTest.php index 7f27aac6881c..f07834b223b8 100644 --- a/tests/Unit/Migration/ImportTest.php +++ b/tests/Unit/Migration/ImportTest.php @@ -30,11 +30,21 @@ class ImportTest extends TestCase use MockAccountData; use DatabaseTransactions; + public $migration_array; + public function setUp(): void { parent::setUp(); $this->makeTestData(); + + $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + + $handle = fopen($migration_file, "r"); + $migration_file = fread($handle, filesize($migration_file)); + fclose($handle); + + $this->migration_array = json_decode($migration_file,1); } public function testImportClassExists() @@ -95,11 +105,11 @@ class ImportTest extends TestCase $original_count = Invoice::count(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + //$this->migration_array = json_decode(file_get_contents($migration_file), 1); + + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertGreaterThan($original_count, Invoice::count()); } @@ -122,13 +132,13 @@ class ImportTest extends TestCase public function testImportFileExists() { - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $this->assertTrue(file_exists($migration_file)); + // $this->assertTrue(file_exists($migration_file)); - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - $this->assertGreaterThan(1, count($migration_array)); + $this->assertGreaterThan(1, count($this->migration_array)); } @@ -139,11 +149,11 @@ class ImportTest extends TestCase $this->invoice->forceDelete(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertTrue(true); } @@ -180,11 +190,11 @@ class ImportTest extends TestCase $this->invoice->forceDelete(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertGreaterThan($original_number, Invoice::count()); @@ -198,9 +208,9 @@ class ImportTest extends TestCase // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - // $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - // Import::dispatchNow($migration_array, $this->company, $this->user); + // Import::dispatchNow($this->migration_array, $this->company, $this->user); // $this->assertGreaterThan($original_number, Invoice::count()); @@ -232,9 +242,9 @@ class ImportTest extends TestCase // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - // $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - // Import::dispatchNow($migration_array, $this->company, $this->user); + // Import::dispatchNow($this->migration_array, $this->company, $this->user); // $this->assertGreaterThan($original_number, Invoice::count()); @@ -254,11 +264,11 @@ class ImportTest extends TestCase $this->invoice->forceDelete(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertGreaterThan($original_count, Payment::count()); } @@ -285,11 +295,11 @@ class ImportTest extends TestCase $this->invoice->forceDelete(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertGreaterThan($original_count, Credit::count()); } @@ -319,16 +329,16 @@ class ImportTest extends TestCase { $this->invoice->forceDelete(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $differences = []; - foreach ($migration_array['invoices'] as $key => $invoices) { + foreach ($this->migration_array['invoices'] as $key => $invoices) { $record = Invoice::whereNumber($invoices['number']) ->whereAmount($invoices['amount']) ->whereBalance($invoices['balance']) @@ -339,7 +349,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['users'] as $key => $user) { + foreach ($this->migration_array['users'] as $key => $user) { $record = User::whereEmail($user['email'])->first(); if (!$record) { @@ -347,7 +357,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['tax_rates'] as $key => $tax_rate) { + foreach ($this->migration_array['tax_rates'] as $key => $tax_rate) { $record = TaxRate::whereName($tax_rate['name']) ->where('rate', $tax_rate['rate']) ->first(); @@ -357,7 +367,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['clients'] as $key => $client) { + foreach ($this->migration_array['clients'] as $key => $client) { $record = Client::whereName($client['name']) ->whereCity($client['city']) // ->where('paid_to_date', $client['paid_to_date']) // TODO: Doesn't work. Need debugging. @@ -368,7 +378,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['products'] as $key => $product) { + foreach ($this->migration_array['products'] as $key => $product) { $record = Product::where('product_key', $product['product_key']) ->first(); @@ -377,7 +387,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['quotes'] as $key => $quote) { + foreach ($this->migration_array['quotes'] as $key => $quote) { $record = Quote::whereNumber($quote['number']) ->whereIsAmountDiscount($quote['is_amount_discount']) ->whereDueDate($quote['due_date']) @@ -388,7 +398,7 @@ class ImportTest extends TestCase } } - foreach ($migration_array['payments'] as $key => $payment) { + foreach ($this->migration_array['payments'] as $key => $payment) { $record = Payment::whereAmount($payment['amount']) ->whereApplied($payment['applied']) ->whereRefunded($payment['refunded']) @@ -399,7 +409,7 @@ class ImportTest extends TestCase } } - /*foreach ($migration_array['credits'] as $key => $credit) { + /*foreach ($this->migration_array['credits'] as $key => $credit) { // The Import::processCredits() does insert the credit record with number: 0053, // .. however this part of the code doesn't see it at all. @@ -421,11 +431,11 @@ class ImportTest extends TestCase $original = ClientContact::count(); - $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; + // $migration_file = base_path() . '/tests/Unit/Migration/migration.json'; - $migration_array = json_decode(file_get_contents($migration_file), 1); + // $this->migration_array = json_decode(file_get_contents($migration_file), 1); - Import::dispatchNow($migration_array, $this->company, $this->user); + Import::dispatchNow($this->migration_array, $this->company, $this->user); $this->assertGreaterThan($original, ClientContact::count()); }