diff --git a/app/Console/Commands/SendReminders.php b/app/Console/Commands/SendReminders.php index cb76a83ef9f0..b95ff4d90df8 100644 --- a/app/Console/Commands/SendReminders.php +++ b/app/Console/Commands/SendReminders.php @@ -63,8 +63,30 @@ class SendReminders extends Command config(['database.default' => $database]); } + $accounts = $this->accountRepo->findWithFees(); + $this->info(count($accounts) . ' accounts found with fees'); + + foreach ($accounts as $account) { + if (! $account->hasFeature(FEATURE_EMAIL_TEMPLATES_REMINDERS)) { + continue; + } + + $invoices = $this->invoiceRepo->findNeedingReminding($account, false); + $this->info($account->name . ': ' . count($invoices) . ' invoices found'); + + foreach ($invoices as $invoice) { + if ($reminder = $account->getInvoiceReminder($invoice, false)) { + $this->info('Charge fee: ' . $invoice->id); + $number = preg_replace('/[^0-9]/', '', $reminder); + $amount = $account->account_email_settings->{"late_fee{$number}_amount"}; + $percent = $account->account_email_settings->{"late_fee{$number}_percent"}; + $this->invoiceRepo->setLateFee($invoice, $amount, $percent); + } + } + } + $accounts = $this->accountRepo->findWithReminders(); - $this->info(count($accounts) . ' accounts found'); + $this->info(count($accounts) . ' accounts found with reminders'); /** @var \App\Models\Account $account */ foreach ($accounts as $account) { @@ -78,7 +100,7 @@ class SendReminders extends Command /** @var Invoice $invoice */ foreach ($invoices as $invoice) { if ($reminder = $account->getInvoiceReminder($invoice)) { - $this->info('Send to ' . $invoice->id); + $this->info('Send email: ' . $invoice->id); $this->mailer->sendInvoice($invoice, $reminder); } } diff --git a/app/Constants.php b/app/Constants.php index d6591d31d13d..3582416268eb 100644 --- a/app/Constants.php +++ b/app/Constants.php @@ -46,6 +46,7 @@ if (! defined('APP_NAME')) { define('INVOICE_ITEM_TYPE_TASK', 2); define('INVOICE_ITEM_TYPE_PENDING_GATEWAY_FEE', 3); define('INVOICE_ITEM_TYPE_PAID_GATEWAY_FEE', 4); + define('INVOICE_ITEM_TYPE_LATE_FEE', 5); define('PERSON_CONTACT', 'contact'); define('PERSON_USER', 'user'); diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index d6bda523de13..06c340f9d5e0 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -823,6 +823,10 @@ class AccountController extends BaseController $account->{"num_days_{$type}"} = Input::get("num_days_{$type}"); $account->{"field_{$type}"} = Input::get("field_{$type}"); $account->{"direction_{$type}"} = Input::get("field_{$type}") == REMINDER_FIELD_INVOICE_DATE ? REMINDER_DIRECTION_AFTER : Input::get("direction_{$type}"); + + $number = preg_replace('/[^0-9]/', '', $type); + $account->account_email_settings->{"late_fee{$number}_amount"} = Input::get("late_fee{$number}_amount"); + $account->account_email_settings->{"late_fee{$number}_percent"} = Input::get("late_fee{$number}_percent"); } $account->save(); diff --git a/app/Models/AccountEmailSettings.php b/app/Models/AccountEmailSettings.php index 752b2aea1e19..8de75d1d3451 100644 --- a/app/Models/AccountEmailSettings.php +++ b/app/Models/AccountEmailSettings.php @@ -27,6 +27,12 @@ class AccountEmailSettings extends Eloquent 'email_template_reminder1', 'email_template_reminder2', 'email_template_reminder3', + 'late_fee1_amount', + 'late_fee1_percent', + 'late_fee2_amount', + 'late_fee2_percent', + 'late_fee3_amount', + 'late_fee3_percent', ]; } diff --git a/app/Models/Traits/SendsEmails.php b/app/Models/Traits/SendsEmails.php index 2e5ecc11e98b..942be0033784 100644 --- a/app/Models/Traits/SendsEmails.php +++ b/app/Models/Traits/SendsEmails.php @@ -125,9 +125,9 @@ trait SendsEmails * * @return bool */ - public function getReminderDate($reminder) + public function getReminderDate($reminder, $filterEnabled = true) { - if (! $this->{"enable_reminder{$reminder}"}) { + if ($filterEnabled && ! $this->{"enable_reminder{$reminder}"}) { return false; } @@ -142,10 +142,10 @@ trait SendsEmails * * @return bool|string */ - public function getInvoiceReminder($invoice) + public function getInvoiceReminder($invoice, $filterEnabled = true) { for ($i = 1; $i <= 3; $i++) { - if ($date = $this->getReminderDate($i)) { + if ($date = $this->getReminderDate($i, $filterEnabled)) { $field = $this->{"field_reminder{$i}"} == REMINDER_FIELD_DUE_DATE ? 'due_date' : 'invoice_date'; if ($invoice->$field == $date) { return "reminder{$i}"; diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index a1d510c8dd81..56c65e535e7c 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -656,6 +656,18 @@ class AccountRepository return Account::whereRaw('enable_reminder1 = 1 OR enable_reminder2 = 1 OR enable_reminder3 = 1')->get(); } + public function findWithFees() + { + return Account::whereHas('account_email_settings', function($query) { + $query->where('late_fee1_amount', '>', 0) + ->orWhere('late_fee1_percent', '>', 0) + ->orWhere('late_fee2_amount', '>', 0) + ->orWhere('late_fee2_percent', '>', 0) + ->orWhere('late_fee3_amount', '>', 0) + ->orWhere('late_fee3_percent', '>', 0); + })->get(); + } + public function createTokens($user, $name) { $name = trim($name) ?: 'TOKEN'; diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 1200261f887e..190e3a0ce9c9 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -1091,19 +1091,24 @@ class InvoiceRepository extends BaseRepository * * @return mixed */ - public function findNeedingReminding(Account $account) + public function findNeedingReminding(Account $account, $filterEnabled = true) { $dates = []; for ($i = 1; $i <= 3; $i++) { - if ($date = $account->getReminderDate($i)) { + if ($date = $account->getReminderDate($i, $filterEnabled)) { $field = $account->{"field_reminder{$i}"} == REMINDER_FIELD_DUE_DATE ? 'due_date' : 'invoice_date'; $dates[] = "$field = '$date'"; } } + if (! count($dates)) { + return []; + } + $sql = implode(' OR ', $dates); $invoices = Invoice::invoiceType(INVOICE_TYPE_STANDARD) + ->with('invoice_items') ->whereAccountId($account->id) ->where('balance', '>', 0) ->where('is_recurring', '=', false) @@ -1132,6 +1137,32 @@ class InvoiceRepository extends BaseRepository } } + public function setLateFee($invoice, $amount, $percent) + { + if ($amount <= 0 && $percent <= 0) { + return false; + } + + $account = $invoice->account; + + $data = $invoice->toArray(); + $fee = $amount; + + if ($invoice->amount > 0) { + $fee += round($invoice->amount * $percent / 100, 2); + } + + $item = []; + $item['product_key'] = trans('texts.fee'); + $item['notes'] = trans('texts.late_fee_added', ['date' => $account->formatDate('now')]); + $item['qty'] = 1; + $item['cost'] = $fee; + $item['invoice_item_type_id'] = INVOICE_ITEM_TYPE_LATE_FEE; + $data['invoice_items'][] = $item; + + $this->save($data, $invoice); + } + public function setGatewayFee($invoice, $gatewayTypeId) { $account = $invoice->account; diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index c483f3eebe83..11ef9b6a3037 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2303,7 +2303,11 @@ $LANG = array( 'ofx_version' => 'OFX Version', 'gateway_help_23' => ':link to get your Stripe API keys.', 'error_app_key_not_set' => 'Error: the APP_KEY value is not set in the .env file.', - 'error_app_key_set_to_default' => 'Error: the APP_KEY value is set to the default in the .env file.' + 'error_app_key_set_to_default' => 'Error: the APP_KEY value is set to the default in the .env file.', + 'charge_late_fee' => 'Charge Late Fee', + 'late_fee_amount' => 'Late Fee Amount', + 'late_fee_percent' => 'Late Fee Percent', + 'late_fee_added' => 'Late fee added on :date', ); diff --git a/resources/views/accounts/template.blade.php b/resources/views/accounts/template.blade.php index 3ea3b8dcca02..b4ccc1fa2360 100644 --- a/resources/views/accounts/template.blade.php +++ b/resources/views/accounts/template.blade.php @@ -3,36 +3,56 @@ @if (isset($isReminder) && $isReminder) {!! Former::populateField('enable_' . $field, intval($account->{'enable_' . $field})) !!} + {!! Former::populateField('late_fee' . $number . '_amount', $account->account_email_settings->{"late_fee{$number}_amount"}) !!} + {!! Former::populateField('late_fee' . $number . '_percent', $account->account_email_settings->{"late_fee{$number}_percent"}) !!} -