Update routes

This commit is contained in:
David Bomba 2024-03-09 08:08:02 +11:00
commit 374c82fc53
1717 changed files with 626338 additions and 501293 deletions

View File

@ -69,3 +69,6 @@ MICROSOFT_REDIRECT_URI=
APPLE_CLIENT_ID= APPLE_CLIENT_ID=
APPLE_CLIENT_SECRET= APPLE_CLIENT_SECRET=
APPLE_REDIRECT_URI= APPLE_REDIRECT_URI=
NORDIGEN_SECRET_ID=
NORDIGEN_SECRET_KEY=

View File

@ -18,7 +18,7 @@ jobs:
phpunit-versions: ['latest'] phpunit-versions: ['latest']
ci_node_total: [ 8 ] ci_node_total: [ 8 ]
ci_node_index: [ 0, 1, 2, 3, 4, 5, 6, 7] ci_node_index: [ 0, 1, 2, 3, 4, 5, 6, 7]
laravel: [9.*] laravel: [10.*]
dependency-version: [prefer-stable] dependency-version: [prefer-stable]
env: env:
@ -81,9 +81,9 @@ jobs:
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: ${{ matrix.php-versions }} php-version: ${{ matrix.php-versions }}
extensions: mysql, mysqlnd, sqlite3, bcmath, gmp, gd, curl, zip, openssl, mbstring, xml, redis extensions: mysql, mysqlnd, sqlite3, bcmath, gmp, gd, curl, zip, openssl, mbstring, xml, redis, :psr
- uses: actions/checkout@v1 - uses: actions/checkout@v4
with: with:
ref: v5-develop ref: v5-develop
fetch-depth: 1 fetch-depth: 1
@ -96,7 +96,7 @@ jobs:
id: composer-cache id: composer-cache
run: | run: |
echo "::set-output name=dir::$(composer config cache-files-dir)" echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v2 - uses: actions/cache@v3
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}

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

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

View File

@ -43,7 +43,7 @@ jobs:
run: | run: |
git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git
cd ui cd ui
git checkout main git checkout develop
npm i npm i
npm run build npm run build

View File

@ -36,7 +36,8 @@ We offer a $30 per year white-label license to remove the Invoice Ninja branding
### Desktop Apps ### Desktop Apps
* [macOS](https://apps.apple.com/app/id1503970375?platform=mac) * [macOS](https://apps.apple.com/app/id1503970375?platform=mac)
* [Windows](https://microsoft.com/en-us/p/invoice-ninja/9n3f2bbcfdr6) * [Windows](https://microsoft.com/en-us/p/invoice-ninja/9n3f2bbcfdr6)
* [Linux](https://snapcraft.io/invoiceninja) * [Linux - Snap](https://snapcraft.io/invoiceninja)
* [Linux - Flatpak](https://flathub.org/apps/com.invoiceninja.InvoiceNinja)
### Installation Options ### Installation Options
* [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/) * [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/)

View File

@ -1 +1 @@
5.7.54 5.8.34

View File

@ -12,10 +12,10 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use App; use App;
use App\DataMapper\ClientSettings;
use App\Factory\ClientContactFactory; use App\Factory\ClientContactFactory;
use App\Factory\VendorContactFactory; use App\Factory\VendorContactFactory;
use App\Jobs\Company\CreateCompanyToken; use App\Jobs\Company\CreateCompanyToken;
use App\Libraries\MultiDB;
use App\Models\Account; use App\Models\Account;
use App\Models\BankTransaction; use App\Models\BankTransaction;
use App\Models\Client; use App\Models\Client;
@ -128,6 +128,8 @@ class CheckData extends Command
$this->checkCompanyTokens(); $this->checkCompanyTokens();
$this->checkUserState(); $this->checkUserState();
$this->checkContactEmailAndSendEmailStatus(); $this->checkContactEmailAndSendEmailStatus();
$this->checkPaymentCurrency();
$this->checkSubdomainsSet();
if (Ninja::isHosted()) { if (Ninja::isHosted()) {
$this->checkAccountStatuses(); $this->checkAccountStatuses();
@ -314,7 +316,7 @@ class CheckData extends Command
$new_contact->client_id = $client->id; $new_contact->client_id = $client->id;
$new_contact->contact_key = Str::random(40); $new_contact->contact_key = Str::random(40);
$new_contact->is_primary = true; $new_contact->is_primary = true;
$new_contact->save(); $new_contact->saveQuietly();
} }
} }
} }
@ -326,6 +328,7 @@ class CheckData extends Command
->whereNull('contact_key') ->whereNull('contact_key')
->orderBy('id') ->orderBy('id')
->get(['id']); ->get(['id']);
$this->logMessage($contacts->count().' contacts without a contact_key'); $this->logMessage($contacts->count().' contacts without a contact_key');
if ($contacts->count() > 0) { if ($contacts->count() > 0) {
@ -343,20 +346,8 @@ class CheckData extends Command
} }
} }
// check for missing contacts $vendors = Vendor::withTrashed()->doesntHave('contacts');
$vendors = DB::table('vendors')
->leftJoin('vendor_contacts', function ($join) {
$join->on('vendor_contacts.vendor_id', '=', 'vendors.id')
->whereNull('vendor_contacts.deleted_at');
})
->groupBy('vendors.id', 'vendors.user_id', 'vendors.company_id')
->havingRaw('count(vendor_contacts.id) = 0');
if ($this->option('vendor_id')) {
$vendors->where('vendors.id', '=', $this->option('vendor_id'));
}
$vendors = $vendors->get(['vendors.id', 'vendors.user_id', 'vendors.company_id']);
$this->logMessage($vendors->count().' vendors without any contacts'); $this->logMessage($vendors->count().' vendors without any contacts');
if ($vendors->count() > 0) { if ($vendors->count() > 0) {
@ -373,28 +364,11 @@ class CheckData extends Command
$new_contact->vendor_id = $vendor->id; $new_contact->vendor_id = $vendor->id;
$new_contact->contact_key = Str::random(40); $new_contact->contact_key = Str::random(40);
$new_contact->is_primary = true; $new_contact->is_primary = true;
$new_contact->save(); $new_contact->saveQuietly();
} }
} }
} }
private function checkFailedJobs()
{
if (config('ninja.testvars.travis')) {
return;
}
$queueDB = config('queue.connections.database.connection');
$count = DB::connection($queueDB)->table('failed_jobs')->count();
if ($count > 25) {
$this->isValid = false;
}
$this->logMessage($count.' failed jobs');
}
private function checkInvitations() private function checkInvitations()
{ {
$invoices = DB::table('invoices') $invoices = DB::table('invoices')
@ -420,7 +394,7 @@ class CheckData extends Command
$invitation->invoice_id = $invoice->id; $invitation->invoice_id = $invoice->id;
$invitation->client_contact_id = ClientContact::whereClientId($invoice->client_id)->first()->id; $invitation->client_contact_id = ClientContact::whereClientId($invoice->client_id)->first()->id;
$invitation->key = Str::random(config('ninja.key_length')); $invitation->key = Str::random(config('ninja.key_length'));
$invitation->save(); $invitation->saveQuietly();
} }
} }
} }
@ -611,7 +585,7 @@ class CheckData extends Command
if ($this->option('paid_to_date')) { if ($this->option('paid_to_date')) {
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->paid_to_date} to {$total_paid_to_date}"); $this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->paid_to_date} to {$total_paid_to_date}");
$client->paid_to_date = $total_paid_to_date; $client->paid_to_date = $total_paid_to_date;
$client->save(); $client->saveQuietly();
} }
} }
} }
@ -660,7 +634,7 @@ class CheckData extends Command
if ($this->option('client_balance')) { if ($this->option('client_balance')) {
$this->logMessage("# {$client_object->id} " . $client_object->present()->name().' - '.$client_object->number." Fixing {$client_object->balance} to " . $client['invoice_balance']); $this->logMessage("# {$client_object->id} " . $client_object->present()->name().' - '.$client_object->number." Fixing {$client_object->balance} to " . $client['invoice_balance']);
$client_object->balance = $client['invoice_balance']; $client_object->balance = $client['invoice_balance'];
$client_object->save(); $client_object->saveQuietly();
} }
$this->isValid = false; $this->isValid = false;
@ -684,6 +658,8 @@ class CheckData extends Command
->count(); ->count();
if ($count == 0) { if ($count == 0) {
$this->isValid = false;
//factor in over payments to the client balance //factor in over payments to the client balance
$over_payment = Payment::where('client_id', $client->id) $over_payment = Payment::where('client_id', $client->id)
->where('is_deleted', 0) ->where('is_deleted', 0)
@ -692,7 +668,7 @@ class CheckData extends Command
->pluck('p') ->pluck('p')
->first(); ->first();
$over_payment = $over_payment*-1; $over_payment = $over_payment * -1;
if (floatval($over_payment) == floatval($client->balance)) { if (floatval($over_payment) == floatval($client->balance)) {
} else { } else {
@ -704,7 +680,7 @@ class CheckData extends Command
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to 0"); $this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to 0");
$client->balance = $over_payment; $client->balance = $over_payment;
$client->save(); $client->saveQuietly();
} }
} }
}); });
@ -746,6 +722,8 @@ class CheckData extends Command
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
if (number_format($invoice_balance, 4) != number_format($client->balance, 4)) { if (number_format($invoice_balance, 4) != number_format($client->balance, 4)) {
$this->isValid = false;
$this->wrong_balances++; $this->wrong_balances++;
$ledger_balance = $ledger ? $ledger->balance : 0; $ledger_balance = $ledger ? $ledger->balance : 0;
@ -756,7 +734,7 @@ class CheckData extends Command
if ($this->option('client_balance')) { if ($this->option('client_balance')) {
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}"); $this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
$client->balance = $invoice_balance; $client->balance = $invoice_balance;
$client->save(); $client->saveQuietly();
} }
if ($ledger && (number_format($invoice_balance, 4) != number_format($ledger->balance, 4))) { if ($ledger && (number_format($invoice_balance, 4) != number_format($ledger->balance, 4))) {
@ -790,7 +768,7 @@ class CheckData extends Command
if ($this->option('ledger_balance')) { if ($this->option('ledger_balance')) {
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}"); $this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
$client->balance = $invoice_balance; $client->balance = $invoice_balance;
$client->save(); $client->saveQuietly();
$ledger->adjustment = $invoice_balance; $ledger->adjustment = $invoice_balance;
$ledger->balance = $invoice_balance; $ledger->balance = $invoice_balance;
@ -894,6 +872,8 @@ class CheckData extends Command
->exists(); ->exists();
if ($payment) { if ($payment) {
$this->isValid = false;
$this->logMessage("I found a payment for {$account->key}"); $this->logMessage("I found a payment for {$account->key}");
} }
} }
@ -904,12 +884,100 @@ class CheckData extends Command
public function checkClientSettings() public function checkClientSettings()
{ {
if ($this->option('fix') == 'true') { if ($this->option('fix') == 'true') {
Client::query()->whereNull('country_id')->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->country_id = $client->company->settings->country_id;
$client->save(); $client->saveQuietly();
$this->logMessage("Fixing country for # {$client->id}"); $this->logMessage("Fixing country for # {$client->id}");
}); });
Client::query()->whereNull("settings->currency_id")->cursor()->each(function ($client) {
$settings = $client->settings;
$settings->currency_id = (string)$client->company->settings->currency_id;
$client->settings = $settings;
$client->saveQuietly();
$this->logMessage("Fixing currency_id for # {$client->id}");
});
Payment::withTrashed()->where('exchange_rate', 0)->cursor()->each(function ($payment) {
$payment->exchange_rate = 1;
$payment->saveQuietly();
$this->logMessage("Fixing exchange rate for # {$payment->id}");
});
Payment::withTrashed()
->whereHas("client", function ($query) {
$query->whereColumn("settings->currency_id", "!=", "payments.currency_id");
})
->cursor()
->each(function ($p) {
$p->currency_id = $p->client->settings->currency_id;
$p->saveQuietly();
$this->logMessage("Fixing currency for # {$p->id}");
});
Company::whereNull("subdomain")
->cursor()
->when(Ninja::isHosted())
->each(function ($c) {
$c->subdomain = MultiDB::randomSubdomainGenerator();
$c->save();
$this->logMessage("Fixing subdomain for # {$c->id}");
});
Invoice::withTrashed()
->where("partial", 0)
->whereNotNull("partial_due_date")
->cursor()
->each(function ($i) {
$i->partial_due_date = null;
$i->saveQuietly();
$this->logMessage("Fixing partial due date for # {$i->id}");
});
Company::whereDoesntHave('company_users', function ($query){
$query->where('is_owner', 1);
})
->cursor()
->when(Ninja::isHosted())
->each(function ($c){
$this->logMessage("Orphan Account # {$c->account_id}");
});
CompanyUser::whereDoesntHave('tokens')
->cursor()
->when(Ninja::isHosted())
->each(function ($cu){
$this->logMessage("Missing tokens for Company User # {$cu->id}");
});
CompanyUser::whereDoesntHave('user')
->cursor()
->when(Ninja::isHosted())
->each(function ($cu) {
$this->logMessage("Missing user for Company User # {$cu->id}");
});
} }
} }
@ -918,7 +986,7 @@ class CheckData extends Command
if ($this->option('fix') == 'true') { if ($this->option('fix') == 'true') {
Vendor::query()->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->currency_id = $vendor->company->settings->currency_id;
$vendor->save(); $vendor->saveQuietly();
$this->logMessage("Fixing vendor currency for # {$vendor->id}"); $this->logMessage("Fixing vendor currency for # {$vendor->id}");
}); });
@ -940,15 +1008,15 @@ class CheckData extends Command
$val = $invoice->balance; $val = $invoice->balance;
$invoice->balance = 0; $invoice->balance = 0;
$invoice->paid_to_date=$val; $invoice->paid_to_date = $val;
$invoice->save(); $invoice->saveQuietly();
$p = $invoice->payments->first(); $p = $invoice->payments->first();
if ($p && (int)$p->amount == 0) { if ($p && (int)$p->amount == 0) {
$p->amount = $val; $p->amount = $val;
$p->applied = $val; $p->applied = $val;
$p->save(); $p->saveQuietly();
$pivot = $p->paymentables->first(); $pivot = $p->paymentables->first();
$pivot->amount = $val; $pivot->amount = $val;
@ -1009,6 +1077,7 @@ class CheckData extends Command
BankTransaction::with('payment')->withTrashed()->where('invoice_ids', ',,,,,,,,')->cursor()->each(function ($bt) { BankTransaction::with('payment')->withTrashed()->where('invoice_ids', ',,,,,,,,')->cursor()->each(function ($bt) {
if($bt->payment->exists()) { if($bt->payment->exists()) {
$this->isValid = false;
$bt->invoice_ids = collect($bt->payment->invoices)->pluck('hashed_id')->implode(','); $bt->invoice_ids = collect($bt->payment->invoices)->pluck('hashed_id')->implode(',');
$bt->save(); $bt->save();
@ -1039,4 +1108,49 @@ class CheckData extends Command
}); });
} }
} }
public function checkSubdomainsSet()
{
if(Ninja::isSelfHost()) {
return;
}
Company::query()
->whereNull('subdomain')
->orWhere('subdomain', '')
->cursor()
->each(function ($c) {
$c->subdomain = MultiDB::randomSubdomainGenerator();
$c->save();
});
}
public function checkPaymentCurrency()
{
$p = Payment::with('company', 'client')
->withTrashed()
->where('currency_id', '')
->orWhereNull('currency_id');
$this->logMessage($p->count() . " Payments with No currency set");
if($p->count() != 0) {
$this->isValid = false;
}
if ($this->option('fix') == 'true') {
$p->cursor()->each(function ($c) {
$c->currency_id = $c->client->settings->currency_id ?? $c->company->settings->currency_id;
$c->saveQuietly();
$this->logMessage("Fixing - {$c->id}");
});
}
}
} }

View File

@ -29,7 +29,8 @@ use Illuminate\Support\Str;
class CreateAccount extends Command class CreateAccount extends Command
{ {
use MakesHash, GeneratesCounter; use MakesHash;
use GeneratesCounter;
/** /**
* @var string * @var string
@ -97,7 +98,7 @@ class CreateAccount extends Command
'phone' => '', 'phone' => '',
]); ]);
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;

View File

@ -11,58 +11,58 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use stdClass; use App\DataMapper\ClientRegistrationFields;
use Carbon\Carbon; use App\DataMapper\CompanySettings;
use Faker\Factory; use App\DataMapper\FeesAndLimits;
use App\Models\Task; use App\Events\Invoice\InvoiceWasCreated;
use App\Models\User; use App\Events\RecurringInvoice\RecurringInvoiceWasCreated;
use App\Utils\Ninja; use App\Factory\GroupSettingFactory;
use App\Models\Quote; use App\Factory\InvoiceFactory;
use App\Models\Client; use App\Factory\InvoiceItemFactory;
use App\Models\Credit; use App\Factory\RecurringInvoiceFactory;
use App\Models\Vendor; use App\Factory\SubscriptionFactory;
use App\Helpers\Invoice\InvoiceSum;
use App\Jobs\Company\CreateCompanyTaskStatuses;
use App\Libraries\MultiDB;
use App\Models\Account; use App\Models\Account;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Models\BankTransactionRule;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company; use App\Models\Company;
use App\Models\CompanyGateway;
use App\Models\CompanyToken;
use App\Models\Country; use App\Models\Country;
use App\Models\Credit;
use App\Models\Expense; use App\Models\Expense;
use App\Models\Gateway;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Product; use App\Models\Product;
use App\Models\Project; use App\Models\Project;
use App\Models\TaxRate; use App\Models\Quote;
use App\Libraries\MultiDB;
use App\Models\TaskStatus;
use App\Models\CompanyToken;
use App\Models\ClientContact;
use App\Models\VendorContact;
use App\Models\CompanyGateway;
use App\Factory\InvoiceFactory;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Utils\Traits\MakesHash;
use Illuminate\Console\Command;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\DataMapper\FeesAndLimits; use App\Models\Task;
use App\DataMapper\CompanySettings; use App\Models\TaskStatus;
use App\Factory\InvoiceItemFactory; use App\Models\TaxRate;
use App\Helpers\Invoice\InvoiceSum; use App\Models\User;
use App\Models\BankTransactionRule; use App\Models\Vendor;
use App\Factory\GroupSettingFactory; use App\Models\VendorContact;
use App\Factory\SubscriptionFactory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Cache;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Support\Facades\Schema;
use App\Repositories\InvoiceRepository; use App\Repositories\InvoiceRepository;
use App\Factory\RecurringInvoiceFactory; use App\Utils\Ninja;
use App\Events\Invoice\InvoiceWasCreated; use App\Utils\Traits\GeneratesCounter;
use App\DataMapper\ClientRegistrationFields; use App\Utils\Traits\MakesHash;
use App\Jobs\Company\CreateCompanyTaskStatuses; use Carbon\Carbon;
use App\Events\RecurringInvoice\RecurringInvoiceWasCreated; use Faker\Factory;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
use stdClass;
class CreateSingleAccount extends Command class CreateSingleAccount extends Command
{ {
use MakesHash, GeneratesCounter; use MakesHash;
use GeneratesCounter;
protected $description = 'Create Single Sample Account'; protected $description = 'Create Single Sample Account';
@ -101,6 +101,31 @@ class CreateSingleAccount extends Command
$this->warmCache(); $this->warmCache();
$this->createSmallAccount(); $this->createSmallAccount();
try {
$pdo = \DB::connection('ronin')->getPdo();
if(class_exists(\Modules\Ronin\app\Models\Admin::class)) {
$this->info('Creating Ronin Account');
$this->createRoninAccount();
}
} catch (\Exception $e) {
}
}
private function createRoninAccount()
{
$admin = \Modules\Ronin\app\Models\Admin::create([
'first_name' => 'small',
'last_name' => 'example',
'email' => 'small@example.com',
'password' => Hash::make('password'),
]);
} }
private function createSmallAccount() private function createSmallAccount()
@ -115,7 +140,7 @@ class CreateSingleAccount extends Command
$company = Company::factory()->create([ $company = Company::factory()->create([
'account_id' => $account->id, 'account_id' => $account->id,
'slack_webhook_url' => config('ninja.notification.slack'), 'slack_webhook_url' => config('ninja.notification.slack'),
'default_password_timeout' => 30*60000, 'default_password_timeout' => 30 * 60000,
'portal_mode' => 'domain', 'portal_mode' => 'domain',
'portal_domain' => 'http://ninja.test:8000', 'portal_domain' => 'http://ninja.test:8000',
'track_inventory' => true 'track_inventory' => true
@ -164,7 +189,7 @@ class CreateSingleAccount extends Command
]); ]);
} }
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;
@ -508,7 +533,7 @@ class CreateSingleAccount extends Command
private function createTask($client) private function createTask($client)
{ {
$time_log = $this->createTimeLog(rand(1,20)); $time_log = $this->createTimeLog(rand(1, 20));
$status = TaskStatus::where('company_id', $client->company_id)->get()->random(); $status = TaskStatus::where('company_id', $client->company_id)->get()->random();
return Task::factory()->create([ return Task::factory()->create([
@ -517,8 +542,8 @@ class CreateSingleAccount extends Command
'time_log' => $time_log, 'time_log' => $time_log,
'description' => $this->faker->paragraph, 'description' => $this->faker->paragraph,
'status_id' => $status->id ?? null, 'status_id' => $status->id ?? null,
'number' => rand(10000,100000000), 'number' => rand(10000, 100000000),
'rate' => rand(1,150), 'rate' => rand(1, 150),
'client_id' => $client->id 'client_id' => $client->id
]); ]);
} }
@ -537,7 +562,7 @@ class CreateSingleAccount extends Command
Carbon::now()->addSeconds($min)->timestamp, Carbon::now()->addSeconds($min)->timestamp,
Carbon::now()->addSeconds($min += $rando)->timestamp, Carbon::now()->addSeconds($min += $rando)->timestamp,
$this->faker->sentence, $this->faker->sentence,
rand(0,1) === 0 ? false : true rand(0, 1) === 0 ? false : true
]; ];
$min += 300; $min += 300;
@ -552,12 +577,12 @@ class CreateSingleAccount extends Command
'user_id' => $client->user->id, 'user_id' => $client->user->id,
'company_id' => $client->company->id, 'company_id' => $client->company->id,
'client_id' => $client->id, 'client_id' => $client->id,
'due_date' => now()->addSeconds(rand(100000,1000000))->format('Y-m-d'), 'due_date' => now()->addSeconds(rand(100000, 1000000))->format('Y-m-d'),
'budgeted_hours' => rand(100,1000), 'budgeted_hours' => rand(100, 1000),
'task_rate' => rand(1,200), 'task_rate' => rand(1, 200),
]); ]);
for($x=0; $x < rand(2, 5); $x++) { for($x = 0; $x < rand(2, 5); $x++) {
$task = $this->createTask($client); $task = $this->createTask($client);
$task->project_id = $project->id; $task->project_id = $project->id;
$task->save(); $task->save();
@ -777,7 +802,7 @@ class CreateSingleAccount extends Command
private function createGateways($company, $user) private function createGateways($company, $user)
{ {
if (config('ninja.testvars.stripe') && ($this->gateway == 'all' || $this->gateway == 'stripe')) { if (config('ninja.testvars.stripe') && ($this->gateway == 'all' || $this->gateway == 'stripe')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23'; $cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23';
@ -790,15 +815,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.paypal') && ($this->gateway == 'all' || $this->gateway == 'paypal')) { if (config('ninja.testvars.paypal') && ($this->gateway == 'all' || $this->gateway == 'paypal')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '38f2c48af60c7dd69e04248cbb24c36e'; $cg->gateway_key = '38f2c48af60c7dd69e04248cbb24c36e';
@ -811,15 +836,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.paypal_rest') && ($this->gateway == 'all' || $this->gateway == 'paypal_rest')) { if (config('ninja.testvars.paypal_rest') && ($this->gateway == 'all' || $this->gateway == 'paypal_rest')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '80af24a6a691230bbec33e930ab40665'; $cg->gateway_key = '80af24a6a691230bbec33e930ab40665';
@ -832,8 +857,8 @@ class CreateSingleAccount extends Command
// $gateway_types = $cg->driver()->gatewayTypes(); // $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{3} = new FeesAndLimits; $fees_and_limits->{3} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
@ -842,7 +867,7 @@ class CreateSingleAccount extends Command
if (config('ninja.testvars.checkout') && ($this->gateway == 'all' || $this->gateway == 'checkout')) { if (config('ninja.testvars.checkout') && ($this->gateway == 'all' || $this->gateway == 'checkout')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '3758e7f7c6f4cecf0f4f348b9a00f456'; $cg->gateway_key = '3758e7f7c6f4cecf0f4f348b9a00f456';
@ -853,17 +878,17 @@ class CreateSingleAccount extends Command
$cg->config = encrypt(config('ninja.testvars.checkout')); $cg->config = encrypt(config('ninja.testvars.checkout'));
$cg->save(); $cg->save();
$gateway_types = $cg->driver(new Client)->gatewayTypes(); $gateway_types = $cg->driver(new Client())->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.authorize') && ($this->gateway == 'all' || $this->gateway == 'authorizenet')) { if (config('ninja.testvars.authorize') && ($this->gateway == 'all' || $this->gateway == 'authorizenet')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '3b6621f970ab18887c4f6dca78d3f8bb'; $cg->gateway_key = '3b6621f970ab18887c4f6dca78d3f8bb';
@ -874,17 +899,17 @@ class CreateSingleAccount extends Command
$cg->config = encrypt(config('ninja.testvars.authorize')); $cg->config = encrypt(config('ninja.testvars.authorize'));
$cg->save(); $cg->save();
$gateway_types = $cg->driver(new Client)->gatewayTypes(); $gateway_types = $cg->driver(new Client())->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.wepay') && ($this->gateway == 'all' || $this->gateway == 'wepay')) { if (config('ninja.testvars.wepay') && ($this->gateway == 'all' || $this->gateway == 'wepay')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '8fdeed552015b3c7b44ed6c8ebd9e992'; $cg->gateway_key = '8fdeed552015b3c7b44ed6c8ebd9e992';
@ -897,15 +922,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.braintree') && ($this->gateway == 'all' || $this->gateway == 'braintree')) { if (config('ninja.testvars.braintree') && ($this->gateway == 'all' || $this->gateway == 'braintree')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = 'f7ec488676d310683fb51802d076d713'; $cg->gateway_key = 'f7ec488676d310683fb51802d076d713';
@ -918,8 +943,8 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
@ -927,7 +952,7 @@ class CreateSingleAccount extends Command
if (config('ninja.testvars.paytrace.decrypted') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) { if (config('ninja.testvars.paytrace.decrypted') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = 'bbd736b3254b0aabed6ad7fda1298c88'; $cg->gateway_key = 'bbd736b3254b0aabed6ad7fda1298c88';
@ -942,15 +967,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.mollie') && ($this->gateway == 'all' || $this->gateway == 'mollie')) { if (config('ninja.testvars.mollie') && ($this->gateway == 'all' || $this->gateway == 'mollie')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '1bd651fb213ca0c9d66ae3c336dc77e8'; $cg->gateway_key = '1bd651fb213ca0c9d66ae3c336dc77e8';
@ -963,15 +988,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();
} }
if (config('ninja.testvars.square') && ($this->gateway == 'all' || $this->gateway == 'square')) { if (config('ninja.testvars.square') && ($this->gateway == 'all' || $this->gateway == 'square')) {
$cg = new CompanyGateway; $cg = new CompanyGateway();
$cg->company_id = $company->id; $cg->company_id = $company->id;
$cg->user_id = $user->id; $cg->user_id = $user->id;
$cg->gateway_key = '65faab2ab6e3223dbe848b1686490baz'; $cg->gateway_key = '65faab2ab6e3223dbe848b1686490baz';
@ -984,8 +1009,8 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes(); $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass; $fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits; $fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits; $cg->fees_and_limits = $fees_and_limits;
$cg->save(); $cg->save();

View File

@ -47,7 +47,8 @@ use Illuminate\Support\Str;
class CreateTestData extends Command class CreateTestData extends Command
{ {
use MakesHash, GeneratesCounter; use MakesHash;
use GeneratesCounter;
/** /**
* @var string * @var string
@ -115,7 +116,7 @@ class CreateTestData extends Command
]); ]);
} }
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;
@ -210,7 +211,7 @@ class CreateTestData extends Command
]); ]);
} }
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;
@ -307,7 +308,7 @@ class CreateTestData extends Command
]); ]);
} }
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;

View File

@ -54,7 +54,9 @@ use Illuminate\Support\Str;
class DemoMode extends Command class DemoMode extends Command
{ {
use MakesHash, GeneratesCounter, AppSetup; use MakesHash;
use GeneratesCounter;
use AppSetup;
protected $signature = 'ninja:demo-mode'; protected $signature = 'ninja:demo-mode';
@ -151,7 +153,7 @@ class DemoMode extends Command
(new CreateCompanyPaymentTerms($company, $user))->handle(); (new CreateCompanyPaymentTerms($company, $user))->handle();
(new CreateCompanyTaskStatuses($company, $user))->handle(); (new CreateCompanyTaskStatuses($company, $user))->handle();
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $user->id; $company_token->user_id = $user->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;
@ -182,7 +184,7 @@ class DemoMode extends Command
'email_verified_at' => now(), 'email_verified_at' => now(),
]); ]);
$company_token = new CompanyToken; $company_token = new CompanyToken();
$company_token->user_id = $u2->id; $company_token->user_id = $u2->id;
$company_token->company_id = $company->id; $company_token->company_id = $company->id;
$company_token->account_id = $account->id; $company_token->account_id = $account->id;

View File

@ -73,7 +73,7 @@ class DesignUpdate extends Command
$invoice_design = new \App\Services\PdfMaker\Design(strtolower($design->name)); $invoice_design = new \App\Services\PdfMaker\Design(strtolower($design->name));
$invoice_design->document(); $invoice_design->document();
$design_object = new stdClass; $design_object = new stdClass();
$design_object->includes = $invoice_design->getSectionHTML('style'); $design_object->includes = $invoice_design->getSectionHTML('style');
$design_object->header = $invoice_design->getSectionHTML('header'); $design_object->header = $invoice_design->getSectionHTML('header');
$design_object->body = $invoice_design->getSectionHTML('body'); $design_object->body = $invoice_design->getSectionHTML('body');

View File

@ -0,0 +1,84 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class EncryptNinja extends Command
{
protected $files = [
'resources/views/email/template/admin_premium.blade.php',
'resources/views/email/template/client_premium.blade.php',
];
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ninja:crypt {--encrypt} {--decrypt}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Encrypt Protected files';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if($this->option('encrypt')) {
return $this->encryptFiles();
}
if($this->option('decrypt')) {
return $this->decryptFiles();
}
}
private function encryptFiles()
{
foreach ($this->files as $file) {
$contents = Storage::disk('base')->get($file);
$encrypted = encrypt($contents);
Storage::disk('base')->put($file.".enc", $encrypted);
// Storage::disk('base')->delete($file);
}
}
private function decryptFiles()
{
foreach ($this->files as $file) {
$encrypted_file = "{$file}.enc";
$contents = Storage::disk('base')->get($encrypted_file);
$decrypted = decrypt($contents);
Storage::disk('base')->put($file, $decrypted);
}
}
}

View File

@ -61,9 +61,9 @@ class MobileLocalization extends Command
private function laravelResources() private function laravelResources()
{ {
$resources =(array)$this->getResources(); $resources = (array)$this->getResources();
if(is_iterable($resources)){ if(is_iterable($resources)) {
foreach ($resources as $key => $val) { foreach ($resources as $key => $val) {
$transKey = "texts.{$key}"; $transKey = "texts.{$key}";
if (trans($transKey) == $transKey) { if (trans($transKey) == $transKey) {

View File

@ -78,9 +78,10 @@ class OpenApiYaml extends Command
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components.yaml')); Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components.yaml'));
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/responses.yaml'));
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/examples.yaml')); Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/examples.yaml'));
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/responses.yaml'));
$directory = new DirectoryIterator($path . '/components/responses/'); $directory = new DirectoryIterator($path . '/components/responses/');
foreach ($directory as $file) { foreach ($directory as $file) {

View File

@ -50,9 +50,9 @@ class S3Cleanup extends Command
*/ */
public function handle() public function handle()
{ {
if (!Ninja::isHosted()) { // if (!Ninja::isHosted()) {
return; // return;
} // }
$c1 = Company::on('db-ninja-01')->pluck('company_key'); $c1 = Company::on('db-ninja-01')->pluck('company_key');
$c2 = Company::on('db-ninja-02')->pluck('company_key'); $c2 = Company::on('db-ninja-02')->pluck('company_key');

View File

@ -28,7 +28,8 @@ use Illuminate\Support\Facades\App;
//@deprecated 27-11-2022 - only ever should be used for testing //@deprecated 27-11-2022 - only ever should be used for testing
class SendRemindersCron extends Command class SendRemindersCron extends Command
{ {
use MakesReminders, MakesDates; use MakesReminders;
use MakesDates;
/** /**
* The name and signature of the console command. * The name and signature of the console command.
@ -97,7 +98,7 @@ class SendRemindersCron extends Command
}); });
} }
private function calcLateFee($invoice, $template) :Invoice private function calcLateFee($invoice, $template): Invoice
{ {
$late_fee_amount = 0; $late_fee_amount = 0;
$late_fee_percent = 0; $late_fee_percent = 0;
@ -137,7 +138,7 @@ class SendRemindersCron extends Command
* *
* @return Invoice * @return Invoice
*/ */
private function setLateFee($invoice, $amount, $percent) :Invoice private function setLateFee($invoice, $amount, $percent): Invoice
{ {
App::forgetInstance('translator'); App::forgetInstance('translator');
$t = app('translator'); $t = app('translator');
@ -158,7 +159,7 @@ class SendRemindersCron extends Command
$fee += round($invoice->balance * $percent / 100, 2); $fee += round($invoice->balance * $percent / 100, 2);
} }
$invoice_item = new InvoiceItem; $invoice_item = new InvoiceItem();
$invoice_item->type_id = '5'; $invoice_item->type_id = '5';
$invoice_item->product_key = ctrans('texts.fee'); $invoice_item->product_key = ctrans('texts.fee');
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]); $invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]);

View File

@ -53,7 +53,7 @@ class SendTestEmails extends Command
$to_user = User::first(); $to_user = User::first();
$nmo = new NinjaMailerObject; $nmo = new NinjaMailerObject();
$nmo->mailable = new TestMailServer('Email Server Works!', config('mail.from.address')); $nmo->mailable = new TestMailServer('Email Server Works!', config('mail.from.address'));
$nmo->company = $to_user->account->companies()->first(); $nmo->company = $to_user->account->companies()->first();
$nmo->settings = $to_user->account->companies()->first()->settings; $nmo->settings = $to_user->account->companies()->first()->settings;

View File

@ -58,6 +58,7 @@ class TranslationsExport extends Command
'it', 'it',
'ja', 'ja',
'km_KH', 'km_KH',
'lo_LA',
'lt', 'lt',
'lv_LV', 'lv_LV',
'mk_MK', 'mk_MK',
@ -95,7 +96,7 @@ class TranslationsExport extends Command
*/ */
public function handle() public function handle()
{ {
$type =$this->option('type') ?? 'export'; $type = $this->option('type') ?? 'export';
if ($type == 'import') { if ($type == 'import') {
$this->import(); $this->import();
@ -137,6 +138,10 @@ class TranslationsExport extends Command
Storage::disk('local')->makeDirectory("lang/{$lang}"); Storage::disk('local')->makeDirectory("lang/{$lang}");
$translations = Lang::getLoader()->load($lang, 'texts'); $translations = Lang::getLoader()->load($lang, 'texts');
foreach($translations as $key => $value) {
$translations[$key] = html_entity_decode($value);
}
Storage::disk('local')->put("lang/{$lang}/{$lang}.json", json_encode(Arr::dot($translations), JSON_UNESCAPED_UNICODE)); Storage::disk('local')->put("lang/{$lang}/{$lang}.json", json_encode(Arr::dot($translations), JSON_UNESCAPED_UNICODE));
} }
} }

View File

@ -100,7 +100,7 @@ class TypeCheck extends Command
$entity_settings = $this->checkSettingType($client->settings); $entity_settings = $this->checkSettingType($client->settings);
$entity_settings->md5 = md5(time()); $entity_settings->md5 = md5(time());
$client->settings = $entity_settings; $client->settings = $entity_settings;
$client->save(); $client->saveQuietly();
} }
private function checkCompany($company) private function checkCompany($company)
@ -119,7 +119,7 @@ class TypeCheck extends Command
$entity_settings = $this->checkSettingType($client->settings); $entity_settings = $this->checkSettingType($client->settings);
$entity_settings->md5 = md5(time()); $entity_settings->md5 = md5(time());
$client->settings = $entity_settings; $client->settings = $entity_settings;
$client->save(); $client->saveQuietly();
}); });
Company::query()->cursor()->each(function ($company) { Company::query()->cursor()->each(function ($company) {

View File

@ -47,71 +47,71 @@ class Kernel extends ConsoleKernel
protected function schedule(Schedule $schedule) protected function schedule(Schedule $schedule)
{ {
/* Check for the latest version of Invoice Ninja */ /* Check for the latest version of Invoice Ninja */
$schedule->job(new VersionCheck)->daily(); $schedule->job(new VersionCheck())->daily();
/* Returns the number of jobs in the queue */ /* Returns the number of jobs in the queue */
$schedule->job(new QueueSize)->everyFiveMinutes()->withoutOverlapping()->name('queue-size-job')->onOneServer(); $schedule->job(new QueueSize())->everyFiveMinutes()->withoutOverlapping()->name('queue-size-job')->onOneServer();
/* Send reminders */ /* Send reminders */
$schedule->job(new ReminderJob)->hourly()->withoutOverlapping()->name('reminder-job')->onOneServer(); $schedule->job(new ReminderJob())->hourly()->withoutOverlapping()->name('reminder-job')->onOneServer();
/* Sends recurring invoices*/ /* Sends recurring invoices*/
$schedule->job(new RecurringInvoicesCron)->hourly()->withoutOverlapping()->name('recurring-invoice-job')->onOneServer(); $schedule->job(new RecurringInvoicesCron())->hourly()->withoutOverlapping()->name('recurring-invoice-job')->onOneServer();
/* Checks for scheduled tasks */ /* Checks for scheduled tasks */
$schedule->job(new TaskScheduler())->hourlyAt(10)->withoutOverlapping()->name('task-scheduler-job')->onOneServer(); $schedule->job(new TaskScheduler())->hourlyAt(10)->withoutOverlapping()->name('task-scheduler-job')->onOneServer();
/* Stale Invoice Cleanup*/ /* Stale Invoice Cleanup*/
$schedule->job(new CleanStaleInvoiceOrder)->hourlyAt(30)->withoutOverlapping()->name('stale-invoice-job')->onOneServer(); $schedule->job(new CleanStaleInvoiceOrder())->hourlyAt(30)->withoutOverlapping()->name('stale-invoice-job')->onOneServer();
/* Stale Invoice Cleanup*/ /* Stale Invoice Cleanup*/
$schedule->job(new UpdateCalculatedFields)->hourlyAt(40)->withoutOverlapping()->name('update-calculated-fields-job')->onOneServer(); $schedule->job(new UpdateCalculatedFields())->hourlyAt(40)->withoutOverlapping()->name('update-calculated-fields-job')->onOneServer();
/* Checks for large companies and marked them as is_large */ /* Checks for large companies and marked them as is_large */
$schedule->job(new CompanySizeCheck)->dailyAt('23:20')->withoutOverlapping()->name('company-size-job')->onOneServer(); $schedule->job(new CompanySizeCheck())->dailyAt('23:20')->withoutOverlapping()->name('company-size-job')->onOneServer();
/* Pulls in the latest exchange rates */ /* Pulls in the latest exchange rates */
$schedule->job(new UpdateExchangeRates)->dailyAt('23:30')->withoutOverlapping()->name('exchange-rate-job')->onOneServer(); $schedule->job(new UpdateExchangeRates())->dailyAt('23:30')->withoutOverlapping()->name('exchange-rate-job')->onOneServer();
/* Runs cleanup code for subscriptions */ /* Runs cleanup code for subscriptions */
$schedule->job(new SubscriptionCron)->dailyAt('00:01')->withoutOverlapping()->name('subscription-job')->onOneServer(); $schedule->job(new SubscriptionCron())->dailyAt('00:01')->withoutOverlapping()->name('subscription-job')->onOneServer();
/* Sends recurring invoices*/ /* Sends recurring expenses*/
$schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer(); $schedule->job(new RecurringExpensesCron())->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
/* Checks the status of the scheduler */ /* Checks the status of the scheduler */
$schedule->job(new SchedulerCheck)->dailyAt('01:10')->withoutOverlapping(); $schedule->job(new SchedulerCheck())->dailyAt('01:10')->withoutOverlapping();
/* Checks and cleans redundant files */ /* Checks and cleans redundant files */
$schedule->job(new DiskCleanup)->dailyAt('02:10')->withoutOverlapping()->name('disk-cleanup-job')->onOneServer(); $schedule->job(new DiskCleanup())->dailyAt('02:10')->withoutOverlapping()->name('disk-cleanup-job')->onOneServer();
/* Performs system maintenance such as pruning the backup table */ /* Performs system maintenance such as pruning the backup table */
$schedule->job(new SystemMaintenance)->sundays()->at('02:30')->withoutOverlapping()->name('system-maintenance-job')->onOneServer(); $schedule->job(new SystemMaintenance())->sundays()->at('02:30')->withoutOverlapping()->name('system-maintenance-job')->onOneServer();
/* Fires notifications for expired Quotes */ /* Fires notifications for expired Quotes */
$schedule->job(new QuoteCheckExpired)->dailyAt('05:10')->withoutOverlapping()->name('quote-expired-job')->onOneServer(); $schedule->job(new QuoteCheckExpired())->dailyAt('05:10')->withoutOverlapping()->name('quote-expired-job')->onOneServer();
/* Performs auto billing */ /* Performs auto billing */
$schedule->job(new AutoBillCron)->dailyAt('06:20')->withoutOverlapping()->name('auto-bill-job')->onOneServer(); $schedule->job(new AutoBillCron())->dailyAt('06:20')->withoutOverlapping()->name('auto-bill-job')->onOneServer();
/* Fires webhooks for overdue Invoice */ /* Fires webhooks for overdue Invoice */
$schedule->job(new InvoiceCheckLateWebhook)->dailyAt('07:00')->withoutOverlapping()->name('invoice-overdue-job')->onOneServer(); $schedule->job(new InvoiceCheckLateWebhook())->dailyAt('07:00')->withoutOverlapping()->name('invoice-overdue-job')->onOneServer();
/* Pulls in bank transactions from third party services */
$schedule->job(new BankTransactionSync())->everyFourHours()->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
if (Ninja::isSelfHost()) { if (Ninja::isSelfHost()) {
$schedule->call(function () { $schedule->call(function () {
Account::whereNotNull('id')->update(['is_scheduler_running' => true]); Account::query()->whereNotNull('id')->update(['is_scheduler_running' => true]);
})->everyFiveMinutes(); })->everyFiveMinutes();
} }
/* Run hosted specific jobs */ /* Run hosted specific jobs */
if (Ninja::isHosted()) { if (Ninja::isHosted()) {
$schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping(); $schedule->job(new AdjustEmailQuota())->dailyAt('23:30')->withoutOverlapping();
/* Pulls in bank transactions from third party services */
$schedule->job(new BankTransactionSync)->everyFourHours()->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
/* Checks ACH verification status and updates state to authorize when verified */ /* Checks ACH verification status and updates state to authorize when verified */
$schedule->job(new CheckACHStatus)->everySixHours()->withoutOverlapping()->name('ach-status-job')->onOneServer(); $schedule->job(new CheckACHStatus())->everySixHours()->withoutOverlapping()->name('ach-status-job')->onOneServer();
$schedule->command('ninja:check-data --database=db-ninja-01')->dailyAt('02:10')->withoutOverlapping()->name('check-data-db-1-job')->onOneServer(); $schedule->command('ninja:check-data --database=db-ninja-01')->dailyAt('02:10')->withoutOverlapping()->name('check-data-db-1-job')->onOneServer();
@ -120,7 +120,7 @@ class Kernel extends ConsoleKernel
$schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping()->name('s3-cleanup-job')->onOneServer(); $schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping()->name('s3-cleanup-job')->onOneServer();
} }
if (config('queue.default') == 'database' && Ninja::isSelfHost() && config('ninja.internal_queue_enabled') && ! config('ninja.is_docker')) { if (config('queue.default') == 'database' && Ninja::isSelfHost() && config('ninja.internal_queue_enabled') && !config('ninja.is_docker')) {
$schedule->command('queue:work database --stop-when-empty --memory=256')->everyMinute()->withoutOverlapping(); $schedule->command('queue:work database --stop-when-empty --memory=256')->everyMinute()->withoutOverlapping();
$schedule->command('queue:restart')->everyFiveMinutes()->withoutOverlapping(); $schedule->command('queue:restart')->everyFiveMinutes()->withoutOverlapping();
@ -134,7 +134,7 @@ class Kernel extends ConsoleKernel
*/ */
protected function commands() protected function commands()
{ {
$this->load(__DIR__.'/Commands'); $this->load(__DIR__ . '/Commands');
require base_path('routes/console.php'); require base_path('routes/console.php');
} }

View File

@ -64,7 +64,7 @@ class ClientSettings extends BaseSettings
* *
* @return stdClass * @return stdClass
*/ */
public static function defaults() : stdClass public static function defaults(): stdClass
{ {
$data = (object) [ $data = (object) [
'entity' => (string) Client::class, 'entity' => (string) Client::class,

View File

@ -229,7 +229,7 @@ class CompanySettings extends BaseSettings
public $require_quote_signature = false; //@TODO ben to confirm public $require_quote_signature = false; //@TODO ben to confirm
//email settings //email settings
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun' //@implemented public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun' //@implemented
public $gmail_sending_user_id = '0'; //@implemented public $gmail_sending_user_id = '0'; //@implemented
@ -493,7 +493,13 @@ class CompanySettings extends BaseSettings
public $payment_email_all_contacts = false; public $payment_email_all_contacts = false;
public $show_pdfhtml_on_mobile = true;
public $use_unapplied_payment = 'off'; //always, option, off //@implemented
public static $casts = [ public static $casts = [
'use_unapplied_payment' => 'string',
'show_pdfhtml_on_mobile' => 'bool',
'payment_email_all_contacts' => 'bool', 'payment_email_all_contacts' => 'bool',
'statement_design_id' => 'string', 'statement_design_id' => 'string',
'delivery_note_design_id' => 'string', 'delivery_note_design_id' => 'string',
@ -546,7 +552,7 @@ class CompanySettings extends BaseSettings
'use_credits_payment' => 'string', 'use_credits_payment' => 'string',
'recurring_invoice_number_pattern' => 'string', 'recurring_invoice_number_pattern' => 'string',
'recurring_invoice_number_counter' => 'int', 'recurring_invoice_number_counter' => 'int',
'client_portal_under_payment_minimum'=> 'float', 'client_portal_under_payment_minimum' => 'float',
'auto_bill_date' => 'string', 'auto_bill_date' => 'string',
'primary_color' => 'string', 'primary_color' => 'string',
'secondary_color' => 'string', 'secondary_color' => 'string',
@ -855,9 +861,9 @@ class CompanySettings extends BaseSettings
* *
* @return stdClass * @return stdClass
*/ */
public static function notificationDefaults() :stdClass public static function notificationDefaults(): stdClass
{ {
$notification = new stdClass; $notification = new stdClass();
$notification->email = []; $notification->email = [];
$notification->email = ['invoice_sent_all']; $notification->email = ['invoice_sent_all'];
@ -871,11 +877,11 @@ class CompanySettings extends BaseSettings
* *
* @return stdClass * @return stdClass
*/ */
public static function notificationAdminDefaults() :stdClass public static function notificationAdminDefaults(): stdClass
{ {
$notification = new stdClass; $notification = new stdClass();
$notification->email = []; $notification->email = [];
$notification->email = ['invoice_sent_all']; $notification->email = ['invoice_sent_all','payment_success_all','payment_manual_all'];
return $notification; return $notification;
} }
@ -888,7 +894,7 @@ class CompanySettings extends BaseSettings
* *
* @return stdClass The stdClass of PDF variables * @return stdClass The stdClass of PDF variables
*/ */
public static function getEntityVariableDefaults() :stdClass public static function getEntityVariableDefaults(): stdClass
{ {
$variables = [ $variables = [
'client_details' => [ 'client_details' => [
@ -975,7 +981,7 @@ class CompanySettings extends BaseSettings
'$product.tax', '$product.tax',
'$product.line_total', '$product.line_total',
], ],
'task_columns' =>[ 'task_columns' => [
'$task.service', '$task.service',
'$task.description', '$task.description',
'$task.rate', '$task.rate',

View File

@ -27,7 +27,7 @@ class DefaultSettings extends BaseSettings
/** /**
* @return stdClass * @return stdClass
*/ */
public static function userSettings() : stdClass public static function userSettings(): stdClass
{ {
return (object) [ return (object) [
// class_basename(User::class) => self::userSettingsObject(), // class_basename(User::class) => self::userSettingsObject(),

View File

@ -15,6 +15,23 @@ use Illuminate\Support\Facades\App;
class EmailTemplateDefaults class EmailTemplateDefaults
{ {
public array $templates = [
'email_template_invoice',
'email_template_quote',
'email_template_credit',
'email_template_payment',
'email_template_payment_partial',
'email_template_statement',
'email_template_reminder1',
'email_template_reminder2',
'email_template_reminder3',
'email_template_reminder_endless',
'email_template_custom1',
'email_template_custom2',
'email_template_custom3',
'email_template_purchase_order',
];
public static function getDefaultTemplate($template, $locale) public static function getDefaultTemplate($template, $locale)
{ {
App::setLocale($locale); App::setLocale($locale);
@ -116,12 +133,12 @@ class EmailTemplateDefaults
public static function emailInvoiceSubject() public static function emailInvoiceSubject()
{ {
return ctrans('texts.invoice_subject', ['number'=>'$number', 'account'=>'$company.name']); return ctrans('texts.invoice_subject', ['number' => '$number', 'account' => '$company.name']);
} }
public static function emailCreditSubject() public static function emailCreditSubject()
{ {
return ctrans('texts.credit_subject', ['number'=>'$number', 'account'=>'$company.name']); return ctrans('texts.credit_subject', ['number' => '$number', 'account' => '$company.name']);
} }
public static function emailInvoiceTemplate() public static function emailInvoiceTemplate()
@ -140,7 +157,7 @@ class EmailTemplateDefaults
public static function emailQuoteSubject() public static function emailQuoteSubject()
{ {
return ctrans('texts.quote_subject', ['number'=>'$number', 'account'=>'$company.name']); return ctrans('texts.quote_subject', ['number' => '$number', 'account' => '$company.name']);
} }
public static function emailQuoteTemplate() public static function emailQuoteTemplate()
@ -195,7 +212,7 @@ class EmailTemplateDefaults
public static function emailReminder1Subject() public static function emailReminder1Subject()
{ {
return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); return ctrans('texts.reminder_subject', ['invoice' => '$number', 'account' => '$company.name']);
} }
public static function emailReminder1Template() public static function emailReminder1Template()
@ -205,7 +222,7 @@ class EmailTemplateDefaults
public static function emailReminder2Subject() public static function emailReminder2Subject()
{ {
return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); return ctrans('texts.reminder_subject', ['invoice' => '$number', 'account' => '$company.name']);
} }
public static function emailReminder2Template() public static function emailReminder2Template()
@ -215,7 +232,7 @@ class EmailTemplateDefaults
public static function emailReminder3Subject() public static function emailReminder3Subject()
{ {
return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); return ctrans('texts.reminder_subject', ['invoice' => '$number', 'account' => '$company.name']);
} }
public static function emailReminder3Template() public static function emailReminder3Template()
@ -225,7 +242,7 @@ class EmailTemplateDefaults
public static function emailReminderEndlessSubject() public static function emailReminderEndlessSubject()
{ {
return ctrans('texts.reminder_subject', ['invoice'=>'$number', 'account'=>'$company.name']); return ctrans('texts.reminder_subject', ['invoice' => '$number', 'account' => '$company.name']);
} }
public static function emailReminderEndlessTemplate() public static function emailReminderEndlessTemplate()

View File

@ -45,7 +45,7 @@ class EmailReport
/** /**
* The date range the statement should include * The date range the report should include
* *
* @var string * @var string
*/ */
@ -67,7 +67,45 @@ class EmailReport
*/ */
public string $end_date = ''; public string $end_date = '';
/******************************* Parameters **********************************/
/** @var string $report_name */ /** @var string $report_name */
public string $report_name = ''; public string $report_name = '';
/**
* Optional array of report keys for
* filter the columns of the report
*
* @var array $report_keys
*
* */
public array $report_keys = [];
/** Profit Loss Parameters */
public bool $is_income_billed = true;
public bool $is_expense_billed = true;
public bool $include_tax = true;
/**
* Comma separated string of statuses for filtering the Invoice report
*
* all
* draft
* sent
* paid
* unpaid
* overdue
* viewed
*
* */
public string $status = '';
/**
* Comma separated list of product.product_keys
* to filter the report by
*/
public string $product_key = '';
} }

View File

@ -8,11 +8,11 @@
* *
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\DataMapper\Settings; namespace App\DataMapper\Settings;
class SettingsData class SettingsData
{ {
public bool $auto_archive_invoice = false; // @implemented public bool $auto_archive_invoice = false; // @implemented
public string $qr_iban = ''; //@implemented public string $qr_iban = ''; //@implemented

View File

@ -219,7 +219,7 @@ class BaseRule implements RuleInterface
try { try {
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();
}catch(\Exception $e) { } catch(\Exception $e) {
} }
} }
@ -264,14 +264,14 @@ class BaseRule implements RuleInterface
return USStates::getState(strlen($this->client->postal_code) > 1 ? $this->client->postal_code : $this->client->shipping_postal_code); return USStates::getState(strlen($this->client->postal_code) > 1 ? $this->client->postal_code : $this->client->shipping_postal_code);
} catch (\Exception $e) { } catch (\Exception $e) {
return $this->client->company->country()->iso_3166_2 == 'US' ? $this->client->company->tax_data->seller_subregion : 'CA'; return 'CA';
} }
} }
public function isTaxableRegion(): bool public function isTaxableRegion(): bool
{ {
return $this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions || return $this->client->company->tax_data->regions->{$this->client_region}->tax_all_subregions ||
(property_exists($this->client->company->tax_data->regions->{$this->client_region}->subregions, $this->client_subregion) && $this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax); (property_exists($this->client->company->tax_data->regions->{$this->client_region}->subregions, $this->client_subregion) && ($this->client->company->tax_data->regions->{$this->client_region}->subregions->{$this->client_subregion}->apply_tax ?? false));
} }
public function defaultForeign(): self public function defaultForeign(): self
@ -319,6 +319,7 @@ class BaseRule implements RuleInterface
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item), Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item),
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item), Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item),
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item), Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item),
Product::PRODUCT_TYPE_ZERO_RATED => $this->zeroRated($item),
default => $this->defaultForeign(), default => $this->defaultForeign(),
}; };
@ -327,6 +328,14 @@ class BaseRule implements RuleInterface
} }
public function zeroRated($item): self
{
$this->tax_rate1 = 0;
$this->tax_name1 = ctrans('texts.zero_rated');
return $this;
}
public function taxByType(mixed $type): self public function taxByType(mixed $type): self
{ {
return $this; return $this;

View File

@ -11,6 +11,7 @@
namespace App\DataMapper\Tax\DE; namespace App\DataMapper\Tax\DE;
use App\DataMapper\InvoiceItem;
use App\DataMapper\Tax\BaseRule; use App\DataMapper\Tax\BaseRule;
use App\DataMapper\Tax\RuleInterface; use App\DataMapper\Tax\RuleInterface;
use App\Models\Product; use App\Models\Product;
@ -63,7 +64,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxByType($item): self public function taxByType($item): self
{ {
if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id')) { if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id') || (isset($item->type_id) && $item->type_id == '5')) {
return $this->taxExempt($item); return $this->taxExempt($item);
} }

View File

@ -36,4 +36,10 @@ interface RuleInterface
public function override($item); public function override($item);
public function calculateRates(); public function calculateRates();
public function regionWithNoTaxCoverage(string $iso_3166_2): bool;
public function setEntity($entity): self;
public function shouldCalcTax(): bool;
} }

View File

@ -13,7 +13,6 @@ namespace App\DataMapper\Tax;
class TaxModel class TaxModel
{ {
/** @var string $seller_subregion */ /** @var string $seller_subregion */
public string $seller_subregion = 'CA'; public string $seller_subregion = 'CA';

View File

@ -22,7 +22,6 @@ use App\Models\Product;
*/ */
class Rule extends BaseRule implements RuleInterface class Rule extends BaseRule implements RuleInterface
{ {
/** @var string $seller_region */ /** @var string $seller_region */
public string $seller_region = 'US'; public string $seller_region = 'US';

View File

@ -51,7 +51,7 @@ class BaseTransaction implements TransactionInterface
'credit_status', 'credit_status',
]; ];
public function transform(array $data) :array public function transform(array $data): array
{ {
// $invoice = $data['invoice']; // $invoice = $data['invoice'];
// $payment = $data['payment']; // $payment = $data['payment'];
@ -66,7 +66,7 @@ class BaseTransaction implements TransactionInterface
$data['client'], $data['client'],
$data['credit'], $data['credit'],
['metadata' => $data['metadata']], ['metadata' => $data['metadata']],
['event_id' => $this->event_id, 'timestamp' =>time()], ['event_id' => $this->event_id, 'timestamp' => time()],
); );
// return [ // return [
// 'event_id' => $this->event_id, // 'event_id' => $this->event_id,

View File

@ -13,5 +13,5 @@ namespace App\DataMapper\Transactions;
interface TransactionInterface interface TransactionInterface
{ {
public function transform(array $data) :array; public function transform(array $data): array;
} }

59398
app/DataProviders/Domains.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class AccountCreated class AccountCreated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $user; public $user;

View File

@ -21,7 +21,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class StripeConnectFailure class StripeConnectFailure
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public Company $company, public string $db) public function __construct(public Company $company, public string $db)
{ {

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class ClientWasArchived class ClientWasArchived
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Client * @var Client

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CompanyDocumentsDeleted class CompanyDocumentsDeleted
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Company * @var Company

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class ContactLoggedIn class ContactLoggedIn
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $client_contact; public $client_contact;

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasArchived class CreditWasArchived
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $credit; public $credit;

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasCreated class CreditWasCreated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $credit; public $credit;

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasDeleted class CreditWasDeleted
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $credit; public $credit;

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasEmailed class CreditWasEmailed
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $invitation; public $invitation;

View File

@ -18,7 +18,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasEmailedAndFailed class CreditWasEmailedAndFailed
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $credit; public $credit;

View File

@ -19,7 +19,9 @@ use Illuminate\Queue\SerializesModels;
class CreditWasUpdated class CreditWasUpdated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $credit; public $credit;

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class DesignWasArchived class DesignWasArchived
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public Design $design, public Company $company, public array $event_vars) public function __construct(public Design $design, public Company $company, public array $event_vars)
{ {

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class DocumentWasArchived class DocumentWasArchived
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Document * @var Document

View File

@ -24,7 +24,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class InvoiceWasCreated implements ShouldBroadcast class InvoiceWasCreated implements ShouldBroadcast
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Invoice * @var Invoice

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class InvoiceWasUpdated class InvoiceWasUpdated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Invoice * @var Invoice

View File

@ -20,7 +20,9 @@ use Illuminate\Queue\SerializesModels;
class MethodDeleted class MethodDeleted
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var ClientGatewayToken * @var ClientGatewayToken

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class PaymentWasEmailed class PaymentWasEmailed
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* Create a new event instance. * Create a new event instance.

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class PaymentWasEmailedAndFailed class PaymentWasEmailedAndFailed
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Payment * @var Payment

View File

@ -20,7 +20,9 @@ use Illuminate\Queue\SerializesModels;
class QuoteWasApproved class QuoteWasApproved
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $contact; public $contact;

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class RecurringInvoiceWasUpdated class RecurringInvoiceWasUpdated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public RecurringInvoice $recurring_invoice, public Company $company, public array $event_vars) public function __construct(public RecurringInvoice $recurring_invoice, public Company $company, public array $event_vars)
{ {

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class RecurringQuoteWasUpdated class RecurringQuoteWasUpdated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public RecurringQuote $recurring_quote, public Company $company, public array $event_vars) public function __construct(public RecurringQuote $recurring_quote, public Company $company, public array $event_vars)

View File

@ -10,7 +10,9 @@ use Illuminate\Queue\SerializesModels;
class SubscriptionWasCreated class SubscriptionWasCreated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* @var Subscription * @var Subscription

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserLoggedIn class UserLoggedIn
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public User $user, public Company $company, public array $event_vars) public function __construct(public User $user, public Company $company, public array $event_vars)
{ {

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserWasArchived class UserWasArchived
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public User $user, public User $creating_user, public Company $company, public array $event_vars) public function __construct(public User $user, public User $creating_user, public Company $company, public array $event_vars)
{ {

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserWasCreated class UserWasCreated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public function __construct(public User $user, public User $creating_user, public Company $company, public array $event_vars, public $is_react = true) public function __construct(public User $user, public User $creating_user, public Company $company, public array $event_vars, public $is_react = true)
{ {

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserWasDeleted class UserWasDeleted
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $user; public $user;

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserWasRestored class UserWasRestored
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $user; public $user;

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class UserWasUpdated class UserWasUpdated
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $user; public $user;

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/ */
class VendorContactLoggedIn class VendorContactLoggedIn
{ {
use Dispatchable, InteractsWithSockets, SerializesModels; use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/** /**
* Create a new event instance. * Create a new event instance.

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -55,14 +55,12 @@ class Handler extends ExceptionHandler
protected $selfHostDontReport = [ protected $selfHostDontReport = [
FilePermissionsFailure::class, FilePermissionsFailure::class,
PDOException::class,
MaxAttemptsExceededException::class, MaxAttemptsExceededException::class,
CommandNotFoundException::class, CommandNotFoundException::class,
ValidationException::class, ValidationException::class,
ModelNotFoundException::class, ModelNotFoundException::class,
NotFoundHttpException::class, NotFoundHttpException::class,
UnableToCreateDirectory::class, UnableToCreateDirectory::class,
ConnectException::class,
RuntimeException::class, RuntimeException::class,
InvalidArgumentException::class, InvalidArgumentException::class,
CredentialsException::class, CredentialsException::class,
@ -104,10 +102,10 @@ class Handler extends ExceptionHandler
if (Ninja::isHosted()) { if (Ninja::isHosted()) {
if($exception instanceof ThrottleRequestsException && class_exists(\Modules\Admin\Events\ThrottledExceptionRaised::class)) { // if($exception instanceof ThrottleRequestsException && class_exists(\Modules\Admin\Events\ThrottledExceptionRaised::class)) {
$uri = urldecode(request()->getRequestUri()); // $uri = urldecode(request()->getRequestUri());
// event(new \Modules\Admin\Events\ThrottledExceptionRaised(auth()->user()?->account?->key, $uri, request()->ip())); // event(new \Modules\Admin\Events\ThrottledExceptionRaised(auth()->user()?->account?->key, $uri, request()->ip()));
} // }
Integration::configureScope(function (Scope $scope): void { Integration::configureScope(function (Scope $scope): void {
$name = 'hosted@invoiceninja.com'; $name = 'hosted@invoiceninja.com';
@ -214,7 +212,7 @@ class Handler extends ExceptionHandler
public function render($request, Throwable $exception) public function render($request, Throwable $exception)
{ {
if ($exception instanceof ModelNotFoundException && $request->expectsJson()) { if ($exception instanceof ModelNotFoundException && $request->expectsJson()) {
return response()->json(['message'=>$exception->getMessage()], 400); return response()->json(['message' => $exception->getMessage()], 400);
} elseif ($exception instanceof InternalPDFFailure && $request->expectsJson()) { } elseif ($exception instanceof InternalPDFFailure && $request->expectsJson()) {
return response()->json(['message' => $exception->getMessage()], 500); return response()->json(['message' => $exception->getMessage()], 500);
} elseif ($exception instanceof PhantomPDFFailure && $request->expectsJson()) { } elseif ($exception instanceof PhantomPDFFailure && $request->expectsJson()) {
@ -222,11 +220,11 @@ class Handler extends ExceptionHandler
} elseif ($exception instanceof FilePermissionsFailure) { } elseif ($exception instanceof FilePermissionsFailure) {
return response()->json(['message' => $exception->getMessage()], 500); return response()->json(['message' => $exception->getMessage()], 500);
} elseif ($exception instanceof ThrottleRequestsException && $request->expectsJson()) { } elseif ($exception instanceof ThrottleRequestsException && $request->expectsJson()) {
return response()->json(['message'=>'Too many requests'], 429); return response()->json(['message' => 'Too many requests'], 429);
// } elseif ($exception instanceof FatalThrowableError && $request->expectsJson()) { // } elseif ($exception instanceof FatalThrowableError && $request->expectsJson()) {
// return response()->json(['message'=>'Fatal error'], 500); //@deprecated // return response()->json(['message'=>'Fatal error'], 500); //@deprecated
} elseif ($exception instanceof AuthorizationException && $request->expectsJson()) { } elseif ($exception instanceof AuthorizationException && $request->expectsJson()) {
return response()->json(['message'=> $exception->getMessage()], 401); return response()->json(['message' => $exception->getMessage()], 401);
} elseif ($exception instanceof TokenMismatchException) { } elseif ($exception instanceof TokenMismatchException) {
return redirect() return redirect()
->back() ->back()
@ -235,9 +233,9 @@ class Handler extends ExceptionHandler
'message' => ctrans('texts.token_expired'), 'message' => ctrans('texts.token_expired'),
'message-type' => 'danger', ]); 'message-type' => 'danger', ]);
} elseif ($exception instanceof NotFoundHttpException && $request->expectsJson()) { } elseif ($exception instanceof NotFoundHttpException && $request->expectsJson()) {
return response()->json(['message'=>'Route does not exist'], 404); return response()->json(['message' => 'Route does not exist'], 404);
} elseif ($exception instanceof MethodNotAllowedHttpException && $request->expectsJson()) { } elseif ($exception instanceof MethodNotAllowedHttpException && $request->expectsJson()) {
return response()->json(['message'=>'Method not supported for this route'], 404); return response()->json(['message' => 'Method not supported for this route'], 404);
} elseif ($exception instanceof ValidationException && $request->expectsJson()) { } elseif ($exception instanceof ValidationException && $request->expectsJson()) {
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422); return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
} elseif ($exception instanceof RelationNotFoundException && $request->expectsJson()) { } elseif ($exception instanceof RelationNotFoundException && $request->expectsJson()) {
@ -271,6 +269,9 @@ class Handler extends ExceptionHandler
case 'vendor': case 'vendor':
$login = 'vendor.catchall'; $login = 'vendor.catchall';
break; break;
case 'ronin':
$login = 'ronin.login';
break;
default: default:
$login = 'default'; $login = 'default';
break; break;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -9,7 +9,6 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;

View File

@ -25,7 +25,6 @@ use League\Csv\Writer;
class ActivityExport extends BaseExport class ActivityExport extends BaseExport
{ {
private $entity_transformer; private $entity_transformer;
public string $date_key = 'created_at'; public string $date_key = 'created_at';
@ -105,8 +104,6 @@ class ActivityExport extends BaseExport
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format; $this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
// ksort($this->entity_keys);
if (count($this->input['report_keys']) == 0) { if (count($this->input['report_keys']) == 0) {
$this->input['report_keys'] = array_values($this->entity_keys); $this->input['report_keys'] = array_values($this->entity_keys);
} }
@ -143,10 +140,9 @@ class ActivityExport extends BaseExport
$this->csv->insertOne($this->buildActivityRow($activity)); $this->csv->insertOne($this->buildActivityRow($activity));
} }
private function decorateAdvancedFields(Task $task, array $entity) :array private function decorateAdvancedFields(Task $task, array $entity): array
{ {
return $entity; return $entity;
} }

View File

@ -11,27 +11,29 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Models\Task;
use App\Models\User;
use App\Models\Quote;
use App\Models\Client; use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Document; use App\Models\Vendor;
use App\Utils\Helpers;
use App\Models\Company;
use App\Models\Expense; use App\Models\Expense;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Payment; use App\Models\Payment;
use App\Models\Product; use App\Models\Product;
use App\Models\PurchaseOrder; use App\Models\Document;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Models\Task;
use App\Models\Vendor;
use App\Transformers\PaymentTransformer;
use App\Transformers\TaskTransformer;
use App\Utils\Helpers;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use League\Fractal\Manager; use League\Fractal\Manager;
use App\Models\ClientContact;
use App\Models\PurchaseOrder;
use Illuminate\Support\Carbon;
use App\Utils\Traits\MakesHash;
use App\Models\RecurringInvoice;
use App\Jobs\Document\ZipDocuments;
use App\Transformers\TaskTransformer;
use App\Transformers\PaymentTransformer;
use Illuminate\Database\Eloquent\Builder;
use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Serializer\ArraySerializer;
class BaseExport class BaseExport
@ -387,6 +389,8 @@ class BaseExport
protected array $expense_report_keys = [ protected array $expense_report_keys = [
'amount' => 'expense.amount', 'amount' => 'expense.amount',
'tax_amount' => 'expense.tax_amount',
'net_amount' => 'expense.net_amount',
'category' => 'expense.category_id', 'category' => 'expense.category_id',
// 'client' => 'expense.client_id', // 'client' => 'expense.client_id',
'custom_value1' => 'expense.custom_value1', 'custom_value1' => 'expense.custom_value1',
@ -446,9 +450,20 @@ class BaseExport
protected function filterByClients($query) protected function filterByClients($query)
{ {
if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') { if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') {
if(!is_int($this->input['client_id'])) {
$this->input['client_id'] = $this->decodePrimaryKey($this->input['client_id']);
}
$client = Client::withTrashed()->find($this->input['client_id']); $client = Client::withTrashed()->find($this->input['client_id']);
if(!$client) {
return $query;
}
$this->client_description = $client->present()->name; $this->client_description = $client->present()->name;
return $query->where('client_id', $this->input['client_id']); return $query->where('client_id', $this->input['client_id']);
} elseif(isset($this->input['clients']) && count($this->input['clients']) > 0) { } elseif(isset($this->input['clients']) && count($this->input['clients']) > 0) {
$this->client_description = 'Multiple Clients'; $this->client_description = 'Multiple Clients';
@ -457,7 +472,7 @@ class BaseExport
return $query; return $query;
} }
protected function resolveKey($key, $entity, $transformer) :string protected function resolveKey($key, $entity, $transformer): string
{ {
$parts = explode(".", $key); $parts = explode(".", $key);
@ -812,7 +827,14 @@ class BaseExport
} }
public function applyFilters(Builder $query): Builder /**
* Apply Product Filters
*
* @param Builder $query
*
* @return Builder
*/
public function applyProductFilters(Builder $query): Builder
{ {
if(isset($this->input['product_key'])) { if(isset($this->input['product_key'])) {
@ -830,13 +852,328 @@ class BaseExport
return $query; return $query;
} }
protected function addInvoiceStatusFilter($query, $status): Builder /**
* Add Client Filter
*
* @param Builder $query
* @param mixed $clients
*
* @return Builder
*/
protected function addClientFilter(Builder $query, $clients): Builder
{
if(is_string($clients)) {
$clients = explode(',', $clients);
}
$transformed_clients = $this->transformKeys($clients);
nlog($clients);
nlog($transformed_clients);
if(count($transformed_clients) > 0) {
$query->whereIn('client_id', $transformed_clients);
}
return $query;
}
/**
* Add Vendor Filter
*
* @param Builder $query
* @param string $vendors
*
* @return Builder
*/
protected function addVendorFilter(Builder$query, string $vendors): Builder
{
if(is_string($vendors)) {
$vendors = explode(',', $vendors);
}
$transformed_vendors = $this->transformKeys($vendors);
if(count($transformed_vendors) > 0) {
$query->whereIn('vendor_id', $transformed_vendors);
}
return $query;
}
/**
* AddProjectFilter
*
* @param Builder $query
* @param string $projects
*
* @return Builder
*/
protected function addProjectFilter(Builder $query, string $projects): Builder
{
if(is_string($projects)) {
$projects = explode(',', $projects);
}
$transformed_projects = $this->transformKeys($projects);
if(count($transformed_projects) > 0) {
$query->whereIn('project_id', $transformed_projects);
}
return $query;
}
/**
* Add Category Filter
*
* @param Builder $query
* @param string $expense_categories
*
* @return Builder
*/
protected function addCategoryFilter(Builder $query, string $expense_categories): Builder
{
if(is_string($expense_categories)) {
$expense_categories = explode(',', $expense_categories);
}
$transformed_expense_categories = $this->transformKeys($expense_categories);
if(count($transformed_expense_categories) > 0) {
$query->whereIn('category_id', $transformed_expense_categories);
}
return $query;
}
/**
* Add Payment Status Filters
*
* @param Builder $query
* @param string $status
*
* @return Builder
*/
protected function addPaymentStatusFilters(Builder $query, string $status): Builder
{ {
$status_parameters = explode(',', $status); $status_parameters = explode(',', $status);
if(in_array('all', $status_parameters) || count($status_parameters) == 0) {
return $query;
}
if(in_array('all', $status_parameters)) { $query->where(function ($query) use ($status_parameters) {
$payment_filters = [];
if (in_array('pending', $status_parameters)) {
$payment_filters[] = Payment::STATUS_PENDING;
}
if (in_array('cancelled', $status_parameters)) {
$payment_filters[] = Payment::STATUS_CANCELLED;
}
if (in_array('failed', $status_parameters)) {
$payment_filters[] = Payment::STATUS_FAILED;
}
if (in_array('completed', $status_parameters)) {
$payment_filters[] = Payment::STATUS_COMPLETED;
}
if (in_array('partially_refunded', $status_parameters)) {
$payment_filters[] = Payment::STATUS_PARTIALLY_REFUNDED;
}
if (in_array('refunded', $status_parameters)) {
$payment_filters[] = Payment::STATUS_REFUNDED;
}
if (count($payment_filters) > 0) {
$query->whereIn('status_id', $payment_filters);
}
if(in_array('partially_unapplied', $status_parameters)) {
$query->whereColumn('amount', '>', 'applied')->where('refunded', 0);
}
});
return $query;
}
/**
* Add RecurringInvoice Status Filter
*
* @param Builder $query
* @param string $status
*
* @return Builder
*/
protected function addRecurringInvoiceStatusFilter(Builder $query, string $status): Builder
{
$status_parameters = explode(',', $status);
if (in_array('all', $status_parameters) || count($status_parameters) == 0){
return $query;
}
$recurring_filters = [];
if (in_array('active', $status_parameters)) {
$recurring_filters[] = RecurringInvoice::STATUS_ACTIVE;
}
if (in_array('paused', $status_parameters)) {
$recurring_filters[] = RecurringInvoice::STATUS_PAUSED;
}
if (in_array('completed', $status_parameters)) {
$recurring_filters[] = RecurringInvoice::STATUS_COMPLETED;
}
if (count($recurring_filters) >= 1) {
return $query->whereIn('status_id', $recurring_filters);
}
return $query;
}
/**
* Add QuoteStatus Filter
*
* @param Builder $query
* @param string $status
*
* @return Builder
*/
protected function addQuoteStatusFilter(Builder $query, string $status): Builder
{
$status_parameters = explode(',', $status);
if (in_array('all', $status_parameters)) {
return $query;
}
$query->where(function ($query) use ($status_parameters) {
if (in_array('sent', $status_parameters)) {
$query->orWhere(function ($q) {
$q->where('status_id', Quote::STATUS_SENT)
->whereNull('due_date')
->orWhere('due_date', '>=', now()->toDateString());
});
}
$quote_filters = [];
if (in_array('draft', $status_parameters)) {
$quote_filters[] = Quote::STATUS_DRAFT;
}
if (in_array('approved', $status_parameters)) {
$quote_filters[] = Quote::STATUS_APPROVED;
}
if (count($quote_filters) > 0) {
$query->orWhereIn('status_id', $quote_filters);
}
if (in_array('expired', $status_parameters)) {
$query->orWhere(function ($q) {
$q->where('status_id', Quote::STATUS_SENT)
->whereNotNull('due_date')
->where('due_date', '<=', now()->toDateString());
});
}
if (in_array('upcoming', $status_parameters)) {
$query->orWhere(function ($q) {
$q->where('status_id', Quote::STATUS_SENT)
->where('due_date', '>=', now()->toDateString())
->orderBy('due_date', 'DESC');
});
}
if(in_array('converted', $status_parameters)) {
$query->orWhere(function ($q) {
$q->whereNotNull('invoice_id');
});
}
});
return $query;
}
/**
* Add PurchaseOrder Status Filter
*
* @param Builder $query
* @param string $status
*
* @return Builder
*/
protected function addPurchaseOrderStatusFilter(Builder $query, string $status): Builder
{
$status_parameters = explode(',', $status);
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
return $query;
}
$query->where(function ($query) use ($status_parameters) {
$po_status = [];
if (in_array('draft', $status_parameters)) {
$po_status[] = PurchaseOrder::STATUS_DRAFT;
}
if (in_array('sent', $status_parameters)) {
$query->orWhere(function ($q) {
$q->where('status_id', PurchaseOrder::STATUS_SENT)
->whereNull('due_date')
->orWhere('due_date', '>=', now()->toDateString());
});
}
if (in_array('accepted', $status_parameters)) {
$po_status[] = PurchaseOrder::STATUS_ACCEPTED;
}
if (in_array('cancelled', $status_parameters)) {
$po_status[] = PurchaseOrder::STATUS_CANCELLED;
}
if (count($po_status) >= 1) {
$query->whereIn('status_id', $po_status);
}
});
return $query;
}
/**
* Add Invoice Status Filter
*
* @param Builder $query
* @param string $status
* @return Builder
*/
protected function addInvoiceStatusFilter(Builder $query, string $status): Builder
{
$status_parameters = explode(',', $status);
if(in_array('all', $status_parameters) || count($status_parameters) == 0) {
return $query; return $query;
} }
@ -861,6 +1198,10 @@ class BaseExport
$invoice_filters[] = Invoice::STATUS_PARTIAL; $invoice_filters[] = Invoice::STATUS_PARTIAL;
} }
if (in_array('cancelled', $status_parameters)) {
$invoice_filters[] = Invoice::STATUS_CANCELLED;
}
if (count($invoice_filters) > 0) { if (count($invoice_filters) > 0) {
$nested->whereIn('status_id', $invoice_filters); $nested->whereIn('status_id', $invoice_filters);
} }
@ -885,9 +1226,15 @@ class BaseExport
return $query; return $query;
} }
protected function addDateRange($query) /**
* Add Date Range
*
* @param Builder $query
* @return Builder
*/
protected function addDateRange(Builder $query): Builder
{ {
$query = $this->applyFilters($query); $query = $this->applyProductFilters($query);
$date_range = $this->input['date_range']; $date_range = $this->input['date_range'];
@ -985,7 +1332,7 @@ class BaseExport
return array_merge($this->{$entity_report_keys}, $this->item_report_keys); return array_merge($this->{$entity_report_keys}, $this->item_report_keys);
} }
public function buildHeader() :array public function buildHeader(): array
{ {
$helper = new Helpers(); $helper = new Helpers();
@ -1220,4 +1567,35 @@ class BaseExport
return $clean_row; return $clean_row;
} }
public function queueDocuments(Builder $query)
{
nlog("queue docs pls");
if($query->getModel() instanceof Document) {
$documents = $query->pluck('id')->toArray();
} else {
$documents = $query->cursor()
->map(function ($entity) {
return $entity->documents()->pluck('id')->toArray();
})->flatten()
->toArray();
}
nlog($documents);
if(count($documents) > 0) {
$user = $this->company->owner();
if(auth()->user() && auth()->user()->account_id == $this->company->account_id) {
$user = auth()->user();
}
if($this->input['user_id'] ?? false) {
$user = User::where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first();
}
ZipDocuments::dispatch($documents, $this->company, $user);
}
}
} }

View File

@ -11,17 +11,17 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\Company;
use App\Transformers\ClientContactTransformer;
use App\Transformers\ClientTransformer;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Number; use App\Utils\Number;
use App\Models\Client;
use League\Csv\Writer;
use App\Models\Company;
use App\Libraries\MultiDB;
use Illuminate\Support\Facades\App;
use App\Export\Decorators\Decorator;
use App\Transformers\ClientTransformer;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use App\Transformers\ClientContactTransformer; use Illuminate\Support\Facades\App;
use League\Csv\Writer;
class ClientExport extends BaseExport class ClientExport extends BaseExport
{ {
@ -127,10 +127,14 @@ class ClientExport extends BaseExport
$query = Client::query()->with('contacts') $query = Client::query()->with('contacts')
->withTrashed() ->withTrashed()
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -153,7 +157,7 @@ class ClientExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Client $client) :array private function buildRow(Client $client): array
{ {
$transformed_contact = false; $transformed_contact = false;
@ -175,10 +179,14 @@ class ClientExport extends BaseExport
} elseif (is_array($parts) && $parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) { } elseif (is_array($parts) && $parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
$entity[$key] = $transformed_contact[$parts[1]]; $entity[$key] = $transformed_contact[$parts[1]];
} else { } else {
$entity[$key] = ''; // nlog($key);
$entity[$key] = $this->decorator->transform($key, $client);
// $entity[$key] = '';
} }
} }
// return $entity;
return $this->decorateAdvancedFields($client, $entity); return $this->decorateAdvancedFields($client, $entity);
} }
@ -207,7 +215,7 @@ class ClientExport extends BaseExport
return $clean_row; return $clean_row;
} }
private function decorateAdvancedFields(Client $client, array $entity) :array private function decorateAdvancedFields(Client $client, array $entity): array
{ {
if (in_array('client.user', $this->input['report_keys'])) { if (in_array('client.user', $this->input['report_keys'])) {
$entity['client.user'] = $client->user->present()->name(); $entity['client.user'] = $client->user->present()->name();
@ -217,22 +225,6 @@ class ClientExport extends BaseExport
$entity['client.assigned_user'] = $client->assigned_user ? $client->user->present()->name() : ''; $entity['client.assigned_user'] = $client->assigned_user ? $client->user->present()->name() : '';
} }
if (in_array('client.country_id', $this->input['report_keys'])) {
$entity['client.country_id'] = $client->country ? ctrans("texts.country_{$client->country->name}") : '';
}
if (in_array('client.shipping_country_id', $this->input['report_keys'])) {
$entity['client.shipping_country_id'] = $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : '';
}
if (in_array('client.currency_id', $this->input['report_keys'])) {
$entity['client.currency_id'] = $client->currency() ? $client->currency()->code : $client->company->currency()->code;
}
if (in_array('client.industry_id', $this->input['report_keys'])) {
$entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : '';
}
if (in_array('client.classification', $this->input['report_keys']) && isset($client->classification)) { if (in_array('client.classification', $this->input['report_keys']) && isset($client->classification)) {
$entity['client.classification'] = ctrans("texts.{$client->classification}") ?? ''; $entity['client.classification'] = ctrans("texts.{$client->classification}") ?? '';
} }

View File

@ -11,24 +11,26 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company;
use App\Transformers\ClientContactTransformer;
use App\Transformers\ClientTransformer;
use App\Utils\Ninja; use App\Utils\Ninja;
use Illuminate\Contracts\Database\Eloquent\Builder; use App\Models\Client;
use Illuminate\Support\Facades\App;
use League\Csv\Writer; use League\Csv\Writer;
use App\Models\Company;
use App\Libraries\MultiDB;
use App\Models\ClientContact;
use Illuminate\Support\Facades\App;
use App\Export\Decorators\Decorator;
use App\Transformers\ClientTransformer;
use App\Transformers\ClientContactTransformer;
use Illuminate\Database\Eloquent\Builder;
class ContactExport extends BaseExport class ContactExport extends BaseExport
{ {
private ClientTransformer $client_transformer; private ClientTransformer $client_transformer;
private ClientContactTransformer $contact_transformer; private ClientContactTransformer $contact_transformer;
private Decorator $decorator;
public Writer $csv; public Writer $csv;
public string $date_key = 'created_at'; public string $date_key = 'created_at';
@ -39,6 +41,7 @@ class ContactExport extends BaseExport
$this->input = $input; $this->input = $input;
$this->client_transformer = new ClientTransformer(); $this->client_transformer = new ClientTransformer();
$this->contact_transformer = new ClientContactTransformer(); $this->contact_transformer = new ClientContactTransformer();
$this->decorator = new Decorator();
} }
private function init(): Builder private function init(): Builder
@ -102,7 +105,7 @@ class ContactExport extends BaseExport
} }
private function buildRow(ClientContact $contact) :array private function buildRow(ClientContact $contact): array
{ {
$transformed_contact = false; $transformed_contact = false;
@ -119,14 +122,17 @@ class ContactExport extends BaseExport
} elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) { } elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
$entity[$key] = $transformed_contact[$parts[1]]; $entity[$key] = $transformed_contact[$parts[1]];
} else { } else {
$entity[$key] = ''; // nlog($key);
} $entity[$key] = $this->decorator->transform($key, $contact);
} // $entity[$key] = '';
}
}
// return $entity;
return $this->decorateAdvancedFields($contact->client, $entity); return $this->decorateAdvancedFields($contact->client, $entity);
} }
private function decorateAdvancedFields(Client $client, array $entity) :array private function decorateAdvancedFields(Client $client, array $entity): array
{ {
if (in_array('client.country_id', $this->input['report_keys'])) { if (in_array('client.country_id', $this->input['report_keys'])) {
$entity['country'] = $client->country ? ctrans("texts.country_{$client->country->name}") : ''; $entity['country'] = $client->country ? ctrans("texts.country_{$client->country->name}") : '';
@ -144,6 +150,15 @@ class ContactExport extends BaseExport
$entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : ''; $entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : '';
} }
if (in_array('client.user_id', $this->input['report_keys'])) {
$entity['client.user_id'] = $client->user ? $client->user->present()->name() : '';
}
if (in_array('client.assigned_user_id', $this->input['report_keys'])) {
$entity['client.assigned_user_id'] = $client->assigned_user ? $client->assigned_user->present()->name() : '';
}
return $entity; return $entity;
} }
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Credit; use App\Models\Credit;
@ -23,9 +24,10 @@ use League\Csv\Writer;
class CreditExport extends BaseExport class CreditExport extends BaseExport
{ {
private CreditTransformer $credit_transformer; private CreditTransformer $credit_transformer;
private Decorator $decorator;
public string $date_key = 'created_at'; public string $date_key = 'created_at';
public Writer $csv; public Writer $csv;
@ -35,6 +37,7 @@ class CreditExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->credit_transformer = new CreditTransformer(); $this->credit_transformer = new CreditTransformer();
$this->decorator = new Decorator();
} }
public function returnJson() public function returnJson()
@ -100,10 +103,18 @@ class CreditExport extends BaseExport
->withTrashed() ->withTrashed()
->with('client') ->with('client')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['status'] ?? false) {
$query = $this->addCreditStatusFilter($query, $this->input['status']);
}
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -124,7 +135,7 @@ class CreditExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Credit $credit) :array private function buildRow(Credit $credit): array
{ {
$transformed_credit = $this->credit_transformer->transform($credit); $transformed_credit = $this->credit_transformer->transform($credit);
@ -143,7 +154,11 @@ class CreditExport extends BaseExport
} elseif(isset($transformed_credit[$searched_credit_key])) { } elseif(isset($transformed_credit[$searched_credit_key])) {
$entity[$keyval] = $transformed_credit[$searched_credit_key]; $entity[$keyval] = $transformed_credit[$searched_credit_key];
} else { } else {
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $credit);
// $entity[$key] = '';
// $entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
} }
} }
@ -151,38 +166,72 @@ class CreditExport extends BaseExport
return $this->decorateAdvancedFields($credit, $entity); return $this->decorateAdvancedFields($credit, $entity);
} }
private function decorateAdvancedFields(Credit $credit, array $entity) :array public function addCreditStatusFilter($query, $status): Builder
{ {
if (in_array('country_id', $this->input['report_keys'])) {
$entity['country'] = $credit->client->country ? ctrans("texts.country_{$credit->client->country->name}") : ''; $status_parameters = explode(',', $status);
if (in_array('all', $status_parameters)) {
return $query;
} }
if (in_array('currency_id', $this->input['report_keys'])) { $credit_filters = [];
$entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $credit->company->currency()->code;
if (in_array('draft', $status_parameters)) {
$credit_filters[] = Credit::STATUS_DRAFT;
} }
if (in_array('invoice_id', $this->input['report_keys'])) { if (in_array('sent', $status_parameters)) {
$entity['invoice'] = $credit->invoice ? $credit->invoice->number : ''; $credit_filters[] = Credit::STATUS_SENT;
} }
if (in_array('client_id', $this->input['report_keys'])) { if (in_array('partial', $status_parameters)) {
$entity['client'] = $credit->client->present()->name(); $credit_filters[] = Credit::STATUS_PARTIAL;
} }
if (in_array('status_id', $this->input['report_keys'])) { if (in_array('applied', $status_parameters)) {
$entity['status'] = $credit->stringStatus($credit->status_id); $credit_filters[] = Credit::STATUS_APPLIED;
} }
if(in_array('credit.status', $this->input['report_keys'])) { if (count($credit_filters) >= 1) {
$entity['credit.status'] = $credit->stringStatus($credit->status_id); $query->whereIn('status_id', $credit_filters);
} }
return $query;
}
private function decorateAdvancedFields(Credit $credit, array $entity): array
{
// if (in_array('country_id', $this->input['report_keys'])) {
// $entity['country'] = $credit->client->country ? ctrans("texts.country_{$credit->client->country->name}") : '';
// }
// if (in_array('currency_id', $this->input['report_keys'])) {
// $entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $credit->company->currency()->code;
// }
// if (in_array('invoice_id', $this->input['report_keys'])) {
// $entity['invoice'] = $credit->invoice ? $credit->invoice->number : '';
// }
// if (in_array('client_id', $this->input['report_keys'])) {
// $entity['client'] = $credit->client->present()->name();
// }
// if (in_array('status_id', $this->input['report_keys'])) {
// $entity['status'] = $credit->stringStatus($credit->status_id);
// }
// if(in_array('credit.status', $this->input['report_keys'])) {
// $entity['credit.status'] = $credit->stringStatus($credit->status_id);
// }
if (in_array('credit.assigned_user_id', $this->input['report_keys'])) { if (in_array('credit.assigned_user_id', $this->input['report_keys'])) {
$entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name(): ''; $entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name() : '';
} }
if (in_array('credit.user_id', $this->input['report_keys'])) { if (in_array('credit.user_id', $this->input['report_keys'])) {
$entity['credit.user_id'] = $credit->user ? $credit->user->present()->name(): ''; $entity['credit.user_id'] = $credit->user ? $credit->user->present()->name() : '';
} }
return $entity; return $entity;

View File

@ -22,7 +22,6 @@ use League\Csv\Writer;
class DocumentExport extends BaseExport class DocumentExport extends BaseExport
{ {
private $entity_transformer; private $entity_transformer;
public string $date_key = 'created_at'; public string $date_key = 'created_at';
@ -79,6 +78,10 @@ class DocumentExport extends BaseExport
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -101,7 +104,7 @@ class DocumentExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Document $document) :array private function buildRow(Document $document): array
{ {
$transformed_entity = $this->entity_transformer->transform($document); $transformed_entity = $this->entity_transformer->transform($document);
@ -120,7 +123,7 @@ class DocumentExport extends BaseExport
return $this->decorateAdvancedFields($document, $entity); return $this->decorateAdvancedFields($document, $entity);
} }
private function decorateAdvancedFields(Document $document, array $entity) :array private function decorateAdvancedFields(Document $document, array $entity): array
{ {
if (in_array('record_type', $this->input['report_keys'])) { if (in_array('record_type', $this->input['report_keys'])) {
$entity['record_type'] = class_basename($document->documentable); $entity['record_type'] = class_basename($document->documentable);

View File

@ -11,20 +11,22 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Expense; use App\Models\Expense;
use App\Transformers\ExpenseTransformer; use App\Transformers\ExpenseTransformer;
use App\Utils\Ninja; use App\Utils\Ninja;
use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use League\Csv\Writer; use League\Csv\Writer;
class ExpenseExport extends BaseExport class ExpenseExport extends BaseExport
{ {
private $expense_transformer; private $expense_transformer;
private Decorator $decorator;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
@ -34,6 +36,7 @@ class ExpenseExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->expense_transformer = new ExpenseTransformer(); $this->expense_transformer = new ExpenseTransformer();
$this->decorator = new Decorator();
} }
@ -69,14 +72,45 @@ class ExpenseExport extends BaseExport
$this->input['report_keys'] = array_values($this->expense_report_keys); $this->input['report_keys'] = array_values($this->expense_report_keys);
} }
$tax_keys = [
'expense.tax_amount',
'expense.net_amount'
];
$this->input['report_keys'] = array_unique(array_merge($this->input['report_keys'], $tax_keys));
$query = Expense::query() $query = Expense::query()
->with('client') ->with('client')
->withTrashed() ->withTrashed()
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['status'] ?? false) {
$query = $this->addExpenseStatusFilter($query, $this->input['status']);
}
if(isset($this->input['clients'])) {
$query = $this->addClientFilter($query, $this->input['clients']);
}
if(isset($this->input['vendors'])) {
$query = $this->addVendorFilter($query, $this->input['vendors']);
}
if(isset($this->input['projects'])) {
$query = $this->addProjectFilter($query, $this->input['projects']);
}
if(isset($this->input['categories'])) {
$query = $this->addCategoryFilter($query, $this->input['categories']);
}
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -99,9 +133,10 @@ class ExpenseExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Expense $expense) :array private function buildRow(Expense $expense): array
{ {
$transformed_expense = $this->expense_transformer->transform($expense); $transformed_expense = $this->expense_transformer->transform($expense);
$transformed_expense['currency_id'] = $expense->currency ? $expense->currency->code : $expense->company->currency()->code;
$entity = []; $entity = [];
@ -113,7 +148,7 @@ class ExpenseExport extends BaseExport
} elseif (array_key_exists($key, $transformed_expense)) { } elseif (array_key_exists($key, $transformed_expense)) {
$entity[$key] = $transformed_expense[$key]; $entity[$key] = $transformed_expense[$key];
} else { } else {
$entity[$key] = $this->resolveKey($key, $expense, $this->expense_transformer); $entity[$key] = $this->decorator->transform($key, $expense);
} }
} }
@ -121,32 +156,81 @@ class ExpenseExport extends BaseExport
return $this->decorateAdvancedFields($expense, $entity); return $this->decorateAdvancedFields($expense, $entity);
} }
private function decorateAdvancedFields(Expense $expense, array $entity) :array protected function addExpenseStatusFilter($query, $status): Builder
{ {
if (in_array('expense.currency_id', $this->input['report_keys'])) {
$entity['expense.currency_id'] = $expense->currency ? $expense->currency->code : ''; $status_parameters = explode(',', $status);
if (in_array('all', $status_parameters)) {
return $query;
} }
if (in_array('expense.client_id', $this->input['report_keys'])) { $query->where(function ($query) use ($status_parameters) {
$entity['expense.client'] = $expense->client ? $expense->client->present()->name() : ''; if (in_array('logged', $status_parameters)) {
$query->orWhere(function ($query) {
$query->where('amount', '>', 0)
->whereNull('invoice_id')
->whereNull('payment_date')
->where('should_be_invoiced', false);
});
} }
if (in_array('expense.invoice_id', $this->input['report_keys'])) { if (in_array('pending', $status_parameters)) {
$entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : ''; $query->orWhere(function ($query) {
$query->where('should_be_invoiced', true)
->whereNull('invoice_id');
});
} }
if (in_array('expense.category', $this->input['report_keys'])) { if (in_array('invoiced', $status_parameters)) {
$entity['expense.category'] = $expense->category ? $expense->category->name : ''; $query->orWhere(function ($query) {
$query->whereNotNull('invoice_id');
});
} }
if (in_array('expense.vendor_id', $this->input['report_keys'])) { if (in_array('paid', $status_parameters)) {
$entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : ''; $query->orWhere(function ($query) {
$query->whereNotNull('payment_date');
});
} }
if (in_array('expense.payment_type_id', $this->input['report_keys'])) { if (in_array('unpaid', $status_parameters)) {
$entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : ''; $query->orWhere(function ($query) {
$query->whereNull('payment_date');
});
} }
});
return $query;
}
private function decorateAdvancedFields(Expense $expense, array $entity): array
{
// if (in_array('expense.currency_id', $this->input['report_keys'])) {
// $entity['expense.currency_id'] = $expense->currency ? $expense->currency->code : '';
// }
// if (in_array('expense.client_id', $this->input['report_keys'])) {
// $entity['expense.client'] = $expense->client ? $expense->client->present()->name() : '';
// }
// if (in_array('expense.invoice_id', $this->input['report_keys'])) {
// $entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : '';
// }
// if (in_array('expense.category', $this->input['report_keys'])) {
// $entity['expense.category'] = $expense->category ? $expense->category->name : '';
// }
// if (in_array('expense.vendor_id', $this->input['report_keys'])) {
// $entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : '';
// }
// if (in_array('expense.payment_type_id', $this->input['report_keys'])) {
// $entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : '';
// }
if (in_array('expense.project_id', $this->input['report_keys'])) { if (in_array('expense.project_id', $this->input['report_keys'])) {
$entity['expense.project_id'] = $expense->project ? $expense->project->name : ''; $entity['expense.project_id'] = $expense->project ? $expense->project->name : '';
} }
@ -163,6 +247,36 @@ class ExpenseExport extends BaseExport
$entity['expense.category_id'] = $expense->category ? $expense->category->name : ''; $entity['expense.category_id'] = $expense->category ? $expense->category->name : '';
} }
return $this->calcTaxes($entity, $expense);
}
private function calcTaxes($entity, $expense): array
{
$precision = $expense->currency->precision ?? 2;
$entity['expense.net_amount'] = round($expense->amount, $precision);
if($expense->calculate_tax_by_amount) {
$total_tax_amount = round($expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3, $precision);
} else {
if($expense->uses_inclusive_taxes) {
$total_tax_amount = ($this->calcInclusiveLineTax($expense->tax_rate1 ?? 0, $expense->amount, $precision)) + ($this->calcInclusiveLineTax($expense->tax_rate2 ?? 0, $expense->amount, $precision)) + ($this->calcInclusiveLineTax($expense->tax_rate3 ?? 0, $expense->amount, $precision));
$entity['expense.net_amount'] = round(($expense->amount - round($total_tax_amount, $precision)), $precision);
} else {
$total_tax_amount = ($expense->amount * (($expense->tax_rate1 ?? 0) / 100)) + ($expense->amount * (($expense->tax_rate2 ?? 0) / 100)) + ($expense->amount * (($expense->tax_rate3 ?? 0) / 100));
$entity['expense.net_amount'] = round(($expense->amount + round($total_tax_amount, $precision)), $precision);
}
}
$entity['expense.tax_amount'] = round($total_tax_amount, $precision);
return $entity; return $entity;
}
private function calcInclusiveLineTax($tax_rate, $amount, $precision): float
{
return round($amount - ($amount / (1 + ($tax_rate / 100))), $precision);
} }
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Invoice; use App\Models\Invoice;
@ -28,11 +29,14 @@ class InvoiceExport extends BaseExport
public Writer $csv; public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input) public function __construct(Company $company, array $input)
{ {
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->invoice_transformer = new InvoiceTransformer(); $this->invoice_transformer = new InvoiceTransformer();
$this->decorator = new Decorator();
} }
public function init(): Builder public function init(): Builder
@ -54,14 +58,18 @@ class InvoiceExport extends BaseExport
->withTrashed() ->withTrashed()
->with('client') ->with('client')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if(isset($this->input['status'])) { if($this->input['status'] ?? false) {
$query = $this->addInvoiceStatusFilter($query, $this->input['status']); $query = $this->addInvoiceStatusFilter($query, $this->input['status']);
} }
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -103,7 +111,7 @@ class InvoiceExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Invoice $invoice) :array private function buildRow(Invoice $invoice): array
{ {
$transformed_invoice = $this->invoice_transformer->transform($invoice); $transformed_invoice = $this->invoice_transformer->transform($invoice);
@ -116,7 +124,7 @@ class InvoiceExport extends BaseExport
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) { if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]]; $entity[$key] = $transformed_invoice[$parts[1]];
} else { } else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer); $entity[$key] = $this->decorator->transform($key, $invoice);
} }
} }
@ -124,24 +132,24 @@ class InvoiceExport extends BaseExport
return $this->decorateAdvancedFields($invoice, $entity); return $this->decorateAdvancedFields($invoice, $entity);
} }
private function decorateAdvancedFields(Invoice $invoice, array $entity) :array private function decorateAdvancedFields(Invoice $invoice, array $entity): array
{ {
if (in_array('invoice.country_id', $this->input['report_keys'])) { // if (in_array('invoice.country_id', $this->input['report_keys'])) {
$entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; // $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
} // }
if (in_array('invoice.currency_id', $this->input['report_keys'])) { // if (in_array('invoice.currency_id', $this->input['report_keys'])) {
$entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; // $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
} // }
if (in_array('invoice.client_id', $this->input['report_keys'])) { // if (in_array('invoice.client_id', $this->input['report_keys'])) {
$entity['invoice.client_id'] = $invoice->client->present()->name(); // $entity['invoice.client_id'] = $invoice->client->present()->name();
} // }
if (in_array('invoice.status', $this->input['report_keys'])) { // if (in_array('invoice.status', $this->input['report_keys'])) {
$entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); // $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
} // }
if (in_array('invoice.recurring_id', $this->input['report_keys'])) { if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
@ -152,14 +160,13 @@ class InvoiceExport extends BaseExport
} }
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) { if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): ''; $entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';
} }
if (in_array('invoice.user_id', $this->input['report_keys'])) { if (in_array('invoice.user_id', $this->input['report_keys'])) {
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): ''; $entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
} }
return $entity; return $entity;
} }
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Invoice; use App\Models\Invoice;
@ -22,13 +23,14 @@ use League\Csv\Writer;
class InvoiceItemExport extends BaseExport class InvoiceItemExport extends BaseExport
{ {
private $invoice_transformer; private $invoice_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
private Decorator $decorator;
private bool $force_keys = false; private bool $force_keys = false;
private array $storage_array = []; private array $storage_array = [];
@ -46,6 +48,7 @@ class InvoiceItemExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->invoice_transformer = new InvoiceTransformer(); $this->invoice_transformer = new InvoiceTransformer();
$this->decorator = new Decorator();
} }
public function init(): Builder public function init(): Builder
@ -68,11 +71,19 @@ class InvoiceItemExport extends BaseExport
->withTrashed() ->withTrashed()
->with('client') ->with('client')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->applyFilters($query); if($this->input['status'] ?? false) {
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
}
$query = $this->applyProductFilters($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
@ -88,7 +99,6 @@ class InvoiceItemExport extends BaseExport
return ['identifier' => $key, 'display_value' => $headerdisplay[$value]]; return ['identifier' => $key, 'display_value' => $headerdisplay[$value]];
})->toArray(); })->toArray();
$query->cursor() $query->cursor()
->each(function ($resource) { ->each(function ($resource) {
$this->iterateItems($resource); $this->iterateItems($resource);
@ -167,7 +177,7 @@ class InvoiceItemExport extends BaseExport
} }
} }
private function buildRow(Invoice $invoice) :array private function buildRow(Invoice $invoice): array
{ {
$transformed_invoice = $this->invoice_transformer->transform($invoice); $transformed_invoice = $this->invoice_transformer->transform($invoice);
@ -186,53 +196,56 @@ class InvoiceItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_invoice)) { } elseif (array_key_exists($key, $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$key]; $entity[$key] = $transformed_invoice[$key];
} else { } else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer); // nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($invoice, $entity); return $this->decorateAdvancedFields($invoice, $entity);
} }
private function decorateAdvancedFields(Invoice $invoice, array $entity) :array private function decorateAdvancedFields(Invoice $invoice, array $entity): array
{ {
if (in_array('currency_id', $this->input['report_keys'])) { // if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; // $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
} // }
if(array_key_exists('type', $entity)) { // if(array_key_exists('type', $entity)) {
$entity['type'] = $invoice->typeIdString($entity['type']); // $entity['type'] = $invoice->typeIdString($entity['type']);
} // }
if(array_key_exists('tax_category', $entity)) { // if(array_key_exists('tax_category', $entity)) {
$entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']); // $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
} // }
if (in_array('invoice.country_id', $this->input['report_keys'])) { // if (in_array('invoice.country_id', $this->input['report_keys'])) {
$entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; // $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
} // }
if (in_array('invoice.currency_id', $this->input['report_keys'])) { // if (in_array('invoice.currency_id', $this->input['report_keys'])) {
$entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; // $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
} // }
if (in_array('invoice.client_id', $this->input['report_keys'])) { // if (in_array('invoice.client_id', $this->input['report_keys'])) {
$entity['invoice.client_id'] = $invoice->client->present()->name(); // $entity['invoice.client_id'] = $invoice->client->present()->name();
} // }
if (in_array('invoice.status', $this->input['report_keys'])) { // if (in_array('invoice.status', $this->input['report_keys'])) {
$entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); // $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
} // }
if (in_array('invoice.recurring_id', $this->input['report_keys'])) { if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
} }
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) { if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): ''; $entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';
} }
if (in_array('invoice.user_id', $this->input['report_keys'])) { if (in_array('invoice.user_id', $this->input['report_keys'])) {
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): ''; $entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
} }
return $entity; return $entity;

View File

@ -11,15 +11,15 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Utils\Ninja; use App\Export\Decorators\Decorator;
use League\Csv\Writer; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Payment; use App\Models\Payment;
use App\Libraries\MultiDB;
use Illuminate\Support\Facades\App;
use App\Transformers\PaymentTransformer; use App\Transformers\PaymentTransformer;
use App\Utils\Ninja;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use App\Export\Decorators\Decorator; use Illuminate\Support\Facades\App;
use League\Csv\Writer;
class PaymentExport extends BaseExport class PaymentExport extends BaseExport
{ {
@ -61,6 +61,12 @@ class PaymentExport extends BaseExport
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addPaymentStatusFilters($query, $this->input['status'] ?? '');
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -102,7 +108,7 @@ class PaymentExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Payment $payment) :array private function buildRow(Payment $payment): array
{ {
$transformed_entity = $this->entity_transformer->transform($payment); $transformed_entity = $this->entity_transformer->transform($payment);
@ -118,60 +124,62 @@ class PaymentExport extends BaseExport
$entity[$key] = $transformed_entity[$key]; $entity[$key] = $transformed_entity[$key];
} else { } else {
// $entity[$key] = $this->decorator->transform($key, $payment); // nlog($key);
$entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer); $entity[$key] = $this->decorator->transform($key, $payment);
// $entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($payment, $entity); return $this->decorateAdvancedFields($payment, $entity);
} }
private function decorateAdvancedFields(Payment $payment, array $entity) :array private function decorateAdvancedFields(Payment $payment, array $entity): array
{ {
if (in_array('status_id', $this->input['report_keys'])) { // if (in_array('status_id', $this->input['report_keys'])) {
$entity['status'] = $payment->stringStatus($payment->status_id); // $entity['status'] = $payment->stringStatus($payment->status_id);
} // }
if (in_array('vendor_id', $this->input['report_keys'])) { // if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : ''; // $entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : '';
} // }
if (in_array('project_id', $this->input['report_keys'])) { // if (in_array('project_id', $this->input['report_keys'])) {
$entity['project'] = $payment->project()->exists() ? $payment->project->name : ''; // $entity['project'] = $payment->project()->exists() ? $payment->project->name : '';
} // }
if (in_array('currency_id', $this->input['report_keys'])) { // if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; // $entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
} // }
if (in_array('payment.currency', $this->input['report_keys'])) { // if (in_array('payment.currency', $this->input['report_keys'])) {
$entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; // $entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
} // }
if (in_array('exchange_currency_id', $this->input['report_keys'])) { // if (in_array('exchange_currency_id', $this->input['report_keys'])) {
$entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : ''; // $entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : '';
} // }
if (in_array('client_id', $this->input['report_keys'])) { // if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $payment->client->present()->name(); // $entity['client'] = $payment->client->present()->name();
} // }
if (in_array('type_id', $this->input['report_keys'])) { // if (in_array('type_id', $this->input['report_keys'])) {
$entity['type'] = $payment->translatedType(); // $entity['type'] = $payment->translatedType();
} // }
if (in_array('payment.method', $this->input['report_keys'])) { // if (in_array('payment.method', $this->input['report_keys'])) {
$entity['payment.method'] = $payment->translatedType(); // $entity['payment.method'] = $payment->translatedType();
} // }
if (in_array('payment.status', $this->input['report_keys'])) { // if (in_array('payment.status', $this->input['report_keys'])) {
$entity['payment.status'] = $payment->stringStatus($payment->status_id); // $entity['payment.status'] = $payment->stringStatus($payment->status_id);
} // }
if (in_array('gateway_type_id', $this->input['report_keys'])) { // if (in_array('gateway_type_id', $this->input['report_keys'])) {
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type'; // $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
} // }
if (in_array('payment.assigned_user_id', $this->input['report_keys'])) { if (in_array('payment.assigned_user_id', $this->input['report_keys'])) {
$entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : ''; $entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : '';

View File

@ -11,14 +11,15 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Libraries\MultiDB; use App\Utils\Ninja;
use League\Csv\Writer;
use App\Models\Company; use App\Models\Company;
use App\Models\Product; use App\Models\Product;
use App\Transformers\ProductTransformer; use App\Libraries\MultiDB;
use App\Utils\Ninja;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use League\Csv\Writer; use App\Export\Decorators\Decorator;
use App\Transformers\ProductTransformer;
use Illuminate\Database\Eloquent\Builder;
class ProductExport extends BaseExport class ProductExport extends BaseExport
{ {
@ -28,11 +29,14 @@ class ProductExport extends BaseExport
public Writer $csv; public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input) public function __construct(Company $company, array $input)
{ {
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->entity_transformer = new ProductTransformer(); $this->entity_transformer = new ProductTransformer();
$this->decorator = new Decorator();
} }
public function returnJson() public function returnJson()
@ -74,6 +78,10 @@ class ProductExport extends BaseExport
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -97,7 +105,7 @@ class ProductExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Product $product) :array private function buildRow(Product $product): array
{ {
$transformed_entity = $this->entity_transformer->transform($product); $transformed_entity = $this->entity_transformer->transform($product);
@ -109,14 +117,18 @@ class ProductExport extends BaseExport
if (array_key_exists($key, $transformed_entity)) { if (array_key_exists($key, $transformed_entity)) {
$entity[$keyval] = $transformed_entity[$key]; $entity[$keyval] = $transformed_entity[$key];
} else { } else {
$entity[$keyval] = ''; // nlog($key);
$entity[$key] = $this->decorator->transform($key, $product);
// $entity[$key] = '';
} }
} }
return $this->decorateAdvancedFields($product, $entity); return $entity;
// return $this->decorateAdvancedFields($product, $entity);
} }
private function decorateAdvancedFields(Product $product, array $entity) :array private function decorateAdvancedFields(Product $product, array $entity): array
{ {
if (in_array('vendor_id', $this->input['report_keys'])) { if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $product->vendor()->exists() ? $product->vendor->name : ''; $entity['vendor'] = $product->vendor()->exists() ? $product->vendor->name : '';

View File

@ -37,6 +37,7 @@ class ProductSalesExport extends BaseExport
'product_key' => 'product_key', 'product_key' => 'product_key',
'notes' => 'notes', 'notes' => 'notes',
'quantity' => 'quantity', 'quantity' => 'quantity',
'currency' => 'currency',
'cost' => 'price', 'cost' => 'price',
'price' => 'cost', 'price' => 'cost',
'markup' => 'markup', 'markup' => 'markup',
@ -144,7 +145,7 @@ class ProductSalesExport extends BaseExport
$this->csv->insertOne([]); $this->csv->insertOne([]);
if ($grouped->count() >=1) { if ($grouped->count() >= 1) {
$header = []; $header = [];
foreach ($grouped->first() as $key => $value) { foreach ($grouped->first() as $key => $value) {
@ -160,9 +161,10 @@ class ProductSalesExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow($invoice, $invoice_item) :array private function buildRow($invoice, $invoice_item): array
{ {
$transformed_entity = (array)$invoice_item; $transformed_entity = (array)$invoice_item;
$transformed_entity['price'] = ($invoice_item->product_cost ?? 1) * ($invoice->exchange_rate ?? 1) ;
$entity = []; $entity = [];
@ -171,6 +173,8 @@ class ProductSalesExport extends BaseExport
if (array_key_exists($key, $transformed_entity)) { if (array_key_exists($key, $transformed_entity)) {
$entity[$keyval] = $transformed_entity[$key]; $entity[$keyval] = $transformed_entity[$key];
} elseif($key == 'currency') {
$entity['currency'] = $invoice->client->currency()->code;
} else { } else {
$entity[$keyval] = ''; $entity[$keyval] = '';
} }
@ -182,11 +186,11 @@ class ProductSalesExport extends BaseExport
return $entity; return $entity;
} }
private function decorateAdvancedFields(Invoice $invoice, $entity) :array private function decorateAdvancedFields(Invoice $invoice, $entity): array
{ {
$product = $this->getProduct($entity['product_key']);
$entity['cost'] = $product->cost ?? 0; //$product = $this->getProduct($entity['product_key']);
// $entity['cost'] = $product->cost ?? 0;
/** @var float $unit_cost */ /** @var float $unit_cost */
$unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost']; $unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];
@ -253,7 +257,7 @@ class ProductSalesExport extends BaseExport
* @param mixed $entity * @param mixed $entity
* @return float * @return float
*/ */
private function calculateDiscount(Invoice $invoice, $entity) :float private function calculateDiscount(Invoice $invoice, $entity): float
{ {
if ($entity['discount'] == 0) { if ($entity['discount'] == 0) {
return 0; return 0;
@ -274,7 +278,7 @@ class ProductSalesExport extends BaseExport
* @param string $product_key * @param string $product_key
* @return Product * @return Product
*/ */
private function getProduct(string $product_key) :?Product private function getProduct(string $product_key): ?Product
{ {
return $this->products->firstWhere('product_key', $product_key); return $this->products->firstWhere('product_key', $product_key);
} }

View File

@ -11,74 +11,32 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\PurchaseOrder;
use App\Transformers\PurchaseOrderTransformer;
use App\Utils\Ninja; use App\Utils\Ninja;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer; use League\Csv\Writer;
use App\Models\Company;
use App\Libraries\MultiDB;
use App\Models\PurchaseOrder;
use Illuminate\Support\Facades\App;
use App\Export\Decorators\Decorator;
use Illuminate\Database\Eloquent\Builder;
use App\Transformers\PurchaseOrderTransformer;
class PurchaseOrderExport extends BaseExport class PurchaseOrderExport extends BaseExport
{ {
private $purchase_order_transformer; private $purchase_order_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
public array $entity_keys = [ private Decorator $decorator;
'amount' => 'purchase_order.amount',
'balance' => 'purchase_order.balance',
'vendor' => 'purchase_order.vendor_id',
// 'custom_surcharge1' => 'purchase_order.custom_surcharge1',
// 'custom_surcharge2' => 'purchase_order.custom_surcharge2',
// 'custom_surcharge3' => 'purchase_order.custom_surcharge3',
// 'custom_surcharge4' => 'purchase_order.custom_surcharge4',
'custom_value1' => 'purchase_order.custom_value1',
'custom_value2' => 'purchase_order.custom_value2',
'custom_value3' => 'purchase_order.custom_value3',
'custom_value4' => 'purchase_order.custom_value4',
'date' => 'purchase_order.date',
'discount' => 'purchase_order.discount',
'due_date' => 'purchase_order.due_date',
'exchange_rate' => 'purchase_order.exchange_rate',
'footer' => 'purchase_order.footer',
'number' => 'purchase_order.number',
'paid_to_date' => 'purchase_order.paid_to_date',
'partial' => 'purchase_order.partial',
'partial_due_date' => 'purchase_order.partial_due_date',
'po_number' => 'purchase_order.po_number',
'private_notes' => 'purchase_order.private_notes',
'public_notes' => 'purchase_order.public_notes',
'status' => 'purchase_order.status',
'tax_name1' => 'purchase_order.tax_name1',
'tax_name2' => 'purchase_order.tax_name2',
'tax_name3' => 'purchase_order.tax_name3',
'tax_rate1' => 'purchase_order.tax_rate1',
'tax_rate2' => 'purchase_order.tax_rate2',
'tax_rate3' => 'purchase_order.tax_rate3',
'terms' => 'purchase_order.terms',
'total_taxes' => 'purchase_order.total_taxes',
'currency_id' => 'purchase_order.currency_id',
];
private array $decorate_keys = [
'country',
'currency_id',
'status',
'vendor',
'project',
];
public function __construct(Company $company, array $input) public function __construct(Company $company, array $input)
{ {
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->purchase_order_transformer = new PurchaseOrderTransformer(); $this->purchase_order_transformer = new PurchaseOrderTransformer();
$this->decorator = new Decorator();
} }
@ -101,10 +59,16 @@ class PurchaseOrderExport extends BaseExport
->withTrashed() ->withTrashed()
->with('vendor') ->with('vendor')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -147,7 +111,7 @@ class PurchaseOrderExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(PurchaseOrder $purchase_order) :array private function buildRow(PurchaseOrder $purchase_order): array
{ {
$transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order); $transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order);
@ -160,33 +124,43 @@ class PurchaseOrderExport extends BaseExport
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) { if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
$entity[$key] = $transformed_purchase_order[$parts[1]]; $entity[$key] = $transformed_purchase_order[$parts[1]];
} else { } else {
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer); nlog($key);
$entity[$key] = $this->decorator->transform($key, $purchase_order);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($purchase_order, $entity); return $this->decorateAdvancedFields($purchase_order, $entity);
} }
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity): array
{ {
if (in_array('country_id', $this->input['report_keys'])) {
$entity['country'] = $purchase_order->vendor->country ? ctrans("texts.country_{$purchase_order->vendor->country->name}") : ''; if (in_array('purchase_order.currency_id', $this->input['report_keys'])) {
$entity['purchase_order.currency_id'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code;
} }
if (in_array('currency_id', $this->input['report_keys'])) { if (in_array('purchase_order.vendor_id', $this->input['report_keys'])) {
$entity['currency_id'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code; $entity['purchase_order.vendor_id'] = $purchase_order->vendor->present()->name();
}
if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $purchase_order->vendor->present()->name();
} }
if (in_array('purchase_order.status', $this->input['report_keys'])) { if (in_array('purchase_order.status', $this->input['report_keys'])) {
$entity['purchase_order.status'] = $purchase_order->stringStatus($purchase_order->status_id); $entity['purchase_order.status'] = $purchase_order->stringStatus($purchase_order->status_id);
} }
if (in_array('purchase_order.user_id', $this->input['report_keys'])) {
$entity['purchase_order.user_id'] = $purchase_order->user ? $purchase_order->user->present()->name() : '';
}
if (in_array('purchase_order.assigned_user_id', $this->input['report_keys'])) {
$entity['purchase_order.assigned_user_id'] = $purchase_order->assigned_user ? $purchase_order->assigned_user->present()->name() : '';
}
return $entity; return $entity;
} }
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\PurchaseOrder; use App\Models\PurchaseOrder;
@ -22,13 +23,14 @@ use League\Csv\Writer;
class PurchaseOrderItemExport extends BaseExport class PurchaseOrderItemExport extends BaseExport
{ {
private $purchase_order_transformer; private $purchase_order_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
private Decorator $decorator;
private bool $force_keys = false; private bool $force_keys = false;
private array $storage_array = []; private array $storage_array = [];
@ -40,6 +42,7 @@ class PurchaseOrderItemExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->purchase_order_transformer = new PurchaseOrderTransformer(); $this->purchase_order_transformer = new PurchaseOrderTransformer();
$this->decorator = new Decorator();
} }
private function init(): Builder private function init(): Builder
@ -60,10 +63,16 @@ class PurchaseOrderItemExport extends BaseExport
$query = PurchaseOrder::query() $query = PurchaseOrder::query()
->withTrashed() ->withTrashed()
->with('vendor')->where('company_id', $this->company->id) ->with('vendor')->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -153,7 +162,7 @@ class PurchaseOrderItemExport extends BaseExport
} }
} }
private function buildRow(PurchaseOrder $purchase_order) :array private function buildRow(PurchaseOrder $purchase_order): array
{ {
$transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order); $transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order);
@ -171,34 +180,59 @@ class PurchaseOrderItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_purchase_order)) { } elseif (array_key_exists($key, $transformed_purchase_order)) {
$entity[$key] = $transformed_purchase_order[$key]; $entity[$key] = $transformed_purchase_order[$key];
} else { } else {
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer); // nlog($key);
$entity[$key] = $this->decorator->transform($key, $purchase_order);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
} }
} }
return $this->decorateAdvancedFields($purchase_order, $entity); return $this->decorateAdvancedFields($purchase_order, $entity);
} }
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity): array
{ {
if (in_array('currency_id', $this->input['report_keys'])) { // if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code; // $entity['currency'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code;
// }
// if(array_key_exists('type', $entity)) {
// $entity['type'] = $purchase_order->typeIdString($entity['type']);
// }
// if(array_key_exists('tax_category', $entity)) {
// $entity['tax_category'] = $purchase_order->taxTypeString($entity['tax_category']);
// }
// if($this->force_keys) {
// $entity['vendor'] = $purchase_order->vendor->present()->name();
// $entity['vendor_id_number'] = $purchase_order->vendor->id_number;
// $entity['vendor_number'] = $purchase_order->vendor->number;
// $entity['status'] = $purchase_order->stringStatus($purchase_order->status_id);
// }
if (in_array('purchase_order.currency_id', $this->input['report_keys'])) {
$entity['purchase_order.currency_id'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code;
} }
if(array_key_exists('type', $entity)) { if (in_array('purchase_order.vendor_id', $this->input['report_keys'])) {
$entity['type'] = $purchase_order->typeIdString($entity['type']); $entity['purchase_order.vendor_id'] = $purchase_order->vendor->present()->name();
} }
if(array_key_exists('tax_category', $entity)) { if (in_array('purchase_order.status', $this->input['report_keys'])) {
$entity['tax_category'] = $purchase_order->taxTypeString($entity['tax_category']); $entity['purchase_order.status'] = $purchase_order->stringStatus($purchase_order->status_id);
} }
if($this->force_keys) { if (in_array('purchase_order.user_id', $this->input['report_keys'])) {
$entity['vendor'] = $purchase_order->vendor->present()->name(); $entity['purchase_order.user_id'] = $purchase_order->user ? $purchase_order->user->present()->name() : '';
$entity['vendor_id_number'] = $purchase_order->vendor->id_number;
$entity['vendor_number'] = $purchase_order->vendor->number;
$entity['status'] = $purchase_order->stringStatus($purchase_order->status_id);
} }
if (in_array('purchase_order.assigned_user_id', $this->input['report_keys'])) {
$entity['purchase_order.assigned_user_id'] = $purchase_order->assigned_user ? $purchase_order->assigned_user->present()->name() : '';
}
return $entity; return $entity;
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Quote; use App\Models\Quote;
@ -22,13 +23,14 @@ use League\Csv\Writer;
class QuoteExport extends BaseExport class QuoteExport extends BaseExport
{ {
private $quote_transformer; private $quote_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
private Decorator $decorator;
private array $decorate_keys = [ private array $decorate_keys = [
'client', 'client',
'currency', 'currency',
@ -40,6 +42,7 @@ class QuoteExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->quote_transformer = new QuoteTransformer(); $this->quote_transformer = new QuoteTransformer();
$this->decorator = new Decorator();
} }
private function init(): Builder private function init(): Builder
@ -62,10 +65,16 @@ class QuoteExport extends BaseExport
->withTrashed() ->withTrashed()
->with('client') ->with('client')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addQuoteStatusFilter($query, $this->input['status'] ?? '');
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -109,7 +118,7 @@ class QuoteExport extends BaseExport
return $this->csv->toString(); return $this->csv->toString();
} }
private function buildRow(Quote $quote) :array private function buildRow(Quote $quote): array
{ {
$transformed_invoice = $this->quote_transformer->transform($quote); $transformed_invoice = $this->quote_transformer->transform($quote);
@ -122,16 +131,18 @@ class QuoteExport extends BaseExport
if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_invoice)) { if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]]; $entity[$key] = $transformed_invoice[$parts[1]];
} else { } else {
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer); // nlog($key);
$entity[$key] = $this->decorator->transform($key, $quote);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($quote, $entity); return $this->decorateAdvancedFields($quote, $entity);
} }
private function decorateAdvancedFields(Quote $quote, array $entity): array
private function decorateAdvancedFields(Quote $quote, array $entity) :array
{ {
if (in_array('quote.currency_id', $this->input['report_keys'])) { if (in_array('quote.currency_id', $this->input['report_keys'])) {
$entity['quote.currency'] = $quote->client->currency()->code; $entity['quote.currency'] = $quote->client->currency()->code;
@ -150,11 +161,11 @@ class QuoteExport extends BaseExport
} }
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) { if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): ''; $entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name() : '';
} }
if (in_array('quote.user_id', $this->input['report_keys'])) { if (in_array('quote.user_id', $this->input['report_keys'])) {
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): ''; $entity['quote.user_id'] = $quote->user ? $quote->user->present()->name() : '';
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Quote; use App\Models\Quote;
@ -22,14 +23,16 @@ use League\Csv\Writer;
class QuoteItemExport extends BaseExport class QuoteItemExport extends BaseExport
{ {
private $quote_transformer; private $quote_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
private Decorator $decorator;
private array $storage_array = []; private array $storage_array = [];
private array $storage_item_array = []; private array $storage_item_array = [];
private array $decorate_keys = [ private array $decorate_keys = [
@ -42,6 +45,7 @@ class QuoteItemExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->quote_transformer = new QuoteTransformer(); $this->quote_transformer = new QuoteTransformer();
$this->decorator = new Decorator();
} }
public function init(): Builder public function init(): Builder
@ -62,10 +66,16 @@ class QuoteItemExport extends BaseExport
$query = Quote::query() $query = Quote::query()
->withTrashed() ->withTrashed()
->with('client')->where('company_id', $this->company->id) ->with('client')->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addQuoteStatusFilter($query, $this->input['status'] ?? '');
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -159,7 +169,7 @@ class QuoteItemExport extends BaseExport
} }
} }
private function buildRow(Quote $quote) :array private function buildRow(Quote $quote): array
{ {
$transformed_quote = $this->quote_transformer->transform($quote); $transformed_quote = $this->quote_transformer->transform($quote);
@ -178,33 +188,35 @@ class QuoteItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_quote)) { } elseif (array_key_exists($key, $transformed_quote)) {
$entity[$key] = $transformed_quote[$key]; $entity[$key] = $transformed_quote[$key];
} else { } else {
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer); // nlog($key);
$entity[$key] = $this->decorator->transform($key, $quote);
// $entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($quote, $entity); return $this->decorateAdvancedFields($quote, $entity);
} }
private function decorateAdvancedFields(Quote $quote, array $entity) :array private function decorateAdvancedFields(Quote $quote, array $entity): array
{ {
if (in_array('currency_id', $this->input['report_keys'])) { // if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code; // $entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code;
} // }
if (in_array('client_id', $this->input['report_keys'])) { // if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $quote->client->present()->name(); // $entity['client'] = $quote->client->present()->name();
} // }
if (in_array('status_id', $this->input['report_keys'])) { // if (in_array('status_id', $this->input['report_keys'])) {
$entity['status'] = $quote->stringStatus($quote->status_id); // $entity['status'] = $quote->stringStatus($quote->status_id);
} // }
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) { if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): ''; $entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name() : '';
} }
if (in_array('quote.user_id', $this->input['report_keys'])) { if (in_array('quote.user_id', $this->input['report_keys'])) {
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): ''; $entity['quote.user_id'] = $quote->user ? $quote->user->present()->name() : '';
} }

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
@ -22,18 +23,20 @@ use League\Csv\Writer;
class RecurringInvoiceExport extends BaseExport class RecurringInvoiceExport extends BaseExport
{ {
private $invoice_transformer; private $invoice_transformer;
public string $date_key = 'date'; public string $date_key = 'date';
public Writer $csv; public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input) public function __construct(Company $company, array $input)
{ {
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->invoice_transformer = new RecurringInvoiceTransformer(); $this->invoice_transformer = new RecurringInvoiceTransformer();
$this->decorator = new Decorator();
} }
public function init(): Builder public function init(): Builder
@ -54,10 +57,12 @@ class RecurringInvoiceExport extends BaseExport
->withTrashed() ->withTrashed()
->with('client') ->with('client')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
$query = $this->addRecurringInvoiceStatusFilter($query, $this->input['status'] ?? '');
return $query; return $query;
} }
@ -102,7 +107,7 @@ class RecurringInvoiceExport extends BaseExport
} }
private function buildRow(RecurringInvoice $invoice) :array private function buildRow(RecurringInvoice $invoice): array
{ {
$transformed_invoice = $this->invoice_transformer->transform($invoice); $transformed_invoice = $this->invoice_transformer->transform($invoice);
@ -114,40 +119,46 @@ class RecurringInvoiceExport extends BaseExport
if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) { if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]]; $entity[$key] = $transformed_invoice[$parts[1]];
} elseif($parts[0] == 'item') {
$entity[$key] = '';
} else { } else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer); // nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
} }
} }
// return $entity;
return $this->decorateAdvancedFields($invoice, $entity); return $this->decorateAdvancedFields($invoice, $entity);
} }
private function decorateAdvancedFields(RecurringInvoice $invoice, array $entity) :array private function decorateAdvancedFields(RecurringInvoice $invoice, array $entity): array
{ {
if (in_array('country_id', $this->input['report_keys'])) { // if (in_array('country_id', $this->input['report_keys'])) {
$entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; // $entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
} // }
if (in_array('currency_id', $this->input['report_keys'])) { // if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; // $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
} // }
if (in_array('client_id', $this->input['report_keys'])) { // if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $invoice->client->present()->name(); // $entity['client'] = $invoice->client->present()->name();
} // }
if (in_array('recurring_invoice.status', $this->input['report_keys'])) { // if (in_array('recurring_invoice.status', $this->input['report_keys'])) {
$entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id); // $entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id);
} // }
if (in_array('project_id', $this->input['report_keys'])) { // if (in_array('project_id', $this->input['report_keys'])) {
$entity['project'] = $invoice->project ? $invoice->project->name : ''; // $entity['project'] = $invoice->project ? $invoice->project->name : '';
} // }
if (in_array('vendor_id', $this->input['report_keys'])) { // if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : ''; // $entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : '';
} // }
if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) { if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) {
$entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id); $entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV; namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\DateFormat; use App\Models\DateFormat;
@ -25,7 +26,6 @@ use League\Csv\Writer;
class TaskExport extends BaseExport class TaskExport extends BaseExport
{ {
private $entity_transformer; private $entity_transformer;
public string $date_key = 'created_at'; public string $date_key = 'created_at';
@ -34,6 +34,8 @@ class TaskExport extends BaseExport
public Writer $csv; public Writer $csv;
private Decorator $decorator;
private array $storage_array = []; private array $storage_array = [];
private array $storage_item_array = []; private array $storage_item_array = [];
@ -43,6 +45,7 @@ class TaskExport extends BaseExport
$this->company = $company; $this->company = $company;
$this->input = $input; $this->input = $input;
$this->entity_transformer = new TaskTransformer(); $this->entity_transformer = new TaskTransformer();
$this->decorator = new Decorator();
} }
public function init(): Builder public function init(): Builder
@ -65,10 +68,14 @@ class TaskExport extends BaseExport
$query = Task::query() $query = Task::query()
->withTrashed() ->withTrashed()
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', 0); ->where('is_deleted', $this->input['include_deleted']);
$query = $this->addDateRange($query); $query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query; return $query;
} }
@ -116,7 +123,7 @@ class TaskExport extends BaseExport
$this->storage_array = []; $this->storage_array = [];
}); });
// nlog($this->storage_item_array);
return array_merge(['columns' => $header], $this->storage_item_array); return array_merge(['columns' => $header], $this->storage_item_array);
} }
@ -133,16 +140,14 @@ class TaskExport extends BaseExport
$entity[$key] = $transformed_entity[$parts[1]]; $entity[$key] = $transformed_entity[$parts[1]];
} elseif (array_key_exists($key, $transformed_entity)) { } elseif (array_key_exists($key, $transformed_entity)) {
$entity[$key] = $transformed_entity[$key]; $entity[$key] = $transformed_entity[$key];
} elseif (in_array($key, ['task.start_date', 'task.end_date', 'task.duration'])) {
$entity[$key] = '';
} else { } else {
$entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer); $entity[$key] = $this->decorator->transform($key, $task);
} }
} }
$entity['task.start_date'] = '';
$entity['task.end_date'] = '';
$entity['task.duration'] = '';
if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) { if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
$this->storage_array[] = $entity; $this->storage_array[] = $entity;
} else { } else {
@ -191,14 +196,42 @@ class TaskExport extends BaseExport
$this->storage_array[] = $entity; $this->storage_array[] = $entity;
unset($entity['task.start_date']); $entity['task.start_date'] = '';
unset($entity['task.end_date']); $entity['task.end_date'] = '';
unset($entity['task.duration']); $entity['task.duration'] = '';
} }
} }
private function decorateAdvancedFields(Task $task, array $entity) :array /**
* Add Task Status Filter
*
* @param Builder $query
* @param string $status
* @return Builder
*/
protected function addTaskStatusFilter(Builder $query, string $status): Builder
{
$status_parameters = explode(',', $status);
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
return $query;
}
if (in_array('invoiced', $status_parameters)) {
$query->whereNotNull('invoice_id');
}
if (in_array('uninvoiced', $status_parameters)) {
$query->whereNull('invoice_id');
}
return $query;
}
private function decorateAdvancedFields(Task $task, array $entity): array
{ {
if (in_array('task.status_id', $this->input['report_keys'])) { if (in_array('task.status_id', $this->input['report_keys'])) {
$entity['task.status_id'] = $task->status()->exists() ? $task->status->name : ''; $entity['task.status_id'] = $task->status()->exists() ? $task->status->name : '';
@ -208,6 +241,15 @@ class TaskExport extends BaseExport
$entity['task.project_id'] = $task->project()->exists() ? $task->project->name : ''; $entity['task.project_id'] = $task->project()->exists() ? $task->project->name : '';
} }
if (in_array('task.user_id', $this->input['report_keys'])) {
$entity['task.user_id'] = $task->user ? $task->user->present()->name() : '';
}
if (in_array('task.assigned_user_id', $this->input['report_keys'])) {
$entity['task.assigned_user_id'] = $task->assigned_user ? $task->assigned_user->present()->name() : '';
}
return $entity; return $entity;
} }
} }

Some files were not shown because too many files have changed in this diff Show More