Merge pull request #9234 from turbo124/v5-stable

v5.8.21
This commit is contained in:
David Bomba 2024-02-02 07:11:12 +11:00 committed by GitHub
commit 9dfb8c5951
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1479 changed files with 595753 additions and 483502 deletions

View File

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

View File

@ -81,9 +81,9 @@ jobs:
uses: shivammathur/setup-php@v2
with:
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:
ref: v5-develop
fetch-depth: 1
@ -96,7 +96,7 @@ jobs:
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}

View File

@ -43,7 +43,7 @@ jobs:
run: |
git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git
cd ui
git checkout main
git checkout develop
npm i
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
* [macOS](https://apps.apple.com/app/id1503970375?platform=mac)
* [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
* [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/)

View File

@ -1 +1 @@
5.7.57
5.8.21

View File

@ -15,6 +15,7 @@ use App;
use App\Factory\ClientContactFactory;
use App\Factory\VendorContactFactory;
use App\Jobs\Company\CreateCompanyToken;
use App\Libraries\MultiDB;
use App\Models\Account;
use App\Models\BankTransaction;
use App\Models\Client;
@ -127,6 +128,8 @@ class CheckData extends Command
$this->checkCompanyTokens();
$this->checkUserState();
$this->checkContactEmailAndSendEmailStatus();
$this->checkPaymentCurrency();
$this->checkSubdomainsSet();
if (Ninja::isHosted()) {
$this->checkAccountStatuses();
@ -313,7 +316,7 @@ class CheckData extends Command
$new_contact->client_id = $client->id;
$new_contact->contact_key = Str::random(40);
$new_contact->is_primary = true;
$new_contact->save();
$new_contact->saveQuietly();
}
}
}
@ -325,6 +328,7 @@ class CheckData extends Command
->whereNull('contact_key')
->orderBy('id')
->get(['id']);
$this->logMessage($contacts->count().' contacts without a contact_key');
if ($contacts->count() > 0) {
@ -342,20 +346,8 @@ class CheckData extends Command
}
}
// check for missing 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');
$vendors = Vendor::withTrashed()->doesntHave('contacts');
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');
if ($vendors->count() > 0) {
@ -372,28 +364,11 @@ class CheckData extends Command
$new_contact->vendor_id = $vendor->id;
$new_contact->contact_key = Str::random(40);
$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()
{
$invoices = DB::table('invoices')
@ -419,7 +394,7 @@ class CheckData extends Command
$invitation->invoice_id = $invoice->id;
$invitation->client_contact_id = ClientContact::whereClientId($invoice->client_id)->first()->id;
$invitation->key = Str::random(config('ninja.key_length'));
$invitation->save();
$invitation->saveQuietly();
}
}
}
@ -610,7 +585,7 @@ class CheckData extends Command
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}");
$client->paid_to_date = $total_paid_to_date;
$client->save();
$client->saveQuietly();
}
}
}
@ -659,7 +634,7 @@ class CheckData extends Command
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']);
$client_object->balance = $client['invoice_balance'];
$client_object->save();
$client_object->saveQuietly();
}
$this->isValid = false;
@ -683,6 +658,8 @@ class CheckData extends Command
->count();
if ($count == 0) {
$this->isValid = false;
//factor in over payments to the client balance
$over_payment = Payment::where('client_id', $client->id)
->where('is_deleted', 0)
@ -703,7 +680,7 @@ class CheckData extends Command
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to 0");
$client->balance = $over_payment;
$client->save();
$client->saveQuietly();
}
}
});
@ -745,6 +722,8 @@ class CheckData extends Command
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
if (number_format($invoice_balance, 4) != number_format($client->balance, 4)) {
$this->isValid = false;
$this->wrong_balances++;
$ledger_balance = $ledger ? $ledger->balance : 0;
@ -755,7 +734,7 @@ class CheckData extends Command
if ($this->option('client_balance')) {
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
$client->balance = $invoice_balance;
$client->save();
$client->saveQuietly();
}
if ($ledger && (number_format($invoice_balance, 4) != number_format($ledger->balance, 4))) {
@ -789,7 +768,7 @@ class CheckData extends Command
if ($this->option('ledger_balance')) {
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
$client->balance = $invoice_balance;
$client->save();
$client->saveQuietly();
$ledger->adjustment = $invoice_balance;
$ledger->balance = $invoice_balance;
@ -893,6 +872,8 @@ class CheckData extends Command
->exists();
if ($payment) {
$this->isValid = false;
$this->logMessage("I found a payment for {$account->key}");
}
}
@ -905,10 +886,70 @@ class CheckData extends Command
if ($this->option('fix') == 'true') {
Client::query()->whereNull('country_id')->cursor()->each(function ($client) {
$client->country_id = $client->company->settings->country_id;
$client->save();
$client->saveQuietly();
$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}");
});
}
}
@ -917,7 +958,7 @@ class CheckData extends Command
if ($this->option('fix') == 'true') {
Vendor::query()->whereNull('currency_id')->orWhere('currency_id', '')->cursor()->each(function ($vendor) {
$vendor->currency_id = $vendor->company->settings->currency_id;
$vendor->save();
$vendor->saveQuietly();
$this->logMessage("Fixing vendor currency for # {$vendor->id}");
});
@ -940,14 +981,14 @@ class CheckData extends Command
$invoice->balance = 0;
$invoice->paid_to_date = $val;
$invoice->save();
$invoice->saveQuietly();
$p = $invoice->payments->first();
if ($p && (int)$p->amount == 0) {
$p->amount = $val;
$p->applied = $val;
$p->save();
$p->saveQuietly();
$pivot = $p->paymentables->first();
$pivot->amount = $val;
@ -1008,6 +1049,7 @@ class CheckData extends Command
BankTransaction::with('payment')->withTrashed()->where('invoice_ids', ',,,,,,,,')->cursor()->each(function ($bt) {
if($bt->payment->exists()) {
$this->isValid = false;
$bt->invoice_ids = collect($bt->payment->invoices)->pluck('hashed_id')->implode(',');
$bt->save();
@ -1038,4 +1080,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
{
use MakesHash, GeneratesCounter;
use MakesHash;
use GeneratesCounter;
/**
* @var string
@ -97,7 +98,7 @@ class CreateAccount extends Command
'phone' => '',
]);
$company_token = new CompanyToken;
$company_token = new CompanyToken();
$company_token->user_id = $user->id;
$company_token->company_id = $company->id;
$company_token->account_id = $account->id;

View File

@ -61,7 +61,8 @@ use stdClass;
class CreateSingleAccount extends Command
{
use MakesHash, GeneratesCounter;
use MakesHash;
use GeneratesCounter;
protected $description = 'Create Single Sample Account';
@ -100,6 +101,31 @@ class CreateSingleAccount extends Command
$this->warmCache();
$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()
@ -163,7 +189,7 @@ class CreateSingleAccount extends Command
]);
}
$company_token = new CompanyToken;
$company_token = new CompanyToken();
$company_token->user_id = $user->id;
$company_token->company_id = $company->id;
$company_token->account_id = $account->id;
@ -776,7 +802,7 @@ class CreateSingleAccount extends Command
private function createGateways($company, $user)
{
if (config('ninja.testvars.stripe') && ($this->gateway == 'all' || $this->gateway == 'stripe')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23';
@ -789,15 +815,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.paypal') && ($this->gateway == 'all' || $this->gateway == 'paypal')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '38f2c48af60c7dd69e04248cbb24c36e';
@ -810,15 +836,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
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->user_id = $user->id;
$cg->gateway_key = '80af24a6a691230bbec33e930ab40665';
@ -831,8 +857,8 @@ class CreateSingleAccount extends Command
// $gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{3} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{3} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
@ -841,7 +867,7 @@ class CreateSingleAccount extends Command
if (config('ninja.testvars.checkout') && ($this->gateway == 'all' || $this->gateway == 'checkout')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '3758e7f7c6f4cecf0f4f348b9a00f456';
@ -852,17 +878,17 @@ class CreateSingleAccount extends Command
$cg->config = encrypt(config('ninja.testvars.checkout'));
$cg->save();
$gateway_types = $cg->driver(new Client)->gatewayTypes();
$gateway_types = $cg->driver(new Client())->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.authorize') && ($this->gateway == 'all' || $this->gateway == 'authorizenet')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '3b6621f970ab18887c4f6dca78d3f8bb';
@ -873,17 +899,17 @@ class CreateSingleAccount extends Command
$cg->config = encrypt(config('ninja.testvars.authorize'));
$cg->save();
$gateway_types = $cg->driver(new Client)->gatewayTypes();
$gateway_types = $cg->driver(new Client())->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.wepay') && ($this->gateway == 'all' || $this->gateway == 'wepay')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '8fdeed552015b3c7b44ed6c8ebd9e992';
@ -896,15 +922,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.braintree') && ($this->gateway == 'all' || $this->gateway == 'braintree')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = 'f7ec488676d310683fb51802d076d713';
@ -917,8 +943,8 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
@ -926,7 +952,7 @@ class CreateSingleAccount extends Command
if (config('ninja.testvars.paytrace.decrypted') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = 'bbd736b3254b0aabed6ad7fda1298c88';
@ -941,15 +967,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.mollie') && ($this->gateway == 'all' || $this->gateway == 'mollie')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '1bd651fb213ca0c9d66ae3c336dc77e8';
@ -962,15 +988,15 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.square') && ($this->gateway == 'all' || $this->gateway == 'square')) {
$cg = new CompanyGateway;
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '65faab2ab6e3223dbe848b1686490baz';
@ -983,8 +1009,8 @@ class CreateSingleAccount extends Command
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass;
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();

View File

@ -47,7 +47,8 @@ use Illuminate\Support\Str;
class CreateTestData extends Command
{
use MakesHash, GeneratesCounter;
use MakesHash;
use GeneratesCounter;
/**
* @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->company_id = $company->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->company_id = $company->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->company_id = $company->id;
$company_token->account_id = $account->id;

View File

@ -54,7 +54,9 @@ use Illuminate\Support\Str;
class DemoMode extends Command
{
use MakesHash, GeneratesCounter, AppSetup;
use MakesHash;
use GeneratesCounter;
use AppSetup;
protected $signature = 'ninja:demo-mode';
@ -151,7 +153,7 @@ class DemoMode extends Command
(new CreateCompanyPaymentTerms($company, $user))->handle();
(new CreateCompanyTaskStatuses($company, $user))->handle();
$company_token = new CompanyToken;
$company_token = new CompanyToken();
$company_token->user_id = $user->id;
$company_token->company_id = $company->id;
$company_token->account_id = $account->id;
@ -182,7 +184,7 @@ class DemoMode extends Command
'email_verified_at' => now(),
]);
$company_token = new CompanyToken;
$company_token = new CompanyToken();
$company_token->user_id = $u2->id;
$company_token->company_id = $company->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->document();
$design_object = new stdClass;
$design_object = new stdClass();
$design_object->includes = $invoice_design->getSectionHTML('style');
$design_object->header = $invoice_design->getSectionHTML('header');
$design_object->body = $invoice_design->getSectionHTML('body');

View File

@ -50,9 +50,9 @@ class S3Cleanup extends Command
*/
public function handle()
{
if (!Ninja::isHosted()) {
return;
}
// if (!Ninja::isHosted()) {
// return;
// }
$c1 = Company::on('db-ninja-01')->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
class SendRemindersCron extends Command
{
use MakesReminders, MakesDates;
use MakesReminders;
use MakesDates;
/**
* The name and signature of the console command.
@ -158,7 +159,7 @@ class SendRemindersCron extends Command
$fee += round($invoice->balance * $percent / 100, 2);
}
$invoice_item = new InvoiceItem;
$invoice_item = new InvoiceItem();
$invoice_item->type_id = '5';
$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())]);

View File

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

View File

@ -58,6 +58,7 @@ class TranslationsExport extends Command
'it',
'ja',
'km_KH',
'lo_LA',
'lt',
'lv_LV',
'mk_MK',
@ -137,6 +138,10 @@ class TranslationsExport extends Command
Storage::disk('local')->makeDirectory("lang/{$lang}");
$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));
}
}

View File

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

View File

@ -47,71 +47,71 @@ class Kernel extends ConsoleKernel
protected function schedule(Schedule $schedule)
{
/* 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 */
$schedule->job(new QueueSize)->everyFiveMinutes()->withoutOverlapping()->name('queue-size-job')->onOneServer();
$schedule->job(new QueueSize())->everyFiveMinutes()->withoutOverlapping()->name('queue-size-job')->onOneServer();
/* 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*/
$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 */
$schedule->job(new TaskScheduler())->hourlyAt(10)->withoutOverlapping()->name('task-scheduler-job')->onOneServer();
/* 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*/
$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 */
$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 */
$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 */
$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*/
$schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
/* Sends recurring expenses*/
$schedule->job(new RecurringExpensesCron())->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
/* 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 */
$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 */
$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 */
$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 */
$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 */
$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()) {
$schedule->call(function () {
Account::whereNotNull('id')->update(['is_scheduler_running' => true]);
Account::query()->whereNotNull('id')->update(['is_scheduler_running' => true]);
})->everyFiveMinutes();
}
/* Run hosted specific jobs */
if (Ninja::isHosted()) {
$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();
$schedule->job(new AdjustEmailQuota())->dailyAt('23:30')->withoutOverlapping();
/* 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();

View File

@ -229,7 +229,7 @@ class CompanySettings extends BaseSettings
public $require_quote_signature = false; //@TODO ben to confirm
//email settings
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun' //@implemented
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun' //@implemented
public $gmail_sending_user_id = '0'; //@implemented
@ -493,7 +493,10 @@ class CompanySettings extends BaseSettings
public $payment_email_all_contacts = false;
public $show_pdfhtml_on_mobile = true;
public static $casts = [
'show_pdfhtml_on_mobile' => 'bool',
'payment_email_all_contacts' => 'bool',
'statement_design_id' => 'string',
'delivery_note_design_id' => 'string',
@ -857,7 +860,7 @@ class CompanySettings extends BaseSettings
*/
public static function notificationDefaults(): stdClass
{
$notification = new stdClass;
$notification = new stdClass();
$notification->email = [];
$notification->email = ['invoice_sent_all'];
@ -873,7 +876,7 @@ class CompanySettings extends BaseSettings
*/
public static function notificationAdminDefaults(): stdClass
{
$notification = new stdClass;
$notification = new stdClass();
$notification->email = [];
$notification->email = ['invoice_sent_all'];

View File

@ -15,6 +15,23 @@ use Illuminate\Support\Facades\App;
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)
{
App::setLocale($locale);

View File

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

View File

@ -319,6 +319,7 @@ class BaseRule implements RuleInterface
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt($item),
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced($item),
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override($item),
Product::PRODUCT_TYPE_ZERO_RATED => $this->zeroRated($item),
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
{
return $this;

View File

@ -11,6 +11,7 @@
namespace App\DataMapper\Tax\DE;
use App\DataMapper\InvoiceItem;
use App\DataMapper\Tax\BaseRule;
use App\DataMapper\Tax\RuleInterface;
use App\Models\Product;
@ -63,7 +64,7 @@ class Rule extends BaseRule implements RuleInterface
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);
}

View File

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

View File

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

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
{
use Dispatchable, InteractsWithSockets, SerializesModels;
use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
public $user;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)
{

View File

@ -22,7 +22,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)

View File

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

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)
{

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)
{

View File

@ -23,7 +23,9 @@ use Illuminate\Queue\SerializesModels;
*/
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)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -271,6 +271,9 @@ class Handler extends ExceptionHandler
case 'vendor':
$login = 'vendor.catchall';
break;
case 'ronin':
$login = 'ronin.login';
break;
default:
$login = 'default';
break;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,6 @@ use League\Csv\Writer;
class ActivityExport extends BaseExport
{
private $entity_transformer;
public string $date_key = 'created_at';

View File

@ -11,27 +11,29 @@
namespace App\Export\CSV;
use App\Models\Task;
use App\Models\User;
use App\Models\Quote;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company;
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\Invoice;
use App\Models\Payment;
use App\Models\Product;
use App\Models\PurchaseOrder;
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 App\Models\Document;
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;
class BaseExport
@ -387,6 +389,8 @@ class BaseExport
protected array $expense_report_keys = [
'amount' => 'expense.amount',
'tax_amount' => 'expense.tax_amount',
'net_amount' => 'expense.net_amount',
'category' => 'expense.category_id',
// 'client' => 'expense.client_id',
'custom_value1' => 'expense.custom_value1',
@ -830,6 +834,42 @@ class BaseExport
return $query;
}
protected function addClientFilter($query, $clients): Builder
{
$transformed_clients = $this->transformKeys(explode(',', $clients));
$query->whereIn('client_id', $transformed_clients);
return $query;
}
protected function addVendorFilter($query, $vendors): Builder
{
$transformed_vendors = $this->transformKeys(explode(',', $vendors));
$query->whereIn('vendor_id', $transformed_vendors);
return $query;
}
protected function addProjectFilter($query, $projects): Builder
{
$transformed_projects = $this->transformKeys(explode(',', $projects));
$query->whereIn('project_id', $transformed_projects);
return $query;
}
protected function addCategoryFilter($query, $expense_categories): Builder
{
$transformed_expense_categories = $this->transformKeys(explode(',', $expense_categories));
$query->whereIn('category_id', $transformed_expense_categories);
return $query;
}
protected function addInvoiceStatusFilter($query, $status): Builder
{
@ -1220,4 +1260,32 @@ class BaseExport
return $clean_row;
}
public function queueDocuments(Builder $query)
{
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'])
$user = User::where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first();
ZipDocuments::dispatch($documents, $this->company, $user);
}
}
}

View File

@ -131,6 +131,10 @@ class ClientExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -181,9 +185,9 @@ class ClientExport extends BaseExport
}
}
return $entity;
// return $entity;
// return $this->decorateAdvancedFields($client, $entity);
return $this->decorateAdvancedFields($client, $entity);
}
public function processMetaData(array $row, $resource): array
@ -221,21 +225,21 @@ class ClientExport extends BaseExport
$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.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.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.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.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)) {
$entity['client.classification'] = ctrans("texts.{$client->classification}") ?? '';

View File

@ -25,7 +25,6 @@ use Illuminate\Database\Eloquent\Builder;
class ContactExport extends BaseExport
{
private ClientTransformer $client_transformer;
private ClientContactTransformer $contact_transformer;
@ -129,8 +128,8 @@ class ContactExport extends BaseExport
}
}
return $entity;
// return $this->decorateAdvancedFields($contact->client, $entity);
// return $entity;
return $this->decorateAdvancedFields($contact->client, $entity);
}
private function decorateAdvancedFields(Client $client, array $entity): array
@ -151,6 +150,15 @@ class ContactExport extends BaseExport
$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;
}
}

View File

@ -24,7 +24,6 @@ use League\Csv\Writer;
class CreditExport extends BaseExport
{
private CreditTransformer $credit_transformer;
private Decorator $decorator;
@ -108,6 +107,10 @@ class CreditExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -161,29 +164,29 @@ class CreditExport extends BaseExport
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('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('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('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('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('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.status', $this->input['report_keys'])) {
// $entity['credit.status'] = $credit->stringStatus($credit->status_id);
// }
if (in_array('credit.assigned_user_id', $this->input['report_keys'])) {
$entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name() : '';

View File

@ -22,7 +22,6 @@ use League\Csv\Writer;
class DocumentExport extends BaseExport
{
private $entity_transformer;
public string $date_key = 'created_at';
@ -79,6 +78,10 @@ class DocumentExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -73,6 +73,13 @@ class ExpenseExport extends BaseExport
$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()
->with('client')
->withTrashed()
@ -81,6 +88,26 @@ class ExpenseExport extends BaseExport
$query = $this->addDateRange($query);
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;
}
@ -118,43 +145,39 @@ class ExpenseExport extends BaseExport
} elseif (array_key_exists($key, $transformed_expense)) {
$entity[$key] = $transformed_expense[$key];
} else {
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $expense);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $expense, $this->expense_transformer);
}
}
return $entity;
// return $this->decorateAdvancedFields($expense, $entity);
return $this->decorateAdvancedFields($expense, $entity);
}
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.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.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.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.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.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.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'])) {
$entity['expense.project_id'] = $expense->project ? $expense->project->name : '';
@ -172,6 +195,38 @@ class ExpenseExport extends BaseExport
$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;
}
private function calcInclusiveLineTax($tax_rate, $amount, $precision): float
{
return round($amount - ($amount / (1 + ($tax_rate / 100))), $precision);
}
}

View File

@ -62,10 +62,14 @@ class InvoiceExport extends BaseExport
$query = $this->addDateRange($query);
if(isset($this->input['status'])) {
if($this->input['status'] ?? false) {
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
}
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -120,40 +124,36 @@ class InvoiceExport extends BaseExport
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]];
} else {
// 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
{
if (in_array('invoice.country_id', $this->input['report_keys'])) {
$entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
}
// if (in_array('invoice.country_id', $this->input['report_keys'])) {
// $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
// }
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;
}
// 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;
// }
if (in_array('invoice.client_id', $this->input['report_keys'])) {
$entity['invoice.client_id'] = $invoice->client->present()->name();
}
// if (in_array('invoice.client_id', $this->input['report_keys'])) {
// $entity['invoice.client_id'] = $invoice->client->present()->name();
// }
if (in_array('invoice.status', $this->input['report_keys'])) {
$entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
}
// if (in_array('invoice.status', $this->input['report_keys'])) {
// $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
// }
if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
}
// if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
// $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
// }
if (in_array('invoice.auto_bill_enabled', $this->input['report_keys'])) {
$entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
@ -167,7 +167,6 @@ class InvoiceExport extends BaseExport
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
}
return $entity;
}
}

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class InvoiceItemExport extends BaseExport
{
private $invoice_transformer;
public string $date_key = 'date';
@ -78,6 +77,10 @@ class InvoiceItemExport extends BaseExport
$query = $this->applyFilters($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -92,7 +95,6 @@ class InvoiceItemExport extends BaseExport
return ['identifier' => $key, 'display_value' => $headerdisplay[$value]];
})->toArray();
$query->cursor()
->each(function ($resource) {
$this->iterateItems($resource);
@ -196,43 +198,43 @@ class InvoiceItemExport extends BaseExport
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
}
}
return $entity;
// return $this->decorateAdvancedFields($invoice, $entity);
// return $entity;
return $this->decorateAdvancedFields($invoice, $entity);
}
private function decorateAdvancedFields(Invoice $invoice, array $entity): array
{
if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
}
// if (in_array('currency_id', $this->input['report_keys'])) {
// $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
// }
if(array_key_exists('type', $entity)) {
$entity['type'] = $invoice->typeIdString($entity['type']);
}
// if(array_key_exists('type', $entity)) {
// $entity['type'] = $invoice->typeIdString($entity['type']);
// }
if(array_key_exists('tax_category', $entity)) {
$entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
}
// if(array_key_exists('tax_category', $entity)) {
// $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
// }
if (in_array('invoice.country_id', $this->input['report_keys'])) {
$entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
}
// if (in_array('invoice.country_id', $this->input['report_keys'])) {
// $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
// }
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;
}
// 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;
// }
if (in_array('invoice.client_id', $this->input['report_keys'])) {
$entity['invoice.client_id'] = $invoice->client->present()->name();
}
// if (in_array('invoice.client_id', $this->input['report_keys'])) {
// $entity['invoice.client_id'] = $invoice->client->present()->name();
// }
if (in_array('invoice.status', $this->input['report_keys'])) {
$entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
}
// if (in_array('invoice.status', $this->input['report_keys'])) {
// $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
// }
if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
}
// if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
// $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
// }
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';

View File

@ -61,6 +61,10 @@ class PaymentExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -125,55 +129,55 @@ class PaymentExport extends BaseExport
}
return $entity;
// return $this->decorateAdvancedFields($payment, $entity);
// return $entity;
return $this->decorateAdvancedFields($payment, $entity);
}
private function decorateAdvancedFields(Payment $payment, array $entity): array
{
if (in_array('status_id', $this->input['report_keys'])) {
$entity['status'] = $payment->stringStatus($payment->status_id);
}
// if (in_array('status_id', $this->input['report_keys'])) {
// $entity['status'] = $payment->stringStatus($payment->status_id);
// }
if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : '';
}
// if (in_array('vendor_id', $this->input['report_keys'])) {
// $entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : '';
// }
if (in_array('project_id', $this->input['report_keys'])) {
$entity['project'] = $payment->project()->exists() ? $payment->project->name : '';
}
// if (in_array('project_id', $this->input['report_keys'])) {
// $entity['project'] = $payment->project()->exists() ? $payment->project->name : '';
// }
if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
}
// if (in_array('currency_id', $this->input['report_keys'])) {
// $entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
// }
if (in_array('payment.currency', $this->input['report_keys'])) {
$entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
}
// if (in_array('payment.currency', $this->input['report_keys'])) {
// $entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
// }
if (in_array('exchange_currency_id', $this->input['report_keys'])) {
$entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : '';
}
// if (in_array('exchange_currency_id', $this->input['report_keys'])) {
// $entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : '';
// }
if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $payment->client->present()->name();
}
// if (in_array('client_id', $this->input['report_keys'])) {
// $entity['client'] = $payment->client->present()->name();
// }
if (in_array('type_id', $this->input['report_keys'])) {
$entity['type'] = $payment->translatedType();
}
// if (in_array('type_id', $this->input['report_keys'])) {
// $entity['type'] = $payment->translatedType();
// }
if (in_array('payment.method', $this->input['report_keys'])) {
$entity['payment.method'] = $payment->translatedType();
}
// if (in_array('payment.method', $this->input['report_keys'])) {
// $entity['payment.method'] = $payment->translatedType();
// }
if (in_array('payment.status', $this->input['report_keys'])) {
$entity['payment.status'] = $payment->stringStatus($payment->status_id);
}
// if (in_array('payment.status', $this->input['report_keys'])) {
// $entity['payment.status'] = $payment->stringStatus($payment->status_id);
// }
if (in_array('gateway_type_id', $this->input['report_keys'])) {
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
}
// if (in_array('gateway_type_id', $this->input['report_keys'])) {
// $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
// }
if (in_array('payment.assigned_user_id', $this->input['report_keys'])) {
$entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : '';

View File

@ -78,6 +78,10 @@ class ProductExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -37,6 +37,7 @@ class ProductSalesExport extends BaseExport
'product_key' => 'product_key',
'notes' => 'notes',
'quantity' => 'quantity',
'currency' => 'currency',
'cost' => 'price',
'price' => 'cost',
'markup' => 'markup',
@ -163,6 +164,7 @@ class ProductSalesExport extends BaseExport
private function buildRow($invoice, $invoice_item): array
{
$transformed_entity = (array)$invoice_item;
$transformed_entity['price'] = ($invoice_item->product_cost ?? 1) * ($invoice->exchange_rate ?? 1) ;
$entity = [];
@ -171,6 +173,8 @@ class ProductSalesExport extends BaseExport
if (array_key_exists($key, $transformed_entity)) {
$entity[$keyval] = $transformed_entity[$key];
} elseif($key == 'currency') {
$entity['currency'] = $invoice->client->currency()->code;
} else {
$entity[$keyval] = '';
}
@ -184,9 +188,9 @@ class ProductSalesExport extends BaseExport
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 */
$unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];

View File

@ -23,7 +23,6 @@ use App\Transformers\PurchaseOrderTransformer;
class PurchaseOrderExport extends BaseExport
{
private $purchase_order_transformer;
public string $date_key = 'date';
@ -109,6 +108,10 @@ class PurchaseOrderExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -173,8 +176,8 @@ class PurchaseOrderExport extends BaseExport
}
return $entity;
// return $this->decorateAdvancedFields($purchase_order, $entity);
// return $entity;
return $this->decorateAdvancedFields($purchase_order, $entity);
}
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity): array
@ -195,6 +198,15 @@ class PurchaseOrderExport extends BaseExport
$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;
}
}

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class PurchaseOrderItemExport extends BaseExport
{
private $purchase_order_transformer;
public string $date_key = 'date';
@ -68,6 +67,10 @@ class PurchaseOrderItemExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -206,6 +209,16 @@ class PurchaseOrderItemExport extends BaseExport
$entity['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;
}

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class QuoteExport extends BaseExport
{
private $quote_transformer;
public string $date_key = 'date';
@ -70,6 +69,10 @@ class QuoteExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -133,8 +136,8 @@ class QuoteExport extends BaseExport
}
}
return $entity;
// return $this->decorateAdvancedFields($quote, $entity);
// return $entity;
return $this->decorateAdvancedFields($quote, $entity);
}
private function decorateAdvancedFields(Quote $quote, array $entity): array

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class QuoteItemExport extends BaseExport
{
private $quote_transformer;
public string $date_key = 'date';
@ -46,7 +45,7 @@ class QuoteItemExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->quote_transformer = new QuoteTransformer();
$this->decorator = new Decorator;
$this->decorator = new Decorator();
}
public function init(): Builder
@ -71,6 +70,10 @@ class QuoteItemExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -189,22 +192,22 @@ class QuoteItemExport extends BaseExport
}
}
return $entity;
// return $this->decorateAdvancedFields($quote, $entity);
// return $entity;
return $this->decorateAdvancedFields($quote, $entity);
}
private function decorateAdvancedFields(Quote $quote, array $entity): array
{
if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code;
}
// if (in_array('currency_id', $this->input['report_keys'])) {
// $entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code;
// }
if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $quote->client->present()->name();
}
// if (in_array('client_id', $this->input['report_keys'])) {
// $entity['client'] = $quote->client->present()->name();
// }
if (in_array('status_id', $this->input['report_keys'])) {
$entity['status'] = $quote->stringStatus($quote->status_id);
}
// if (in_array('status_id', $this->input['report_keys'])) {
// $entity['status'] = $quote->stringStatus($quote->status_id);
// }
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name() : '';

View File

@ -23,7 +23,6 @@ use League\Csv\Writer;
class RecurringInvoiceExport extends BaseExport
{
private $invoice_transformer;
public string $date_key = 'date';
@ -109,8 +108,6 @@ class RecurringInvoiceExport extends BaseExport
private function buildRow(RecurringInvoice $invoice): array
{
$transformed_invoice = $this->invoice_transformer->transform($invoice);
$transformed_invoice['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id); //need to inject this here because it is also a valid key
// nlog($transformed_invoice);
$entity = [];
@ -122,8 +119,7 @@ class RecurringInvoiceExport extends BaseExport
$entity[$key] = $transformed_invoice[$parts[1]];
} elseif($parts[0] == 'item') {
$entity[$key] = '';
}
else {
} else {
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
@ -131,36 +127,36 @@ class RecurringInvoiceExport extends BaseExport
}
}
// nlog($entity);
return $entity;
// return $this->decorateAdvancedFields($invoice, $entity);
// return $entity;
return $this->decorateAdvancedFields($invoice, $entity);
}
private function decorateAdvancedFields(RecurringInvoice $invoice, array $entity): array
{
if (in_array('country_id', $this->input['report_keys'])) {
$entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
}
// if (in_array('country_id', $this->input['report_keys'])) {
// $entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
// }
if (in_array('currency_id', $this->input['report_keys'])) {
$entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
}
// if (in_array('currency_id', $this->input['report_keys'])) {
// $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
// }
if (in_array('client_id', $this->input['report_keys'])) {
$entity['client'] = $invoice->client->present()->name();
}
// if (in_array('client_id', $this->input['report_keys'])) {
// $entity['client'] = $invoice->client->present()->name();
// }
if (in_array('recurring_invoice.status', $this->input['report_keys'])) {
$entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id);
}
// if (in_array('recurring_invoice.status', $this->input['report_keys'])) {
// $entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id);
// }
if (in_array('project_id', $this->input['report_keys'])) {
$entity['project'] = $invoice->project ? $invoice->project->name : '';
}
// if (in_array('project_id', $this->input['report_keys'])) {
// $entity['project'] = $invoice->project ? $invoice->project->name : '';
// }
if (in_array('vendor_id', $this->input['report_keys'])) {
$entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : '';
}
// if (in_array('vendor_id', $this->input['report_keys'])) {
// $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'])) {
$entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);

View File

@ -26,7 +26,6 @@ use League\Csv\Writer;
class TaskExport extends BaseExport
{
private $entity_transformer;
public string $date_key = 'created_at';
@ -73,6 +72,10 @@ class TaskExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -120,7 +123,7 @@ class TaskExport extends BaseExport
$this->storage_array = [];
});
// nlog($this->storage_item_array);
return array_merge(['columns' => $header], $this->storage_item_array);
}
@ -140,19 +143,11 @@ class TaskExport extends BaseExport
} elseif (in_array($key, ['task.start_date', 'task.end_date', 'task.duration'])) {
$entity[$key] = '';
} else {
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $task);
// $entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
}
// $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)) {
$this->storage_array[] = $entity;
} else {
@ -197,13 +192,13 @@ class TaskExport extends BaseExport
$entity['task.duration'] = $task->calcDuration();
}
// $entity = $this->decorateAdvancedFields($task, $entity);
$entity = $this->decorateAdvancedFields($task, $entity);
$this->storage_array[] = $entity;
unset($entity['task.start_date']);
unset($entity['task.end_date']);
unset($entity['task.duration']);
$entity['task.start_date'] = '';
$entity['task.end_date'] = '';
$entity['task.duration'] = '';
}
}
@ -218,6 +213,15 @@ class TaskExport extends BaseExport
$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;
}
}

View File

@ -24,7 +24,6 @@ use League\Csv\Writer;
class VendorExport extends BaseExport
{
private $vendor_transformer;
private $contact_transformer;
@ -67,6 +66,10 @@ class VendorExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}
@ -126,15 +129,14 @@ class VendorExport extends BaseExport
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
$entity[$key] = $transformed_contact[$parts[1]];
} else {
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $vendor);
// $entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
}
}
return $entity;
// return $this->decorateAdvancedFields($vendor, $entity);
// return $entity;
return $this->decorateAdvancedFields($vendor, $entity);
}
private function decorateAdvancedFields(Vendor $vendor, array $entity): array
@ -151,6 +153,15 @@ class VendorExport extends BaseExport
$entity['vendor.classification'] = ctrans("texts.{$vendor->classification}") ?? '';
}
if (in_array('vendor.user_id', $this->input['report_keys'])) {
$entity['vendor.user_id'] = $vendor->user ? $vendor->user->present()->name() : '';
}
if (in_array('vendor.assigned_user_id', $this->input['report_keys'])) {
$entity['vendor.assigned_user_id'] = $vendor->assigned_user ? $vendor->assigned_user->present()->name() : '';
}
// $entity['status'] = $this->calculateStatus($vendor);
return $entity;

View File

@ -29,8 +29,7 @@ class ClientDecorator extends Decorator implements DecoratorInterface
if($client && method_exists($this, $key)) {
return $this->{$key}($client);
}
elseif($client && $client->{$key}) {
} elseif($client && $client->{$key}) {
return $client->{$key};
}

View File

@ -27,8 +27,7 @@ class ContactDecorator implements DecoratorInterface
if($contact && method_exists($this, $key)) {
return $this->{$key}($contact);
}
elseif($contact && $contact->{$key}){
} elseif($contact && $contact->{$key}) {
return $contact->{$key};
}

View File

@ -13,7 +13,6 @@ namespace App\Export\Decorators;
class Decorator implements DecoratorInterface
{
public function __construct()
{
}

View File

@ -15,7 +15,6 @@ use App\Models\Payment;
class PaymentDecorator extends Decorator implements DecoratorInterface
{
private $entity_key = 'payment';
public function transform(string $key, $entity): mixed
@ -42,8 +41,7 @@ class PaymentDecorator extends Decorator implements DecoratorInterface
if($payment && method_exists($this, $key)) {
return $this->{$key}($payment);
}
elseif($payment && $payment->{$key}){
} elseif($payment && $payment->{$key}) {
return $payment->{$key};
}

View File

@ -17,7 +17,7 @@ class BankIntegrationFactory
{
public static function create(int $company_id, int $user_id, int $account_id): BankIntegration
{
$bank_integration = new BankIntegration;
$bank_integration = new BankIntegration();
$bank_integration->account_id = $account_id;
$bank_integration->user_id = $user_id;
$bank_integration->company_id = $company_id;

View File

@ -17,7 +17,7 @@ class BankTransactionFactory
{
public static function create(int $company_id, int $user_id): BankTransaction
{
$bank_transaction = new BankTransaction;
$bank_transaction = new BankTransaction();
$bank_transaction->user_id = $user_id;
$bank_transaction->company_id = $company_id;

View File

@ -17,7 +17,7 @@ class BankTransactionRuleFactory
{
public static function create(int $company_id, int $user_id): BankTransactionRule
{
$bank_transaction_rule = new BankTransactionRule;
$bank_transaction_rule = new BankTransactionRule();
$bank_transaction_rule->user_id = $user_id;
$bank_transaction_rule->company_id = $company_id;

View File

@ -18,7 +18,7 @@ class ClientContactFactory
{
public static function create(int $company_id, int $user_id): ClientContact
{
$client_contact = new ClientContact;
$client_contact = new ClientContact();
$client_contact->first_name = '';
$client_contact->user_id = $user_id;
$client_contact->company_id = $company_id;

View File

@ -19,7 +19,7 @@ class ClientFactory
{
public static function create(int $company_id, int $user_id): Client
{
$client = new Client;
$client = new Client();
$client->company_id = $company_id;
$client->user_id = $user_id;
$client->name = '';

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