Merge pull request #6176 from turbo124/v5-develop

Add late fees to reminders.
This commit is contained in:
David Bomba 2021-07-01 19:53:19 +10:00 committed by GitHub
commit 857964f39a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 124 additions and 11 deletions

View File

@ -208,9 +208,6 @@ class PaymentController extends BaseController
{ {
$payment = $this->payment_repo->save($request->all(), PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id)); $payment = $this->payment_repo->save($request->all(), PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id));
if($request->has('email_receipt') && $request->input('email_receipt') == 'true' && !$payment->client->getSetting('client_manual_payment_notification'))
$payment->service()->sendEmail();
return $this->itemResponse($payment); return $this->itemResponse($payment);
} }

View File

@ -29,6 +29,7 @@ class CheckClientExistence
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
$multiple_contacts = ClientContact::query() $multiple_contacts = ClientContact::query()
->with('company','client')
->where('email', auth('contact')->user()->email) ->where('email', auth('contact')->user()->email)
->whereNotNull('email') ->whereNotNull('email')
->where('email', '<>', '') ->where('email', '<>', '')

View File

@ -37,8 +37,9 @@ class StoreClientGatewayTokenRequest extends Request
public function rules() public function rules()
{ {
//ensure client is present
$rules = [ $rules = [
'client_id' => 'required', 'client_id' => 'required|exists:clients,id,company_id,'.auth()->user()->company()->id,
'company_gateway_id' => 'required', 'company_gateway_id' => 'required',
'gateway_type_id' => 'required|integer', 'gateway_type_id' => 'required|integer',
'meta' => 'required', 'meta' => 'required',

View File

@ -56,7 +56,7 @@ class CompanySizeCheck implements ShouldQueue
{ {
Company::cursor()->each(function ($company) { Company::cursor()->each(function ($company) {
if ($company->invoices()->count() > 1000 || $company->products()->count() > 1000 || $company->clients()->count() > 1000) { if ($company->invoices()->count() > 500 || $company->products()->count() > 500 || $company->clients()->count() > 500) {
nlog("Marking company {$company->id} as large"); nlog("Marking company {$company->id} as large");

View File

@ -29,6 +29,7 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
//@DEPRECATED
class SendReminders implements ShouldQueue class SendReminders implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesDates, MakesReminders; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesDates, MakesReminders;

View File

@ -393,6 +393,10 @@ class Import implements ShouldQueue
foreach ($data['settings'] as $key => $value) { foreach ($data['settings'] as $key => $value) {
if ($key == 'invoice_design_id' || $key == 'quote_design_id' || $key == 'credit_design_id') { if ($key == 'invoice_design_id' || $key == 'quote_design_id' || $key == 'credit_design_id') {
$value = $this->encodePrimaryKey($value); $value = $this->encodePrimaryKey($value);
if(!$value)
$value = $this->encodePrimaryKey(1);
} }
if ($key == 'payment_terms' && $key = '') { if ($key == 'payment_terms' && $key = '') {

View File

@ -11,11 +11,13 @@
namespace App\Jobs\Util; namespace App\Jobs\Util;
use App\DataMapper\InvoiceItem;
use App\Events\Invoice\InvoiceWasEmailed; use App\Events\Invoice\InvoiceWasEmailed;
use App\Jobs\Entity\EmailEntity; use App\Jobs\Entity\EmailEntity;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Invoice; use App\Models\Invoice;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesReminders; use App\Utils\Traits\MakesReminders;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
@ -26,7 +28,7 @@ use Illuminate\Support\Carbon;
class ReminderJob implements ShouldQueue class ReminderJob implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesReminders; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesReminders, MakesDates;
public function __construct() public function __construct()
{ {
@ -65,6 +67,8 @@ class ReminderJob implements ShouldQueue
if ($invoice->isPayable()) { if ($invoice->isPayable()) {
$reminder_template = $invoice->calculateTemplate('invoice'); $reminder_template = $invoice->calculateTemplate('invoice');
$invoice->service()->touchReminder($reminder_template)->save(); $invoice->service()->touchReminder($reminder_template)->save();
$invoice = $this->calcLateFee($invoice, $reminder_template);
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) { $invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template); EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
@ -84,4 +88,89 @@ class ReminderJob implements ShouldQueue
}); });
} }
/**
* Calculates the late if - if any - and rebuilds the invoice
*
* @param Invoice $invoice
* @param string $template
* @return Invoice
*/
private function calcLateFee($invoice, $template) :Invoice
{
$late_fee_amount = 0;
$late_fee_percent = 0;
switch ($template) {
case 'reminder1':
$late_fee_amount = $invoice->client->getSetting('late_fee_amount1');
$late_fee_percent = $invoice->client->getSetting('late_fee_percent1');
break;
case 'reminder2':
$late_fee_amount = $invoice->client->getSetting('late_fee_amount2');
$late_fee_percent = $invoice->client->getSetting('late_fee_percent2');
break;
case 'reminder3':
$late_fee_amount = $invoice->client->getSetting('late_fee_amount3');
$late_fee_percent = $invoice->client->getSetting('late_fee_percent3');
break;
case 'endless_reminder':
$late_fee_amount = $invoice->client->getSetting('late_fee_endless_amount');
$late_fee_percent = $invoice->client->getSetting('late_fee_endless_percent');
break;
default:
$late_fee_amount = 0;
$late_fee_percent = 0;
break;
}
return $this->setLateFee($invoice, $late_fee_amount, $late_fee_percent);
}
/**
* Applies the late fee to the invoice line items
*
* @param Invoice $invoice
* @param float $amount The fee amount
* @param float $percent The fee percentage amount
*
* @return Invoice
*/
private function setLateFee($invoice, $amount, $percent) :Invoice
{
$temp_invoice_balance = $invoice->balance;
if ($amount <= 0 && $percent <= 0) {
return $invoice;
}
$fee = $amount;
if ($invoice->partial > 0) {
$fee += round($invoice->partial * $percent / 100, 2);
} else {
$fee += round($invoice->balance * $percent / 100, 2);
}
$invoice_item = new InvoiceItem;
$invoice_item->type_id = '5';
$invoice_item->product_key = trans('texts.fee');
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]);
$invoice_item->quantity = 1;
$invoice_item->cost = $fee;
$invoice_items = $invoice->line_items;
$invoice_items[] = $invoice_item;
$invoice->line_items = $invoice_items;
/**Refresh Invoice values*/
$invoice = $invoice->calc()->getInvoice();
$invoice->client->service()->updateBalance($this->invoice->balance - $temp_invoice_balance)->save();
$invoice->ledger()->updateInvoiceBalance($this->invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$this->invoice->number}");
return $invoice;
}
} }

View File

@ -35,6 +35,7 @@ class ClientGatewayToken extends BaseModel
'gateway_customer_reference', 'gateway_customer_reference',
'gateway_type_id', 'gateway_type_id',
'meta', 'meta',
'client_id',
]; ];
public function getEntityType() public function getEntityType()

View File

@ -48,6 +48,25 @@ class CompanyRepository extends BaseRepository
private function parseCustomFields($fields) :array private function parseCustomFields($fields) :array
{ {
if(array_key_exists('account1', $fields))
$fields['company1'] = $fields['account1'];
if(array_key_exists('company2', $fields))
$fields['company2'] = $fields['account2'];
if(array_key_exists('invoice1', $fields))
$fields['surcharge1'] = $fields['invoice1'];
if(array_key_exists('invoice2', $fields))
$fields['surcharge2'] = $fields['invoice2'];
if(array_key_exists('invoice_text1', $fields))
$fields['invoice1'] = $fields['invoice_text1'];
if(array_key_exists('invoice_text2', $fields))
$fields['invoice2'] = $fields['invoice_text2'];
foreach ($fields as &$value) { foreach ($fields as &$value) {
$value = (string) $value; $value = (string) $value;
} }

View File

@ -29,9 +29,7 @@ class GroupSettingRepository extends BaseRepository
$group_setting->save(); $group_setting->save();
} }
nlog($data['settings']); if(!array_key_exists('settings', $data) || count((array)$data['settings']) == 0){
if(count((array)$data['settings']) == 0){
$settings = new \stdClass; $settings = new \stdClass;
$settings->entity = Client::class; $settings->entity = Client::class;
$group_setting->settings = $settings; $group_setting->settings = $settings;

View File

@ -157,9 +157,11 @@ class PaymentRepository extends BaseRepository {
if ( ! $is_existing_payment && ! $this->import_mode ) { if ( ! $is_existing_payment && ! $this->import_mode ) {
if ($payment->client->getSetting('client_manual_payment_notification')) if (array_key_exists('email_receipt', $data) && $data['email_receipt'] == true)
$payment->service()->sendEmail(); $payment->service()->sendEmail();
elseif(!array_key_exists('email_receipt', $data) && $payment->client->getSetting('client_manual_payment_notification'))
$payment->service()->sendEmail();
event( new PaymentWasCreated( $payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null) ) ); event( new PaymentWasCreated( $payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null) ) );
} }