From e519234fe026fdabcd56db4d028daef15106bb67 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 08:24:30 +1000 Subject: [PATCH 1/7] v5.6.25 --- app/Models/Credit.php | 8 ++++---- .../Migration/PaymentMigrationRepository.php | 2 ++ app/Repositories/PaymentRepository.php | 2 +- app/Repositories/SubscriptionRepository.php | 2 ++ app/Repositories/TaskRepository.php | 9 ++++++--- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/Models/Credit.php b/app/Models/Credit.php index 0fb203bd38d3..12923bc4f555 100644 --- a/app/Models/Credit.php +++ b/app/Models/Credit.php @@ -57,11 +57,11 @@ use Laracasts\Presenter\PresentableTrait; * @property string|null $private_notes * @property string|null $terms * @property string|null $tax_name1 - * @property string $tax_rate1 + * @property float $tax_rate1 * @property string|null $tax_name2 - * @property string $tax_rate2 + * @property float $tax_rate2 * @property string|null $tax_name3 - * @property string $tax_rate3 + * @property float $tax_rate3 * @property string $total_taxes * @property int $uses_inclusive_taxes * @property string|null $custom_value1 @@ -90,7 +90,7 @@ use Laracasts\Presenter\PresentableTrait; * @property string|null $reminder2_sent * @property string|null $reminder3_sent * @property string|null $reminder_last_sent - * @property string $paid_to_date + * @property float $paid_to_date * @property int|null $subscription_id * @property-read \Illuminate\Database\Eloquent\Collection $activities * @property-read int|null $activities_count diff --git a/app/Repositories/Migration/PaymentMigrationRepository.php b/app/Repositories/Migration/PaymentMigrationRepository.php index c5de18c89ecd..762944609f83 100644 --- a/app/Repositories/Migration/PaymentMigrationRepository.php +++ b/app/Repositories/Migration/PaymentMigrationRepository.php @@ -146,6 +146,8 @@ class PaymentMigrationRepository extends BaseRepository } if (array_key_exists('credits', $data) && is_array($data['credits']) && count($data['credits']) > 0) { + + /** @var float $credit_totals **/ $credit_totals = array_sum(array_column($data['credits'], 'amount')); $credits = Credit::whereIn('id', array_column($data['credits'], 'credit_id'))->withTrashed()->get(); diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index 0c3ce1c8ce75..4400e66155ef 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -188,7 +188,7 @@ class PaymentRepository extends BaseRepository $paymentable->save(); $credit = $credit->service()->markSent()->save(); - (new ApplyCreditPayment($credit, $payment, $paid_credit['amount'], $credit->company))->handle(); + (new ApplyCreditPayment($credit, $payment, $paid_credit['amount']))->handle(); } } } diff --git a/app/Repositories/SubscriptionRepository.php b/app/Repositories/SubscriptionRepository.php index dd647ca5d32f..4e1d05f9f291 100644 --- a/app/Repositories/SubscriptionRepository.php +++ b/app/Repositories/SubscriptionRepository.php @@ -48,6 +48,7 @@ class SubscriptionRepository extends BaseRepository DB::connection(config('database.default'))->beginTransaction(); $data = []; + /** @var \App\Models\Client $client **/ $client = Client::factory()->create([ 'user_id' => $subscription->user_id, 'company_id' => $subscription->company_id, @@ -56,6 +57,7 @@ class SubscriptionRepository extends BaseRepository 'settings' => ClientSettings::defaults(), ]); + /** @var \App\Models\ClientContact $contact **/ $contact = ClientContact::factory()->create([ 'user_id' => $subscription->user_id, 'company_id' => $subscription->company_id, diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index be1f17e4911d..051a2c1c5689 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -148,13 +148,16 @@ class TaskRepository extends BaseRepository * Store tasks in bulk. * * @param array $task - * @return task|null + * @return Task|null */ public function create($task): ?Task { + /** @var \App\Models\User $user **/ + $user = auth()->user(); + return $this->save( $task, - TaskFactory::create(auth()->user()->company()->id, auth()->user()->id) + TaskFactory::create($user->company()->id, $user->id) ); } @@ -175,7 +178,7 @@ class TaskRepository extends BaseRepository /** * Sorts the task status order IF the old status has changed between requests * - * @param stdCLass $old_task The old task object + * @param \stdCLass $old_task The old task object * @param Task $new_task The new Task model * @return void */ From 8a3514aa57308780b732e33ea1b438ce6360e449 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 08:30:17 +1000 Subject: [PATCH 2/7] v5.6.25 --- app/Repositories/TaskStatusRepository.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Repositories/TaskStatusRepository.php b/app/Repositories/TaskStatusRepository.php index c3702136056c..faf650ef2203 100644 --- a/app/Repositories/TaskStatusRepository.php +++ b/app/Repositories/TaskStatusRepository.php @@ -21,6 +21,7 @@ class TaskStatusRepository extends BaseRepository { public function delete($task_status) { + /** @var \App\Models\TaskStatus $ts **/ $ts = TaskStatus::where('company_id', $task_status->company_id) ->first(); From d00cdd29f77bb00c0a3054ab1180793ba2029871 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 08:40:08 +1000 Subject: [PATCH 3/7] Fixes for expense id encoding in bank transactions --- app/Models/BankTransaction.php | 5 ++--- app/Repositories/Migration/PaymentMigrationRepository.php | 2 +- app/Transformers/BankTransactionTransformer.php | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/Models/BankTransaction.php b/app/Models/BankTransaction.php index f67e75a9d634..2772e0d146f2 100644 --- a/app/Models/BankTransaction.php +++ b/app/Models/BankTransaction.php @@ -59,7 +59,6 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @method static \Illuminate\Database\Eloquent\Builder|BankTransaction onlyTrashed() * @method static \Illuminate\Database\Eloquent\Builder|BankTransaction query() * @method static \Illuminate\Database\Eloquent\Builder|BaseModel scope() - * @method static \Illuminate\Database\Eloquent\Account withTrashed() * @method static \Illuminate\Database\Eloquent\Builder|BankTransaction withoutTrashed() * @property-read \App\Models\Payment|null $payment * @mixin \Eloquent @@ -137,12 +136,12 @@ class BankTransaction extends BaseModel public function vendor(): \Illuminate\Database\Eloquent\Relations\BelongsTo { - return $this->belongsTo(Vendor::class); + return $this->belongsTo(Vendor::class)->withTrashed(); } public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo { - return $this->belongsTo(Expense::class); + return $this->belongsTo(Expense::class)->withTrashed(); } public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Repositories/Migration/PaymentMigrationRepository.php b/app/Repositories/Migration/PaymentMigrationRepository.php index 762944609f83..00bf928ae367 100644 --- a/app/Repositories/Migration/PaymentMigrationRepository.php +++ b/app/Repositories/Migration/PaymentMigrationRepository.php @@ -156,7 +156,7 @@ class PaymentMigrationRepository extends BaseRepository $payment->credits->each(function ($cre) use ($credit_totals) { $cre->pivot->amount = $credit_totals; - $cre->pivot->save(); + $cre->pivot->save(); $cre->paid_to_date += $credit_totals; $cre->balance -= $credit_totals; diff --git a/app/Transformers/BankTransactionTransformer.php b/app/Transformers/BankTransactionTransformer.php index 5d941dbefe68..e128d9b9869b 100644 --- a/app/Transformers/BankTransactionTransformer.php +++ b/app/Transformers/BankTransactionTransformer.php @@ -63,7 +63,7 @@ class BankTransactionTransformer extends EntityTransformer 'description' => (string) $bank_transaction->description ?: '', 'base_type' => (string) $bank_transaction->base_type ?: '', 'invoice_ids' => (string) $bank_transaction->invoice_ids ?: '', - 'expense_id'=> (string) $bank_transaction->expense_id ?: '', + 'expense_id'=> (string) $this->encodePrimaryKey($bank_transaction->expense_id) ?: '', 'payment_id'=> (string) $this->encodePrimaryKey($bank_transaction->payment_id) ?: '', 'vendor_id'=> (string) $this->encodePrimaryKey($bank_transaction->vendor_id) ?: '', 'bank_transaction_rule_id' => (string) $this->encodePrimaryKey($bank_transaction->bank_transaction_rule_id) ?: '', From 0a37f2940cd51d9b9033b0c24a0b2fed4192f423 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 13:32:59 +1000 Subject: [PATCH 4/7] Fixes for setting and linking expense id --- .../UpdateBankTransactionRequest.php | 12 ++++++------ app/Repositories/BankTransactionRepository.php | 18 +++++++++++++----- .../BankTransactionTransformer.php | 2 +- tests/Feature/BankTransactionApiTest.php | 18 +++++++++++++++++- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/app/Http/Requests/BankTransaction/UpdateBankTransactionRequest.php b/app/Http/Requests/BankTransaction/UpdateBankTransactionRequest.php index c774e8a1dd75..fca323fe2c9a 100644 --- a/app/Http/Requests/BankTransaction/UpdateBankTransactionRequest.php +++ b/app/Http/Requests/BankTransaction/UpdateBankTransactionRequest.php @@ -44,9 +44,9 @@ class UpdateBankTransactionRequest extends Request $rules['vendor_id'] = 'bail|required|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; } - if (isset($this->expense_id)) { - $rules['expense_id'] = 'bail|required|exists:expenses,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; - } + // if (isset($this->expense_id)) { + // $rules['expense_id'] = 'bail|required|exists:expenses,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; + // } $rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; @@ -67,9 +67,9 @@ class UpdateBankTransactionRequest extends Request $input['vendor_id'] = $this->decodePrimaryKey($input['vendor_id']); } - if (array_key_exists('expense_id', $input) && strlen($input['expense_id']) > 1) { - $input['expense_id'] = $this->decodePrimaryKey($input['expense_id']); - } + // if (array_key_exists('expense_id', $input) && strlen($input['expense_id']) > 1) { + // $input['expense_id'] = $this->decodePrimaryKey($input['expense_id']); + // } if (array_key_exists('ninja_category_id', $input) && strlen($input['ninja_category_id']) > 1) { $input['ninja_category_id'] = $this->decodePrimaryKey($input['ninja_category_id']); diff --git a/app/Repositories/BankTransactionRepository.php b/app/Repositories/BankTransactionRepository.php index d9db85172a13..4130e72333e0 100644 --- a/app/Repositories/BankTransactionRepository.php +++ b/app/Repositories/BankTransactionRepository.php @@ -11,20 +11,23 @@ namespace App\Repositories; -use App\Jobs\Bank\MatchBankTransactions; +use App\Models\Expense; use App\Models\BankTransaction; +use App\Jobs\Bank\MatchBankTransactions; /** * Class for bank transaction repository. */ class BankTransactionRepository extends BaseRepository { + public function save($data, BankTransaction $bank_transaction) { if (array_key_exists('bank_integration_id', $data)) { $bank_transaction->bank_integration_id = $data['bank_integration_id']; } + $bank_transaction->fill($data); $bank_transaction->save(); @@ -49,11 +52,16 @@ class BankTransactionRepository extends BaseRepository $bt->payment_id = null; } - if($bt->expense()->exists()) { - $bt->expense->transaction_id = null; - $bt->expense_id = null; - } + $e = Expense::whereIn('id', $this->transformKeys(explode(",", $bt->expense_id))) + ->cursor() + ->each(function ($expense){ + + $expense->transaction_id = null; + $expense->saveQuietly(); + + }); + $bt->expense_id = null; $bt->vendor_id = null; $bt->status_id = 1; $bt->invoice_ids = null; diff --git a/app/Transformers/BankTransactionTransformer.php b/app/Transformers/BankTransactionTransformer.php index e128d9b9869b..5d941dbefe68 100644 --- a/app/Transformers/BankTransactionTransformer.php +++ b/app/Transformers/BankTransactionTransformer.php @@ -63,7 +63,7 @@ class BankTransactionTransformer extends EntityTransformer 'description' => (string) $bank_transaction->description ?: '', 'base_type' => (string) $bank_transaction->base_type ?: '', 'invoice_ids' => (string) $bank_transaction->invoice_ids ?: '', - 'expense_id'=> (string) $this->encodePrimaryKey($bank_transaction->expense_id) ?: '', + 'expense_id'=> (string) $bank_transaction->expense_id ?: '', 'payment_id'=> (string) $this->encodePrimaryKey($bank_transaction->payment_id) ?: '', 'vendor_id'=> (string) $this->encodePrimaryKey($bank_transaction->vendor_id) ?: '', 'bank_transaction_rule_id' => (string) $this->encodePrimaryKey($bank_transaction->bank_transaction_rule_id) ?: '', diff --git a/tests/Feature/BankTransactionApiTest.php b/tests/Feature/BankTransactionApiTest.php index 79496014fd28..f27aa681f843 100644 --- a/tests/Feature/BankTransactionApiTest.php +++ b/tests/Feature/BankTransactionApiTest.php @@ -12,6 +12,7 @@ namespace Tests\Feature; use Tests\TestCase; +use App\Models\Expense; use Tests\MockAccountData; use App\Models\BankIntegration; use App\Models\BankTransaction; @@ -122,19 +123,31 @@ class BankTransactionApiTest extends TestCase 'user_id' => $this->user->id, ]); + $e = Expense::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + ]); + $bank_transaction = BankTransaction::factory()->create([ 'bank_integration_id' => $bi->id, 'user_id' => $this->user->id, 'company_id' => $this->company->id, 'payment_id' => $this->payment->id, - 'expense_id' => $this->expense->id, + 'expense_id' => "{$this->expense->hashed_id},{$e->hashed_id}", 'invoice_ids' => $this->invoice->hashed_id, ]); + $e->transaction_id = $bank_transaction->id; + $e->save(); + + $this->expense->transaction_id = $bank_transaction->id; + $this->expense->save(); + $data = [ 'ids' => [$this->encodePrimaryKey($bank_transaction->id)], ]; + nlog($bank_transaction->toArray()); $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, @@ -146,6 +159,9 @@ class BankTransactionApiTest extends TestCase $this->assertEquals("", $arr['data'][0]['payment_id']); $this->assertEquals("", $arr['data'][0]['invoice_ids']); $this->assertEquals("", $arr['data'][0]['expense_id']); + + $this->assertNull($e->fresh()->transaction_id); + $this->assertNull($this->expense->fresh()->transaction_id); } } From 7fca2cd24f1c6b92f91ceb35d0f46536455431da Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 13:36:15 +1000 Subject: [PATCH 5/7] Minor fixes --- app/Factory/RecurringExpenseToExpenseFactory.php | 2 +- app/Jobs/Bank/MatchBankTransactions.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Factory/RecurringExpenseToExpenseFactory.php b/app/Factory/RecurringExpenseToExpenseFactory.php index 1f162eb8d73c..069a18410677 100644 --- a/app/Factory/RecurringExpenseToExpenseFactory.php +++ b/app/Factory/RecurringExpenseToExpenseFactory.php @@ -55,7 +55,7 @@ class RecurringExpenseToExpenseFactory $expense->custom_value2 = $recurring_expense->custom_value2; $expense->custom_value3 = $recurring_expense->custom_value3; $expense->custom_value4 = $recurring_expense->custom_value4; - $expense->transaction_id = $recurring_expense->transaction_id; + $expense->transaction_id = null; $expense->category_id = $recurring_expense->category_id; $expense->payment_type_id = $recurring_expense->payment_type_id; $expense->project_id = $recurring_expense->project_id; diff --git a/app/Jobs/Bank/MatchBankTransactions.php b/app/Jobs/Bank/MatchBankTransactions.php index 98b4c05dc700..4f38ff399ac9 100644 --- a/app/Jobs/Bank/MatchBankTransactions.php +++ b/app/Jobs/Bank/MatchBankTransactions.php @@ -148,7 +148,7 @@ class MatchBankTransactions implements ShouldQueue private function linkExpense($input) { - $this->bt = BankTransaction::find($input['id']); + $this->bt = BankTransaction::withTrashed()->find($input['id']); if (!$this->bt) { return $this; @@ -243,7 +243,7 @@ class MatchBankTransactions implements ShouldQueue private function matchExpense($input) :self { //if there is a category id, pull it from Yodlee and insert - or just reuse!! - $this->bt = BankTransaction::withTrashed()->find($input['id']); + $this->bt = BankTransaction::find($input['id']); if (!$this->bt || $this->bt->status_id == BankTransaction::STATUS_CONVERTED) { return $this; From 6a92d918959de7eaade9f90953e983de6c74f8bd Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 13:37:10 +1000 Subject: [PATCH 6/7] Update last sent date for recurring expenses --- app/Jobs/Cron/RecurringExpensesCron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/Cron/RecurringExpensesCron.php b/app/Jobs/Cron/RecurringExpensesCron.php index b3f785444a5c..1b51f2fc70f4 100644 --- a/app/Jobs/Cron/RecurringExpensesCron.php +++ b/app/Jobs/Cron/RecurringExpensesCron.php @@ -111,7 +111,7 @@ class RecurringExpensesCron $recurring_expense->next_send_date = $recurring_expense->nextSendDate(); $recurring_expense->next_send_date_client = $recurring_expense->next_send_date; - + $recurring_expense->last_sent_date = now(); $recurring_expense->remaining_cycles = $recurring_expense->remainingCycles(); $recurring_expense->save(); } From 57d63c833361e940fea9b7f49147f8fc1b7d272b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 3 Aug 2023 13:41:04 +1000 Subject: [PATCH 7/7] Updates for static analysis --- app/Filters/QueryFilters.php | 2 -- app/Models/Activity.php | 52 +++++++++++++----------------------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/app/Filters/QueryFilters.php b/app/Filters/QueryFilters.php index e0da087a8442..1f8f1ce4208c 100644 --- a/app/Filters/QueryFilters.php +++ b/app/Filters/QueryFilters.php @@ -289,7 +289,6 @@ abstract class QueryFilters /** * @return Builder - * @throws RuntimeException */ public function without_deleted_clients(): Builder { @@ -302,7 +301,6 @@ abstract class QueryFilters /** * @return Builder - * @throws RuntimeException */ public function without_deleted_vendors(): Builder { diff --git a/app/Models/Activity.php b/app/Models/Activity.php index 7105dbda7298..2677a149d5c5 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -274,7 +274,7 @@ class Activity extends StaticModel ]; - public function getHashedIdAttribute() + public function getHashedIdAttribute(): string { return $this->encodePrimaryKey($this->id); } @@ -285,109 +285,95 @@ class Activity extends StaticModel return self::class; } - - public function backup() + public function backup(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(Backup::class); } - - public function history() + public function history(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(Backup::class); } - public function user() :BelongsTo + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class)->withTrashed(); } - - public function contact() + public function contact(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(ClientContact::class, 'client_contact_id', 'id')->withTrashed(); } - - public function client() + public function client(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Client::class)->withTrashed(); } - - public function invoice() + public function invoice(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Invoice::class)->withTrashed(); } - public function vendor() + public function vendor(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Vendor::class)->withTrashed(); } - public function recurring_invoice() + public function recurring_invoice(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(RecurringInvoice::class)->withTrashed(); } - - public function credit() + public function credit(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Credit::class)->withTrashed(); } - - public function quote() + public function quote(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Quote::class)->withTrashed(); } - - public function subscription() + public function subscription(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Subscription::class)->withTrashed(); } - - public function payment() + public function payment(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Payment::class)->withTrashed(); } - - public function expense() + public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Expense::class)->withTrashed(); } - public function recurring_expense() + public function recurring_expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(RecurringExpense::class)->withTrashed(); } - - public function purchase_order() + public function purchase_order(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(PurchaseOrder::class)->withTrashed(); } - - public function vendor_contact() + public function vendor_contact(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(VendorContact::class)->withTrashed(); } - - public function task() + public function task(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Task::class)->withTrashed(); } - - public function company() + public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Company::class); }