mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2026-03-03 03:07:01 +00:00
@@ -1 +1 @@
|
||||
5.12.49
|
||||
5.12.65
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -47,7 +47,7 @@ class ClientSyncCast implements CastsAttributes
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
52
app/Casts/ExpenseSyncCast.php
Normal file
52
app/Casts/ExpenseSyncCast.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\ExpenseSync;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class ExpenseSyncCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null; // Return null if the value is null
|
||||
}
|
||||
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$es = new ExpenseSync();
|
||||
$es->qb_id = $data['qb_id'];
|
||||
|
||||
return $es;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'qb_id' => $value->qb_id,
|
||||
];
|
||||
|
||||
return [
|
||||
$key => json_encode($data),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ class InvoiceBackupCast implements CastsAttributes
|
||||
'redirect' => $value->redirect,
|
||||
'adjustable_amount' => $value->adjustable_amount,
|
||||
'notes' => $value->notes,
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -25,14 +25,11 @@ class InvoiceSyncCast implements CastsAttributes
|
||||
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
if (!is_array($data) || empty($data)) {
|
||||
return null; // Return null if decoded data is not an array or is empty
|
||||
}
|
||||
|
||||
$is = new InvoiceSync();
|
||||
$is->qb_id = $data['qb_id'];
|
||||
|
||||
return $is;
|
||||
return InvoiceSync::fromArray($data);
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
@@ -41,12 +38,12 @@ class InvoiceSyncCast implements CastsAttributes
|
||||
return [$key => null];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'qb_id' => $value->qb_id,
|
||||
];
|
||||
|
||||
return [
|
||||
$key => json_encode($data)
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
'invitations' => $value->invitations,
|
||||
'dn_completed' => $value->dn_completed,
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -46,7 +46,7 @@ class PaymentSyncCast implements CastsAttributes
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -32,7 +32,6 @@ class ProductSyncCast implements CastsAttributes
|
||||
|
||||
$ps = new ProductSync();
|
||||
$ps->qb_id = $data['qb_id'];
|
||||
|
||||
return $ps;
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ class ProductSyncCast implements CastsAttributes
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -30,10 +30,9 @@ class QuickbooksSettingsCast implements CastsAttributes
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
if ($value instanceof QuickbooksSettings) {
|
||||
return json_encode(get_object_vars($value));
|
||||
return json_encode($value->toArray());
|
||||
}
|
||||
|
||||
return null;
|
||||
// return json_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -19,25 +19,21 @@ class QuoteSyncCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
if (is_null($value)) {
|
||||
return null; // Return null if the value is null
|
||||
}
|
||||
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
if (!is_array($data) || empty($data)) {
|
||||
return null; // Return null if decoded data is not an array or is empty
|
||||
}
|
||||
|
||||
$is = new QuoteSync($data);
|
||||
|
||||
return $is;
|
||||
return QuoteSync::fromArray($data);
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
|
||||
if (is_null($value)) {
|
||||
return [$key => null];
|
||||
}
|
||||
@@ -45,8 +41,9 @@ class QuoteSyncCast implements CastsAttributes
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
'invitations' => $value->invitations,
|
||||
'dn_completed' => $value->dn_completed,
|
||||
])
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -39,7 +39,7 @@ class TransactionEventMetadataCast implements CastsAttributes
|
||||
}
|
||||
|
||||
return [
|
||||
$key => json_encode($value->toArray())
|
||||
$key => json_encode($value->toArray()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -45,6 +45,7 @@ use App\Factory\ClientContactFactory;
|
||||
use App\Factory\VendorContactFactory;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Utils\BcMath;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
@@ -194,8 +195,7 @@ class CheckData extends Command
|
||||
if ($this->option('tasks') == 'true') {
|
||||
$log = [(int) $log[0], (int) $log[1], (string) $log[2], (bool) $log[3]];
|
||||
}
|
||||
}
|
||||
elseif(count($log) == 4){
|
||||
} elseif (count($log) == 4) {
|
||||
|
||||
if ($this->option('tasks') == 'true') {
|
||||
$log = [(int) $log[0], (int) $log[1], (string) $log[2], (bool) $log[3]];
|
||||
@@ -757,7 +757,7 @@ class CheckData extends Command
|
||||
|
||||
$over_payment = $over_payment * -1;
|
||||
|
||||
if (floatval($over_payment) == floatval($client->balance)) {
|
||||
if (BcMath::equal($over_payment, $client->balance)) {
|
||||
} else {
|
||||
$this->logMessage("# {$client->id} # {$client->name} {$client->balance} is invalid should be {$over_payment}");
|
||||
}
|
||||
@@ -868,9 +868,7 @@ class CheckData extends Command
|
||||
$this->logMessage("{$this->wrong_balances} clients with incorrect ledger balances");
|
||||
}
|
||||
|
||||
private function checkLogoFiles()
|
||||
{
|
||||
}
|
||||
private function checkLogoFiles() {}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -142,7 +142,7 @@ class CreateSingleAccount extends Command
|
||||
'default_password_timeout' => 30 * 60000,
|
||||
'portal_mode' => 'domain',
|
||||
'portal_domain' => 'http://ninja.test:8000',
|
||||
'track_inventory' => true
|
||||
'track_inventory' => true,
|
||||
]);
|
||||
|
||||
$custom_fields = new \stdClass();
|
||||
@@ -223,21 +223,21 @@ class CreateSingleAccount extends Command
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'GST',
|
||||
'rate' => 10
|
||||
'rate' => 10,
|
||||
]);
|
||||
|
||||
TaxRate::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'VAT',
|
||||
'rate' => 17.5
|
||||
'rate' => 17.5,
|
||||
]);
|
||||
|
||||
TaxRate::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'CA Sales Tax',
|
||||
'rate' => 5
|
||||
'rate' => 5,
|
||||
]);
|
||||
|
||||
$bi = BankIntegration::factory()->create([
|
||||
@@ -261,7 +261,7 @@ class CreateSingleAccount extends Command
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'cypress'
|
||||
'name' => 'cypress',
|
||||
]);
|
||||
|
||||
$client->custom_value1 = $company->company_key;
|
||||
@@ -423,6 +423,18 @@ class CreateSingleAccount extends Command
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
||||
$p1a = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'product_key' => 'pro_plan_annual',
|
||||
'notes' => 'The Pro Plan Annual',
|
||||
'cost' => 120,
|
||||
'price' => 120,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
|
||||
$p2 = Product::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
@@ -558,6 +570,18 @@ class CreateSingleAccount extends Command
|
||||
|
||||
}
|
||||
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->id = 66;
|
||||
$sub->name = " PRO Pro Plan Annual";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p1a->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
$sub->allow_plan_changes = true;
|
||||
$sub->frequency_id = RecurringInvoice::FREQUENCY_ANNUALLY;
|
||||
$sub->save();
|
||||
|
||||
|
||||
$_sub = $sub->replicate();
|
||||
$_sub->id = 41;
|
||||
$_sub->name = "Enterprise Plan 3-5 Users";
|
||||
@@ -613,7 +637,7 @@ class CreateSingleAccount extends Command
|
||||
'company_id' => $company->id,
|
||||
'product_key' => $key,
|
||||
'notes' => $product['description'],
|
||||
'price' => $product['price']
|
||||
'price' => $product['price'],
|
||||
]);
|
||||
|
||||
if (!Subscription::find($product['subscription_id'])) {
|
||||
@@ -721,7 +745,7 @@ class CreateSingleAccount extends Command
|
||||
'status_id' => $status->id ?? null,
|
||||
'number' => rand(10000, 100000000),
|
||||
'rate' => rand(1, 150),
|
||||
'client_id' => $client->id
|
||||
'client_id' => $client->id,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -739,7 +763,7 @@ class CreateSingleAccount extends Command
|
||||
Carbon::now()->addSeconds($min)->timestamp,
|
||||
Carbon::now()->addSeconds($min += $rando)->timestamp,
|
||||
$this->faker->sentence,
|
||||
rand(0, 1) === 0 ? false : true
|
||||
rand(0, 1) === 0 ? false : true,
|
||||
];
|
||||
|
||||
$min += 300;
|
||||
@@ -1178,7 +1202,7 @@ class CreateSingleAccount extends Command
|
||||
'company_id' => $company->id,
|
||||
'name' => 'cypress',
|
||||
'country_id' => 826,
|
||||
'settings' => $c_settings
|
||||
'settings' => $c_settings,
|
||||
]);
|
||||
|
||||
$cg = new CompanyGateway();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -34,7 +34,7 @@ class OpenApiYaml extends Command
|
||||
|
||||
private array $directories = [
|
||||
'/components/schemas',
|
||||
'/paths/'
|
||||
'/paths/',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
237
app/Console/Commands/PullPeppolDocs.php
Normal file
237
app/Console/Commands/PullPeppolDocs.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Utils\TempFile;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Utils\Traits\SavesDocuments;
|
||||
use App\Services\EDocument\Gateway\Storecove\Storecove;
|
||||
|
||||
class PullPeppolDocs extends Command
|
||||
{
|
||||
use SavesDocuments;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:pull-peppol-docs';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Pull Peppol docs from the E-Invoice API';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
set_time_limit(3600);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
$this->info("Pulling Peppol docs is not supported on hosted.");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->info("Pulling Peppol docs from the E-Invoice API");
|
||||
|
||||
$account = Account::first();
|
||||
|
||||
$quota_count = $account->e_invoice_quota;
|
||||
|
||||
$this->info("E-Invoice Quota Remaining: $quota_count");
|
||||
|
||||
$this->info("E-Invoice Token: " . $account->e_invoicing_token);
|
||||
|
||||
if (!isset($account->e_invoicing_token)) {
|
||||
|
||||
$this->info("No e-invoicing token found! You will not be able to authenticate with the E-Invoice API. Try logging out and back in again.");
|
||||
|
||||
$this->info("Updating Token...");
|
||||
|
||||
$response_array = $this->updateToken($account);
|
||||
|
||||
$this->info($response[1]);
|
||||
|
||||
if($response_array[0] != 200){
|
||||
|
||||
$this->error("Failed to update token exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->info("License key in use: " . config('ninja.license_key'));
|
||||
|
||||
Account::query()
|
||||
->with('companies')
|
||||
->where('e_invoice_quota', '>', 0)
|
||||
->whereHas('companies', function ($q) {
|
||||
$q->whereNotNull('legal_entity_id');
|
||||
})
|
||||
->cursor()
|
||||
->each(function ($account) {
|
||||
|
||||
$account->companies->filter(function ($company) {
|
||||
|
||||
return $company->settings->e_invoice_type == 'PEPPOL' && ($company->tax_data->acts_as_receiver ?? false);
|
||||
|
||||
})
|
||||
->each(function ($company) {
|
||||
|
||||
$this->info("Pulling Peppol docs for company: {$company->present()->name()}");
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::baseUrl(config('ninja.hosted_ninja_url'))
|
||||
->withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
'X-EInvoice-Token' => $company->account->e_invoicing_token,
|
||||
])
|
||||
->post('/api/einvoice/peppol/documents', data: [
|
||||
'license_key' => config('ninja.license_key'),
|
||||
'account_key' => $company->account->key,
|
||||
'company_key' => $company->company_key,
|
||||
'legal_entity_id' => $company->legal_entity_id,
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
|
||||
$hash = $response->header('X-CONFIRMATION-HASH');
|
||||
|
||||
$this->info($response->body() );
|
||||
|
||||
$this->handleSuccess($response->json(), $company, $hash);
|
||||
} else {
|
||||
nlog($response->body());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private function updateToken(Account $account): array
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::baseUrl(config('ninja.hosted_ninja_url'))
|
||||
->withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
])
|
||||
->post('/api/einvoice/tokens/rotate', data: [
|
||||
'license' => config('ninja.license_key'),
|
||||
'account_key' => $account->key,
|
||||
]);
|
||||
|
||||
|
||||
if ($response->successful()) {
|
||||
|
||||
$account->update([
|
||||
'e_invoicing_token' => $response->json('token'),
|
||||
]);
|
||||
|
||||
return [200, $response->json('token')];
|
||||
// return 'success';
|
||||
}
|
||||
|
||||
return [422, $response->body()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the success of the Peppol docs pull
|
||||
*
|
||||
* @param array $received_documents
|
||||
* @param Company $company
|
||||
* @param string $hash
|
||||
* @return void
|
||||
*/
|
||||
private function handleSuccess(array $received_documents, Company $company, string $hash): void
|
||||
{
|
||||
|
||||
$storecove = new Storecove();
|
||||
|
||||
$doc_count = count($received_documents);
|
||||
|
||||
$this->info("{$doc_count} documents found.");
|
||||
|
||||
if ($doc_count > 0) {
|
||||
$this->info('Processing documents...');
|
||||
|
||||
foreach ($received_documents as $document) {
|
||||
|
||||
$storecove_invoice = $storecove->expense->getStorecoveInvoice(json_encode($document['document']['invoice']));
|
||||
$expense = $storecove->expense->createExpense($storecove_invoice, $company);
|
||||
|
||||
$file_name = $document['guid'];
|
||||
|
||||
if (strlen($document['html'] ?? '') > 5) {
|
||||
|
||||
$upload_document = TempFile::UploadedFileFromRaw($document['html'], "{$file_name}.html", 'text/html');
|
||||
$this->saveDocument($upload_document, $expense, true);
|
||||
$upload_document = null;
|
||||
}
|
||||
|
||||
if (strlen($document['original_base64_xml'] ?? '') > 5) {
|
||||
|
||||
$upload_document = TempFile::UploadedFileFromBase64($document['original_base64_xml'], "{$file_name}.xml", 'application/xml');
|
||||
$this->saveDocument($upload_document, $expense, true);
|
||||
$upload_document = null;
|
||||
}
|
||||
|
||||
foreach ($document['document']['invoice']['attachments'] as $attachment) {
|
||||
|
||||
$upload_document = TempFile::UploadedFileFromBase64($attachment['document'], $attachment['filename'], $attachment['mime_type']);
|
||||
$this->saveDocument($upload_document, $expense, true);
|
||||
$upload_document = null;
|
||||
|
||||
}
|
||||
|
||||
$this->info("Document {$file_name} processed.");
|
||||
|
||||
}
|
||||
|
||||
$this->info("Finished processing documents, flushing upstream...");
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::baseUrl(config('ninja.hosted_ninja_url'))
|
||||
->withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
'X-EInvoice-Token' => $company->account->e_invoicing_token,
|
||||
])
|
||||
->post('/api/einvoice/peppol/documents/flush', data: [
|
||||
'license_key' => config('ninja.license_key'),
|
||||
'account_key' => $company->account->key,
|
||||
'company_key' => $company->company_key,
|
||||
'legal_entity_id' => $company->legal_entity_id,
|
||||
'hash' => $hash,
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
}
|
||||
|
||||
$this->info("Finished flushing upstream.");
|
||||
$this->info("Finished task!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -205,9 +205,7 @@ class SendRemindersCron extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function webHookExpiredQuotes()
|
||||
{
|
||||
}
|
||||
private function webHookExpiredQuotes() {}
|
||||
|
||||
private function executeWebhooks()
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -16,8 +16,8 @@ class ClientRegistrationFields
|
||||
{
|
||||
public static function generate()
|
||||
{
|
||||
$data =
|
||||
[
|
||||
$data
|
||||
= [
|
||||
[
|
||||
'key' => 'first_name',
|
||||
'required' => true,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -1094,7 +1094,7 @@ class CompanySettings extends BaseSettings
|
||||
],
|
||||
'statement_details' => [
|
||||
'$statement_date',
|
||||
'$balance'
|
||||
'$balance',
|
||||
],
|
||||
'delivery_note_columns' => [
|
||||
'$product.item',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
10
app/DataMapper/DocuNinjaSync.php
Normal file
10
app/DataMapper/DocuNinjaSync.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
class DocuNinjaSync
|
||||
{
|
||||
public string $document_id = '';
|
||||
public string $document_invitation_id = '';
|
||||
public string $signature = '';
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ class EmailTemplateDefaults
|
||||
'email_template_custom2',
|
||||
'email_template_custom3',
|
||||
'email_template_purchase_order',
|
||||
'email_template_payment_failed'
|
||||
'email_template_payment_failed',
|
||||
];
|
||||
|
||||
public static function getDefaultTemplate($template, $locale)
|
||||
|
||||
45
app/DataMapper/ExpenseSync.php
Normal file
45
app/DataMapper/ExpenseSync.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\ExpenseSyncCast;
|
||||
use App\DataMapper\TaxReport\TaxReport;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
|
||||
/**
|
||||
* ExpenseSync.
|
||||
*/
|
||||
class ExpenseSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->qb_id = $attributes['qb_id'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ExpenseSyncCast::class;
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self($data);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www/elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -103,4 +103,3 @@ class InvoiceBackup implements Castable
|
||||
return $this->child_invoice_ids->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -70,6 +70,8 @@ class InvoiceItem
|
||||
|
||||
public $unit_code = 'C62';
|
||||
|
||||
public $income_account_id = '';
|
||||
|
||||
public static $casts = [
|
||||
'net_cost' => 'float',
|
||||
'task_id' => 'string',
|
||||
@@ -99,5 +101,6 @@ class InvoiceItem
|
||||
'custom_value3' => 'string',
|
||||
'custom_value4' => 'string',
|
||||
'unit_code' => 'string',
|
||||
'income_account_id' => 'string',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -21,13 +21,12 @@ use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
*/
|
||||
class InvoiceSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->qb_id = $attributes['qb_id'] ?? '';
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
public string $qb_id = '',
|
||||
public array $invitations = [],
|
||||
public bool $dn_completed = false,
|
||||
){}
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
@@ -40,6 +39,62 @@ class InvoiceSync implements Castable
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self($data);
|
||||
return new self(
|
||||
qb_id: $data['qb_id'] ?? '',
|
||||
invitations: $data['invitations'] ?? [],
|
||||
dn_completed: $data['dn_completed'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an invitation to the invitations array
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
* @param string $dn_id The DocuNinja ID
|
||||
* @param string $dn_invitation_id The DocuNinja invitation ID
|
||||
* @param string $dn_sig The DocuNinja signature
|
||||
*/
|
||||
public function addInvitation(
|
||||
string $invitation_key,
|
||||
string $dn_id,
|
||||
string $dn_invitation_id,
|
||||
string $dn_sig
|
||||
): void {
|
||||
$this->invitations[] = [
|
||||
'invitation_key' => $invitation_key,
|
||||
'dn_id' => $dn_id,
|
||||
'dn_invitation_id' => $dn_invitation_id,
|
||||
'dn_sig' => $dn_sig,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get invitation data by invitation key
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
* @return array|null The invitation data or null if not found
|
||||
*/
|
||||
public function getInvitation(string $invitation_key): ?array
|
||||
{
|
||||
foreach ($this->invitations as $invitation) {
|
||||
if ($invitation['invitation_key'] === $invitation_key) {
|
||||
return $invitation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an invitation by invitation key
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
*/
|
||||
public function removeInvitation(string $invitation_key): void
|
||||
{
|
||||
$this->invitations = array_filter($this->invitations, function($invitation) use ($invitation_key) {
|
||||
return $invitation['invitation_key'] !== $invitation_key;
|
||||
});
|
||||
// Re-index the array to maintain numeric keys
|
||||
$this->invitations = array_values($this->invitations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -32,6 +32,8 @@ class QuickbooksSettings implements Castable
|
||||
|
||||
public string $baseURL;
|
||||
|
||||
public string $companyName;
|
||||
|
||||
public QuickbooksSync $settings;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
@@ -42,6 +44,7 @@ class QuickbooksSettings implements Castable
|
||||
$this->accessTokenExpiresAt = $attributes['accessTokenExpiresAt'] ?? 0;
|
||||
$this->refreshTokenExpiresAt = $attributes['refreshTokenExpiresAt'] ?? 0;
|
||||
$this->baseURL = $attributes['baseURL'] ?? '';
|
||||
$this->companyName = $attributes['companyName'] ?? '';
|
||||
$this->settings = new QuickbooksSync($attributes['settings'] ?? []);
|
||||
}
|
||||
|
||||
@@ -55,4 +58,75 @@ class QuickbooksSettings implements Castable
|
||||
return new self($data);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'accessTokenKey' => $this->accessTokenKey,
|
||||
'refresh_token' => $this->refresh_token,
|
||||
'realmID' => $this->realmID,
|
||||
'accessTokenExpiresAt' => $this->accessTokenExpiresAt,
|
||||
'refreshTokenExpiresAt' => $this->refreshTokenExpiresAt,
|
||||
'baseURL' => $this->baseURL,
|
||||
'companyName' => $this->companyName,
|
||||
'settings' => $this->settings->toArray(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Patches our settings object with the
|
||||
* selected changes we authorize.
|
||||
*
|
||||
* @param array $changes
|
||||
* @return self
|
||||
*/
|
||||
public function with(array $changes): self
|
||||
{
|
||||
|
||||
$settings = $this->settings->toArray();
|
||||
|
||||
$new_settings = [
|
||||
'client' => [
|
||||
'direction' => $changes['client']['direction'] ?? $this->settings->client->direction->value,
|
||||
],
|
||||
'invoice' => [
|
||||
'direction' => $changes['invoice']['direction'] ?? $this->settings->invoice->direction->value,
|
||||
],
|
||||
'product' => [
|
||||
'direction' => $changes['product']['direction'] ?? $this->settings->product->direction->value,
|
||||
],
|
||||
'qb_income_account_id' => $changes['qb_income_account_id'] ?? $this->settings->qb_income_account_id,
|
||||
'automatic_taxes' => $changes['automatic_taxes'] ?? $this->settings->automatic_taxes,
|
||||
];
|
||||
|
||||
$final_settings['settings'] = array_merge($settings, $new_settings);
|
||||
|
||||
return new self(array_merge($this->toArray(), $final_settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this QuickbooksSettings instance represents actual data or is just a default empty object.
|
||||
*
|
||||
* @return bool True if this has actual QuickBooks connection data, false if it's just defaults
|
||||
*/
|
||||
public function isConfigured(): bool
|
||||
{
|
||||
// If accessTokenKey is set, we have a connection
|
||||
return !empty($this->accessTokenKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this QuickbooksSettings instance is empty (default values only).
|
||||
*
|
||||
* @return bool True if this is an empty/default instance
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->accessTokenKey)
|
||||
&& empty($this->refresh_token)
|
||||
&& empty($this->realmID)
|
||||
&& $this->accessTokenExpiresAt === 0
|
||||
&& $this->refreshTokenExpiresAt === 0
|
||||
&& empty($this->baseURL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,22 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Models\Product;
|
||||
|
||||
/**
|
||||
* QuickbooksSync.
|
||||
*
|
||||
* Product type to income account mapping:
|
||||
* Keys are Product::PRODUCT_TYPE_* constants (int). Values are QuickBooks account IDs (string|null).
|
||||
* Example: [Product::PRODUCT_TYPE_SERVICE => '123', Product::PRODUCT_TYPE_PHYSICAL => '456']
|
||||
* Null values indicate the account has not been configured for that product type.
|
||||
*/
|
||||
class QuickbooksSync
|
||||
{
|
||||
@@ -35,9 +42,25 @@ class QuickbooksSync
|
||||
|
||||
public QuickbooksSyncMap $expense;
|
||||
|
||||
public string $default_income_account = '';
|
||||
public QuickbooksSyncMap $expense_category;
|
||||
|
||||
public string $default_expense_account = '';
|
||||
/**
|
||||
* QuickBooks income account ID per product type.
|
||||
* Use getAccountId(int $productTypeId) or the typed properties (physical, service, etc.).
|
||||
*/
|
||||
public array $income_account_map;
|
||||
|
||||
public array $tax_rate_map;
|
||||
|
||||
public ?string $qb_income_account_id = null;
|
||||
|
||||
public bool $automatic_taxes = false;
|
||||
|
||||
public ?string $default_taxable_code = null;
|
||||
|
||||
public ?string $default_exempt_code = null;
|
||||
|
||||
public ?string $country = null;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
@@ -50,7 +73,36 @@ class QuickbooksSync
|
||||
$this->product = new QuickbooksSyncMap($attributes['product'] ?? []);
|
||||
$this->payment = new QuickbooksSyncMap($attributes['payment'] ?? []);
|
||||
$this->expense = new QuickbooksSyncMap($attributes['expense'] ?? []);
|
||||
$this->default_income_account = $attributes['default_income_account'] ?? '';
|
||||
$this->default_expense_account = $attributes['default_expense_account'] ?? '';
|
||||
$this->expense_category = new QuickbooksSyncMap($attributes['expense_category'] ?? []);
|
||||
$this->income_account_map = $attributes['income_account_map'] ?? [];
|
||||
$this->qb_income_account_id = $attributes['qb_income_account_id'] ?? null;
|
||||
$this->tax_rate_map = $attributes['tax_rate_map'] ?? [];
|
||||
$this->automatic_taxes = $attributes['automatic_taxes'] ?? false; //requires us to syncronously push the invoice to QB, and return fully formed Invoice with taxes included.
|
||||
$this->default_taxable_code = $attributes['default_taxable_code'] ?? null;
|
||||
$this->default_exempt_code = $attributes['default_exempt_code'] ?? null;
|
||||
$this->country = $attributes['country'] ?? null;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'client' => $this->client->toArray(),
|
||||
'vendor' => $this->vendor->toArray(),
|
||||
'invoice' => $this->invoice->toArray(),
|
||||
'sales' => $this->sales->toArray(),
|
||||
'quote' => $this->quote->toArray(),
|
||||
'purchase_order' => $this->purchase_order->toArray(),
|
||||
'product' => $this->product->toArray(),
|
||||
'payment' => $this->payment->toArray(),
|
||||
'expense' => $this->expense->toArray(),
|
||||
'expense_category' => $this->expense_category->toArray(),
|
||||
'income_account_map' => $this->income_account_map,
|
||||
'qb_income_account_id' => $this->qb_income_account_id,
|
||||
'tax_rate_map' => $this->tax_rate_map,
|
||||
'automatic_taxes' => $this->automatic_taxes,
|
||||
'default_taxable_code' => $this->default_taxable_code,
|
||||
'default_exempt_code' => $this->default_exempt_code,
|
||||
'country' => $this->country,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -19,13 +19,19 @@ use App\Enum\SyncDirection;
|
||||
*/
|
||||
class QuickbooksSyncMap
|
||||
{
|
||||
public SyncDirection $direction = SyncDirection::BIDIRECTIONAL;
|
||||
public SyncDirection $direction = SyncDirection::NONE;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->direction = isset($attributes['direction'])
|
||||
? SyncDirection::from($attributes['direction'])
|
||||
: SyncDirection::BIDIRECTIONAL;
|
||||
: SyncDirection::NONE;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'direction' => $this->direction->value,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -20,15 +20,11 @@ use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
*/
|
||||
class QuoteSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
|
||||
$this->qb_id = $attributes['qb_id'] ?? '';
|
||||
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
public string $qb_id = '',
|
||||
public array $invitations = [],
|
||||
public bool $dn_completed = false,
|
||||
){}
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
@@ -41,6 +37,62 @@ class QuoteSync implements Castable
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self($data);
|
||||
return new self(
|
||||
qb_id: $data['qb_id'] ?? '',
|
||||
invitations: $data['invitations'] ?? [],
|
||||
dn_completed: $data['dn_completed'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an invitation to the invitations array
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
* @param string $dn_id The DocuNinja ID
|
||||
* @param string $dn_invitation_id The DocuNinja invitation ID
|
||||
* @param string $dn_sig The DocuNinja signature
|
||||
*/
|
||||
public function addInvitation(
|
||||
string $invitation_key,
|
||||
string $dn_id,
|
||||
string $dn_invitation_id,
|
||||
string $dn_sig
|
||||
): void {
|
||||
$this->invitations[] = [
|
||||
'invitation_key' => $invitation_key,
|
||||
'dn_id' => $dn_id,
|
||||
'dn_invitation_id' => $dn_invitation_id,
|
||||
'dn_sig' => $dn_sig,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get invitation data by invitation key
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
* @return array|null The invitation data or null if not found
|
||||
*/
|
||||
public function getInvitation(string $invitation_key): ?array
|
||||
{
|
||||
foreach ($this->invitations as $invitation) {
|
||||
if ($invitation['invitation_key'] === $invitation_key) {
|
||||
return $invitation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an invitation by invitation key
|
||||
*
|
||||
* @param string $invitation_key The invitation key
|
||||
*/
|
||||
public function removeInvitation(string $invitation_key): void
|
||||
{
|
||||
$this->invitations = array_filter($this->invitations, function($invitation) use ($invitation_key) {
|
||||
return $invitation['invitation_key'] !== $invitation_key;
|
||||
});
|
||||
// Re-index the array to maintain numeric keys
|
||||
$this->invitations = array_values($this->invitations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -14,7 +14,6 @@ namespace App\DataMapper\Schedule;
|
||||
|
||||
class InvoiceOutstandingTasks
|
||||
{
|
||||
|
||||
/**
|
||||
* Defines the template name
|
||||
*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -276,6 +276,10 @@ class SettingsData
|
||||
|
||||
public string $email_template_reminder_endless = ''; //@implemented
|
||||
|
||||
public string $email_template_payment_failed = ''; //@implemented
|
||||
|
||||
public string $email_subject_payment_failed = ''; //@implemented
|
||||
|
||||
public string $email_signature = ''; //@implemented
|
||||
|
||||
public bool $enable_email_markup = true; //@TODO -
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
@@ -106,9 +106,7 @@ class PayPalBalanceAffecting
|
||||
public $creditTransactionalFee;
|
||||
public $originalInvoiceId;
|
||||
|
||||
public function __construct(private array $import_row)
|
||||
{
|
||||
}
|
||||
public function __construct(private array $import_row) {}
|
||||
|
||||
public function run(): self
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user