Compare commits
78 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
29bfbaf644 | |
|
|
27dd9907f3 | |
|
|
5a188ac355 | |
|
|
cfc41eb29a | |
|
|
e58f19f593 | |
|
|
e8336c85d7 | |
|
|
117709e551 | |
|
|
70dea557f5 | |
|
|
084f0fea25 | |
|
|
256555c952 | |
|
|
9b98d45d3b | |
|
|
c3b5a972a1 | |
|
|
7e1a6bc1c7 | |
|
|
0a7744a70e | |
|
|
1252cdf7ae | |
|
|
af926a394c | |
|
|
c5c9c4325e | |
|
|
3d3b5f6938 | |
|
|
ff92756dbc | |
|
|
a141ca1549 | |
|
|
bf8041ab7c | |
|
|
8bc1513591 | |
|
|
63e6f75a24 | |
|
|
5482f44bea | |
|
|
81ec3986ca | |
|
|
1a3badf748 | |
|
|
c7e79fe673 | |
|
|
8d23ba14d4 | |
|
|
1836ccc434 | |
|
|
94b628b6eb | |
|
|
67df175525 | |
|
|
47f33c8691 | |
|
|
6a0fff10ae | |
|
|
a447b6a20b | |
|
|
f7961ecb61 | |
|
|
37c74ee18c | |
|
|
555eb80018 | |
|
|
1e8727c4a4 | |
|
|
74f71d61d6 | |
|
|
8a137329d4 | |
|
|
c02c87765b | |
|
|
7393360db3 | |
|
|
f7055b516e | |
|
|
ee775e58a0 | |
|
|
5ff70dbeae | |
|
|
3791469c31 | |
|
|
1a86d5445b | |
|
|
442ff42ceb | |
|
|
b94316dbed | |
|
|
14fd4063f5 | |
|
|
97f2e70f5d | |
|
|
edd0de38ca | |
|
|
d53e1012af | |
|
|
5895c1b0ed | |
|
|
aa918f7ec0 | |
|
|
33078ee86c | |
|
|
6c8c270c2f | |
|
|
5afd3b85bc | |
|
|
dab787c3ae | |
|
|
03a39f33b8 | |
|
|
cbc5cb5f9b | |
|
|
4127eb32f9 | |
|
|
bf5359cb72 | |
|
|
d42735f2ee | |
|
|
ea663394b1 | |
|
|
b93ec6dd93 | |
|
|
a431dd43d4 | |
|
|
1c5c568251 | |
|
|
604ba82f8f | |
|
|
c8e0cdd090 | |
|
|
54ba4349f6 | |
|
|
0865ab3c3e | |
|
|
fc8cb7af36 | |
|
|
46de411160 | |
|
|
ff50e3c9d9 | |
|
|
fdf7d2d3cf | |
|
|
dd60eb3b58 | |
|
|
1f4fae314c |
|
|
@ -1,3 +1,4 @@
|
|||
# Invoice Ninja Code of Conduct
|
||||
|
||||
The development team has invested a tremendous amount of time and energy into this project. While we appreciate that bugs can be frustrating we ask that our community refrain from insults and snide remarks. We're happy to provide support to both our hosted and selfhosted communities but ask that feedback is always polite.
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ A good bug report shouldn't leave others needing to chase you up for more inform
|
|||
|
||||
#### How Do I Submit a Good Bug Report?
|
||||
|
||||
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <contact@invoiceninja.com>.
|
||||
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <>.
|
||||
|
||||
|
||||
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
|
||||
|
|
@ -116,4 +116,4 @@ All PRs should be created against the v5-develop branch.
|
|||
|
||||
|
||||
## Attribution
|
||||
This guide is based on the **contributing.md**. [Make your own](https://contributing.md/)!
|
||||
This guide is based on the **contributing.md**. [Make your own](https://contributing.md/)!
|
||||
|
|
|
|||
|
|
@ -179,4 +179,4 @@ For further information on responsible disclosure please read [here](https://che
|
|||
|
||||
## License
|
||||
Invoice Ninja is released under the Elastic License.
|
||||
See [LICENSE](LICENSE) for details.
|
||||
See [LICENSE](LICENSE) for details.
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
## Security
|
||||
|
||||
If you find a security issue with this application, please send an email to contact@invoiceninja.com.
|
||||
Please follow responsible disclosure procedures if you detect an issue.
|
||||
For further information on responsible disclosure please read [here](https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html).
|
||||
|
|
@ -1 +1 @@
|
|||
5.12.23
|
||||
5.11.70
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -38,8 +37,8 @@ class ClientSyncCast implements CastsAttributes
|
|||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\InvoiceBackup;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class InvoiceBackupCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return new InvoiceBackup();
|
||||
}
|
||||
|
||||
$data = json_decode($value, true) ?? [];
|
||||
|
||||
return InvoiceBackup::fromArray($data);
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
// Ensure we're dealing with our object type
|
||||
if (! $value instanceof InvoiceBackup) {
|
||||
throw new \InvalidArgumentException('Value must be an InvoiceBackup instance.');
|
||||
}
|
||||
|
||||
return [
|
||||
$key => json_encode([
|
||||
'guid' => $value->guid,
|
||||
'cancellation' => $value->cancellation ? [
|
||||
'adjustment' => $value->cancellation->adjustment,
|
||||
'status_id' => $value->cancellation->status_id,
|
||||
] : [],
|
||||
'parent_invoice_id' => $value->parent_invoice_id,
|
||||
'parent_invoice_number' => $value->parent_invoice_number,
|
||||
'document_type' => $value->document_type,
|
||||
'child_invoice_ids' => $value->child_invoice_ids->toArray(),
|
||||
'redirect' => $value->redirect,
|
||||
'adjustable_amount' => $value->adjustable_amount,
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -19,6 +18,7 @@ class InvoiceSyncCast implements CastsAttributes
|
|||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
if (is_null($value)) {
|
||||
return null; // Return null if the value is null
|
||||
}
|
||||
|
|
@ -29,24 +29,28 @@ class InvoiceSyncCast implements CastsAttributes
|
|||
return null;
|
||||
}
|
||||
|
||||
$is = new InvoiceSync();
|
||||
$is->qb_id = $data['qb_id'];
|
||||
|
||||
$is = new InvoiceSync($data);
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'qb_id' => $value->qb_id,
|
||||
];
|
||||
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
];
|
||||
|
||||
|
||||
return [
|
||||
$key => json_encode($data)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class PaymentSyncCast implements CastsAttributes
|
|||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -39,10 +38,10 @@ class ProductSyncCast implements CastsAttributes
|
|||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\TransactionEventMetadata;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class TransactionEventMetadataCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new TransactionEventMetadata($data);
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
return [
|
||||
$key => json_encode($value->toArray())
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -87,7 +86,7 @@ class CheckData extends Command
|
|||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:check-data {--database=} {--fix=} {--portal_url=} {--client_id=} {--vendor_id=} {--paid_to_date=} {--client_balance=} {--ledger_balance=} {--balance_status=} {--bank_transaction=} {--line_items=} {--payment_balance=} {--tasks=}';
|
||||
protected $signature = 'ninja:check-data {--database=} {--fix=} {--portal_url=} {--client_id=} {--vendor_id=} {--paid_to_date=} {--client_balance=} {--ledger_balance=} {--balance_status=} {--bank_transaction=} {--line_items=} {--payment_balance=}';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
|
@ -118,7 +117,6 @@ class CheckData extends Command
|
|||
config(['database.default' => $database]);
|
||||
}
|
||||
|
||||
$this->checkTaskTimeLogs();
|
||||
$this->checkInvoiceBalances();
|
||||
$this->checkClientBalanceEdgeCases();
|
||||
$this->checkPaidToDatesNew();
|
||||
|
|
@ -181,37 +179,6 @@ class CheckData extends Command
|
|||
$this->log .= $str."\n";
|
||||
}
|
||||
|
||||
private function checkTaskTimeLogs()
|
||||
{
|
||||
\App\Models\Task::query()->cursor()->each(function ($task) {
|
||||
$time_log = json_decode($task->time_log, true);
|
||||
|
||||
foreach($time_log as &$log){
|
||||
if(count($log) > 4){
|
||||
|
||||
$this->logMessage("Task #{$task->id} has a time log with more than 4 elements");
|
||||
|
||||
if($this->option('tasks') == 'true'){
|
||||
$log = [(int)$log[0], (int)$log[1], (string)$log[2], (bool)$log[3]];
|
||||
}
|
||||
}
|
||||
elseif(count($log) == 4){
|
||||
|
||||
if($this->option('tasks') == 'true'){
|
||||
$log = [(int)$log[0], (int)$log[1], (string)$log[2], (bool)$log[3]];
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($log); // Unset the reference variable
|
||||
|
||||
if($this->option('tasks') == 'true'){
|
||||
$task->time_log = json_encode($time_log);
|
||||
$task->saveQuietly();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private function checkCompanyTokens()
|
||||
{
|
||||
CompanyUser::query()->cursor()->each(function ($cu) {
|
||||
|
|
@ -623,7 +590,7 @@ class CheckData extends Command
|
|||
|
||||
private function clientCreditPaymentablesNew($client)
|
||||
{
|
||||
|
||||
|
||||
$results = \DB::select("
|
||||
SELECT
|
||||
SUM(paymentables.amount - paymentables.refunded) as credit_payment
|
||||
|
|
@ -970,14 +937,14 @@ class CheckData extends Command
|
|||
public function checkClientSettings()
|
||||
{
|
||||
if ($this->option('fix') == 'true') {
|
||||
Client::query()->withTrashed()->whereNull('country_id')->orWhere('country_id', 0)->cursor()->each(function ($client) {
|
||||
Client::query()->whereNull('country_id')->orWhere('country_id', 0)->cursor()->each(function ($client) {
|
||||
$client->country_id = $client->company->settings->country_id;
|
||||
$client->saveQuietly();
|
||||
|
||||
$this->logMessage("Fixing country for # {$client->id}");
|
||||
});
|
||||
|
||||
Client::query()->withTrashed()->whereNull("settings->currency_id")->orWhereJsonContains('settings', ['currency_id' => ''])->cursor()->each(function ($client) {
|
||||
Client::query()->whereNull("settings->currency_id")->orWhereJsonContains('settings', ['currency_id' => ''])->cursor()->each(function ($client) {
|
||||
$settings = $client->settings;
|
||||
$settings->currency_id = (string)$client->company->settings->currency_id;
|
||||
$client->settings = $settings;
|
||||
|
|
@ -987,7 +954,7 @@ class CheckData extends Command
|
|||
|
||||
});
|
||||
|
||||
Payment::withTrashed()->withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment) {
|
||||
Payment::withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment) {
|
||||
$payment->exchange_rate = 1;
|
||||
$payment->saveQuietly();
|
||||
|
||||
|
|
@ -1000,11 +967,11 @@ class CheckData extends Command
|
|||
})
|
||||
->cursor()
|
||||
->each(function ($p) {
|
||||
$p->currency_id = $p->client->settings->currency_id ?? $p->company->settings->currency_id;
|
||||
$p->currency_id = $p->client->settings->currency_id;
|
||||
$p->saveQuietly();
|
||||
|
||||
|
||||
$this->logMessage("Fixing currency for # {$p->id} with new currency {$p->currency_id}");
|
||||
$this->logMessage("Fixing currency for # {$p->id}");
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -1015,7 +982,7 @@ class CheckData extends Command
|
|||
$c->subdomain = MultiDB::randomSubdomainGenerator();
|
||||
$c->save();
|
||||
|
||||
$this->logMessage("Fixing subdomain for # {$c->id} with new subdomain {$c->subdomain}");
|
||||
$this->logMessage("Fixing subdomain for # {$c->id}");
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -1076,7 +1043,7 @@ class CheckData extends Command
|
|||
public function checkVendorSettings()
|
||||
{
|
||||
if ($this->option('fix') == 'true') {
|
||||
Vendor::query()->withTrashed()->whereNull('currency_id')->orWhere('currency_id', '')->cursor()->each(function ($vendor) {
|
||||
Vendor::query()->whereNull('currency_id')->orWhere('currency_id', '')->cursor()->each(function ($vendor) {
|
||||
$vendor->currency_id = $vendor->company->settings->currency_id;
|
||||
$vendor->saveQuietly();
|
||||
|
||||
|
|
@ -1174,7 +1141,7 @@ class CheckData extends Command
|
|||
$bt->invoice_ids = collect($bt->payment->invoices)->pluck('hashed_id')->implode(',');
|
||||
$bt->save();
|
||||
|
||||
$this->logMessage("Fixing - {$bt->id} with new invoice IDs {$bt->invoice_ids}");
|
||||
$this->logMessage("Fixing - {$bt->id}");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1195,7 +1162,7 @@ class CheckData extends Command
|
|||
$c->send_email = false;
|
||||
$c->saveQuietly();
|
||||
|
||||
$this->logMessage("Fixing - {$c->id} with new send email {$c->send_email}");
|
||||
$this->logMessage("Fixing - {$c->id}");
|
||||
|
||||
});
|
||||
}
|
||||
|
|
@ -1234,11 +1201,11 @@ class CheckData extends Command
|
|||
|
||||
if ($this->option('fix') == 'true') {
|
||||
|
||||
$p->cursor()->each(function ($payment) {
|
||||
$payment->currency_id = $payment->client->settings->currency_id ?? $payment->company->settings->currency_id;
|
||||
$payment->saveQuietly();
|
||||
$p->cursor()->each(function ($c) {
|
||||
$c->currency_id = $c->client->settings->currency_id ?? $c->company->settings->currency_id;
|
||||
$c->saveQuietly();
|
||||
|
||||
$this->logMessage("Fixing payment ID - {$payment->id} with new currency {$payment->currency_id}");
|
||||
$this->logMessage("Fixing - {$c->id}");
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -33,7 +32,6 @@ use App\Models\TaxRate;
|
|||
use App\Libraries\MultiDB;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\Subscription;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\VendorContact;
|
||||
use App\Models\CompanyGateway;
|
||||
|
|
@ -144,12 +142,6 @@ class CreateSingleAccount extends Command
|
|||
'portal_domain' => 'http://ninja.test:8000',
|
||||
'track_inventory' => true
|
||||
]);
|
||||
|
||||
$custom_fields = new \stdClass();
|
||||
$custom_fields->client1 = 'CKey|single_line_text';
|
||||
$custom_fields->client2 = 'AKey|single_line_text';
|
||||
$company->custom_fields = $custom_fields;
|
||||
|
||||
$faker = \Faker\Factory::create();
|
||||
|
||||
$settings = $company->settings;
|
||||
|
|
@ -263,11 +255,7 @@ class CreateSingleAccount extends Command
|
|||
'company_id' => $company->id,
|
||||
'name' => 'cypress'
|
||||
]);
|
||||
|
||||
$client->custom_value1 = $company->company_key;
|
||||
$client->custom_value2 = $account->key;
|
||||
$client->save();
|
||||
|
||||
|
||||
ClientContact::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $client->id,
|
||||
|
|
@ -418,8 +406,8 @@ class CreateSingleAccount extends Command
|
|||
'company_id' => $company->id,
|
||||
'product_key' => 'pro_plan',
|
||||
'notes' => 'The Pro Plan',
|
||||
'cost' => 12,
|
||||
'price' => 12,
|
||||
'cost' => 10,
|
||||
'price' => 10,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
|
@ -428,38 +416,8 @@ class CreateSingleAccount extends Command
|
|||
'company_id' => $company->id,
|
||||
'product_key' => 'enterprise_plan',
|
||||
'notes' => 'The Enterprise Plan',
|
||||
'cost' => 16,
|
||||
'price' => 16,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$pe5 = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'enterprise_plan_5',
|
||||
'notes' => 'The Enterprise Plan 5',
|
||||
'cost' => 28,
|
||||
'price' => 28,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$pe10 = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'enterprise_plan_10',
|
||||
'notes' => 'The Enterprise Plan 10',
|
||||
'cost' => 56,
|
||||
'price' => 56,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$pe20 = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'enterprise_plan_20',
|
||||
'notes' => 'The Enterprise Plan 20',
|
||||
'cost' => 112,
|
||||
'price' => 112,
|
||||
'cost' => 14,
|
||||
'price' => 14,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
|
@ -473,28 +431,6 @@ class CreateSingleAccount extends Command
|
|||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
||||
$p4= Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'docuninja_user',
|
||||
'notes' => 'The DocuNinja Monthly User Plan',
|
||||
'cost' => 6,
|
||||
'price' => 6,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
||||
$p5 = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'docuninja_user_annual',
|
||||
'notes' => 'The DocuNinja Annual User Plan',
|
||||
'cost' => 60,
|
||||
'price' => 60,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$webhook_config = [
|
||||
'post_purchase_url' => 'http://ninja.test:8000/api/admin/plan',
|
||||
'post_purchase_rest_method' => 'post',
|
||||
|
|
@ -527,119 +463,8 @@ class CreateSingleAccount extends Command
|
|||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY;
|
||||
$sub->save();
|
||||
|
||||
if(!\App\Models\Subscription::find(6)){
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->id = 6;
|
||||
$sub->name = " PRO Pro Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p1->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY;
|
||||
$sub->save();
|
||||
|
||||
}
|
||||
|
||||
if (!\App\Models\Subscription::find(11)) {
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->id = 11;
|
||||
$sub->name = " EEE Enterprise Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p2->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY;
|
||||
$sub->max_seats_limit =2;
|
||||
$sub->per_seat_enabled = true;
|
||||
$sub->save();
|
||||
|
||||
}
|
||||
|
||||
$_sub = $sub->replicate();
|
||||
$_sub->id = 41;
|
||||
$_sub->name = "Enterprise Plan 3-5 Users";
|
||||
$_sub->recurring_product_ids = "{$pe5->hashed_id}";
|
||||
$_sub->max_seats_limit =5;
|
||||
$_sub->per_seat_enabled = true;
|
||||
$_sub->save();
|
||||
|
||||
$_sub = $sub->replicate();
|
||||
$_sub->id = 46;
|
||||
$_sub->name = "Enterprise Plan 6-10 Users";
|
||||
$_sub->recurring_product_ids = "{$pe10->hashed_id}";
|
||||
$_sub->max_seats_limit =10;
|
||||
$_sub->per_seat_enabled = true;
|
||||
$_sub->save();
|
||||
|
||||
$_sub = $sub->replicate();
|
||||
$_sub->id = 51;
|
||||
$_sub->name = "Enterprise Plan 11-20 Users";
|
||||
$_sub->recurring_product_ids = "{$pe20->hashed_id}";
|
||||
$_sub->max_seats_limit =20;
|
||||
$_sub->per_seat_enabled = true;
|
||||
$_sub->save();
|
||||
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->name = "DocuNinja Monthly Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p4->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY;
|
||||
$sub->save();
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->name = "DocuNinja Annual Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p5->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_ANNUALLY;
|
||||
$sub->save();
|
||||
|
||||
|
||||
if($config = config('admin-api.products')){
|
||||
|
||||
foreach($config as $key => $product){
|
||||
|
||||
if(!$p = Product::where('product_key', $key)->first()){
|
||||
|
||||
$p = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => $key,
|
||||
'notes' => $product['description'],
|
||||
'price' => $product['price']
|
||||
]);
|
||||
|
||||
if(!Subscription::find($product['subscription_id'])){
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->id = $product['subscription_id'];
|
||||
$sub->name = $product['description'];
|
||||
$sub->recurring_product_ids = "{$p->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = $product['term'] == 'month' ? RecurringInvoice::FREQUENCY_MONTHLY : RecurringInvoice::FREQUENCY_ANNUALLY;
|
||||
$sub->max_seats_limit = $product['users'] ?? 1;
|
||||
$sub->per_seat_enabled = true;
|
||||
$sub->save();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function createClient($company, $user)
|
||||
{
|
||||
// dispatch(function () use ($company, $user) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -71,7 +70,7 @@ class DesignUpdate extends Command
|
|||
private function handleOnDb()
|
||||
{
|
||||
foreach (Design::where('is_custom', false)->get() as $design) {
|
||||
|
||||
|
||||
$invoice_design = new \App\Services\Pdf\DesignExtractor($design->name);
|
||||
|
||||
$design_object = new stdClass();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -57,9 +56,8 @@ class S3Cleanup extends Command
|
|||
|
||||
$c1 = Company::on('db-ninja-01')->pluck('company_key');
|
||||
$c2 = Company::on('db-ninja-02')->pluck('company_key');
|
||||
$c3 = Company::on('db-ninja-03')->pluck('company_key');
|
||||
|
||||
$merged = $c1->merge($c2)->merge($c3)->toArray();
|
||||
$merged = $c1->merge($c2)->toArray();
|
||||
|
||||
$directories = Storage::disk(config('filesystems.default'))->directories();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -89,9 +88,9 @@ class SendRemindersCron extends Command
|
|||
});
|
||||
|
||||
if ($invoice->invitations->count() > 0) {
|
||||
// event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $reminder_template));
|
||||
|
||||
event(new \App\Events\General\EntityWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null), $reminder_template));
|
||||
// event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $reminder_template));
|
||||
|
||||
event(new \App\Events\General\EntityWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null), $reminder_template));
|
||||
|
||||
$invoice->entityEmailEvent($invoice->invitations->first(), $reminder_template);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -36,7 +35,6 @@ class TranslationsExport extends Command
|
|||
protected $log = '';
|
||||
|
||||
private array $langs = [
|
||||
'af_ZA',
|
||||
'ar',
|
||||
'bg',
|
||||
'ca',
|
||||
|
|
@ -57,7 +55,6 @@ class TranslationsExport extends Command
|
|||
'he',
|
||||
'hr',
|
||||
'hu',
|
||||
'id_ID',
|
||||
'it',
|
||||
'ja',
|
||||
'km_KH',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -34,13 +33,11 @@ use App\Jobs\Ninja\BankTransactionSync;
|
|||
use App\Jobs\Cron\RecurringExpensesCron;
|
||||
use App\Jobs\Cron\RecurringInvoicesCron;
|
||||
use App\Jobs\EDocument\EInvoicePullDocs;
|
||||
use App\Jobs\Cron\InvoiceTaxSummary;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use App\Jobs\Invoice\InvoiceCheckLateWebhook;
|
||||
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
|
||||
use App\PaymentDrivers\Rotessa\Jobs\TransactionReport;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use App\Console\Commands\CreateElasticIndex;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
|
@ -73,29 +70,6 @@ class Kernel extends ConsoleKernel
|
|||
/* Checks for scheduled tasks */
|
||||
$schedule->job(new TaskScheduler())->hourlyAt(10)->withoutOverlapping()->name('task-scheduler-job')->onOneServer();
|
||||
|
||||
// Run hourly over 26-hour period for complete timezone coverage
|
||||
$schedule->job(new InvoiceTaxSummary())
|
||||
->hourly()
|
||||
->when(function () {
|
||||
$now = now();
|
||||
$hour = $now->hour;
|
||||
|
||||
// Run for 26 hours starting from UTC 10:00 on last day of month
|
||||
// This covers the transition period when timezones move to next month
|
||||
if ($now->isSameDay($now->copy()->endOfMonth())) {
|
||||
// Start at UTC 10:00 (when UTC+14 moves to next day)
|
||||
return $hour >= 10;
|
||||
} elseif ($now->isSameDay($now->copy()->startOfMonth())) {
|
||||
// Continue until UTC 12:00 (when UTC-12 moves to next day)
|
||||
return $hour <= 12;
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
->withoutOverlapping()
|
||||
->name('invoice-tax-summary-26hour-coverage')
|
||||
->onOneServer();
|
||||
|
||||
/* Checks Rotessa Transactions */
|
||||
$schedule->job(new TransactionReport())->dailyAt('01:48')->withoutOverlapping()->name('rotessa-transaction-report')->onOneServer();
|
||||
|
||||
|
|
@ -157,8 +131,6 @@ class Kernel extends ConsoleKernel
|
|||
|
||||
$schedule->command('ninja:check-data --database=db-ninja-02')->dailyAt('02:20')->withoutOverlapping()->name('check-data-db-2-job')->onOneServer();
|
||||
|
||||
$schedule->command('ninja:check-data --database=db-ninja-03')->dailyAt('02:30')->withoutOverlapping()->name('check-data-db-2-job')->onOneServer();
|
||||
|
||||
$schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping()->name('s3-cleanup-job')->onOneServer();
|
||||
}
|
||||
|
||||
|
|
@ -180,5 +152,4 @@ class Kernel extends ConsoleKernel
|
|||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -76,10 +75,9 @@ class EmailSuccess extends GenericMixedMetric
|
|||
*/
|
||||
public $string_metric8 = '';
|
||||
|
||||
public function __construct($string_metric7 = '', $string_metric8 = '', string $string_metric9 = '')
|
||||
public function __construct($string_metric7 = '', $string_metric8 = '')
|
||||
{
|
||||
$this->string_metric7 = $string_metric7;
|
||||
$this->string_metric8 = $string_metric8;
|
||||
$this->string_metric9 = $string_metric9;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class JobFailureAnalytics extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'job.failed';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'name';
|
||||
public $string_metric6 = 'exception';
|
||||
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public function __construct($string_metric5, $string_metric6)
|
||||
{
|
||||
$this->string_metric5 = $string_metric5;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
/**
|
||||
* Cancellation value object for invoice backup data.
|
||||
*/
|
||||
class Cancellation
|
||||
{
|
||||
public function __construct(
|
||||
public float $adjustment = 0, // The cancellation adjustment amount
|
||||
public int $status_id = 0 //The status id of the invoice when it was cancelled
|
||||
) {}
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self(
|
||||
adjustment: $data['adjustment'] ?? 0,
|
||||
status_id: $data['status_id'] ?? 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -12,9 +11,8 @@
|
|||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use stdClass;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* CompanySettings.
|
||||
|
|
@ -231,7 +229,7 @@ class CompanySettings extends BaseSettings
|
|||
public $require_quote_signature = false; //@TODO ben to confirm
|
||||
|
||||
//email settings
|
||||
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun', 'client_brevo', 'client_ses', 'ses' //@implemented
|
||||
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun', 'client_brevo' //@implemented
|
||||
|
||||
public $gmail_sending_user_id = '0'; //@implemented
|
||||
|
||||
|
|
@ -479,7 +477,7 @@ class CompanySettings extends BaseSettings
|
|||
|
||||
public $sync_invoice_quote_columns = true;
|
||||
|
||||
public $e_invoice_type = 'EN16931';
|
||||
public $e_invoice_type = 'EN16931'; //verifactu
|
||||
|
||||
public $e_quote_type = 'OrderX_Comfort';
|
||||
|
||||
|
|
@ -530,18 +528,7 @@ class CompanySettings extends BaseSettings
|
|||
|
||||
public bool $unlock_invoice_documents_after_payment = false;
|
||||
|
||||
public string $ses_secret_key = '';
|
||||
public string $ses_access_key = '';
|
||||
public string $ses_region = '';
|
||||
public string $ses_topic_arn = '';
|
||||
public string $ses_from_address = '';
|
||||
|
||||
public static $casts = [
|
||||
'ses_from_address' => 'string',
|
||||
'ses_topic_arn' => 'string',
|
||||
'ses_secret_key' => 'string',
|
||||
'ses_access_key' => 'string',
|
||||
'ses_region' => 'string',
|
||||
'unlock_invoice_documents_after_payment' => 'bool',
|
||||
'preference_product_notes_for_html_view' => 'bool',
|
||||
'enable_client_profile_update' => 'bool',
|
||||
|
|
@ -943,10 +930,7 @@ class CompanySettings extends BaseSettings
|
|||
{
|
||||
$notification = new stdClass();
|
||||
$notification->email = [];
|
||||
|
||||
if(Ninja::isSelfHost()) {
|
||||
$notification->email = ['invoice_sent_all', 'payment_success_all', 'payment_manual_all'];
|
||||
}
|
||||
$notification->email = ['invoice_sent_all', 'payment_success_all', 'payment_manual_all'];
|
||||
|
||||
return $notification;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\InvoiceBackupCast;
|
||||
use App\DataMapper\Cancellation;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* InvoiceBackup.
|
||||
*/
|
||||
class InvoiceBackup implements Castable
|
||||
{
|
||||
public function __construct(
|
||||
public string $guid = '', // The E-INVOICE SENT GUID reference - or enum to advise the document has been successfully sent.
|
||||
public Cancellation $cancellation = new Cancellation(0,0),
|
||||
public ?string $parent_invoice_id = null, // The id of the invoice that was cancelled
|
||||
public ?string $parent_invoice_number = null, // The number of the invoice that was cancelled
|
||||
public ?string $document_type = null, // F1, R2
|
||||
public Collection $child_invoice_ids = new Collection(), // Collection of child invoice IDs
|
||||
public ?string $redirect = null, // The redirect url for the invoice
|
||||
public float $adjustable_amount = 0,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array<string, mixed> $arguments
|
||||
*/
|
||||
public static function castUsing(array $arguments): string
|
||||
{
|
||||
return InvoiceBackupCast::class;
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self(
|
||||
guid: $data['guid'] ?? '',
|
||||
cancellation: Cancellation::fromArray($data['cancellation'] ?? []),
|
||||
parent_invoice_id: $data['parent_invoice_id'] ?? null,
|
||||
parent_invoice_number: $data['parent_invoice_number'] ?? null,
|
||||
document_type: $data['document_type'] ?? null,
|
||||
child_invoice_ids: isset($data['child_invoice_ids']) ? collect($data['child_invoice_ids']) : new Collection(),
|
||||
redirect: $data['redirect'] ?? null,
|
||||
adjustable_amount: $data['adjustable_amount'] ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child invoice ID to the collection
|
||||
*/
|
||||
public function addChildInvoiceId(string $invoiceId): void
|
||||
{
|
||||
$this->child_invoice_ids->push($invoiceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child invoice ID from the collection
|
||||
*/
|
||||
public function removeChildInvoiceId(string $invoiceId): void
|
||||
{
|
||||
$this->child_invoice_ids = $this->child_invoice_ids->reject($invoiceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a child invoice ID exists
|
||||
*/
|
||||
public function hasChildInvoiceId(string $invoiceId): bool
|
||||
{
|
||||
return $this->child_invoice_ids->contains($invoiceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all child invoice IDs as an array
|
||||
*/
|
||||
public function getChildInvoiceIds(): array
|
||||
{
|
||||
return $this->child_invoice_ids->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -13,7 +12,6 @@
|
|||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\InvoiceSyncCast;
|
||||
use App\DataMapper\TaxReport\TaxReport;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
|
||||
/**
|
||||
|
|
@ -25,7 +23,9 @@ class InvoiceSync implements Castable
|
|||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
|
||||
$this->qb_id = $attributes['qb_id'] ?? '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ class ReferralEarning
|
|||
public string $version = 'alpha';
|
||||
|
||||
public string $referral_start_date = ''; // The date this referral was registered.
|
||||
|
||||
|
||||
public string $qualifies_after = ''; // The date the payout qualifies after (5 months / 1 year)
|
||||
|
||||
|
||||
public string $period_ending = ''; // The Date this set relates to. ie 2024-07-31 = July 2024
|
||||
|
||||
public string $account_key = '';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Schedule;
|
||||
|
||||
class InvoiceOutstandingTasks
|
||||
{
|
||||
|
||||
/**
|
||||
* Defines the template name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $template = 'invoice_outstanding_tasks';
|
||||
|
||||
/**
|
||||
* The date range the report should include
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $date_range = 'this_month';
|
||||
|
||||
/**
|
||||
* An array of clients hashed_ids
|
||||
*
|
||||
* Leave blank if this action should apply to all clients
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public array $clients = [];
|
||||
|
||||
/**
|
||||
* If true, the invoice will be auto-sent
|
||||
* else it will be generated and kept in a draft state
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public bool $auto_send = false;
|
||||
|
||||
/**
|
||||
* If true, the project tasks will be included in the report
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public bool $include_project_tasks = false;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\DataMapper\Schedule;
|
||||
|
||||
class PaymentSchedule
|
||||
{
|
||||
/**
|
||||
* The template name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $template = 'payment_schedule';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array(
|
||||
* 'id' => int,
|
||||
* 'date' => string,
|
||||
* 'amount' => float,
|
||||
* 'is_amount' => bool
|
||||
* )
|
||||
*/
|
||||
public array $schedule = [];
|
||||
|
||||
/**
|
||||
* The invoice id
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $invoice_id = '';
|
||||
|
||||
/**
|
||||
* Whether to auto bill the invoice
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public bool $auto_bill = false;
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
@ -112,7 +111,7 @@ class BaseRule implements RuleInterface
|
|||
];
|
||||
|
||||
/** EU TAXES */
|
||||
|
||||
|
||||
/** Supported E Delivery Countries */
|
||||
public array $peppol_business_countries = [
|
||||
'AT',
|
||||
|
|
@ -253,10 +252,10 @@ class BaseRule implements RuleInterface
|
|||
|
||||
$tax_data = $company->origin_tax_data;
|
||||
|
||||
} elseif ($this->invoice->location && $this->invoice->location->is_shipping_location && $this->invoice->location->tax_data) {
|
||||
} elseif($this->invoice->location && $this->invoice->location->is_shipping_location && $this->invoice->location->tax_data){
|
||||
|
||||
$tax_data = $this->invoice->location->tax_data;
|
||||
|
||||
|
||||
} elseif ($this->client->tax_data) {
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue