Merge branch 'master' of github.com:akaunting/akaunting
This commit is contained in:
commit
7ec0746de6
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@ -5,6 +5,7 @@ on:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
|
15
app/Events/Email/TooManyEmailsSent.php
Normal file
15
app/Events/Email/TooManyEmailsSent.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events\Email;
|
||||
|
||||
use App\Abstracts\Event;
|
||||
|
||||
class TooManyEmailsSent extends Event
|
||||
{
|
||||
public $user_id;
|
||||
|
||||
public function __construct(int $user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Abstracts\Http\SettingController;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Models\Setting\Tax;
|
||||
|
||||
@ -10,6 +11,8 @@ class Defaults extends SettingController
|
||||
{
|
||||
public function edit()
|
||||
{
|
||||
$accounts = Account::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$sales_categories = Category::income()->enabled()->orderBy('name')->take(setting('default.select_limit'))->get();
|
||||
|
||||
$sale_category_id = setting('default.income_category');
|
||||
@ -37,6 +40,7 @@ class Defaults extends SettingController
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
return view('settings.default.edit', compact(
|
||||
'accounts',
|
||||
'sales_categories',
|
||||
'purchases_categories',
|
||||
'taxes',
|
||||
|
@ -32,7 +32,7 @@ class Tax extends FormRequest
|
||||
|
||||
return [
|
||||
'name' => 'required|string',
|
||||
'rate' => 'required|min:0|max:100',
|
||||
'rate' => 'required|numeric|min:0|max:100',
|
||||
'type' => $type,
|
||||
'enabled' => $enabled,
|
||||
];
|
||||
|
@ -4,12 +4,15 @@ namespace App\Jobs\Banking;
|
||||
|
||||
use App\Abstracts\Job;
|
||||
use App\Events\Banking\TransactionSent;
|
||||
use App\Http\Requests\Common\CustomMail as Request;
|
||||
use App\Models\Banking\Transaction;
|
||||
use App\Notifications\Banking\Transaction as Notification;
|
||||
|
||||
class SendTransactionAsCustomMail extends Job
|
||||
{
|
||||
public function __construct($request, $template_alias)
|
||||
public string $template_alias;
|
||||
|
||||
public function __construct(Request $request, string $template_alias)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->template_alias = $template_alias;
|
||||
|
@ -5,11 +5,14 @@ namespace App\Jobs\Document;
|
||||
use App\Abstracts\Job;
|
||||
use App\Events\Document\DocumentSending;
|
||||
use App\Events\Document\DocumentSent;
|
||||
use App\Http\Requests\Common\CustomMail as Request;
|
||||
use App\Models\Document\Document;
|
||||
|
||||
class SendDocumentAsCustomMail extends Job
|
||||
{
|
||||
public function __construct($request, $template_alias)
|
||||
public string $template_alias;
|
||||
|
||||
public function __construct(Request $request, string $template_alias)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->template_alias = $template_alias;
|
||||
|
@ -31,6 +31,13 @@ class DeleteCategory extends Job implements ShouldDelete
|
||||
*/
|
||||
public function authorize(): void
|
||||
{
|
||||
// Can not delete transfer category
|
||||
if ($this->model->isTransferCategory()) {
|
||||
$message = trans('messages.error.transfer_category', ['type' => $this->model->name]);
|
||||
|
||||
throw new \Exception($message);
|
||||
}
|
||||
|
||||
// Can not delete the last category by type
|
||||
if (Category::where('type', $this->model->type)->count() == 1) {
|
||||
$message = trans('messages.error.last_category', ['type' => strtolower(trans_choice('general.' . $this->model->type . 's', 1))]);
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Listeners\Document;
|
||||
|
||||
use App\Events\Document\DocumentRecurring as Event;
|
||||
use App\Events\Document\DocumentSent;
|
||||
use App\Traits\Documents;
|
||||
|
||||
class SendDocumentRecurringNotification
|
||||
@ -35,6 +36,8 @@ class SendDocumentRecurringNotification
|
||||
$document->contact->notify(new $notification($document, "{$document->type}_recur_customer"));
|
||||
}
|
||||
|
||||
event(new DocumentSent($document));
|
||||
|
||||
// Check if should notify users
|
||||
if (! $config['notify_user']) {
|
||||
return;
|
||||
|
14
app/Listeners/Email/ReportTooManyEmailsSent.php
Normal file
14
app/Listeners/Email/ReportTooManyEmailsSent.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners\Email;
|
||||
|
||||
use App\Exceptions\Common\TooManyEmailsSent;
|
||||
use App\Events\Email\TooManyEmailsSent as Event;
|
||||
|
||||
class ReportTooManyEmailsSent
|
||||
{
|
||||
public function handle(Event $event): void
|
||||
{
|
||||
report(new TooManyEmailsSent('Too many emails sent!'));
|
||||
}
|
||||
}
|
72
app/Listeners/Email/TellFirewallTooManyEmailsSent.php
Normal file
72
app/Listeners/Email/TellFirewallTooManyEmailsSent.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners\Email;
|
||||
|
||||
use Akaunting\Firewall\Events\AttackDetected;
|
||||
use Akaunting\Firewall\Traits\Helper;
|
||||
use App\Events\Email\TooManyEmailsSent as Event;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
class TellFirewallTooManyEmailsSent
|
||||
{
|
||||
use Helper;
|
||||
|
||||
public function handle(Event $event): void
|
||||
{
|
||||
$this->request = request();
|
||||
$this->middleware = 'too_many_emails_sent';
|
||||
$this->user_id = $event->user_id;
|
||||
|
||||
$this->loadConfig();
|
||||
|
||||
if ($this->skip($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$log = $this->log();
|
||||
|
||||
event(new AttackDetected($log));
|
||||
}
|
||||
|
||||
public function loadConfig(): void
|
||||
{
|
||||
$config = array_merge_recursive(
|
||||
Config::get('firewall'),
|
||||
[
|
||||
'middleware' => [
|
||||
$this->middleware => [
|
||||
'enabled' => env('FIREWALL_MIDDLEWARE_' . strtoupper($this->middleware) . '_ENABLED', env('FIREWALL_ENABLED', true)),
|
||||
|
||||
'methods' => ['post'],
|
||||
|
||||
'routes' => [
|
||||
'only' => [], // i.e. 'contact'
|
||||
'except' => [], // i.e. 'admin/*'
|
||||
],
|
||||
|
||||
'auto_block' => [
|
||||
'attempts' => env('FIREWALL_MIDDLEWARE_' . strtoupper($this->middleware) . '_AUTO_BLOCK_ATTEMPTS', 20),
|
||||
'frequency' => 1 * 60, // 1 minute
|
||||
'period' => 30 * 60, // 30 minutes
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
Config::set('firewall', $config);
|
||||
}
|
||||
|
||||
public function skip($event): bool
|
||||
{
|
||||
if ($this->isDisabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->isWhitelist()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -111,12 +111,18 @@ class Transaction extends Notification
|
||||
|
||||
public function getTagsReplacement(): array
|
||||
{
|
||||
$route_params = [
|
||||
'company_id' => $this->transaction->company_id,
|
||||
'transaction' => $this->transaction->id,
|
||||
'payment' => $this->transaction->id,
|
||||
];
|
||||
|
||||
return [
|
||||
money($this->transaction->amount, $this->transaction->currency_code, true),
|
||||
company_date($this->transaction->paid_at),
|
||||
URL::signedRoute('signed.payments.show', [$this->transaction->id]),
|
||||
route('transactions.show', $this->transaction->id),
|
||||
route('portal.payments.show', $this->transaction->id),
|
||||
URL::signedRoute('signed.payments.show', $route_params),
|
||||
route('transactions.show', $route_params),
|
||||
route('portal.payments.show', $route_params),
|
||||
$this->transaction->contact->name,
|
||||
$this->transaction->company->name,
|
||||
$this->transaction->company->email,
|
||||
|
@ -122,14 +122,19 @@ class PaymentReceived extends Notification
|
||||
|
||||
public function getTagsReplacement(): array
|
||||
{
|
||||
$route_params = [
|
||||
'company_id' => $this->invoice->company_id,
|
||||
'invoice' => $this->invoice->id,
|
||||
];
|
||||
|
||||
return [
|
||||
$this->invoice->document_number,
|
||||
money($this->invoice->amount, $this->invoice->currency_code, true),
|
||||
company_date($this->invoice->due_at),
|
||||
trans('documents.statuses.' . $this->invoice->status),
|
||||
URL::signedRoute('signed.invoices.show', [$this->invoice->id]),
|
||||
route('invoices.show', $this->invoice->id),
|
||||
route('portal.invoices.show', $this->invoice->id),
|
||||
URL::signedRoute('signed.invoices.show', $route_params),
|
||||
route('invoices.show', $route_params),
|
||||
route('portal.invoices.show', $route_params),
|
||||
money($this->transaction->amount, $this->transaction->currency_code, true),
|
||||
company_date($this->transaction->paid_at),
|
||||
$this->transaction->payment_method,
|
||||
|
@ -90,13 +90,18 @@ class Bill extends Notification
|
||||
|
||||
public function getTagsReplacement(): array
|
||||
{
|
||||
$route_params = [
|
||||
'company_id' => $this->bill->company_id,
|
||||
'bill' => $this->bill->id,
|
||||
];
|
||||
|
||||
return [
|
||||
$this->bill->document_number,
|
||||
money($this->bill->amount, $this->bill->currency_code, true),
|
||||
money($this->bill->amount_due, $this->bill->currency_code, true),
|
||||
company_date($this->bill->issued_at),
|
||||
company_date($this->bill->due_at),
|
||||
route('bills.show', $this->bill->id),
|
||||
route('bills.show', $route_params),
|
||||
$this->bill->contact_name,
|
||||
$this->bill->company->name,
|
||||
$this->bill->company->email,
|
||||
|
@ -116,15 +116,20 @@ class Invoice extends Notification
|
||||
|
||||
public function getTagsReplacement(): array
|
||||
{
|
||||
$route_params = [
|
||||
'company_id' => $this->invoice->company_id,
|
||||
'invoice' => $this->invoice->id,
|
||||
];
|
||||
|
||||
return [
|
||||
$this->invoice->document_number,
|
||||
money($this->invoice->amount, $this->invoice->currency_code, true),
|
||||
money($this->invoice->amount_due, $this->invoice->currency_code, true),
|
||||
company_date($this->invoice->issued_at),
|
||||
company_date($this->invoice->due_at),
|
||||
URL::signedRoute('signed.invoices.show', [$this->invoice->id]),
|
||||
route('invoices.show', $this->invoice->id),
|
||||
route('portal.invoices.show', $this->invoice->id),
|
||||
URL::signedRoute('signed.invoices.show', $route_params),
|
||||
route('invoices.show', $route_params),
|
||||
route('portal.invoices.show', $route_params),
|
||||
$this->invoice->contact_name,
|
||||
$this->invoice->company->name,
|
||||
$this->invoice->company->email,
|
||||
|
@ -104,6 +104,10 @@ class Event extends Provider
|
||||
'App\Events\Setting\CategoryDeleted' => [
|
||||
'App\Listeners\Setting\DeleteCategoryDeletedSubCategories',
|
||||
],
|
||||
'App\Events\Email\TooManyEmailsSent' => [
|
||||
'App\Listeners\Email\ReportTooManyEmailsSent',
|
||||
'App\Listeners\Email\TellFirewallTooManyEmailsSent',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Abstracts\Job;
|
||||
use App\Exceptions\Common\TooManyEmailsSent;
|
||||
use App\Events\Email\TooManyEmailsSent;
|
||||
use App\Traits\Jobs;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
|
||||
@ -14,42 +14,38 @@ trait Emails
|
||||
public function sendEmail(Job $job): array
|
||||
{
|
||||
// Check if the user has reached the limit of emails per month
|
||||
$key_per_month = 'email-month:' . user()->id;
|
||||
$key_per_month = 'email-month:' . user_id();
|
||||
$limit_per_month = config('app.throttles.email.month');
|
||||
$decay_per_month = 60 * 60 * 24 * 30;
|
||||
|
||||
$can_send = RateLimiter::attempt($key_per_month, $limit_per_month, fn() => '', $decay_per_month);
|
||||
$can_send = RateLimiter::attempt($key_per_month, $limit_per_month, fn() => null, $decay_per_month);
|
||||
|
||||
if ($can_send) {
|
||||
// Check if the user has reached the limit of emails per minute
|
||||
$key_per_minute = 'email-minute:' . user()->id;
|
||||
$key_per_minute = 'email-minute:' . user_id();
|
||||
$limit_per_minute = config('app.throttles.email.minute');
|
||||
|
||||
$can_send = RateLimiter::attempt($key_per_minute, $limit_per_minute, fn() => '');
|
||||
$can_send = RateLimiter::attempt($key_per_minute, $limit_per_minute, fn() => null);
|
||||
}
|
||||
|
||||
if ($can_send) {
|
||||
$this->dispatch($job);
|
||||
|
||||
$response = [
|
||||
return [
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'data' => '',
|
||||
'message' => '',
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response = [
|
||||
event(new TooManyEmailsSent(user_id()));
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'data' => null,
|
||||
'message' => 'Too many emails sent!',
|
||||
];
|
||||
|
||||
report(new TooManyEmailsSent('Too many emails sent!'));
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
@ -22,11 +22,12 @@ use App\Models\Setting\Category;
|
||||
use App\Models\Setting\Currency;
|
||||
use App\Models\Setting\Tax;
|
||||
use App\Traits\Jobs;
|
||||
use App\Traits\Sources;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
trait Import
|
||||
{
|
||||
use Jobs;
|
||||
use Jobs, Sources;
|
||||
|
||||
public function getAccountId($row)
|
||||
{
|
||||
@ -98,8 +99,8 @@ trait Import
|
||||
'symbol' => isset($row['currency_symbol']) ? $row['currency_symbol'] : config('money.' . $row['currency_code'] . '.symbol'),
|
||||
'precision' => isset($row['currency_precision']) ? $row['currency_precision'] : config('money.' . $row['currency_code'] . '.precision'),
|
||||
'decimal_mark' => isset($row['currency_decimal_mark']) ? $row['currency_decimal_mark'] : config('money.' . $row['currency_code'] . '.decimal_mark'),
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new CurrencyRequest)->rules());
|
||||
@ -178,8 +179,8 @@ trait Import
|
||||
'number' => !empty($row['account_number']) ? $row['account_number'] : (string) rand(1, 10000),
|
||||
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new AccountRequest)->rules());
|
||||
@ -205,8 +206,8 @@ trait Import
|
||||
'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : default_currency(),
|
||||
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new AccountRequest)->rules());
|
||||
@ -232,8 +233,8 @@ trait Import
|
||||
'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : default_currency(),
|
||||
'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0,
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new AccountRequest)->rules());
|
||||
@ -257,8 +258,8 @@ trait Import
|
||||
'type' => $type,
|
||||
'color' => !empty($row['category_color']) ? $row['category_color'] : '#' . dechex(rand(0x000000, 0xFFFFFF)),
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new CategoryRequest)->rules());
|
||||
@ -283,8 +284,8 @@ trait Import
|
||||
'name' => !empty($row['contact_name']) ? $row['contact_name'] : $row['contact_email'],
|
||||
'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : default_currency(),
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new ContactRequest)->rules());
|
||||
@ -309,8 +310,8 @@ trait Import
|
||||
'email' => !empty($row['contact_email']) ? $row['contact_email'] : null,
|
||||
'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : default_currency(),
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new ContactRequest)->rules());
|
||||
@ -330,14 +331,14 @@ trait Import
|
||||
|
||||
$data = [
|
||||
'company_id' => company_id(),
|
||||
'type' => $row['item_type'],
|
||||
'type' => !empty($row['item_type']) ? $row['item_type'] : (!empty($row['type']) ? $row['type'] : 'product'),
|
||||
'name' => $row['item_name'],
|
||||
'description' => !empty($row['item_description']) ? $row['item_description'] : null,
|
||||
'sale_price' => !empty($row['sale_price']) ? $row['sale_price'] : (!empty($row['price']) ? $row['price'] : 0),
|
||||
'purchase_price' => !empty($row['purchase_price']) ? $row['purchase_price'] : (!empty($row['price']) ? $row['price'] : 0),
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new ItemRequest())->rules());
|
||||
@ -361,8 +362,8 @@ trait Import
|
||||
'type' => $type,
|
||||
'name' => !empty($row['tax_name']) ? $row['tax_name'] : (string) $row['tax_rate'],
|
||||
'enabled' => 1,
|
||||
'created_from' => $row['created_from'],
|
||||
'created_by' => $row['created_by'],
|
||||
'created_from' => !empty($row['created_from']) ? $row['created_from'] : $this->getSourcePrefix() . 'import',
|
||||
'created_by' => !empty($row['created_by']) ? $row['created_by'] : user()->id,
|
||||
];
|
||||
|
||||
Validator::validate($data, (new TaxRequest())->rules());
|
||||
|
@ -23,6 +23,7 @@ trait Recurring
|
||||
$limit_by = !empty($request['recurring_limit']) ? $request['recurring_limit'] : 'count';
|
||||
$limit_count = isset($request['recurring_limit_count']) ? (int) $request['recurring_limit_count'] : 0;
|
||||
$limit_date = !empty($request['recurring_limit_date']) ? $request['recurring_limit_date'] : null;
|
||||
$auto_send = !empty($request['recurring_send_email']) ? $request['recurring_send_email'] : 0;
|
||||
$source = !empty($request['created_from']) ? $request['created_from'] : source_name();
|
||||
$owner = !empty($request['created_by']) ? $request['created_by'] : user_id();
|
||||
|
||||
@ -35,6 +36,7 @@ trait Recurring
|
||||
'limit_by' => $limit_by,
|
||||
'limit_count' => $limit_count,
|
||||
'limit_date' => $limit_date,
|
||||
'auto_send' => $auto_send,
|
||||
'created_from' => $source,
|
||||
'created_by' => $owner,
|
||||
]);
|
||||
@ -54,6 +56,7 @@ trait Recurring
|
||||
$limit_by = !empty($request['recurring_limit']) ? $request['recurring_limit'] : 'count';
|
||||
$limit_count = isset($request['recurring_limit_count']) ? (int) $request['recurring_limit_count'] : 0;
|
||||
$limit_date = !empty($request['recurring_limit_date']) ? $request['recurring_limit_date'] : null;
|
||||
$auto_send = !empty($request['recurring_send_email']) ? $request['recurring_send_email'] : 0;
|
||||
|
||||
$recurring = $this->recurring();
|
||||
$model_exists = $recurring->count();
|
||||
@ -66,6 +69,7 @@ trait Recurring
|
||||
'limit_by' => $limit_by,
|
||||
'limit_count' => $limit_count,
|
||||
'limit_date' => $limit_date,
|
||||
'auto_send' => $auto_send,
|
||||
];
|
||||
|
||||
if (! empty($request['recurring_status'])) {
|
||||
|
@ -7,6 +7,7 @@ use App\Abstracts\View\Component;
|
||||
class Link extends Component
|
||||
{
|
||||
public $href;
|
||||
public $target;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
@ -14,9 +15,10 @@ class Link extends Component
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
$href = '',
|
||||
string $href = '', string $target = '_self'
|
||||
) {
|
||||
$this->href = $href;
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,9 @@ class Recurring extends Component
|
||||
public $limitCount = '';
|
||||
public $limitDateValue = '';
|
||||
|
||||
public $sendEmailShow;
|
||||
public $sendEmail;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
@ -41,6 +44,9 @@ class Recurring extends Component
|
||||
$startedValue = '',
|
||||
$limitCount = '',
|
||||
$limitDateValue = '',
|
||||
|
||||
$sendEmailShow = true,
|
||||
$sendEmail = false
|
||||
) {
|
||||
$this->type = $this->getType($type);
|
||||
$this->frequency = $this->getFrequency($frequency);
|
||||
@ -55,6 +61,9 @@ class Recurring extends Component
|
||||
$this->startedValue = $this->getStartedValue($startedValue);
|
||||
$this->limitCount = $this->getLimitCount($limitCount);
|
||||
$this->limitDateValue = $this->getLimitDateValue($limitDateValue);
|
||||
|
||||
$this->sendEmailShow = $this->getSendEmailShow($sendEmailShow);
|
||||
$this->sendEmail = $this->getSendEmail($sendEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,4 +180,22 @@ class Recurring extends Component
|
||||
|
||||
return Date::now()->toDateString();
|
||||
}
|
||||
|
||||
protected function getSendEmailShow($sendEmailShow)
|
||||
{
|
||||
if (! empty($sendEmailShow)) {
|
||||
return $sendEmailShow;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getSendEmail($sendEmail)
|
||||
{
|
||||
if (! empty($sendEmail)) {
|
||||
return $sendEmail;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
81
app/View/Components/PaymentMethod.php
Normal file
81
app/View/Components/PaymentMethod.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use App\Abstracts\View\Component;
|
||||
use App\Utilities\Modules;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PaymentMethod extends Component
|
||||
{
|
||||
public $code, $method;
|
||||
|
||||
public $payment_methods;
|
||||
|
||||
public $payment_method;
|
||||
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
$code = null, $method = null, string $payment_method = null, array $payment_methods = [], $type = null
|
||||
) {
|
||||
$this->code = $code;
|
||||
$this->method = $method;
|
||||
$this->type = $type;
|
||||
|
||||
$this->payment_methods = $this->getPaymentMethods($payment_methods, $type);
|
||||
$this->payment_method = $this->getPaymentMethod($payment_method, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.payment_method');
|
||||
}
|
||||
|
||||
protected function getPaymentMethods($payment_methods, $type)
|
||||
{
|
||||
if (! empty($payment_methods)) {
|
||||
return $payment_methods;
|
||||
}
|
||||
|
||||
// check here protal or admin panel..
|
||||
if (empty($type)) {
|
||||
$type = Str::contains(request()->route()->getName(), 'portal') ? 'customer' : 'all';
|
||||
}
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods($type);
|
||||
|
||||
return $payment_methods;
|
||||
}
|
||||
|
||||
protected function getPaymentMethod($payment_method, $code)
|
||||
{
|
||||
if (! empty($payment_methods)) {
|
||||
return $payment_methods;
|
||||
}
|
||||
|
||||
if (! empty($this->payment_methods[$code])) {
|
||||
return $this->payment_methods[$code];
|
||||
}
|
||||
|
||||
if (! empty($this->payment_methods[$this->method])) {
|
||||
return $this->payment_methods[$this->method];
|
||||
}
|
||||
|
||||
if (! empty($this->payment_methods[$payment_method])) {
|
||||
return $this->payment_methods[$payment_method];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -122,7 +122,7 @@ class SearchString extends Component
|
||||
}
|
||||
|
||||
if (! empty($options['translation']) && ! isset($options['boolean'])) {
|
||||
return $options['translation'];
|
||||
return $this->findTranslation($options['translation']);
|
||||
}
|
||||
|
||||
if (!empty($options['key'])) {
|
||||
|
@ -130,7 +130,7 @@ class Menu extends Presenter
|
||||
{
|
||||
$id = Str::slug($item->title);
|
||||
|
||||
return '<details class="relative">
|
||||
return '<details class="relative" ' . $this->getActiveStateOnChild($item) . '>
|
||||
<summary class="' . $this->getClass($item). '" href="#navbar-' . $id . '" aria-controls="navbar-' . $id . '">
|
||||
<div class="pb-2.5 flex items-center cursor-pointer text-purple text-sm '. $this->getActiveState($item) .'">
|
||||
' . $this->getIcon($item) . '
|
||||
|
237
composer.lock
generated
237
composer.lock
generated
@ -142,16 +142,16 @@
|
||||
},
|
||||
{
|
||||
"name": "akaunting/laravel-firewall",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/akaunting/laravel-firewall.git",
|
||||
"reference": "6a44c0bf31530f3ae94fbee849395ee91c7ffb54"
|
||||
"reference": "ef48b2e63a7746e0513ce47d8e811ac58ad3bfc7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/akaunting/laravel-firewall/zipball/6a44c0bf31530f3ae94fbee849395ee91c7ffb54",
|
||||
"reference": "6a44c0bf31530f3ae94fbee849395ee91c7ffb54",
|
||||
"url": "https://api.github.com/repos/akaunting/laravel-firewall/zipball/ef48b2e63a7746e0513ce47d8e811ac58ad3bfc7",
|
||||
"reference": "ef48b2e63a7746e0513ce47d8e811ac58ad3bfc7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -203,9 +203,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/akaunting/laravel-firewall/issues",
|
||||
"source": "https://github.com/akaunting/laravel-firewall/tree/2.1.0"
|
||||
"source": "https://github.com/akaunting/laravel-firewall/tree/2.1.3"
|
||||
},
|
||||
"time": "2023-03-07T12:53:34+00:00"
|
||||
"time": "2023-03-25T11:05:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "akaunting/laravel-language",
|
||||
@ -798,23 +798,27 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
"version": "v1.0.4",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/awslabs/aws-crt-php.git",
|
||||
"reference": "f5c64ee7c5fce196e2519b3d9b7138649efe032d"
|
||||
"reference": "1926277fc71d253dfa820271ac5987bdb193ccf5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/f5c64ee7c5fce196e2519b3d9b7138649efe032d",
|
||||
"reference": "f5c64ee7c5fce196e2519b3d9b7138649efe032d",
|
||||
"url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5",
|
||||
"reference": "1926277fc71d253dfa820271ac5987bdb193ccf5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|^5.6.3"
|
||||
"phpunit/phpunit": "^4.8.35||^5.6.3||^9.5",
|
||||
"yoast/phpunit-polyfills": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -833,7 +837,7 @@
|
||||
}
|
||||
],
|
||||
"description": "AWS Common Runtime for PHP",
|
||||
"homepage": "http://aws.amazon.com/sdkforphp",
|
||||
"homepage": "https://github.com/awslabs/aws-crt-php",
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"aws",
|
||||
@ -842,22 +846,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/awslabs/aws-crt-php/issues",
|
||||
"source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.4"
|
||||
"source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1"
|
||||
},
|
||||
"time": "2023-01-31T23:08:25+00:00"
|
||||
"time": "2023-03-24T20:22:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.261.14",
|
||||
"version": "3.262.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "121638bb7e62ee2f71838c52e79884f4301a9400"
|
||||
"reference": "42ca7ade60a775fc5eb103d4631df3d366b48a29"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/121638bb7e62ee2f71838c52e79884f4301a9400",
|
||||
"reference": "121638bb7e62ee2f71838c52e79884f4301a9400",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/42ca7ade60a775fc5eb103d4631df3d366b48a29",
|
||||
"reference": "42ca7ade60a775fc5eb103d4631df3d366b48a29",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -936,9 +940,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.261.14"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.262.1"
|
||||
},
|
||||
"time": "2023-03-17T18:21:00+00:00"
|
||||
"time": "2023-03-24T18:20:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "balping/json-raw-encoder",
|
||||
@ -2934,16 +2938,16 @@
|
||||
},
|
||||
{
|
||||
"name": "genealabs/laravel-model-caching",
|
||||
"version": "0.13.2",
|
||||
"version": "0.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/GeneaLabs/laravel-model-caching.git",
|
||||
"reference": "1fe37744efa9d5ed3d8c245c68271022b0e452ab"
|
||||
"reference": "631bb7f1d84c5863d82cff90e48152f65616597e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/GeneaLabs/laravel-model-caching/zipball/1fe37744efa9d5ed3d8c245c68271022b0e452ab",
|
||||
"reference": "1fe37744efa9d5ed3d8c245c68271022b0e452ab",
|
||||
"url": "https://api.github.com/repos/GeneaLabs/laravel-model-caching/zipball/631bb7f1d84c5863d82cff90e48152f65616597e",
|
||||
"reference": "631bb7f1d84c5863d82cff90e48152f65616597e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2997,22 +3001,22 @@
|
||||
"description": "Automatic caching for Eloquent models.",
|
||||
"support": {
|
||||
"issues": "https://github.com/GeneaLabs/laravel-model-caching/issues",
|
||||
"source": "https://github.com/GeneaLabs/laravel-model-caching/tree/0.13.2"
|
||||
"source": "https://github.com/GeneaLabs/laravel-model-caching/tree/0.13.4"
|
||||
},
|
||||
"time": "2023-03-09T14:37:04+00:00"
|
||||
"time": "2023-03-27T13:53:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "genealabs/laravel-pivot-events",
|
||||
"version": "10.0.0",
|
||||
"version": "10.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/GeneaLabs/laravel-pivot-events.git",
|
||||
"reference": "48dc3cc7c26d6343741dd23f75763e79b7a2706b"
|
||||
"reference": "862371f6f89be296cc026c9cf5b372dca4d7958b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/GeneaLabs/laravel-pivot-events/zipball/48dc3cc7c26d6343741dd23f75763e79b7a2706b",
|
||||
"reference": "48dc3cc7c26d6343741dd23f75763e79b7a2706b",
|
||||
"url": "https://api.github.com/repos/GeneaLabs/laravel-pivot-events/zipball/862371f6f89be296cc026c9cf5b372dca4d7958b",
|
||||
"reference": "862371f6f89be296cc026c9cf5b372dca4d7958b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3054,7 +3058,7 @@
|
||||
"issues": "https://github.com/GeneaLabs/laravel-pivot/issues",
|
||||
"source": "https://github.com/GeneaLabs/laravel-pivot"
|
||||
},
|
||||
"time": "2023-02-17T14:30:37+00:00"
|
||||
"time": "2023-03-22T14:46:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "graham-campbell/markdown",
|
||||
@ -4655,16 +4659,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jaybizzle/crawler-detect",
|
||||
"version": "v1.2.113",
|
||||
"version": "v1.2.114",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
|
||||
"reference": "6710b75871da2b718550c2bc33388315a3b20151"
|
||||
"reference": "62d0e6b38f6715c673e156ffb0fc894791de3452"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/6710b75871da2b718550c2bc33388315a3b20151",
|
||||
"reference": "6710b75871da2b718550c2bc33388315a3b20151",
|
||||
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/62d0e6b38f6715c673e156ffb0fc894791de3452",
|
||||
"reference": "62d0e6b38f6715c673e156ffb0fc894791de3452",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4701,9 +4705,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/JayBizzle/Crawler-Detect/issues",
|
||||
"source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.113"
|
||||
"source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.114"
|
||||
},
|
||||
"time": "2023-02-02T21:01:40+00:00"
|
||||
"time": "2023-03-21T21:54:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
@ -5544,16 +5548,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.3.9",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5"
|
||||
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c1e114f74e518daca2729ea8c4bf1167038fa4b5",
|
||||
"reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
|
||||
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5589,7 +5593,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.4-dev"
|
||||
"dev-main": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -5646,7 +5650,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-15T14:07:24+00:00"
|
||||
"time": "2023-03-24T15:16:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/config",
|
||||
@ -7883,38 +7887,44 @@
|
||||
},
|
||||
{
|
||||
"name": "php-http/discovery",
|
||||
"version": "1.14.3",
|
||||
"version": "1.15.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-http/discovery.git",
|
||||
"reference": "31d8ee46d0215108df16a8527c7438e96a4d7735"
|
||||
"reference": "5cc428320191ac1d0b6520034c2dc0698628ced5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735",
|
||||
"reference": "31d8ee46d0215108df16a8527c7438e96a4d7735",
|
||||
"url": "https://api.github.com/repos/php-http/discovery/zipball/5cc428320191ac1d0b6520034c2dc0698628ced5",
|
||||
"reference": "5cc428320191ac1d0b6520034c2dc0698628ced5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0|^2.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"nyholm/psr7": "<1.0"
|
||||
},
|
||||
"provide": {
|
||||
"php-http/async-client-implementation": "*",
|
||||
"php-http/client-implementation": "*",
|
||||
"psr/http-client-implementation": "*",
|
||||
"psr/http-factory-implementation": "*",
|
||||
"psr/http-message-implementation": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1.0.2|^2.0",
|
||||
"graham-campbell/phpspec-skip-example-extension": "^5.0",
|
||||
"php-http/httplug": "^1.0 || ^2.0",
|
||||
"php-http/message-factory": "^1.0",
|
||||
"phpspec/phpspec": "^5.1 || ^6.1"
|
||||
"phpspec/phpspec": "^5.1 || ^6.1 || ^7.3",
|
||||
"symfony/phpunit-bridge": "^6.2"
|
||||
},
|
||||
"suggest": {
|
||||
"php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories"
|
||||
},
|
||||
"type": "library",
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
"class": "Http\\Discovery\\Composer\\Plugin",
|
||||
"plugin-optional": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@ -7931,7 +7941,7 @@
|
||||
"email": "mark.sagikazar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Finds installed HTTPlug implementations and PSR-7 message factories",
|
||||
"description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations",
|
||||
"homepage": "http://php-http.org",
|
||||
"keywords": [
|
||||
"adapter",
|
||||
@ -7940,13 +7950,14 @@
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"psr17",
|
||||
"psr7"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-http/discovery/issues",
|
||||
"source": "https://github.com/php-http/discovery/tree/1.14.3"
|
||||
"source": "https://github.com/php-http/discovery/tree/1.15.2"
|
||||
},
|
||||
"time": "2022-07-11T14:04:40+00:00"
|
||||
"time": "2023-02-11T08:28:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/guzzle7-adapter",
|
||||
@ -9087,16 +9098,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psy/psysh",
|
||||
"version": "v0.11.12",
|
||||
"version": "v0.11.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bobthecow/psysh.git",
|
||||
"reference": "52cb7c47d403c31c0adc9bf7710fc355f93c20f7"
|
||||
"reference": "722317c9f5627e588788e340f29b923e58f92f54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/52cb7c47d403c31c0adc9bf7710fc355f93c20f7",
|
||||
"reference": "52cb7c47d403c31c0adc9bf7710fc355f93c20f7",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/722317c9f5627e588788e340f29b923e58f92f54",
|
||||
"reference": "722317c9f5627e588788e340f29b923e58f92f54",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -9157,9 +9168,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/bobthecow/psysh/issues",
|
||||
"source": "https://github.com/bobthecow/psysh/tree/v0.11.12"
|
||||
"source": "https://github.com/bobthecow/psysh/tree/v0.11.13"
|
||||
},
|
||||
"time": "2023-01-29T21:24:40+00:00"
|
||||
"time": "2023-03-21T14:22:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
@ -9703,32 +9714,31 @@
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "3.16.0",
|
||||
"version": "3.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getsentry/sentry-php.git",
|
||||
"reference": "5326a8786b8c7c3a51ea0c6d06e6cb6a9dfa6779"
|
||||
"reference": "95d2e932383cf684f77acff0d2a5aef5ad2f1933"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/5326a8786b8c7c3a51ea0c6d06e6cb6a9dfa6779",
|
||||
"reference": "5326a8786b8c7c3a51ea0c6d06e6cb6a9dfa6779",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/95d2e932383cf684f77acff0d2a5aef5ad2f1933",
|
||||
"reference": "95d2e932383cf684f77acff0d2a5aef5ad2f1933",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"guzzlehttp/promises": "^1.4",
|
||||
"guzzlehttp/psr7": "^1.8.4|^2.1.1",
|
||||
"jean85/pretty-package-versions": "^1.5|^2.0.4",
|
||||
"php": "^7.2|^8.0",
|
||||
"php-http/async-client-implementation": "^1.0",
|
||||
"php-http/client-common": "^1.5|^2.0",
|
||||
"php-http/discovery": "^1.11, <1.15",
|
||||
"php-http/discovery": "^1.15",
|
||||
"php-http/httplug": "^1.1|^2.0",
|
||||
"php-http/message": "^1.5",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message-implementation": "^1.0",
|
||||
"psr/http-factory-implementation": "^1.0",
|
||||
"psr/log": "^1.0|^2.0|^3.0",
|
||||
"symfony/options-resolver": "^3.4.43|^4.4.30|^5.0.11|^6.0",
|
||||
"symfony/polyfill-php80": "^1.17"
|
||||
@ -9739,6 +9749,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.19|3.4.*",
|
||||
"guzzlehttp/psr7": "^1.8.4|^2.1.1",
|
||||
"http-interop/http-factory-guzzle": "^1.0",
|
||||
"monolog/monolog": "^1.6|^2.0|^3.0",
|
||||
"nikic/php-parser": "^4.10.3",
|
||||
@ -9791,7 +9802,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/getsentry/sentry-php/issues",
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/3.16.0"
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/3.17.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -9803,20 +9814,20 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-16T10:37:16+00:00"
|
||||
"time": "2023-03-26T21:54:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry-laravel",
|
||||
"version": "3.3.0",
|
||||
"version": "3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getsentry/sentry-laravel.git",
|
||||
"reference": "e9c87d6580fc56147f580e1d714d8eb4e06d2752"
|
||||
"reference": "c502e8b9005990d03f5ec5cc852e98a27c26056d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/e9c87d6580fc56147f580e1d714d8eb4e06d2752",
|
||||
"reference": "e9c87d6580fc56147f580e1d714d8eb4e06d2752",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/c502e8b9005990d03f5ec5cc852e98a27c26056d",
|
||||
"reference": "c502e8b9005990d03f5ec5cc852e98a27c26056d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -9884,7 +9895,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/getsentry/sentry-laravel/issues",
|
||||
"source": "https://github.com/getsentry/sentry-laravel/tree/3.3.0"
|
||||
"source": "https://github.com/getsentry/sentry-laravel/tree/3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -9896,7 +9907,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-16T12:25:43+00:00"
|
||||
"time": "2023-03-22T10:51:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simple-icons/simple-icons",
|
||||
@ -13198,16 +13209,16 @@
|
||||
},
|
||||
{
|
||||
"name": "brianium/paratest",
|
||||
"version": "v7.1.1",
|
||||
"version": "v7.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paratestphp/paratest.git",
|
||||
"reference": "abc123183e90f33ce1312b5bfaa49d80d8c646b2"
|
||||
"reference": "10e66ccdad397200f8129a034f0d3bf8cbe4c524"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/abc123183e90f33ce1312b5bfaa49d80d8c646b2",
|
||||
"reference": "abc123183e90f33ce1312b5bfaa49d80d8c646b2",
|
||||
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/10e66ccdad397200f8129a034f0d3bf8cbe4c524",
|
||||
"reference": "10e66ccdad397200f8129a034f0d3bf8cbe4c524",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -13221,7 +13232,7 @@
|
||||
"phpunit/php-code-coverage": "^10.0.2",
|
||||
"phpunit/php-file-iterator": "^4.0.1",
|
||||
"phpunit/php-timer": "^6.0",
|
||||
"phpunit/phpunit": "^10.0.16",
|
||||
"phpunit/phpunit": "^10.0.17",
|
||||
"sebastian/environment": "^6.0",
|
||||
"symfony/console": "^6.2.7",
|
||||
"symfony/process": "^6.2.7"
|
||||
@ -13231,8 +13242,8 @@
|
||||
"ext-pcov": "*",
|
||||
"ext-posix": "*",
|
||||
"infection/infection": "^0.26.19",
|
||||
"phpstan/phpstan": "^1.10.6",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.2",
|
||||
"phpstan/phpstan": "^1.10.7",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.3",
|
||||
"phpstan/phpstan-phpunit": "^1.3.10",
|
||||
"phpstan/phpstan-strict-rules": "^1.5",
|
||||
"squizlabs/php_codesniffer": "^3.7.2",
|
||||
@ -13277,7 +13288,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paratestphp/paratest/issues",
|
||||
"source": "https://github.com/paratestphp/paratest/tree/v7.1.1"
|
||||
"source": "https://github.com/paratestphp/paratest/tree/v7.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -13289,7 +13300,7 @@
|
||||
"type": "paypal"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-13T10:11:07+00:00"
|
||||
"time": "2023-03-20T15:15:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
@ -13675,16 +13686,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v7.1.2",
|
||||
"version": "v7.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/collision.git",
|
||||
"reference": "f502ff3b2051124c89b4dd3a8a497ca65f3ce26c"
|
||||
"reference": "c680af93e414110b36056029f63120e6bc78f6e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/f502ff3b2051124c89b4dd3a8a497ca65f3ce26c",
|
||||
"reference": "f502ff3b2051124c89b4dd3a8a497ca65f3ce26c",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/c680af93e414110b36056029f63120e6bc78f6e3",
|
||||
"reference": "c680af93e414110b36056029f63120e6bc78f6e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -13694,19 +13705,19 @@
|
||||
"symfony/console": "^6.2.7"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<10.0.16"
|
||||
"phpunit/phpunit": "<10.0.17"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^7.1.1",
|
||||
"laravel/framework": "^10.3.3",
|
||||
"laravel/pint": "^1.6.0",
|
||||
"brianium/paratest": "^7.1.2",
|
||||
"laravel/framework": "^10.4.1",
|
||||
"laravel/pint": "^1.7.0",
|
||||
"laravel/sail": "^1.21.2",
|
||||
"laravel/sanctum": "^3.2.1",
|
||||
"laravel/tinker": "^2.8.1",
|
||||
"nunomaduro/larastan": "^2.5.1",
|
||||
"orchestra/testbench-core": "^8.0.5",
|
||||
"pestphp/pest": "^2.0.0",
|
||||
"phpunit/phpunit": "^10.0.16",
|
||||
"orchestra/testbench-core": "^8.1.1",
|
||||
"pestphp/pest": "^2.0.2",
|
||||
"phpunit/phpunit": "^10.0.17",
|
||||
"sebastian/environment": "^6.0.0",
|
||||
"spatie/laravel-ignition": "^2.0.0"
|
||||
},
|
||||
@ -13767,7 +13778,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-14T14:34:49+00:00"
|
||||
"time": "2023-03-23T21:41:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@ -14200,16 +14211,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "10.0.16",
|
||||
"version": "10.0.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "07d386a11ac7094032900f07cada1c8975d16607"
|
||||
"reference": "20c23e85c86e5c06d63538ba464e8054f4744e62"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/07d386a11ac7094032900f07cada1c8975d16607",
|
||||
"reference": "07d386a11ac7094032900f07cada1c8975d16607",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/20c23e85c86e5c06d63538ba464e8054f4744e62",
|
||||
"reference": "20c23e85c86e5c06d63538ba464e8054f4744e62",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -14280,7 +14291,8 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.0.16"
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.0.19"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -14296,7 +14308,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-13T09:02:40+00:00"
|
||||
"time": "2023-03-27T11:46:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@ -14600,16 +14612,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "70dd1b20bc198da394ad542e988381b44e64e39f"
|
||||
"reference": "aae9a0a43bff37bd5d8d0311426c87bf36153f02"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/70dd1b20bc198da394ad542e988381b44e64e39f",
|
||||
"reference": "70dd1b20bc198da394ad542e988381b44e64e39f",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/aae9a0a43bff37bd5d8d0311426c87bf36153f02",
|
||||
"reference": "aae9a0a43bff37bd5d8d0311426c87bf36153f02",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -14654,7 +14666,8 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/5.0.0"
|
||||
"security": "https://github.com/sebastianbergmann/diff/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/5.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -14662,7 +14675,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-03T07:00:31+00:00"
|
||||
"time": "2023-03-23T05:12:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
|
@ -214,6 +214,7 @@ class Document extends AbstractFactory
|
||||
'recurring_frequency' => 'daily',
|
||||
'recurring_interval' => '1',
|
||||
'recurring_limit_count' => '7',
|
||||
'recurring_send_email' => '1',
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ namespace Database\Factories;
|
||||
|
||||
use App\Abstracts\Factory;
|
||||
use App\Models\Banking\Transaction as Model;
|
||||
use App\Models\Common\Contact;
|
||||
use App\Traits\Transactions;
|
||||
use App\Utilities\Date;
|
||||
|
||||
@ -61,10 +62,21 @@ class Transaction extends Factory
|
||||
*/
|
||||
public function income()
|
||||
{
|
||||
return $this->state([
|
||||
return $this->state(function (array $attributes): array {
|
||||
$contacts = Contact::customer()->enabled()->get();
|
||||
|
||||
if ($contacts->count()) {
|
||||
$contact = $contacts->random(1)->first();
|
||||
} else {
|
||||
$contact = Contact::factory()->customer()->enabled()->create();
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'income',
|
||||
'contact_id' => $contact->id,
|
||||
'category_id' => $this->company->categories()->income()->get()->random(1)->pluck('id')->first(),
|
||||
]);
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,10 +86,21 @@ class Transaction extends Factory
|
||||
*/
|
||||
public function expense()
|
||||
{
|
||||
return $this->state([
|
||||
return $this->state(function (array $attributes): array {
|
||||
$contacts = Contact::vendor()->enabled()->get();
|
||||
|
||||
if ($contacts->count()) {
|
||||
$contact = $contacts->random(1)->first();
|
||||
} else {
|
||||
$contact = Contact::factory()->vendor()->enabled()->create();
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'expense',
|
||||
'contact_id' => $contact->id,
|
||||
'category_id' => $this->company->categories()->expense()->get()->random(1)->pluck('id')->first(),
|
||||
]);
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
Binary file not shown.
Binary file not shown.
@ -22,6 +22,7 @@
|
||||
:config="dateConfig"
|
||||
class="datepicker w-full text-sm px-3 py-2.5 mt-1 rounded-lg border border-light-gray text-black placeholder-light-gray bg-white disabled:bg-gray-200 focus:outline-none focus:ring-transparent focus:border-purple"
|
||||
v-model="real_model"
|
||||
:placeholder="placeholder"
|
||||
@input="change"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled">
|
||||
|
@ -188,16 +188,6 @@ export default {
|
||||
created: function() {
|
||||
this.form = new Form('form-create');
|
||||
|
||||
// for override global currency variable..
|
||||
this.currency = {
|
||||
decimal: '.',
|
||||
thousands: ',',
|
||||
prefix: '$ ',
|
||||
suffix: '',
|
||||
precision: 2,
|
||||
masked: false /* doesn't work with directive */
|
||||
};
|
||||
|
||||
// Parent vue instance methods merge with child vue instance methods
|
||||
if (this.$root.$options.methods) {
|
||||
let parent_methods = this.$root.$options.methods;
|
||||
|
@ -126,6 +126,22 @@
|
||||
<div class="text-red text-sm mt-1 ml-2 block" v-if="limitDateError" v-html="limitDateError"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="sendEmailShow" class="flex flex-wrap lg:flex-nowrap items-center space-y-1 lg:space-y-0">
|
||||
<div class="w-24 sm:w-60 px-0 sm:px-2 text-sm">
|
||||
{{ sendEmailText }}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center mt-1">
|
||||
<label @click="sendEmail=1;change();" v-bind:class="[sendEmail == 1 ? ['bg-green-500','text-white'] : 'bg-black-100']" class="relative w-10 ltr:rounded-tl-lg ltr:rounded-bl-lg rtl:rounded-tr-lg rtl:rounded-br-lg py-2 px-1 text-sm text-center transition-all cursor-pointer">
|
||||
{{ sendEmailYesText }}
|
||||
</label>
|
||||
|
||||
<label @click="sendEmail=0;change();"v-bind:class="[sendEmail == 0 ? ['bg-red-500','text-white'] : 'bg-black-100']" class="relative w-10 ltr:rounded-tr-lg ltr:rounded-br-lg rtl:rounded-tl-lg rtl:rounded-bl-lg py-2 px-1 text-sm text-center transition-all cursor-pointer">
|
||||
{{ sendEmailNoText }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -246,6 +262,32 @@ export default {
|
||||
default: 'dd MM yyyy',
|
||||
description: "Default date format"
|
||||
},
|
||||
|
||||
sendEmailShow: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
description: "Created recurring model send automatically option"
|
||||
},
|
||||
sendEmailText: {
|
||||
type: String,
|
||||
default: 'Send email automatically',
|
||||
description: "Created recurring model send automatically option"
|
||||
},
|
||||
sendEmailYesText: {
|
||||
type: String,
|
||||
default: 'Yes',
|
||||
description: "Send email option yes text"
|
||||
},
|
||||
sendEmailNoText: {
|
||||
type: String,
|
||||
default: 'No',
|
||||
description: "Send email option no text"
|
||||
},
|
||||
sendEmailValue: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
description: "Send Email value"
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -258,6 +300,7 @@ export default {
|
||||
limitCount: 0,
|
||||
limitDate: '',
|
||||
formatDate: 'dd MM YYYY',
|
||||
sendEmail: 0,
|
||||
}
|
||||
},
|
||||
|
||||
@ -284,6 +327,8 @@ export default {
|
||||
this.limit = 'on';
|
||||
}
|
||||
|
||||
this.sendEmail = this.sendEmailValue;
|
||||
|
||||
setTimeout(function() {
|
||||
this.change();
|
||||
}.bind(this), 800);
|
||||
@ -315,6 +360,8 @@ export default {
|
||||
this.$emit('limit_count', 0);
|
||||
break;
|
||||
}
|
||||
|
||||
this.$emit('send_email', this.sendEmail);
|
||||
},
|
||||
|
||||
convertToDarteFormat(format) {
|
||||
|
@ -13,7 +13,7 @@ export default {
|
||||
new BrowserTracing({
|
||||
tracingOrigins: [],
|
||||
}),
|
||||
new Sentry.Replay()
|
||||
//new Sentry.Replay()
|
||||
],
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
@ -22,11 +22,11 @@ export default {
|
||||
|
||||
// This sets the sample rate to be 10%. You may want this to be 100% while
|
||||
// in development and sample at a lower rate in production
|
||||
replaysSessionSampleRate: exception_tracker.params.replays_session_sample_rate,
|
||||
//replaysSessionSampleRate: exception_tracker.params.replays_session_sample_rate,
|
||||
|
||||
// If the entire session is not sampled, use the below sample rate to sample
|
||||
// sessions when an error occurs.
|
||||
replaysOnErrorSampleRate: exception_tracker.params.replays_on_error_sample_rate,
|
||||
//replaysOnErrorSampleRate: exception_tracker.params.replays_on_error_sample_rate,
|
||||
});
|
||||
|
||||
Sentry.setUser({
|
||||
|
@ -42,7 +42,7 @@ return [
|
||||
'send_invoice' => 'Send Invoice',
|
||||
'get_paid' => 'Get Paid',
|
||||
'accept_payments' => 'Accept Online Payments',
|
||||
'payment_received' => 'Payment received',
|
||||
'payments_received' => 'Payments received',
|
||||
|
||||
'form_description' => [
|
||||
'billing' => 'Billing details appear in your invoice. Invoice Date is used in the dashboard and reports. Select the date you expect to get paid as the Due Date.',
|
||||
|
@ -25,7 +25,8 @@ return [
|
||||
'not_user_company' => 'Error: You are not allowed to manage this company!',
|
||||
'customer' => 'Error: User not created! :name already uses this email address.',
|
||||
'no_file' => 'Error: No file selected!',
|
||||
'last_category' => 'Error: Can not delete the last :type category!',
|
||||
'last_category' => 'Error: Can not delete the last <b>:type</b> category!',
|
||||
'transfer_category' => 'Error: Can not delete the transfer <b>:type</b> category!',
|
||||
'change_type' => 'Error: Can not change the type because it has :text related!',
|
||||
'invalid_apikey' => 'Error: The API Key entered is invalid!',
|
||||
'import_column' => 'Error: :message Column name: :column. Line number: :line.',
|
||||
|
@ -29,6 +29,7 @@ return [
|
||||
'child' => ':url was automatically created on :date',
|
||||
'message' => 'This is a recurring :type and the next :type will be automatically generated on :date',
|
||||
'message_parent' => 'This :type was automatically generated from :link',
|
||||
'send_email_auto' => 'Send email automatically',
|
||||
|
||||
'frequency_type' => 'Repeat this :type',
|
||||
'limit_date' => 'Create first :type on',
|
||||
|
@ -11,34 +11,36 @@
|
||||
<x-form.group.text name="name" label="{{ trans($textName) }}" form-group-class="{{ $classNameFromGroupClass }}" />
|
||||
@endif
|
||||
|
||||
<div class="sm:col-span-3 grid gap-x-8 gap-y-6">
|
||||
<div class="sm:col-span-3">
|
||||
<div class="relative sm:col-span-6 grid gap-x-8 gap-y-6">
|
||||
@if (! $hideEmail)
|
||||
<x-form.group.text name="email" label="{{ trans($textEmail) }}" not-required />
|
||||
<x-form.group.text name="email" label="{{ trans($textEmail) }}" form-group-class="sm:col-span-6" not-required />
|
||||
@endif
|
||||
|
||||
@if (! $hidePhone)
|
||||
<x-form.group.text name="phone" label="{{ trans($textPhone) }}" not-required />
|
||||
<x-form.group.text name="phone" label="{{ trans($textPhone) }}" form-group-class="sm:col-span-6" not-required />
|
||||
@endif
|
||||
|
||||
@if (! $hideWebsite)
|
||||
<x-form.group.text name="website" label="{{ trans($textWebsite) }}" not-required />
|
||||
<x-form.group.text name="website" label="{{ trans($textWebsite) }}" form-group-class="sm:col-span-6" not-required />
|
||||
@endif
|
||||
|
||||
@if (! $hideReference)
|
||||
<x-form.group.text name="reference" label="{{ trans($textReference) }}" not-required />
|
||||
<x-form.group.text name="reference" label="{{ trans($textReference) }}" form-group-class="sm:col-span-6" not-required />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-3">
|
||||
<div class="relative sm:col-span-6 grid gap-x-8 gap-y-6">
|
||||
@if (! $hideCanLogin)
|
||||
<div class="mt-9">
|
||||
<div class="sm:col-span-6 mt-9 mb-2">
|
||||
@if (empty($contact))
|
||||
<x-tooltip id="tooltip-client_portal-text" placement="bottom" message="{{ trans('customers.can_login_description') }}">
|
||||
<x-form.group.checkbox
|
||||
name="create_user"
|
||||
:options="['1' => trans('customers.can_login')]"
|
||||
@input="onCanLogin($event)"
|
||||
checkbox-class="sm:col-span-6"
|
||||
/>
|
||||
</x-tooltip>
|
||||
@else
|
||||
@ -46,7 +48,6 @@
|
||||
<x-form.group.checkbox
|
||||
name="create_user"
|
||||
:options="['1' => trans('customers.user_created')]"
|
||||
checkbox-class="sm:col-span-6"
|
||||
checked
|
||||
disabled
|
||||
/>
|
||||
@ -55,7 +56,6 @@
|
||||
<x-form.group.checkbox
|
||||
name="create_user"
|
||||
:options="['1' => trans('customers.can_login')]"
|
||||
checkbox-class="sm:col-span-6"
|
||||
@input="onCanLogin($event)"
|
||||
/>
|
||||
</x-tooltip>
|
||||
@ -65,8 +65,9 @@
|
||||
@endif
|
||||
|
||||
@if (! $hideLogo)
|
||||
<x-form.group.file name="logo" label="{{ trans_choice('general.pictures', 1) }}" :value="! empty($contact) ? $contact->logo : false" not-required />
|
||||
<x-form.group.file name="logo" label="{{ trans_choice('general.pictures', 1) }}" :value="! empty($contact) ? $contact->logo : false" form-group-class="sm:col-span-6" not-required />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-form.section>
|
||||
|
@ -7,23 +7,27 @@
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="body">
|
||||
<div class="sm:col-span-2 grid gap-x-8 gap-y-6">
|
||||
<div class="sm:col-span-2">
|
||||
<div class="relative sm:col-span-6 grid gap-x-8 gap-y-6">
|
||||
@if (! $hideDocumentTitle)
|
||||
<x-form.group.text name="title" label="{{ trans('settings.invoice.title') }}" value="{{ $titleSetting }}" not-required data-field="setting" />
|
||||
<x-form.group.text name="title" label="{{ trans('settings.invoice.title') }}" value="{{ $titleSetting }}" not-required data-field="setting" form-group-class="sm:col-span-6" />
|
||||
@endif
|
||||
|
||||
@if (! $hideDocumentSubheading)
|
||||
<x-form.group.text name="subheading" label="{{ trans('settings.invoice.subheading') }}" value="{{ $subheadingSetting }}" not-required data-field="setting" />
|
||||
<x-form.group.text name="subheading" label="{{ trans('settings.invoice.subheading') }}" value="{{ $subheadingSetting }}" not-required data-field="setting" form-group-class="sm:col-span-6" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-1"></div>
|
||||
|
||||
<div class="sm:col-span-2">
|
||||
<div class="relative sm:col-span-6 grid gap-x-8 gap-y-6">
|
||||
@if (! $hideLogo)
|
||||
<x-form.group.file name="company_logo" label="{{ trans('settings.company.logo') }}" :value="setting('company.logo')" not-required data-field="setting" />
|
||||
<x-form.group.file name="company_logo" label="{{ trans('settings.company.logo') }}" :value="setting('company.logo')" not-required data-field="setting" form-group-class="sm:col-span-6" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-2 relative">
|
||||
@if (! $hideCompanyEdit)
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
<div class="text-xs mt-6" style="margin-left: 0 !important;">
|
||||
<span class="font-medium">
|
||||
{{ trans('invoices.payment_received') }} :
|
||||
{{ trans('invoices.payments_received') }}:
|
||||
</span>
|
||||
|
||||
@if ($transactions->count())
|
||||
|
@ -52,7 +52,7 @@
|
||||
@if (! $hideCompanyTaxNumber)
|
||||
@if (setting('company.tax_number'))
|
||||
<p>
|
||||
<span class="text-medium text-default">
|
||||
<span class="font-semibold">
|
||||
{{ trans('general.tax_number') }}:
|
||||
</span>
|
||||
{{ setting('company.tax_number') }}
|
||||
@ -153,7 +153,7 @@
|
||||
@if (! $hideContactTaxNumber)
|
||||
@if ($document->contact_tax_number)
|
||||
<p>
|
||||
<span class="text-medium text-default">
|
||||
<span class="font-semibold">
|
||||
{{ trans('general.tax_number') }}:
|
||||
</span>
|
||||
{{ $document->contact_tax_number }}
|
||||
|
@ -116,7 +116,7 @@
|
||||
@if (! $hideContactTaxNumber)
|
||||
@if ($document->contact_tax_number)
|
||||
<p>
|
||||
<span class="text-medium text-default">
|
||||
<span class="font-semibold">
|
||||
{{ trans('general.tax_number') }}:
|
||||
</span>
|
||||
{{ $document->contact_tax_number }}
|
||||
|
@ -52,7 +52,7 @@
|
||||
@if (! $hideCompanyTaxNumber)
|
||||
<p class="text-white">
|
||||
@if (setting('company.tax_number'))
|
||||
<span class="text-medium text-default">
|
||||
<span class="font-semibold">
|
||||
{{ trans('general.tax_number') }}:
|
||||
</span>
|
||||
|
||||
@ -122,7 +122,7 @@
|
||||
@if (! $hideContactTaxNumber)
|
||||
@if ($document->contact_tax_number)
|
||||
<p>
|
||||
<span class="text-medium text-default">
|
||||
<span class="font-semibold">
|
||||
{{ trans('general.tax_number') }}:
|
||||
</span>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="w-full flex items-center text-purple px-2 h-9 leading-9 whitespace-nowrap" {{ $attributes }}>
|
||||
<a href="{!! $href !!}" class="w-full h-full flex items-center rounded-md px-2 text-sm font-normal hover:bg-lilac-100">
|
||||
<a href="{!! $href !!}" target="{!! $target !!}" class="w-full h-full flex items-center rounded-md px-2 text-sm font-normal hover:bg-lilac-100">
|
||||
{!! $slot !!}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -3,6 +3,9 @@
|
||||
:date-range-text="{{ json_encode(trans('general.date_range')) }}"
|
||||
middle-text="{!! trans('recurring.limit_middle') !!}"
|
||||
end-text="{{ Str::plural(Str::replace('-recurring', '', $type)) }}"
|
||||
send-email-text="{{ trans('recurring.send_email_auto') }}"
|
||||
send-email-yes-text="{{ trans('general.yes') }}"
|
||||
send-email-no-text="{{ trans('general.no') }}"
|
||||
|
||||
:frequencies="{{ json_encode($frequencies) }}"
|
||||
frequency-text="{!! trans('recurring.frequency_type', ['type' => Str::replace('-recurring', '', $type)]) !!}"
|
||||
@ -65,6 +68,15 @@
|
||||
@endif
|
||||
:limit-date-error="form.errors.get('recurring_limit_date')"
|
||||
|
||||
send-email-show="{{ $sendEmailShow }}"
|
||||
send-email-value="{{ $sendEmail }}"
|
||||
@if ($attributes->has('@send_email'))
|
||||
@send_email="form.recurring_send_email = $event;{{ $attributes['@send_email'] }}"
|
||||
@else
|
||||
@send_email="form.recurring_send_email = $event"
|
||||
@endif
|
||||
:send-email-error="form.errors.get('recurring_send_email')"
|
||||
|
||||
date-format="{{ company_date_format() }}"
|
||||
|
||||
{{ $attributes }}
|
||||
|
@ -1,5 +1,5 @@
|
||||
@props([
|
||||
'metaTitle', 'title',
|
||||
'metaTitle', 'title', 'currency'
|
||||
])
|
||||
|
||||
<head>
|
||||
|
5
resources/views/components/payment_method.blade.php
Normal file
5
resources/views/components/payment_method.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@if (! empty($payment_method))
|
||||
{!! $payment_method !!}
|
||||
@else
|
||||
<x-empty-data />
|
||||
@endif
|
@ -8,7 +8,14 @@
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div data-swiper="{{ $slides }}" x-data="{ active: window.location.hash.split('#')[1] == undefined ? '{{ $active }}' : window.location.hash.split('#')[1] }">
|
||||
<div
|
||||
data-swiper="{{ $slides }}"
|
||||
@if(! $attributes->has('ignore-hash'))
|
||||
x-data="{ active: window.location.hash.split('#')[1] == undefined ? '{{ $active }}' : window.location.hash.split('#')[1] }"
|
||||
@else
|
||||
x-data="{ active: '{{ $active }}' }"
|
||||
@endif
|
||||
>
|
||||
<div data-tabs-swiper>
|
||||
<ul data-tabs-swiper-wrapper {{ ((! $attributes->has('override')) || ($attributes->has('override') && ! in_array('class', explode(',', $attributes->get('override'))))) ? $attributes->merge(['class' => 'inline-flex overflow-x-scroll large-overflow-unset']) : $attributes }}>
|
||||
{!! $navs !!}
|
||||
|
@ -132,7 +132,7 @@
|
||||
</td>
|
||||
|
||||
<td valign="top" class="border-bottom-dashed-black" style="width:70%; margin: 0px; padding: 8px 0 0 0; font-size: 12px;">
|
||||
{{ !empty($payment_methods[$transaction->payment_method]) ? $payment_methods[$transaction->payment_method] : trans('general.na') }}
|
||||
<x-payment-method :method="$transaction->payment_method" />
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
@ -214,11 +214,7 @@
|
||||
</td>
|
||||
|
||||
<td valign="top" valign="top" class="border-bottom-dashed-black" style="width:70%; margin: 0px; padding: 8px 0 0 0; font-size: 12px;">
|
||||
@if (! empty($payment_methods[$transfer->expense_transaction->payment_method]))
|
||||
{!! $payment_methods[$transfer->expense_transaction->payment_method] !!}
|
||||
@else
|
||||
<x-empty-data />
|
||||
@endif
|
||||
<x-payment-method :method="$transfer->expense_transaction->payment_method" />
|
||||
</td>
|
||||
</tr>
|
||||
@stack('payment_method_input_end')
|
||||
|
@ -30,11 +30,7 @@
|
||||
</td>
|
||||
|
||||
<td valign="top" style="width:70%; margin: 0px; padding: 8px 0 8px 0; font-size: 12px; border-bottom:1px solid #adadad;">
|
||||
@if (! empty($payment_methods[$transfer->expense_transaction->payment_method]))
|
||||
{!! $payment_methods[$transfer->expense_transaction->payment_method] !!}
|
||||
@else
|
||||
<x-empty-data />
|
||||
@endif
|
||||
<x-payment-method :method="$transfer->expense_transaction->payment_method" />
|
||||
</td>
|
||||
</tr>
|
||||
@stack('payment_method_input_end')
|
||||
|
@ -224,11 +224,7 @@
|
||||
</td>
|
||||
|
||||
<td valign="top" style="width:70%; margin: 0px; padding: 0; font-size: 12px; border-bottom:1px solid; line-height: 24px;">
|
||||
@if (! empty($payment_methods[$transfer->expense_transaction->payment_method]))
|
||||
{!! $payment_methods[$transfer->expense_transaction->payment_method] !!}
|
||||
@else
|
||||
<x-empty-data />
|
||||
@endif
|
||||
<x-payment-method :method="$transfer->expense_transaction->payment_method" />
|
||||
</td>
|
||||
</tr>
|
||||
@stack('payment_method_input_end')
|
||||
|
@ -100,7 +100,7 @@
|
||||
<x-slot name="body" class="block" override="class">
|
||||
<div class="text-xs mt-1" style="margin-left: 0 !important;">
|
||||
<span class="font-medium">
|
||||
{{ trans('invoices.payment_received') }} :
|
||||
{{ trans('invoices.payments_received') }}:
|
||||
</span>
|
||||
|
||||
@if ($invoice->transactions->count())
|
||||
|
@ -98,7 +98,7 @@
|
||||
<x-slot name="body" class="block" override="class">
|
||||
<div class="text-xs mt-1" style="margin-left: 0 !important;">
|
||||
<span class="font-medium">
|
||||
{{ trans('invoices.payment_received') }} :
|
||||
{{ trans('invoices.payments_received') }}:
|
||||
</span>
|
||||
|
||||
@if ($invoice->transactions->count())
|
||||
|
@ -107,7 +107,7 @@
|
||||
<x-slot name="body" class="block" override="class">
|
||||
<div class="text-xs mt-1" style="margin-left: 0 !important;">
|
||||
<span class="font-medium">
|
||||
{{ trans('invoices.payment_received') }} :
|
||||
{{ trans('invoices.payments_received') }}:
|
||||
</span>
|
||||
|
||||
@if ($invoice->transactions->count())
|
||||
|
@ -41,7 +41,7 @@
|
||||
</x-table.td>
|
||||
|
||||
<x-table.td class="w-4/12 sm:w-3/12">
|
||||
{{ $payment_methods[$item->payment_method] }}
|
||||
<x-payment-method :method="$item->payment_method" type="customer" />
|
||||
</x-table.td>
|
||||
|
||||
<x-table.td class="w-3/12" hidden-mobile>
|
||||
|
@ -17,21 +17,23 @@
|
||||
<x-form.group.color name="color" label="{{ trans('general.color') }}" />
|
||||
|
||||
@if ($type_disabled)
|
||||
<x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" disabled />
|
||||
<x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" v-disabled="true" />
|
||||
|
||||
<input type="hidden" name="type" value="{{ $category->type }}" />
|
||||
@else
|
||||
<x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" change="updateParentCategories" />
|
||||
@endif
|
||||
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="$parent_categories" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" />
|
||||
|
||||
<x-form.input.hidden name="parent_category_id" value="{{ $category->parent_id }}" />
|
||||
<x-form.input.hidden name="categories" value="{{ json_encode($categories) }}" />
|
||||
@endif
|
||||
</x-slot>
|
||||
</x-form.section>
|
||||
|
||||
@if (! $type_disabled)
|
||||
<x-form.group.switch name="enabled" label="{{ trans('general.enabled') }}" />
|
||||
@endif
|
||||
|
||||
@can('update-settings-categories')
|
||||
<x-form.section>
|
||||
|
@ -67,7 +67,11 @@
|
||||
@foreach($categories as $item)
|
||||
<x-table.tr href="{{ route('categories.edit', $item->id) }}">
|
||||
<x-table.td kind="bulkaction">
|
||||
<x-index.bulkaction.single id="{{ $item->id }}" name="{{ $item->name }}" />
|
||||
<x-index.bulkaction.single
|
||||
id="{{ $item->id }}"
|
||||
name="{{ $item->name }}"
|
||||
:disabled="($item->isTransferCategory()) ? true : false"
|
||||
/>
|
||||
</x-table.td>
|
||||
|
||||
<x-table.td class="w-5/12">
|
||||
|
@ -10,7 +10,13 @@
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="body">
|
||||
<x-form.group.account name="account" not-required without-change />
|
||||
<x-form.group.select
|
||||
name="account"
|
||||
label="{{ trans_choice('general.accounts', 1) }}"
|
||||
:options="$accounts"
|
||||
:selected="setting('default.account')"
|
||||
not-required
|
||||
/>
|
||||
|
||||
<x-form.group.currency name="currency" not-required />
|
||||
|
||||
|
@ -4,9 +4,11 @@ namespace Tests\Feature\Banking;
|
||||
|
||||
use App\Exports\Banking\Transactions as Export;
|
||||
use App\Jobs\Banking\CreateTransaction;
|
||||
use App\Notifications\Banking\Transaction as Notification;
|
||||
use App\Models\Banking\Transaction;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Tests\Feature\FeatureTestCase;
|
||||
|
||||
@ -70,6 +72,43 @@ class TransactionsTest extends FeatureTestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function testItShouldSendTransactionEmail()
|
||||
{
|
||||
NotificationFacade::fake();
|
||||
|
||||
$transaction = $this->dispatch(new CreateTransaction($this->getRequest()));
|
||||
|
||||
$this->loginAs()
|
||||
->post(route('modals.transactions.emails.store', $transaction->id), $this->getEmailRequest($transaction))
|
||||
->assertStatus(200);
|
||||
|
||||
$this->assertFlashLevel('success');
|
||||
|
||||
NotificationFacade::assertSentTo($transaction->contact, Notification::class);
|
||||
}
|
||||
|
||||
public function testItShouldHitRateLimitForSendTransactionEmail()
|
||||
{
|
||||
NotificationFacade::fake();
|
||||
|
||||
$limit_per_minute = (int) config('app.throttles.email.minute');
|
||||
|
||||
$transaction = $this->dispatch(new CreateTransaction($this->getRequest()));
|
||||
|
||||
for ($i = 0; $i < $limit_per_minute; $i++) {
|
||||
$this->loginAs()
|
||||
->post(route('modals.transactions.emails.store', $transaction->id), $this->getEmailRequest($transaction));
|
||||
}
|
||||
|
||||
$this->loginAs()
|
||||
->post(route('modals.transactions.emails.store', $transaction->id), $this->getEmailRequest($transaction))
|
||||
->assertJson([
|
||||
'success' => false,
|
||||
]);
|
||||
|
||||
NotificationFacade::assertSentTimes(Notification::class, $limit_per_minute);
|
||||
}
|
||||
|
||||
public function testItShouldSeeTransactionUpdatePage()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
@ -192,4 +231,18 @@ class TransactionsTest extends FeatureTestCase
|
||||
|
||||
return $factory->raw();
|
||||
}
|
||||
|
||||
public function getEmailRequest($transaction)
|
||||
{
|
||||
$email_template = config('type.transaction.' . $transaction->type . '.email_template');
|
||||
|
||||
$notification = new Notification($transaction, $email_template, true);
|
||||
|
||||
return [
|
||||
'transaction_id' => $transaction->id,
|
||||
'to' => $transaction->contact->email,
|
||||
'subject' => $notification->getSubject(),
|
||||
'body' => $notification->getBody(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,11 @@ namespace Tests\Feature\Sales;
|
||||
use App\Exports\Sales\Invoices as Export;
|
||||
use App\Jobs\Document\CreateDocument;
|
||||
use App\Models\Document\Document;
|
||||
use App\Notifications\Sale\Invoice as Notification;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Tests\Feature\FeatureTestCase;
|
||||
@ -127,6 +129,43 @@ class InvoicesTest extends FeatureTestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function testItShouldSendInvoiceEmail()
|
||||
{
|
||||
NotificationFacade::fake();
|
||||
|
||||
$invoice = $this->dispatch(new CreateDocument($this->getRequest()));
|
||||
|
||||
$this->loginAs()
|
||||
->post(route('modals.invoices.emails.store', $invoice->id), $this->getEmailRequest($invoice))
|
||||
->assertStatus(200);
|
||||
|
||||
$this->assertFlashLevel('success');
|
||||
|
||||
NotificationFacade::assertSentTo($invoice->contact, Notification::class);
|
||||
}
|
||||
|
||||
public function testItShouldHitRateLimitForSendInvoiceEmail()
|
||||
{
|
||||
NotificationFacade::fake();
|
||||
|
||||
$limit_per_minute = (int) config('app.throttles.email.minute');
|
||||
|
||||
$invoice = $this->dispatch(new CreateDocument($this->getRequest()));
|
||||
|
||||
for ($i = 0; $i < $limit_per_minute; $i++) {
|
||||
$this->loginAs()
|
||||
->post(route('modals.invoices.emails.store', $invoice->id), $this->getEmailRequest($invoice));
|
||||
}
|
||||
|
||||
$this->loginAs()
|
||||
->post(route('modals.invoices.emails.store', $invoice->id), $this->getEmailRequest($invoice))
|
||||
->assertJson([
|
||||
'success' => false,
|
||||
]);
|
||||
|
||||
NotificationFacade::assertSentTimes(Notification::class, $limit_per_minute);
|
||||
}
|
||||
|
||||
public function testItShouldSeeInvoiceUpdatePage()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
@ -254,4 +293,16 @@ class InvoicesTest extends FeatureTestCase
|
||||
|
||||
return $factory->raw();
|
||||
}
|
||||
|
||||
public function getEmailRequest($invoice)
|
||||
{
|
||||
$notification = new Notification($invoice, 'invoice_new_customer', true);
|
||||
|
||||
return [
|
||||
'document_id' => $invoice->id,
|
||||
'to' => $invoice->contact->email,
|
||||
'subject' => $notification->getSubject(),
|
||||
'body' => $notification->getBody(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user