Compare commits
10 commits
69b8a85b83
...
96dadaa5d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96dadaa5d4 | ||
|
|
db47163eb3 | ||
|
|
fb36a6052f | ||
|
|
6b22ccd13b | ||
|
|
746d5ce67f | ||
|
|
42bc2ed5b9 | ||
|
|
8eb3433912 | ||
|
|
3c5fe85011 | ||
|
|
02b84688e5 | ||
|
|
baf5912361 |
38 changed files with 200 additions and 185 deletions
|
|
@ -1 +1 @@
|
|||
5.5.70
|
||||
5.5.71
|
||||
|
|
@ -11,18 +11,14 @@
|
|||
|
||||
namespace App\DataMapper\Schedule;
|
||||
|
||||
use App\Models\Client;
|
||||
use stdClass;
|
||||
|
||||
class ClientStatement
|
||||
class EmailStatement
|
||||
{
|
||||
|
||||
/**
|
||||
* Defines the template name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $template = 'client_statement';
|
||||
public string $template = 'email_statement';
|
||||
|
||||
/**
|
||||
* An array of clients hashed_ids
|
||||
|
|
@ -36,13 +32,17 @@ class ClientStatement
|
|||
/**
|
||||
* The consts to be used to define the date_range variable of the statement
|
||||
*/
|
||||
public const THIS_MONTH = 'this_month';
|
||||
public const THIS_QUARTER = 'this_quarter';
|
||||
public const THIS_YEAR = 'this_year';
|
||||
public const PREVIOUS_MONTH = 'previous_month';
|
||||
public const PREVIOUS_QUARTER = 'previous_quarter';
|
||||
public const PREVIOUS_YEAR = 'previous_year';
|
||||
public const CUSTOM_RANGE = "custom_range";
|
||||
public const LAST7 = "last7_days";
|
||||
public const LAST30 = "last30_days";
|
||||
public const LAST365 = "last365_days";
|
||||
public const THIS_MONTH = "this_month";
|
||||
public const LAST_MONTH = "last_month";
|
||||
public const THIS_QUARTER = "this_quarter";
|
||||
public const LAST_QUARTER = "last_quarter";
|
||||
public const THIS_YEAR = "this_year";
|
||||
public const LAST_YEAR = "last_year";
|
||||
public const CUSTOM_RANGE = "custom";
|
||||
|
||||
|
||||
/**
|
||||
* The date range the statement should include
|
||||
|
|
@ -91,6 +91,4 @@ class ClientStatement
|
|||
* @var string
|
||||
*/
|
||||
public string $status = 'paid'; // paid | unpaid
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -76,19 +76,15 @@ class CreateEntityPdf implements ShouldQueue
|
|||
$this->invitation = $invitation;
|
||||
|
||||
if ($invitation instanceof InvoiceInvitation) {
|
||||
// $invitation->load('contact.client.company','invoice.client','invoice.user.account');
|
||||
$this->entity = $invitation->invoice;
|
||||
$this->entity_string = 'invoice';
|
||||
} elseif ($invitation instanceof QuoteInvitation) {
|
||||
// $invitation->load('contact.client.company','quote.client','quote.user.account');
|
||||
$this->entity = $invitation->quote;
|
||||
$this->entity_string = 'quote';
|
||||
} elseif ($invitation instanceof CreditInvitation) {
|
||||
// $invitation->load('contact.client.company','credit.client','credit.user.account');
|
||||
$this->entity = $invitation->credit;
|
||||
$this->entity_string = 'credit';
|
||||
} elseif ($invitation instanceof RecurringInvoiceInvitation) {
|
||||
// $invitation->load('contact.client.company','recurring_invoice');
|
||||
$this->entity = $invitation->recurring_invoice;
|
||||
$this->entity_string = 'recurring_invoice';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,25 +19,16 @@ use Illuminate\Bus\Queueable;
|
|||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientLedgerBalanceUpdate implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $company;
|
||||
|
||||
public $client;
|
||||
|
||||
public $deleteWhenMissingModels = true;
|
||||
|
||||
public function __construct(Company $company, Client $client)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->client = $client;
|
||||
}
|
||||
public function __construct(public Company $company, public Client $client)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
|
|
@ -78,4 +69,11 @@ class ClientLedgerBalanceUpdate implements ShouldQueue
|
|||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
return [(new WithoutOverlapping($this->client->id))->dontRelease()];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ class NinjaMailerJob implements ShouldQueue
|
|||
|
||||
switch ($class) {
|
||||
case Invoice::class:
|
||||
event(new InvoiceWasEmailedAndFailed($this->nmo->invitation, $this->nmo->company, $message, $this->nmo->reminder_template, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
event(new InvoiceWasEmailedAndFailed($this->nmo->invitation, $this->nmo->company, $message, $this->nmo->template, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
break;
|
||||
case Payment::class:
|
||||
event(new PaymentWasEmailedAndFailed($this->nmo->entity, $this->nmo->company, $message, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
|
@ -578,7 +578,7 @@ class NinjaMailerJob implements ShouldQueue
|
|||
* Logs any errors to the SystemLog
|
||||
*
|
||||
* @param string $errors
|
||||
* @param App\Models\User | App\Models\Client $recipient_object
|
||||
* @param App\Models\User | App\Models\Client | null $recipient_object
|
||||
* @return void
|
||||
*/
|
||||
private function logMailError($errors, $recipient_object) :void
|
||||
|
|
|
|||
|
|
@ -56,9 +56,5 @@ class QuoteWorkflowSettings implements ShouldQueue
|
|||
$this->quote->service()->sendEmail($invitation->contact);
|
||||
});
|
||||
}
|
||||
|
||||
// if ($this->client->getSetting('auto_archive_quote')) {
|
||||
// $this->base_repository->archive($this->quote);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ class CreditCreatedNotification implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 10;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
|
@ -65,10 +67,8 @@ class CreditCreatedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
// $first_notification_sent = false;
|
||||
}
|
||||
|
||||
/* Override the methods in the Notification Class */
|
||||
|
|
|
|||
|
|
@ -62,14 +62,10 @@ class CreditEmailedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
// $first_notification_sent = false;
|
||||
}
|
||||
|
||||
// $notification->method = $methods;
|
||||
|
||||
// $user->notify($notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class InvoiceCreatedNotification implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 5;
|
||||
public $delay = 7;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -71,7 +71,7 @@ class InvoiceCreatedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class InvoiceEmailedNotification implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 5;
|
||||
public $delay = 10;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -69,7 +69,7 @@ class InvoiceEmailedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class InvoiceFailedEmailNotification
|
|||
|
||||
use UserNotifies, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $delay = 7;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
|
@ -63,7 +65,7 @@ class InvoiceFailedEmailNotification
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
$first_notification_sent = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,10 +59,5 @@ class InvoicePaidActivity implements ShouldQueue
|
|||
$event->invoice->subscription->service()->planPaid($event->invoice);
|
||||
}
|
||||
|
||||
// try {
|
||||
// $event->invoice->service()->touchPdf();
|
||||
// } catch (\Exception $e) {
|
||||
// nlog(print_r($e->getMessage(), 1));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class InvitationViewedListener implements ShouldQueue
|
|||
unset($methods[$key]);
|
||||
|
||||
$nmo->to_user = $company_user->user;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ class PaymentEmailedActivity implements ShouldQueue
|
|||
public function handle($event)
|
||||
{
|
||||
MultiDB::setDb($event->company->db);
|
||||
|
||||
$payment = $event->payment;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class PaymentNotification implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 5;
|
||||
public $delay = 20;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
|
|
@ -74,7 +74,7 @@ class PaymentNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class PurchaseOrderAcceptedListener implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class PurchaseOrderCreatedListener implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 7;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
|
@ -71,7 +73,7 @@ class PurchaseOrderCreatedListener implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class PurchaseOrderEmailedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class QuoteApprovedNotification implements ShouldQueue
|
|||
{
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 5;
|
||||
public $delay = 8;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -69,7 +69,7 @@ class QuoteApprovedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class QuoteCreatedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
/* This prevents more than one notification being sent */
|
||||
$first_notification_sent = false;
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ class QuoteEmailedNotification implements ShouldQueue
|
|||
foreach ($event->invitation->company->company_users as $company_user) {
|
||||
$user = $company_user->user;
|
||||
|
||||
// $notification = new EntitySentNotification($event->invitation, 'quote');
|
||||
|
||||
$methods = $this->findUserNotificationTypes($event->invitation, $company_user, 'quote', ['all_notifications', 'quote_sent', 'quote_sent_all', 'quote_sent_user']);
|
||||
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
|
|
@ -63,14 +61,10 @@ class QuoteEmailedNotification implements ShouldQueue
|
|||
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
(new NinjaMailerJob($nmo))->handle();
|
||||
|
||||
// $first_notification_sent = false;
|
||||
}
|
||||
|
||||
// $notification->method = $methods;
|
||||
|
||||
// $user->notify($notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,10 +59,6 @@ class AppStoreRenewSubscription implements ShouldQueue
|
|||
|
||||
$account->save();
|
||||
|
||||
// $server_notification = $event->getServerNotification();
|
||||
// $subscription = $event->getSubscription();
|
||||
// $subscription_identifier = $event->getSubscriptionIdentifier();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
49
app/Listeners/Subscription/PlayStoreRenewSubscription.php
Normal file
49
app/Listeners/Subscription/PlayStoreRenewSubscription.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Listeners\Subscription;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Notifications\Ninja\RenewalFailureNotification;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRenewed;
|
||||
|
||||
class PlayStoreRenewSubscription implements ShouldQueue
|
||||
{
|
||||
public function handle(SubscriptionRenewed $event)
|
||||
{
|
||||
$notification = $event->getServerNotification();
|
||||
nlog("google");
|
||||
nlog($notification);
|
||||
$in_app_identifier = $event->getSubscriptionIdentifier();
|
||||
|
||||
MultiDB::findAndSetDbByInappTransactionId($in_app_identifier);
|
||||
|
||||
$expirationTime = $event->getSubscription()->getExpiryTime();
|
||||
|
||||
$account = Account::where('inapp_transaction_id', $in_app_identifier)->first();
|
||||
|
||||
if ($account) {
|
||||
$account->update(['plan_expires' => Carbon::parse($expirationTime)]);
|
||||
}
|
||||
|
||||
if (!$account) {
|
||||
$ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
|
||||
$ninja_company->notification(new RenewalFailureNotification("{$in_app_identifier}"))->ninja();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ use App\Utils\Ninja;
|
|||
use App\Utils\Number;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use stdClass;
|
||||
use App\Models\Payment;
|
||||
|
||||
class EntityPaidObject
|
||||
{
|
||||
|
|
@ -29,7 +30,7 @@ class EntityPaidObject
|
|||
|
||||
public $settings;
|
||||
|
||||
public function __construct($payment)
|
||||
public function __construct(public Payment $payment)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
$this->company = $payment->company;
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||
$invoice_list = '<br><br>';
|
||||
|
||||
foreach ($this->payment->invoices as $invoice) {
|
||||
$invoice_list .= ctrans('texts.invoice_number_short')." {$invoice->number} - ".Number::formatMoney($invoice->pivot->amount, $this->client).'<br>';
|
||||
$invoice_list .= ctrans('texts.invoice_number_short')." {$invoice->number} ".Number::formatMoney($invoice->pivot->amount, $this->client).'<br>';
|
||||
}
|
||||
|
||||
return $invoice_list;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ class CompanyGateway extends BaseModel
|
|||
// const TYPE_WEPAY = 309;
|
||||
// const TYPE_PAYFAST = 310;
|
||||
// const TYPE_PAYTRACE = 311;
|
||||
// const TYPE_MOLLIE = 312;
|
||||
// const TYPE_EWAY = 313;
|
||||
// const TYPE_FORTE = 314;
|
||||
|
||||
public $gateway_consts = [
|
||||
|
|
@ -91,6 +93,8 @@ class CompanyGateway extends BaseModel
|
|||
'8fdeed552015b3c7b44ed6c8ebd9e992' => 309,
|
||||
'd6814fc83f45d2935e7777071e629ef9' => 310,
|
||||
'bbd736b3254b0aabed6ad7fda1298c88' => 311,
|
||||
'1bd651fb213ca0c9d66ae3c336dc77e7' => 312,
|
||||
'944c20175bbe6b9972c05bcfe294c2c7' => 313,
|
||||
'kivcvjexxvdiyqtj3mju5d6yhpeht2xs' => 314,
|
||||
'65faab2ab6e3223dbe848b1686490baz' => 320,
|
||||
'b9886f9257f0c6ee7c302f1c74475f6c' => 321,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Credit\CreditWasUpdated;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\Inviteable;
|
||||
|
|
@ -44,38 +43,6 @@ class CreditInvitation extends BaseModel
|
|||
return self::class;
|
||||
}
|
||||
|
||||
// public function getSignatureDateAttribute($value)
|
||||
// {
|
||||
// if (!$value) {
|
||||
// return (new Carbon($value))->format('Y-m-d');
|
||||
// }
|
||||
// return $value;
|
||||
// }
|
||||
|
||||
// public function getSentDateAttribute($value)
|
||||
// {
|
||||
// if (!$value) {
|
||||
// return (new Carbon($value))->format('Y-m-d');
|
||||
// }
|
||||
// return $value;
|
||||
// }
|
||||
|
||||
// public function getViewedDateAttribute($value)
|
||||
// {
|
||||
// if (!$value) {
|
||||
// return (new Carbon($value))->format('Y-m-d');
|
||||
// }
|
||||
// return $value;
|
||||
// }
|
||||
|
||||
// public function getOpenedDateAttribute($value)
|
||||
// {
|
||||
// if (!$value) {
|
||||
// return (new Carbon($value))->format('Y-m-d');
|
||||
// }
|
||||
// return $value;
|
||||
// }
|
||||
|
||||
public function entityType()
|
||||
{
|
||||
return Credit::class;
|
||||
|
|
@ -129,7 +96,6 @@ class CreditInvitation extends BaseModel
|
|||
$storage_path = Storage::url($this->credit->client->quote_filepath($this).$this->credit->numberFormatter().'.pdf');
|
||||
|
||||
if (! Storage::exists($this->credit->client->credit_filepath($this).$this->credit->numberFormatter().'.pdf')) {
|
||||
event(new CreditWasUpdated($this->credit, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
(new CreateEntityPdf($this))->handle();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ class QuoteInvitation extends BaseModel
|
|||
$storage_path = Storage::url($this->quote->client->quote_filepath($this).$this->quote->numberFormatter().'.pdf');
|
||||
|
||||
if (! Storage::exists($this->quote->client->quote_filepath($this).$this->quote->numberFormatter().'.pdf')) {
|
||||
event(new QuoteWasUpdated($this->quote, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
(new CreateEntityPdf($this))->handle();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ class RenewalFailureNotification extends Notification
|
|||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct(protected string $notification_message){}
|
||||
public function __construct(protected ?string $notification_message)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
|
|
|
|||
|
|
@ -409,12 +409,10 @@ class EventServiceProvider extends ServiceProvider
|
|||
],
|
||||
InvoiceWasUpdated::class => [
|
||||
UpdateInvoiceActivity::class,
|
||||
CreateInvoicePdf::class,
|
||||
],
|
||||
InvoiceWasCreated::class => [
|
||||
CreateInvoiceActivity::class,
|
||||
InvoiceCreatedNotification::class,
|
||||
// CreateInvoicePdf::class,
|
||||
],
|
||||
InvoiceWasPaid::class => [
|
||||
InvoicePaidActivity::class,
|
||||
|
|
@ -453,7 +451,7 @@ class EventServiceProvider extends ServiceProvider
|
|||
InvitationViewedListener::class,
|
||||
],
|
||||
PaymentWasEmailed::class => [
|
||||
PaymentEmailedActivity::class,
|
||||
// PaymentEmailedActivity::class,
|
||||
],
|
||||
PaymentWasEmailedAndFailed::class => [
|
||||
// PaymentEmailFailureActivity::class,
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ use Illuminate\Support\Facades\Cache;
|
|||
class BankMatchingService implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public $company_id, public $db){}
|
||||
public function __construct(public $company_id, public $db)
|
||||
{
|
||||
}
|
||||
|
||||
public function handle() :void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ class ApplyPayment
|
|||
->updateBalance($this->amount_applied * -1)
|
||||
->updatePaidToDate($this->amount_applied)
|
||||
->updateStatus()
|
||||
->touchPdf()
|
||||
->save();
|
||||
|
||||
$this->credit
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
namespace App\Services\Email;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Models\Client;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Company;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\VendorContact;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
|
||||
|
|
@ -81,4 +81,5 @@ class EmailObject
|
|||
|
||||
public array $variables = [];
|
||||
|
||||
public ?Company $company = null;
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ use App\Models\Scheduler;
|
|||
use App\Utils\Traits\MakesDates;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Carbon\Carbon;
|
||||
use App\DataMapper\Schedule\EmailStatement;
|
||||
|
||||
class SchedulerService
|
||||
{
|
||||
|
|
@ -39,7 +40,7 @@ class SchedulerService
|
|||
$this->{$this->scheduler->template}();
|
||||
}
|
||||
|
||||
private function client_statement()
|
||||
private function email_statement()
|
||||
{
|
||||
$query = Client::query()
|
||||
->where('company_id', $this->scheduler->company_id)
|
||||
|
|
@ -93,13 +94,16 @@ class SchedulerService
|
|||
private function calculateStartAndEndDates(): array
|
||||
{
|
||||
return match ($this->scheduler->parameters['date_range']) {
|
||||
'this_month' => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')],
|
||||
'this_quarter' => [now()->startOfDay()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->lastOfQuarter()->format('Y-m-d')],
|
||||
'this_year' => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')],
|
||||
'previous_month' => [now()->startOfDay()->subMonthNoOverflow()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->subMonthNoOverflow()->lastOfMonth()->format('Y-m-d')],
|
||||
'previous_quarter' => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')],
|
||||
'previous_year' => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')],
|
||||
'custom_range' => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']],
|
||||
EmailStatement::LAST7 => [now()->startOfDay()->subDays(7)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::LAST30 => [now()->startOfDay()->subDays(30)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::LAST365 => [now()->startOfDay()->subDays(365)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::THIS_MONTH => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')],
|
||||
EmailStatement::LAST_MONTH => [now()->startOfDay()->subMonthNoOverflow()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->subMonthNoOverflow()->lastOfMonth()->format('Y-m-d')],
|
||||
EmailStatement::THIS_QUARTER => [now()->startOfDay()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->lastOfQuarter()->format('Y-m-d')],
|
||||
EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')],
|
||||
EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')],
|
||||
EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')],
|
||||
EmailStatement::CUSTOM_RANGE => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']],
|
||||
default => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')],
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ class Number
|
|||
|
||||
$value = floatval($value);
|
||||
|
||||
$_value = $value;
|
||||
|
||||
$currency = $entity->currency();
|
||||
|
||||
$thousand = $currency->thousand_separator;
|
||||
|
|
@ -179,6 +181,15 @@ class Number
|
|||
} elseif ($swapSymbol) {
|
||||
return "{$value} ".trim($symbol);
|
||||
} elseif ($entity->getSetting('show_currency_code') === false) {
|
||||
|
||||
/* Ensures we place the negative symbol ahead of the currency symbol*/
|
||||
if($_value < 0){
|
||||
|
||||
$value = substr($value, 1);
|
||||
$symbol = "-{$symbol}";
|
||||
|
||||
}
|
||||
|
||||
return "{$symbol}{$value}";
|
||||
} else {
|
||||
return self::formatValue($value, $currency);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ return [
|
|||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.5.70',
|
||||
'app_tag' => '5.5.70',
|
||||
'app_version' => '5.5.71',
|
||||
'app_tag' => '5.5.71',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
|
|
|||
|
|
@ -1,30 +1,31 @@
|
|||
<?php
|
||||
|
||||
use App\Listeners\Subscription\AppStoreRenewSubscription;
|
||||
use Imdhemy\Purchases\Events\AppStore\Cancel;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidChangeRenewalPref;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidChangeRenewalStatus;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidFailToRenew;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRecover;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRenew;
|
||||
use Imdhemy\Purchases\Events\AppStore\InitialBuy;
|
||||
use Imdhemy\Purchases\Events\AppStore\InteractiveRenewal;
|
||||
use Imdhemy\Purchases\Events\AppStore\PriceIncreaseConsent;
|
||||
use Imdhemy\Purchases\Events\AppStore\Refund;
|
||||
use Imdhemy\Purchases\Events\AppStore\Revoke;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRenew;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRecover;
|
||||
use Imdhemy\Purchases\Events\AppStore\InitialBuy;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidFailToRenew;
|
||||
use App\Listeners\Subscription\AppStoreRenewSubscription;
|
||||
use Imdhemy\Purchases\Events\AppStore\InteractiveRenewal;
|
||||
use App\Listeners\Subscription\PlayStoreRenewSubscription;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidChangeRenewalPref;
|
||||
use Imdhemy\Purchases\Events\AppStore\PriceIncreaseConsent;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionOnHold;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPaused;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionExpired;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRenewed;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRevoked;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidChangeRenewalStatus;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionCanceled;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionDeferred;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionExpired;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionInGracePeriod;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionOnHold;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPauseScheduleChanged;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPaused;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPriceChangeConfirmed;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPurchased;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRecovered;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRenewed;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRestarted;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRevoked;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionInGracePeriod;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPauseScheduleChanged;
|
||||
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionPriceChangeConfirmed;
|
||||
|
||||
return [
|
||||
'routing' => [],
|
||||
|
|
@ -40,7 +41,7 @@ return [
|
|||
* --------------------------------------------------------
|
||||
*/
|
||||
SubscriptionPurchased::class => [],
|
||||
SubscriptionRenewed::class => [],
|
||||
SubscriptionRenewed::class => [PlayStoreRenewSubscription::class],
|
||||
SubscriptionInGracePeriod::class => [],
|
||||
SubscriptionExpired::class => [],
|
||||
SubscriptionCanceled::class => [],
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@ use App\Factory\SchedulerFactory;
|
|||
use App\Models\Client;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\Scheduler;
|
||||
use App\Services\Scheduler\SchedulerService;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\DataMapper\Schedule\EmailStatement;
|
||||
use App\Services\Scheduler\SchedulerService;
|
||||
use Illuminate\Foundation\Testing\WithoutEvents;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
|
@ -77,7 +78,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -143,7 +144,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -176,7 +177,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->addDay()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -200,7 +201,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -232,7 +233,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -268,7 +269,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => "2023-01-01",
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -287,7 +288,7 @@ class SchedulerTest extends TestCase
|
|||
|
||||
$this->assertIsArray($method);
|
||||
|
||||
$this->assertEquals('previous_month', $scheduler->parameters['date_range']);
|
||||
$this->assertEquals(EmailStatement::LAST_MONTH, $scheduler->parameters['date_range']);
|
||||
|
||||
$this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $method);
|
||||
|
||||
|
|
@ -304,7 +305,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
@ -337,13 +338,13 @@ class SchedulerTest extends TestCase
|
|||
|
||||
$this->travelTo(Carbon::parse('2023-01-14'));
|
||||
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-01-31'], $this->getDateRange('this_month'));
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-03-31'], $this->getDateRange('this_quarter'));
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-12-31'], $this->getDateRange('this_year'));
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-01-31'], $this->getDateRange(EmailStatement::THIS_MONTH));
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-03-31'], $this->getDateRange(EmailStatement::THIS_QUARTER));
|
||||
$this->assertEqualsCanonicalizing(['2023-01-01','2023-12-31'], $this->getDateRange(EmailStatement::THIS_YEAR));
|
||||
|
||||
$this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $this->getDateRange('previous_month'));
|
||||
$this->assertEqualsCanonicalizing(['2022-10-01','2022-12-31'], $this->getDateRange('previous_quarter'));
|
||||
$this->assertEqualsCanonicalizing(['2022-01-01','2022-12-31'], $this->getDateRange('previous_year'));
|
||||
$this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $this->getDateRange(EmailStatement::LAST_MONTH));
|
||||
$this->assertEqualsCanonicalizing(['2022-10-01','2022-12-31'], $this->getDateRange(EmailStatement::LAST_QUARTER));
|
||||
$this->assertEqualsCanonicalizing(['2022-01-01','2022-12-31'], $this->getDateRange(EmailStatement::LAST_YEAR));
|
||||
|
||||
$this->travelBack();
|
||||
|
||||
|
|
@ -352,13 +353,17 @@ class SchedulerTest extends TestCase
|
|||
private function getDateRange($range)
|
||||
{
|
||||
return match ($range) {
|
||||
'this_month' => [now()->firstOfMonth()->format('Y-m-d'), now()->lastOfMonth()->format('Y-m-d')],
|
||||
'this_quarter' => [now()->firstOfQuarter()->format('Y-m-d'), now()->lastOfQuarter()->format('Y-m-d')],
|
||||
'this_year' => [now()->firstOfYear()->format('Y-m-d'), now()->lastOfYear()->format('Y-m-d')],
|
||||
'previous_month' => [now()->subMonth()->firstOfMonth()->format('Y-m-d'), now()->subMonth()->lastOfMonth()->format('Y-m-d')],
|
||||
'previous_quarter' => [now()->subQuarter()->firstOfQuarter()->format('Y-m-d'), now()->subQuarter()->lastOfQuarter()->format('Y-m-d')],
|
||||
'previous_year' => [now()->subYear()->firstOfYear()->format('Y-m-d'), now()->subYear()->lastOfYear()->format('Y-m-d')],
|
||||
'custom_range' => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']]
|
||||
EmailStatement::LAST7 => [now()->startOfDay()->subDays(7)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::LAST30 => [now()->startOfDay()->subDays(30)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::LAST365 => [now()->startOfDay()->subDays(365)->format('Y-m-d'), now()->startOfDay()->format('Y-m-d')],
|
||||
EmailStatement::THIS_MONTH => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')],
|
||||
EmailStatement::LAST_MONTH => [now()->startOfDay()->subMonthNoOverflow()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->subMonthNoOverflow()->lastOfMonth()->format('Y-m-d')],
|
||||
EmailStatement::THIS_QUARTER => [now()->startOfDay()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->lastOfQuarter()->format('Y-m-d')],
|
||||
EmailStatement::LAST_QUARTER => [now()->startOfDay()->subQuarterNoOverflow()->firstOfQuarter()->format('Y-m-d'), now()->startOfDay()->subQuarterNoOverflow()->lastOfQuarter()->format('Y-m-d')],
|
||||
EmailStatement::THIS_YEAR => [now()->startOfDay()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->lastOfYear()->format('Y-m-d')],
|
||||
EmailStatement::LAST_YEAR => [now()->startOfDay()->subYearNoOverflow()->firstOfYear()->format('Y-m-d'), now()->startOfDay()->subYearNoOverflow()->lastOfYear()->format('Y-m-d')],
|
||||
EmailStatement::CUSTOM_RANGE => [$this->scheduler->parameters['start_date'], $this->scheduler->parameters['end_date']],
|
||||
default => [now()->startOfDay()->firstOfMonth()->format('Y-m-d'), now()->startOfDay()->lastOfMonth()->format('Y-m-d')],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +375,7 @@ class SchedulerTest extends TestCase
|
|||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'client_statement',
|
||||
'parameters' => [
|
||||
'date_range' => 'previous_month',
|
||||
'date_range' => EmailStatement::LAST_MONTH,
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'paid',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue