Merge pull request #9298 from turbo124/v5-develop

Set default payment notifications for new companies
This commit is contained in:
David Bomba 2024-02-16 08:47:42 +11:00 committed by GitHub
commit 49dfee7afe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
139 changed files with 919 additions and 909 deletions

76
.github/workflows/react_release.yml vendored Normal file
View File

@ -0,0 +1,76 @@
on:
release:
types: [released]
name: React Release
jobs:
build:
name: Upload Release Asset
runs-on: ubuntu-latest
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
extensions: mysql, mysqlnd, sqlite3, bcmath, gd, curl, zip, openssl, mbstring, xml
- name: Checkout code
uses: actions/checkout@v1
with:
ref: v5-develop
- name: Copy .env file
run: |
cp .env.example .env
- name: Install composer dependencies
run: |
composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
composer install --no-dev
- name: Prepare Laravel Application
run: |
cp .env.example .env
php artisan key:generate --force
php artisan optimize
php artisan storage:link --force
sudo php artisan cache:clear
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
sudo find ./ -type d -exec chmod 755 {} \;
sudo rm -f public/main.*
sudo rm -f public/flutter*
- name: Prepare React FrontEnd
run: |
git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git
cd ui
git checkout develop
npm i
npm run build
cp -r dist/* ../public/
- name: Prepare JS/CSS assets
run: |
npm i
npm run production
- name: Cleanup Builds
run: |
sudo rm -rf bootstrap/cache/*
sudo rm -rf node_modules
sudo rm -rf .git
sudo rm .env
- name: Build project
run: |
shopt -s dotglob
tar --exclude='public/storage' --exclude='.htaccess' --exclude='invoiceninja.zip' -zcvf /home/runner/work/invoiceninja/react-invoiceninja.tar *
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: |
/home/runner/work/invoiceninja/react-invoiceninja.tar

View File

@ -1 +1 @@
5.8.24 5.8.25

View File

@ -891,7 +891,7 @@ class CheckData extends Command
$this->logMessage("Fixing country for # {$client->id}"); $this->logMessage("Fixing country for # {$client->id}");
}); });
Client::query()->whereNull("settings->currency_id")->cursor()->each(function ($client){ Client::query()->whereNull("settings->currency_id")->cursor()->each(function ($client) {
$settings = $client->settings; $settings = $client->settings;
$settings->currency_id = (string)$client->company->settings->currency_id; $settings->currency_id = (string)$client->company->settings->currency_id;
$client->settings = $settings; $client->settings = $settings;
@ -901,7 +901,7 @@ class CheckData extends Command
}); });
Payment::withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment){ Payment::withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment) {
$payment->exchange_rate = 1; $payment->exchange_rate = 1;
$payment->saveQuietly(); $payment->saveQuietly();

View File

@ -52,8 +52,9 @@ class EncryptNinja extends Command
*/ */
public function handle() public function handle()
{ {
if($this->option('encrypt')) if($this->option('encrypt')) {
return $this->encryptFiles(); return $this->encryptFiles();
}
if($this->option('decrypt')) { if($this->option('decrypt')) {
return $this->decryptFiles(); return $this->decryptFiles();
@ -67,7 +68,7 @@ class EncryptNinja extends Command
$contents = Storage::disk('base')->get($file); $contents = Storage::disk('base')->get($file);
$encrypted = encrypt($contents); $encrypted = encrypt($contents);
Storage::disk('base')->put($file.".enc", $encrypted); Storage::disk('base')->put($file.".enc", $encrypted);
Storage::disk('base')->delete($file); // Storage::disk('base')->delete($file);
} }
} }

View File

@ -878,7 +878,7 @@ class CompanySettings extends BaseSettings
{ {
$notification = new stdClass(); $notification = new stdClass();
$notification->email = []; $notification->email = [];
$notification->email = ['invoice_sent_all']; $notification->email = ['invoice_sent_all','payment_success_all','payment_manual_all'];
return $notification; return $notification;
} }

View File

@ -59391,7 +59391,7 @@ class Domains
'wireconnected.com' 'wireconnected.com'
]; ];
public static function getDomains() public static function getDomains(): array
{ {
return self::$verify_domains; return self::$verify_domains;
} }

View File

@ -451,13 +451,15 @@ class BaseExport
{ {
if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') { if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') {
if(!is_int($this->input['client_id'])) if(!is_int($this->input['client_id'])) {
$this->input['client_id'] = $this->decodePrimaryKey($this->input['client_id']); $this->input['client_id'] = $this->decodePrimaryKey($this->input['client_id']);
}
$client = Client::withTrashed()->find($this->input['client_id']); $client = Client::withTrashed()->find($this->input['client_id']);
if(!$client) if(!$client) {
return $query; return $query;
}
$this->client_description = $client->present()->name; $this->client_description = $client->present()->name;
return $query->where('client_id', $this->input['client_id']); return $query->where('client_id', $this->input['client_id']);
@ -845,16 +847,18 @@ class BaseExport
protected function addClientFilter($query, $clients): Builder protected function addClientFilter($query, $clients): Builder
{ {
if(is_string($clients)) if(is_string($clients)) {
$clients = explode(',', $clients); $clients = explode(',', $clients);
}
$transformed_clients = $this->transformKeys($clients); $transformed_clients = $this->transformKeys($clients);
nlog($clients); nlog($clients);
nlog($transformed_clients); nlog($transformed_clients);
if(count($transformed_clients) > 0) if(count($transformed_clients) > 0) {
$query->whereIn('client_id', $transformed_clients); $query->whereIn('client_id', $transformed_clients);
}
return $query; return $query;
} }
@ -868,8 +872,9 @@ class BaseExport
$transformed_vendors = $this->transformKeys($vendors); $transformed_vendors = $this->transformKeys($vendors);
if(count($transformed_vendors) > 0) if(count($transformed_vendors) > 0) {
$query->whereIn('vendor_id', $transformed_vendors); $query->whereIn('vendor_id', $transformed_vendors);
}
return $query; return $query;
} }
@ -883,8 +888,9 @@ class BaseExport
$transformed_projects = $this->transformKeys($projects); $transformed_projects = $this->transformKeys($projects);
if(count($transformed_projects) > 0) if(count($transformed_projects) > 0) {
$query->whereIn('project_id', $transformed_projects); $query->whereIn('project_id', $transformed_projects);
}
return $query; return $query;
} }
@ -899,8 +905,9 @@ class BaseExport
$transformed_expense_categories = $this->transformKeys($expense_categories); $transformed_expense_categories = $this->transformKeys($expense_categories);
if(count($transformed_expense_categories) > 0) if(count($transformed_expense_categories) > 0) {
$query->whereIn('category_id', $transformed_expense_categories); $query->whereIn('category_id', $transformed_expense_categories);
}
return $query; return $query;
} }
@ -1299,11 +1306,11 @@ class BaseExport
public function queueDocuments(Builder $query) public function queueDocuments(Builder $query)
{ {
nlog("queue docs pls"); nlog("queue docs pls");
if($query->getModel() instanceof Document) if($query->getModel() instanceof Document) {
$documents = $query->pluck('id')->toArray(); $documents = $query->pluck('id')->toArray();
else{ } else {
$documents = $query->cursor() $documents = $query->cursor()
->map(function ($entity){ ->map(function ($entity) {
return $entity->documents()->pluck('id')->toArray(); return $entity->documents()->pluck('id')->toArray();
})->flatten() })->flatten()
->toArray(); ->toArray();
@ -1315,11 +1322,13 @@ class BaseExport
$user = $this->company->owner(); $user = $this->company->owner();
if(auth()->user() && auth()->user()->account_id == $this->company->account_id) if(auth()->user() && auth()->user()->account_id == $this->company->account_id) {
$user = auth()->user(); $user = auth()->user();
}
if($this->input['user_id'] ?? false) if($this->input['user_id'] ?? false) {
$user = User::where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first(); $user = User::where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first();
}
ZipDocuments::dispatch($documents, $this->company, $user); ZipDocuments::dispatch($documents, $this->company, $user);
} }

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class ExpenseExport extends BaseExport class ExpenseExport extends BaseExport
{ {
private $expense_transformer; private $expense_transformer;
private Decorator $decorator; private Decorator $decorator;
@ -206,15 +205,13 @@ class ExpenseExport extends BaseExport
if($expense->calculate_tax_by_amount) { if($expense->calculate_tax_by_amount) {
$total_tax_amount = round($expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3, $precision); $total_tax_amount = round($expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3, $precision);
} } else {
else {
if($expense->uses_inclusive_taxes){ if($expense->uses_inclusive_taxes) {
$total_tax_amount = ($this->calcInclusiveLineTax($expense->tax_rate1 ?? 0, $expense->amount,$precision)) + ($this->calcInclusiveLineTax($expense->tax_rate2 ?? 0, $expense->amount,$precision)) + ($this->calcInclusiveLineTax($expense->tax_rate3 ?? 0, $expense->amount,$precision)); $total_tax_amount = ($this->calcInclusiveLineTax($expense->tax_rate1 ?? 0, $expense->amount, $precision)) + ($this->calcInclusiveLineTax($expense->tax_rate2 ?? 0, $expense->amount, $precision)) + ($this->calcInclusiveLineTax($expense->tax_rate3 ?? 0, $expense->amount, $precision));
$entity['expense.net_amount'] = round(($expense->amount - round($total_tax_amount, $precision)), $precision); $entity['expense.net_amount'] = round(($expense->amount - round($total_tax_amount, $precision)), $precision);
} } else {
else{ $total_tax_amount = ($expense->amount * (($expense->tax_rate1 ?? 0) / 100)) + ($expense->amount * (($expense->tax_rate2 ?? 0) / 100)) + ($expense->amount * (($expense->tax_rate3 ?? 0) / 100));
$total_tax_amount = ($expense->amount * (($expense->tax_rate1 ?? 0)/100)) + ($expense->amount * (($expense->tax_rate2 ?? 0)/100)) + ($expense->amount * (($expense->tax_rate3 ?? 0)/100));
$entity['expense.net_amount'] = round(($expense->amount + round($total_tax_amount, $precision)), $precision); $entity['expense.net_amount'] = round(($expense->amount + round($total_tax_amount, $precision)), $precision);
} }
} }

View File

@ -165,8 +165,7 @@ class ClientFilters extends QueryFilters
$dir = ($sort_col[1] == 'asc') ? 'asc' : 'desc'; $dir = ($sort_col[1] == 'asc') ? 'asc' : 'desc';
if($sort_col[0] == 'number') if($sort_col[0] == 'number') {
{
return $this->builder->orderByRaw('ABS(number) ' . $dir); return $this->builder->orderByRaw('ABS(number) ' . $dir);
} }

View File

@ -318,13 +318,12 @@ class InvoiceFilters extends QueryFilters
if ($sort_col[0] == 'client_id') { if ($sort_col[0] == 'client_id') {
return $this->builder->orderBy(\App\Models\Client::select ('name') return $this->builder->orderBy(\App\Models\Client::select('name')
->whereColumn('clients.id', 'invoices.client_id'), $dir); ->whereColumn('clients.id', 'invoices.client_id'), $dir);
} }
if($sort_col[0] == 'number') if($sort_col[0] == 'number') {
{
return $this->builder->orderByRaw('ABS(number) ' . $dir); return $this->builder->orderByRaw('ABS(number) ' . $dir);
} }

View File

@ -70,8 +70,9 @@ class TransactionTransformer implements BankRevenueInterface
{ {
$data = []; $data = [];
if (!array_key_exists('transactions', $transactionResponse) || !array_key_exists('booked', $transactionResponse["transactions"])) if (!array_key_exists('transactions', $transactionResponse) || !array_key_exists('booked', $transactionResponse["transactions"])) {
throw new \Exception('invalid dataset'); throw new \Exception('invalid dataset');
}
foreach ($transactionResponse["transactions"]["booked"] as $transaction) { foreach ($transactionResponse["transactions"]["booked"] as $transaction) {
$data[] = $this->transformTransaction($transaction); $data[] = $this->transformTransaction($transaction);
@ -83,11 +84,11 @@ class TransactionTransformer implements BankRevenueInterface
{ {
// depending on institution, the result can be different, so we load the first available unique id // depending on institution, the result can be different, so we load the first available unique id
$transactionId = ''; $transactionId = '';
if (array_key_exists('transactionId', $transaction)) if (array_key_exists('transactionId', $transaction)) {
$transactionId = $transaction["transactionId"]; $transactionId = $transaction["transactionId"];
else if (array_key_exists('internalTransactionId', $transaction)) } elseif (array_key_exists('internalTransactionId', $transaction)) {
$transactionId = $transaction["internalTransactionId"]; $transactionId = $transaction["internalTransactionId"];
else { } else {
nlog(`Invalid Input for nordigen transaction transformer: ` . $transaction); nlog(`Invalid Input for nordigen transaction transformer: ` . $transaction);
throw new \Exception('invalid dataset: missing transactionId - Please report this error to the developer'); throw new \Exception('invalid dataset: missing transactionId - Please report this error to the developer');
} }
@ -96,22 +97,24 @@ class TransactionTransformer implements BankRevenueInterface
// description could be in varios places // description could be in varios places
$description = ''; $description = '';
if (array_key_exists('remittanceInformationStructured', $transaction)) if (array_key_exists('remittanceInformationStructured', $transaction)) {
$description = $transaction["remittanceInformationStructured"]; $description = $transaction["remittanceInformationStructured"];
else if (array_key_exists('remittanceInformationStructuredArray', $transaction)) } elseif (array_key_exists('remittanceInformationStructuredArray', $transaction)) {
$description = implode('\n', $transaction["remittanceInformationStructuredArray"]); $description = implode('\n', $transaction["remittanceInformationStructuredArray"]);
else if (array_key_exists('remittanceInformationUnstructured', $transaction)) } elseif (array_key_exists('remittanceInformationUnstructured', $transaction)) {
$description = $transaction["remittanceInformationUnstructured"]; $description = $transaction["remittanceInformationUnstructured"];
else if (array_key_exists('remittanceInformationUnstructuredArray', $transaction)) } elseif (array_key_exists('remittanceInformationUnstructuredArray', $transaction)) {
$description = implode('\n', $transaction["remittanceInformationUnstructuredArray"]); $description = implode('\n', $transaction["remittanceInformationUnstructuredArray"]);
else } else {
Log::warning("Missing description for the following transaction: " . json_encode($transaction)); Log::warning("Missing description for the following transaction: " . json_encode($transaction));
}
// enrich description with currencyExchange informations // enrich description with currencyExchange informations
if (array_key_exists('currencyExchange', $transaction)) if (isset($transaction['currencyExchange'])) {
foreach ($transaction["currencyExchange"] as $exchangeRate) { foreach ($transaction["currencyExchange"] as $exchangeRate) {
$targetAmount = round($amount * (float) $exchangeRate["exchangeRate"], 2); $targetAmount = round($amount * (float) ($exchangeRate["exchangeRate"] ?? 1) , 2);
$description .= '\nexchangeRate: ' . $amount . " " . $exchangeRate["sourceCurrency"] . " = " . $targetAmount . " " . $exchangeRate["targetCurrency"] . " (" . $exchangeRate["quotationDate"] . ")"; $description .= '\nexchangeRate: ' . $amount . " " . ($exchangeRate["sourceCurrency"] ?? '?') . " = " . $targetAmount . " " . ($exchangeRate["targetCurrency"] ?? '?') . " (" . ($exchangeRate["quotationDate"] ?? '?') . ")";
}
} }
// participant data // participant data
@ -153,8 +156,9 @@ class TransactionTransformer implements BankRevenueInterface
return $item->code == $code; return $item->code == $code;
})->first(); })->first();
if ($currency) if ($currency) {
return $currency->id; return $currency->id;
}
return 1; return 1;

View File

@ -112,8 +112,9 @@ class BankTransactionController extends BaseController
$this->bank_transaction_repo->convert_matched($bank_transactions); $this->bank_transaction_repo->convert_matched($bank_transactions);
} else { } else {
$bank_transactions->each(function ($bank_transaction, $key) use ($action, $user) { $bank_transactions->each(function ($bank_transaction, $key) use ($action, $user) {
if($user->can('edit', $bank_transaction)) if($user->can('edit', $bank_transaction)) {
$this->bank_transaction_repo->{$action}($bank_transaction); $this->bank_transaction_repo->{$action}($bank_transaction);
}
}); });
} }

View File

@ -421,10 +421,10 @@ class ClientController extends BaseController
$documents = Document::query() $documents = Document::query()
->company() ->company()
->whereHasMorph('documentable', [Invoice::class, Quote::class, Credit::class, Expense::class, Payment::class, Task::class], function ($query) use($client) { ->whereHasMorph('documentable', [Invoice::class, Quote::class, Credit::class, Expense::class, Payment::class, Task::class], function ($query) use ($client) {
$query->where('client_id', $client->id); $query->where('client_id', $client->id);
}) })
->orWhereHasMorph('documentable', [Client::class], function ($query) use ($client){ ->orWhereHasMorph('documentable', [Client::class], function ($query) use ($client) {
$query->where('id', $client->id); $query->where('id', $client->id);
}); });

View File

@ -74,8 +74,9 @@ class DocumentController extends Controller
$hash = Cache::pull($hash); $hash = Cache::pull($hash);
if(!$hash) if(!$hash) {
abort(404); abort(404);
}
MultiDB::setDb($hash['db']); MultiDB::setDb($hash['db']);

View File

@ -58,4 +58,3 @@ class EmailPreferencesController extends Controller
return back()->with('message', ctrans('texts.updated_settings')); return back()->with('message', ctrans('texts.updated_settings'));
} }
} }

View File

@ -224,8 +224,9 @@ class InvoiceController extends Controller
$settings = auth()->guard('contact')->user()->client->getMergedSettings(); $settings = auth()->guard('contact')->user()->client->getMergedSettings();
$variables = false; $variables = false;
if(($invitation = $invoices->first()->invitations()->first() ?? false) && $settings->show_accept_invoice_terms) if(($invitation = $invoices->first()->invitations()->first() ?? false) && $settings->show_accept_invoice_terms) {
$variables = (new HtmlEngine($invitation))->generateLabelsAndValues(); $variables = (new HtmlEngine($invitation))->generateLabelsAndValues();
}
$data = [ $data = [
'settings' => $settings, 'settings' => $settings,

View File

@ -12,24 +12,25 @@
namespace App\Http\Controllers\ClientPortal; namespace App\Http\Controllers\ClientPortal;
use App\Factory\PaymentFactory;
use App\Http\Controllers\Controller;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Models\CompanyGateway;
use App\Models\GatewayType;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Payment; use App\Models\Payment;
use App\Utils\HtmlEngine;
use Illuminate\View\View;
use App\Models\GatewayType;
use App\Models\PaymentHash; use App\Models\PaymentHash;
use App\Models\PaymentType; use App\Models\PaymentType;
use Illuminate\Http\Request;
use App\Models\CompanyGateway;
use App\Factory\PaymentFactory;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesDates;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Contracts\View\Factory;
use App\PaymentDrivers\Stripe\BankTransfer; use App\PaymentDrivers\Stripe\BankTransfer;
use App\Services\ClientPortal\InstantPayment; use App\Services\ClientPortal\InstantPayment;
use App\Services\Subscription\SubscriptionService; use App\Services\Subscription\SubscriptionService;
use App\Utils\Traits\MakesDates; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
/** /**
* Class PaymentController. * Class PaymentController.
@ -125,10 +126,16 @@ class PaymentController extends Controller
// 09-07-2022 catch duplicate responses for invoices that already paid here. // 09-07-2022 catch duplicate responses for invoices that already paid here.
if ($invoice && $invoice->status_id == Invoice::STATUS_PAID) { if ($invoice && $invoice->status_id == Invoice::STATUS_PAID) {
$invitation = $invoice->invitations->first();
$variables = ($invitation && auth()->guard('contact')->user()->client->getSetting('show_accept_invoice_terms')) ? (new HtmlEngine($invitation))->generateLabelsAndValues() : false;
$data = [ $data = [
'invoice' => $invoice, 'invoice' => $invoice,
'key' => false, 'key' => false,
'invitation' => $invoice->invitations->first() 'invitation' => $invitation,
'variables' => $variables,
]; ];
if ($request->query('mode') === 'fullscreen') { if ($request->query('mode') === 'fullscreen') {

View File

@ -29,8 +29,9 @@ class HostedMigrationController extends Controller
MultiDB::findAndSetDbByCompanyKey($request->company_key); MultiDB::findAndSetDbByCompanyKey($request->company_key);
$c = Company::where('company_key', $request->company_key)->first(); $c = Company::where('company_key', $request->company_key)->first();
if(!$c || $c->is_disabled) if(!$c || $c->is_disabled) {
return response()->json(['message' => 'ok'], 200); return response()->json(['message' => 'ok'], 200);
}
// if(\App\Models\Invoice::query()->where('company_id', $c->id)->where('created_at', '>', now()->subMonths(2))->first()) // if(\App\Models\Invoice::query()->where('company_id', $c->id)->where('created_at', '>', now()->subMonths(2))->first())
// return response()->json(['message' => 'New data exists, are you sure? Please log in here https://app.invoicing.co and delete the company if you really need to migrate again.'], 400); // return response()->json(['message' => 'New data exists, are you sure? Please log in here https://app.invoicing.co and delete the company if you really need to migrate again.'], 400);

View File

@ -22,18 +22,22 @@ class MailgunWebhookController extends BaseController
{ {
private $invitation; private $invitation;
public function __construct() {} public function __construct()
{
}
public function webhook(Request $request) public function webhook(Request $request)
{ {
$input = $request->all(); $input = $request->all();
if (\abs(\time() - $request['signature']['timestamp']) > 15) if (\abs(\time() - $request['signature']['timestamp']) > 15) {
return response()->json(['message' => 'Success'], 200); return response()->json(['message' => 'Success'], 200);
}
if(\hash_equals(\hash_hmac('sha256', $input['signature']['timestamp'] . $input['signature']['token'], config('services.mailgun.webhook_signing_key')), $input['signature']['signature'])) if(\hash_equals(\hash_hmac('sha256', $input['signature']['timestamp'] . $input['signature']['token'], config('services.mailgun.webhook_signing_key')), $input['signature']['signature'])) {
ProcessMailgunWebhook::dispatch($request->all())->delay(10); ProcessMailgunWebhook::dispatch($request->all())->delay(10);
}
return response()->json(['message' => 'Success.'], 200); return response()->json(['message' => 'Success.'], 200);
} }

View File

@ -67,7 +67,7 @@ class TokenAuth
$truth->setUser($company_token->user); $truth->setUser($company_token->user);
$truth->setCompany($company_token->company); $truth->setCompany($company_token->company);
$truth->setCompanyToken($company_token); $truth->setCompanyToken($company_token);
$truth->setPremiumHosted($company_token->account->isPremium());
/* /*
| This method binds the db to the jobs created using this | This method binds the db to the jobs created using this
| session | session

View File

@ -198,17 +198,21 @@ class Request extends FormRequest
} }
} }
if(isset($input['public_notes'])) if(isset($input['public_notes'])) {
$input['public_notes'] = str_replace("</sc","<-", $input['public_notes']); $input['public_notes'] = str_replace("</sc", "<-", $input['public_notes']);
}
if(isset($input['footer'])) if(isset($input['footer'])) {
$input['footer'] = str_replace("</sc", "<-", $input['footer']); $input['footer'] = str_replace("</sc", "<-", $input['footer']);
}
if(isset($input['terms'])) if(isset($input['terms'])) {
$input['terms'] = str_replace("</sc", "<-", $input['terms']); $input['terms'] = str_replace("</sc", "<-", $input['terms']);
}
if(isset($input['private_notes'])) if(isset($input['private_notes'])) {
$input['private_notes'] = str_replace("</sc", "<-", $input['private_notes']); $input['private_notes'] = str_replace("</sc", "<-", $input['private_notes']);
}
return $input; return $input;
} }

View File

@ -88,10 +88,9 @@ class PaymentAppliedValidAmount implements Rule
nlog($inv->amount); nlog($inv->amount);
nlog($invoice['amount']); nlog($invoice['amount']);
if($inv->status_id == Invoice::STATUS_DRAFT && $inv->amount >= $invoice['amount']){ if($inv->status_id == Invoice::STATUS_DRAFT && $inv->amount >= $invoice['amount']) {
} } elseif ($inv->balance < $invoice['amount']) {
elseif ($inv->balance < $invoice['amount']) {
$this->message = 'Amount cannot be greater than invoice balance'; $this->message = 'Amount cannot be greater than invoice balance';
return false; return false;

View File

@ -117,10 +117,8 @@ class Wave extends BaseImport implements ImportInterface
$this->transformer = new InvoiceTransformer($this->company); $this->transformer = new InvoiceTransformer($this->company);
foreach($data as $key => $invoice) foreach($data as $key => $invoice) {
{ if(!isset($invoice['Invoice Number']) || empty($invoice['Invoice Number'])) {
if(!isset($invoice['Invoice Number']) || empty($invoice['Invoice Number']))
{
unset($data[$key]); unset($data[$key]);
} }
} }

View File

@ -72,12 +72,12 @@ class CompanyExport implements ShouldQueue
$this->file_name = date('Y-m-d') . '_' . str_replace([" ", "/"], ["_",""], $this->company->present()->name() . '_' . $this->company->company_key . '.json'); $this->file_name = date('Y-m-d') . '_' . str_replace([" ", "/"], ["_",""], $this->company->present()->name() . '_' . $this->company->company_key . '.json');
$this->writer = new File($this->file_name); $this->writer = new File($this->file_name);
set_time_limit(0); set_time_limit(0);
$this->writer->value('app_version', config('ninja.app_version')); $this->writer->value('app_version', config('ninja.app_version'));
$this->writer->value('storage_url', Storage::url('')); $this->writer->value('storage_url', Storage::url(''));
$this->export_data['activities'] = $this->company->all_activities->map(function ($activity) { $this->export_data['activities'] = $this->company->all_activities->map(function ($activity) {
$activity = $this->transformArrayOfKeys($activity, [ $activity = $this->transformArrayOfKeys($activity, [
@ -104,9 +104,9 @@ $this->writer->value('storage_url', Storage::url(''));
})->makeHidden(['id'])->all(); })->makeHidden(['id'])->all();
$x = $this->writer->collection('activities'); $x = $this->writer->collection('activities');
$x->addItems($this->export_data['activities']); $x->addItems($this->export_data['activities']);
$this->export_data = null; $this->export_data = null;
$this->export_data['users'] = $this->company->users()->withTrashed()->cursor()->map(function ($user) { $this->export_data['users'] = $this->company->users()->withTrashed()->cursor()->map(function ($user) {
@ -116,9 +116,9 @@ $this->export_data = null;
$x = $this->writer->collection('users'); $x = $this->writer->collection('users');
$x->addItems($this->export_data['users']); $x->addItems($this->export_data['users']);
$this->export_data = null; $this->export_data = null;
$this->export_data['client_contacts'] = $this->company->client_contacts->map(function ($client_contact) { $this->export_data['client_contacts'] = $this->company->client_contacts->map(function ($client_contact) {
@ -140,9 +140,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('client_contacts'); $x = $this->writer->collection('client_contacts');
$x->addItems($this->export_data['client_contacts']); $x->addItems($this->export_data['client_contacts']);
$this->export_data = null; $this->export_data = null;
$this->export_data['client_gateway_tokens'] = $this->company->client_gateway_tokens->map(function ($client_gateway_token) { $this->export_data['client_gateway_tokens'] = $this->company->client_gateway_tokens->map(function ($client_gateway_token) {
$client_gateway_token = $this->transformArrayOfKeys($client_gateway_token, ['company_id', 'client_id', 'company_gateway_id']); $client_gateway_token = $this->transformArrayOfKeys($client_gateway_token, ['company_id', 'client_id', 'company_gateway_id']);
@ -151,9 +151,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('client_gateway_tokens'); $x = $this->writer->collection('client_gateway_tokens');
$x->addItems($this->export_data['client_gateway_tokens']); $x->addItems($this->export_data['client_gateway_tokens']);
$this->export_data = null; $this->export_data = null;
$this->export_data['clients'] = $this->company->clients()->orderBy('number', 'DESC')->cursor()->map(function ($client) { $this->export_data['clients'] = $this->company->clients()->orderBy('number', 'DESC')->cursor()->map(function ($client) {
$client = $this->transformArrayOfKeys($client, ['company_id', 'user_id', 'assigned_user_id', 'group_settings_id']); $client = $this->transformArrayOfKeys($client, ['company_id', 'user_id', 'assigned_user_id', 'group_settings_id']);
@ -162,18 +162,18 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('clients'); $x = $this->writer->collection('clients');
$x->addItems($this->export_data['clients']); $x->addItems($this->export_data['clients']);
$this->export_data = null; $this->export_data = null;
// $this->export_data['company'] = $this->company->toArray(); // $this->export_data['company'] = $this->company->toArray();
// $this->export_data['company']['company_key'] = $this->createHash(); // $this->export_data['company']['company_key'] = $this->createHash();
$this->writer->value('company', $this->company->toJson(), encode: false); $this->writer->value('company', $this->company->toJson(), encode: false);
// $x = $this->writer->collection('company'); // $x = $this->writer->collection('company');
// $x->addItems($this->export_data['company']); // $x->addItems($this->export_data['company']);
// $this->export_data = null; // $this->export_data = null;
$this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway) { $this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway) {
@ -184,9 +184,9 @@ $this->writer->value('company', $this->company->toJson(), encode: false);
})->all(); })->all();
$x = $this->writer->collection('company_gateways'); $x = $this->writer->collection('company_gateways');
$x->addItems($this->export_data['company_gateways']); $x->addItems($this->export_data['company_gateways']);
$this->export_data = null; $this->export_data = null;
@ -198,9 +198,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('company_tokens'); $x = $this->writer->collection('company_tokens');
$x->addItems($this->export_data['company_tokens']); $x->addItems($this->export_data['company_tokens']);
$this->export_data = null; $this->export_data = null;
$this->export_data['company_ledger'] = $this->company->ledger->map(function ($ledger) { $this->export_data['company_ledger'] = $this->company->ledger->map(function ($ledger) {
@ -210,9 +210,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('company_ledger'); $x = $this->writer->collection('company_ledger');
$x->addItems($this->export_data['company_ledger']); $x->addItems($this->export_data['company_ledger']);
$this->export_data = null; $this->export_data = null;
$this->export_data['company_users'] = $this->company->company_users()->without(['user','account'])->cursor()->map(function ($company_user) { $this->export_data['company_users'] = $this->company->company_users()->without(['user','account'])->cursor()->map(function ($company_user) {
@ -221,9 +221,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('company_users'); $x = $this->writer->collection('company_users');
$x->addItems($this->export_data['company_users']); $x->addItems($this->export_data['company_users']);
$this->export_data = null; $this->export_data = null;
$this->export_data['credits'] = $this->company->credits()->orderBy('number', 'DESC')->cursor()->map(function ($credit) { $this->export_data['credits'] = $this->company->credits()->orderBy('number', 'DESC')->cursor()->map(function ($credit) {
@ -233,9 +233,9 @@ $this->export_data = null;
return $credit->makeVisible(['id']); return $credit->makeVisible(['id']);
})->all(); })->all();
$x = $this->writer->collection('credits'); $x = $this->writer->collection('credits');
$x->addItems($this->export_data['credits']); $x->addItems($this->export_data['credits']);
$this->export_data = null; $this->export_data = null;
$this->export_data['credit_invitations'] = CreditInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit) { $this->export_data['credit_invitations'] = CreditInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit) {
@ -245,17 +245,17 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('credit_invitations'); $x = $this->writer->collection('credit_invitations');
$x->addItems($this->export_data['credit_invitations']); $x->addItems($this->export_data['credit_invitations']);
$this->export_data = null; $this->export_data = null;
$this->export_data['designs'] = $this->company->user_designs->makeHidden(['id'])->all(); $this->export_data['designs'] = $this->company->user_designs->makeHidden(['id'])->all();
$x = $this->writer->collection('designs'); $x = $this->writer->collection('designs');
$x->addItems($this->export_data['designs']); $x->addItems($this->export_data['designs']);
$this->export_data = null; $this->export_data = null;
$this->export_data['documents'] = $this->company->all_documents->map(function ($document) { $this->export_data['documents'] = $this->company->all_documents->map(function ($document) {
@ -265,9 +265,9 @@ $this->export_data = null;
return $document->makeVisible(['id']); return $document->makeVisible(['id']);
})->all(); })->all();
$x = $this->writer->collection('documents'); $x = $this->writer->collection('documents');
$x->addItems($this->export_data['documents']); $x->addItems($this->export_data['documents']);
$this->export_data = null; $this->export_data = null;
$this->export_data['expense_categories'] = $this->company->expense_categories()->cursor()->map(function ($expense_category) { $this->export_data['expense_categories'] = $this->company->expense_categories()->cursor()->map(function ($expense_category) {
$expense_category = $this->transformArrayOfKeys($expense_category, ['user_id', 'company_id']); $expense_category = $this->transformArrayOfKeys($expense_category, ['user_id', 'company_id']);
@ -275,9 +275,9 @@ $this->export_data = null;
return $expense_category->makeVisible(['id']); return $expense_category->makeVisible(['id']);
})->all(); })->all();
$x = $this->writer->collection('expense_categories'); $x = $this->writer->collection('expense_categories');
$x->addItems($this->export_data['expense_categories']); $x->addItems($this->export_data['expense_categories']);
$this->export_data = null; $this->export_data = null;
$this->export_data['expenses'] = $this->company->expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) { $this->export_data['expenses'] = $this->company->expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) {
@ -288,9 +288,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('expenses'); $x = $this->writer->collection('expenses');
$x->addItems($this->export_data['expenses']); $x->addItems($this->export_data['expenses']);
$this->export_data = null; $this->export_data = null;
$this->export_data['group_settings'] = $this->company->group_settings->map(function ($gs) { $this->export_data['group_settings'] = $this->company->group_settings->map(function ($gs) {
@ -300,9 +300,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('group_settings'); $x = $this->writer->collection('group_settings');
$x->addItems($this->export_data['group_settings']); $x->addItems($this->export_data['group_settings']);
$this->export_data = null; $this->export_data = null;
$this->export_data['invoices'] = $this->company->invoices()->orderBy('number', 'DESC')->cursor()->map(function ($invoice) { $this->export_data['invoices'] = $this->company->invoices()->orderBy('number', 'DESC')->cursor()->map(function ($invoice) {
@ -318,9 +318,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('invoices'); $x = $this->writer->collection('invoices');
$x->addItems($this->export_data['invoices']); $x->addItems($this->export_data['invoices']);
$this->export_data = null; $this->export_data = null;
$this->export_data['invoice_invitations'] = InvoiceInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice) { $this->export_data['invoice_invitations'] = InvoiceInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice) {
$invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'invoice_id']); $invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'invoice_id']);
@ -329,9 +329,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('invoice_invitations'); $x = $this->writer->collection('invoice_invitations');
$x->addItems($this->export_data['invoice_invitations']); $x->addItems($this->export_data['invoice_invitations']);
$this->export_data = null; $this->export_data = null;
$this->export_data['payment_terms'] = $this->company->user_payment_terms->map(function ($term) { $this->export_data['payment_terms'] = $this->company->user_payment_terms->map(function ($term) {
@ -341,9 +341,9 @@ $this->export_data = null;
})->makeHidden(['id'])->all(); })->makeHidden(['id'])->all();
$x = $this->writer->collection('payment_terms'); $x = $this->writer->collection('payment_terms');
$x->addItems($this->export_data['payment_terms']); $x->addItems($this->export_data['payment_terms']);
$this->export_data = null; $this->export_data = null;
$this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment) { $this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment) {
@ -357,9 +357,9 @@ $this->export_data = null;
$x = $this->writer->collection('payments'); $x = $this->writer->collection('payments');
$x->addItems($this->export_data['payments']); $x->addItems($this->export_data['payments']);
$this->export_data = null; $this->export_data = null;
$this->export_data['products'] = $this->company->products->map(function ($product) { $this->export_data['products'] = $this->company->products->map(function ($product) {
@ -370,9 +370,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('products'); $x = $this->writer->collection('products');
$x->addItems($this->export_data['products']); $x->addItems($this->export_data['products']);
$this->export_data = null; $this->export_data = null;
$this->export_data['projects'] = $this->company->projects()->orderBy('number', 'DESC')->cursor()->map(function ($project) { $this->export_data['projects'] = $this->company->projects()->orderBy('number', 'DESC')->cursor()->map(function ($project) {
@ -383,9 +383,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('projects'); $x = $this->writer->collection('projects');
$x->addItems($this->export_data['projects']); $x->addItems($this->export_data['projects']);
$this->export_data = null; $this->export_data = null;
$this->export_data['quotes'] = $this->company->quotes()->orderBy('number', 'DESC')->cursor()->map(function ($quote) { $this->export_data['quotes'] = $this->company->quotes()->orderBy('number', 'DESC')->cursor()->map(function ($quote) {
@ -396,9 +396,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('quotes'); $x = $this->writer->collection('quotes');
$x->addItems($this->export_data['quotes']); $x->addItems($this->export_data['quotes']);
$this->export_data = null; $this->export_data = null;
$this->export_data['quote_invitations'] = QuoteInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote) { $this->export_data['quote_invitations'] = QuoteInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote) {
@ -408,9 +408,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('quote_invitations'); $x = $this->writer->collection('quote_invitations');
$x->addItems($this->export_data['quote_invitations']); $x->addItems($this->export_data['quote_invitations']);
$this->export_data = null; $this->export_data = null;
$this->export_data['recurring_expenses'] = $this->company->recurring_expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) { $this->export_data['recurring_expenses'] = $this->company->recurring_expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) {
@ -422,9 +422,9 @@ $this->export_data = null;
$x = $this->writer->collection('recurring_expenses'); $x = $this->writer->collection('recurring_expenses');
$x->addItems($this->export_data['recurring_expenses']); $x->addItems($this->export_data['recurring_expenses']);
$this->export_data = null; $this->export_data = null;
$this->export_data['recurring_invoices'] = $this->company->recurring_invoices()->orderBy('number', 'DESC')->cursor()->map(function ($ri) { $this->export_data['recurring_invoices'] = $this->company->recurring_invoices()->orderBy('number', 'DESC')->cursor()->map(function ($ri) {
@ -435,9 +435,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('recurring_invoices'); $x = $this->writer->collection('recurring_invoices');
$x->addItems($this->export_data['recurring_invoices']); $x->addItems($this->export_data['recurring_invoices']);
$this->export_data = null; $this->export_data = null;
$this->export_data['recurring_invoice_invitations'] = RecurringInvoiceInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($ri) { $this->export_data['recurring_invoice_invitations'] = RecurringInvoiceInvitation::query()->where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($ri) {
@ -447,9 +447,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('recurring_invoice_invitations'); $x = $this->writer->collection('recurring_invoice_invitations');
$x->addItems($this->export_data['recurring_invoice_invitations']); $x->addItems($this->export_data['recurring_invoice_invitations']);
$this->export_data = null; $this->export_data = null;
@ -467,9 +467,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('subscriptions'); $x = $this->writer->collection('subscriptions');
$x->addItems($this->export_data['subscriptions']); $x->addItems($this->export_data['subscriptions']);
$this->export_data = null; $this->export_data = null;
$this->export_data['system_logs'] = $this->company->system_logs->map(function ($log) { $this->export_data['system_logs'] = $this->company->system_logs->map(function ($log) {
$log->client_id = $this->encodePrimaryKey($log->client_id); $log->client_id = $this->encodePrimaryKey($log->client_id);
@ -479,9 +479,9 @@ $this->export_data = null;
})->makeHidden(['id'])->all(); })->makeHidden(['id'])->all();
$x = $this->writer->collection('system_logs'); $x = $this->writer->collection('system_logs');
$x->addItems($this->export_data['system_logs']); $x->addItems($this->export_data['system_logs']);
$this->export_data = null; $this->export_data = null;
$this->export_data['tasks'] = $this->company->tasks()->orderBy('number', 'DESC')->cursor()->map(function ($task) { $this->export_data['tasks'] = $this->company->tasks()->orderBy('number', 'DESC')->cursor()->map(function ($task) {
@ -493,9 +493,9 @@ $this->export_data = null;
$x = $this->writer->collection('tasks'); $x = $this->writer->collection('tasks');
$x->addItems($this->export_data['tasks']); $x->addItems($this->export_data['tasks']);
$this->export_data = null; $this->export_data = null;
$this->export_data['task_statuses'] = $this->company->task_statuses->map(function ($status) { $this->export_data['task_statuses'] = $this->company->task_statuses->map(function ($status) {
@ -508,9 +508,9 @@ $this->export_data = null;
$x = $this->writer->collection('task_statuses'); $x = $this->writer->collection('task_statuses');
$x->addItems($this->export_data['task_statuses']); $x->addItems($this->export_data['task_statuses']);
$this->export_data = null; $this->export_data = null;
$this->export_data['tax_rates'] = $this->company->tax_rates->map(function ($rate) { $this->export_data['tax_rates'] = $this->company->tax_rates->map(function ($rate) {
@ -522,9 +522,9 @@ $this->export_data = null;
$x = $this->writer->collection('tax_rates'); $x = $this->writer->collection('tax_rates');
$x->addItems($this->export_data['tax_rates']); $x->addItems($this->export_data['tax_rates']);
$this->export_data = null; $this->export_data = null;
$this->export_data['vendors'] = $this->company->vendors()->orderBy('number', 'DESC')->cursor()->map(function ($vendor) { $this->export_data['vendors'] = $this->company->vendors()->orderBy('number', 'DESC')->cursor()->map(function ($vendor) {
@ -533,9 +533,9 @@ $this->export_data = null;
$x = $this->writer->collection('vendors'); $x = $this->writer->collection('vendors');
$x->addItems($this->export_data['vendors']); $x->addItems($this->export_data['vendors']);
$this->export_data = null; $this->export_data = null;
$this->export_data['vendor_contacts'] = VendorContact::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($vendor) { $this->export_data['vendor_contacts'] = VendorContact::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($vendor) {
@ -547,9 +547,9 @@ $this->export_data = null;
$x = $this->writer->collection('vendor_contacts'); $x = $this->writer->collection('vendor_contacts');
$x->addItems($this->export_data['vendor_contacts']); $x->addItems($this->export_data['vendor_contacts']);
$this->export_data = null; $this->export_data = null;
$this->export_data['webhooks'] = $this->company->webhooks->map(function ($hook) { $this->export_data['webhooks'] = $this->company->webhooks->map(function ($hook) {
@ -560,9 +560,9 @@ $this->export_data = null;
})->makeHidden(['id'])->all(); })->makeHidden(['id'])->all();
$x = $this->writer->collection('webhooks'); $x = $this->writer->collection('webhooks');
$x->addItems($this->export_data['webhooks']); $x->addItems($this->export_data['webhooks']);
$this->export_data = null; $this->export_data = null;
$this->export_data['purchase_orders'] = $this->company->purchase_orders()->orderBy('number', 'DESC')->cursor()->map(function ($purchase_order) { $this->export_data['purchase_orders'] = $this->company->purchase_orders()->orderBy('number', 'DESC')->cursor()->map(function ($purchase_order) {
@ -578,9 +578,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('purchase_orders'); $x = $this->writer->collection('purchase_orders');
$x->addItems($this->export_data['purchase_orders']); $x->addItems($this->export_data['purchase_orders']);
$this->export_data = null; $this->export_data = null;
@ -591,9 +591,9 @@ $this->export_data = null;
})->all(); })->all();
$x = $this->writer->collection('purchase_order_invitations'); $x = $this->writer->collection('purchase_order_invitations');
$x->addItems($this->export_data['purchase_order_invitations']); $x->addItems($this->export_data['purchase_order_invitations']);
$this->export_data = null; $this->export_data = null;
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) { $this->export_data['bank_integrations'] = $this->company->bank_integrations()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) {
$bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']); $bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']);
@ -601,9 +601,9 @@ $this->export_data = null;
return $bank_integration->makeVisible(['id','user_id','company_id','account_id','hashed_id']); return $bank_integration->makeVisible(['id','user_id','company_id','account_id','hashed_id']);
})->all(); })->all();
$x = $this->writer->collection('bank_integrations'); $x = $this->writer->collection('bank_integrations');
$x->addItems($this->export_data['bank_integrations']); $x->addItems($this->export_data['bank_integrations']);
$this->export_data = null; $this->export_data = null;
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) { $this->export_data['bank_transactions'] = $this->company->bank_transactions()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) {
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','ninja_category_id','vendor_id']); $bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','ninja_category_id','vendor_id']);
@ -611,9 +611,9 @@ $this->export_data = null;
return $bank_transaction->makeVisible(['id','user_id','company_id']); return $bank_transaction->makeVisible(['id','user_id','company_id']);
})->all(); })->all();
$x = $this->writer->collection('bank_transactions'); $x = $this->writer->collection('bank_transactions');
$x->addItems($this->export_data['bank_transactions']); $x->addItems($this->export_data['bank_transactions']);
$this->export_data = null; $this->export_data = null;
$this->export_data['schedulers'] = $this->company->schedulers()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) { $this->export_data['schedulers'] = $this->company->schedulers()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) {
$scheduler = $this->transformArrayOfKeys($scheduler, ['company_id', 'user_id']); $scheduler = $this->transformArrayOfKeys($scheduler, ['company_id', 'user_id']);
@ -621,14 +621,14 @@ $this->export_data = null;
return $scheduler->makeVisible(['id','user_id','company_id']); return $scheduler->makeVisible(['id','user_id','company_id']);
})->all(); })->all();
$x = $this->writer->collection('schedulers'); $x = $this->writer->collection('schedulers');
$x->addItems($this->export_data['schedulers']); $x->addItems($this->export_data['schedulers']);
$this->export_data = null; $this->export_data = null;
//write to tmp and email to owner(); //write to tmp and email to owner();
$this->writer->end(); $this->writer->end();
$this->zipAndSend(); $this->zipAndSend();
@ -680,20 +680,20 @@ $this->writer->end();
$zip->close(); $zip->close();
Storage::disk(config('filesystems.default'))->put('backups/'.str_replace(".json", ".zip",$this->file_name), file_get_contents($zip_path)); Storage::disk(config('filesystems.default'))->put('backups/'.str_replace(".json", ".zip", $this->file_name), file_get_contents($zip_path));
if(file_exists($zip_path)) { if(file_exists($zip_path)) {
unlink($zip_path); unlink($zip_path);
} }
if(file_exists($this->file_name)){ if(file_exists($this->file_name)) {
unlink($this->file_name); unlink($this->file_name);
} }
if(Ninja::isSelfHost()) { if(Ninja::isSelfHost()) {
$storage_path = 'backups/'.str_replace(".json", ".zip",$this->file_name); $storage_path = 'backups/'.str_replace(".json", ".zip", $this->file_name);
} else { } else {
$storage_path = Storage::disk(config('filesystems.default'))->path('backups/'.str_replace(".json", ".zip",$this->file_name)); $storage_path = Storage::disk(config('filesystems.default'))->path('backups/'.str_replace(".json", ".zip", $this->file_name));
} }
$url = Cache::get($this->hash); $url = Cache::get($this->hash);

View File

@ -1,65 +0,0 @@
<?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\Jobs\Cron;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\RecurringInvoice;
use Illuminate\Foundation\Bus\Dispatchable;
/*@not used*/
class CompanyRecurringCron
{
use Dispatchable;
public $tries = 1;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle(): void
{
//multiDB environment, need to
foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db);
Company::where('is_disabled', 0)
->whereHas('recurring_invoices', function ($query) {
$query->where('next_send_date', '<=', now()->toDateTimeString())
->whereNotNull('next_send_date')
->whereNull('deleted_at')
->where('is_deleted', false)
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
->where('remaining_cycles', '!=', '0')
->whereHas('client', function ($query) {
$query->where('is_deleted', 0)
->where('deleted_at', null);
});
})
->cursor()->each(function ($company) {
SendCompanyRecurring::dispatch($company->id, $company->db);
});
}
}
}

View File

@ -51,7 +51,7 @@ class RecurringExpensesCron
Auth::logout(); Auth::logout();
if (! config('ninja.db.multi_db_enabled')) { if (! config('ninja.db.multi_db_enabled')) {
$recurring_expenses = RecurringExpense::where('next_send_date', '<=', now()->toDateTimeString()) $recurring_expenses = RecurringExpense::query()->where('next_send_date', '<=', now()->toDateTimeString())
->whereNotNull('next_send_date') ->whereNotNull('next_send_date')
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('status_id', RecurringInvoice::STATUS_ACTIVE) ->where('status_id', RecurringInvoice::STATUS_ACTIVE)
@ -76,7 +76,7 @@ class RecurringExpensesCron
foreach (MultiDB::$dbs as $db) { foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db); MultiDB::setDB($db);
$recurring_expenses = RecurringExpense::where('next_send_date', '<=', now()->toDateTimeString()) $recurring_expenses = RecurringExpense::query()->where('next_send_date', '<=', now()->toDateTimeString())
->whereNotNull('next_send_date') ->whereNotNull('next_send_date')
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('status_id', RecurringInvoice::STATUS_ACTIVE) ->where('status_id', RecurringInvoice::STATUS_ACTIVE)

View File

@ -48,7 +48,7 @@ class RecurringInvoicesCron
Auth::logout(); Auth::logout();
if (! config('ninja.db.multi_db_enabled')) { if (! config('ninja.db.multi_db_enabled')) {
$recurring_invoices = RecurringInvoice::where('status_id', RecurringInvoice::STATUS_ACTIVE) $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE)
->where('is_deleted', false) ->where('is_deleted', false)
->where('remaining_cycles', '!=', '0') ->where('remaining_cycles', '!=', '0')
->whereNotNull('next_send_date') ->whereNotNull('next_send_date')
@ -87,7 +87,7 @@ class RecurringInvoicesCron
foreach (MultiDB::$dbs as $db) { foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db); MultiDB::setDB($db);
$recurring_invoices = RecurringInvoice::where('status_id', RecurringInvoice::STATUS_ACTIVE) $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE)
->where('is_deleted', false) ->where('is_deleted', false)
->where('remaining_cycles', '!=', '0') ->where('remaining_cycles', '!=', '0')
->whereNull('deleted_at') ->whereNull('deleted_at')

View File

@ -1,74 +0,0 @@
<?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\Jobs\Cron;
use App\Jobs\RecurringInvoice\SendRecurring;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\RecurringInvoice;
use Illuminate\Foundation\Bus\Dispatchable;
/*@not used*/
class SendCompanyRecurring
{
use Dispatchable;
public $tries = 1;
/** @var \App\Models\Company $company */
public $company;
public function __construct(private int $company_id, private string $db)
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle(): void
{
MultiDB::setDB($this->db);
$recurring_invoices = Company::where('id', $this->company_id)
->where('is_disabled', 0)
->whereHas('recurring_invoices', function ($query) {
$query->where('next_send_date', '<=', now()->toDateTimeString())
->whereNotNull('next_send_date')
->whereNull('deleted_at')
->where('is_deleted', false)
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
->where('remaining_cycles', '!=', '0')
->whereHas('client', function ($query) {
$query->where('is_deleted', 0)
->where('deleted_at', null);
});
})
->cursor()->each(function ($recurring_invoice) {
nlog("Trying to send {$recurring_invoice->number}");
if ($recurring_invoice->company->stop_on_unpaid_recurring) {
if ($recurring_invoice->invoices()->whereIn('status_id', [2, 3])->where('is_deleted', 0)->where('balance', '>', 0)->exists()) {
return;
}
}
try {
(new SendRecurring($recurring_invoice, $recurring_invoice->company->db))->handle();
} catch (\Exception $e) {
nlog("Unable to sending recurring invoice {$recurring_invoice->id} ".$e->getMessage());
}
});
}
}

View File

@ -52,7 +52,7 @@ class SubscriptionCron
->whereNotNull('subscription_id') ->whereNotNull('subscription_id')
->cursor(); ->cursor();
$invoices->each(function ($invoice) { $invoices->each(function (Invoice $invoice) {
$subscription = $invoice->subscription; $subscription = $invoice->subscription;
$body = [ $body = [
@ -80,7 +80,7 @@ class SubscriptionCron
->whereNotNull('subscription_id') ->whereNotNull('subscription_id')
->cursor(); ->cursor();
$invoices->each(function ($invoice) { $invoices->each(function (Invoice $invoice) {
$subscription = $invoice->subscription; $subscription = $invoice->subscription;
$body = [ $body = [

View File

@ -99,10 +99,9 @@ class NinjaMailerJob implements ShouldQueue
} }
$this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name); $this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name);
}elseif(isset($this->nmo->invitation->user)){ } elseif(isset($this->nmo->invitation->user)) {
$this->nmo->mailable->replyTo($this->nmo->invitation->user->email, $this->nmo->invitation->user->present()->name()); $this->nmo->mailable->replyTo($this->nmo->invitation->user->email, $this->nmo->invitation->user->present()->name());
} } else {
else {
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name()); $this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
} }
@ -270,12 +269,12 @@ class NinjaMailerJob implements ShouldQueue
if(Ninja::isHosted() && $this->company->account->isPaid() && $this->nmo->settings->email_sending_method == 'default') { if(Ninja::isHosted() && $this->company->account->isPaid() && $this->nmo->settings->email_sending_method == 'default') {
//check if outlook. //check if outlook.
try{ try {
$email = $this->nmo->to_user->email; $email = $this->nmo->to_user->email;
$domain = explode("@", $email)[1] ?? ""; $domain = explode("@", $email)[1] ?? "";
$dns = dns_get_record($domain, DNS_MX); $dns = dns_get_record($domain, DNS_MX);
$server = $dns[0]["target"]; $server = $dns[0]["target"];
if(stripos($server, "outlook.com") !== false){ if(stripos($server, "outlook.com") !== false) {
$this->mailer = 'postmark'; $this->mailer = 'postmark';
$this->client_postmark_secret = config('services.postmark-outlook.token'); $this->client_postmark_secret = config('services.postmark-outlook.token');
@ -286,8 +285,7 @@ class NinjaMailerJob implements ShouldQueue
return $this; return $this;
} }
} } catch(\Exception $e) {
catch(\Exception $e){
nlog($e->getMessage()); nlog($e->getMessage());
} }
} }

View File

@ -16,7 +16,6 @@ namespace App\Jobs\Mail;
*/ */
class NinjaMailerObject class NinjaMailerObject
{ {
/* @var Illuminate\Mail\Mailable */ /* @var Illuminate\Mail\Mailable */
public $mailable; public $mailable;

View File

@ -34,7 +34,10 @@ use App\Notifications\Ninja\EmailBounceNotification;
class ProcessMailgunWebhook implements ShouldQueue class ProcessMailgunWebhook implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public $tries = 1; public $tries = 1;
@ -89,8 +92,9 @@ class ProcessMailgunWebhook implements ShouldQueue
{ {
nlog($this->request); nlog($this->request);
if(!$this->request['event-data']['tags'][0]) if(!$this->request['event-data']['tags'][0]) {
return; return;
}
MultiDB::findAndSetDbByCompanyKey($this->request['event-data']['tags'][0]); MultiDB::findAndSetDbByCompanyKey($this->request['event-data']['tags'][0]);
$company = Company::where('company_key', $this->request['event-data']['tags'][0])->first(); $company = Company::where('company_key', $this->request['event-data']['tags'][0])->first();
@ -128,8 +132,8 @@ class ProcessMailgunWebhook implements ShouldQueue
} }
} }
/* /*
{ {
"signature": { "signature": {
"token": "7f388cf8096aa0bca1477aee9d91e156c61f8fa8282c7f1c0c", "token": "7f388cf8096aa0bca1477aee9d91e156c61f8fa8282c7f1c0c",
"timestamp": "1705376308", "timestamp": "1705376308",
@ -170,8 +174,8 @@ class ProcessMailgunWebhook implements ShouldQueue
"my-var-2": "awesome" "my-var-2": "awesome"
} }
} }
} }
*/ */
private function processOpen() private function processOpen()
{ {
$this->invitation->opened_date = now(); $this->invitation->opened_date = now();
@ -180,8 +184,9 @@ class ProcessMailgunWebhook implements ShouldQueue
$sl = $this->getSystemLog($this->request['MessageID']); $sl = $this->getSystemLog($this->request['MessageID']);
/** Prevents Gmail tracking from firing inappropriately */ /** Prevents Gmail tracking from firing inappropriately */
if($this->request['signature']['timestamp'] < $sl->log['signature']['timestamp'] + 3) if($this->request['signature']['timestamp'] < $sl->log['signature']['timestamp'] + 3) {
return; return;
}
$event = [ $event = [
'bounce_id' => '', 'bounce_id' => '',
@ -201,8 +206,8 @@ class ProcessMailgunWebhook implements ShouldQueue
} }
/* /*
{ {
"signature": { "signature": {
"token": "70b91a64ed0f1bdf90fb9c6ea7e3c31d5792a3d0945ffc20fe", "token": "70b91a64ed0f1bdf90fb9c6ea7e3c31d5792a3d0945ffc20fe",
"timestamp": "1705376276", "timestamp": "1705376276",
@ -262,8 +267,8 @@ class ProcessMailgunWebhook implements ShouldQueue
"my-var-2": "awesome" "my-var-2": "awesome"
} }
} }
} }
*/ */
private function processDelivery() private function processDelivery()
{ {
$this->invitation->email_status = 'delivered'; $this->invitation->email_status = 'delivered';
@ -384,8 +389,8 @@ class ProcessMailgunWebhook implements ShouldQueue
} }
/* /*
{ {
"signature": { "signature": {
"token": "d7be371deef49c8b187119df295e3eb17fd1974d513a4be2cb", "token": "d7be371deef49c8b187119df295e3eb17fd1974d513a4be2cb",
"timestamp": "1705376380", "timestamp": "1705376380",
@ -423,8 +428,8 @@ class ProcessMailgunWebhook implements ShouldQueue
"my-var-2": "awesome" "my-var-2": "awesome"
} }
} }
} }
*/ */
private function processSpamComplaint() private function processSpamComplaint()
{ {
$this->invitation->email_status = 'spam'; $this->invitation->email_status = 'spam';

View File

@ -94,6 +94,7 @@ class UserEmailChanged implements ShouldQueue
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'settings' => $this->settings, 'settings' => $this->settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
} }
} }

View File

@ -233,7 +233,6 @@ class Import implements ShouldQueue
['name' => ctrans('texts.ready_to_do'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 2], ['name' => ctrans('texts.ready_to_do'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 2],
['name' => ctrans('texts.in_progress'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 3], ['name' => ctrans('texts.in_progress'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 3],
['name' => ctrans('texts.done'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 4], ['name' => ctrans('texts.done'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now(), 'status_order' => 4],
]; ];
TaskStatus::insert($task_statuses); TaskStatus::insert($task_statuses);

View File

@ -94,7 +94,7 @@ class VersionCheck implements ShouldQueue
Client::doesntHave('contacts') Client::doesntHave('contacts')
->cursor() ->cursor()
->each(function ($client) { ->each(function (Client $client) {
$new_contact = ClientContactFactory::create($client->company_id, $client->user_id); $new_contact = ClientContactFactory::create($client->company_id, $client->user_id);
$new_contact->client_id = $client->id; $new_contact->client_id = $client->id;
@ -107,7 +107,7 @@ class VersionCheck implements ShouldQueue
Vendor::doesntHave('contacts') Vendor::doesntHave('contacts')
->cursor() ->cursor()
->each(function ($vendor) { ->each(function (Vendor $vendor) {
$new_contact = VendorContactFactory::create($vendor->company_id, $vendor->user_id); $new_contact = VendorContactFactory::create($vendor->company_id, $vendor->user_id);
$new_contact->vendor_id = $vendor->id; $new_contact->vendor_id = $vendor->id;

View File

@ -37,8 +37,9 @@ class InvoiceFailedEmailNotification
{ {
MultiDB::setDb($event->company->db); MultiDB::setDb($event->company->db);
if(Cache::has("invoice_failed_email_notification_{$event->invitation->key}")) if(Cache::has("invoice_failed_email_notification_{$event->invitation->key}")) {
return; return;
}
$invoice = $event->invitation->invoice; $invoice = $event->invitation->invoice;

View File

@ -44,6 +44,7 @@ class ClientUnsubscribedObject
'settings' => $this->company->settings, 'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'text_body' => "\n\n".ctrans('texts.client_unsubscribed_help', ['client' => $this->contact->present()->name()])."\n\n", 'text_body' => "\n\n".ctrans('texts.client_unsubscribed_help', ['client' => $this->contact->present()->name()])."\n\n",
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
$mail_obj = new \stdClass(); $mail_obj = new \stdClass();

View File

@ -94,6 +94,7 @@ class EntityCreatedObject
'settings' => $this->company->settings, 'settings' => $this->company->settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => str_replace(['$view_button','$viewButton','$viewLink','$view_url'], '$view_url', $content), 'text_body' => str_replace(['$view_button','$viewButton','$viewLink','$view_url'], '$view_url', $content),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
} else { } else {
$this->entity->load('client.country', 'client.company'); $this->entity->load('client.country', 'client.company');
@ -181,6 +182,7 @@ class EntityCreatedObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => str_replace(['$view_button','$viewButton','$view_link','$view_button'], '$view_url', $content), 'text_body' => str_replace(['$view_button','$viewButton','$view_link','$view_button'], '$view_url', $content),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
} }
} }

View File

@ -152,6 +152,7 @@ class EntityFailedSendObject
"settings" => $settings, "settings" => $settings,
"whitelabel" => $this->company->account->isPaid() ? true : false, "whitelabel" => $this->company->account->isPaid() ? true : false,
"text_body" => str_replace("<br>", "\n", $content), "text_body" => str_replace("<br>", "\n", $content),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -12,6 +12,7 @@
namespace App\Mail\Admin; namespace App\Mail\Admin;
use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailable;
//@deprecated? //@deprecated?
class EntityNotificationMailer extends Mailable class EntityNotificationMailer extends Mailable
{ {

View File

@ -105,6 +105,7 @@ class EntityPaidObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -87,6 +87,8 @@ class EntitySentObject
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings, 'settings' => $this->company->settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
$mail_obj->markdown = 'email.admin.generic'; $mail_obj->markdown = 'email.admin.generic';
$mail_obj->tag = $this->company->company_key; $mail_obj->tag = $this->company->company_key;
@ -197,6 +199,8 @@ class EntitySentObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
} }
} }

View File

@ -116,6 +116,7 @@ class EntityViewedObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -76,6 +76,7 @@ class InventoryNotificationObject
'settings' => $this->product->company->settings, 'settings' => $this->product->company->settings,
'whitelabel' => $this->product->company->account->isPaid() ? true : false, 'whitelabel' => $this->product->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->product->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -99,6 +99,7 @@ class PaymentFailureObject
'button' => $this->use_react_url ? ctrans('texts.view_client') : ctrans('texts.login'), 'button' => $this->use_react_url ? ctrans('texts.view_client') : ctrans('texts.login'),
'additional_info' => $this->error, 'additional_info' => $this->error,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -92,6 +92,7 @@ class PurchaseOrderAcceptedObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -91,6 +91,7 @@ class QuoteApprovedObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -91,6 +91,8 @@ class QuoteExpiredObject
'settings' => $settings, 'settings' => $settings,
'whitelabel' => $this->company->account->isPaid() ? true : false, 'whitelabel' => $this->company->account->isPaid() ? true : false,
'text_body' => $content, 'text_body' => $content,
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
return $data; return $data;

View File

@ -41,6 +41,7 @@ class ResetPasswordObject
'settings' => $this->company->settings, 'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'text_body' => ctrans('texts.reset_password'), 'text_body' => ctrans('texts.reset_password'),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
$mail_obj = new \stdClass(); $mail_obj = new \stdClass();

View File

@ -53,6 +53,7 @@ class VerifyUserObject
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'signature' => $this->company->settings->email_signature, 'signature' => $this->company->settings->email_signature,
'text_body' => ctrans('texts.confirmation_message'), 'text_body' => ctrans('texts.confirmation_message'),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
$mail_obj = new \stdClass(); $mail_obj = new \stdClass();

View File

@ -52,7 +52,7 @@ class ClientStatement extends Mailable
public function content() public function content()
{ {
return new Content( return new Content(
view: 'email.template.client', view: $this->data['company']->account->isPremium() ? 'email.template.client_premium' : 'email.template.client',
text: 'email.template.text', text: 'email.template.text',
with: [ with: [
'text_body' => $this->data['body'], 'text_body' => $this->data['body'],

View File

@ -134,9 +134,9 @@ class InvoiceEmailEngine extends BaseEmailEngine
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->invoice->numberFormatter().'.pdf']]); $this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->invoice->numberFormatter().'.pdf']]);
} }
// $hash = Str::uuid(); // $hash = Str::uuid();
// $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]); // $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
// Cache::put($hash, $url, now()->addHour()); // Cache::put($hash, $url, now()->addHour());
//attach third party documents //attach third party documents
if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) { if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {

View File

@ -48,6 +48,7 @@ class ClientContactRequestCancellationObject
'signature' => $this->company->settings->email_signature, 'signature' => $this->company->settings->email_signature,
'settings' => $this->company->settings, 'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(), 'logo' => $this->company->present()->logo(),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]; ];
$mail_obj = new \stdClass(); $mail_obj = new \stdClass();

View File

@ -58,6 +58,7 @@ class OtpCode extends Mailable
'title' => ctrans('texts.otp_code_subject'), 'title' => ctrans('texts.otp_code_subject'),
'content' => ctrans('texts.otp_code_body', ['code' => $this->code]), 'content' => ctrans('texts.otp_code_body', ['code' => $this->code]),
'whitelabel' => $this->company->account->isPaid(), 'whitelabel' => $this->company->account->isPaid(),
'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
]); ]);
} }
} }

View File

@ -75,7 +75,7 @@ class TemplateEmail extends Mailable
$template_name = 'email.template.'.$this->build_email->getTemplate(); $template_name = 'email.template.'.$this->build_email->getTemplate();
if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') { if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') {
$template_name = 'email.template.client'; $template_name = $this->company->account->isPremium() ? 'email.template.client_premium' : 'email.template.client';
} }
if ($this->build_email->getTemplate() == 'custom') { if ($this->build_email->getTemplate() == 'custom') {

View File

@ -19,7 +19,6 @@ use Illuminate\Support\Facades\App;
class UserLoggedIn extends Mailable class UserLoggedIn extends Mailable
{ {
/** /**
* Create a new message instance. * Create a new message instance.
* *

View File

@ -72,7 +72,7 @@ class VendorTemplateEmail extends Mailable
$template_name = 'email.template.'.$this->build_email->getTemplate(); $template_name = 'email.template.'.$this->build_email->getTemplate();
if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') { if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') {
$template_name = 'email.template.client'; $template_name = $this->company->account->isPremium() ? 'email.template.client_premium' : 'email.template.client';
} }
if ($this->build_email->getTemplate() == 'custom') { if ($this->build_email->getTemplate() == 'custom') {

View File

@ -296,6 +296,7 @@ class Account extends BaseModel
public function isPremium(): bool public function isPremium(): bool
{ {
// return true;
return Ninja::isHosted() && $this->isPaidHostedClient() && !$this->isTrial() && Carbon::createFromTimestamp($this->created_at)->diffInMonths() > 2; return Ninja::isHosted() && $this->isPaidHostedClient() && !$this->isTrial() && Carbon::createFromTimestamp($this->created_at)->diffInMonths() > 2;
} }

View File

@ -328,8 +328,9 @@ class BaseModel extends Model
*/ */
public function parseHtmlVariables(string $field, array $variables): string public function parseHtmlVariables(string $field, array $variables): string
{ {
if(!$this->{$field}) if(!$this->{$field}) {
return ''; return '';
}
$section = strtr($this->{$field}, $variables['labels']); $section = strtr($this->{$field}, $variables['labels']);

View File

@ -201,7 +201,8 @@ class CompanyUser extends Pivot
* @return bool * @return bool
*/ */
public function portalType(): bool public function portalType(): bool
{ nlog(isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link); {
nlog(isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link);
return isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link; return isset($this->react_settings->react_notification_link) && $this->react_settings->react_notification_link;
} }

View File

@ -325,8 +325,9 @@ class Payment extends BaseModel
return '<h6><span class="badge badge-danger">'.ctrans('texts.payment_status_3').'</span></h6>'; return '<h6><span class="badge badge-danger">'.ctrans('texts.payment_status_3').'</span></h6>';
case self::STATUS_COMPLETED: case self::STATUS_COMPLETED:
if($this->amount > $this->applied) if($this->amount > $this->applied) {
return '<h6><span class="badge badge-info">' . ctrans('texts.partially_unapplied') . '</span></h6>'; return '<h6><span class="badge badge-info">' . ctrans('texts.partially_unapplied') . '</span></h6>';
}
return '<h6><span class="badge badge-info">'.ctrans('texts.payment_status_4').'</span></h6>'; return '<h6><span class="badge badge-info">'.ctrans('texts.payment_status_4').'</span></h6>';
case self::STATUS_PARTIALLY_REFUNDED: case self::STATUS_PARTIALLY_REFUNDED:

View File

@ -78,7 +78,6 @@ use Illuminate\Support\Carbon;
* @property-read \App\Models\User $user * @property-read \App\Models\User $user
* @property-read \App\Models\Vendor|null $vendor * @property-read \App\Models\Vendor|null $vendor
* @property-read \App\Models\ExpenseCategory|null $category * @property-read \App\Models\ExpenseCategory|null $category
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns) * @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
* @method static \Database\Factories\RecurringExpenseFactory factory($count = null, $state = []) * @method static \Database\Factories\RecurringExpenseFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|RecurringExpense filter(\App\Filters\QueryFilters $filters) * @method static \Illuminate\Database\Eloquent\Builder|RecurringExpense filter(\App\Filters\QueryFilters $filters)
@ -222,7 +221,7 @@ class RecurringExpense extends BaseModel
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id');
} }
public function company() public function company():\Illuminate\Database\Eloquent\Relations\BelongsTo
{ {
return $this->belongsTo(Company::class); return $this->belongsTo(Company::class);
} }

View File

@ -106,7 +106,6 @@ use Laracasts\Presenter\PresentableTrait;
* @property-read \App\Models\Subscription|null $subscription * @property-read \App\Models\Subscription|null $subscription
* @property-read \App\Models\User $user * @property-read \App\Models\User $user
* @property-read \App\Models\Vendor|null $vendor * @property-read \App\Models\Vendor|null $vendor
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns) * @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
* @method static \Database\Factories\RecurringInvoiceFactory factory($count = null, $state = []) * @method static \Database\Factories\RecurringInvoiceFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|RecurringInvoice filter(\App\Filters\QueryFilters $filters) * @method static \Illuminate\Database\Eloquent\Builder|RecurringInvoice filter(\App\Filters\QueryFilters $filters)
@ -343,16 +342,25 @@ class RecurringInvoice extends BaseModel
} }
} }
public function calculateStatus() /**
* CalculateStatus
*
* Calculates the status of the Recurring Invoice.
*
* We only apply the pending status on new models, we never revert an invoice back to
* pending.
* @param bool $new_model
* @return int
*/
public function calculateStatus(bool $new_model = false) //15-02-2024 - $new_model needed
{ {
if($this->remaining_cycles == 0) { if($this->remaining_cycles == 0) {
return self::STATUS_COMPLETED; return self::STATUS_COMPLETED;
} elseif ($this->status_id == self::STATUS_ACTIVE && Carbon::parse($this->next_send_date)->isFuture()) { } elseif ($new_model && $this->status_id == self::STATUS_ACTIVE && Carbon::parse($this->next_send_date)->isFuture())
return self::STATUS_PENDING; return self::STATUS_PENDING;
} else {
return $this->status_id; return $this->status_id;
}
} }

View File

@ -214,8 +214,9 @@ class CheckoutComPaymentDriver extends BaseDriver
{ {
$this->init(); $this->init();
if($this->company_gateway->update_details) if($this->company_gateway->update_details) {
$this->updateCustomer(); $this->updateCustomer();
}
$request = new RefundRequest(); $request = new RefundRequest();
$request->reference = "{$payment->transaction_reference} ".now(); $request->reference = "{$payment->transaction_reference} ".now();
@ -332,8 +333,9 @@ class CheckoutComPaymentDriver extends BaseDriver
public function updateCustomer($customer_id = null) public function updateCustomer($customer_id = null)
{ {
if(!$customer_id) if(!$customer_id) {
return; return;
}
try { try {

View File

@ -272,8 +272,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
//capture //capture
$orderID = $response['orderID']; $orderID = $response['orderID'];
if($this->company_gateway->require_shipping_address) if($this->company_gateway->require_shipping_address) {
{
$shipping_data = $shipping_data =
[[ [[

View File

@ -24,18 +24,6 @@ class ComposerServiceProvider extends ServiceProvider
public function boot() public function boot()
{ {
view()->composer('portal.*', PortalComposer::class); view()->composer('portal.*', PortalComposer::class);
// view()->composer(
// ['email.admin.generic', 'email.client.generic'],
// function ($view) {
// $view->with(
// 'template',
// Ninja::isHosted()
// );
// }
// );
} }
/** /**

View File

@ -365,7 +365,7 @@ class BaseRepository
$model = $model->calc()->getRecurringInvoice(); $model = $model->calc()->getRecurringInvoice();
$model->status_id = $model->calculateStatus(); $model->status_id = $model->calculateStatus($this->new_model);
if ($this->new_model) { if ($this->new_model) {
event('eloquent.created: App\Models\RecurringInvoice', $model); event('eloquent.created: App\Models\RecurringInvoice', $model);

View File

@ -89,7 +89,7 @@ class ClientContactRepository extends BaseRepository
->where('company_id', $client->company_id) ->where('company_id', $client->company_id)
->where('client_id', $client->id) ->where('client_id', $client->id)
->where('email', $update_contact->email)->cursor() ->where('email', $update_contact->email)->cursor()
->each(function ($saveable_contact) use ($update_contact){ ->each(function ($saveable_contact) use ($update_contact) {
$saveable_contact->password = $update_contact->password; $saveable_contact->password = $update_contact->password;
$saveable_contact->save(); $saveable_contact->save();
}); });

View File

@ -26,7 +26,8 @@ use Illuminate\Database\QueryException;
class ClientService class ClientService
{ {
use MakesDates, GeneratesCounter; use MakesDates;
use GeneratesCounter;
private string $client_start_date; private string $client_start_date;
@ -153,8 +154,9 @@ class ClientService
{ {
$x = 1; $x = 1;
if(isset($this->client->number)) if(isset($this->client->number)) {
return $this; return $this;
}
do { do {
try { try {

View File

@ -68,6 +68,7 @@ class AdminEmailMailable extends Mailable
'logo' => $this->email_object->company->present()->logo(), 'logo' => $this->email_object->company->present()->logo(),
'settings' => $this->email_object->settings, 'settings' => $this->email_object->settings,
'whitelabel' => $this->email_object->company->account->isPaid() ? true : false, 'whitelabel' => $this->email_object->company->account->isPaid() ? true : false,
'template' => $this->email_object->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin',
] ]
); );
} }

View File

@ -107,10 +107,10 @@ class EmailDefaults
match ($this->email->email_object->settings->email_style) { match ($this->email->email_object->settings->email_style) {
'plain' => $this->template = 'email.template.plain', 'plain' => $this->template = 'email.template.plain',
'light' => $this->template = 'email.template.client', 'light' => $this->template = $this->email->email_object->company->account->isPremium() ? 'email.template.client_premium' : 'email.template.client',
'dark' => $this->template = 'email.template.client', 'dark' => $this->template = $this->email->email_object->company->account->isPremium() ? 'email.template.client_premium' :'email.template.client',
'custom' => $this->template = 'email.template.custom', 'custom' => $this->template = 'email.template.custom',
default => $this->template = 'email.template.client', default => $this->template = $this->email->email_object->company->account->isPremium() ? 'email.template.client_premium' :'email.template.client',
}; };
$this->email->email_object->html_template = $this->template; $this->email->email_object->html_template = $this->template;
@ -211,17 +211,15 @@ class EmailDefaults
$reply_to_email = $this->email->company->owner()->email; $reply_to_email = $this->email->company->owner()->email;
$reply_to_name = $this->email->company->owner()->present()->name(); $reply_to_name = $this->email->company->owner()->present()->name();
if(str_contains($this->email->email_object->settings->reply_to_email, "@")){ if(str_contains($this->email->email_object->settings->reply_to_email, "@")) {
$reply_to_email = $this->email->email_object->settings->reply_to_email; $reply_to_email = $this->email->email_object->settings->reply_to_email;
} } elseif(isset($this->email->email_object->invitation->user)) {
elseif(isset($this->email->email_object->invitation->user)) {
$reply_to_email = $this->email->email_object->invitation->user->email; $reply_to_email = $this->email->email_object->invitation->user->email;
} }
if(strlen($this->email->email_object->settings->reply_to_name) > 3) { if(strlen($this->email->email_object->settings->reply_to_name) > 3) {
$reply_to_name =$this->email->email_object->settings->reply_to_name; $reply_to_name = $this->email->email_object->settings->reply_to_name;
} } elseif(isset($this->email->email_object->invitation->user)) {
elseif(isset($this->email->email_object->invitation->user)) {
$reply_to_name = $this->email->email_object->invitation->user->present()->name(); $reply_to_name = $this->email->email_object->invitation->user->present()->name();
} }

View File

@ -34,7 +34,6 @@ use CleverIt\UBL\Invoice\Price;
class RoEInvoice extends AbstractService class RoEInvoice extends AbstractService
{ {
public function __construct(public Invoice $invoice) public function __construct(public Invoice $invoice)
{ {
} }

View File

@ -18,7 +18,9 @@ use Illuminate\Database\QueryException;
class SendEmail class SendEmail
{ {
public function __construct(public Payment $payment, public ?ClientContact $contact) {} public function __construct(public Payment $payment, public ?ClientContact $contact)
{
}
/** /**
* Builds the correct template to send. * Builds the correct template to send.

View File

@ -46,14 +46,15 @@ class ChangePlanInvoice extends AbstractService
$invoice = $this->generateInvoice($refund); $invoice = $this->generateInvoice($refund);
if($refund >= $new_charge){ if($refund >= $new_charge) {
$invoice = $invoice->markPaid()->save(); $invoice = $invoice->markPaid()->save();
//generate new recurring invoice at this point as we know the user has succeeded with their upgrade. //generate new recurring invoice at this point as we know the user has succeeded with their upgrade.
} }
if($refund > $new_charge) if($refund > $new_charge) {
return $this->generateCredit($refund - $new_charge); return $this->generateCredit($refund - $new_charge);
}
return $invoice; return $invoice;
} }

View File

@ -21,7 +21,6 @@ use App\Repositories\SubscriptionRepository;
class InvoiceToRecurring extends AbstractService class InvoiceToRecurring extends AbstractService
{ {
protected \App\Services\Subscription\SubscriptionStatus $status; protected \App\Services\Subscription\SubscriptionStatus $status;
public function __construct(protected int $client_id, public Subscription $subscription, public array $bundle = []) public function __construct(protected int $client_id, public Subscription $subscription, public array $bundle = [])

View File

@ -19,7 +19,9 @@ use App\Services\AbstractService;
class SubscriptionStatus extends AbstractService class SubscriptionStatus extends AbstractService
{ {
public function __construct(public Subscription $subscription, protected RecurringInvoice $recurring_invoice) {} public function __construct(public Subscription $subscription, protected RecurringInvoice $recurring_invoice)
{
}
/** @var bool $is_trial */ /** @var bool $is_trial */
public bool $is_trial = false; public bool $is_trial = false;
@ -66,7 +68,7 @@ class SubscriptionStatus extends AbstractService
$this->refundable_invoice = $primary_invoice; $this->refundable_invoice = $primary_invoice;
return $primary_invoice ? max(0, round(($primary_invoice->paid_to_date * $this->getProRataRatio()),2)) : 0; return $primary_invoice ? max(0, round(($primary_invoice->paid_to_date * $this->getProRataRatio()), 2)) : 0;
} }
@ -76,7 +78,7 @@ class SubscriptionStatus extends AbstractService
* The ratio of days used / days in interval * The ratio of days used / days in interval
* @return float * @return float
*/ */
public function getProRataRatio():float public function getProRataRatio(): float
{ {
$subscription_interval_end_date = Carbon::parse($this->recurring_invoice->next_send_date_client); $subscription_interval_end_date = Carbon::parse($this->recurring_invoice->next_send_date_client);
@ -93,8 +95,9 @@ class SubscriptionStatus extends AbstractService
->orderBy('id', 'desc') ->orderBy('id', 'desc')
->first(); ->first();
if(!$primary_invoice) if(!$primary_invoice) {
return 0; return 0;
}
$subscription_start_date = Carbon::parse($primary_invoice->date)->startOfDay(); $subscription_start_date = Carbon::parse($primary_invoice->date)->startOfDay();
@ -140,8 +143,9 @@ class SubscriptionStatus extends AbstractService
private function checkTrial(): self private function checkTrial(): self
{ {
if(!$this->subscription->trial_enabled) if(!$this->subscription->trial_enabled) {
return $this->setIsTrial(false); return $this->setIsTrial(false);
}
$primary_invoice = Invoice::query() $primary_invoice = Invoice::query()
->where('company_id', $this->recurring_invoice->company_id) ->where('company_id', $this->recurring_invoice->company_id)
@ -170,8 +174,9 @@ class SubscriptionStatus extends AbstractService
*/ */
private function checkRefundable(): self private function checkRefundable(): self
{ {
if(!$this->recurring_invoice->subscription->refund_period || $this->recurring_invoice->subscription->refund_period === 0) if(!$this->recurring_invoice->subscription->refund_period || $this->recurring_invoice->subscription->refund_period === 0) {
return $this->setRefundable(false); return $this->setRefundable(false);
}
$primary_invoice = $this->recurring_invoice $primary_invoice = $this->recurring_invoice
->invoices() ->invoices()
@ -183,7 +188,7 @@ class SubscriptionStatus extends AbstractService
if($primary_invoice && if($primary_invoice &&
$primary_invoice->status_id == Invoice::STATUS_PAID && $primary_invoice->status_id == Invoice::STATUS_PAID &&
Carbon::parse($primary_invoice->date)->addSeconds($this->recurring_invoice->subscription->refund_period)->lte(now()->startOfDay()->addSeconds($primary_invoice->client->timezone_offset())) Carbon::parse($primary_invoice->date)->addSeconds($this->recurring_invoice->subscription->refund_period)->lte(now()->startOfDay()->addSeconds($primary_invoice->client->timezone_offset()))
){ ) {
return $this->setRefundable(true); return $this->setRefundable(true);
} }

View File

@ -38,10 +38,11 @@ class UpgradePrice extends AbstractService
->subscription ->subscription
->status($this->recurring_invoice); ->status($this->recurring_invoice);
if($this->status->is_in_good_standing) if($this->status->is_in_good_standing) {
$this->calculateUpgrade(); $this->calculateUpgrade();
else } else {
$this->upgrade_price = $this->subscription->price; $this->upgrade_price = $this->subscription->price;
}
return $this; return $this;
@ -70,10 +71,11 @@ class UpgradePrice extends AbstractService
private function getRefundableAmount(?Invoice $invoice, float $ratio): float private function getRefundableAmount(?Invoice $invoice, float $ratio): float
{ {
if (!$invoice || !$invoice->date || $invoice->status_id != Invoice::STATUS_PAID || $ratio == 0) if (!$invoice || !$invoice->date || $invoice->status_id != Invoice::STATUS_PAID || $ratio == 0) {
return 0; return 0;
}
return max(0, round(($invoice->paid_to_date*$ratio),2)); return max(0, round(($invoice->paid_to_date * $ratio), 2));
} }
private function getCredits(): float private function getCredits(): float
@ -82,7 +84,7 @@ class UpgradePrice extends AbstractService
$use_credit_setting = $this->recurring_invoice->client->getSetting('use_credits_payment'); $use_credit_setting = $this->recurring_invoice->client->getSetting('use_credits_payment');
if($use_credit_setting){ if($use_credit_setting) {
$outstanding_credits = Credit::query() $outstanding_credits = Credit::query()
->where('client_id', $this->recurring_invoice->client_id) ->where('client_id', $this->recurring_invoice->client_id)

View File

@ -745,8 +745,9 @@ class HtmlEngine
if((int)$this->client->country_id !== (int)$this->company->settings->country_id) { if((int)$this->client->country_id !== (int)$this->company->settings->country_id) {
$tax_label .= ctrans('texts.intracommunity_tax_info') . "<br>"; $tax_label .= ctrans('texts.intracommunity_tax_info') . "<br>";
if($this->entity_calc->getTotalTaxes() > 0) if($this->entity_calc->getTotalTaxes() > 0) {
$tax_label = ''; $tax_label = '';
}
} }

View File

@ -74,11 +74,13 @@ trait CleanLineItems
} }
if(isset($item['notes'])) if(isset($item['notes'])) {
$item['notes'] = str_replace("</", "<-", $item['notes']); $item['notes'] = str_replace("</", "<-", $item['notes']);
}
if(isset($item['product_key'])) if(isset($item['product_key'])) {
$item['product_key'] = str_replace("</", "<-", $item['product_key']); $item['product_key'] = str_replace("</", "<-", $item['product_key']);
}
} }

View File

@ -21,6 +21,15 @@ class TruthSource
public $company_token; public $company_token;
public $premium_hosted;
public function setPremiumHosted($premium_hosted)
{
$this->premium_hosted = $premium_hosted;
return $this;
}
public function setCompanyUser($company_user) public function setCompanyUser($company_user)
{ {
$this->company_user = $company_user; $this->company_user = $company_user;
@ -49,6 +58,11 @@ class TruthSource
return $this; return $this;
} }
public function getPremiumHosted()
{
return $this->premium_hosted;
}
public function getCompany() public function getCompany()
{ {
return $this->company; return $this->company;

169
composer.lock generated
View File

@ -707,16 +707,16 @@
}, },
{ {
"name": "amphp/socket", "name": "amphp/socket",
"version": "v2.2.2", "version": "v2.2.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/amphp/socket.git", "url": "https://github.com/amphp/socket.git",
"reference": "eb6c5e6baae5aebd9a209f50e81bff38c7efef97" "reference": "40c80bdc67a9f975ecb5f4083e3c84ef9f23eace"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/amphp/socket/zipball/eb6c5e6baae5aebd9a209f50e81bff38c7efef97", "url": "https://api.github.com/repos/amphp/socket/zipball/40c80bdc67a9f975ecb5f4083e3c84ef9f23eace",
"reference": "eb6c5e6baae5aebd9a209f50e81bff38c7efef97", "reference": "40c80bdc67a9f975ecb5f4083e3c84ef9f23eace",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -735,7 +735,7 @@
"amphp/phpunit-util": "^3", "amphp/phpunit-util": "^3",
"amphp/process": "^2", "amphp/process": "^2",
"phpunit/phpunit": "^9", "phpunit/phpunit": "^9",
"psalm/phar": "^5.4" "psalm/phar": "5.20"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -779,7 +779,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/amphp/socket/issues", "issues": "https://github.com/amphp/socket/issues",
"source": "https://github.com/amphp/socket/tree/v2.2.2" "source": "https://github.com/amphp/socket/tree/v2.2.3"
}, },
"funding": [ "funding": [
{ {
@ -787,7 +787,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2023-12-31T18:12:01+00:00" "time": "2024-02-13T21:03:09+00:00"
}, },
{ {
"name": "amphp/sync", "name": "amphp/sync",
@ -1343,16 +1343,16 @@
}, },
{ {
"name": "aws/aws-sdk-php", "name": "aws/aws-sdk-php",
"version": "3.298.3", "version": "3.298.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/aws/aws-sdk-php.git", "url": "https://github.com/aws/aws-sdk-php.git",
"reference": "70fde185df4a8dd99983a308b823991fb5b39060" "reference": "db225c3a1c5dabfbb5071349cfb7e4c396c3d9ec"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/70fde185df4a8dd99983a308b823991fb5b39060", "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/db225c3a1c5dabfbb5071349cfb7e4c396c3d9ec",
"reference": "70fde185df4a8dd99983a308b823991fb5b39060", "reference": "db225c3a1c5dabfbb5071349cfb7e4c396c3d9ec",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1432,9 +1432,9 @@
"support": { "support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues", "issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.298.3" "source": "https://github.com/aws/aws-sdk-php/tree/3.298.9"
}, },
"time": "2024-02-05T19:05:28+00:00" "time": "2024-02-13T19:08:16+00:00"
}, },
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",
@ -1717,16 +1717,16 @@
}, },
{ {
"name": "checkout/checkout-sdk-php", "name": "checkout/checkout-sdk-php",
"version": "3.0.20", "version": "3.0.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/checkout/checkout-sdk-php.git", "url": "https://github.com/checkout/checkout-sdk-php.git",
"reference": "4310ef994a663b925d1209f8c579f0965f5e14f8" "reference": "0195aa0153b79b3f8350509e54a5654e57f62bd3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/4310ef994a663b925d1209f8c579f0965f5e14f8", "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/0195aa0153b79b3f8350509e54a5654e57f62bd3",
"reference": "4310ef994a663b925d1209f8c579f0965f5e14f8", "reference": "0195aa0153b79b3f8350509e54a5654e57f62bd3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1779,9 +1779,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/checkout/checkout-sdk-php/issues", "issues": "https://github.com/checkout/checkout-sdk-php/issues",
"source": "https://github.com/checkout/checkout-sdk-php/tree/3.0.20" "source": "https://github.com/checkout/checkout-sdk-php/tree/3.0.21"
}, },
"time": "2024-01-10T13:50:01+00:00" "time": "2024-02-08T17:30:23+00:00"
}, },
{ {
"name": "clue/stream-filter", "name": "clue/stream-filter",
@ -3455,16 +3455,16 @@
}, },
{ {
"name": "google/apiclient-services", "name": "google/apiclient-services",
"version": "v0.334.0", "version": "v0.335.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/googleapis/google-api-php-client-services.git", "url": "https://github.com/googleapis/google-api-php-client-services.git",
"reference": "5d2ebd6199b34b4b207eff2118bb783ae7b6f413" "reference": "3e6cea8f43066378babdf00e718f01c7c55233fd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/5d2ebd6199b34b4b207eff2118bb783ae7b6f413", "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/3e6cea8f43066378babdf00e718f01c7c55233fd",
"reference": "5d2ebd6199b34b4b207eff2118bb783ae7b6f413", "reference": "3e6cea8f43066378babdf00e718f01c7c55233fd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3493,9 +3493,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/googleapis/google-api-php-client-services/issues", "issues": "https://github.com/googleapis/google-api-php-client-services/issues",
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.334.0" "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.335.0"
}, },
"time": "2024-02-04T01:06:40+00:00" "time": "2024-02-12T01:08:15+00:00"
}, },
{ {
"name": "google/auth", "name": "google/auth",
@ -5326,16 +5326,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v10.43.0", "version": "v10.44.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "4f7802dfc9993cb57cf69615491ce1a7eb2e9529" "reference": "1199dbe361787bbe9648131a79f53921b4148cf6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/4f7802dfc9993cb57cf69615491ce1a7eb2e9529", "url": "https://api.github.com/repos/laravel/framework/zipball/1199dbe361787bbe9648131a79f53921b4148cf6",
"reference": "4f7802dfc9993cb57cf69615491ce1a7eb2e9529", "reference": "1199dbe361787bbe9648131a79f53921b4148cf6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5383,6 +5383,7 @@
"conflict": { "conflict": {
"carbonphp/carbon-doctrine-types": ">=3.0", "carbonphp/carbon-doctrine-types": ">=3.0",
"doctrine/dbal": ">=4.0", "doctrine/dbal": ">=4.0",
"phpunit/phpunit": ">=11.0.0",
"tightenco/collect": "<5.5.33" "tightenco/collect": "<5.5.33"
}, },
"provide": { "provide": {
@ -5527,7 +5528,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-01-30T16:25:02+00:00" "time": "2024-02-13T16:01:16+00:00"
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
@ -5709,16 +5710,16 @@
}, },
{ {
"name": "laravel/socialite", "name": "laravel/socialite",
"version": "v5.11.0", "version": "v5.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/socialite.git", "url": "https://github.com/laravel/socialite.git",
"reference": "4f6a8af6f3f7c18da03d19842dd0514315501c10" "reference": "ffeeb2cdf723b4c88b25479968e2d3a61a83dbe5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/socialite/zipball/4f6a8af6f3f7c18da03d19842dd0514315501c10", "url": "https://api.github.com/repos/laravel/socialite/zipball/ffeeb2cdf723b4c88b25479968e2d3a61a83dbe5",
"reference": "4f6a8af6f3f7c18da03d19842dd0514315501c10", "reference": "ffeeb2cdf723b4c88b25479968e2d3a61a83dbe5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5775,7 +5776,7 @@
"issues": "https://github.com/laravel/socialite/issues", "issues": "https://github.com/laravel/socialite/issues",
"source": "https://github.com/laravel/socialite" "source": "https://github.com/laravel/socialite"
}, },
"time": "2023-12-02T18:22:36+00:00" "time": "2024-02-11T18:29:55+00:00"
}, },
{ {
"name": "laravel/tinker", "name": "laravel/tinker",
@ -8024,16 +8025,16 @@
}, },
{ {
"name": "nordigen/nordigen-php", "name": "nordigen/nordigen-php",
"version": "1.1.1", "version": "1.1.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nordigen/nordigen-php.git", "url": "https://github.com/nordigen/nordigen-php.git",
"reference": "1770384ceb8042c7275cb0e404d8b7131bdccc56" "reference": "573a9935fc7444ba84d0cdd7dba46e033dbf7bd5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nordigen/nordigen-php/zipball/1770384ceb8042c7275cb0e404d8b7131bdccc56", "url": "https://api.github.com/repos/nordigen/nordigen-php/zipball/573a9935fc7444ba84d0cdd7dba46e033dbf7bd5",
"reference": "1770384ceb8042c7275cb0e404d8b7131bdccc56", "reference": "573a9935fc7444ba84d0cdd7dba46e033dbf7bd5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8073,9 +8074,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nordigen/nordigen-php/issues", "issues": "https://github.com/nordigen/nordigen-php/issues",
"source": "https://github.com/nordigen/nordigen-php/tree/1.1.1" "source": "https://github.com/nordigen/nordigen-php/tree/1.1.2"
}, },
"time": "2023-06-22T10:53:06+00:00" "time": "2024-02-13T14:06:32+00:00"
}, },
{ {
"name": "nunomaduro/termwind", "name": "nunomaduro/termwind",
@ -15831,36 +15832,36 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "barryvdh/laravel-debugbar", "name": "barryvdh/laravel-debugbar",
"version": "v3.9.2", "version": "v3.10.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git", "url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "bfd0131c146973cab164e50f5cdd8a67cc60cab1" "reference": "09d3dc77d7dc1b063e3728a6029c39ee0fbebf1d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/bfd0131c146973cab164e50f5cdd8a67cc60cab1", "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/09d3dc77d7dc1b063e3728a6029c39ee0fbebf1d",
"reference": "bfd0131c146973cab164e50f5cdd8a67cc60cab1", "reference": "09d3dc77d7dc1b063e3728a6029c39ee0fbebf1d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"illuminate/routing": "^9|^10", "illuminate/routing": "^9|^10|^11",
"illuminate/session": "^9|^10", "illuminate/session": "^9|^10|^11",
"illuminate/support": "^9|^10", "illuminate/support": "^9|^10|^11",
"maximebf/debugbar": "^1.18.2", "maximebf/debugbar": "~1.20.1",
"php": "^8.0", "php": "^8.0",
"symfony/finder": "^6" "symfony/finder": "^6|^7"
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "^1.3.3", "mockery/mockery": "^1.3.3",
"orchestra/testbench-dusk": "^5|^6|^7|^8", "orchestra/testbench-dusk": "^5|^6|^7|^8|^9",
"phpunit/phpunit": "^8.5.30|^9.0", "phpunit/phpunit": "^8.5.30|^9.0",
"squizlabs/php_codesniffer": "^3.5" "squizlabs/php_codesniffer": "^3.5"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.8-dev" "dev-master": "3.10-dev"
}, },
"laravel": { "laravel": {
"providers": [ "providers": [
@ -15899,7 +15900,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/barryvdh/laravel-debugbar/issues", "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.9.2" "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.10.4"
}, },
"funding": [ "funding": [
{ {
@ -15911,7 +15912,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2023-08-25T18:43:57+00:00" "time": "2024-02-14T08:52:12+00:00"
}, },
{ {
"name": "barryvdh/laravel-ide-helper", "name": "barryvdh/laravel-ide-helper",
@ -16507,16 +16508,16 @@
}, },
{ {
"name": "fidry/cpu-core-counter", "name": "fidry/cpu-core-counter",
"version": "1.0.0", "version": "1.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/theofidry/cpu-core-counter.git", "url": "https://github.com/theofidry/cpu-core-counter.git",
"reference": "85193c0b0cb5c47894b5eaec906e946f054e7077" "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/85193c0b0cb5c47894b5eaec906e946f054e7077", "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42",
"reference": "85193c0b0cb5c47894b5eaec906e946f054e7077", "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -16556,7 +16557,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/theofidry/cpu-core-counter/issues", "issues": "https://github.com/theofidry/cpu-core-counter/issues",
"source": "https://github.com/theofidry/cpu-core-counter/tree/1.0.0" "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0"
}, },
"funding": [ "funding": [
{ {
@ -16564,7 +16565,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2023-09-17T21:38:23+00:00" "time": "2024-02-07T09:43:46+00:00"
}, },
{ {
"name": "filp/whoops", "name": "filp/whoops",
@ -16884,16 +16885,16 @@
}, },
{ {
"name": "larastan/larastan", "name": "larastan/larastan",
"version": "v2.8.1", "version": "v2.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/larastan/larastan.git", "url": "https://github.com/larastan/larastan.git",
"reference": "b7cc6a29c457a7d4f3de90466392ae9ad3e17022" "reference": "35fa9cbe1895e76215bbe74571a344f2705fbe01"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/larastan/larastan/zipball/b7cc6a29c457a7d4f3de90466392ae9ad3e17022", "url": "https://api.github.com/repos/larastan/larastan/zipball/35fa9cbe1895e76215bbe74571a344f2705fbe01",
"reference": "b7cc6a29c457a7d4f3de90466392ae9ad3e17022", "reference": "35fa9cbe1895e76215bbe74571a344f2705fbe01",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -16961,7 +16962,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/larastan/larastan/issues", "issues": "https://github.com/larastan/larastan/issues",
"source": "https://github.com/larastan/larastan/tree/v2.8.1" "source": "https://github.com/larastan/larastan/tree/v2.9.0"
}, },
"funding": [ "funding": [
{ {
@ -16981,26 +16982,26 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2024-01-08T09:11:17+00:00" "time": "2024-02-13T11:49:22+00:00"
}, },
{ {
"name": "maximebf/debugbar", "name": "maximebf/debugbar",
"version": "v1.19.1", "version": "v1.20.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/maximebf/php-debugbar.git", "url": "https://github.com/maximebf/php-debugbar.git",
"reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523" "reference": "06ebf922ccedfa4cc43015825697ee8c1fb80f7e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/03dd40a1826f4d585ef93ef83afa2a9874a00523", "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/06ebf922ccedfa4cc43015825697ee8c1fb80f7e",
"reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523", "reference": "06ebf922ccedfa4cc43015825697ee8c1fb80f7e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1|^8", "php": "^7.1|^8",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/var-dumper": "^4|^5|^6" "symfony/var-dumper": "^4|^5|^6|^7"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": ">=7.5.20 <10.0", "phpunit/phpunit": ">=7.5.20 <10.0",
@ -17014,7 +17015,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.18-dev" "dev-master": "1.20-dev"
} }
}, },
"autoload": { "autoload": {
@ -17045,9 +17046,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/maximebf/php-debugbar/issues", "issues": "https://github.com/maximebf/php-debugbar/issues",
"source": "https://github.com/maximebf/php-debugbar/tree/v1.19.1" "source": "https://github.com/maximebf/php-debugbar/tree/v1.20.1"
}, },
"time": "2023-10-12T08:10:52+00:00" "time": "2024-02-13T19:03:14+00:00"
}, },
{ {
"name": "mockery/mockery", "name": "mockery/mockery",
@ -17488,16 +17489,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.10.57", "version": "1.10.58",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "1627b1d03446904aaa77593f370c5201d2ecc34e" "reference": "a23518379ec4defd9e47cbf81019526861623ec2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/1627b1d03446904aaa77593f370c5201d2ecc34e", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a23518379ec4defd9e47cbf81019526861623ec2",
"reference": "1627b1d03446904aaa77593f370c5201d2ecc34e", "reference": "a23518379ec4defd9e47cbf81019526861623ec2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -17546,7 +17547,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-01-24T11:51:34+00:00" "time": "2024-02-12T20:02:57+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -19101,16 +19102,16 @@
}, },
{ {
"name": "spatie/laravel-ignition", "name": "spatie/laravel-ignition",
"version": "2.4.1", "version": "2.4.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/spatie/laravel-ignition.git", "url": "https://github.com/spatie/laravel-ignition.git",
"reference": "005e1e7b1232f3b22d7e7be3f602693efc7dba67" "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/005e1e7b1232f3b22d7e7be3f602693efc7dba67", "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/351504f4570e32908839fc5a2dc53bf77d02f85e",
"reference": "005e1e7b1232f3b22d7e7be3f602693efc7dba67", "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -19189,7 +19190,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-01-12T13:14:58+00:00" "time": "2024-02-09T16:08:40+00:00"
}, },
{ {
"name": "spaze/phpstan-stripe", "name": "spaze/phpstan-stripe",

View File

@ -17,8 +17,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true), 'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION', '5.8.24'), 'app_version' => env('APP_VERSION', '5.8.25'),
'app_tag' => env('APP_TAG', '5.8.24'), 'app_tag' => env('APP_TAG', '5.8.25'),
'minimum_client_version' => '5.0.16', 'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1', 'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false), 'api_secret' => env('API_SECRET', false),

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,6 @@
$email_alignment = isset($settings->email_alignment) ? $settings->email_alignment : 'center'; $email_alignment = isset($settings->email_alignment) ? $settings->email_alignment : 'center';
@endphp @endphp
<!DOCTYPE html <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace Tests\Feature; namespace Tests\Feature\PaymentLink;
use Tests\TestCase; use Tests\TestCase;
use App\Models\Invoice; use App\Models\Invoice;