From 18bb84f2a1716735e5f2b578c84bf8c0545ddbf6 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 21 Nov 2021 21:08:21 +1100 Subject: [PATCH 1/8] Fixes for client portal --- app/Http/Middleware/ContactAccount.php | 4 ++-- app/Http/Middleware/SetDomainNameDb.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Middleware/ContactAccount.php b/app/Http/Middleware/ContactAccount.php index e1ac296fc851..79faf0a9c740 100644 --- a/app/Http/Middleware/ContactAccount.php +++ b/app/Http/Middleware/ContactAccount.php @@ -32,8 +32,8 @@ class ContactAccount if(!Ninja::isHosted()) { $account_id = Account::first()->id; - $request->attributes->add(['account_id' => $account_id]); - + $request->request->add(['account_id' => $account_id]); + } return $next($request); diff --git a/app/Http/Middleware/SetDomainNameDb.php b/app/Http/Middleware/SetDomainNameDb.php index 728f14fcbf4d..ab49e9ef15dd 100644 --- a/app/Http/Middleware/SetDomainNameDb.php +++ b/app/Http/Middleware/SetDomainNameDb.php @@ -49,7 +49,7 @@ class SetDomainNameDb ]; if($company = MultiDB::findAndSetDbByDomain($query)){ - $request->attributes->add(['account_id' => $company->account_id]); + $request->request->add(['account_id' => $company->account_id]); } else { @@ -71,7 +71,7 @@ class SetDomainNameDb ]; if($company = MultiDB::findAndSetDbByDomain($query)){ - $request->attributes->add(['account_id' => $company->account_id]); + $request->request->add(['account_id' => $company->account_id]); } else { From 17482da60fc93db89530b0f8969c5543a9b58fa8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 21 Nov 2021 21:19:24 +1100 Subject: [PATCH 2/8] Add validation rules for discounts --- app/Http/Requests/Credit/StoreCreditRequest.php | 1 + app/Http/Requests/Credit/UpdateCreditRequest.php | 1 + app/Http/Requests/Invoice/StoreInvoiceRequest.php | 1 + app/Http/Requests/Invoice/UpdateInvoiceRequest.php | 1 + app/Http/Requests/Quote/StoreQuoteRequest.php | 1 + app/Http/Requests/Quote/UpdateQuoteRequest.php | 1 + 6 files changed, 6 insertions(+) diff --git a/app/Http/Requests/Credit/StoreCreditRequest.php b/app/Http/Requests/Credit/StoreCreditRequest.php index e4fc2f23ad53..5b0cd808ee5b 100644 --- a/app/Http/Requests/Credit/StoreCreditRequest.php +++ b/app/Http/Requests/Credit/StoreCreditRequest.php @@ -56,6 +56,7 @@ class StoreCreditRequest extends Request // $rules['number'] = new UniqueCreditNumberRule($this->all()); $rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)]; + $rules['discount'] = 'sometimes|numeric'; diff --git a/app/Http/Requests/Credit/UpdateCreditRequest.php b/app/Http/Requests/Credit/UpdateCreditRequest.php index 28cbfe2b4b0e..d7abee626b0a 100644 --- a/app/Http/Requests/Credit/UpdateCreditRequest.php +++ b/app/Http/Requests/Credit/UpdateCreditRequest.php @@ -57,6 +57,7 @@ class UpdateCreditRequest extends Request $rules['number'] = Rule::unique('credits')->where('company_id', auth()->user()->company()->id)->ignore($this->credit->id); $rules['line_items'] = 'array'; + $rules['discount'] = 'sometimes|numeric'; return $rules; } diff --git a/app/Http/Requests/Invoice/StoreInvoiceRequest.php b/app/Http/Requests/Invoice/StoreInvoiceRequest.php index efb4e9310673..06b0bf1b1cde 100644 --- a/app/Http/Requests/Invoice/StoreInvoiceRequest.php +++ b/app/Http/Requests/Invoice/StoreInvoiceRequest.php @@ -56,6 +56,7 @@ class StoreInvoiceRequest extends Request $rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())]; $rules['line_items'] = 'array'; + $rules['discount'] = 'sometimes|numeric'; return $rules; } diff --git a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php index d90688ef7b0c..d008d7a36bee 100644 --- a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php +++ b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php @@ -56,6 +56,7 @@ class UpdateInvoiceRequest extends Request $rules['number'] = Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->invoice->id); $rules['line_items'] = 'array'; + $rules['discount'] = 'sometimes|numeric'; if($this->input('status_id') != Invoice::STATUS_DRAFT) $rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all()); diff --git a/app/Http/Requests/Quote/StoreQuoteRequest.php b/app/Http/Requests/Quote/StoreQuoteRequest.php index 01145f54750f..30f5587f5917 100644 --- a/app/Http/Requests/Quote/StoreQuoteRequest.php +++ b/app/Http/Requests/Quote/StoreQuoteRequest.php @@ -50,6 +50,7 @@ class StoreQuoteRequest extends Request } $rules['number'] = ['nullable',Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)]; + $rules['discount'] = 'sometimes|numeric'; // $rules['number'] = new UniqueQuoteNumberRule($this->all()); $rules['line_items'] = 'array'; diff --git a/app/Http/Requests/Quote/UpdateQuoteRequest.php b/app/Http/Requests/Quote/UpdateQuoteRequest.php index d67ce3dc1f04..0fa9e56f7812 100644 --- a/app/Http/Requests/Quote/UpdateQuoteRequest.php +++ b/app/Http/Requests/Quote/UpdateQuoteRequest.php @@ -51,6 +51,7 @@ class UpdateQuoteRequest extends Request $rules['number'] = Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)->ignore($this->quote->id); $rules['line_items'] = 'array'; + $rules['discount'] = 'sometimes|numeric'; return $rules; } From 540e382bd13be75a70acaaf367b217788c3c22a8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 07:04:58 +1100 Subject: [PATCH 3/8] Fixes for system loggeR --- app/PaymentDrivers/MolliePaymentDriver.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/PaymentDrivers/MolliePaymentDriver.php b/app/PaymentDrivers/MolliePaymentDriver.php index 1aac3ee606ca..7215a65df07e 100644 --- a/app/PaymentDrivers/MolliePaymentDriver.php +++ b/app/PaymentDrivers/MolliePaymentDriver.php @@ -176,7 +176,7 @@ class MolliePaymentDriver extends BaseDriver SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_MOLLIE, $this->client, - $this->client->companyk + $this->client->company ); nlog($e->getMessage()); @@ -239,7 +239,8 @@ class MolliePaymentDriver extends BaseDriver SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_MOLLIE, - $this->client + $this->client, + $this->client->company ); return $payment; @@ -259,7 +260,8 @@ class MolliePaymentDriver extends BaseDriver SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, - $this->client + $this->client, + $this->client->company ); return false; @@ -331,7 +333,8 @@ class MolliePaymentDriver extends BaseDriver SystemLog::CATEGORY_GATEWAY_RESPONSE, $response, SystemLog::TYPE_MOLLIE, - $client + $client, + $client->company ); return response()->json([], 200); From d09025367f4bd1dbe1bc4cbb444e2f6375f1e53f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 07:20:53 +1100 Subject: [PATCH 4/8] Minor fixes --- app/PaymentDrivers/MolliePaymentDriver.php | 2 +- app/Services/Subscription/SubscriptionService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/PaymentDrivers/MolliePaymentDriver.php b/app/PaymentDrivers/MolliePaymentDriver.php index 7215a65df07e..e05fe4972924 100644 --- a/app/PaymentDrivers/MolliePaymentDriver.php +++ b/app/PaymentDrivers/MolliePaymentDriver.php @@ -312,7 +312,7 @@ class MolliePaymentDriver extends BaseDriver $client = $record->client; } else{ - $client = Client::withTrashed()->find($this->decodePrimaryKey($payment['metadata']->client_id)); + $client = Client::withTrashed()->find($this->decodePrimaryKey($payment->metadata->client_id)); } $message = [ diff --git a/app/Services/Subscription/SubscriptionService.php b/app/Services/Subscription/SubscriptionService.php index a1984fb7a2a0..56a09555d900 100644 --- a/app/Services/Subscription/SubscriptionService.php +++ b/app/Services/Subscription/SubscriptionService.php @@ -718,7 +718,7 @@ class SubscriptionService public function convertInvoiceToRecurring($client_id) :RecurringInvoice { - $client = Client::find($client_id); + $client = Client::withTrashed()->find($client_id); $subscription_repo = new SubscriptionRepository(); From 46c0ba1c7da7efea564719de02ed3b57c2c51274 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 12:53:40 +1100 Subject: [PATCH 5/8] Set DB in subscription service --- app/Services/Subscription/SubscriptionService.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Services/Subscription/SubscriptionService.php b/app/Services/Subscription/SubscriptionService.php index 56a09555d900..ba7da5f28670 100644 --- a/app/Services/Subscription/SubscriptionService.php +++ b/app/Services/Subscription/SubscriptionService.php @@ -717,7 +717,8 @@ class SubscriptionService */ public function convertInvoiceToRecurring($client_id) :RecurringInvoice { - + MultiDB::setDb($this->subscription->company->db); + $client = Client::withTrashed()->find($client_id); $subscription_repo = new SubscriptionRepository(); From 60d9b4f649965dd9dbb7cb3e4c0d37b4fbcd64eb Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 15:25:43 +1100 Subject: [PATCH 6/8] Working on negative payments for credits --- app/Http/Controllers/CreditController.php | 5 ++ app/Repositories/PaymentRepository.php | 2 +- app/Services/Credit/CreditService.php | 58 +++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 88a48009878a..067543775276 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -524,6 +524,11 @@ class CreditController extends BaseController { /*If we are using bulk actions, we don't want to return anything */ switch ($action) { + case 'mark_paid': + $credit->service()->markPaid()->save(); + return $this->itemResponse($credit); + break; + case 'clone_to_credit': $credit = CloneCreditFactory::create($credit, auth()->user()->id); diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index c7ae018be8f0..0307d177d132 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -191,7 +191,7 @@ class PaymentRepository extends BaseRepository { if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate'])) return $payment; - $client = Client::find($data['client_id']); + $client = Client::withTrashed()->find($data['client_id']); $client_currency = $client->getSetting('currency_id'); $company_currency = $client->company->settings->currency_id; diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index c6b41fb3eef3..9a867284afa3 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -11,8 +11,12 @@ namespace App\Services\Credit; +use App\Factory\PaymentFactory; use App\Jobs\Util\UnlinkFile; use App\Models\Credit; +use App\Models\Payment; +use App\Models\PaymentType; +use App\Repositories\PaymentRepository; use App\Services\Credit\CreateInvitations; use App\Services\Credit\TriggeredActions; use App\Utils\Traits\MakesHash; @@ -79,6 +83,60 @@ class CreditService return $this; } + /* + For euro users - we mark a credit as paid when + we need to document a refund of sorts. + + Criteria: Credit must be a negative value + A negative payment for the balance will be generated + This amount will be reduced from the clients paid to date. + + */ + public function markPaid() + { + if($this->credit->balance > 0) + return $this; + + $payment_repo = new PaymentRepository(); + + //set credit balance to zero + $adjustment = $this->credit->balance; + + $this->updateBalance($adjustment) + ->updatePaidToDate($adjustment) + ->save(); + + //create a negative payment of total $this->credit->balance + $payment = PaymentFactory::create($this->credit->company_id, $this->credit->user_id); + $payment->client_id = $this->credit->client_id; + $payment->amount = $adjustment; + $payment->applied = $adjustment; + $payment->refunded = 0; + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->type_id = PaymentType::CREDIT; + $payment->is_manual = true; + $payment->date = now(); + + $payment->saveQuietly(); + $payment->number = $payment->client->getNextPaymentNumber($payment->client, $payment); + $payment = $payment_repo->processExchangeRates(['client_id' => $this->credit->client_id], $payment); + $payment->saveQuietly(); + + $payment + ->credits() + ->attach($this->credit->id, ['amount' => $adjustment]); + + //reduce client paid_to_date by $this->credit->balance amount + $this->credit + ->client + ->updatePaidToDate($adjustment) + ->save(); + + event('eloquent.created: App\Models\Payment', $payment); + + return $this; + } + public function markSent() { $this->credit = (new MarkSent($this->credit->client, $this->credit))->run(); From 24c733827b250bc6fe706c11bd8c58bb35d74967 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 21:09:28 +1100 Subject: [PATCH 7/8] Handle negative payments --- app/Repositories/PaymentRepository.php | 2 +- app/Services/Credit/CreditService.php | 4 +++- app/Services/Invoice/AutoBillInvoice.php | 2 +- app/Services/Payment/DeletePayment.php | 7 ++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index 0307d177d132..4ea1e65340e3 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -185,7 +185,7 @@ class PaymentRepository extends BaseRepository { * @param $payment * @return */ - private function processExchangeRates($data, $payment) + public function processExchangeRates($data, $payment) { if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate'])) diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 9a867284afa3..22bd94a56448 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -16,6 +16,7 @@ use App\Jobs\Util\UnlinkFile; use App\Models\Credit; use App\Models\Payment; use App\Models\PaymentType; +use App\Repositories\CreditRepository; use App\Repositories\PaymentRepository; use App\Services\Credit\CreateInvitations; use App\Services\Credit\TriggeredActions; @@ -97,7 +98,7 @@ class CreditService if($this->credit->balance > 0) return $this; - $payment_repo = new PaymentRepository(); + $payment_repo = new PaymentRepository(new CreditRepository()); //set credit balance to zero $adjustment = $this->credit->balance; @@ -129,6 +130,7 @@ class CreditService //reduce client paid_to_date by $this->credit->balance amount $this->credit ->client + ->service() ->updatePaidToDate($adjustment) ->save(); diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index ae84ea16462a..f1ea59aefc8d 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -130,7 +130,7 @@ class AutoBillInvoice extends AbstractService info("Auto Bill payment captured for ".$this->invoice->number); } - return $this->invoice; + return $this->invoice->fresh(); } /** diff --git a/app/Services/Payment/DeletePayment.php b/app/Services/Payment/DeletePayment.php index 626327f803a7..58222c6e75d1 100644 --- a/app/Services/Payment/DeletePayment.php +++ b/app/Services/Payment/DeletePayment.php @@ -139,8 +139,13 @@ class DeletePayment if ($this->payment->credits()->exists()) { $this->payment->credits()->each(function ($paymentable_credit) { + $multiplier = 1; + + if($paymentable_credit->pivot->amount < 0) + $multiplier = -1; + $paymentable_credit->service() - ->updateBalance($paymentable_credit->pivot->amount) + ->updateBalance($paymentable_credit->pivot->amount*$multiplier) ->updatePaidToDate($paymentable_credit->pivot->amount*-1) ->setStatus(Credit::STATUS_SENT) ->save(); From 14e9e8358de56213d9a186efa53b2d4714d39a60 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 22 Nov 2021 21:30:32 +1100 Subject: [PATCH 8/8] Only generate invitations for contacts with send_email true --- app/Services/Invoice/CreateInvitations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Services/Invoice/CreateInvitations.php b/app/Services/Invoice/CreateInvitations.php index 07734ab6433f..fb5e26a82b7d 100644 --- a/app/Services/Invoice/CreateInvitations.php +++ b/app/Services/Invoice/CreateInvitations.php @@ -33,7 +33,7 @@ class CreateInvitations extends AbstractService public function run() { - $contacts = $this->invoice->client->contacts; + $contacts = $this->invoice->client->contacts()->where('send_email', true)->get(); if($contacts->count() == 0){ $this->createBlankContact();