mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
merge v5-develop
This commit is contained in:
commit
da54eea655
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -14,6 +14,11 @@ https://invoiceninja.github.io/docs/self-host-troubleshooting/ -->
|
|||||||
- Version: <!-- i.e. v4.5.25 / v5.0.30 -->
|
- Version: <!-- i.e. v4.5.25 / v5.0.30 -->
|
||||||
- Environment: <!-- Docker/Shared Hosting/ZIP/Other -->
|
- Environment: <!-- Docker/Shared Hosting/ZIP/Other -->
|
||||||
|
|
||||||
|
## Interface
|
||||||
|
- Flutter: []
|
||||||
|
- React: []
|
||||||
|
- Both: []
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
- Can you replicate the issue on our v5 demo site https://demo.invoiceninja.com or https://react.invoicing.co/demo?
|
- Can you replicate the issue on our v5 demo site https://demo.invoiceninja.com or https://react.invoicing.co/demo?
|
||||||
- Have you searched existing issues?
|
- Have you searched existing issues?
|
||||||
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -32,9 +32,9 @@ jobs:
|
|||||||
- name: Prepare Laravel Application
|
- name: Prepare Laravel Application
|
||||||
run: |
|
run: |
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
php artisan key:generate
|
php artisan key:generate --force
|
||||||
php artisan optimize
|
php artisan optimize
|
||||||
php artisan storage:link
|
php artisan storage:link --force
|
||||||
sudo php artisan cache:clear
|
sudo php artisan cache:clear
|
||||||
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
||||||
sudo find ./ -type d -exec chmod 755 {} \;
|
sudo find ./ -type d -exec chmod 755 {} \;
|
||||||
@ -46,7 +46,11 @@ jobs:
|
|||||||
git checkout main
|
git checkout main
|
||||||
npm i
|
npm i
|
||||||
npm run build
|
npm run build
|
||||||
cp -r dist/react/* ../public/react
|
|
||||||
|
mkdir -p ../public/react/${{ github.event.release.tag_name }}/
|
||||||
|
cp -r dist/react/* ../public/react/${{ github.event.release.tag_name }}/
|
||||||
|
cp -r dist/react/* ../public/react/
|
||||||
|
|
||||||
mkdir -p ../public/tinymce_6.4.2/tinymce/js/
|
mkdir -p ../public/tinymce_6.4.2/tinymce/js/
|
||||||
cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
|
cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -1 +1 @@
|
|||||||
5.6.26
|
5.7.22
|
@ -35,6 +35,7 @@ use App\Models\BankTransaction;
|
|||||||
use App\Models\QuoteInvitation;
|
use App\Models\QuoteInvitation;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
use App\Models\InvoiceInvitation;
|
use App\Models\InvoiceInvitation;
|
||||||
use App\DataMapper\ClientSettings;
|
use App\DataMapper\ClientSettings;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@ -185,6 +186,9 @@ class CheckData extends Command
|
|||||||
if ($cu->company && $cu->user) {
|
if ($cu->company && $cu->user) {
|
||||||
(new CreateCompanyToken($cu->company, $cu->user, 'System'))->handle();
|
(new CreateCompanyToken($cu->company, $cu->user, 'System'))->handle();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// $cu->forceDelete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -468,7 +472,7 @@ class CheckData extends Command
|
|||||||
$ii->saveQuietly();
|
$ii->saveQuietly();
|
||||||
});
|
});
|
||||||
|
|
||||||
collect([Invoice::class, Quote::class, Credit::class, PurchaseOrder::class])->each(function ($entity) {
|
collect([Invoice::class, Quote::class, Credit::class, PurchaseOrder::class, RecurringInvoice::class])->each(function ($entity) {
|
||||||
if ($entity::doesntHave('invitations')->count() > 0) {
|
if ($entity::doesntHave('invitations')->count() > 0) {
|
||||||
$entity::doesntHave('invitations')->cursor()->each(function ($entity) {
|
$entity::doesntHave('invitations')->cursor()->each(function ($entity) {
|
||||||
$client_vendor_key = 'client_id';
|
$client_vendor_key = 'client_id';
|
||||||
@ -545,7 +549,7 @@ class CheckData extends Command
|
|||||||
|
|
||||||
private function clientPaidToDateQuery()
|
private function clientPaidToDateQuery()
|
||||||
{
|
{
|
||||||
$results = \DB::select(\DB::raw("
|
$results = \DB::select("
|
||||||
SELECT
|
SELECT
|
||||||
clients.id as client_id,
|
clients.id as client_id,
|
||||||
clients.paid_to_date as client_paid_to_date,
|
clients.paid_to_date as client_paid_to_date,
|
||||||
@ -560,14 +564,14 @@ class CheckData extends Command
|
|||||||
GROUP BY clients.id
|
GROUP BY clients.id
|
||||||
HAVING payments_applied != client_paid_to_date
|
HAVING payments_applied != client_paid_to_date
|
||||||
ORDER BY clients.id;
|
ORDER BY clients.id;
|
||||||
"));
|
");
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function clientCreditPaymentables($client)
|
private function clientCreditPaymentables($client)
|
||||||
{
|
{
|
||||||
$results = \DB::select(\DB::raw("
|
$results = \DB::select("
|
||||||
SELECT
|
SELECT
|
||||||
SUM(paymentables.amount - paymentables.refunded) as credit_payment
|
SUM(paymentables.amount - paymentables.refunded) as credit_payment
|
||||||
FROM payments
|
FROM payments
|
||||||
@ -579,7 +583,7 @@ class CheckData extends Command
|
|||||||
AND paymentables.amount > 0
|
AND paymentables.amount > 0
|
||||||
AND payments.is_deleted = 0
|
AND payments.is_deleted = 0
|
||||||
AND payments.client_id = ?;
|
AND payments.client_id = ?;
|
||||||
"), [App\Models\Credit::class, $client->id]);
|
", [App\Models\Credit::class, $client->id]);
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
@ -617,108 +621,9 @@ class CheckData extends Command
|
|||||||
$this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect paid to dates");
|
$this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect paid to dates");
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkPaidToDates()
|
|
||||||
{
|
|
||||||
$this->wrong_paid_to_dates = 0;
|
|
||||||
$credit_total_applied = 0;
|
|
||||||
|
|
||||||
$clients = DB::table('clients')
|
|
||||||
->leftJoin('payments', function ($join) {
|
|
||||||
$join->on('payments.client_id', '=', 'clients.id')
|
|
||||||
->where('payments.is_deleted', 0)
|
|
||||||
->whereIn('payments.status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED]);
|
|
||||||
})
|
|
||||||
->where('clients.is_deleted', 0)
|
|
||||||
->where('clients.updated_at', '>', now()->subDays(2))
|
|
||||||
->groupBy('clients.id')
|
|
||||||
->havingRaw('clients.paid_to_date != sum(coalesce(payments.amount - payments.refunded, 0))')
|
|
||||||
->get(['clients.id', 'clients.paid_to_date', DB::raw('sum(coalesce(payments.amount - payments.refunded, 0)) as amount')]);
|
|
||||||
|
|
||||||
/* Due to accounting differences we need to perform a second loop here to ensure there actually is an issue */
|
|
||||||
$clients->each(function ($client_record) use ($credit_total_applied) {
|
|
||||||
$client = Client::withTrashed()->find($client_record->id);
|
|
||||||
|
|
||||||
$total_invoice_payments = 0;
|
|
||||||
|
|
||||||
foreach ($client->invoices()->where('is_deleted', false)->where('status_id', '>', 1)->get() as $invoice) {
|
|
||||||
$total_invoice_payments += $invoice->payments()
|
|
||||||
->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
|
||||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
|
||||||
->pluck('p')
|
|
||||||
->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
//commented IN 27/06/2021 - sums ALL client payments AND the unapplied amounts to match the client paid to date
|
|
||||||
$p = Payment::where('client_id', $client->id)
|
|
||||||
->where('is_deleted', 0)
|
|
||||||
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
|
||||||
->sum(DB::Raw('amount - applied'));
|
|
||||||
|
|
||||||
$total_invoice_payments += $p;
|
|
||||||
|
|
||||||
// 10/02/21
|
|
||||||
foreach ($client->payments as $payment) {
|
|
||||||
$credit_total_applied += $payment->paymentables()
|
|
||||||
->where('paymentable_type', App\Models\Credit::class)
|
|
||||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
|
||||||
->pluck('p')
|
|
||||||
->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($credit_total_applied < 0) {
|
|
||||||
$total_invoice_payments += $credit_total_applied;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (round($total_invoice_payments, 2) != round($client->paid_to_date, 2)) {
|
|
||||||
$this->wrong_paid_to_dates++;
|
|
||||||
|
|
||||||
$this->logMessage($client->present()->name().' id = # '.$client->id." - Paid to date does not match Client Paid To Date = {$client->paid_to_date} - Invoice Payments = {$total_invoice_payments}");
|
|
||||||
|
|
||||||
$this->isValid = false;
|
|
||||||
|
|
||||||
if ($this->option('paid_to_date')) {
|
|
||||||
$this->logMessage("# {$client->id} " . $client->present()->name().' - '.$client->number." Fixing {$client->paid_to_date} to {$total_invoice_payments}");
|
|
||||||
$client->paid_to_date = $total_invoice_payments;
|
|
||||||
$client->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect paid to dates");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function checkInvoicePayments()
|
|
||||||
{
|
|
||||||
$this->wrong_balances = 0;
|
|
||||||
|
|
||||||
Client::cursor()->where('is_deleted', 0)->where('clients.updated_at', '>', now()->subDays(2))->each(function ($client) {
|
|
||||||
$client->invoices->where('is_deleted', false)->whereIn('status_id', '!=', Invoice::STATUS_DRAFT)->each(function ($invoice) use ($client) {
|
|
||||||
$total_paid = $invoice->payments()
|
|
||||||
->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
|
||||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
|
||||||
->pluck('p')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
$total_credit = $invoice->credits()->get()->sum('amount');
|
|
||||||
|
|
||||||
$calculated_paid_amount = $invoice->amount - $invoice->balance - $total_credit;
|
|
||||||
|
|
||||||
if ((string)$total_paid != (string)($invoice->amount - $invoice->balance - $total_credit)) {
|
|
||||||
$this->wrong_balances++;
|
|
||||||
|
|
||||||
$this->logMessage($client->present()->name().' - '.$client->id." - Total Paid = {$total_paid} != Calculated Total = {$calculated_paid_amount}");
|
|
||||||
|
|
||||||
$this->isValid = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->logMessage("{$this->wrong_balances} clients with incorrect invoice balances");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function clientBalanceQuery()
|
private function clientBalanceQuery()
|
||||||
{
|
{
|
||||||
$results = \DB::select(\DB::raw("
|
$results = \DB::select("
|
||||||
SELECT
|
SELECT
|
||||||
SUM(invoices.balance) as invoice_balance,
|
SUM(invoices.balance) as invoice_balance,
|
||||||
clients.id as client_id,
|
clients.id as client_id,
|
||||||
@ -732,7 +637,7 @@ class CheckData extends Command
|
|||||||
GROUP BY clients.id
|
GROUP BY clients.id
|
||||||
HAVING invoice_balance != clients.balance
|
HAVING invoice_balance != clients.balance
|
||||||
ORDER BY clients.id;
|
ORDER BY clients.id;
|
||||||
"));
|
");
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
@ -809,7 +714,7 @@ class CheckData extends Command
|
|||||||
|
|
||||||
private function invoiceBalanceQuery()
|
private function invoiceBalanceQuery()
|
||||||
{
|
{
|
||||||
$results = \DB::select(\DB::raw("
|
$results = \DB::select("
|
||||||
SELECT
|
SELECT
|
||||||
clients.id,
|
clients.id,
|
||||||
clients.balance,
|
clients.balance,
|
||||||
@ -823,7 +728,7 @@ class CheckData extends Command
|
|||||||
GROUP BY clients.id
|
GROUP BY clients.id
|
||||||
HAVING(invoices_balance != clients.balance)
|
HAVING(invoices_balance != clients.balance)
|
||||||
ORDER BY clients.id;
|
ORDER BY clients.id;
|
||||||
"));
|
");
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
@ -873,7 +778,7 @@ class CheckData extends Command
|
|||||||
$this->wrong_balances = 0;
|
$this->wrong_balances = 0;
|
||||||
$this->wrong_paid_to_dates = 0;
|
$this->wrong_paid_to_dates = 0;
|
||||||
|
|
||||||
foreach (Client::where('is_deleted', 0)->where('clients.updated_at', '>', now()->subDays(2))->cursor() as $client) {
|
foreach (Client::query()->where('is_deleted', 0)->where('clients.updated_at', '>', now()->subDays(2))->cursor() as $client) {
|
||||||
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2,3])->sum('balance');
|
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2,3])->sum('balance');
|
||||||
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
||||||
|
|
||||||
@ -957,7 +862,7 @@ class CheckData extends Command
|
|||||||
}
|
}
|
||||||
$records = DB::table($table)
|
$records = DB::table($table)
|
||||||
->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id")
|
->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id")
|
||||||
->where("{$table}.{$company_id}", '!=', DB::raw("{$tableName}.company_id"))
|
->whereRaw("{$table}.{$company_id} != {$tableName}.company_id")
|
||||||
->get(["{$table}.id"]);
|
->get(["{$table}.id"]);
|
||||||
|
|
||||||
if ($records->count()) {
|
if ($records->count()) {
|
||||||
@ -967,11 +872,6 @@ class CheckData extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// foreach(User::cursor() as $user) {
|
|
||||||
|
|
||||||
// $records = Company::where('account_id',)
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pluralizeEntityType($type)
|
public function pluralizeEntityType($type)
|
||||||
|
@ -61,6 +61,8 @@ class CreateTestData extends Command
|
|||||||
|
|
||||||
protected $invoice_repo;
|
protected $invoice_repo;
|
||||||
|
|
||||||
|
protected $count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
|
@ -48,7 +48,7 @@ class ReactBuilder extends Command
|
|||||||
{
|
{
|
||||||
$includes = '';
|
$includes = '';
|
||||||
|
|
||||||
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||||
|
|
||||||
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||||
if ($file->getExtension() == 'js') {
|
if ($file->getExtension() == 'js') {
|
||||||
|
@ -173,7 +173,7 @@ class SendRemindersCron extends Command
|
|||||||
/**Refresh Invoice values*/
|
/**Refresh Invoice values*/
|
||||||
$invoice->calc()->getInvoice()->save();
|
$invoice->calc()->getInvoice()->save();
|
||||||
$invoice->fresh();
|
$invoice->fresh();
|
||||||
$invoice->service()->deletePdf()->save();
|
// $invoice->service()->deletePdf()->save();
|
||||||
if ($invoice->client->getSetting('enable_e_invoice')){
|
if ($invoice->client->getSetting('enable_e_invoice')){
|
||||||
$invoice->service()->deleteEInvoice()->save();
|
$invoice->service()->deleteEInvoice()->save();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ class TypeCheck extends Command
|
|||||||
$client->save();
|
$client->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
Company::cursor()->each(function ($company) {
|
Company::query()->cursor()->each(function ($company) {
|
||||||
$this->logMessage("Checking company {$company->id}");
|
$this->logMessage("Checking company {$company->id}");
|
||||||
$company->saveSettings($company->settings, $company);
|
$company->saveSettings($company->settings, $company);
|
||||||
});
|
});
|
||||||
|
@ -11,28 +11,29 @@
|
|||||||
|
|
||||||
namespace App\Console;
|
namespace App\Console;
|
||||||
|
|
||||||
use App\Jobs\Cron\AutoBillCron;
|
use App\Utils\Ninja;
|
||||||
use App\Jobs\Cron\RecurringExpensesCron;
|
use App\Models\Account;
|
||||||
use App\Jobs\Cron\RecurringInvoicesCron;
|
|
||||||
use App\Jobs\Cron\SubscriptionCron;
|
|
||||||
use App\Jobs\Cron\UpdateCalculatedFields;
|
|
||||||
use App\Jobs\Invoice\InvoiceCheckLateWebhook;
|
|
||||||
use App\Jobs\Ninja\AdjustEmailQuota;
|
|
||||||
use App\Jobs\Ninja\BankTransactionSync;
|
|
||||||
use App\Jobs\Ninja\CompanySizeCheck;
|
|
||||||
use App\Jobs\Ninja\QueueSize;
|
use App\Jobs\Ninja\QueueSize;
|
||||||
use App\Jobs\Ninja\SystemMaintenance;
|
|
||||||
use App\Jobs\Ninja\TaskScheduler;
|
|
||||||
use App\Jobs\Quote\QuoteCheckExpired;
|
|
||||||
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
|
|
||||||
use App\Jobs\Util\DiskCleanup;
|
use App\Jobs\Util\DiskCleanup;
|
||||||
use App\Jobs\Util\ReminderJob;
|
use App\Jobs\Util\ReminderJob;
|
||||||
use App\Jobs\Util\SchedulerCheck;
|
use App\Jobs\Cron\AutoBillCron;
|
||||||
use App\Jobs\Util\UpdateExchangeRates;
|
|
||||||
use App\Jobs\Util\VersionCheck;
|
use App\Jobs\Util\VersionCheck;
|
||||||
use App\Models\Account;
|
use App\Jobs\Ninja\TaskScheduler;
|
||||||
use App\Utils\Ninja;
|
use App\Jobs\Util\SchedulerCheck;
|
||||||
|
use App\Jobs\Ninja\CheckACHStatus;
|
||||||
|
use App\Jobs\Cron\SubscriptionCron;
|
||||||
|
use App\Jobs\Ninja\AdjustEmailQuota;
|
||||||
|
use App\Jobs\Ninja\CompanySizeCheck;
|
||||||
|
use App\Jobs\Ninja\SystemMaintenance;
|
||||||
|
use App\Jobs\Quote\QuoteCheckExpired;
|
||||||
|
use App\Jobs\Util\UpdateExchangeRates;
|
||||||
|
use App\Jobs\Ninja\BankTransactionSync;
|
||||||
|
use App\Jobs\Cron\RecurringExpensesCron;
|
||||||
|
use App\Jobs\Cron\RecurringInvoicesCron;
|
||||||
|
use App\Jobs\Cron\UpdateCalculatedFields;
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
|
use App\Jobs\Invoice\InvoiceCheckLateWebhook;
|
||||||
|
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
|
||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
class Kernel extends ConsoleKernel
|
class Kernel extends ConsoleKernel
|
||||||
@ -107,7 +108,10 @@ class Kernel extends ConsoleKernel
|
|||||||
$schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping();
|
$schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping();
|
||||||
|
|
||||||
/* Pulls in bank transactions from third party services */
|
/* Pulls in bank transactions from third party services */
|
||||||
$schedule->job(new BankTransactionSync)->dailyAt('04:10')->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
|
$schedule->job(new BankTransactionSync)->everyFourHours()->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
|
||||||
|
|
||||||
|
/* Checks ACH verification status and updates state to authorize when verified */
|
||||||
|
$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();
|
||||||
|
|
||||||
|
101
app/DataMapper/Analytics/RevenueTrack.php
Normal file
101
app/DataMapper/Analytics/RevenueTrack.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?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\DataMapper\Analytics;
|
||||||
|
|
||||||
|
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||||
|
|
||||||
|
class RevenueTrack extends GenericMixedMetric
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The type of Sample.
|
||||||
|
*
|
||||||
|
* Monotonically incrementing counter
|
||||||
|
*
|
||||||
|
* - counter
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $type = 'mixed_metric';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the counter.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $name = 'app.revenue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The datetime of the counter measurement.
|
||||||
|
*
|
||||||
|
* date("Y-m-d H:i:s")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public $datetime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Client email
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $string_metric5 = 'email';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The AccountKey email
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $string_metric6 = 'key';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product Type
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $string_metric7 = 'product';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gateway Reference
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $string_metric8 = 'gateway_reference';
|
||||||
|
|
||||||
|
public $string_metric9 = 'entity_reference';
|
||||||
|
|
||||||
|
public $string_metric10 = 'gateway_type';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The counter
|
||||||
|
* set to 1.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $int_metric1 = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount Received
|
||||||
|
*
|
||||||
|
* @var double
|
||||||
|
*/
|
||||||
|
public $double_metric2 = 0;
|
||||||
|
|
||||||
|
public function __construct($string_metric5, $string_metric6, $int_metric1, $double_metric2, $string_metric7, $string_metric8, $string_metric9, $string_metric10)
|
||||||
|
{
|
||||||
|
$this->int_metric1 = $int_metric1;
|
||||||
|
$this->double_metric2 = $double_metric2;
|
||||||
|
$this->string_metric5 = $string_metric5;
|
||||||
|
$this->string_metric6 = $string_metric6;
|
||||||
|
$this->string_metric7 = $string_metric7;
|
||||||
|
$this->string_metric8 = $string_metric8;
|
||||||
|
$this->string_metric9 = $string_metric9;
|
||||||
|
$this->string_metric10 = $string_metric10;
|
||||||
|
}
|
||||||
|
}
|
@ -481,8 +481,11 @@ class CompanySettings extends BaseSettings
|
|||||||
|
|
||||||
public $enable_e_invoice = false;
|
public $enable_e_invoice = false;
|
||||||
|
|
||||||
|
public $classification = ''; // individual, company, partnership, trust, charity, government, other
|
||||||
|
|
||||||
public static $casts = [
|
public static $casts = [
|
||||||
'enable_e_invoice' => 'bool',
|
'enable_e_invoice' => 'bool',
|
||||||
|
'classification' => 'string',
|
||||||
'default_expense_payment_type_id' => 'string',
|
'default_expense_payment_type_id' => 'string',
|
||||||
'e_invoice_type' => 'string',
|
'e_invoice_type' => 'string',
|
||||||
'mailgun_endpoint' => 'string',
|
'mailgun_endpoint' => 'string',
|
||||||
@ -812,7 +815,7 @@ class CompanySettings extends BaseSettings
|
|||||||
* need to provide a fallback catch on old settings objects which will
|
* need to provide a fallback catch on old settings objects which will
|
||||||
* set new properties to the object prior to being returned.
|
* set new properties to the object prior to being returned.
|
||||||
*
|
*
|
||||||
* @param $settings
|
* @param \stdClass $settings
|
||||||
*
|
*
|
||||||
* @return stdClass
|
* @return stdClass
|
||||||
*/
|
*/
|
||||||
@ -843,6 +846,23 @@ class CompanySettings extends BaseSettings
|
|||||||
return $notification;
|
return $notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stubs the notification defaults
|
||||||
|
*
|
||||||
|
* @return stdClass
|
||||||
|
*/
|
||||||
|
public static function notificationAdminDefaults() :stdClass
|
||||||
|
{
|
||||||
|
$notification = new stdClass;
|
||||||
|
$notification->email = [];
|
||||||
|
$notification->email = ['invoice_sent_all'];
|
||||||
|
|
||||||
|
return $notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines entity variables for PDF generation
|
* Defines entity variables for PDF generation
|
||||||
*
|
*
|
||||||
|
@ -61,8 +61,13 @@ class InvoiceItem
|
|||||||
|
|
||||||
public $tax_id = '';
|
public $tax_id = '';
|
||||||
|
|
||||||
|
public $task_id = '';
|
||||||
|
|
||||||
|
public $expense_id = '';
|
||||||
|
|
||||||
public static $casts = [
|
public static $casts = [
|
||||||
|
'task_id' => 'string',
|
||||||
|
'expense_id' => 'string',
|
||||||
'tax_id' => 'string',
|
'tax_id' => 'string',
|
||||||
'type_id' => 'string',
|
'type_id' => 'string',
|
||||||
'quantity' => 'float',
|
'quantity' => 'float',
|
||||||
|
@ -250,8 +250,8 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
// $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
// $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
$this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
$this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate ?? 0;
|
||||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
$this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate ?? 0;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
||||||
|
@ -363,7 +363,15 @@ class BaseRule implements RuleInterface
|
|||||||
|
|
||||||
public function override($item): self
|
public function override($item): self
|
||||||
{
|
{
|
||||||
|
$this->tax_rate1 = $item->tax_rate1;
|
||||||
|
$this->tax_name1 = $item->tax_name1;
|
||||||
|
$this->tax_rate2 = $item->tax_rate2;
|
||||||
|
$this->tax_name2 = $item->tax_name2;
|
||||||
|
$this->tax_rate3 = $item->tax_rate3;
|
||||||
|
$this->tax_name3 = $item->tax_name3;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function calculateRates(): self
|
public function calculateRates(): self
|
||||||
|
@ -49,6 +49,10 @@ class Rule extends BaseRule implements RuleInterface
|
|||||||
|
|
||||||
$this->tax_rate1 = $item->tax_rate1;
|
$this->tax_rate1 = $item->tax_rate1;
|
||||||
$this->tax_name1 = $item->tax_name1;
|
$this->tax_name1 = $item->tax_name1;
|
||||||
|
$this->tax_rate2 = $item->tax_rate2;
|
||||||
|
$this->tax_name2 = $item->tax_name2;
|
||||||
|
$this->tax_rate3 = $item->tax_rate3;
|
||||||
|
$this->tax_name3 = $item->tax_name3;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
||||||
|
36
app/Events/Account/StripeConnectFailure.php
Normal file
36
app/Events/Account/StripeConnectFailure.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?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\Events\Account;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Broadcasting\PrivateChannel;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StripeConnectFailure.
|
||||||
|
*/
|
||||||
|
class StripeConnectFailure
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
|
public function __construct(public Company $company, public string $db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function broadcastOn()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
45
app/Events/Vendor/VendorContactLoggedIn.php
vendored
Normal file
45
app/Events/Vendor/VendorContactLoggedIn.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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\Events\Vendor;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorContactLoggedIn.
|
||||||
|
*/
|
||||||
|
class VendorContactLoggedIn
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct(public VendorContact $contact, public Company $company, public array $event_vars)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channels the event should broadcast on.
|
||||||
|
*
|
||||||
|
* @return Channel|array
|
||||||
|
*/
|
||||||
|
public function broadcastOn()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ use App\Libraries\MultiDB;
|
|||||||
use App\Models\DateFormat;
|
use App\Models\DateFormat;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use App\Transformers\ActivityTransformer;
|
use App\Transformers\ActivityTransformer;
|
||||||
|
|
||||||
class ActivityExport extends BaseExport
|
class ActivityExport extends BaseExport
|
||||||
@ -39,10 +40,6 @@ class ActivityExport extends BaseExport
|
|||||||
'address' => 'address',
|
'address' => 'address',
|
||||||
];
|
];
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -50,47 +47,33 @@ class ActivityExport extends BaseExport
|
|||||||
$this->entity_transformer = new ActivityTransformer();
|
$this->entity_transformer = new ActivityTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function returnJson()
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
$query = $this->init();
|
||||||
App::forgetInstance('translator');
|
|
||||||
App::setLocale($this->company->locale());
|
|
||||||
$t = app('translator');
|
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
|
||||||
|
|
||||||
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
//load the CSV document from a string
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
$this->csv = Writer::createFromString();
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
ksort($this->entity_keys);
|
|
||||||
|
|
||||||
if (count($this->input['report_keys']) == 0) {
|
$report = $query->cursor()
|
||||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildActivityRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
private function buildActivityRow(Activity $activity): array
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Activity::query()
|
|
||||||
->where('company_id', $this->company->id);
|
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
|
||||||
|
|
||||||
$query->cursor()
|
|
||||||
->each(function ($entity) {
|
|
||||||
$this->buildRow($entity);
|
|
||||||
});
|
|
||||||
|
|
||||||
return $this->csv->toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildRow(Activity $activity)
|
|
||||||
{
|
{
|
||||||
|
return [
|
||||||
$this->csv->insertOne([
|
|
||||||
Carbon::parse($activity->created_at)->format($this->date_format),
|
Carbon::parse($activity->created_at)->format($this->date_format),
|
||||||
ctrans("texts.activity_{$activity->activity_type_id}",[
|
ctrans("texts.activity_{$activity->activity_type_id}",[
|
||||||
|
'payment_amount' => $activity->payment ? $activity->payment->amount : '',
|
||||||
|
'adjustment' => $activity->payment ? $activity->payment->refunded : '',
|
||||||
'client' => $activity->client ? $activity->client->present()->name() : '',
|
'client' => $activity->client ? $activity->client->present()->name() : '',
|
||||||
'contact' => $activity->contact ? $activity->contact->present()->name() : '',
|
'contact' => $activity->contact ? $activity->contact->present()->name() : '',
|
||||||
'quote' => $activity->quote ? $activity->quote->number : '',
|
'quote' => $activity->quote ? $activity->quote->number : '',
|
||||||
@ -108,7 +91,57 @@ class ActivityExport extends BaseExport
|
|||||||
'recurring_expense' => $activity->recurring_expense ? $activity->recurring_expense->number : '',
|
'recurring_expense' => $activity->recurring_expense ? $activity->recurring_expense->number : '',
|
||||||
]),
|
]),
|
||||||
$activity->ip,
|
$activity->ip,
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(): Builder
|
||||||
|
{
|
||||||
|
MultiDB::setDb($this->company->db);
|
||||||
|
App::forgetInstance('translator');
|
||||||
|
App::setLocale($this->company->locale());
|
||||||
|
$t = app('translator');
|
||||||
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
|
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
|
||||||
|
|
||||||
|
// ksort($this->entity_keys);
|
||||||
|
|
||||||
|
if (count($this->input['report_keys']) == 0) {
|
||||||
|
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = Activity::query()
|
||||||
|
->where('company_id', $this->company->id);
|
||||||
|
|
||||||
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
|
|
||||||
|
$query->cursor()
|
||||||
|
->each(function ($entity) {
|
||||||
|
$this->buildRow($entity);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->csv->toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildRow(Activity $activity)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->csv->insertOne($this->buildActivityRow($activity));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -117,4 +150,27 @@ class ActivityExport extends BaseExport
|
|||||||
{
|
{
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function processMetaData(array $row, $resource): array
|
||||||
|
{
|
||||||
|
|
||||||
|
$clean_row = [];
|
||||||
|
|
||||||
|
foreach (array_values($this->input['report_keys']) as $key => $value) {
|
||||||
|
|
||||||
|
nlog("key: {$key}, value: {$value}");
|
||||||
|
nlog($row);
|
||||||
|
$clean_row[$key]['entity'] = 'activity';
|
||||||
|
$clean_row[$key]['id'] = $key;
|
||||||
|
$clean_row[$key]['hashed_id'] = null;
|
||||||
|
$clean_row[$key]['value'] = $row[$key];
|
||||||
|
$clean_row[$key]['identifier'] = $value;
|
||||||
|
$clean_row[$key]['display_value'] = $row[$key];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clean_row;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,19 +11,30 @@
|
|||||||
|
|
||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Models\Quote;
|
||||||
use App\Utils\Number;
|
use App\Utils\Number;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Utils\Helpers;
|
||||||
use App\Models\Company;
|
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\Document;
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Transformers\TaskTransformer;
|
use App\Transformers\TaskTransformer;
|
||||||
use App\Transformers\PaymentTransformer;
|
use App\Transformers\PaymentTransformer;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use League\Fractal\Serializer\ArraySerializer;
|
use League\Fractal\Serializer\ArraySerializer;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\Task;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
class BaseExport
|
class BaseExport
|
||||||
{
|
{
|
||||||
@ -43,8 +54,6 @@ class BaseExport
|
|||||||
|
|
||||||
public string $client_description = 'All Clients';
|
public string $client_description = 'All Clients';
|
||||||
|
|
||||||
public array $forced_keys = [];
|
|
||||||
|
|
||||||
protected array $vendor_report_keys = [
|
protected array $vendor_report_keys = [
|
||||||
'address1' => 'vendor.address1',
|
'address1' => 'vendor.address1',
|
||||||
'address2' => 'vendor.address2',
|
'address2' => 'vendor.address2',
|
||||||
@ -57,7 +66,7 @@ class BaseExport
|
|||||||
'id_number' => 'vendor.id_number',
|
'id_number' => 'vendor.id_number',
|
||||||
'name' => 'vendor.name',
|
'name' => 'vendor.name',
|
||||||
'number' => 'vendor.number',
|
'number' => 'vendor.number',
|
||||||
'client_phone' => 'vendor.phone',
|
'phone' => 'vendor.phone',
|
||||||
'postal_code' => 'vendor.postal_code',
|
'postal_code' => 'vendor.postal_code',
|
||||||
'private_notes' => 'vendor.private_notes',
|
'private_notes' => 'vendor.private_notes',
|
||||||
'public_notes' => 'vendor.public_notes',
|
'public_notes' => 'vendor.public_notes',
|
||||||
@ -94,7 +103,6 @@ class BaseExport
|
|||||||
"state" => "client.state",
|
"state" => "client.state",
|
||||||
"postal_code" => "client.postal_code",
|
"postal_code" => "client.postal_code",
|
||||||
"country" => "client.country_id",
|
"country" => "client.country_id",
|
||||||
"custom_value4" => "contact.custom_value4",
|
|
||||||
"shipping_address1" => "client.shipping_address1",
|
"shipping_address1" => "client.shipping_address1",
|
||||||
"shipping_address2" => "client.shipping_address2",
|
"shipping_address2" => "client.shipping_address2",
|
||||||
"shipping_city" => "client.shipping_city",
|
"shipping_city" => "client.shipping_city",
|
||||||
@ -109,6 +117,15 @@ class BaseExport
|
|||||||
"first_name" => "contact.first_name",
|
"first_name" => "contact.first_name",
|
||||||
"last_name" => "contact.last_name",
|
"last_name" => "contact.last_name",
|
||||||
"email" => "contact.email",
|
"email" => "contact.email",
|
||||||
|
'custom_value1' => 'client.custom_value1',
|
||||||
|
'custom_value2' => 'client.custom_value2',
|
||||||
|
'custom_value3' => 'client.custom_value3',
|
||||||
|
'custom_value4' => 'client.custom_value4',
|
||||||
|
"contact_custom_value1" => "contact.custom_value1",
|
||||||
|
"contact_custom_value2" => "contact.custom_value2",
|
||||||
|
"contact_custom_value3" => "contact.custom_value3",
|
||||||
|
"contact_custom_value4" => "contact.custom_value4",
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $invoice_report_keys = [
|
protected array $invoice_report_keys = [
|
||||||
@ -126,6 +143,7 @@ class BaseExport
|
|||||||
"private_notes" => "invoice.private_notes",
|
"private_notes" => "invoice.private_notes",
|
||||||
"uses_inclusive_taxes" => "invoice.uses_inclusive_taxes",
|
"uses_inclusive_taxes" => "invoice.uses_inclusive_taxes",
|
||||||
"is_amount_discount" => "invoice.is_amount_discount",
|
"is_amount_discount" => "invoice.is_amount_discount",
|
||||||
|
"discount" => "invoice.discount",
|
||||||
"partial" => "invoice.partial",
|
"partial" => "invoice.partial",
|
||||||
"partial_due_date" => "invoice.partial_due_date",
|
"partial_due_date" => "invoice.partial_due_date",
|
||||||
"surcharge1" => "invoice.custom_surcharge1",
|
"surcharge1" => "invoice.custom_surcharge1",
|
||||||
@ -136,6 +154,16 @@ class BaseExport
|
|||||||
"tax_amount" => "invoice.total_taxes",
|
"tax_amount" => "invoice.total_taxes",
|
||||||
"assigned_user" => "invoice.assigned_user_id",
|
"assigned_user" => "invoice.assigned_user_id",
|
||||||
"user" => "invoice.user_id",
|
"user" => "invoice.user_id",
|
||||||
|
"custom_value1" => "invoice.custom_value1",
|
||||||
|
"custom_value2" => "invoice.custom_value2",
|
||||||
|
"custom_value3" => "invoice.custom_value3",
|
||||||
|
"custom_value4" => "invoice.custom_value4",
|
||||||
|
'tax_name1' => 'invoice.tax_name1',
|
||||||
|
'tax_name2' => 'invoice.tax_name2',
|
||||||
|
'tax_name3' => 'invoice.tax_name3',
|
||||||
|
'tax_rate1' => 'invoice.tax_rate1',
|
||||||
|
'tax_rate2' => 'invoice.tax_rate2',
|
||||||
|
'tax_rate3' => 'invoice.tax_rate3',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $recurring_invoice_report_keys = [
|
protected array $recurring_invoice_report_keys = [
|
||||||
@ -153,6 +181,7 @@ class BaseExport
|
|||||||
"private_notes" => "recurring_invoice.private_notes",
|
"private_notes" => "recurring_invoice.private_notes",
|
||||||
"uses_inclusive_taxes" => "recurring_invoice.uses_inclusive_taxes",
|
"uses_inclusive_taxes" => "recurring_invoice.uses_inclusive_taxes",
|
||||||
"is_amount_discount" => "recurring_invoice.is_amount_discount",
|
"is_amount_discount" => "recurring_invoice.is_amount_discount",
|
||||||
|
"discount" => "recurring_invoice.discount",
|
||||||
"partial" => "recurring_invoice.partial",
|
"partial" => "recurring_invoice.partial",
|
||||||
"partial_due_date" => "recurring_invoice.partial_due_date",
|
"partial_due_date" => "recurring_invoice.partial_due_date",
|
||||||
"surcharge1" => "recurring_invoice.custom_surcharge1",
|
"surcharge1" => "recurring_invoice.custom_surcharge1",
|
||||||
@ -164,17 +193,23 @@ class BaseExport
|
|||||||
"assigned_user" => "recurring_invoice.assigned_user_id",
|
"assigned_user" => "recurring_invoice.assigned_user_id",
|
||||||
"user" => "recurring_invoice.user_id",
|
"user" => "recurring_invoice.user_id",
|
||||||
"frequency_id" => "recurring_invoice.frequency_id",
|
"frequency_id" => "recurring_invoice.frequency_id",
|
||||||
"next_send_date" => "recurring_invoice.next_send_date"
|
"next_send_date" => "recurring_invoice.next_send_date",
|
||||||
|
"custom_value1" => "recurring_invoice.custom_value1",
|
||||||
|
"custom_value2" => "recurring_invoice.custom_value2",
|
||||||
|
"custom_value3" => "recurring_invoice.custom_value3",
|
||||||
|
"custom_value4" => "recurring_invoice.custom_value4",
|
||||||
|
'tax_name1' => 'recurring_invoice.tax_name1',
|
||||||
|
'tax_name2' => 'recurring_invoice.tax_name2',
|
||||||
|
'tax_name3' => 'recurring_invoice.tax_name3',
|
||||||
|
'tax_rate1' => 'recurring_invoice.tax_rate1',
|
||||||
|
'tax_rate2' => 'recurring_invoice.tax_rate2',
|
||||||
|
'tax_rate3' => 'recurring_invoice.tax_rate3',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $purchase_order_report_keys = [
|
protected array $purchase_order_report_keys = [
|
||||||
'amount' => 'purchase_order.amount',
|
'amount' => 'purchase_order.amount',
|
||||||
'balance' => 'purchase_order.balance',
|
'balance' => 'purchase_order.balance',
|
||||||
'vendor' => 'purchase_order.vendor_id',
|
'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_value1' => 'purchase_order.custom_value1',
|
||||||
'custom_value2' => 'purchase_order.custom_value2',
|
'custom_value2' => 'purchase_order.custom_value2',
|
||||||
'custom_value3' => 'purchase_order.custom_value3',
|
'custom_value3' => 'purchase_order.custom_value3',
|
||||||
@ -203,17 +238,41 @@ class BaseExport
|
|||||||
'currency_id' => 'purchase_order.currency_id',
|
'currency_id' => 'purchase_order.currency_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected array $product_report_keys = [
|
||||||
|
// 'project' => 'project_id',
|
||||||
|
// 'vendor' => 'vendor_id',
|
||||||
|
'custom_value1' => 'custom_value1',
|
||||||
|
'custom_value2' => 'custom_value2',
|
||||||
|
'custom_value3' => 'custom_value3',
|
||||||
|
'custom_value4' => 'custom_value4',
|
||||||
|
'product_key' => 'product_key',
|
||||||
|
'notes' => 'notes',
|
||||||
|
'cost' => 'cost',
|
||||||
|
'price' => 'price',
|
||||||
|
'quantity' => 'quantity',
|
||||||
|
'tax_rate1' => 'tax_rate1',
|
||||||
|
'tax_rate2' => 'tax_rate2',
|
||||||
|
'tax_rate3' => 'tax_rate3',
|
||||||
|
'tax_name1' => 'tax_name1',
|
||||||
|
'tax_name2' => 'tax_name2',
|
||||||
|
'tax_name3' => 'tax_name3',
|
||||||
|
'image' => 'product_image',
|
||||||
|
'tax_category' => 'tax_id',
|
||||||
|
'max_quantity' => 'max_quantity',
|
||||||
|
'in_stock_quantity' => 'in_stock_quantity',
|
||||||
|
];
|
||||||
|
|
||||||
protected array $item_report_keys = [
|
protected array $item_report_keys = [
|
||||||
"quantity" => "item.quantity",
|
"quantity" => "item.quantity",
|
||||||
"cost" => "item.cost",
|
"cost" => "item.cost",
|
||||||
"product_key" => "item.product_key",
|
"product_key" => "item.product_key",
|
||||||
"notes" => "item.notes",
|
"notes" => "item.notes",
|
||||||
"item_tax1" => "item.tax_name1",
|
"tax_name1" => "item.tax_name1",
|
||||||
"item_tax_rate1" => "item.tax_rate1",
|
"tax_rate1" => "item.tax_rate1",
|
||||||
"item_tax2" => "item.tax_name2",
|
"tax_name2" => "item.tax_name2",
|
||||||
"item_tax_rate2" => "item.tax_rate2",
|
"tax_rate2" => "item.tax_rate2",
|
||||||
"item_tax3" => "item.tax_name3",
|
"tax_name3" => "item.tax_name3",
|
||||||
"item_tax_rate3" => "item.tax_rate3",
|
"tax_rate3" => "item.tax_rate3",
|
||||||
"custom_value1" => "item.custom_value1",
|
"custom_value1" => "item.custom_value1",
|
||||||
"custom_value2" => "item.custom_value2",
|
"custom_value2" => "item.custom_value2",
|
||||||
"custom_value3" => "item.custom_value3",
|
"custom_value3" => "item.custom_value3",
|
||||||
@ -221,6 +280,9 @@ class BaseExport
|
|||||||
"discount" => "item.discount",
|
"discount" => "item.discount",
|
||||||
"type" => "item.type_id",
|
"type" => "item.type_id",
|
||||||
"tax_category" => "item.tax_id",
|
"tax_category" => "item.tax_id",
|
||||||
|
'is_amount_discount' => 'item.is_amount_discount',
|
||||||
|
'line_total' => 'item.line_total',
|
||||||
|
'gross_line_total' => 'item.gross_line_total',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $quote_report_keys = [
|
protected array $quote_report_keys = [
|
||||||
@ -242,6 +304,7 @@ class BaseExport
|
|||||||
"private_notes" => "quote.private_notes",
|
"private_notes" => "quote.private_notes",
|
||||||
"uses_inclusive_taxes" => "quote.uses_inclusive_taxes",
|
"uses_inclusive_taxes" => "quote.uses_inclusive_taxes",
|
||||||
"is_amount_discount" => "quote.is_amount_discount",
|
"is_amount_discount" => "quote.is_amount_discount",
|
||||||
|
"discount" => "quote.discount",
|
||||||
"partial" => "quote.partial",
|
"partial" => "quote.partial",
|
||||||
"partial_due_date" => "quote.partial_due_date",
|
"partial_due_date" => "quote.partial_due_date",
|
||||||
"surcharge1" => "quote.custom_surcharge1",
|
"surcharge1" => "quote.custom_surcharge1",
|
||||||
@ -252,6 +315,12 @@ class BaseExport
|
|||||||
"tax_amount" => "quote.total_taxes",
|
"tax_amount" => "quote.total_taxes",
|
||||||
"assigned_user" => "quote.assigned_user_id",
|
"assigned_user" => "quote.assigned_user_id",
|
||||||
"user" => "quote.user_id",
|
"user" => "quote.user_id",
|
||||||
|
'tax_name1' => 'quote.tax_name1',
|
||||||
|
'tax_name2' => 'quote.tax_name2',
|
||||||
|
'tax_name3' => 'quote.tax_name3',
|
||||||
|
'tax_rate1' => 'quote.tax_rate1',
|
||||||
|
'tax_rate2' => 'quote.tax_rate2',
|
||||||
|
'tax_rate3' => 'quote.tax_rate3',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $credit_report_keys = [
|
protected array $credit_report_keys = [
|
||||||
@ -263,6 +332,7 @@ class BaseExport
|
|||||||
"date" => "credit.date",
|
"date" => "credit.date",
|
||||||
"due_date" => "credit.due_date",
|
"due_date" => "credit.due_date",
|
||||||
"terms" => "credit.terms",
|
"terms" => "credit.terms",
|
||||||
|
"discount" => "credit.discount",
|
||||||
"footer" => "credit.footer",
|
"footer" => "credit.footer",
|
||||||
"status" => "credit.status",
|
"status" => "credit.status",
|
||||||
"public_notes" => "credit.public_notes",
|
"public_notes" => "credit.public_notes",
|
||||||
@ -275,6 +345,10 @@ class BaseExport
|
|||||||
"surcharge2" => "credit.custom_surcharge2",
|
"surcharge2" => "credit.custom_surcharge2",
|
||||||
"surcharge3" => "credit.custom_surcharge3",
|
"surcharge3" => "credit.custom_surcharge3",
|
||||||
"surcharge4" => "credit.custom_surcharge4",
|
"surcharge4" => "credit.custom_surcharge4",
|
||||||
|
"custom_value1" => "credit.custom_value1",
|
||||||
|
"custom_value2" => "credit.custom_value2",
|
||||||
|
"custom_value3" => "credit.custom_value3",
|
||||||
|
"custom_value4" => "credit.custom_value4",
|
||||||
"exchange_rate" => "credit.exchange_rate",
|
"exchange_rate" => "credit.exchange_rate",
|
||||||
"tax_amount" => "credit.total_taxes",
|
"tax_amount" => "credit.total_taxes",
|
||||||
"assigned_user" => "credit.assigned_user_id",
|
"assigned_user" => "credit.assigned_user_id",
|
||||||
@ -304,7 +378,7 @@ class BaseExport
|
|||||||
protected array $expense_report_keys = [
|
protected array $expense_report_keys = [
|
||||||
'amount' => 'expense.amount',
|
'amount' => 'expense.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',
|
||||||
'custom_value2' => 'expense.custom_value2',
|
'custom_value2' => 'expense.custom_value2',
|
||||||
'custom_value3' => 'expense.custom_value3',
|
'custom_value3' => 'expense.custom_value3',
|
||||||
@ -518,31 +592,33 @@ class BaseExport
|
|||||||
$manager->setSerializer(new ArraySerializer());
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$transformed_client = $manager->createData($transformed_client)->toArray();
|
$transformed_client = $manager->createData($transformed_client)->toArray();
|
||||||
|
|
||||||
if($column == 'name')
|
if(in_array($column, ['client.name', 'name']))
|
||||||
return $transformed_client['display_name'];
|
return $transformed_client['display_name'];
|
||||||
|
|
||||||
if($column == 'user_id')
|
if(in_array($column, ['client.user_id', 'user_id']))
|
||||||
return $entity->client->user->present()->name();
|
return $entity->client->user->present()->name();
|
||||||
|
|
||||||
if($column == 'country_id')
|
if(in_array($column, ['client.assigned_user_id', 'assigned_user_id']))
|
||||||
|
return $entity->client->assigned_user->present()->name();
|
||||||
|
|
||||||
|
if(in_array($column, ['client.country_id', 'country_id']))
|
||||||
return $entity->client->country ? ctrans("texts.country_{$entity->client->country->name}") : '';
|
return $entity->client->country ? ctrans("texts.country_{$entity->client->country->name}") : '';
|
||||||
|
|
||||||
if($column == 'shipping_country_id')
|
if(in_array($column, ['client.shipping_country_id', 'shipping_country_id']))
|
||||||
return $entity->client->shipping_country ? ctrans("texts.country_{$entity->client->shipping_country->name}") : '';
|
return $entity->client->shipping_country ? ctrans("texts.country_{$entity->client->shipping_country->name}") : '';
|
||||||
|
|
||||||
if($column == 'size_id')
|
if(in_array($column, ['client.size_id', 'size_id']))
|
||||||
return $entity->client->size?->name ?? '';
|
return $entity->client->size?->name ?? '';
|
||||||
|
|
||||||
if($column == 'industry_id')
|
if(in_array($column, ['client.industry_id', 'industry_id']))
|
||||||
return $entity->client->industry?->name ?? '';
|
return $entity->client->industry?->name ?? '';
|
||||||
|
|
||||||
if ($column == 'currency_id') {
|
if (in_array($column, ['client.currency_id', 'currency_id']))
|
||||||
return $entity->client->currency() ? $entity->client->currency()->code : $entity->company->currency()->code;
|
return $entity->client->currency() ? $entity->client->currency()->code : $entity->company->currency()->code;
|
||||||
}
|
|
||||||
|
|
||||||
if($column == 'client.payment_terms') {
|
if(in_array($column, ['payment_terms', 'client.payment_terms']))
|
||||||
return $entity->client->getSetting('payment_terms');
|
return $entity->client->getSetting('payment_terms');
|
||||||
}
|
|
||||||
|
|
||||||
if(array_key_exists($column, $transformed_client))
|
if(array_key_exists($column, $transformed_client))
|
||||||
return $transformed_client[$column];
|
return $transformed_client[$column];
|
||||||
@ -584,7 +660,7 @@ class BaseExport
|
|||||||
// nlog("searching for {$column}");
|
// nlog("searching for {$column}");
|
||||||
$transformed_invoice = false;
|
$transformed_invoice = false;
|
||||||
|
|
||||||
if($transformer instanceof PaymentTransformer) {
|
if($transformer instanceof PaymentTransformer && ($entity->invoices ?? false)) {
|
||||||
$transformed_invoices = $transformer->includeInvoices($entity);
|
$transformed_invoices = $transformer->includeInvoices($entity);
|
||||||
|
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
@ -606,7 +682,7 @@ class BaseExport
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($transformer instanceof TaskTransformer) {
|
if($transformer instanceof TaskTransformer && ($entity->invoice ?? false)) {
|
||||||
$transformed_invoice = $transformer->includeInvoice($entity);
|
$transformed_invoice = $transformer->includeInvoice($entity);
|
||||||
|
|
||||||
if(!$transformed_invoice)
|
if(!$transformed_invoice)
|
||||||
@ -822,16 +898,31 @@ class BaseExport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the merged array of
|
||||||
|
* the entity with the matching
|
||||||
|
* item report keys
|
||||||
|
*
|
||||||
|
* @param string $entity_report_keys
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function mergeItemsKeys(string $entity_report_keys): array
|
||||||
|
{
|
||||||
|
return array_merge($this->{$entity_report_keys}, $this->item_report_keys);
|
||||||
|
}
|
||||||
|
|
||||||
public function buildHeader() :array
|
public function buildHeader() :array
|
||||||
{
|
{
|
||||||
|
$helper = new Helpers();
|
||||||
|
|
||||||
$header = [];
|
$header = [];
|
||||||
|
// nlog("header");
|
||||||
// nlog($this->input['report_keys']);
|
foreach ($this->input['report_keys'] as $value) {
|
||||||
|
|
||||||
foreach (array_merge($this->input['report_keys'], $this->forced_keys) as $value) {
|
|
||||||
|
|
||||||
$key = array_search($value, $this->entity_keys);
|
$key = array_search($value, $this->entity_keys);
|
||||||
|
$original_key = $key;
|
||||||
|
|
||||||
|
// nlog("{$key} => {$value}");
|
||||||
$prefix = '';
|
$prefix = '';
|
||||||
|
|
||||||
if(!$key) {
|
if(!$key) {
|
||||||
@ -854,7 +945,6 @@ class BaseExport
|
|||||||
$key = array_search($value, $this->payment_report_keys);
|
$key = array_search($value, $this->payment_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!$key) {
|
if(!$key) {
|
||||||
$prefix = ctrans('texts.quote')." ";
|
$prefix = ctrans('texts.quote')." ";
|
||||||
$key = array_search($value, $this->quote_report_keys);
|
$key = array_search($value, $this->quote_report_keys);
|
||||||
@ -873,6 +963,9 @@ class BaseExport
|
|||||||
if(!$key) {
|
if(!$key) {
|
||||||
$prefix = ctrans('texts.expense')." ";
|
$prefix = ctrans('texts.expense')." ";
|
||||||
$key = array_search($value, $this->expense_report_keys);
|
$key = array_search($value, $this->expense_report_keys);
|
||||||
|
|
||||||
|
if(!$key && $value == 'expense.category')
|
||||||
|
$key = 'category';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$key) {
|
if(!$key) {
|
||||||
@ -892,8 +985,15 @@ class BaseExport
|
|||||||
|
|
||||||
if(!$key) {
|
if(!$key) {
|
||||||
$prefix = '';
|
$prefix = '';
|
||||||
|
$key = array_search($value, $this->product_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!$key) {
|
||||||
|
$prefix = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// nlog("key => {$key}");
|
||||||
|
|
||||||
$key = str_replace('item.', '', $key);
|
$key = str_replace('item.', '', $key);
|
||||||
$key = str_replace('recurring_invoice.', '', $key);
|
$key = str_replace('recurring_invoice.', '', $key);
|
||||||
$key = str_replace('purchase_order.', '', $key);
|
$key = str_replace('purchase_order.', '', $key);
|
||||||
@ -906,11 +1006,42 @@ class BaseExport
|
|||||||
$key = str_replace('contact.', '', $key);
|
$key = str_replace('contact.', '', $key);
|
||||||
$key = str_replace('payment.', '', $key);
|
$key = str_replace('payment.', '', $key);
|
||||||
$key = str_replace('expense.', '', $key);
|
$key = str_replace('expense.', '', $key);
|
||||||
|
$key = str_replace('product.', '', $key);
|
||||||
|
$key = str_replace('task.', '', $key);
|
||||||
|
|
||||||
if(in_array($key, ['quote1','quote2','quote3','quote4','credit1','credit2','credit3','credit4','purchase_order1','purchase_order2','purchase_order3','purchase_order4']))
|
if(stripos($value, 'custom_value') !== false)
|
||||||
{
|
{
|
||||||
$number = substr($key, -1);
|
$parts = explode(".", $value);
|
||||||
$header[] = ctrans('texts.item') . " ". ctrans("texts.custom_value{$number}");
|
|
||||||
|
if(count($parts) == 2 && in_array($parts[0], ['credit','quote','invoice','purchase_order','recurring_invoice'])){
|
||||||
|
$entity = "invoice".substr($parts[1], -1);
|
||||||
|
$prefix = ctrans("texts.".$parts[0]);
|
||||||
|
$fallback = "custom_value".substr($parts[1], -1);
|
||||||
|
$custom_field_label = $helper->makeCustomField($this->company->custom_fields, $entity);
|
||||||
|
|
||||||
|
if(strlen($custom_field_label) > 1)
|
||||||
|
$header[] = $custom_field_label;
|
||||||
|
else {
|
||||||
|
$header[] = $prefix . " ". ctrans("texts.{$fallback}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif(count($parts) == 2 && (stripos($parts[0], 'vendor_contact') !== false || stripos($parts[0], 'contact') !== false)) {
|
||||||
|
$parts[0] = str_replace('vendor_contact', 'contact', $parts[0]);
|
||||||
|
|
||||||
|
$entity = "contact".substr($parts[1], -1);
|
||||||
|
$custom_field_string = strlen($helper->makeCustomField($this->company->custom_fields, $entity)) > 1 ? $helper->makeCustomField($this->company->custom_fields, $entity) : ctrans("texts.{$parts[1]}");
|
||||||
|
$header[] = ctrans("texts.{$parts[0]}") . " " . $custom_field_string;
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif(count($parts) == 2 && in_array(substr($original_key, 0, -1), ['credit','quote','invoice','purchase_order','recurring_invoice','task'])){
|
||||||
|
$custom_field_string = strlen($helper->makeCustomField($this->company->custom_fields, "product".substr($original_key,-1))) > 1 ? $helper->makeCustomField($this->company->custom_fields, "product".substr($original_key,-1)) : ctrans("texts.{$parts[1]}");
|
||||||
|
$header[] = ctrans("texts.{$parts[0]}") . " " . $custom_field_string;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$header[] = "{$prefix}" . ctrans("texts.{$key}");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -922,4 +1053,100 @@ class BaseExport
|
|||||||
|
|
||||||
return $header;
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function processMetaData(array $row, $resource): array
|
||||||
|
{
|
||||||
|
$class = get_class($resource);
|
||||||
|
|
||||||
|
$entity = '';
|
||||||
|
|
||||||
|
match ($class) {
|
||||||
|
Invoice::class => $entity = 'invoice',
|
||||||
|
RecurringInvoice::class => $entity = 'recurring_invoice',
|
||||||
|
Quote::class => $entity = 'quote',
|
||||||
|
Credit::class => $entity = 'credit',
|
||||||
|
Expense::class => $entity = 'expense',
|
||||||
|
Document::class => $entity = 'document',
|
||||||
|
ClientContact::class => $entity = 'contact',
|
||||||
|
PurchaseOrder::class => $entity = 'purchase_order',
|
||||||
|
Payment::class => $entity = 'payment',
|
||||||
|
Product::class => $entity = 'product',
|
||||||
|
Task::class => $entity = 'task',
|
||||||
|
Vendor::class => $entity = 'vendor',
|
||||||
|
default => $entity = 'invoice',
|
||||||
|
};
|
||||||
|
|
||||||
|
$clean_row = [];
|
||||||
|
|
||||||
|
foreach (array_values($this->input['report_keys']) as $key => $value) {
|
||||||
|
|
||||||
|
$report_keys = explode(".", $value);
|
||||||
|
|
||||||
|
$column_key = $value;
|
||||||
|
|
||||||
|
if($value == 'product_image') {
|
||||||
|
$column_key = 'image';
|
||||||
|
$value = 'image';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($value == 'tax_id') {
|
||||||
|
$column_key = 'tax_category';
|
||||||
|
$value = 'tax_category';
|
||||||
|
}
|
||||||
|
|
||||||
|
$clean_row[$key]['entity'] = $report_keys[0];
|
||||||
|
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
|
||||||
|
$clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
|
||||||
|
$clean_row[$key]['value'] = $row[$column_key];
|
||||||
|
$clean_row[$key]['identifier'] = $value;
|
||||||
|
$clean_row[$key]['display_value'] = $row[$column_key];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clean_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processItemMetaData(array $row, $resource): array
|
||||||
|
{
|
||||||
|
$class = get_class($resource);
|
||||||
|
|
||||||
|
$entity = '';
|
||||||
|
|
||||||
|
match ($class) {
|
||||||
|
Invoice::class => $entity = 'invoice',
|
||||||
|
Quote::class => $entity = 'quote',
|
||||||
|
Credit::class => $entity = 'credit',
|
||||||
|
Expense::class => $entity = 'expense',
|
||||||
|
Document::class => $entity = 'document',
|
||||||
|
ClientContact::class => $entity = 'contact',
|
||||||
|
PurchaseOrder::class => $entity = 'purchase_order',
|
||||||
|
default => $entity = 'invoice',
|
||||||
|
};
|
||||||
|
|
||||||
|
$clean_row = [];
|
||||||
|
|
||||||
|
foreach (array_values($this->input['report_keys']) as $key => $value) {
|
||||||
|
|
||||||
|
$report_keys = explode(".", $value);
|
||||||
|
|
||||||
|
$column_key = $value;
|
||||||
|
|
||||||
|
if($value == 'type_id' || $value == 'item.type_id')
|
||||||
|
$column_key = 'type';
|
||||||
|
|
||||||
|
if($value == 'tax_id' || $value == 'item.tax_id')
|
||||||
|
$column_key = 'tax_category';
|
||||||
|
|
||||||
|
$clean_row[$key]['entity'] = $report_keys[0];
|
||||||
|
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
|
||||||
|
$clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
|
||||||
|
$clean_row[$key]['value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
|
||||||
|
$clean_row[$key]['identifier'] = $value;
|
||||||
|
$clean_row[$key]['display_value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clean_row;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,16 @@
|
|||||||
|
|
||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
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 Illuminate\Support\Facades\App;
|
use App\Utils\Number;
|
||||||
|
use App\Models\Client;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use App\Transformers\ClientTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use App\Transformers\ClientContactTransformer;
|
||||||
|
|
||||||
class ClientExport extends BaseExport
|
class ClientExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -72,16 +74,6 @@ class ClientExport extends BaseExport
|
|||||||
'status' => 'status'
|
'status' => 'status'
|
||||||
];
|
];
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'client.country_id',
|
|
||||||
'client.shipping_country_id',
|
|
||||||
'client.currency',
|
|
||||||
'client.industry',
|
|
||||||
];
|
|
||||||
|
|
||||||
public array $forced_keys = [
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -90,7 +82,28 @@ class ClientExport extends BaseExport
|
|||||||
$this->contact_transformer = new ClientContactTransformer();
|
$this->contact_transformer = new ClientContactTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($client) {
|
||||||
|
$row = $this->buildRow($client);
|
||||||
|
return $this->processMetaData($row, $client);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
@ -98,16 +111,10 @@ class ClientExport extends BaseExport
|
|||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->client_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Client::query()->with('contacts')
|
$query = Client::query()->with('contacts')
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
@ -115,6 +122,20 @@ class ClientExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($client) {
|
->each(function ($client) {
|
||||||
$this->csv->insertOne($this->buildRow($client));
|
$this->csv->insertOne($this->buildRow($client));
|
||||||
@ -152,6 +173,30 @@ class ClientExport extends BaseExport
|
|||||||
return $this->decorateAdvancedFields($client, $entity);
|
return $this->decorateAdvancedFields($client, $entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function processMetaData(array $row, $resource): array
|
||||||
|
{
|
||||||
|
$clean_row = [];
|
||||||
|
foreach (array_values($this->input['report_keys']) as $key => $value) {
|
||||||
|
|
||||||
|
$report_keys = explode(".", $value);
|
||||||
|
|
||||||
|
$column_key = $value;
|
||||||
|
$clean_row[$key]['entity'] = $report_keys[0];
|
||||||
|
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
|
||||||
|
$clean_row[$key]['hashed_id'] = $report_keys[0] == 'client' ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
|
||||||
|
$clean_row[$key]['value'] = $row[$column_key];
|
||||||
|
$clean_row[$key]['identifier'] = $value;
|
||||||
|
|
||||||
|
if(in_array($clean_row[$key]['id'], ['paid_to_date', 'balance', 'credit_balance','payment_balance']))
|
||||||
|
$clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $resource);
|
||||||
|
else
|
||||||
|
$clean_row[$key]['display_value'] = $row[$column_key];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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'])) {
|
||||||
|
@ -18,6 +18,7 @@ use App\Models\Company;
|
|||||||
use App\Transformers\ClientContactTransformer;
|
use App\Transformers\ClientContactTransformer;
|
||||||
use App\Transformers\ClientTransformer;
|
use App\Transformers\ClientTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -32,54 +33,6 @@ class ContactExport extends BaseExport
|
|||||||
|
|
||||||
public string $date_key = 'created_at';
|
public string $date_key = 'created_at';
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'address1' => 'client.address1',
|
|
||||||
'address2' => 'client.address2',
|
|
||||||
'balance' => 'client.balance',
|
|
||||||
'city' => 'client.city',
|
|
||||||
'country' => 'client.country_id',
|
|
||||||
'credit_balance' => 'client.credit_balance',
|
|
||||||
'custom_value1' => 'client.custom_value1',
|
|
||||||
'custom_value2' => 'client.custom_value2',
|
|
||||||
'custom_value3' => 'client.custom_value3',
|
|
||||||
'custom_value4' => 'client.custom_value4',
|
|
||||||
'id_number' => 'client.id_number',
|
|
||||||
'industry' => 'client.industry_id',
|
|
||||||
'last_login' => 'client.last_login',
|
|
||||||
'name' => 'client.name',
|
|
||||||
'number' => 'client.number',
|
|
||||||
'paid_to_date' => 'client.paid_to_date',
|
|
||||||
'client_phone' => 'client.phone',
|
|
||||||
'postal_code' => 'client.postal_code',
|
|
||||||
'private_notes' => 'client.private_notes',
|
|
||||||
'public_notes' => 'client.public_notes',
|
|
||||||
'shipping_address1' => 'client.shipping_address1',
|
|
||||||
'shipping_address2' => 'client.shipping_address2',
|
|
||||||
'shipping_city' => 'client.shipping_city',
|
|
||||||
'shipping_country' => 'client.shipping_country_id',
|
|
||||||
'shipping_postal_code' => 'client.shipping_postal_code',
|
|
||||||
'shipping_state' => 'client.shipping_state',
|
|
||||||
'state' => 'client.state',
|
|
||||||
'vat_number' => 'client.vat_number',
|
|
||||||
'website' => 'client.website',
|
|
||||||
'currency' => 'client.currency',
|
|
||||||
'first_name' => 'contact.first_name',
|
|
||||||
'last_name' => 'contact.last_name',
|
|
||||||
'contact_phone' => 'contact.phone',
|
|
||||||
'contact_custom_value1' => 'contact.custom_value1',
|
|
||||||
'contact_custom_value2' => 'contact.custom_value2',
|
|
||||||
'contact_custom_value3' => 'contact.custom_value3',
|
|
||||||
'contact_custom_value4' => 'contact.custom_value4',
|
|
||||||
'email' => 'contact.email',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'client.country_id',
|
|
||||||
'client.shipping_country_id',
|
|
||||||
'client.currency',
|
|
||||||
'client.industry',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -88,29 +41,39 @@ class ContactExport extends BaseExport
|
|||||||
$this->contact_transformer = new ClientContactTransformer();
|
$this->contact_transformer = new ClientContactTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
private function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->client_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = ClientContact::query()
|
$query = ClientContact::query()
|
||||||
->where('company_id', $this->company->id);
|
->where('company_id', $this->company->id);
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()->each(function ($contact) {
|
$query->cursor()->each(function ($contact) {
|
||||||
$this->csv->insertOne($this->buildRow($contact));
|
$this->csv->insertOne($this->buildRow($contact));
|
||||||
});
|
});
|
||||||
@ -118,6 +81,27 @@ class ContactExport extends BaseExport
|
|||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($contact) {
|
||||||
|
$row = $this->buildRow($contact);
|
||||||
|
return $this->processMetaData($row, $contact);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function buildRow(ClientContact $contact) :array
|
private function buildRow(ClientContact $contact) :array
|
||||||
{
|
{
|
||||||
$transformed_contact = false;
|
$transformed_contact = false;
|
||||||
@ -129,14 +113,13 @@ class ContactExport extends BaseExport
|
|||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$parts = explode('.', $key);
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if ($parts[0] == 'client' && array_key_exists($parts[1], $transformed_client)) {
|
if ($parts[0] == 'client' && array_key_exists($parts[1], $transformed_client)) {
|
||||||
$entity[$keyval] = $transformed_client[$parts[1]];
|
$entity[$key] = $transformed_client[$parts[1]];
|
||||||
} elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
|
} elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
$entity[$key] = $transformed_contact[$parts[1]];
|
||||||
} else {
|
} else {
|
||||||
$entity[$keyval] = '';
|
$entity[$key] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,13 +11,15 @@
|
|||||||
|
|
||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\Credit;
|
|
||||||
use App\Transformers\CreditTransformer;
|
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use Illuminate\Support\Facades\App;
|
use App\Utils\Number;
|
||||||
|
use App\Models\Credit;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use App\Transformers\CreditTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class CreditExport extends BaseExport
|
class CreditExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -28,51 +30,6 @@ class CreditExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
|
||||||
'client' => 'client_id',
|
|
||||||
'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'country' => 'country_id',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'invoice' => 'invoice_id',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'country',
|
|
||||||
'client',
|
|
||||||
'invoice',
|
|
||||||
'currency',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -80,31 +37,82 @@ class CreditExport extends BaseExport
|
|||||||
$this->credit_transformer = new CreditTransformer();
|
$this->credit_transformer = new CreditTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function returnJson()
|
||||||
{
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($credit) {
|
||||||
|
$row = $this->buildRow($credit);
|
||||||
|
return $this->processMetaData($row, $credit);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processMetaData(array $row, $resource): array
|
||||||
|
{
|
||||||
|
$clean_row = [];
|
||||||
|
foreach (array_values($this->input['report_keys']) as $key => $value) {
|
||||||
|
|
||||||
|
$report_keys = explode(".", $value);
|
||||||
|
|
||||||
|
$column_key = $value;
|
||||||
|
$clean_row[$key]['entity'] = $report_keys[0];
|
||||||
|
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
|
||||||
|
$clean_row[$key]['hashed_id'] = $report_keys[0] == 'credit' ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
|
||||||
|
$clean_row[$key]['value'] = $row[$column_key];
|
||||||
|
$clean_row[$key]['identifier'] = $value;
|
||||||
|
|
||||||
|
if(in_array($clean_row[$key]['id'], ['paid_to_date','total_taxes','amount', 'balance', 'partial', 'refunded', 'applied','unit_cost','cost','price']))
|
||||||
|
$clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $resource->client);
|
||||||
|
else
|
||||||
|
$clean_row[$key]['display_value'] = $row[$column_key];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clean_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(): Builder
|
||||||
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->credit_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Credit::query()
|
$query = Credit::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', 0);
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run(): string
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($credit) {
|
->each(function ($credit) {
|
||||||
$this->csv->insertOne($this->buildRow($credit));
|
$this->csv->insertOne($this->buildRow($credit));
|
||||||
@ -120,22 +128,22 @@ class CreditExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval)
|
|
||||||
$keyval = array_search(str_replace("credit.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
|
||||||
if(!$keyval)
|
|
||||||
$keyval = $key;
|
$keyval = $key;
|
||||||
|
$credit_key = str_replace("credit.", "", $key);
|
||||||
|
$searched_credit_key = array_search(str_replace("credit.", "", $key), $this->credit_report_keys) ?? $key;
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_credit)) {
|
if (isset($transformed_credit[$credit_key])) {
|
||||||
$entity[$keyval] = $transformed_credit[$key];
|
$entity[$keyval] = $transformed_credit[$credit_key];
|
||||||
} elseif (array_key_exists($keyval, $transformed_credit)) {
|
} elseif (isset($transformed_credit[$keyval])) {
|
||||||
$entity[$keyval] = $transformed_credit[$keyval];
|
$entity[$keyval] = $transformed_credit[$keyval];
|
||||||
|
} elseif(isset($transformed_credit[$searched_credit_key])){
|
||||||
|
$entity[$keyval] = $transformed_credit[$searched_credit_key];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
|
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->decorateAdvancedFields($credit, $entity);
|
return $this->decorateAdvancedFields($credit, $entity);
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
|||||||
use App\Models\Document;
|
use App\Models\Document;
|
||||||
use App\Transformers\DocumentTransformer;
|
use App\Transformers\DocumentTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -30,16 +31,11 @@ class DocumentExport extends BaseExport
|
|||||||
|
|
||||||
public array $entity_keys = [
|
public array $entity_keys = [
|
||||||
'record_type' => 'record_type',
|
'record_type' => 'record_type',
|
||||||
// 'record_name' => 'record_name',
|
|
||||||
'name' => 'name',
|
'name' => 'name',
|
||||||
'type' => 'type',
|
'type' => 'type',
|
||||||
'created_at' => 'created_at',
|
'created_at' => 'created_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -47,28 +43,56 @@ class DocumentExport extends BaseExport
|
|||||||
$this->entity_transformer = new DocumentTransformer();
|
$this->entity_transformer = new DocumentTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function returnJson()
|
||||||
{
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($document) {
|
||||||
|
$row = $this->buildRow($document);
|
||||||
|
return $this->processMetaData($row, $document);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(): Builder
|
||||||
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Document::query()->where('company_id', $this->company->id);
|
$query = Document::query()->where('company_id', $this->company->id);
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($entity) {
|
->each(function ($entity) {
|
||||||
$this->csv->insertOne($this->buildRow($entity));
|
$this->csv->insertOne($this->buildRow($entity));
|
||||||
|
@ -16,6 +16,7 @@ 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\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -28,51 +29,6 @@ class ExpenseExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'expense.amount',
|
|
||||||
'category' => 'expense.category',
|
|
||||||
'client' => 'expense.client_id',
|
|
||||||
'custom_value1' => 'expense.custom_value1',
|
|
||||||
'custom_value2' => 'expense.custom_value2',
|
|
||||||
'custom_value3' => 'expense.custom_value3',
|
|
||||||
'custom_value4' => 'expense.custom_value4',
|
|
||||||
'currency' => 'expense.currency_id',
|
|
||||||
'date' => 'expense.date',
|
|
||||||
'exchange_rate' => 'expense.exchange_rate',
|
|
||||||
'converted_amount' => 'expense.foreign_amount',
|
|
||||||
'invoice_currency_id' => 'expense.invoice_currency_id',
|
|
||||||
'payment_date' => 'expense.payment_date',
|
|
||||||
'number' => 'expense.number',
|
|
||||||
'payment_type_id' => 'expense.payment_type_id',
|
|
||||||
'private_notes' => 'expense.private_notes',
|
|
||||||
'project' => 'expense.project_id',
|
|
||||||
'public_notes' => 'expense.public_notes',
|
|
||||||
'tax_amount1' => 'expense.tax_amount1',
|
|
||||||
'tax_amount2' => 'expense.tax_amount2',
|
|
||||||
'tax_amount3' => 'expense.tax_amount3',
|
|
||||||
'tax_name1' => 'expense.tax_name1',
|
|
||||||
'tax_name2' => 'expense.tax_name2',
|
|
||||||
'tax_name3' => 'expense.tax_name3',
|
|
||||||
'tax_rate1' => 'expense.tax_rate1',
|
|
||||||
'tax_rate2' => 'expense.tax_rate2',
|
|
||||||
'tax_rate3' => 'expense.tax_rate3',
|
|
||||||
'transaction_reference' => 'expense.transaction_reference',
|
|
||||||
'vendor' => 'expense.vendor_id',
|
|
||||||
'invoice' => 'expense.invoice_id',
|
|
||||||
'user' => 'expense.user',
|
|
||||||
'assigned_user' => 'expense.assigned_user',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'client',
|
|
||||||
'currency',
|
|
||||||
'invoice',
|
|
||||||
'category',
|
|
||||||
'vendor',
|
|
||||||
'project',
|
|
||||||
'payment_type_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -80,24 +36,39 @@ class ExpenseExport extends BaseExport
|
|||||||
$this->expense_transformer = new ExpenseTransformer();
|
$this->expense_transformer = new ExpenseTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
|
||||||
|
public function returnJson()
|
||||||
{
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(): Builder
|
||||||
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->expense_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Expense::query()
|
$query = Expense::query()
|
||||||
->with('client')
|
->with('client')
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
@ -106,6 +77,20 @@ class ExpenseExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($expense) {
|
->each(function ($expense) {
|
||||||
$this->csv->insertOne($this->buildRow($expense));
|
$this->csv->insertOne($this->buildRow($expense));
|
||||||
@ -122,7 +107,6 @@ class ExpenseExport extends BaseExport
|
|||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$parts = explode('.', $key);
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if (is_array($parts) && $parts[0] == 'expense' && array_key_exists($parts[1], $transformed_expense)) {
|
if (is_array($parts) && $parts[0] == 'expense' && array_key_exists($parts[1], $transformed_expense)) {
|
||||||
$entity[$key] = $transformed_expense[$parts[1]];
|
$entity[$key] = $transformed_expense[$parts[1]];
|
||||||
@ -175,6 +159,10 @@ class ExpenseExport extends BaseExport
|
|||||||
$entity['expense.assigned_user'] = $expense->assigned_user ? $expense->assigned_user->present()->name() : '';
|
$entity['expense.assigned_user'] = $expense->assigned_user ? $expense->assigned_user->present()->name() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('expense.category_id', $this->input['report_keys'])) {
|
||||||
|
$entity['expense.category_id'] = $expense->category ? $expense->category->name : '';
|
||||||
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use App\Libraries\MultiDB;
|
|||||||
use App\Export\CSV\BaseExport;
|
use App\Export\CSV\BaseExport;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class InvoiceExport extends BaseExport
|
class InvoiceExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -29,56 +30,6 @@ class InvoiceExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
|
||||||
'client' => 'client_id',
|
|
||||||
'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency_id' => 'currency_id',
|
|
||||||
'payment_number' => 'payment_number',
|
|
||||||
'payment_date' => 'payment_date',
|
|
||||||
'payment_amount' => 'payment_amount',
|
|
||||||
'method' => 'method',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'country',
|
|
||||||
'client',
|
|
||||||
'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;
|
||||||
@ -86,24 +37,19 @@ class InvoiceExport extends BaseExport
|
|||||||
$this->invoice_transformer = new InvoiceTransformer();
|
$this->invoice_transformer = new InvoiceTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->invoice_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Invoice::query()
|
$query = Invoice::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->with('client')
|
->with('client')
|
||||||
@ -112,10 +58,43 @@ class InvoiceExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
if(isset($this->input['status'])){
|
if(isset($this->input['status'])) {
|
||||||
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
|
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($invoice) {
|
->each(function ($invoice) {
|
||||||
$this->csv->insertOne($this->buildRow($invoice));
|
$this->csv->insertOne($this->buildRow($invoice));
|
||||||
@ -131,24 +110,15 @@ class InvoiceExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||||
|
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||||
|
} else {
|
||||||
|
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
|
||||||
$keyval = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_invoice)) {
|
|
||||||
$entity[$keyval] = $transformed_invoice[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
|
||||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->decorateAdvancedFields($invoice, $entity);
|
return $this->decorateAdvancedFields($invoice, $entity);
|
||||||
@ -156,32 +126,23 @@ class InvoiceExport extends BaseExport
|
|||||||
|
|
||||||
private function decorateAdvancedFields(Invoice $invoice, array $entity) :array
|
private function decorateAdvancedFields(Invoice $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('invoice.country_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
if (in_array('invoice.currency_id', $this->input['report_keys'])) {
|
||||||
$entity['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('client_id', $this->input['report_keys'])) {
|
if (in_array('invoice.client_id', $this->input['report_keys'])) {
|
||||||
$entity['client'] = $invoice->client->present()->name();
|
$entity['invoice.client_id'] = $invoice->client->present()->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('status_id', $this->input['report_keys'])) {
|
if (in_array('invoice.status', $this->input['report_keys'])) {
|
||||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
$entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $payment_exists = $invoice->payments()->exists();
|
|
||||||
|
|
||||||
// $entity['payment_number'] = $payment_exists ? $invoice->payments()->pluck('number')->implode(',') : '';
|
|
||||||
|
|
||||||
// $entity['payment_date'] = $payment_exists ? $invoice->payments()->pluck('date')->implode(',') : '';
|
|
||||||
|
|
||||||
// $entity['payment_amount'] = $payment_exists ? Number::formatMoney($invoice->payments()->sum('paymentables.amount'), $invoice->company) : ctrans('texts.unpaid');
|
|
||||||
|
|
||||||
// $entity['method'] = $payment_exists ? $invoice->payments()->first()->translatedType() : "";
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -31,64 +31,9 @@ class InvoiceItemExport extends BaseExport
|
|||||||
|
|
||||||
private bool $force_keys = false;
|
private bool $force_keys = false;
|
||||||
|
|
||||||
public array $entity_keys = [
|
private array $storage_array = [];
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
private array $storage_item_array = [];
|
||||||
'client' => 'client_id',
|
|
||||||
'client_number' => 'client.number',
|
|
||||||
'client_id_number' => 'client.id_number',
|
|
||||||
'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'quantity' => 'item.quantity',
|
|
||||||
'cost' => 'item.cost',
|
|
||||||
'product_key' => 'item.product_key',
|
|
||||||
'buy_price' => 'item.product_cost',
|
|
||||||
'notes' => 'item.notes',
|
|
||||||
'discount' => 'item.discount',
|
|
||||||
'is_amount_discount' => 'item.is_amount_discount',
|
|
||||||
'tax_rate1' => 'item.tax_rate1',
|
|
||||||
'tax_rate2' => 'item.tax_rate2',
|
|
||||||
'tax_rate3' => 'item.tax_rate3',
|
|
||||||
'tax_name1' => 'item.tax_name1',
|
|
||||||
'tax_name2' => 'item.tax_name2',
|
|
||||||
'tax_name3' => 'item.tax_name3',
|
|
||||||
'line_total' => 'item.line_total',
|
|
||||||
'gross_line_total' => 'item.gross_line_total',
|
|
||||||
'invoice1' => 'item.custom_value1',
|
|
||||||
'invoice2' => 'item.custom_value2',
|
|
||||||
'invoice3' => 'item.custom_value3',
|
|
||||||
'invoice4' => 'item.custom_value4',
|
|
||||||
'tax_category' => 'item.tax_id',
|
|
||||||
'type' => 'item.type_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
private array $decorate_keys = [
|
||||||
'client',
|
'client',
|
||||||
@ -103,37 +48,77 @@ class InvoiceItemExport extends BaseExport
|
|||||||
$this->invoice_transformer = new InvoiceTransformer();
|
$this->invoice_transformer = new InvoiceTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
if (count($this->input['report_keys']) == 0) {
|
if (count($this->input['report_keys']) == 0) {
|
||||||
$this->force_keys = true;
|
$this->force_keys = true;
|
||||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
$this->input['report_keys'] = array_values($this->mergeItemsKeys('invoice_report_keys'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Invoice::query()
|
$query = Invoice::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', 0);
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
|
||||||
|
$query->cursor()
|
||||||
|
->each(function ($resource) {
|
||||||
|
$this->iterateItems($resource);
|
||||||
|
|
||||||
|
foreach($this->storage_array as $row) {
|
||||||
|
$this->storage_item_array[] = $this->processItemMetaData($row, $resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->storage_array = [];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $this->storage_item_array);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($invoice) {
|
->each(function ($invoice) {
|
||||||
$this->iterateItems($invoice);
|
$this->iterateItems($invoice);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->csv->insertAll($this->storage_array);
|
||||||
|
|
||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,46 +131,32 @@ class InvoiceItemExport extends BaseExport
|
|||||||
foreach ($invoice->line_items as $item) {
|
foreach ($invoice->line_items as $item) {
|
||||||
$item_array = [];
|
$item_array = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
foreach (array_values(array_intersect($this->input['report_keys'], $this->item_report_keys)) as $key) { //items iterator produces item array
|
||||||
|
|
||||||
if (str_contains($key, "item.")) {
|
if (str_contains($key, "item.")) {
|
||||||
|
|
||||||
$key = str_replace("item.", "", $key);
|
$key = str_replace("item.", "", $key);
|
||||||
|
|
||||||
$keyval = $key;
|
|
||||||
|
|
||||||
$keyval = str_replace("custom_value", "invoice", $key);
|
|
||||||
|
|
||||||
if($key == 'type_id')
|
if($key == 'type_id')
|
||||||
$keyval = 'type';
|
$key = 'type';
|
||||||
|
|
||||||
if($key == 'tax_id')
|
if($key == 'tax_id')
|
||||||
$keyval = 'tax_category';
|
$key = 'tax_category';
|
||||||
|
|
||||||
if (property_exists($item, $key)) {
|
if (property_exists($item, $key)) {
|
||||||
$item_array[$keyval] = $item->{$key};
|
$item_array[$key] = $item->{$key};
|
||||||
} else {
|
|
||||||
$item_array[$keyval] = '';
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$item_array[$key] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity = [];
|
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_items)) {
|
|
||||||
$entity[$keyval] = $transformed_items[$key];
|
|
||||||
} else {
|
|
||||||
$entity[$keyval] = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$transformed_items = array_merge($transformed_invoice, $item_array);
|
$transformed_items = array_merge($transformed_invoice, $item_array);
|
||||||
$entity = $this->decorateAdvancedFields($invoice, $transformed_items);
|
$entity = $this->decorateAdvancedFields($invoice, $transformed_items);
|
||||||
|
|
||||||
$this->csv->insertOne($entity);
|
$this->storage_array[] = $entity;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,23 +167,19 @@ class InvoiceItemExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$keyval) {
|
if(is_array($parts) && $parts[0] == 'item')
|
||||||
$keyval = $key;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_invoice)) {
|
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||||
$entity[$keyval] = $transformed_invoice[$key];
|
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
}else if (array_key_exists($key, $transformed_invoice)) {
|
||||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
$entity[$key] = $transformed_invoice[$key];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,13 +200,7 @@ class InvoiceItemExport extends BaseExport
|
|||||||
$entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
|
$entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->force_keys) {
|
|
||||||
$entity['client'] = $invoice->client->present()->name();
|
|
||||||
$entity['client_id_number'] = $invoice->client->id_number;
|
|
||||||
$entity['client_number'] = $invoice->client->number;
|
|
||||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
|||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Transformers\PaymentTransformer;
|
use App\Transformers\PaymentTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -27,40 +28,6 @@ class PaymentExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'amount',
|
|
||||||
'applied' => 'applied',
|
|
||||||
'client' => 'client_id',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'exchange_currency' => 'exchange_currency_id',
|
|
||||||
'gateway' => 'gateway_type_id',
|
|
||||||
'number' => 'number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'project' => 'project_id',
|
|
||||||
'refunded' => 'refunded',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'transaction_reference' => 'transaction_reference',
|
|
||||||
'type' => 'type_id',
|
|
||||||
'vendor' => 'vendor_id',
|
|
||||||
'invoices' => 'invoices',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'vendor',
|
|
||||||
'status',
|
|
||||||
'project',
|
|
||||||
'client',
|
|
||||||
'currency',
|
|
||||||
'exchange_currency',
|
|
||||||
'type',
|
|
||||||
'invoices',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -68,24 +35,19 @@ class PaymentExport extends BaseExport
|
|||||||
$this->entity_transformer = new PaymentTransformer();
|
$this->entity_transformer = new PaymentTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
private function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->payment_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Payment::query()
|
$query = Payment::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
@ -93,6 +55,39 @@ class PaymentExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use ($headerdisplay) {
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($entity) {
|
->each(function ($entity) {
|
||||||
$this->csv->insertOne($this->buildRow($entity));
|
$this->csv->insertOne($this->buildRow($entity));
|
||||||
@ -108,24 +103,17 @@ class PaymentExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("payment.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
if (is_array($parts) && $parts[0] == 'payment' && array_key_exists($parts[1], $transformed_entity)) {
|
||||||
|
$entity[$key] = $transformed_entity[$parts[1]];
|
||||||
|
} elseif (array_key_exists($key, $transformed_entity)) {
|
||||||
|
$entity[$key] = $transformed_entity[$key];
|
||||||
|
} else {
|
||||||
|
$entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
|
||||||
$keyval = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_entity)) {
|
|
||||||
$entity[$keyval] = $transformed_entity[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
|
||||||
$entity[$keyval] = $transformed_entity[$keyval];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $payment, $this->entity_transformer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->decorateAdvancedFields($payment, $entity);
|
return $this->decorateAdvancedFields($payment, $entity);
|
||||||
|
@ -13,10 +13,10 @@ namespace App\Export\CSV;
|
|||||||
|
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Document;
|
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Transformers\ProductTransformer;
|
use App\Transformers\ProductTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -28,31 +28,6 @@ class ProductExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'project' => 'project_id',
|
|
||||||
'vendor' => 'vendor_id',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'product_key' => 'product_key',
|
|
||||||
'notes' => 'notes',
|
|
||||||
'cost' => 'cost',
|
|
||||||
'price' => 'price',
|
|
||||||
'quantity' => 'quantity',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'vendor',
|
|
||||||
'project',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -60,24 +35,38 @@ class ProductExport extends BaseExport
|
|||||||
$this->entity_transformer = new ProductTransformer();
|
$this->entity_transformer = new ProductTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function returnJson()
|
||||||
{
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(): Builder
|
||||||
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->product_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Product::query()
|
$query = Product::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
@ -85,6 +74,21 @@ class ProductExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($entity) {
|
->each(function ($entity) {
|
||||||
$this->csv->insertOne($this->buildRow($entity));
|
$this->csv->insertOne($this->buildRow($entity));
|
||||||
@ -100,7 +104,7 @@ class ProductExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
$keyval = array_search($key, $this->product_report_keys);
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_entity)) {
|
if (array_key_exists($key, $transformed_entity)) {
|
||||||
$entity[$keyval] = $transformed_entity[$key];
|
$entity[$keyval] = $transformed_entity[$key];
|
||||||
|
@ -85,7 +85,7 @@ class ProductSalesExport extends BaseExport
|
|||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
$this->products = Product::where('company_id', $this->company->id)->withTrashed()->get();
|
$this->products = Product::query()->where('company_id', $this->company->id)->withTrashed()->get();
|
||||||
|
|
||||||
//load the CSV document from a string
|
//load the CSV document from a string
|
||||||
$this->csv = Writer::createFromString();
|
$this->csv = Writer::createFromString();
|
||||||
@ -187,6 +187,7 @@ class ProductSalesExport extends BaseExport
|
|||||||
$product = $this->getProduct($entity['product_key']);
|
$product = $this->getProduct($entity['product_key']);
|
||||||
|
|
||||||
$entity['cost'] = $product->cost ?? 0;
|
$entity['cost'] = $product->cost ?? 0;
|
||||||
|
/** @var float $unit_cost */
|
||||||
$unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];
|
$unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];
|
||||||
|
|
||||||
$entity['client'] = $invoice->client->present()->name();
|
$entity['client'] = $invoice->client->present()->name();
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
|
|
||||||
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 App\Utils\Number;
|
use App\Utils\Number;
|
||||||
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\Transformers\PurchaseOrderTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class PurchaseOrderExport extends BaseExport
|
class PurchaseOrderExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -81,24 +82,19 @@ class PurchaseOrderExport extends BaseExport
|
|||||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
|
||||||
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->purchase_order_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = PurchaseOrder::query()
|
$query = PurchaseOrder::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->with('vendor')
|
->with('vendor')
|
||||||
@ -107,9 +103,39 @@ class PurchaseOrderExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
// if(isset($this->input['status'])) {
|
return $query;
|
||||||
// $query = $this->addPurchaseOrderStatusFilter($query, $this->input['status']);
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($purchase_order) {
|
->each(function ($purchase_order) {
|
||||||
@ -126,23 +152,16 @@ class PurchaseOrderExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$keyval) {
|
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
|
||||||
$keyval = $key;
|
$entity[$key] = $transformed_purchase_order[$parts[1]];
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_purchase_order)) {
|
|
||||||
$entity[$keyval] = $transformed_purchase_order[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_purchase_order)) {
|
|
||||||
$entity[$keyval] = $transformed_purchase_order[$keyval];
|
|
||||||
} else {
|
} else {
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $purchase_order, $this->purchase_order_transformer);
|
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->decorateAdvancedFields($purchase_order, $entity);
|
return $this->decorateAdvancedFields($purchase_order, $entity);
|
||||||
|
@ -11,13 +11,14 @@
|
|||||||
|
|
||||||
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\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 Illuminate\Database\Eloquent\Builder;
|
||||||
|
use App\Transformers\PurchaseOrderTransformer;
|
||||||
|
|
||||||
class PurchaseOrderItemExport extends BaseExport
|
class PurchaseOrderItemExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -30,70 +31,9 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
|
|
||||||
private bool $force_keys = false;
|
private bool $force_keys = false;
|
||||||
|
|
||||||
public array $entity_keys = [
|
private array $storage_array = [];
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
|
||||||
'vendor' => 'vendor_id',
|
|
||||||
'vendor_number' => 'vendor.number',
|
|
||||||
'vendor_id_number' => 'vendor.id_number',
|
|
||||||
// 'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
// 'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
// 'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
// 'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
// 'custom_value1' => 'custom_value1',
|
|
||||||
// 'custom_value2' => 'custom_value2',
|
|
||||||
// 'custom_value3' => 'custom_value3',
|
|
||||||
// 'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'quantity' => 'item.quantity',
|
|
||||||
'cost' => 'item.cost',
|
|
||||||
'product_key' => 'item.product_key',
|
|
||||||
'buy_price' => 'item.product_cost',
|
|
||||||
'notes' => 'item.notes',
|
|
||||||
'discount' => 'item.discount',
|
|
||||||
'is_amount_discount' => 'item.is_amount_discount',
|
|
||||||
'tax_rate1' => 'item.tax_rate1',
|
|
||||||
'tax_rate2' => 'item.tax_rate2',
|
|
||||||
'tax_rate3' => 'item.tax_rate3',
|
|
||||||
'tax_name1' => 'item.tax_name1',
|
|
||||||
'tax_name2' => 'item.tax_name2',
|
|
||||||
'tax_name3' => 'item.tax_name3',
|
|
||||||
'line_total' => 'item.line_total',
|
|
||||||
'gross_line_total' => 'item.gross_line_total',
|
|
||||||
'purchase_order1' => 'item.custom_value1',
|
|
||||||
'purchase_order2' => 'item.custom_value2',
|
|
||||||
'purchase_order3' => 'item.custom_value3',
|
|
||||||
'purchase_order4' => 'item.custom_value4',
|
|
||||||
'tax_category' => 'item.tax_id',
|
|
||||||
'type' => 'item.type_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
private array $storage_item_array = [];
|
||||||
'client',
|
|
||||||
'currency_id',
|
|
||||||
'status'
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
@ -102,25 +42,19 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
private function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
if (count($this->input['report_keys']) == 0) {
|
if (count($this->input['report_keys']) == 0) {
|
||||||
$this->force_keys = true;
|
$this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
|
||||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = PurchaseOrder::query()
|
$query = PurchaseOrder::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->with('vendor')->where('company_id', $this->company->id)
|
->with('vendor')->where('company_id', $this->company->id)
|
||||||
@ -128,12 +62,54 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$query->cursor()
|
||||||
|
->each(function ($resource) {
|
||||||
|
$this->iterateItems($resource);
|
||||||
|
|
||||||
|
foreach($this->storage_array as $row) {
|
||||||
|
$this->storage_item_array[] = $this->processItemMetaData($row, $resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->storage_array = [];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $this->storage_item_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($purchase_order) {
|
->each(function ($purchase_order) {
|
||||||
$this->iterateItems($purchase_order);
|
$this->iterateItems($purchase_order);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->csv->insertAll($this->storage_array);
|
||||||
|
|
||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function iterateItems(PurchaseOrder $purchase_order)
|
private function iterateItems(PurchaseOrder $purchase_order)
|
||||||
@ -145,16 +121,12 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
foreach ($purchase_order->line_items as $item) {
|
foreach ($purchase_order->line_items as $item) {
|
||||||
$item_array = [];
|
$item_array = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
foreach (array_values(array_intersect($this->input['report_keys'], $this->item_report_keys)) as $key) { //items iterator produces item array
|
||||||
|
|
||||||
if (str_contains($key, "item.")) {
|
if (str_contains($key, "item.")) {
|
||||||
|
|
||||||
$key = str_replace("item.", "", $key);
|
$key = str_replace("item.", "", $key);
|
||||||
|
|
||||||
$keyval = $key;
|
|
||||||
|
|
||||||
$keyval = str_replace("custom_value", "purchase_order", $key);
|
|
||||||
|
|
||||||
if($key == 'type_id') {
|
if($key == 'type_id') {
|
||||||
$keyval = 'type';
|
$keyval = 'type';
|
||||||
}
|
}
|
||||||
@ -164,29 +136,17 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (property_exists($item, $key)) {
|
if (property_exists($item, $key)) {
|
||||||
$item_array[$keyval] = $item->{$key};
|
$item_array[$key] = $item->{$key};
|
||||||
} else {
|
} else {
|
||||||
$item_array[$keyval] = '';
|
$item_array[$key] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity = [];
|
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_items)) {
|
|
||||||
$entity[$keyval] = $transformed_items[$key];
|
|
||||||
} else {
|
|
||||||
$entity[$keyval] = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$transformed_items = array_merge($transformed_purchase_order, $item_array);
|
$transformed_items = array_merge($transformed_purchase_order, $item_array);
|
||||||
$entity = $this->decorateAdvancedFields($purchase_order, $transformed_items);
|
$entity = $this->decorateAdvancedFields($purchase_order, $transformed_items);
|
||||||
|
|
||||||
$this->csv->insertOne($entity);
|
$this->storage_array[] = $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,22 +157,18 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
$parts = explode('.', $key);
|
||||||
|
|
||||||
if(!$keyval) {
|
if(is_array($parts) && $parts[0] == 'item') {
|
||||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
|
||||||
$keyval = $key;
|
$entity[$key] = $transformed_purchase_order[$parts[1]];
|
||||||
}
|
} elseif (array_key_exists($key, $transformed_purchase_order)) {
|
||||||
|
$entity[$key] = $transformed_purchase_order[$key];
|
||||||
if (array_key_exists($key, $transformed_purchase_order)) {
|
|
||||||
$entity[$keyval] = $transformed_purchase_order[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_purchase_order)) {
|
|
||||||
$entity[$keyval] = $transformed_purchase_order[$keyval];
|
|
||||||
} else {
|
} else {
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $purchase_order, $this->purchase_order_transformer);
|
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,4 +198,5 @@ class PurchaseOrderItemExport extends BaseExport
|
|||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
|||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Transformers\QuoteTransformer;
|
use App\Transformers\QuoteTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -28,43 +29,6 @@ class QuoteExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
|
||||||
'client' => 'client_id',
|
|
||||||
'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'valid_until' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'invoice' => 'invoice_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
private array $decorate_keys = [
|
||||||
'client',
|
'client',
|
||||||
'currency',
|
'currency',
|
||||||
@ -78,24 +42,20 @@ class QuoteExport extends BaseExport
|
|||||||
$this->quote_transformer = new QuoteTransformer();
|
$this->quote_transformer = new QuoteTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
private function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->quote_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Quote::query()
|
$query = Quote::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->with('client')
|
->with('client')
|
||||||
@ -104,6 +64,41 @@ class QuoteExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use ($headerdisplay) {
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($quote) {
|
->each(function ($quote) {
|
||||||
$this->csv->insertOne($this->buildRow($quote));
|
$this->csv->insertOne($this->buildRow($quote));
|
||||||
@ -114,50 +109,42 @@ class QuoteExport extends BaseExport
|
|||||||
|
|
||||||
private function buildRow(Quote $quote) :array
|
private function buildRow(Quote $quote) :array
|
||||||
{
|
{
|
||||||
$transformed_entity = $this->quote_transformer->transform($quote);
|
$transformed_invoice = $this->quote_transformer->transform($quote);
|
||||||
|
|
||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||||
|
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||||
|
} else {
|
||||||
|
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
|
||||||
$keyval = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_entity)) {
|
|
||||||
$entity[$keyval] = $transformed_entity[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
|
||||||
$entity[$keyval] = $transformed_entity[$keyval];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $quote, $this->quote_transformer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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('quote.currency_id', $this->input['report_keys'])) {
|
||||||
$entity['currency'] = $quote->client->currency()->code;
|
$entity['quote.currency'] = $quote->client->currency()->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('client_id', $this->input['report_keys'])) {
|
if (in_array('quote.client_id', $this->input['report_keys'])) {
|
||||||
$entity['client'] = $quote->client->present()->name();
|
$entity['quote.client'] = $quote->client->present()->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('status_id', $this->input['report_keys'])) {
|
if (in_array('quote.status', $this->input['report_keys'])) {
|
||||||
$entity['status'] = $quote->stringStatus($quote->status_id);
|
$entity['quote.status'] = $quote->stringStatus($quote->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
if (in_array('quote.invoice_id', $this->input['report_keys'])) {
|
||||||
$entity['invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
|||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Transformers\QuoteTransformer;
|
use App\Transformers\QuoteTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -28,63 +29,8 @@ class QuoteItemExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
private array $storage_array = [];
|
||||||
'amount' => 'amount',
|
private array $storage_item_array = [];
|
||||||
'balance' => 'balance',
|
|
||||||
'client' => 'client_id',
|
|
||||||
'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'quantity' => 'item.quantity',
|
|
||||||
'cost' => 'item.cost',
|
|
||||||
'product_key' => 'item.product_key',
|
|
||||||
'buy_price' => 'item.product_cost',
|
|
||||||
'cost' => 'item.cost',
|
|
||||||
'notes' => 'item.notes',
|
|
||||||
'discount' => 'item.discount',
|
|
||||||
'is_amount_discount' => 'item.is_amount_discount',
|
|
||||||
'tax_rate1' => 'item.tax_rate1',
|
|
||||||
'tax_rate2' => 'item.tax_rate2',
|
|
||||||
'tax_rate3' => 'item.tax_rate3',
|
|
||||||
'tax_name1' => 'item.tax_name1',
|
|
||||||
'tax_name2' => 'item.tax_name2',
|
|
||||||
'tax_name3' => 'item.tax_name3',
|
|
||||||
'line_total' => 'item.line_total',
|
|
||||||
'gross_line_total' => 'item.gross_line_total',
|
|
||||||
'quote1' => 'item.custom_value1',
|
|
||||||
'quote2' => 'item.custom_value2',
|
|
||||||
'quote3' => 'item.custom_value3',
|
|
||||||
'quote4' => 'item.custom_value4',
|
|
||||||
'tax_category' => 'item.tax_id',
|
|
||||||
'type' => 'item.type_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
private array $decorate_keys = [
|
||||||
'client',
|
'client',
|
||||||
@ -98,24 +44,19 @@ class QuoteItemExport extends BaseExport
|
|||||||
$this->quote_transformer = new QuoteTransformer();
|
$this->quote_transformer = new QuoteTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->mergeItemsKeys('quote_report_keys'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Quote::query()
|
$query = Quote::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->with('client')->where('company_id', $this->company->id)
|
->with('client')->where('company_id', $this->company->id)
|
||||||
@ -123,12 +64,58 @@ class QuoteItemExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$query->cursor()
|
||||||
|
->each(function ($resource) {
|
||||||
|
$this->iterateItems($resource);
|
||||||
|
|
||||||
|
foreach($this->storage_array as $row) {
|
||||||
|
$this->storage_item_array[] = $this->processItemMetaData($row, $resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->storage_array = [];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $this->storage_item_array);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($quote) {
|
->each(function ($quote) {
|
||||||
$this->iterateItems($quote);
|
$this->iterateItems($quote);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->csv->insertAll($this->storage_array);
|
||||||
|
|
||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function iterateItems(Quote $quote)
|
private function iterateItems(Quote $quote)
|
||||||
@ -137,51 +124,34 @@ class QuoteItemExport extends BaseExport
|
|||||||
|
|
||||||
$transformed_items = [];
|
$transformed_items = [];
|
||||||
|
|
||||||
$transformed_items = [];
|
|
||||||
|
|
||||||
foreach ($quote->line_items as $item) {
|
foreach ($quote->line_items as $item) {
|
||||||
$item_array = [];
|
$item_array = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
foreach (array_values(array_intersect($this->input['report_keys'], $this->item_report_keys)) as $key) { //items iterator produces item array
|
||||||
|
|
||||||
if (str_contains($key, "item.")) {
|
if (str_contains($key, "item.")) {
|
||||||
|
|
||||||
$key = str_replace("item.", "", $key);
|
$key = str_replace("item.", "", $key);
|
||||||
|
|
||||||
$keyval = $key;
|
|
||||||
|
|
||||||
$keyval = str_replace("custom_value", "quote", $key);
|
|
||||||
|
|
||||||
if($key == 'type_id')
|
if($key == 'type_id')
|
||||||
$keyval = 'type';
|
$key = 'type';
|
||||||
|
|
||||||
if($key == 'tax_id')
|
if($key == 'tax_id')
|
||||||
$keyval = 'tax_category';
|
$key = 'tax_category';
|
||||||
|
|
||||||
if (property_exists($item, $key)) {
|
if (property_exists($item, $key)) {
|
||||||
$item_array[$keyval] = $item->{$key};
|
$item_array[$key] = $item->{$key};
|
||||||
} else {
|
|
||||||
$item_array[$keyval] = '';
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$item_array[$key] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity = [];
|
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_items)) {
|
|
||||||
$entity[$keyval] = $transformed_items[$key];
|
|
||||||
} else {
|
|
||||||
$entity[$keyval] = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$transformed_items = array_merge($transformed_quote, $item_array);
|
$transformed_items = array_merge($transformed_quote, $item_array);
|
||||||
$entity = $this->decorateAdvancedFields($quote, $transformed_items);
|
$entity = $this->decorateAdvancedFields($quote, $transformed_items);
|
||||||
|
|
||||||
$this->csv->insertOne($entity);
|
$this->storage_array[] = $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,25 +162,22 @@ class QuoteItemExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("quote.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
if(is_array($parts) && $parts[0] == 'item') {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_quote)) {
|
||||||
$keyval = $key;
|
$entity[$key] = $transformed_quote[$parts[1]];
|
||||||
|
} elseif (array_key_exists($key, $transformed_quote)) {
|
||||||
|
$entity[$key] = $transformed_quote[$key];
|
||||||
|
} else {
|
||||||
|
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_quote)) {
|
|
||||||
$entity[$keyval] = $transformed_quote[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_quote)) {
|
|
||||||
$entity[$keyval] = $transformed_quote[$keyval];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $quote, $this->quote_transformer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->decorateAdvancedFields($quote, $entity);
|
return $this->decorateAdvancedFields($quote, $entity);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
|||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Transformers\RecurringInvoiceTransformer;
|
use App\Transformers\RecurringInvoiceTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -28,56 +29,6 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'amount' => 'amount',
|
|
||||||
'balance' => 'balance',
|
|
||||||
'client' => 'client_id',
|
|
||||||
// 'custom_surcharge1' => 'custom_surcharge1',
|
|
||||||
// 'custom_surcharge2' => 'custom_surcharge2',
|
|
||||||
// 'custom_surcharge3' => 'custom_surcharge3',
|
|
||||||
// 'custom_surcharge4' => 'custom_surcharge4',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'date' => 'date',
|
|
||||||
'discount' => 'discount',
|
|
||||||
'due_date' => 'due_date',
|
|
||||||
'exchange_rate' => 'exchange_rate',
|
|
||||||
'footer' => 'footer',
|
|
||||||
'number' => 'number',
|
|
||||||
'paid_to_date' => 'paid_to_date',
|
|
||||||
'partial' => 'partial',
|
|
||||||
'partial_due_date' => 'partial_due_date',
|
|
||||||
'po_number' => 'po_number',
|
|
||||||
'private_notes' => 'private_notes',
|
|
||||||
'public_notes' => 'public_notes',
|
|
||||||
'next_send_date' => 'next_send_date',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'tax_name1' => 'tax_name1',
|
|
||||||
'tax_name2' => 'tax_name2',
|
|
||||||
'tax_name3' => 'tax_name3',
|
|
||||||
'tax_rate1' => 'tax_rate1',
|
|
||||||
'tax_rate2' => 'tax_rate2',
|
|
||||||
'tax_rate3' => 'tax_rate3',
|
|
||||||
'terms' => 'terms',
|
|
||||||
'total_taxes' => 'total_taxes',
|
|
||||||
'currency' => 'currency_id',
|
|
||||||
'vendor' => 'vendor_id',
|
|
||||||
'project' => 'project_id',
|
|
||||||
'frequency_id' => 'frequency_id',
|
|
||||||
'next_send_date' => 'next_send_date'
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'country',
|
|
||||||
'client',
|
|
||||||
'currency',
|
|
||||||
'status',
|
|
||||||
'vendor',
|
|
||||||
'project',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -85,7 +36,7 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
$this->invoice_transformer = new RecurringInvoiceTransformer();
|
$this->invoice_transformer = new RecurringInvoiceTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
@ -93,23 +44,33 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
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->recurring_invoice_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = RecurringInvoice::query()
|
$query = RecurringInvoice::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', 0);
|
||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($invoice) {
|
->each(function ($invoice) {
|
||||||
$this->csv->insertOne($this->buildRow($invoice));
|
$this->csv->insertOne($this->buildRow($invoice));
|
||||||
@ -118,6 +79,27 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
@ -125,22 +107,13 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
$entity = [];
|
$entity = [];
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("recurring_invoice.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$keyval) {
|
if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||||
$keyval = $key;
|
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_invoice)) {
|
|
||||||
$entity[$keyval] = $transformed_invoice[$key];
|
|
||||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
|
||||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
|
||||||
} else {
|
} else {
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -175,7 +148,7 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
}
|
}
|
||||||
|
|
||||||
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['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
|
$entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -18,6 +18,7 @@ use App\Models\Task;
|
|||||||
use App\Models\Timezone;
|
use App\Models\Timezone;
|
||||||
use App\Transformers\TaskTransformer;
|
use App\Transformers\TaskTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
@ -33,30 +34,9 @@ class TaskExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
public array $entity_keys = [
|
private array $storage_array = [];
|
||||||
'start_date' => 'start_date',
|
|
||||||
'end_date' => 'end_date',
|
|
||||||
'duration' => 'duration',
|
|
||||||
'rate' => 'rate',
|
|
||||||
'number' => 'number',
|
|
||||||
'description' => 'description',
|
|
||||||
'custom_value1' => 'custom_value1',
|
|
||||||
'custom_value2' => 'custom_value2',
|
|
||||||
'custom_value3' => 'custom_value3',
|
|
||||||
'custom_value4' => 'custom_value4',
|
|
||||||
'status' => 'status_id',
|
|
||||||
'project' => 'project_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
private array $storage_item_array = [];
|
||||||
'status',
|
|
||||||
'project',
|
|
||||||
'client',
|
|
||||||
'invoice',
|
|
||||||
'start_date',
|
|
||||||
'end_date',
|
|
||||||
'duration',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
@ -65,7 +45,7 @@ class TaskExport extends BaseExport
|
|||||||
$this->entity_transformer = new TaskTransformer();
|
$this->entity_transformer = new TaskTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
@ -74,19 +54,12 @@ class TaskExport extends BaseExport
|
|||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
|
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
|
||||||
|
|
||||||
//load the CSV document from a string
|
|
||||||
$this->csv = Writer::createFromString();
|
|
||||||
|
|
||||||
ksort($this->entity_keys);
|
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->task_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Task::query()
|
$query = Task::query()
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
@ -94,52 +67,87 @@ class TaskExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//load the CSV document from a string
|
||||||
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($entity) {
|
->each(function ($entity) {
|
||||||
$this->buildRow($entity);
|
$this->buildRow($entity);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->csv->insertAll($this->storage_array);
|
||||||
|
|
||||||
return $this->csv->toString();
|
return $this->csv->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$query->cursor()
|
||||||
|
->each(function ($resource) {
|
||||||
|
|
||||||
|
$this->buildRow($resource);
|
||||||
|
|
||||||
|
foreach($this->storage_array as $row)
|
||||||
|
{
|
||||||
|
$this->storage_item_array[] = $this->processMetaData($row, $resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->storage_array = [];
|
||||||
|
});
|
||||||
|
nlog($this->storage_item_array);
|
||||||
|
return array_merge(['columns' => $header], $this->storage_item_array);
|
||||||
|
}
|
||||||
|
|
||||||
private function buildRow(Task $task)
|
private function buildRow(Task $task)
|
||||||
{
|
{
|
||||||
$entity = [];
|
$entity = [];
|
||||||
$transformed_entity = $this->entity_transformer->transform($task);
|
$transformed_entity = $this->entity_transformer->transform($task);
|
||||||
|
|
||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if(!$keyval) {
|
$parts = explode('.', $key);
|
||||||
$keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
|
|
||||||
|
if (is_array($parts) && $parts[0] == 'task' && array_key_exists($parts[1], $transformed_entity)) {
|
||||||
|
$entity[$key] = $transformed_entity[$parts[1]];
|
||||||
|
} elseif (array_key_exists($key, $transformed_entity)) {
|
||||||
|
$entity[$key] = $transformed_entity[$key];
|
||||||
|
} else {
|
||||||
|
$entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$keyval) {
|
|
||||||
$keyval = $key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists($key, $transformed_entity)) {
|
$entity['task.start_date'] = '';
|
||||||
$entity[$keyval] = $transformed_entity[$key];
|
$entity['task.end_date'] = '';
|
||||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
$entity['task.duration'] = '';
|
||||||
$entity[$keyval] = $transformed_entity[$keyval];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$entity[$keyval] = $this->resolveKey($keyval, $task, $this->entity_transformer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$entity['start_date'] = '';
|
|
||||||
$entity['end_date'] = '';
|
|
||||||
$entity['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->csv->insertOne($entity);
|
$this->storage_array[] = $entity;
|
||||||
} else {
|
} else {
|
||||||
$this->iterateLogs($task, $entity);
|
$this->iterateLogs($task, $entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function iterateLogs(Task $task, array $entity)
|
private function iterateLogs(Task $task, array $entity)
|
||||||
@ -163,39 +171,40 @@ class TaskExport extends BaseExport
|
|||||||
|
|
||||||
foreach ($logs as $key => $item) {
|
foreach ($logs as $key => $item) {
|
||||||
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
|
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
|
||||||
$entity['start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
|
$entity['task.start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
|
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
|
||||||
$entity['end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
|
$entity['task.end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
|
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
|
||||||
$entity['end_date'] = ctrans('texts.is_running');
|
$entity['task.end_date'] = ctrans('texts.is_running');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
|
if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
|
||||||
$entity['duration'] = $task->calcDuration();
|
$entity['task.duration'] = $task->calcDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||||
|
|
||||||
$this->csv->insertOne($entity);
|
$this->storage_array[] = $entity;
|
||||||
|
|
||||||
unset($entity['start_date']);
|
unset($entity['task.start_date']);
|
||||||
unset($entity['end_date']);
|
unset($entity['task.end_date']);
|
||||||
unset($entity['duration']);
|
unset($entity['task.duration']);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function decorateAdvancedFields(Task $task, array $entity) :array
|
private function decorateAdvancedFields(Task $task, array $entity) :array
|
||||||
{
|
{
|
||||||
if (in_array('status_id', $this->input['report_keys'])) {
|
if (in_array('task.status_id', $this->input['report_keys'])) {
|
||||||
$entity['status'] = $task->status()->exists() ? $task->status->name : '';
|
$entity['task.status_id'] = $task->status()->exists() ? $task->status->name : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('project_id', $this->input['report_keys'])) {
|
if (in_array('task.project_id', $this->input['report_keys'])) {
|
||||||
$entity['project'] = $task->project()->exists() ? $task->project->name : '';
|
$entity['task.project_id'] = $task->project()->exists() ? $task->project->name : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -17,6 +17,7 @@ use App\Models\Company;
|
|||||||
use App\Transformers\VendorContactTransformer;
|
use App\Transformers\VendorContactTransformer;
|
||||||
use App\Transformers\VendorTransformer;
|
use App\Transformers\VendorTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
|
||||||
@ -31,46 +32,6 @@ class VendorExport extends BaseExport
|
|||||||
|
|
||||||
public string $date_key = 'created_at';
|
public string $date_key = 'created_at';
|
||||||
|
|
||||||
public array $entity_keys = [
|
|
||||||
'address1' => 'vendor.address1',
|
|
||||||
'address2' => 'vendor.address2',
|
|
||||||
'city' => 'vendor.city',
|
|
||||||
'country' => 'vendor.country_id',
|
|
||||||
'custom_value1' => 'vendor.custom_value1',
|
|
||||||
'custom_value2' => 'vendor.custom_value2',
|
|
||||||
'custom_value3' => 'vendor.custom_value3',
|
|
||||||
'custom_value4' => 'vendor.custom_value4',
|
|
||||||
'id_number' => 'vendor.id_number',
|
|
||||||
'name' => 'vendor.name',
|
|
||||||
'number' => 'vendor.number',
|
|
||||||
'phone' => 'vendor.phone',
|
|
||||||
'postal_code' => 'vendor.postal_code',
|
|
||||||
'private_notes' => 'vendor.private_notes',
|
|
||||||
'public_notes' => 'vendor.public_notes',
|
|
||||||
'state' => 'vendor.state',
|
|
||||||
'vat_number' => 'vendor.vat_number',
|
|
||||||
'website' => 'vendor.website',
|
|
||||||
'currency' => 'vendor.currency',
|
|
||||||
'first_name' => 'vendor_contact.first_name',
|
|
||||||
'last_name' => 'vendor_contact.last_name',
|
|
||||||
'contact_phone' => 'vendor_contact.phone',
|
|
||||||
'contact_custom_value1' => 'vendor_contact.custom_value1',
|
|
||||||
'contact_custom_value2' => 'vendor_contact.custom_value2',
|
|
||||||
'contact_custom_value3' => 'vendor_contact.custom_value3',
|
|
||||||
'contact_custom_value4' => 'vendor_contact.custom_value4',
|
|
||||||
'email' => 'vendor_contact.email',
|
|
||||||
'status' => 'vendor.status'
|
|
||||||
];
|
|
||||||
|
|
||||||
private array $decorate_keys = [
|
|
||||||
'vendor.country_id',
|
|
||||||
'vendor.currency',
|
|
||||||
];
|
|
||||||
|
|
||||||
public array $forced_keys = [
|
|
||||||
// 'vendor.status'
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
@ -79,8 +40,9 @@ class VendorExport extends BaseExport
|
|||||||
$this->contact_transformer = new VendorContactTransformer();
|
$this->contact_transformer = new VendorContactTransformer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run()
|
public function init(): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
App::setLocale($this->company->locale());
|
App::setLocale($this->company->locale());
|
||||||
@ -91,12 +53,9 @@ class VendorExport extends BaseExport
|
|||||||
$this->csv = Writer::createFromString();
|
$this->csv = Writer::createFromString();
|
||||||
|
|
||||||
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->vendor_report_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert the header
|
|
||||||
$this->csv->insertOne($this->buildHeader());
|
|
||||||
|
|
||||||
$query = Vendor::query()->with('contacts')
|
$query = Vendor::query()->with('contacts')
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
@ -104,6 +63,37 @@ class VendorExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function returnJson()
|
||||||
|
{
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
$headerdisplay = $this->buildHeader();
|
||||||
|
|
||||||
|
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||||
|
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$report = $query->cursor()
|
||||||
|
->map(function ($resource) {
|
||||||
|
$row = $this->buildRow($resource);
|
||||||
|
return $this->processMetaData($row, $resource);
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return array_merge(['columns' => $header], $report);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = $this->init();
|
||||||
|
|
||||||
|
//insert the header
|
||||||
|
$this->csv->insertOne($this->buildHeader());
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function ($vendor) {
|
->each(function ($vendor) {
|
||||||
$this->csv->insertOne($this->buildRow($vendor));
|
$this->csv->insertOne($this->buildRow($vendor));
|
||||||
@ -114,7 +104,7 @@ class VendorExport extends BaseExport
|
|||||||
|
|
||||||
private function buildRow(Vendor $vendor) :array
|
private function buildRow(Vendor $vendor) :array
|
||||||
{
|
{
|
||||||
$transformed_contact = [];
|
$transformed_contact = false;
|
||||||
|
|
||||||
$transformed_vendor = $this->vendor_transformer->transform($vendor);
|
$transformed_vendor = $this->vendor_transformer->transform($vendor);
|
||||||
|
|
||||||
@ -127,14 +117,12 @@ class VendorExport extends BaseExport
|
|||||||
foreach (array_values($this->input['report_keys']) as $key) {
|
foreach (array_values($this->input['report_keys']) as $key) {
|
||||||
$parts = explode('.', $key);
|
$parts = explode('.', $key);
|
||||||
|
|
||||||
$keyval = array_search($key, $this->entity_keys);
|
|
||||||
|
|
||||||
if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
|
if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
|
||||||
$entity[$keyval] = $transformed_vendor[$parts[1]];
|
$entity[$key] = $transformed_vendor[$parts[1]];
|
||||||
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && array_key_exists($parts[1], $transformed_contact)) {
|
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
|
||||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
$entity[$key] = $transformed_contact[$parts[1]];
|
||||||
} else {
|
} else {
|
||||||
$entity[$keyval] = '';
|
$entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ class ClientFactory
|
|||||||
$client->is_deleted = 0;
|
$client->is_deleted = 0;
|
||||||
$client->client_hash = Str::random(40);
|
$client->client_hash = Str::random(40);
|
||||||
$client->settings = ClientSettings::defaults();
|
$client->settings = ClientSettings::defaults();
|
||||||
|
$client->classification = '';
|
||||||
|
|
||||||
return $client;
|
return $client;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,9 @@ class RecurringExpenseFactory
|
|||||||
$recurring_expense->tax_amount1 = 0;
|
$recurring_expense->tax_amount1 = 0;
|
||||||
$recurring_expense->tax_amount2 = 0;
|
$recurring_expense->tax_amount2 = 0;
|
||||||
$recurring_expense->tax_amount3 = 0;
|
$recurring_expense->tax_amount3 = 0;
|
||||||
$recurring_expense->date = null;
|
$recurring_expense->date = now()->format('Y-m-d');
|
||||||
|
$recurring_expense->next_send_date = now()->format('Y-m-d');
|
||||||
|
$recurring_expense->next_send_date_client = now()->format('Y-m-d');
|
||||||
$recurring_expense->payment_date = null;
|
$recurring_expense->payment_date = null;
|
||||||
$recurring_expense->amount = 0;
|
$recurring_expense->amount = 0;
|
||||||
$recurring_expense->foreign_amount = 0;
|
$recurring_expense->foreign_amount = 0;
|
||||||
@ -47,6 +49,7 @@ class RecurringExpenseFactory
|
|||||||
$recurring_expense->custom_value4 = '';
|
$recurring_expense->custom_value4 = '';
|
||||||
$recurring_expense->uses_inclusive_taxes = true;
|
$recurring_expense->uses_inclusive_taxes = true;
|
||||||
$recurring_expense->calculate_tax_by_amount = true;
|
$recurring_expense->calculate_tax_by_amount = true;
|
||||||
|
$recurring_expense->remaining_cycles = -1;
|
||||||
|
|
||||||
return $recurring_expense;
|
return $recurring_expense;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ class RecurringExpenseToExpenseFactory
|
|||||||
$expense->tax_amount3 = $recurring_expense->tax_amount3 ?: 0;
|
$expense->tax_amount3 = $recurring_expense->tax_amount3 ?: 0;
|
||||||
$expense->uses_inclusive_taxes = $recurring_expense->uses_inclusive_taxes;
|
$expense->uses_inclusive_taxes = $recurring_expense->uses_inclusive_taxes;
|
||||||
$expense->calculate_tax_by_amount = $recurring_expense->calculate_tax_by_amount;
|
$expense->calculate_tax_by_amount = $recurring_expense->calculate_tax_by_amount;
|
||||||
|
$expense->invoice_currency_id = $recurring_expense->invoice_currency_id;
|
||||||
|
|
||||||
return $expense;
|
return $expense;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ class VendorFactory
|
|||||||
$vendor->country_id = 4;
|
$vendor->country_id = 4;
|
||||||
$vendor->is_deleted = 0;
|
$vendor->is_deleted = 0;
|
||||||
$vendor->vendor_hash = Str::random(40);
|
$vendor->vendor_hash = Str::random(40);
|
||||||
|
$vendor->classification = '';
|
||||||
|
|
||||||
return $vendor;
|
return $vendor;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,11 @@ class CreditFilters extends QueryFilters
|
|||||||
->orWhere('credits.custom_value4', 'like', '%'.$filter.'%')
|
->orWhere('credits.custom_value4', 'like', '%'.$filter.'%')
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,10 @@ class ExpenseFilters extends QueryFilters
|
|||||||
->orWhere('custom_value1', 'like', '%'.$filter.'%')
|
->orWhere('custom_value1', 'like', '%'.$filter.'%')
|
||||||
->orWhere('custom_value2', 'like', '%'.$filter.'%')
|
->orWhere('custom_value2', 'like', '%'.$filter.'%')
|
||||||
->orWhere('custom_value3', 'like', '%'.$filter.'%')
|
->orWhere('custom_value3', 'like', '%'.$filter.'%')
|
||||||
->orWhere('custom_value4', 'like', '%'.$filter.'%');
|
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||||
|
->orWhereHas('category', function ($q) use ($filter) {
|
||||||
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,16 +169,27 @@ class ExpenseFilters extends QueryFilters
|
|||||||
return $this->builder;
|
return $this->builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sort_col[0] == 'client_id') {
|
if ($sort_col[0] == 'client_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||||
return $this->builder->orderBy(\App\Models\Client::select('name')
|
return $this->builder
|
||||||
|
->orderByRaw('ISNULL(client_id), client_id '. $sort_col[1])
|
||||||
|
->orderBy(\App\Models\Client::select('name')
|
||||||
->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
|
->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sort_col[0] == 'vendor_id') {
|
if ($sort_col[0] == 'vendor_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||||
return $this->builder->orderBy(\App\Models\Vendor::select('name')
|
return $this->builder
|
||||||
|
->orderByRaw('ISNULL(vendor_id), vendor_id '. $sort_col[1])
|
||||||
|
->orderBy(\App\Models\Vendor::select('name')
|
||||||
->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
|
->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($sort_col[0] == 'category_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||||
|
return $this->builder
|
||||||
|
->orderByRaw('ISNULL(category_id), category_id '. $sort_col[1])
|
||||||
|
->orderBy(\App\Models\ExpenseCategory::select('name')
|
||||||
|
->whereColumn('expense_categories.id', 'expenses.category_id'), $sort_col[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
|
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
|
||||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
|
@ -116,6 +116,11 @@ class InvoiceFilters extends QueryFilters
|
|||||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -224,6 +229,32 @@ class InvoiceFilters extends QueryFilters
|
|||||||
return $this->builder->where('due_date', '>=', $date);
|
return $this->builder->where('due_date', '>=', $date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function date_range(string $date_range = ''): Builder
|
||||||
|
{
|
||||||
|
$parts = explode(",", $date_range);
|
||||||
|
|
||||||
|
if (count($parts) != 3) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!in_array($parts[0], ['date','due_date'])) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
$start_date = Carbon::parse($parts[1]);
|
||||||
|
$end_date = Carbon::parse($parts[2]);
|
||||||
|
|
||||||
|
return $this->builder->whereBetween($parts[0], [$start_date, $end_date]);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(\Exception $e){
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts the list based on $sort.
|
* Sorts the list based on $sort.
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
namespace App\Filters;
|
namespace App\Filters;
|
||||||
|
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PaymentFilters.
|
* PaymentFilters.
|
||||||
@ -43,6 +45,11 @@ class PaymentFilters extends QueryFilters
|
|||||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -117,6 +124,8 @@ class PaymentFilters extends QueryFilters
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of payments that can be matched to bank transactions
|
* Returns a list of payments that can be matched to bank transactions
|
||||||
|
* @param ?string $value
|
||||||
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public function match_transactions($value = 'true'): Builder
|
public function match_transactions($value = 'true'): Builder
|
||||||
{
|
{
|
||||||
@ -124,7 +133,7 @@ class PaymentFilters extends QueryFilters
|
|||||||
if ($value == 'true') {
|
if ($value == 'true') {
|
||||||
return $this->builder
|
return $this->builder
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->where(function ($query) {
|
->where(function (Builder $query) {
|
||||||
$query->whereNull('transaction_id')
|
$query->whereNull('transaction_id')
|
||||||
->orWhere("transaction_id", "")
|
->orWhere("transaction_id", "")
|
||||||
->company();
|
->company();
|
||||||
@ -169,6 +178,33 @@ class PaymentFilters extends QueryFilters
|
|||||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function date_range(string $date_range = ''): Builder
|
||||||
|
{
|
||||||
|
$parts = explode(",", $date_range);
|
||||||
|
|
||||||
|
if (count($parts) != 3) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!in_array($parts[0], ['date'])) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
$start_date = Carbon::parse($parts[1]);
|
||||||
|
$end_date = Carbon::parse($parts[2]);
|
||||||
|
|
||||||
|
return $this->builder->whereBetween($parts[0], [$start_date, $end_date]);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(\Exception $e){
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the query by the users company ID.
|
* Filters the query by the users company ID.
|
||||||
*
|
*
|
||||||
|
@ -72,8 +72,8 @@ abstract class QueryFilters
|
|||||||
/**
|
/**
|
||||||
* Apply the filters to the builder.
|
* Apply the filters to the builder.
|
||||||
*
|
*
|
||||||
* @param Builder $builder
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
* @return Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
public function apply(Builder $builder)
|
public function apply(Builder $builder)
|
||||||
{
|
{
|
||||||
@ -239,7 +239,11 @@ abstract class QueryFilters
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
public function is_deleted($value = 'true')
|
public function is_deleted($value = 'true')
|
||||||
{
|
{
|
||||||
if ($value == 'true') {
|
if ($value == 'true') {
|
||||||
@ -294,7 +298,7 @@ abstract class QueryFilters
|
|||||||
{
|
{
|
||||||
return $this->builder->where(function ($query) {
|
return $this->builder->where(function ($query) {
|
||||||
$query->whereHas('client', function ($sub_query) {
|
$query->whereHas('client', function ($sub_query) {
|
||||||
$sub_query->where('is_deleted', 0);
|
$sub_query->where('is_deleted', 0)->where('deleted_at', null);
|
||||||
})->orWhere('client_id', null);
|
})->orWhere('client_id', null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -306,7 +310,7 @@ abstract class QueryFilters
|
|||||||
{
|
{
|
||||||
return $this->builder->where(function ($query) {
|
return $this->builder->where(function ($query) {
|
||||||
$query->whereHas('vendor', function ($sub_query) {
|
$query->whereHas('vendor', function ($sub_query) {
|
||||||
$sub_query->where('is_deleted', 0);
|
$sub_query->where('is_deleted', 0)->where('deleted_at', null);
|
||||||
})->orWhere('vendor_id', null);
|
})->orWhere('vendor_id', null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,11 @@ class QuoteFilters extends QueryFilters
|
|||||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,11 @@ class RecurringInvoiceFilters extends QueryFilters
|
|||||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,11 @@ class TaskFilters extends QueryFilters
|
|||||||
})
|
})
|
||||||
->orWhereHas('client', function ($q) use ($filter) {
|
->orWhereHas('client', function ($q) use ($filter) {
|
||||||
$q->where('name', 'like', '%'.$filter.'%');
|
$q->where('name', 'like', '%'.$filter.'%');
|
||||||
|
})
|
||||||
|
->orWhereHas('client.contacts', function ($q) use ($filter) {
|
||||||
|
$q->where('first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('email', 'like', '%'.$filter.'%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,7 @@ class UserFilters extends QueryFilters
|
|||||||
$user_array = $this->transformKeys(explode(',', $user_id));
|
$user_array = $this->transformKeys(explode(',', $user_id));
|
||||||
|
|
||||||
return $this->builder->where(function ($query) use ($user_array) {
|
return $this->builder->where(function ($query) use ($user_array) {
|
||||||
$query->whereNotIn('id', $user_array)
|
$query->whereNotIn('id', $user_array);
|
||||||
->where('account_id', auth()->user()->account_id);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
111
app/Helpers/Bank/Yodlee/DTO/AccountSummary.php
Normal file
111
app/Helpers/Bank/Yodlee/DTO/AccountSummary.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?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\Helpers\Bank\Yodlee\DTO;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
|
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [
|
||||||
|
"account": [
|
||||||
|
[
|
||||||
|
"CONTAINER": "bank",
|
||||||
|
"providerAccountId": 1005,
|
||||||
|
"accountName": "Business Acct",
|
||||||
|
"accountStatus": "ACTIVE",
|
||||||
|
"accountNumber": "1011",
|
||||||
|
"aggregationSource": "USER",
|
||||||
|
"isAsset": true,
|
||||||
|
"balance": [
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 304.98,
|
||||||
|
],
|
||||||
|
"id": 10139315,
|
||||||
|
"includeInNetWorth": true,
|
||||||
|
"providerId": "3857",
|
||||||
|
"providerName": "Bank",
|
||||||
|
"isManual": false,
|
||||||
|
"availableBalance": {#2966
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 304.98,
|
||||||
|
],
|
||||||
|
"currentBalance": [
|
||||||
|
"currency": "AUD",
|
||||||
|
"amount": 3044.98,
|
||||||
|
],
|
||||||
|
"accountType": "CHECKING",
|
||||||
|
"displayedName": "after David",
|
||||||
|
"createdDate": "2023-01-10T08:29:07Z",
|
||||||
|
"classification": "SMALL_BUSINESS",
|
||||||
|
"lastUpdated": "2023-08-01T23:50:13Z",
|
||||||
|
"nickname": "Business ",
|
||||||
|
"bankTransferCode": [
|
||||||
|
[
|
||||||
|
"id": "062",
|
||||||
|
"type": "BSB",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"dataset": [
|
||||||
|
[
|
||||||
|
"name": "BASIC_AGG_DATA",
|
||||||
|
"additionalStatus": "AVAILABLE_DATA_RETRIEVED",
|
||||||
|
"updateEligibility": "ALLOW_UPDATE",
|
||||||
|
"lastUpdated": "2023-08-01T23:49:53Z",
|
||||||
|
"lastUpdateAttempt": "2023-08-01T23:49:53Z",
|
||||||
|
"nextUpdateScheduled": "2023-08-03T14:45:14Z",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
class AccountSummary extends Data
|
||||||
|
{
|
||||||
|
public ?int $id;
|
||||||
|
|
||||||
|
#[MapInputName('CONTAINER')]
|
||||||
|
public ?string $account_type = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountName')]
|
||||||
|
public ?string $account_name = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountStatus')]
|
||||||
|
public ?string $account_status = '';
|
||||||
|
|
||||||
|
#[MapInputName('accountNumber')]
|
||||||
|
public ?string $account_number = '';
|
||||||
|
|
||||||
|
#[MapInputName('providerAccountId')]
|
||||||
|
public int $provider_account_id;
|
||||||
|
|
||||||
|
#[MapInputName('providerId')]
|
||||||
|
public ?string $provider_id = '';
|
||||||
|
|
||||||
|
#[MapInputName('providerName')]
|
||||||
|
public ?string $provider_name = '';
|
||||||
|
|
||||||
|
public ?string $nickname = '';
|
||||||
|
|
||||||
|
public ?float $current_balance = 0;
|
||||||
|
public ?string $account_currency = '';
|
||||||
|
|
||||||
|
public static function prepareForPipeline(Collection $properties) : Collection
|
||||||
|
{
|
||||||
|
|
||||||
|
$properties->put('current_balance', $properties['currentBalance']['amount'] ?? 0);
|
||||||
|
$properties->put('account_currency', $properties['currentBalance']['currency'] ?? 0);
|
||||||
|
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
}
|
@ -64,6 +64,7 @@ use App\Helpers\Bank\AccountTransformerInterface;
|
|||||||
|
|
||||||
class AccountTransformer implements AccountTransformerInterface
|
class AccountTransformer implements AccountTransformerInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
public function transform($yodlee_account)
|
public function transform($yodlee_account)
|
||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
@ -93,13 +94,54 @@ class AccountTransformer implements AccountTransformerInterface
|
|||||||
$account_currency = $account->balance->currency ?? '';
|
$account_currency = $account->balance->currency ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$account_status = $account->accountStatus;
|
||||||
|
|
||||||
|
if(property_exists($account, 'dataset')){
|
||||||
|
$dataset = $account->dataset[0];
|
||||||
|
$status = false;
|
||||||
|
$update = false;
|
||||||
|
|
||||||
|
match($dataset->additionalStatus ?? ''){
|
||||||
|
'LOGIN_IN_PROGRESS' => $status = 'Data retrieval in progress.',
|
||||||
|
'USER_INPUT_REQUIRED' => $status = 'Please reconnect your account, authentication required.',
|
||||||
|
'LOGIN_SUCCESS' => $status = 'Data retrieval in progress',
|
||||||
|
'ACCOUNT_SUMMARY_RETRIEVED' => $status = 'Account summary retrieval in progress.',
|
||||||
|
'NEVER_INITIATED' => $status = 'Upstream working on connecting to your account.',
|
||||||
|
'LOGIN_FAILED' => $status = 'Authentication failed, please try reauthenticating.',
|
||||||
|
'REQUEST_TIME_OUT' => $status = 'Timeout encountered retrieving data.',
|
||||||
|
'DATA_RETRIEVAL_FAILED' => $status = 'Login successful, but data retrieval failed.',
|
||||||
|
'PARTIAL_DATA_RETRIEVED' => $status = 'Partial data update failed.',
|
||||||
|
'PARTIAL_DATA_RETRIEVED_REM_SCHED' => $status = 'Partial data update failed.',
|
||||||
|
'SUCCESS' => $status = 'All accounts added or updated successfully.',
|
||||||
|
default => $status = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if($status){
|
||||||
|
$account_status = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
match($dataset->updateEligibility ?? ''){
|
||||||
|
'ALLOW_UPDATE' => $update = 'Account connection stable.',
|
||||||
|
'ALLOW_UPDATE_WITH_CREDENTIALS' => $update = 'Please reconnect your account with updated credentials.',
|
||||||
|
'DISALLOW_UPDATE' => $update = 'Update not available due to technical issues.',
|
||||||
|
default => $update = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if($status && $update){
|
||||||
|
$account_status = $status . ' - ' . $update;
|
||||||
|
}
|
||||||
|
elseif($update){
|
||||||
|
$account_status = $update;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $account->id,
|
'id' => $account->id,
|
||||||
'account_type' => $account->CONTAINER,
|
'account_type' => $account->CONTAINER,
|
||||||
// 'account_name' => $account->accountName,
|
// 'account_name' => $account->accountName,
|
||||||
'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
|
'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
|
||||||
'account_status' => $account->accountStatus,
|
'account_status' => $account_status,
|
||||||
'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
|
'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
|
||||||
'provider_account_id' => $account->providerAccountId,
|
'provider_account_id' => $account->providerAccountId,
|
||||||
'provider_id' => $account->providerId,
|
'provider_id' => $account->providerId,
|
||||||
|
@ -297,4 +297,71 @@ class Yodlee
|
|||||||
'secret' => $this->client_secret,
|
'secret' => $this->client_secret,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updateEligibility
|
||||||
|
*
|
||||||
|
* ALLOW_UPDATE
|
||||||
|
* ALLOW_UPDATE_WITH_CREDENTIALS
|
||||||
|
* DISALLOW_UPDATE
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* additionalStatus
|
||||||
|
*
|
||||||
|
* LOGIN_IN_PROGRESS
|
||||||
|
* DATA_RETRIEVAL_IN_PROGRESS
|
||||||
|
* ACCT_SUMMARY_RECEIVED
|
||||||
|
* AVAILABLE_DATA_RETRIEVED
|
||||||
|
* PARTIAL_DATA_RETRIEVED
|
||||||
|
* DATA_RETRIEVAL_FAILED
|
||||||
|
* DATA_NOT_AVAILABLE
|
||||||
|
* ACCOUNT_LOCKED
|
||||||
|
* ADDL_AUTHENTICATION_REQUIRED
|
||||||
|
* BETA_SITE_DEV_IN_PROGRESS
|
||||||
|
* CREDENTIALS_UPDATE_NEEDED
|
||||||
|
* INCORRECT_CREDENTIALS
|
||||||
|
* PROPERTY_VALUE_NOT_AVAILABLE
|
||||||
|
* INVALID_ADDL_INFO_PROVIDED
|
||||||
|
* REQUEST_TIME_OUT
|
||||||
|
* SITE_BLOCKING_ERROR
|
||||||
|
* UNEXPECTED_SITE_ERROR
|
||||||
|
* SITE_NOT_SUPPORTED
|
||||||
|
* SITE_UNAVAILABLE
|
||||||
|
* TECH_ERROR
|
||||||
|
* USER_ACTION_NEEDED_AT_SITE
|
||||||
|
* SITE_SESSION_INVALIDATED
|
||||||
|
* NEW_AUTHENTICATION_REQUIRED
|
||||||
|
* DATASET_NOT_SUPPORTED
|
||||||
|
* ENROLLMENT_REQUIRED_FOR_DATASET
|
||||||
|
* CONSENT_REQUIRED
|
||||||
|
* CONSENT_EXPIRED
|
||||||
|
* CONSENT_REVOKED
|
||||||
|
* INCORRECT_OAUTH_TOKEN
|
||||||
|
* MIGRATION_IN_PROGRESS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IN_PROGRESS LOGIN_IN_PROGRESS Provider login is in progress.
|
||||||
|
* IN_PROGRESS USER_INPUT_REQUIRED Provider site requires MFA-based authentication and needs user input for login.
|
||||||
|
* IN_PROGRESS LOGIN_SUCCESS Provider login is successful.
|
||||||
|
* IN_PROGRESS ACCOUNT_SUMMARY_RETRIEVED Account summary info may not have the complete info of accounts that are available in the provider site. This depends on the sites behaviour. Account summary info may not be available at all times.
|
||||||
|
* FAILED NEVER_INITIATED The add or update provider account was not triggered due to techincal reasons. This is a rare occurrence and usually resolves quickly.
|
||||||
|
* FAILED LOGIN_FAILED Provider login failed.
|
||||||
|
* FAILED REQUEST_TIME_OUT The process timed out.
|
||||||
|
* FAILED DATA_RETRIEVAL_FAILED All accounts under the provider account failed with same or different errors, though login was successful.
|
||||||
|
* FAILED No additional status or information will be provided when there are errors other than the ones listed above.
|
||||||
|
* PARTIAL_SUCCESS PARTIAL_DATA_RETRIEVED DATA_RETRIEVAL_FAILED_PARTIALLY One/few accounts data gathered and one/few accounts failed.
|
||||||
|
* PARTIAL_SUCCESS PARTIAL_DATA_RETRIEVED_REM_SCHED DATA_RETRIEVAL_FAILED_PARTIALLY One/few accounts data gathered One/few accounts failed
|
||||||
|
* SUCCESS All accounts under the provider was added or updated successfully.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updateEligibility
|
||||||
|
*
|
||||||
|
* ALLOW_UPDATE The status indicates that the account is eligible for the next update and applies to both MFA and non-MFA accounts. For MFA-based accounts, the user may have to provide the MFA details during account refresh.
|
||||||
|
* ALLOW_UPDATE_WITH_CREDENTIALS The status indicates updating or refreshing the account by directing the user to edit the provided credentials.
|
||||||
|
* DISALLOW_UPDATE The status indicates the account is not eligible for the update or refresh process due to a site issue or a technical error.
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ class InvoiceItemSum
|
|||||||
|
|
||||||
private function push(): self
|
private function push(): self
|
||||||
{
|
{
|
||||||
$this->sub_total += $this->getLineTotal();
|
$this->sub_total += round($this->getLineTotal(), $this->currency->precision);
|
||||||
|
|
||||||
$this->gross_sub_total += $this->getGrossLineTotal();
|
$this->gross_sub_total += $this->getGrossLineTotal();
|
||||||
|
|
||||||
@ -391,15 +391,15 @@ class InvoiceItemSum
|
|||||||
{
|
{
|
||||||
$this->setGroupedTaxes(collect([]));
|
$this->setGroupedTaxes(collect([]));
|
||||||
|
|
||||||
$item_tax = 0;
|
foreach ($this->line_items as $key => $this->item) {
|
||||||
|
|
||||||
foreach ($this->line_items as $this->item) {
|
|
||||||
if ($this->item->line_total == 0) {
|
if ($this->item->line_total == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$item_tax = 0;
|
||||||
|
|
||||||
//$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
|
//$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
|
||||||
$amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total)) : 0;
|
$amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->invoice->discount * ( $this->item->line_total / $this->sub_total)) : 0;
|
||||||
|
|
||||||
$item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
|
$item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
|
||||||
|
|
||||||
@ -424,9 +424,19 @@ class InvoiceItemSum
|
|||||||
if ($item_tax_rate3_total != 0) {
|
if ($item_tax_rate3_total != 0) {
|
||||||
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
|
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->item->gross_line_total = $this->getLineTotal() + $item_tax;
|
||||||
|
$this->item->tax_amount = $item_tax;
|
||||||
|
|
||||||
|
$this->line_items[$key] = $this->item;
|
||||||
|
|
||||||
|
$this->setTotalTaxes($this->getTotalTaxes() + $item_tax);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setTotalTaxes($item_tax);
|
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ class InvoiceItemSumInclusive
|
|||||||
|
|
||||||
protected RecurringInvoice | Invoice | Quote | Credit | PurchaseOrder | RecurringQuote $invoice;
|
protected RecurringInvoice | Invoice | Quote | Credit | PurchaseOrder | RecurringQuote $invoice;
|
||||||
|
|
||||||
private $currency;
|
private \App\Models\Currency $currency;
|
||||||
|
|
||||||
private $total_taxes;
|
private $total_taxes;
|
||||||
|
|
||||||
@ -226,8 +226,10 @@ class InvoiceItemSumInclusive
|
|||||||
|
|
||||||
$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / 100));
|
$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / 100));
|
||||||
|
|
||||||
|
/** @var float $item_tax_rate1_total */
|
||||||
$item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
|
$item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
|
||||||
|
|
||||||
|
/** @var float $item_tax */
|
||||||
$item_tax += $this->formatValue($item_tax_rate1_total, $this->currency->precision);
|
$item_tax += $this->formatValue($item_tax_rate1_total, $this->currency->precision);
|
||||||
|
|
||||||
if (strlen($this->item->tax_name1) > 1) {
|
if (strlen($this->item->tax_name1) > 1) {
|
||||||
@ -347,15 +349,17 @@ class InvoiceItemSumInclusive
|
|||||||
{
|
{
|
||||||
$this->setGroupedTaxes(collect([]));
|
$this->setGroupedTaxes(collect([]));
|
||||||
|
|
||||||
$item_tax = 0;
|
|
||||||
|
|
||||||
foreach ($this->line_items as $this->item) {
|
foreach ($this->line_items as $this->item) {
|
||||||
if ($this->sub_total == 0) {
|
if ($this->sub_total == 0) {
|
||||||
$amount = $this->item->line_total;
|
$amount = $this->item->line_total;
|
||||||
} else {
|
} else {
|
||||||
$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
|
$amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->invoice->discount * ($this->item->line_total / $this->sub_total)) : 0;
|
||||||
|
// $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$item_tax = 0;
|
||||||
|
|
||||||
$item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
|
$item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
|
||||||
|
|
||||||
$item_tax += $item_tax_rate1_total;
|
$item_tax += $item_tax_rate1_total;
|
||||||
@ -379,9 +383,17 @@ class InvoiceItemSumInclusive
|
|||||||
if ($item_tax_rate3_total != 0) {
|
if ($item_tax_rate3_total != 0) {
|
||||||
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
|
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setTotalTaxes($this->getTotalTaxes() + $item_tax);
|
||||||
|
$this->item->gross_line_total = $this->getLineTotal();
|
||||||
|
|
||||||
|
$this->item->tax_amount = $item_tax;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setTotalTaxes($item_tax);
|
return $this;
|
||||||
|
|
||||||
|
// $this->setTotalTaxes($item_tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,8 +308,9 @@ class InvoiceSum
|
|||||||
|
|
||||||
public function setTaxMap(): self
|
public function setTaxMap(): self
|
||||||
{
|
{
|
||||||
if ($this->invoice->is_amount_discount == true) {
|
if ($this->invoice->is_amount_discount) {
|
||||||
$this->invoice_items->calcTaxesWithAmountDiscount();
|
$this->invoice_items->calcTaxesWithAmountDiscount();
|
||||||
|
$this->invoice->line_items = $this->invoice_items->getLineItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tax_map = collect();
|
$this->tax_map = collect();
|
||||||
@ -327,8 +328,6 @@ class InvoiceSum
|
|||||||
return $value['key'] == $key;
|
return $value['key'] == $key;
|
||||||
})->sum('total');
|
})->sum('total');
|
||||||
|
|
||||||
//$total_line_tax -= $this->discount($total_line_tax);
|
|
||||||
|
|
||||||
$this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
|
$this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
|
||||||
|
|
||||||
$this->total_taxes += $total_line_tax;
|
$this->total_taxes += $total_line_tax;
|
||||||
@ -377,16 +376,6 @@ class InvoiceSum
|
|||||||
|
|
||||||
public function purgeTaxes(): self
|
public function purgeTaxes(): self
|
||||||
{
|
{
|
||||||
// $this->tax_rate1 = 0;
|
|
||||||
// $this->tax_name1 = '';
|
|
||||||
|
|
||||||
// $this->tax_rate2 = 0;
|
|
||||||
// $this->tax_name2 = '';
|
|
||||||
|
|
||||||
// $this->tax_rate3 = 0;
|
|
||||||
// $this->tax_name3 = '';
|
|
||||||
|
|
||||||
// $this->discount = 0;
|
|
||||||
|
|
||||||
$line_items = collect($this->invoice->line_items);
|
$line_items = collect($this->invoice->line_items);
|
||||||
|
|
||||||
|
@ -315,8 +315,9 @@ class InvoiceSumInclusive
|
|||||||
|
|
||||||
public function setTaxMap()
|
public function setTaxMap()
|
||||||
{
|
{
|
||||||
if ($this->invoice->is_amount_discount == true) {
|
if ($this->invoice->is_amount_discount) {
|
||||||
$this->invoice_items->calcTaxesWithAmountDiscount();
|
$this->invoice_items->calcTaxesWithAmountDiscount();
|
||||||
|
$this->invoice->line_items = $this->invoice_items->getLineItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tax_map = collect();
|
$this->tax_map = collect();
|
||||||
|
@ -33,6 +33,7 @@ class GmailTransport extends AbstractTransport
|
|||||||
nlog("In Do Send");
|
nlog("In Do Send");
|
||||||
$message = MessageConverter::toEmail($message->getOriginalMessage());
|
$message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||||
|
|
||||||
|
/** @phpstan-ignore-next-line **/
|
||||||
$token = $message->getHeaders()->get('gmailtoken')->getValue();
|
$token = $message->getHeaders()->get('gmailtoken')->getValue();
|
||||||
$message->getHeaders()->remove('gmailtoken');
|
$message->getHeaders()->remove('gmailtoken');
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ class GmailTransport extends AbstractTransport
|
|||||||
if ($bccs) {
|
if ($bccs) {
|
||||||
$bcc_list = 'Bcc: ';
|
$bcc_list = 'Bcc: ';
|
||||||
|
|
||||||
|
|
||||||
|
/** @phpstan-ignore-next-line **/
|
||||||
foreach ($bccs->getAddresses() as $address) {
|
foreach ($bccs->getAddresses() as $address) {
|
||||||
$bcc_list .= $address->getAddress() .',';
|
$bcc_list .= $address->getAddress() .',';
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ class Office365MailTransport extends AbstractTransport
|
|||||||
$symfony_message = MessageConverter::toEmail($message->getOriginalMessage());
|
$symfony_message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||||
|
|
||||||
$graph = new Graph();
|
$graph = new Graph();
|
||||||
|
|
||||||
|
/** @phpstan-ignore-next-line **/
|
||||||
$token = $symfony_message->getHeaders()->get('gmailtoken')->getValue();
|
$token = $symfony_message->getHeaders()->get('gmailtoken')->getValue();
|
||||||
$symfony_message->getHeaders()->remove('gmailtoken');
|
$symfony_message->getHeaders()->remove('gmailtoken');
|
||||||
|
|
||||||
@ -38,6 +40,8 @@ class Office365MailTransport extends AbstractTransport
|
|||||||
$bcc_list = '';
|
$bcc_list = '';
|
||||||
|
|
||||||
if ($bccs) {
|
if ($bccs) {
|
||||||
|
|
||||||
|
/** @phpstan-ignore-next-line **/
|
||||||
foreach ($bccs->getAddresses() as $address) {
|
foreach ($bccs->getAddresses() as $address) {
|
||||||
$bcc_list .= 'Bcc: "'.$address->getAddress().'" <'.$address->getAddress().'>\r\n';
|
$bcc_list .= 'Bcc: "'.$address->getAddress().'" <'.$address->getAddress().'>\r\n';
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class SubscriptionCalculator
|
|||||||
*/
|
*/
|
||||||
public function isPaidUp() :bool
|
public function isPaidUp() :bool
|
||||||
{
|
{
|
||||||
$outstanding_invoices_exist = Invoice::whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
$outstanding_invoices_exist = Invoice::query()->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||||
->where('subscription_id', $this->invoice->subscription_id)
|
->where('subscription_id', $this->invoice->subscription_id)
|
||||||
->where('client_id', $this->invoice->client_id)
|
->where('client_id', $this->invoice->client_id)
|
||||||
->where('balance', '>', 0)
|
->where('balance', '>', 0)
|
||||||
|
@ -72,7 +72,7 @@ class AccountController extends BaseController
|
|||||||
|
|
||||||
MultiDB::findAndSetDbByAccountKey($account->key);
|
MultiDB::findAndSetDbByAccountKey($account->key);
|
||||||
|
|
||||||
$cu = CompanyUser::where('user_id', $account->users()->first()->id);
|
$cu = CompanyUser::query()->where('user_id', $account->users()->first()->id);
|
||||||
|
|
||||||
$company_user = $cu->first();
|
$company_user = $cu->first();
|
||||||
|
|
||||||
|
@ -418,10 +418,12 @@ class LoginController extends BaseController
|
|||||||
->setReturnType(Model\User::class)
|
->setReturnType(Model\User::class)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
nlog($user);
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$account = request()->input('account');
|
$account = request()->input('account');
|
||||||
|
|
||||||
$email = $user->getMail() ?: $user->getUserPrincipalName();
|
$email = $user->getUserPrincipalName() ?? false;
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
'oauth_user_id' => $user->getId(),
|
'oauth_user_id' => $user->getId(),
|
||||||
@ -436,8 +438,8 @@ class LoginController extends BaseController
|
|||||||
return $this->existingOauthUser($existing_user);
|
return $this->existingOauthUser($existing_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If this is a result user/email combo - lets add their OAuth details details
|
// If this is a result user/email combo - lets add their OAuth details details
|
||||||
if ($existing_login_user = MultiDB::hasUser(['email' => $email])) {
|
if ($email && $existing_login_user = MultiDB::hasUser(['email' => $email])) {
|
||||||
if (!$existing_login_user->account) {
|
if (!$existing_login_user->account) {
|
||||||
return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
|
return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
|
||||||
}
|
}
|
||||||
@ -447,7 +449,6 @@ class LoginController extends BaseController
|
|||||||
return $this->existingLoginUser($user->getId(), 'microsoft');
|
return $this->existingLoginUser($user->getId(), 'microsoft');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Signup!
|
// Signup!
|
||||||
if (request()->has('create') && request()->input('create') == 'true') {
|
if (request()->has('create') && request()->input('create') == 'true') {
|
||||||
$new_account = [
|
$new_account = [
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Bank;
|
namespace App\Http\Controllers\Bank;
|
||||||
|
|
||||||
|
use App\Helpers\Bank\Yodlee\DTO\AccountSummary;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\BankIntegration;
|
||||||
use App\Helpers\Bank\Yodlee\Yodlee;
|
use App\Helpers\Bank\Yodlee\Yodlee;
|
||||||
use App\Http\Controllers\BaseController;
|
use App\Http\Controllers\BaseController;
|
||||||
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
|
||||||
use App\Jobs\Bank\ProcessBankTransactions;
|
use App\Jobs\Bank\ProcessBankTransactions;
|
||||||
use App\Models\BankIntegration;
|
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
||||||
use Illuminate\Http\Request;
|
use App\Http\Requests\Yodlee\YodleeAdminRequest;
|
||||||
|
|
||||||
class YodleeController extends BaseController
|
class YodleeController extends BaseController
|
||||||
{
|
{
|
||||||
@ -277,4 +279,27 @@ class YodleeController extends BaseController
|
|||||||
|
|
||||||
// return response()->json(['message' => 'Unauthorized'], 403);
|
// return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function accountStatus(YodleeAdminRequest $request, $account_number)
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$bank_integration = BankIntegration::query()
|
||||||
|
->withTrashed()
|
||||||
|
->where('company_id', $user->company()->id)
|
||||||
|
->where('account_id', $account_number)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if(!$bank_integration)
|
||||||
|
return response()->json(['message' => 'Account does not exist.'], 400);
|
||||||
|
|
||||||
|
$yodlee = new Yodlee($user->account->bank_integration_account_id);
|
||||||
|
|
||||||
|
$summary = $yodlee->getAccountSummary($account_number);
|
||||||
|
|
||||||
|
$transformed_summary = AccountSummary::from($summary[0]);
|
||||||
|
|
||||||
|
return response()->json($transformed_summary, 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,15 +71,21 @@ class BankTransactionController extends BaseController
|
|||||||
|
|
||||||
public function create(CreateBankTransactionRequest $request)
|
public function create(CreateBankTransactionRequest $request)
|
||||||
{
|
{
|
||||||
$bank_transaction = BankTransactionFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$bank_transaction = BankTransactionFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($bank_transaction);
|
return $this->itemResponse($bank_transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(StoreBankTransactionRequest $request)
|
public function store(StoreBankTransactionRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
//stub to store the model
|
//stub to store the model
|
||||||
$bank_transaction = $this->bank_transaction_repo->save($request->all(), BankTransactionFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
$bank_transaction = $this->bank_transaction_repo->save($request->all(), BankTransactionFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
return $this->itemResponse($bank_transaction);
|
return $this->itemResponse($bank_transaction);
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use App\Models\BankTransactionRule;
|
use App\Models\BankTransactionRule;
|
||||||
use App\Filters\BankTransactionFilters;
|
|
||||||
use App\Factory\BankTransactionRuleFactory;
|
use App\Factory\BankTransactionRuleFactory;
|
||||||
use App\Filters\BankTransactionRuleFilters;
|
use App\Filters\BankTransactionRuleFilters;
|
||||||
use App\Repositories\BankTransactionRuleRepository;
|
use App\Repositories\BankTransactionRuleRepository;
|
||||||
@ -26,6 +24,7 @@ use App\Http\Requests\BankTransactionRule\StoreBankTransactionRuleRequest;
|
|||||||
use App\Http\Requests\BankTransactionRule\CreateBankTransactionRuleRequest;
|
use App\Http\Requests\BankTransactionRule\CreateBankTransactionRuleRequest;
|
||||||
use App\Http\Requests\BankTransactionRule\UpdateBankTransactionRuleRequest;
|
use App\Http\Requests\BankTransactionRule\UpdateBankTransactionRuleRequest;
|
||||||
use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest;
|
use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest;
|
||||||
|
use App\Services\Bank\BankMatchingService;
|
||||||
|
|
||||||
class BankTransactionRuleController extends BaseController
|
class BankTransactionRuleController extends BaseController
|
||||||
{
|
{
|
||||||
@ -256,8 +255,12 @@ class BankTransactionRuleController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule)
|
public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule)
|
||||||
{
|
{
|
||||||
//stubs for updating the model
|
/** @var \App\Models\User $user */
|
||||||
$bank_transaction = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule);
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule);
|
||||||
|
|
||||||
|
BankMatchingService::dispatch($user->company()->id, $user->company()->db);
|
||||||
|
|
||||||
return $this->itemResponse($bank_transaction_rule->fresh());
|
return $this->itemResponse($bank_transaction_rule->fresh());
|
||||||
}
|
}
|
||||||
@ -304,6 +307,7 @@ class BankTransactionRuleController extends BaseController
|
|||||||
{
|
{
|
||||||
/** @var \App\Models\User $user **/
|
/** @var \App\Models\User $user **/
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id);
|
$bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($bank_transaction_rule);
|
return $this->itemResponse($bank_transaction_rule);
|
||||||
@ -355,6 +359,8 @@ class BankTransactionRuleController extends BaseController
|
|||||||
|
|
||||||
$bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), BankTransactionRuleFactory::create($user->company()->id, $user->id));
|
$bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), BankTransactionRuleFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
|
BankMatchingService::dispatch($user->company()->id, $user->company()->db);
|
||||||
|
|
||||||
return $this->itemResponse($bank_transaction_rule);
|
return $this->itemResponse($bank_transaction_rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,9 +530,8 @@ class BaseController extends Controller
|
|||||||
|
|
||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line */
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection(); /** @phpstan-ignore-line */
|
$query = $paginator->getCollection();
|
||||||
|
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
|
|
||||||
@ -636,7 +635,7 @@ class BaseController extends Controller
|
|||||||
|
|
||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line */
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection();
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
@ -885,7 +884,7 @@ class BaseController extends Controller
|
|||||||
|
|
||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line */
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection();
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
@ -1066,7 +1065,7 @@ class BaseController extends Controller
|
|||||||
$data = $this->first_load;
|
$data = $this->first_load;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$included = request()->input('include');
|
$included = request()->input('include', '');
|
||||||
$included = explode(',', $included);
|
$included = explode(',', $included);
|
||||||
|
|
||||||
foreach ($included as $include) {
|
foreach ($included as $include) {
|
||||||
|
@ -11,30 +11,31 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Client\ClientWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Client\ClientWasUpdated;
|
use App\Models\Client;
|
||||||
|
use App\Models\Account;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use App\Factory\ClientFactory;
|
use App\Factory\ClientFactory;
|
||||||
use App\Filters\ClientFilters;
|
use App\Filters\ClientFilters;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Jobs\Client\UpdateTaxData;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Repositories\ClientRepository;
|
||||||
|
use App\Events\Client\ClientWasCreated;
|
||||||
|
use App\Events\Client\ClientWasUpdated;
|
||||||
|
use App\Transformers\ClientTransformer;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use App\Http\Requests\Client\BulkClientRequest;
|
use App\Http\Requests\Client\BulkClientRequest;
|
||||||
use App\Http\Requests\Client\CreateClientRequest;
|
|
||||||
use App\Http\Requests\Client\DestroyClientRequest;
|
|
||||||
use App\Http\Requests\Client\EditClientRequest;
|
use App\Http\Requests\Client\EditClientRequest;
|
||||||
use App\Http\Requests\Client\PurgeClientRequest;
|
|
||||||
use App\Http\Requests\Client\ShowClientRequest;
|
use App\Http\Requests\Client\ShowClientRequest;
|
||||||
|
use App\Http\Requests\Client\PurgeClientRequest;
|
||||||
use App\Http\Requests\Client\StoreClientRequest;
|
use App\Http\Requests\Client\StoreClientRequest;
|
||||||
|
use App\Http\Requests\Client\CreateClientRequest;
|
||||||
use App\Http\Requests\Client\UpdateClientRequest;
|
use App\Http\Requests\Client\UpdateClientRequest;
|
||||||
use App\Http\Requests\Client\UploadClientRequest;
|
use App\Http\Requests\Client\UploadClientRequest;
|
||||||
use App\Models\Account;
|
use App\Http\Requests\Client\DestroyClientRequest;
|
||||||
use App\Models\Client;
|
|
||||||
use App\Repositories\ClientRepository;
|
|
||||||
use App\Transformers\ClientTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\BulkOptions;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use App\Utils\Traits\Uploadable;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ClientController.
|
* Class ClientController.
|
||||||
@ -227,7 +228,7 @@ class ClientController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $client);
|
$this->saveDocuments($request->file('documents'), $client, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($client->fresh());
|
return $this->itemResponse($client->fresh());
|
||||||
@ -285,4 +286,18 @@ class ClientController extends BaseController
|
|||||||
|
|
||||||
return $this->itemResponse($merged_client);
|
return $this->itemResponse($merged_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the client's tax data
|
||||||
|
*
|
||||||
|
* @param PurgeClientRequest $request
|
||||||
|
* @param Client $client
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function updateTaxData(PurgeClientRequest $request, Client $client)
|
||||||
|
{
|
||||||
|
(new UpdateTaxData($client, $client->company))->handle();
|
||||||
|
|
||||||
|
return $this->itemResponse($client->fresh());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ class ApplePayDomainController extends Controller
|
|||||||
/* Self Host */
|
/* Self Host */
|
||||||
|
|
||||||
if (Ninja::isSelfHost()) {
|
if (Ninja::isSelfHost()) {
|
||||||
$cgs = CompanyGateway::whereIn('gateway_key', $this->stripe_keys)
|
$cgs = CompanyGateway::query()
|
||||||
|
->whereIn('gateway_key', $this->stripe_keys)
|
||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ class CreditController extends Controller
|
|||||||
{
|
{
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
$invitation = $credit->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
// $invitation = $credit->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
||||||
|
$invitation = $credit->invitations()->where('client_contact_id', auth()->guard('contact')->user()->id)->first();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'credit' => $credit,
|
'credit' => $credit,
|
||||||
|
@ -71,7 +71,7 @@ class DocumentController extends Controller
|
|||||||
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
|
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection<Document> $documents **/
|
/** @var \Illuminate\Database\Eloquent\Collection<Document> $documents **/
|
||||||
$documents = Document::whereIn('id', $this->transformKeys($request->file_hash))
|
$documents = Document::query()->whereIn('id', $this->transformKeys($request->file_hash))
|
||||||
->where('company_id', auth()->guard('contact')->user()->company_id)
|
->where('company_id', auth()->guard('contact')->user()->company_id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ use Illuminate\Support\Facades\Hash;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EntityViewController
|
||||||
|
* @deprecated 5.7 ?
|
||||||
|
*/
|
||||||
class EntityViewController extends Controller
|
class EntityViewController extends Controller
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
@ -11,26 +11,27 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Events\Credit\CreditWasViewed;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Invoice\InvoiceWasViewed;
|
use App\Models\Client;
|
||||||
use App\Events\Misc\InvitationWasViewed;
|
use App\Models\Payment;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\QuoteInvitation;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Models\CreditInvitation;
|
||||||
|
use App\Utils\Traits\MakesDates;
|
||||||
|
use App\Jobs\Entity\CreateRawPdf;
|
||||||
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Events\Quote\QuoteWasViewed;
|
use App\Events\Quote\QuoteWasViewed;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Jobs\Entity\CreateRawPdf;
|
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\ClientContact;
|
|
||||||
use App\Models\CreditInvitation;
|
|
||||||
use App\Models\InvoiceInvitation;
|
|
||||||
use App\Models\Payment;
|
|
||||||
use App\Models\PurchaseOrderInvitation;
|
|
||||||
use App\Models\QuoteInvitation;
|
|
||||||
use App\Services\ClientPortal\InstantPayment;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesDates;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Str;
|
use App\Events\Credit\CreditWasViewed;
|
||||||
|
use App\Events\Contact\ContactLoggedIn;
|
||||||
|
use App\Models\PurchaseOrderInvitation;
|
||||||
|
use App\Events\Invoice\InvoiceWasViewed;
|
||||||
|
use App\Events\Misc\InvitationWasViewed;
|
||||||
|
use App\Services\ClientPortal\InstantPayment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvitationController.
|
* Class InvitationController.
|
||||||
@ -94,6 +95,7 @@ class InvitationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$client_contact = $invitation->contact;
|
$client_contact = $invitation->contact;
|
||||||
|
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars()));
|
||||||
|
|
||||||
if (empty($client_contact->email)) {
|
if (empty($client_contact->email)) {
|
||||||
$client_contact->email = Str::random(15) . "@example.com";
|
$client_contact->email = Str::random(15) . "@example.com";
|
||||||
|
@ -87,14 +87,19 @@ class InvoiceController extends Controller
|
|||||||
public function showBlob($hash)
|
public function showBlob($hash)
|
||||||
{
|
{
|
||||||
$data = Cache::get($hash);
|
$data = Cache::get($hash);
|
||||||
|
$invitation = false;
|
||||||
|
|
||||||
match($data['entity_type']){
|
match($data['entity_type'] ?? false){
|
||||||
'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
||||||
'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
|
'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
|
||||||
'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']),
|
'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']),
|
||||||
'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (! $invitation) {
|
||||||
|
return redirect('/');
|
||||||
|
}
|
||||||
|
|
||||||
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||||
|
|
||||||
$headers = ['Content-Type' => 'application/pdf'];
|
$headers = ['Content-Type' => 'application/pdf'];
|
||||||
@ -128,7 +133,8 @@ class InvoiceController extends Controller
|
|||||||
|
|
||||||
public function downloadInvoices($ids)
|
public function downloadInvoices($ids)
|
||||||
{
|
{
|
||||||
$data['invoices'] = Invoice::whereIn('id', $ids)
|
$data['invoices'] = Invoice::query()
|
||||||
|
->whereIn('id', $ids)
|
||||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->get();
|
->get();
|
||||||
@ -153,7 +159,8 @@ class InvoiceController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function makePayment(array $ids)
|
private function makePayment(array $ids)
|
||||||
{
|
{
|
||||||
$invoices = Invoice::whereIn('id', $ids)
|
$invoices = Invoice::query()
|
||||||
|
->whereIn('id', $ids)
|
||||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->get();
|
->get();
|
||||||
@ -215,7 +222,8 @@ class InvoiceController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function downloadInvoicePDF(array $ids)
|
private function downloadInvoicePDF(array $ids)
|
||||||
{
|
{
|
||||||
$invoices = Invoice::whereIn('id', $ids)
|
$invoices = Invoice::query()
|
||||||
|
->whereIn('id', $ids)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||||
->get();
|
->get();
|
||||||
@ -244,11 +252,20 @@ class InvoiceController extends Controller
|
|||||||
// create new archive
|
// create new archive
|
||||||
$zipFile = new \PhpZip\ZipFile();
|
$zipFile = new \PhpZip\ZipFile();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
foreach ($invoices as $invoice) {
|
foreach ($invoices as $invoice) {
|
||||||
//add it to the zip
|
|
||||||
$zipFile->addFromString(basename($invoice->pdf_file_path()), file_get_contents($invoice->pdf_file_path(null, 'url', true)));
|
if ($invoice->client->getSetting('enable_e_invoice')) {
|
||||||
|
$xml = $invoice->service()->getEInvoice();
|
||||||
|
$zipFile->addFromString($invoice->getFileName("xml"), $xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$file = $invoice->service()->getRawInvoicePdf();
|
||||||
|
$zip_file_name = $invoice->getFileName();
|
||||||
|
$zipFile->addFromString($zip_file_name, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip';
|
$filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip';
|
||||||
$filepath = sys_get_temp_dir().'/'.$filename;
|
$filepath = sys_get_temp_dir().'/'.$filename;
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ class NinjaPlanController extends Controller
|
|||||||
public function index(string $contact_key, string $account_or_company_key)
|
public function index(string $contact_key, string $account_or_company_key)
|
||||||
{
|
{
|
||||||
MultiDB::findAndSetDbByCompanyKey($account_or_company_key);
|
MultiDB::findAndSetDbByCompanyKey($account_or_company_key);
|
||||||
$company = Company::where('company_key', $account_or_company_key)->first();
|
$company = Company::query()->where('company_key', $account_or_company_key)->first();
|
||||||
|
|
||||||
if (! $company) {
|
if (! $company) {
|
||||||
MultiDB::findAndSetDbByAccountKey($account_or_company_key);
|
MultiDB::findAndSetDbByAccountKey($account_or_company_key);
|
||||||
|
|
||||||
/** @var \App\Models\Account $account **/
|
/** @var \App\Models\Account $account **/
|
||||||
$account = Account::where('key', $account_or_company_key)->first();
|
$account = Account::query()->where('key', $account_or_company_key)->first();
|
||||||
} else {
|
} else {
|
||||||
$account = $company->account;
|
$account = $company->account;
|
||||||
}
|
}
|
||||||
@ -157,6 +157,8 @@ class NinjaPlanController extends Controller
|
|||||||
|
|
||||||
//create recurring invoice
|
//create recurring invoice
|
||||||
$subscription_repo = new SubscriptionRepository();
|
$subscription_repo = new SubscriptionRepository();
|
||||||
|
|
||||||
|
/** @var \App\Models\Subscription $subscription **/
|
||||||
$subscription = Subscription::find(6);
|
$subscription = Subscription::find(6);
|
||||||
|
|
||||||
$recurring_invoice = RecurringInvoiceFactory::create($subscription->company_id, $subscription->user_id);
|
$recurring_invoice = RecurringInvoiceFactory::create($subscription->company_id, $subscription->user_id);
|
||||||
@ -181,7 +183,7 @@ class NinjaPlanController extends Controller
|
|||||||
->increment()
|
->increment()
|
||||||
->queue();
|
->queue();
|
||||||
|
|
||||||
$old_recurring = RecurringInvoice::where('company_id', config('ninja.ninja_default_company_id'))
|
$old_recurring = RecurringInvoice::query()->where('company_id', config('ninja.ninja_default_company_id'))
|
||||||
->where('client_id', $client->id)
|
->where('client_id', $client->id)
|
||||||
->where('id', '!=', $recurring_invoice->id)
|
->where('id', '!=', $recurring_invoice->id)
|
||||||
->first();
|
->first();
|
||||||
@ -215,7 +217,7 @@ class NinjaPlanController extends Controller
|
|||||||
$data['late_invoice'] = false;
|
$data['late_invoice'] = false;
|
||||||
|
|
||||||
if (MultiDB::findAndSetDbByAccountKey(Auth::guard('contact')->user()->client->custom_value2)) {
|
if (MultiDB::findAndSetDbByAccountKey(Auth::guard('contact')->user()->client->custom_value2)) {
|
||||||
$account = Account::where('key', Auth::guard('contact')->user()->client->custom_value2)->first();
|
$account = Account::query()->where('key', Auth::guard('contact')->user()->client->custom_value2)->first();
|
||||||
|
|
||||||
if ($account) {
|
if ($account) {
|
||||||
//offer the option to have a free trial
|
//offer the option to have a free trial
|
||||||
|
@ -169,7 +169,7 @@ class PaymentController extends Controller
|
|||||||
$payment = $payment->service()->applyCredits($payment_hash)->save();
|
$payment = $payment->service()->applyCredits($payment_hash)->save();
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Invoice> $invoices */
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Invoice> $invoices */
|
||||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')));
|
$invoices = Invoice::query()->whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')));
|
||||||
|
|
||||||
$invoices->each(function ($invoice) {
|
$invoices->each(function ($invoice) {
|
||||||
/** @var \App\Models\Invoice $invoice **/
|
/** @var \App\Models\Invoice $invoice **/
|
||||||
|
@ -12,21 +12,22 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Events\Misc\InvitationWasViewed;
|
use App\Utils\Ninja;
|
||||||
|
use App\Models\Quote;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\QuoteInvitation;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Events\Quote\QuoteWasViewed;
|
use App\Events\Quote\QuoteWasViewed;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
|
use App\Jobs\Invoice\InjectSignature;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Events\Misc\InvitationWasViewed;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest;
|
use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest;
|
||||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
|
use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
|
||||||
use App\Jobs\Invoice\InjectSignature;
|
use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
|
||||||
use App\Models\Quote;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\View\View;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class QuoteController extends Controller
|
class QuoteController extends Controller
|
||||||
{
|
{
|
||||||
@ -53,7 +54,7 @@ class QuoteController extends Controller
|
|||||||
{
|
{
|
||||||
/* If the quote is expired, convert the status here */
|
/* If the quote is expired, convert the status here */
|
||||||
|
|
||||||
$invitation = $quote->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
$invitation = $quote->invitations()->where('client_contact_id', auth()->guard('contact')->user()->id)->first();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'quote' => $quote,
|
'quote' => $quote,
|
||||||
@ -95,8 +96,9 @@ class QuoteController extends Controller
|
|||||||
/** @var \App\Models\ClientContact $client_contact **/
|
/** @var \App\Models\ClientContact $client_contact **/
|
||||||
$client_contact = auth()->user();
|
$client_contact = auth()->user();
|
||||||
|
|
||||||
$data['quotes'] = Quote::whereIn('id', $ids)
|
$data['quotes'] = Quote::query()
|
||||||
->whereClientId($client_contact->client->id)
|
->whereIn('id', $ids)
|
||||||
|
->where('client_id', $client_contact->client_id)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@ -120,36 +122,38 @@ class QuoteController extends Controller
|
|||||||
/** @var \App\Models\ClientContact $client_contact **/
|
/** @var \App\Models\ClientContact $client_contact **/
|
||||||
$client_contact = auth()->user();
|
$client_contact = auth()->user();
|
||||||
|
|
||||||
$quotes = Quote::whereIn('id', $ids)
|
$quote_invitations = QuoteInvitation::query()
|
||||||
->whereClientId($client_contact->client_id)
|
->with('quote','company')
|
||||||
|
->whereIn('quote_id', $ids)
|
||||||
|
->where('client_contact_id', $client_contact->id)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
if (! $quotes || $quotes->count() == 0) {
|
if (! $quote_invitations || $quote_invitations->count() == 0) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('client.quotes.index')
|
->route('client.quotes.index')
|
||||||
->with('message', ctrans('texts.no_quotes_available_for_download'));
|
->with('message', ctrans('texts.no_quotes_available_for_download'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($quotes->count() == 1) {
|
if ($quote_invitations->count() == 1) {
|
||||||
$file = $quotes->first()->service()->getQuotePdf();
|
$invitation = $quote_invitations->first();
|
||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($file) {
|
||||||
echo Storage::get($file);
|
echo $file;
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
}, $invitation->quote->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->buildZip($quotes);
|
return $this->buildZip($quote_invitations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildZip($quotes)
|
private function buildZip($quote_invitations)
|
||||||
{
|
{
|
||||||
// create new archive
|
// create new archive
|
||||||
$zipFile = new \PhpZip\ZipFile();
|
$zipFile = new \PhpZip\ZipFile();
|
||||||
try {
|
try {
|
||||||
foreach ($quotes as $quote) {
|
foreach ($quote_invitations as $invitation) {
|
||||||
//add it to the zip
|
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||||
$zipFile->addFromString(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true)));
|
$zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file);
|
||||||
}
|
}
|
||||||
|
|
||||||
$filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
|
$filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
|
||||||
@ -160,7 +164,6 @@ class QuoteController extends Controller
|
|||||||
|
|
||||||
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
|
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
|
||||||
} catch (\PhpZip\Exception\ZipException $e) {
|
} catch (\PhpZip\Exception\ZipException $e) {
|
||||||
// handle exception
|
|
||||||
} finally {
|
} finally {
|
||||||
$zipFile->close();
|
$zipFile->close();
|
||||||
}
|
}
|
||||||
@ -168,7 +171,8 @@ class QuoteController extends Controller
|
|||||||
|
|
||||||
protected function approve(array $ids, $process = false)
|
protected function approve(array $ids, $process = false)
|
||||||
{
|
{
|
||||||
$quotes = Quote::whereIn('id', $ids)
|
$quotes = Quote::query()
|
||||||
|
->whereIn('id', $ids)
|
||||||
->where('client_id', auth()->guard('contact')->user()->client->id)
|
->where('client_id', auth()->guard('contact')->user()->client->id)
|
||||||
->where('company_id', auth()->guard('contact')->user()->client->company_id)
|
->where('company_id', auth()->guard('contact')->user()->client->company_id)
|
||||||
->whereIn('status_id', [Quote::STATUS_DRAFT, Quote::STATUS_SENT])
|
->whereIn('status_id', [Quote::STATUS_DRAFT, Quote::STATUS_SENT])
|
||||||
@ -195,10 +199,10 @@ class QuoteController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($ids) == 1) {
|
if ($quotes->count() == 1) {
|
||||||
//forward client to the invoice if it exists
|
//forward client to the invoice if it exists
|
||||||
if ($quote->invoice()->exists()) {
|
if ($quotes->first()->invoice()->exists()) {
|
||||||
return redirect()->route('client.invoice.show', $quote->invoice->hashed_id);
|
return redirect()->route('client.invoice.show', $quotes->first()->invoice->hashed_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('client.quote.show', $quotes->first()->hashed_id);
|
return redirect()->route('client.quote.show', $quotes->first()->hashed_id);
|
||||||
|
@ -22,9 +22,10 @@ class SwitchCompanyController extends Controller
|
|||||||
|
|
||||||
public function __invoke(string $contact)
|
public function __invoke(string $contact)
|
||||||
{
|
{
|
||||||
$client_contact = ClientContact::where('email', auth()->user()->email)
|
$client_contact = ClientContact::query()
|
||||||
|
->where('email', auth()->user()->email)
|
||||||
->where('id', $this->transformKeys($contact))
|
->where('id', $this->transformKeys($contact))
|
||||||
->first();
|
->firstOrFail();
|
||||||
|
|
||||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class UploadController extends Controller
|
|||||||
/** @var \App\Models\ClientContact $client_contact **/
|
/** @var \App\Models\ClientContact $client_contact **/
|
||||||
$client_contact = auth()->user();
|
$client_contact = auth()->user();
|
||||||
|
|
||||||
$this->saveDocuments($request->getFile(), $client_contact->client, true);
|
$this->saveDocuments($request->getFile(), $client_contact->client, $request->input('is_public', true));
|
||||||
|
|
||||||
return response([], 200);
|
return response([], 200);
|
||||||
}
|
}
|
||||||
|
@ -11,38 +11,39 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\DataMapper\Analytics\AccountDeleted;
|
use Str;
|
||||||
use App\DataMapper\CompanySettings;
|
use App\Utils\Ninja;
|
||||||
use App\Http\Requests\Company\CreateCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\DefaultCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\DestroyCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\EditCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\ShowCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\StoreCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
|
||||||
use App\Http\Requests\Company\UploadCompanyRequest;
|
|
||||||
use App\Jobs\Company\CreateCompany;
|
|
||||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
|
||||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
|
||||||
use App\Jobs\Company\CreateCompanyToken;
|
|
||||||
use App\Jobs\Mail\NinjaMailerJob;
|
|
||||||
use App\Jobs\Mail\NinjaMailerObject;
|
|
||||||
use App\Mail\Company\CompanyDeleted;
|
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyUser;
|
use App\Models\CompanyUser;
|
||||||
use App\Repositories\CompanyRepository;
|
|
||||||
use App\Transformers\CompanyTransformer;
|
|
||||||
use App\Transformers\CompanyUserTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use App\Utils\Traits\Uploadable;
|
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Str;
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Jobs\Company\CreateCompany;
|
||||||
|
use App\Jobs\Company\CompanyTaxRate;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Mail\Company\CompanyDeleted;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
use App\Repositories\CompanyRepository;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
|
use App\Transformers\CompanyTransformer;
|
||||||
|
use App\DataMapper\Analytics\AccountDeleted;
|
||||||
|
use App\Transformers\CompanyUserTransformer;
|
||||||
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||||
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
|
use App\Http\Requests\Company\EditCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\ShowCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\StoreCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\CreateCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\UploadCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\DefaultCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\DestroyCompanyRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CompanyController.
|
* Class CompanyController.
|
||||||
@ -423,7 +424,7 @@ class CompanyController extends BaseController
|
|||||||
$company = $this->company_repo->save($request->all(), $company);
|
$company = $this->company_repo->save($request->all(), $company);
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->input('documents'), $company, false);
|
$this->saveDocuments($request->input('documents'), $company, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($request->has('e_invoice_certificate') && !is_null($request->file("e_invoice_certificate"))){
|
if($request->has('e_invoice_certificate') && !is_null($request->file("e_invoice_certificate"))){
|
||||||
@ -615,7 +616,7 @@ class CompanyController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $company);
|
$this->saveDocuments($request->file('documents'), $company, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($company->fresh());
|
return $this->itemResponse($company->fresh());
|
||||||
@ -679,4 +680,36 @@ class CompanyController extends BaseController
|
|||||||
|
|
||||||
return $this->itemResponse($company->fresh());
|
return $this->itemResponse($company->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateOriginTaxData(DefaultCompanyRequest $request, Company $company)
|
||||||
|
{
|
||||||
|
|
||||||
|
if($company->settings->country_id == "840" && !$company?->account->isFreeHostedClient())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
(new CompanyTaxRate($company))->handle();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return response()->json(['message' => 'There was a problem updating the tax rates. Please try again.'], 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return response()->json(['message' => 'Tax configuration not available due to settings / plan restriction.'], 400);
|
||||||
|
|
||||||
|
return $this->itemResponse($company->fresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logo()
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$company = $user->company();
|
||||||
|
$logo = strlen($company->settings->company_logo) > 5 ? $company->settings->company_logo : 'https://pdf.invoicing.co/favicon-v2.png';
|
||||||
|
$headers = ['Content-Disposition' => 'inline'];
|
||||||
|
|
||||||
|
return response()->streamDownload(function () use ($logo){
|
||||||
|
echo @file_get_contents($logo);
|
||||||
|
}, 'logo.png', $headers);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,10 +111,11 @@ class CompanyUserController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(UpdateCompanyUserRequest $request, User $user)
|
public function update(UpdateCompanyUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $auth_user */
|
||||||
|
$auth_user = auth()->user();
|
||||||
|
$company = $auth_user->company();
|
||||||
|
|
||||||
$company = auth()->user()->company();
|
$company_user = CompanyUser::query()->where('user_id', $user->id)->where('company_id',$company->id)->first();
|
||||||
|
|
||||||
$company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
|
|
||||||
|
|
||||||
if (! $company_user) {
|
if (! $company_user) {
|
||||||
throw new ModelNotFoundException(ctrans('texts.company_user_not_found'));
|
throw new ModelNotFoundException(ctrans('texts.company_user_not_found'));
|
||||||
@ -122,11 +123,16 @@ class CompanyUserController extends BaseController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth()->user()->isAdmin()) {
|
if ($auth_user->isAdmin()) {
|
||||||
$company_user->fill($request->input('company_user'));
|
$company_user->fill($request->input('company_user'));
|
||||||
} else {
|
} else {
|
||||||
$company_user->settings = $request->input('company_user')['settings'];
|
$company_user->settings = $request->input('company_user')['settings'];
|
||||||
$company_user->notifications = $request->input('company_user')['notifications'];
|
$company_user->notifications = $request->input('company_user')['notifications'];
|
||||||
|
|
||||||
|
if(isset($request->input('company_user')['react_settings'])) {
|
||||||
|
$company_user->react_settings = $request->input('company_user')['react_settings'];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$company_user->save();
|
$company_user->save();
|
||||||
@ -136,8 +142,11 @@ class CompanyUserController extends BaseController
|
|||||||
|
|
||||||
public function updatePreferences(UpdateCompanyUserPreferencesRequest $request, User $user)
|
public function updatePreferences(UpdateCompanyUserPreferencesRequest $request, User $user)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $auth_user */
|
||||||
|
$auth_user = auth()->user();
|
||||||
|
$company = $auth_user->company();
|
||||||
|
|
||||||
$company = auth()->user()->company();
|
$company = $auth_user->company();
|
||||||
|
|
||||||
$company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
|
$company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ class ConnectedAccountController extends BaseController
|
|||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$email = $user->getMail() ?: $user->getUserPrincipalName();
|
$email = $user->getUserPrincipalName() ?? false;
|
||||||
|
|
||||||
nlog("microsoft");
|
nlog("microsoft");
|
||||||
nlog($email);
|
nlog($email);
|
||||||
|
@ -148,10 +148,10 @@ class CreditController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function create(CreateCreditRequest $request)
|
public function create(CreateCreditRequest $request)
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user**/
|
/** @var \App\Models\User $user **/
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$credit = CreditFactory::create($user->company()->id, auth()->user()->id);
|
$credit = CreditFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($credit);
|
return $this->itemResponse($credit);
|
||||||
}
|
}
|
||||||
@ -197,11 +197,9 @@ class CreditController extends BaseController
|
|||||||
public function store(StoreCreditRequest $request)
|
public function store(StoreCreditRequest $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @var \App\Models\User $user**/
|
/** @var \App\Models\User $user **/
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
// $client = Client::find($request->input('client_id'));
|
|
||||||
|
|
||||||
$credit = $this->credit_repository->save($request->all(), CreditFactory::create($user->company()->id, $user->id));
|
$credit = $this->credit_repository->save($request->all(), CreditFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
$credit = $credit->service()
|
$credit = $credit->service()
|
||||||
@ -387,8 +385,8 @@ class CreditController extends BaseController
|
|||||||
$credit = $this->credit_repository->save($request->all(), $credit);
|
$credit = $this->credit_repository->save($request->all(), $credit);
|
||||||
|
|
||||||
$credit->service()
|
$credit->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request);
|
||||||
->deletePdf();
|
// ->deletePdf();
|
||||||
|
|
||||||
/** @var \App\Models\User $user**/
|
/** @var \App\Models\User $user**/
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
@ -506,7 +504,7 @@ class CreditController extends BaseController
|
|||||||
public function bulk(BulkCreditRequest $request)
|
public function bulk(BulkCreditRequest $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @var \App\Models\User $user**/
|
/** @var \App\Models\User $user **/
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = $request->input('action');
|
$action = $request->input('action');
|
||||||
@ -531,20 +529,18 @@ class CreditController extends BaseController
|
|||||||
if ($action == 'bulk_download' && $credits->count() > 1) {
|
if ($action == 'bulk_download' && $credits->count() > 1) {
|
||||||
$credits->each(function ($credit) use($user){
|
$credits->each(function ($credit) use($user){
|
||||||
if ($user->cannot('view', $credit)) {
|
if ($user->cannot('view', $credit)) {
|
||||||
nlog('access denied');
|
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('text.access_denied')]);
|
return response()->json(['message' => ctrans('text.access_denied')]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ZipCredits::dispatch($credits, $credits->first()->company, $user);
|
ZipCredits::dispatch($credits->pluck('id')->toArray(), $credits->first()->company, $user);
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'bulk_print' && $user->can('view', $credits->first())) {
|
if ($action == 'bulk_print' && $user->can('view', $credits->first())) {
|
||||||
$paths = $credits->map(function ($credit) {
|
$paths = $credits->map(function ($credit) {
|
||||||
return $credit->service()->getCreditPdf($credit->invitations->first());
|
return (new \App\Jobs\Entity\CreateRawPdf($credit->invitations->first(), $credit->company->db))->handle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||||
@ -594,11 +590,8 @@ class CreditController extends BaseController
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
// $file = $credit->pdf_file_path();
|
|
||||||
$file = $credit->service()->getCreditPdf($credit->invitations->first());
|
$file = $credit->service()->getCreditPdf($credit->invitations->first());
|
||||||
|
|
||||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
@ -725,7 +718,7 @@ class CreditController extends BaseController
|
|||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*
|
*
|
||||||
* @param UploadCreditRequest $request
|
* @param UploadCreditRequest $request
|
||||||
* @param Credit $client
|
* @param Credit $credit
|
||||||
* @return Response
|
* @return Response
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -778,7 +771,7 @@ class CreditController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $credit);
|
$this->saveDocuments($request->file('documents'), $credit, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($credit->fresh());
|
return $this->itemResponse($credit->fresh());
|
||||||
|
@ -128,7 +128,7 @@ class DocumentController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*
|
*
|
||||||
* @param EditDocumentRegquest $request
|
* @param EditDocumentRequest $request
|
||||||
* @param Document $document
|
* @param Document $document
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
|
@ -78,6 +78,8 @@ class EmailController extends BaseController
|
|||||||
$entity_obj->service()->markSent()->save();
|
$entity_obj->service()->markSent()->save();
|
||||||
|
|
||||||
$mo->invitation_id = $invitation->id;
|
$mo->invitation_id = $invitation->id;
|
||||||
|
$mo->client_id = $invitation->contact->client_id ?? null;
|
||||||
|
$mo->vendor_id = $invitation->contact->vendor_id ?? null;
|
||||||
|
|
||||||
Email::dispatch($mo, $invitation->company);
|
Email::dispatch($mo, $invitation->company);
|
||||||
}
|
}
|
||||||
@ -125,7 +127,6 @@ class EmailController extends BaseController
|
|||||||
$this->entity_transformer = PurchaseOrderTransformer::class;
|
$this->entity_transformer = PurchaseOrderTransformer::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
return $this->itemResponse($entity_obj->fresh());
|
return $this->itemResponse($entity_obj->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
68
app/Http/Controllers/EmailHistoryController.php
Normal file
68
app/Http/Controllers/EmailHistoryController.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?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\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\Email\ClientEmailHistoryRequest;
|
||||||
|
use App\Http\Requests\Email\EntityEmailHistoryRequest;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
|
class EmailHistoryController extends BaseController
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clientHistory(ClientEmailHistoryRequest $request, Client $client)
|
||||||
|
{
|
||||||
|
$data = SystemLog::where('client_id', $client->id)
|
||||||
|
->where('category_id', SystemLog::CATEGORY_MAIL)
|
||||||
|
->orderBy('id', 'DESC')
|
||||||
|
->cursor()
|
||||||
|
->map(function ($system_log) {
|
||||||
|
if($system_log->log['history'] ?? false) {
|
||||||
|
return $system_log->log['history'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return response()->json($data, 200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May need to expand on this using
|
||||||
|
* just the message-id and search for the
|
||||||
|
* entity in the invitations
|
||||||
|
*/
|
||||||
|
public function entityHistory(EntityEmailHistoryRequest $request)
|
||||||
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$data = SystemLog::where('company_id', $user->company()->id)
|
||||||
|
->where('category_id', SystemLog::CATEGORY_MAIL)
|
||||||
|
->whereJsonContains('log->history->entity_id', $this->encodePrimaryKey($request->entity_id))
|
||||||
|
->orderBy('id', 'DESC')
|
||||||
|
->cursor()
|
||||||
|
->map(function ($system_log) {
|
||||||
|
if($system_log->log['history'] ?? false) {
|
||||||
|
return $system_log->log['history'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return response()->json($data, 200);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -564,7 +564,7 @@ class ExpenseController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $expense);
|
$this->saveDocuments($request->file('documents'), $expense, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($expense->fresh());
|
return $this->itemResponse($expense->fresh());
|
||||||
|
@ -139,12 +139,14 @@ class GroupSettingController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(UpdateGroupSettingRequest $request, GroupSetting $group_setting)
|
public function update(UpdateGroupSettingRequest $request, GroupSetting $group_setting)
|
||||||
{
|
{
|
||||||
|
/** Need this to prevent settings from being overwritten */
|
||||||
|
if(!$request->file('company_logo'))
|
||||||
$group_setting = $this->group_setting_repo->save($request->all(), $group_setting);
|
$group_setting = $this->group_setting_repo->save($request->all(), $group_setting);
|
||||||
|
|
||||||
$this->uploadLogo($request->file('company_logo'), $group_setting->company, $group_setting);
|
$this->uploadLogo($request->file('company_logo'), $group_setting->company, $group_setting);
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->input('documents'), $group_setting, false);
|
$this->saveDocuments($request->input('documents'), $group_setting, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($group_setting);
|
return $this->itemResponse($group_setting);
|
||||||
@ -217,7 +219,7 @@ class GroupSettingController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $group_setting);
|
$this->saveDocuments($request->file('documents'), $group_setting, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($group_setting->fresh());
|
return $this->itemResponse($group_setting->fresh());
|
||||||
|
@ -92,15 +92,82 @@ class ImportController extends Controller
|
|||||||
|
|
||||||
$class_map = $this->getEntityMap($entityType);
|
$class_map = $this->getEntityMap($entityType);
|
||||||
|
|
||||||
|
$hints = $this->setImportHints($entityType, $class_map::importable(), $csv_array[0]);
|
||||||
|
|
||||||
$data['mappings'][$entityType] = [
|
$data['mappings'][$entityType] = [
|
||||||
'available' => $class_map::importable(),
|
'available' => $class_map::importable(),
|
||||||
'headers' => array_slice($csv_array, 0, 2),
|
'headers' => array_slice($csv_array, 0, 2),
|
||||||
|
'hints' => $hints,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setImportHints($entity_type, $available_keys, $headers): array
|
||||||
|
{
|
||||||
|
$hints = [];
|
||||||
|
|
||||||
|
$translated_keys = collect($available_keys)->map(function ($value,$key){
|
||||||
|
|
||||||
|
$parts = explode(".", $value);
|
||||||
|
$index = $parts[0];
|
||||||
|
$label = $parts[1] ?? $parts[0];
|
||||||
|
|
||||||
|
return ['key' => $key, 'index' => ctrans("texts.{$index}"), 'label' => ctrans("texts.{$label}")];
|
||||||
|
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
|
||||||
|
foreach($headers as $key => $value) {
|
||||||
|
|
||||||
|
foreach($translated_keys as $tkey => $tvalue)
|
||||||
|
{
|
||||||
|
|
||||||
|
if($this->testMatch($value, $tvalue['label'])) {
|
||||||
|
$hit = $tvalue['key'];
|
||||||
|
$hints[$key] = $hit;
|
||||||
|
unset($translated_keys[$tkey]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$hints[$key] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//second pass using the index of the translation here
|
||||||
|
foreach($headers as $key => $value)
|
||||||
|
{
|
||||||
|
if(isset($hints[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($translated_keys as $tkey => $tvalue)
|
||||||
|
{
|
||||||
|
if($this->testMatch($value, $tvalue['index'])) {
|
||||||
|
$hit = $tvalue['key'];
|
||||||
|
$hints[$key] = $hit;
|
||||||
|
unset($translated_keys[$tkey]);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$hints[$key] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function testMatch($haystack, $needle): bool
|
||||||
|
{
|
||||||
|
return stripos($haystack, $needle) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
private function convertEncoding($data)
|
private function convertEncoding($data)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -115,6 +182,9 @@ class ImportController extends Controller
|
|||||||
|
|
||||||
public function import(ImportRequest $request)
|
public function import(ImportRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
|
|
||||||
if (empty($data['hash'])) {
|
if (empty($data['hash'])) {
|
||||||
@ -130,7 +200,7 @@ class ImportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
unset($data['files']);
|
unset($data['files']);
|
||||||
CSVIngest::dispatch($data, auth()->user()->company());
|
CSVIngest::dispatch($data, $user->company());
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('texts.import_started')], 200);
|
return response()->json(['message' => ctrans('texts.import_started')], 200);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,9 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function create(CreateInvoiceRequest $request)
|
public function create(CreateInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
$invoice = InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$invoice = InvoiceFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
}
|
}
|
||||||
@ -211,7 +213,11 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function store(StoreInvoiceRequest $request)
|
public function store(StoreInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
$invoice = $this->invoice_repo->save($request->all(), InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$invoice = $this->invoice_repo->save($request->all(), InvoiceFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
$invoice = $invoice->service()
|
$invoice = $invoice->service()
|
||||||
->fillDefaults()
|
->fillDefaults()
|
||||||
@ -219,7 +225,7 @@ class InvoiceController extends BaseController
|
|||||||
->adjustInventory()
|
->adjustInventory()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars($user ? $user->id : null)));
|
||||||
|
|
||||||
$transaction = [
|
$transaction = [
|
||||||
'invoice' => $invoice->transaction_event(),
|
'invoice' => $invoice->transaction_event(),
|
||||||
@ -409,7 +415,7 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$invoice->service()
|
$invoice->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
->deletePdf()
|
// ->deletePdf()
|
||||||
->adjustInventory($old_invoice);
|
->adjustInventory($old_invoice);
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
@ -473,62 +479,17 @@ class InvoiceController extends BaseController
|
|||||||
return $this->itemResponse($invoice->fresh());
|
return $this->itemResponse($invoice->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform bulk actions on the list view.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Support\Collection
|
|
||||||
*
|
|
||||||
* @OA\Post(
|
|
||||||
* path="/api/v1/invoices/bulk",
|
|
||||||
* operationId="bulkInvoices",
|
|
||||||
* tags={"invoices"},
|
|
||||||
* summary="Performs bulk actions on an array of invoices",
|
|
||||||
* description="",
|
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
|
||||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
|
||||||
* @OA\RequestBody(
|
|
||||||
* description="User credentials",
|
|
||||||
* required=true,
|
|
||||||
* @OA\MediaType(
|
|
||||||
* mediaType="application/json",
|
|
||||||
* @OA\Schema(
|
|
||||||
* type="array",
|
|
||||||
* @OA\Items(
|
|
||||||
* type="integer",
|
|
||||||
* description="Array of hashed IDs to be bulk 'actioned",
|
|
||||||
* example="[0,1,2,3]",
|
|
||||||
* ),
|
|
||||||
* )
|
|
||||||
* )
|
|
||||||
* ),
|
|
||||||
* @OA\Response(
|
|
||||||
* response=200,
|
|
||||||
* description="The Bulk Action response",
|
|
||||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
|
||||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
|
||||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
|
||||||
* ),
|
|
||||||
* @OA\Response(
|
|
||||||
* response=422,
|
|
||||||
* description="Validation error",
|
|
||||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
|
||||||
|
|
||||||
* ),
|
|
||||||
* @OA\Response(
|
|
||||||
* response="default",
|
|
||||||
* description="Unexpected Error",
|
|
||||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
|
||||||
* ),
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
public function bulk(BulkInvoiceRequest $request)
|
public function bulk(BulkInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = $request->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = $request->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !auth()->user()->company()->account->account_sms_verified) {
|
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) {
|
||||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,8 +504,8 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ($action == 'bulk_download' && $invoices->count() > 1) {
|
if ($action == 'bulk_download' && $invoices->count() > 1) {
|
||||||
$invoices->each(function ($invoice) {
|
$invoices->each(function ($invoice) use($user) {
|
||||||
if (auth()->user()->cannot('view', $invoice)) {
|
if ($user->cannot('view', $invoice)) {
|
||||||
nlog('access denied');
|
nlog('access denied');
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('text.access_denied')]);
|
return response()->json(['message' => ctrans('text.access_denied')]);
|
||||||
@ -556,7 +517,7 @@ class InvoiceController extends BaseController
|
|||||||
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'download' && $invoices->count() >=1 && auth()->user()->can('view', $invoices->first())) {
|
if ($action == 'download' && $invoices->count() >=1 && $user->can('view', $invoices->first())) {
|
||||||
$file = $invoices->first()->service()->getInvoicePdf();
|
$file = $invoices->first()->service()->getInvoicePdf();
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($file) {
|
||||||
@ -564,9 +525,9 @@ class InvoiceController extends BaseController
|
|||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'bulk_print' && auth()->user()->can('view', $invoices->first())) {
|
if ($action == 'bulk_print' && $user->can('view', $invoices->first())) {
|
||||||
$paths = $invoices->map(function ($invoice) {
|
$paths = $invoices->map(function ($invoice) {
|
||||||
return $invoice->service()->getInvoicePdf();
|
return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first(), $invoice->company->db))->handle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||||
@ -579,15 +540,15 @@ class InvoiceController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
$invoices->each(function ($invoice, $key) use ($action) {
|
$invoices->each(function ($invoice, $key) use ($action, $user) {
|
||||||
if (auth()->user()->can('edit', $invoice)) {
|
if ($user->can('edit', $invoice)) {
|
||||||
$this->performAction($invoice, $action, true);
|
$this->performAction($invoice, $action, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Need to understand which permission are required for the given bulk action ie. view / edit */
|
/* Need to understand which permission are required for the given bulk action ie. view / edit */
|
||||||
|
|
||||||
return $this->listResponse(Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Invoice::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -739,7 +700,7 @@ class InvoiceController extends BaseController
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'cancel':
|
case 'cancel':
|
||||||
$invoice = $invoice->service()->handleCancellation()->deletePdf()->save();
|
$invoice = $invoice->service()->handleCancellation()->save();
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
$this->itemResponse($invoice);
|
$this->itemResponse($invoice);
|
||||||
}
|
}
|
||||||
@ -889,6 +850,7 @@ class InvoiceController extends BaseController
|
|||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
$file = $invoice->service()->getEInvoice($contact);
|
$file = $invoice->service()->getEInvoice($contact);
|
||||||
|
$file_name = $invoice->getFileName("xml");
|
||||||
|
|
||||||
$headers = ['Content-Type' => 'application/xml'];
|
$headers = ['Content-Type' => 'application/xml'];
|
||||||
|
|
||||||
@ -897,8 +859,8 @@ class InvoiceController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($file) {
|
||||||
echo Storage::get($file);
|
echo $file;
|
||||||
}, basename($file), $headers);
|
}, $file_name, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1005,16 +967,17 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function upload(UploadInvoiceRequest $request, Invoice $invoice)
|
public function upload(UploadInvoiceRequest $request, Invoice $invoice)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! $this->checkFeature(Account::FEATURE_DOCUMENTS)) {
|
if (! $this->checkFeature(Account::FEATURE_DOCUMENTS)) {
|
||||||
return $this->featureFailure();
|
return $this->featureFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $invoice);
|
$this->saveDocuments($request->file('documents'), $invoice, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('file')) {
|
if ($request->has('file')) {
|
||||||
$this->saveDocuments($request->file('documents'), $invoice);
|
$this->saveDocuments($request->file('file'), $invoice, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($invoice->fresh());
|
return $this->itemResponse($invoice->fresh());
|
||||||
@ -1022,7 +985,10 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
public function update_reminders(UpdateReminderRequest $request)
|
public function update_reminders(UpdateReminderRequest $request)
|
||||||
{
|
{
|
||||||
UpdateReminders::dispatch(auth()->user()->company());
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
UpdateReminders::dispatch($user->company());
|
||||||
|
|
||||||
return response()->json(['message' => 'Updating reminders'], 200);
|
return response()->json(['message' => 'Updating reminders'], 200);
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ class MigrationController extends BaseController
|
|||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$company_count = $user->account->companies()->count();
|
$company_count = $user->account->companies()->count();
|
||||||
|
$fresh_company = false;
|
||||||
|
|
||||||
// Look for possible existing company (based on company keys).
|
// Look for possible existing company (based on company keys).
|
||||||
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first();
|
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first();
|
||||||
|
@ -74,6 +74,7 @@ class OneTimeTokenController extends BaseController
|
|||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'company_key'=> $user->company()->company_key,
|
'company_key'=> $user->company()->company_key,
|
||||||
'context' => $request->input('context'),
|
'context' => $request->input('context'),
|
||||||
|
'is_react' => $request->request()->hasHeader('X-REACT') ? true : false,
|
||||||
];
|
];
|
||||||
|
|
||||||
Cache::put($hash, $data, 3600);
|
Cache::put($hash, $data, 3600);
|
||||||
|
@ -749,7 +749,7 @@ class PaymentController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $payment);
|
$this->saveDocuments($request->file('documents'), $payment, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($payment->fresh());
|
return $this->itemResponse($payment->fresh());
|
||||||
|
@ -95,7 +95,7 @@ class PreviewPurchaseOrderController extends BaseController
|
|||||||
return response()->json(['message' => ctrans('texts.invalid_design_object')], 400);
|
return response()->json(['message' => ctrans('texts.invalid_design_object')], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity_obj = PurchaseOrder::whereId($this->decodePrimaryKey(request()->input('entity_id')))->company()->first();
|
$entity_obj = PurchaseOrder::query()->whereId($this->decodePrimaryKey(request()->input('entity_id')))->company()->first();
|
||||||
|
|
||||||
if (! $entity_obj) {
|
if (! $entity_obj) {
|
||||||
return $this->blankEntity();
|
return $this->blankEntity();
|
||||||
@ -181,7 +181,8 @@ class PreviewPurchaseOrderController extends BaseController
|
|||||||
DB::connection(config('database.default'))->beginTransaction();
|
DB::connection(config('database.default'))->beginTransaction();
|
||||||
|
|
||||||
if ($request->has('entity_id')) {
|
if ($request->has('entity_id')) {
|
||||||
$entity_obj = $class::on(config('database.default'))
|
/** @var \App\Models\PurchaseOrder|\Illuminate\Contracts\Database\Eloquent\Builder $entity_obj **/
|
||||||
|
$entity_obj = \App\Models\PurchaseOrder::on(config('database.default'))
|
||||||
->with('vendor.company')
|
->with('vendor.company')
|
||||||
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
|
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
|
||||||
->where('company_id', $company->id)
|
->where('company_id', $company->id)
|
||||||
|
@ -541,7 +541,7 @@ class ProductController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $product);
|
$this->saveDocuments($request->file('documents'), $product, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($product->fresh());
|
return $this->itemResponse($product->fresh());
|
||||||
|
@ -264,7 +264,7 @@ class ProjectController extends BaseController
|
|||||||
$project->saveQuietly();
|
$project->saveQuietly();
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->input('documents'), $project);
|
$this->saveDocuments($request->input('documents'), $project, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
event('eloquent.updated: App\Models\Project', $project);
|
event('eloquent.updated: App\Models\Project', $project);
|
||||||
@ -373,7 +373,7 @@ class ProjectController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->input('documents'), $project);
|
$this->saveDocuments($request->input('documents'), $project, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
event('eloquent.created: App\Models\Project', $project);
|
event('eloquent.created: App\Models\Project', $project);
|
||||||
@ -565,7 +565,7 @@ class ProjectController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $project);
|
$this->saveDocuments($request->file('documents'), $project, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($project->fresh());
|
return $this->itemResponse($project->fresh());
|
||||||
|
@ -139,7 +139,10 @@ class PurchaseOrderController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function create(CreatePurchaseOrderRequest $request)
|
public function create(CreatePurchaseOrderRequest $request)
|
||||||
{
|
{
|
||||||
$purchase_order = PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$purchase_order = PurchaseOrderFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($purchase_order);
|
return $this->itemResponse($purchase_order);
|
||||||
}
|
}
|
||||||
@ -183,7 +186,10 @@ class PurchaseOrderController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function store(StorePurchaseOrderRequest $request)
|
public function store(StorePurchaseOrderRequest $request)
|
||||||
{
|
{
|
||||||
$purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
$purchase_order = $purchase_order->service()
|
$purchase_order = $purchase_order->service()
|
||||||
->fillDefaults()
|
->fillDefaults()
|
||||||
@ -361,7 +367,7 @@ class PurchaseOrderController extends BaseController
|
|||||||
|
|
||||||
$purchase_order = $purchase_order->service()
|
$purchase_order = $purchase_order->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
->touchPdf()
|
// ->touchPdf()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
event(new PurchaseOrderWasUpdated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new PurchaseOrderWasUpdated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
@ -475,11 +481,14 @@ class PurchaseOrderController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function bulk(BulkPurchaseOrderRequest $request)
|
public function bulk(BulkPurchaseOrderRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = $request->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = $request->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !auth()->user()->company()->account->account_sms_verified) {
|
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) {
|
||||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,20 +502,20 @@ class PurchaseOrderController extends BaseController
|
|||||||
* Download Purchase Order/s
|
* Download Purchase Order/s
|
||||||
*/
|
*/
|
||||||
if ($action == 'bulk_download' && $purchase_orders->count() >= 1) {
|
if ($action == 'bulk_download' && $purchase_orders->count() >= 1) {
|
||||||
$purchase_orders->each(function ($purchase_order) {
|
$purchase_orders->each(function ($purchase_order) use ($user){
|
||||||
if (auth()->user()->cannot('view', $purchase_order)) {
|
if ($user->cannot('view', $purchase_order)) {
|
||||||
return response()->json(['message' => ctrans('text.access_denied')]);
|
return response()->json(['message' => ctrans('text.access_denied')]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ZipPurchaseOrders::dispatch($purchase_orders, $purchase_orders->first()->company, auth()->user());
|
ZipPurchaseOrders::dispatch($purchase_orders->pluck("id")->toArray(), $purchase_orders->first()->company, auth()->user());
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'bulk_print' && auth()->user()->can('view', $purchase_orders->first())) {
|
if ($action == 'bulk_print' && $user->can('view', $purchase_orders->first())) {
|
||||||
$paths = $purchase_orders->map(function ($purchase_order) {
|
$paths = $purchase_orders->map(function ($purchase_order) {
|
||||||
return $purchase_order->service()->getPurchaseOrderPdf();
|
return (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($purchase_order->invitations->first()))->rawPdf();
|
||||||
});
|
});
|
||||||
|
|
||||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||||
@ -519,8 +528,8 @@ class PurchaseOrderController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
$purchase_orders->each(function ($purchase_order, $key) use ($action) {
|
$purchase_orders->each(function ($purchase_order, $key) use ($action, $user) {
|
||||||
if (auth()->user()->can('edit', $purchase_order)) {
|
if ($user->can('edit', $purchase_order)) {
|
||||||
$this->performAction($purchase_order, $action, true);
|
$this->performAction($purchase_order, $action, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -751,7 +760,7 @@ class PurchaseOrderController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $purchase_order);
|
$this->saveDocuments($request->file('documents'), $purchase_order, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($purchase_order->fresh());
|
return $this->itemResponse($purchase_order->fresh());
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Quote;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Project;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Filters\QuoteFilters;
|
use App\Filters\QuoteFilters;
|
||||||
@ -33,6 +34,7 @@ use App\Transformers\QuoteTransformer;
|
|||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
|
use App\Transformers\ProjectTransformer;
|
||||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||||
use App\Factory\CloneQuoteToProjectFactory;
|
use App\Factory\CloneQuoteToProjectFactory;
|
||||||
use App\Http\Requests\Quote\EditQuoteRequest;
|
use App\Http\Requests\Quote\EditQuoteRequest;
|
||||||
@ -395,8 +397,8 @@ class QuoteController extends BaseController
|
|||||||
$quote = $this->quote_repo->save($request->all(), $quote);
|
$quote = $this->quote_repo->save($request->all(), $quote);
|
||||||
|
|
||||||
$quote->service()
|
$quote->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request);
|
||||||
->deletePdf();
|
// ->deletePdf();
|
||||||
|
|
||||||
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
@ -524,16 +526,15 @@ class QuoteController extends BaseController
|
|||||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$quotes = Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
$quotes = Quote::query()->with('invitations')->withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||||
|
|
||||||
if (! $quotes) {
|
if (! $quotes) {
|
||||||
return response()->json(['message' => ctrans('texts.quote_not_found')]);
|
return response()->json(['message' => ctrans('texts.quote_not_found')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Download Invoice/s
|
* Download Quote/s
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ($action == 'bulk_download' && $quotes->count() >= 1) {
|
if ($action == 'bulk_download' && $quotes->count() >= 1) {
|
||||||
$quotes->each(function ($quote) use($user){
|
$quotes->each(function ($quote) use($user){
|
||||||
if ($user->cannot('view', $quote)) {
|
if ($user->cannot('view', $quote)) {
|
||||||
@ -541,7 +542,7 @@ class QuoteController extends BaseController
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ZipQuotes::dispatch($quotes, $quotes->first()->company, auth()->user());
|
ZipQuotes::dispatch($quotes->pluck('id')->toArray(), $quotes->first()->company, auth()->user());
|
||||||
|
|
||||||
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
return response()->json(['message' => ctrans('texts.sent_message')], 200);
|
||||||
}
|
}
|
||||||
@ -556,12 +557,12 @@ class QuoteController extends BaseController
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'bulk_print' && $user->can('view', $quotes->first())) {
|
if ($action == 'bulk_print' && $user->can('view', $quotes->first())) {
|
||||||
$paths = $quotes->map(function ($quote) {
|
$paths = $quotes->map(function ($quote) {
|
||||||
return $quote->service()->getQuotePdf();
|
return (new \App\Jobs\Entity\CreateRawPdf($quote->invitations->first(), $quote->company->db))->handle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||||
@ -575,18 +576,13 @@ class QuoteController extends BaseController
|
|||||||
if ($action == 'convert_to_project') {
|
if ($action == 'convert_to_project') {
|
||||||
$quotes->each(function ($quote, $key) use ($user) {
|
$quotes->each(function ($quote, $key) use ($user) {
|
||||||
if ($user->can('edit', $quote)) {
|
if ($user->can('edit', $quote)) {
|
||||||
$project = CloneQuoteToProjectFactory::create($quote, $user->id);
|
|
||||||
|
|
||||||
if (empty($project->number)) {
|
$quote->service()->convertToProject();
|
||||||
$project->number = $this->getNextProjectNumber($project);
|
|
||||||
}
|
|
||||||
$project->save();
|
|
||||||
$quote->project_id = $project->id;
|
|
||||||
$quote->save();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -684,6 +680,13 @@ class QuoteController extends BaseController
|
|||||||
private function performAction(Quote $quote, $action, $bulk = false)
|
private function performAction(Quote $quote, $action, $bulk = false)
|
||||||
{
|
{
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
|
case 'convert_to_project':
|
||||||
|
|
||||||
|
$this->entity_type = Project::class;
|
||||||
|
$this->entity_transformer = ProjectTransformer::class;
|
||||||
|
|
||||||
|
return $this->itemResponse($quote->service()->convertToProject());
|
||||||
|
|
||||||
case 'convert':
|
case 'convert':
|
||||||
case 'convert_to_invoice':
|
case 'convert_to_invoice':
|
||||||
|
|
||||||
@ -692,8 +695,6 @@ class QuoteController extends BaseController
|
|||||||
|
|
||||||
return $this->itemResponse($quote->service()->convertToInvoice());
|
return $this->itemResponse($quote->service()->convertToInvoice());
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'clone_to_invoice':
|
case 'clone_to_invoice':
|
||||||
|
|
||||||
$this->entity_type = Invoice::class;
|
$this->entity_type = Invoice::class;
|
||||||
@ -702,41 +703,38 @@ class QuoteController extends BaseController
|
|||||||
$invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
|
$invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
|
||||||
|
|
||||||
return $this->itemResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
break;
|
|
||||||
case 'clone_to_quote':
|
case 'clone_to_quote':
|
||||||
$quote = CloneQuoteFactory::create($quote, auth()->user()->id);
|
$quote = CloneQuoteFactory::create($quote, auth()->user()->id);
|
||||||
|
|
||||||
return $this->itemResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
break;
|
|
||||||
case 'approve':
|
case 'approve':
|
||||||
if (! in_array($quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
|
if (! in_array($quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
|
||||||
return response()->json(['message' => ctrans('texts.quote_unapprovable')], 400);
|
return response()->json(['message' => ctrans('texts.quote_unapprovable')], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($quote->service()->approveWithNoCoversion()->save());
|
return $this->itemResponse($quote->service()->approveWithNoCoversion()->save());
|
||||||
break;
|
|
||||||
case 'history':
|
case 'history':
|
||||||
// code...
|
// code...
|
||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
|
|
||||||
//$file = $quote->pdf_file_path();
|
|
||||||
$file = $quote->service()->getQuotePdf();
|
$file = $quote->service()->getQuotePdf();
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($file) {
|
||||||
echo Storage::get($file);
|
echo Storage::get($file);
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->quote_repo->restore($quote);
|
$this->quote_repo->restore($quote);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->itemResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'archive':
|
case 'archive':
|
||||||
$this->quote_repo->archive($quote);
|
$this->quote_repo->archive($quote);
|
||||||
|
|
||||||
@ -754,16 +752,11 @@ class QuoteController extends BaseController
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
$quote->service()->sendEmail();
|
|
||||||
|
|
||||||
return response()->json(['message'=> ctrans('texts.sent_message')], 200);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'send_email':
|
case 'send_email':
|
||||||
|
|
||||||
$quote->service()->sendEmail();
|
$quote->service()->sendEmail();
|
||||||
|
|
||||||
return response()->json(['message'=> ctrans('texts.sent_message')], 200);
|
return response()->json(['message'=> ctrans('texts.sent_message')], 200);
|
||||||
break;
|
|
||||||
|
|
||||||
case 'mark_sent':
|
case 'mark_sent':
|
||||||
$quote->service()->markSent()->save();
|
$quote->service()->markSent()->save();
|
||||||
@ -905,7 +898,7 @@ class QuoteController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $quote);
|
$this->saveDocuments($request->file('documents'), $quote, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($quote->fresh());
|
return $this->itemResponse($quote->fresh());
|
||||||
|
@ -609,7 +609,7 @@ class RecurringExpenseController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $recurring_expense);
|
$this->saveDocuments($request->file('documents'), $recurring_expense, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($recurring_expense->fresh());
|
return $this->itemResponse($recurring_expense->fresh());
|
||||||
|
@ -153,7 +153,10 @@ class RecurringInvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function create(CreateRecurringInvoiceRequest $request)
|
public function create(CreateRecurringInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
$recurring_invoice = RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$recurring_invoice = RecurringInvoiceFactory::create($user->company()->id, $user->id);
|
||||||
|
|
||||||
return $this->itemResponse($recurring_invoice);
|
return $this->itemResponse($recurring_invoice);
|
||||||
}
|
}
|
||||||
@ -199,7 +202,10 @@ class RecurringInvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function store(StoreRecurringInvoiceRequest $request)
|
public function store(StoreRecurringInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
$recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create($user->company()->id, $user->id));
|
||||||
|
|
||||||
$recurring_invoice->service()
|
$recurring_invoice->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
@ -380,7 +386,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
|
|
||||||
$recurring_invoice->service()
|
$recurring_invoice->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
->deletePdf()
|
// ->deletePdf()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
@ -405,18 +411,21 @@ class RecurringInvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function bulk(BulkRecurringInvoiceRequest $request)
|
public function bulk(BulkRecurringInvoiceRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0;
|
$percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0;
|
||||||
|
|
||||||
if (in_array($request->action, ['increase_prices', 'update_prices'])) {
|
if (in_array($request->action, ['increase_prices', 'update_prices'])) {
|
||||||
UpdateRecurring::dispatch($request->ids, auth()->user()->company(), auth()->user(), $request->action, $percentage_increase);
|
UpdateRecurring::dispatch($request->ids, $user->company(), $user, $request->action, $percentage_increase);
|
||||||
|
|
||||||
return response()->json(['message' => 'Update in progress.'], 200);
|
return response()->json(['message' => 'Update in progress.'], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
$recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
|
$recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
|
||||||
|
|
||||||
$recurring_invoices->each(function ($recurring_invoice, $key) use ($request) {
|
$recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) {
|
||||||
if (auth()->user()->can('edit', $recurring_invoice)) {
|
if ($user->can('edit', $recurring_invoice)) {
|
||||||
$this->performAction($recurring_invoice, $request->action, true);
|
$this->performAction($recurring_invoice, $request->action, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -550,7 +559,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->has('documents')) {
|
if ($request->has('documents')) {
|
||||||
$this->saveDocuments($request->file('documents'), $recurring_invoice);
|
$this->saveDocuments($request->file('documents'), $recurring_invoice, $request->input('is_public', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($recurring_invoice->fresh());
|
return $this->itemResponse($recurring_invoice->fresh());
|
||||||
|
@ -14,6 +14,7 @@ namespace App\Http\Controllers\Reports;
|
|||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Jobs\Report\SendToAdmin;
|
use App\Jobs\Report\SendToAdmin;
|
||||||
use App\Export\CSV\ActivityExport;
|
use App\Export\CSV\ActivityExport;
|
||||||
|
use App\Jobs\Report\PreviewReport;
|
||||||
use App\Http\Controllers\BaseController;
|
use App\Http\Controllers\BaseController;
|
||||||
use App\Http\Requests\Report\GenericReportRequest;
|
use App\Http\Requests\Report\GenericReportRequest;
|
||||||
|
|
||||||
@ -31,14 +32,27 @@ class ActivityReportController extends BaseController
|
|||||||
|
|
||||||
public function __invoke(GenericReportRequest $request)
|
public function __invoke(GenericReportRequest $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
if ($request->has('send_email') && $request->get('send_email')) {
|
if ($request->has('send_email') && $request->get('send_email')) {
|
||||||
SendToAdmin::dispatch(auth()->user()->company(), $request->all(), ActivityExport::class, $this->filename);
|
SendToAdmin::dispatch($user->company(), $request->all(), ActivityExport::class, $this->filename);
|
||||||
|
|
||||||
return response()->json(['message' => 'working...'], 200);
|
return response()->json(['message' => 'working...'], 200);
|
||||||
}
|
}
|
||||||
// expect a list of visible fields, or use the default
|
// expect a list of visible fields, or use the default
|
||||||
|
|
||||||
$export = new ActivityExport(auth()->user()->company(), $request->all());
|
if($request->has('output') && $request->input('output') == 'json') {
|
||||||
|
|
||||||
|
$hash = \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
PreviewReport::dispatch($user->company(), $request->all(), ActivityExport::class, $hash);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
$export = new ActivityExport($user->company(), $request->all());
|
||||||
|
|
||||||
$csv = $export->run();
|
$csv = $export->run();
|
||||||
|
|
||||||
|
@ -11,12 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Reports;
|
namespace App\Http\Controllers\Reports;
|
||||||
|
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Jobs\Report\SendToAdmin;
|
||||||
use App\Export\CSV\ContactExport;
|
use App\Export\CSV\ContactExport;
|
||||||
|
use App\Jobs\Report\PreviewReport;
|
||||||
use App\Http\Controllers\BaseController;
|
use App\Http\Controllers\BaseController;
|
||||||
use App\Http\Requests\Report\GenericReportRequest;
|
use App\Http\Requests\Report\GenericReportRequest;
|
||||||
use App\Jobs\Report\SendToAdmin;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
|
|
||||||
class ClientContactReportController extends BaseController
|
class ClientContactReportController extends BaseController
|
||||||
{
|
{
|
||||||
@ -62,13 +63,29 @@ class ClientContactReportController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function __invoke(GenericReportRequest $request)
|
public function __invoke(GenericReportRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
if ($request->has('send_email') && $request->get('send_email')) {
|
if ($request->has('send_email') && $request->get('send_email')) {
|
||||||
SendToAdmin::dispatch(auth()->user()->company(), $request->all(), ContactExport::class, $this->filename);
|
SendToAdmin::dispatch($user->company(), $request->all(), ContactExport::class, $this->filename);
|
||||||
|
|
||||||
return response()->json(['message' => 'working...'], 200);
|
return response()->json(['message' => 'working...'], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// expect a list of visible fields, or use the default
|
// expect a list of visible fields, or use the default
|
||||||
$export = new ContactExport(auth()->user()->company(), $request->all());
|
if($request->has('output') && $request->input('output') == 'json') {
|
||||||
|
|
||||||
|
$hash = \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
PreviewReport::dispatch($user->company(), $request->all(), ContactExport::class, $hash);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// expect a list of visible fields, or use the default
|
||||||
|
$export = new ContactExport($user->company(), $request->all());
|
||||||
|
|
||||||
$csv = $export->run();
|
$csv = $export->run();
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user