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 -->
|
||||
- Environment: <!-- Docker/Shared Hosting/ZIP/Other -->
|
||||
|
||||
## Interface
|
||||
- Flutter: []
|
||||
- React: []
|
||||
- Both: []
|
||||
|
||||
## Checklist
|
||||
- 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?
|
||||
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -32,9 +32,9 @@ jobs:
|
||||
- name: Prepare Laravel Application
|
||||
run: |
|
||||
cp .env.example .env
|
||||
php artisan key:generate
|
||||
php artisan key:generate --force
|
||||
php artisan optimize
|
||||
php artisan storage:link
|
||||
php artisan storage:link --force
|
||||
sudo php artisan cache:clear
|
||||
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
||||
sudo find ./ -type d -exec chmod 755 {} \;
|
||||
@ -46,7 +46,11 @@ jobs:
|
||||
git checkout main
|
||||
npm i
|
||||
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/
|
||||
cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
|
||||
cd ..
|
||||
|
@ -1 +1 @@
|
||||
5.6.26
|
||||
5.7.22
|
@ -35,6 +35,7 @@ use App\Models\BankTransaction;
|
||||
use App\Models\QuoteInvitation;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\DataMapper\ClientSettings;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@ -185,6 +186,9 @@ class CheckData extends Command
|
||||
if ($cu->company && $cu->user) {
|
||||
(new CreateCompanyToken($cu->company, $cu->user, 'System'))->handle();
|
||||
}
|
||||
else {
|
||||
// $cu->forceDelete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -468,7 +472,7 @@ class CheckData extends Command
|
||||
$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) {
|
||||
$entity::doesntHave('invitations')->cursor()->each(function ($entity) {
|
||||
$client_vendor_key = 'client_id';
|
||||
@ -545,7 +549,7 @@ class CheckData extends Command
|
||||
|
||||
private function clientPaidToDateQuery()
|
||||
{
|
||||
$results = \DB::select(\DB::raw("
|
||||
$results = \DB::select("
|
||||
SELECT
|
||||
clients.id as client_id,
|
||||
clients.paid_to_date as client_paid_to_date,
|
||||
@ -560,14 +564,14 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING payments_applied != client_paid_to_date
|
||||
ORDER BY clients.id;
|
||||
"));
|
||||
");
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function clientCreditPaymentables($client)
|
||||
{
|
||||
$results = \DB::select(\DB::raw("
|
||||
$results = \DB::select("
|
||||
SELECT
|
||||
SUM(paymentables.amount - paymentables.refunded) as credit_payment
|
||||
FROM payments
|
||||
@ -579,7 +583,7 @@ class CheckData extends Command
|
||||
AND paymentables.amount > 0
|
||||
AND payments.is_deleted = 0
|
||||
AND payments.client_id = ?;
|
||||
"), [App\Models\Credit::class, $client->id]);
|
||||
", [App\Models\Credit::class, $client->id]);
|
||||
|
||||
return $results;
|
||||
}
|
||||
@ -617,108 +621,9 @@ class CheckData extends Command
|
||||
$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()
|
||||
{
|
||||
$results = \DB::select(\DB::raw("
|
||||
$results = \DB::select("
|
||||
SELECT
|
||||
SUM(invoices.balance) as invoice_balance,
|
||||
clients.id as client_id,
|
||||
@ -732,7 +637,7 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING invoice_balance != clients.balance
|
||||
ORDER BY clients.id;
|
||||
"));
|
||||
");
|
||||
|
||||
return $results;
|
||||
}
|
||||
@ -809,7 +714,7 @@ class CheckData extends Command
|
||||
|
||||
private function invoiceBalanceQuery()
|
||||
{
|
||||
$results = \DB::select(\DB::raw("
|
||||
$results = \DB::select("
|
||||
SELECT
|
||||
clients.id,
|
||||
clients.balance,
|
||||
@ -823,7 +728,7 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING(invoices_balance != clients.balance)
|
||||
ORDER BY clients.id;
|
||||
"));
|
||||
");
|
||||
|
||||
return $results;
|
||||
}
|
||||
@ -873,7 +778,7 @@ class CheckData extends Command
|
||||
$this->wrong_balances = 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');
|
||||
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
||||
|
||||
@ -957,7 +862,7 @@ class CheckData extends Command
|
||||
}
|
||||
$records = DB::table($table)
|
||||
->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"]);
|
||||
|
||||
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)
|
||||
|
@ -61,6 +61,8 @@ class CreateTestData extends Command
|
||||
|
||||
protected $invoice_repo;
|
||||
|
||||
protected $count;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ class ReactBuilder extends Command
|
||||
{
|
||||
$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) {
|
||||
if ($file->getExtension() == 'js') {
|
||||
|
@ -173,7 +173,7 @@ class SendRemindersCron extends Command
|
||||
/**Refresh Invoice values*/
|
||||
$invoice->calc()->getInvoice()->save();
|
||||
$invoice->fresh();
|
||||
$invoice->service()->deletePdf()->save();
|
||||
// $invoice->service()->deletePdf()->save();
|
||||
if ($invoice->client->getSetting('enable_e_invoice')){
|
||||
$invoice->service()->deleteEInvoice()->save();
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class TypeCheck extends Command
|
||||
$client->save();
|
||||
});
|
||||
|
||||
Company::cursor()->each(function ($company) {
|
||||
Company::query()->cursor()->each(function ($company) {
|
||||
$this->logMessage("Checking company {$company->id}");
|
||||
$company->saveSettings($company->settings, $company);
|
||||
});
|
||||
|
@ -11,28 +11,29 @@
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\Cron\AutoBillCron;
|
||||
use App\Jobs\Cron\RecurringExpensesCron;
|
||||
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\Utils\Ninja;
|
||||
use App\Models\Account;
|
||||
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\ReminderJob;
|
||||
use App\Jobs\Util\SchedulerCheck;
|
||||
use App\Jobs\Util\UpdateExchangeRates;
|
||||
use App\Jobs\Cron\AutoBillCron;
|
||||
use App\Jobs\Util\VersionCheck;
|
||||
use App\Models\Account;
|
||||
use App\Utils\Ninja;
|
||||
use App\Jobs\Ninja\TaskScheduler;
|
||||
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 App\Jobs\Invoice\InvoiceCheckLateWebhook;
|
||||
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
@ -107,7 +108,10 @@ class Kernel extends ConsoleKernel
|
||||
$schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping();
|
||||
|
||||
/* 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();
|
||||
|
||||
|
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 $classification = ''; // individual, company, partnership, trust, charity, government, other
|
||||
|
||||
public static $casts = [
|
||||
'enable_e_invoice' => 'bool',
|
||||
'classification' => 'string',
|
||||
'default_expense_payment_type_id' => 'string',
|
||||
'e_invoice_type' => 'string',
|
||||
'mailgun_endpoint' => 'string',
|
||||
@ -812,7 +815,7 @@ class CompanySettings extends BaseSettings
|
||||
* need to provide a fallback catch on old settings objects which will
|
||||
* set new properties to the object prior to being returned.
|
||||
*
|
||||
* @param $settings
|
||||
* @param \stdClass $settings
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
@ -843,6 +846,23 @@ class CompanySettings extends BaseSettings
|
||||
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
|
||||
*
|
||||
|
@ -61,8 +61,13 @@ class InvoiceItem
|
||||
|
||||
public $tax_id = '';
|
||||
|
||||
public $task_id = '';
|
||||
|
||||
public $expense_id = '';
|
||||
|
||||
public static $casts = [
|
||||
'task_id' => 'string',
|
||||
'expense_id' => 'string',
|
||||
'tax_id' => 'string',
|
||||
'type_id' => 'string',
|
||||
'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->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;
|
||||
$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 ?? 0;
|
||||
|
||||
return $this;
|
||||
|
||||
|
@ -363,7 +363,15 @@ class BaseRule implements RuleInterface
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
public function calculateRates(): self
|
||||
|
@ -49,6 +49,10 @@ class Rule extends BaseRule implements RuleInterface
|
||||
|
||||
$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;
|
||||
|
||||
|
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 Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
|
||||
class ActivityExport extends BaseExport
|
||||
@ -39,10 +40,6 @@ class ActivityExport extends BaseExport
|
||||
'address' => 'address',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
|
||||
];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -50,47 +47,33 @@ class ActivityExport extends BaseExport
|
||||
$this->entity_transformer = new ActivityTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public function returnJson()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
$query = $this->init();
|
||||
|
||||
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
|
||||
$headerdisplay = $this->buildHeader();
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
$header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
|
||||
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
|
||||
})->toArray();
|
||||
|
||||
ksort($this->entity_keys);
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
$report = $query->cursor()
|
||||
->map(function ($resource) {
|
||||
$row = $this->buildActivityRow($resource);
|
||||
return $this->processMetaData($row, $resource);
|
||||
})->toArray();
|
||||
|
||||
return array_merge(['columns' => $header], $report);
|
||||
}
|
||||
|
||||
//insert the header
|
||||
$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)
|
||||
private function buildActivityRow(Activity $activity): array
|
||||
{
|
||||
|
||||
$this->csv->insertOne([
|
||||
return [
|
||||
Carbon::parse($activity->created_at)->format($this->date_format),
|
||||
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() : '',
|
||||
'contact' => $activity->contact ? $activity->contact->present()->name() : '',
|
||||
'quote' => $activity->quote ? $activity->quote->number : '',
|
||||
@ -108,7 +91,57 @@ class ActivityExport extends BaseExport
|
||||
'recurring_expense' => $activity->recurring_expense ? $activity->recurring_expense->number : '',
|
||||
]),
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Number;
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Helpers;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Document;
|
||||
use League\Fractal\Manager;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use App\Models\Product;
|
||||
use App\Models\Task;
|
||||
use App\Models\Vendor;
|
||||
|
||||
class BaseExport
|
||||
{
|
||||
@ -43,8 +54,6 @@ class BaseExport
|
||||
|
||||
public string $client_description = 'All Clients';
|
||||
|
||||
public array $forced_keys = [];
|
||||
|
||||
protected array $vendor_report_keys = [
|
||||
'address1' => 'vendor.address1',
|
||||
'address2' => 'vendor.address2',
|
||||
@ -57,7 +66,7 @@ class BaseExport
|
||||
'id_number' => 'vendor.id_number',
|
||||
'name' => 'vendor.name',
|
||||
'number' => 'vendor.number',
|
||||
'client_phone' => 'vendor.phone',
|
||||
'phone' => 'vendor.phone',
|
||||
'postal_code' => 'vendor.postal_code',
|
||||
'private_notes' => 'vendor.private_notes',
|
||||
'public_notes' => 'vendor.public_notes',
|
||||
@ -94,7 +103,6 @@ class BaseExport
|
||||
"state" => "client.state",
|
||||
"postal_code" => "client.postal_code",
|
||||
"country" => "client.country_id",
|
||||
"custom_value4" => "contact.custom_value4",
|
||||
"shipping_address1" => "client.shipping_address1",
|
||||
"shipping_address2" => "client.shipping_address2",
|
||||
"shipping_city" => "client.shipping_city",
|
||||
@ -109,6 +117,15 @@ class BaseExport
|
||||
"first_name" => "contact.first_name",
|
||||
"last_name" => "contact.last_name",
|
||||
"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 = [
|
||||
@ -126,6 +143,7 @@ class BaseExport
|
||||
"private_notes" => "invoice.private_notes",
|
||||
"uses_inclusive_taxes" => "invoice.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "invoice.is_amount_discount",
|
||||
"discount" => "invoice.discount",
|
||||
"partial" => "invoice.partial",
|
||||
"partial_due_date" => "invoice.partial_due_date",
|
||||
"surcharge1" => "invoice.custom_surcharge1",
|
||||
@ -136,6 +154,16 @@ class BaseExport
|
||||
"tax_amount" => "invoice.total_taxes",
|
||||
"assigned_user" => "invoice.assigned_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 = [
|
||||
@ -153,6 +181,7 @@ class BaseExport
|
||||
"private_notes" => "recurring_invoice.private_notes",
|
||||
"uses_inclusive_taxes" => "recurring_invoice.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "recurring_invoice.is_amount_discount",
|
||||
"discount" => "recurring_invoice.discount",
|
||||
"partial" => "recurring_invoice.partial",
|
||||
"partial_due_date" => "recurring_invoice.partial_due_date",
|
||||
"surcharge1" => "recurring_invoice.custom_surcharge1",
|
||||
@ -164,17 +193,23 @@ class BaseExport
|
||||
"assigned_user" => "recurring_invoice.assigned_user_id",
|
||||
"user" => "recurring_invoice.user_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 = [
|
||||
'amount' => 'purchase_order.amount',
|
||||
'balance' => 'purchase_order.balance',
|
||||
'vendor' => 'purchase_order.vendor_id',
|
||||
// 'custom_surcharge1' => 'purchase_order.custom_surcharge1',
|
||||
// 'custom_surcharge2' => 'purchase_order.custom_surcharge2',
|
||||
// 'custom_surcharge3' => 'purchase_order.custom_surcharge3',
|
||||
// 'custom_surcharge4' => 'purchase_order.custom_surcharge4',
|
||||
'custom_value1' => 'purchase_order.custom_value1',
|
||||
'custom_value2' => 'purchase_order.custom_value2',
|
||||
'custom_value3' => 'purchase_order.custom_value3',
|
||||
@ -203,17 +238,41 @@ class BaseExport
|
||||
'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 = [
|
||||
"quantity" => "item.quantity",
|
||||
"cost" => "item.cost",
|
||||
"product_key" => "item.product_key",
|
||||
"notes" => "item.notes",
|
||||
"item_tax1" => "item.tax_name1",
|
||||
"item_tax_rate1" => "item.tax_rate1",
|
||||
"item_tax2" => "item.tax_name2",
|
||||
"item_tax_rate2" => "item.tax_rate2",
|
||||
"item_tax3" => "item.tax_name3",
|
||||
"item_tax_rate3" => "item.tax_rate3",
|
||||
"tax_name1" => "item.tax_name1",
|
||||
"tax_rate1" => "item.tax_rate1",
|
||||
"tax_name2" => "item.tax_name2",
|
||||
"tax_rate2" => "item.tax_rate2",
|
||||
"tax_name3" => "item.tax_name3",
|
||||
"tax_rate3" => "item.tax_rate3",
|
||||
"custom_value1" => "item.custom_value1",
|
||||
"custom_value2" => "item.custom_value2",
|
||||
"custom_value3" => "item.custom_value3",
|
||||
@ -221,6 +280,9 @@ class BaseExport
|
||||
"discount" => "item.discount",
|
||||
"type" => "item.type_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 = [
|
||||
@ -242,6 +304,7 @@ class BaseExport
|
||||
"private_notes" => "quote.private_notes",
|
||||
"uses_inclusive_taxes" => "quote.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "quote.is_amount_discount",
|
||||
"discount" => "quote.discount",
|
||||
"partial" => "quote.partial",
|
||||
"partial_due_date" => "quote.partial_due_date",
|
||||
"surcharge1" => "quote.custom_surcharge1",
|
||||
@ -252,6 +315,12 @@ class BaseExport
|
||||
"tax_amount" => "quote.total_taxes",
|
||||
"assigned_user" => "quote.assigned_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 = [
|
||||
@ -263,6 +332,7 @@ class BaseExport
|
||||
"date" => "credit.date",
|
||||
"due_date" => "credit.due_date",
|
||||
"terms" => "credit.terms",
|
||||
"discount" => "credit.discount",
|
||||
"footer" => "credit.footer",
|
||||
"status" => "credit.status",
|
||||
"public_notes" => "credit.public_notes",
|
||||
@ -275,6 +345,10 @@ class BaseExport
|
||||
"surcharge2" => "credit.custom_surcharge2",
|
||||
"surcharge3" => "credit.custom_surcharge3",
|
||||
"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",
|
||||
"tax_amount" => "credit.total_taxes",
|
||||
"assigned_user" => "credit.assigned_user_id",
|
||||
@ -304,7 +378,7 @@ class BaseExport
|
||||
protected array $expense_report_keys = [
|
||||
'amount' => 'expense.amount',
|
||||
'category' => 'expense.category_id',
|
||||
'client' => 'expense.client_id',
|
||||
// 'client' => 'expense.client_id',
|
||||
'custom_value1' => 'expense.custom_value1',
|
||||
'custom_value2' => 'expense.custom_value2',
|
||||
'custom_value3' => 'expense.custom_value3',
|
||||
@ -518,31 +592,33 @@ class BaseExport
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_client = $manager->createData($transformed_client)->toArray();
|
||||
|
||||
if($column == 'name')
|
||||
if(in_array($column, ['client.name', '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();
|
||||
|
||||
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}") : '';
|
||||
|
||||
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}") : '';
|
||||
|
||||
if($column == 'size_id')
|
||||
if(in_array($column, ['client.size_id', 'size_id']))
|
||||
return $entity->client->size?->name ?? '';
|
||||
|
||||
if($column == 'industry_id')
|
||||
if(in_array($column, ['client.industry_id', 'industry_id']))
|
||||
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;
|
||||
}
|
||||
|
||||
if($column == 'client.payment_terms') {
|
||||
if(in_array($column, ['payment_terms', 'client.payment_terms']))
|
||||
return $entity->client->getSetting('payment_terms');
|
||||
}
|
||||
|
||||
|
||||
if(array_key_exists($column, $transformed_client))
|
||||
return $transformed_client[$column];
|
||||
@ -584,7 +660,7 @@ class BaseExport
|
||||
// nlog("searching for {$column}");
|
||||
$transformed_invoice = false;
|
||||
|
||||
if($transformer instanceof PaymentTransformer) {
|
||||
if($transformer instanceof PaymentTransformer && ($entity->invoices ?? false)) {
|
||||
$transformed_invoices = $transformer->includeInvoices($entity);
|
||||
|
||||
$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);
|
||||
|
||||
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
|
||||
{
|
||||
$helper = new Helpers();
|
||||
|
||||
$header = [];
|
||||
|
||||
// nlog($this->input['report_keys']);
|
||||
|
||||
foreach (array_merge($this->input['report_keys'], $this->forced_keys) as $value) {
|
||||
// nlog("header");
|
||||
foreach ($this->input['report_keys'] as $value) {
|
||||
|
||||
$key = array_search($value, $this->entity_keys);
|
||||
$original_key = $key;
|
||||
|
||||
// nlog("{$key} => {$value}");
|
||||
$prefix = '';
|
||||
|
||||
if(!$key) {
|
||||
@ -854,7 +945,6 @@ class BaseExport
|
||||
$key = array_search($value, $this->payment_report_keys);
|
||||
}
|
||||
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.quote')." ";
|
||||
$key = array_search($value, $this->quote_report_keys);
|
||||
@ -873,6 +963,9 @@ class BaseExport
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.expense')." ";
|
||||
$key = array_search($value, $this->expense_report_keys);
|
||||
|
||||
if(!$key && $value == 'expense.category')
|
||||
$key = 'category';
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
@ -892,8 +985,15 @@ class BaseExport
|
||||
|
||||
if(!$key) {
|
||||
$prefix = '';
|
||||
$key = array_search($value, $this->product_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
// nlog("key => {$key}");
|
||||
|
||||
$key = str_replace('item.', '', $key);
|
||||
$key = str_replace('recurring_invoice.', '', $key);
|
||||
$key = str_replace('purchase_order.', '', $key);
|
||||
@ -906,11 +1006,42 @@ class BaseExport
|
||||
$key = str_replace('contact.', '', $key);
|
||||
$key = str_replace('payment.', '', $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);
|
||||
$header[] = ctrans('texts.item') . " ". ctrans("texts.custom_value{$number}");
|
||||
$parts = explode(".", $value);
|
||||
|
||||
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
|
||||
{
|
||||
@ -922,4 +1053,100 @@ class BaseExport
|
||||
|
||||
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;
|
||||
|
||||
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 Illuminate\Support\Facades\App;
|
||||
use App\Utils\Number;
|
||||
use App\Models\Client;
|
||||
use League\Csv\Writer;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use App\Transformers\ClientTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Transformers\ClientContactTransformer;
|
||||
|
||||
class ClientExport extends BaseExport
|
||||
{
|
||||
@ -72,16 +74,6 @@ class ClientExport extends BaseExport
|
||||
'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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -90,7 +82,28 @@ class ClientExport extends BaseExport
|
||||
$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);
|
||||
App::forgetInstance('translator');
|
||||
@ -98,16 +111,10 @@ class ClientExport extends BaseExport
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
@ -115,6 +122,20 @@ class ClientExport extends BaseExport
|
||||
|
||||
$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 ($client) {
|
||||
$this->csv->insertOne($this->buildRow($client));
|
||||
@ -152,6 +173,30 @@ class ClientExport extends BaseExport
|
||||
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
|
||||
{
|
||||
if (in_array('client.user', $this->input['report_keys'])) {
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Company;
|
||||
use App\Transformers\ClientContactTransformer;
|
||||
use App\Transformers\ClientTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -32,54 +33,6 @@ class ContactExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -88,29 +41,39 @@ class ContactExport extends BaseExport
|
||||
$this->contact_transformer = new ClientContactTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->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 ($contact) {
|
||||
$this->csv->insertOne($this->buildRow($contact));
|
||||
});
|
||||
@ -118,6 +81,27 @@ class ContactExport extends BaseExport
|
||||
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
|
||||
{
|
||||
$transformed_contact = false;
|
||||
@ -129,14 +113,13 @@ class ContactExport extends BaseExport
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$parts = explode('.', $key);
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
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)) {
|
||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
||||
$entity[$key] = $transformed_contact[$parts[1]];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,13 +11,15 @@
|
||||
|
||||
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 Illuminate\Support\Facades\App;
|
||||
use App\Utils\Number;
|
||||
use App\Models\Credit;
|
||||
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
|
||||
{
|
||||
@ -28,51 +30,6 @@ class CreditExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -80,31 +37,82 @@ class CreditExport extends BaseExport
|
||||
$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);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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()
|
||||
->withTrashed()
|
||||
->with('client')->where('company_id', $this->company->id)
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$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()
|
||||
->each(function ($credit) {
|
||||
$this->csv->insertOne($this->buildRow($credit));
|
||||
@ -120,22 +128,22 @@ class CreditExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
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;
|
||||
$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)) {
|
||||
$entity[$keyval] = $transformed_credit[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_credit)) {
|
||||
if (isset($transformed_credit[$credit_key])) {
|
||||
$entity[$keyval] = $transformed_credit[$credit_key];
|
||||
} elseif (isset($transformed_credit[$keyval])) {
|
||||
$entity[$keyval] = $transformed_credit[$keyval];
|
||||
} elseif(isset($transformed_credit[$searched_credit_key])){
|
||||
$entity[$keyval] = $transformed_credit[$searched_credit_key];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($credit, $entity);
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use App\Transformers\DocumentTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -30,16 +31,11 @@ class DocumentExport extends BaseExport
|
||||
|
||||
public array $entity_keys = [
|
||||
'record_type' => 'record_type',
|
||||
// 'record_name' => 'record_name',
|
||||
'name' => 'name',
|
||||
'type' => 'type',
|
||||
'created_at' => 'created_at',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
|
||||
];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -47,28 +43,56 @@ class DocumentExport extends BaseExport
|
||||
$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);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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 = $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->csv->insertOne($this->buildRow($entity));
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Transformers\ExpenseTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -28,51 +29,6 @@ class ExpenseExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -80,24 +36,39 @@ class ExpenseExport extends BaseExport
|
||||
$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);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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()
|
||||
->with('client')
|
||||
->withTrashed()
|
||||
@ -106,6 +77,20 @@ class ExpenseExport extends BaseExport
|
||||
|
||||
$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 ($expense) {
|
||||
$this->csv->insertOne($this->buildRow($expense));
|
||||
@ -122,7 +107,6 @@ class ExpenseExport extends BaseExport
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $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)) {
|
||||
$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() : '';
|
||||
}
|
||||
|
||||
if (in_array('expense.category_id', $this->input['report_keys'])) {
|
||||
$entity['expense.category_id'] = $expense->category ? $expense->category->name : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use App\Libraries\MultiDB;
|
||||
use App\Export\CSV\BaseExport;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use App\Transformers\InvoiceTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class InvoiceExport extends BaseExport
|
||||
{
|
||||
@ -29,56 +30,6 @@ class InvoiceExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -86,24 +37,19 @@ class InvoiceExport extends BaseExport
|
||||
$this->invoice_transformer = new InvoiceTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public 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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
@ -116,6 +62,39 @@ class InvoiceExport extends BaseExport
|
||||
$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()
|
||||
->each(function ($invoice) {
|
||||
$this->csv->insertOne($this->buildRow($invoice));
|
||||
@ -131,24 +110,15 @@ class InvoiceExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
$parts = explode('.', $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);
|
||||
@ -156,32 +126,23 @@ class InvoiceExport extends BaseExport
|
||||
|
||||
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'])) {
|
||||
$entity['currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
|
||||
if (in_array('invoice.currency_id', $this->input['report_keys'])) {
|
||||
$entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
|
||||
}
|
||||
|
||||
if (in_array('client_id', $this->input['report_keys'])) {
|
||||
$entity['client'] = $invoice->client->present()->name();
|
||||
if (in_array('invoice.client_id', $this->input['report_keys'])) {
|
||||
$entity['invoice.client_id'] = $invoice->client->present()->name();
|
||||
}
|
||||
|
||||
if (in_array('status_id', $this->input['report_keys'])) {
|
||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
||||
if (in_array('invoice.status', $this->input['report_keys'])) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,11 @@
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Transformers\InvoiceTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -31,64 +31,9 @@ class InvoiceItemExport extends BaseExport
|
||||
|
||||
private bool $force_keys = false;
|
||||
|
||||
public array $entity_keys = [
|
||||
'amount' => 'amount',
|
||||
'balance' => 'balance',
|
||||
'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 $storage_array = [];
|
||||
|
||||
private array $storage_item_array = [];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
@ -103,37 +48,77 @@ class InvoiceItemExport extends BaseExport
|
||||
$this->invoice_transformer = new InvoiceTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public 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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$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()
|
||||
->withTrashed()
|
||||
->with('client')->where('company_id', $this->company->id)
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$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()
|
||||
->each(function ($invoice) {
|
||||
$this->iterateItems($invoice);
|
||||
});
|
||||
|
||||
$this->csv->insertAll($this->storage_array);
|
||||
|
||||
return $this->csv->toString();
|
||||
}
|
||||
|
||||
@ -146,46 +131,32 @@ class InvoiceItemExport extends BaseExport
|
||||
foreach ($invoice->line_items as $item) {
|
||||
$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.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "invoice", $key);
|
||||
|
||||
if($key == 'type_id')
|
||||
$keyval = 'type';
|
||||
$key = 'type';
|
||||
|
||||
if($key == 'tax_id')
|
||||
$keyval = 'tax_category';
|
||||
$key = 'tax_category';
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
} else {
|
||||
$item_array[$keyval] = '';
|
||||
$item_array[$key] = $item->{$key};
|
||||
}
|
||||
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);
|
||||
$entity = $this->decorateAdvancedFields($invoice, $transformed_items);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
$this->storage_array[] = $entity;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,23 +167,19 @@ class InvoiceItemExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
$parts = explode('.', $key);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
if(is_array($parts) && $parts[0] == 'item')
|
||||
continue;
|
||||
|
||||
if (array_key_exists($key, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
||||
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||
}else if (array_key_exists($key, $transformed_invoice)) {
|
||||
$entity[$key] = $transformed_invoice[$key];
|
||||
}
|
||||
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']);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\Payment;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -27,40 +28,6 @@ class PaymentExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -68,24 +35,19 @@ class PaymentExport extends BaseExport
|
||||
$this->entity_transformer = new PaymentTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
@ -93,6 +55,39 @@ class PaymentExport extends BaseExport
|
||||
|
||||
$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()
|
||||
->each(function ($entity) {
|
||||
$this->csv->insertOne($this->buildRow($entity));
|
||||
@ -108,24 +103,17 @@ class PaymentExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("payment.", "", $key), $this->entity_keys) ?? $key;
|
||||
$parts = explode('.', $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);
|
||||
|
@ -13,10 +13,10 @@ namespace App\Export\CSV;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use App\Models\Product;
|
||||
use App\Transformers\ProductTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -28,31 +28,6 @@ class ProductExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -60,24 +35,38 @@ class ProductExport extends BaseExport
|
||||
$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);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
@ -85,6 +74,21 @@ class ProductExport extends BaseExport
|
||||
|
||||
$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->csv->insertOne($this->buildRow($entity));
|
||||
@ -100,7 +104,7 @@ class ProductExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
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)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
|
@ -85,7 +85,7 @@ class ProductSalesExport extends BaseExport
|
||||
$t = app('translator');
|
||||
$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
|
||||
$this->csv = Writer::createFromString();
|
||||
@ -187,6 +187,7 @@ class ProductSalesExport extends BaseExport
|
||||
$product = $this->getProduct($entity['product_key']);
|
||||
|
||||
$entity['cost'] = $product->cost ?? 0;
|
||||
/** @var float $unit_cost */
|
||||
$unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];
|
||||
|
||||
$entity['client'] = $invoice->client->present()->name();
|
||||
|
@ -11,14 +11,15 @@
|
||||
|
||||
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\Number;
|
||||
use Illuminate\Support\Facades\App;
|
||||
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
|
||||
{
|
||||
@ -81,24 +82,19 @@ class PurchaseOrderExport extends BaseExport
|
||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
|
||||
public 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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->with('vendor')
|
||||
@ -107,9 +103,39 @@ class PurchaseOrderExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
// if(isset($this->input['status'])) {
|
||||
// $query = $this->addPurchaseOrderStatusFilter($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()
|
||||
->each(function ($purchase_order) {
|
||||
@ -126,23 +152,16 @@ class PurchaseOrderExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
$parts = explode('.', $key);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $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];
|
||||
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
|
||||
$entity[$key] = $transformed_purchase_order[$parts[1]];
|
||||
} 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);
|
||||
|
@ -11,13 +11,14 @@
|
||||
|
||||
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 Illuminate\Support\Facades\App;
|
||||
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
|
||||
{
|
||||
@ -30,70 +31,9 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
|
||||
private bool $force_keys = false;
|
||||
|
||||
public array $entity_keys = [
|
||||
'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 $storage_array = [];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
'currency_id',
|
||||
'status'
|
||||
];
|
||||
private array $storage_item_array = [];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
@ -102,25 +42,19 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->force_keys = true;
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
$this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
|
||||
}
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')->where('company_id', $this->company->id)
|
||||
@ -128,12 +62,54 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
|
||||
$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()
|
||||
->each(function ($purchase_order) {
|
||||
$this->iterateItems($purchase_order);
|
||||
});
|
||||
|
||||
$this->csv->insertAll($this->storage_array);
|
||||
|
||||
return $this->csv->toString();
|
||||
|
||||
}
|
||||
|
||||
private function iterateItems(PurchaseOrder $purchase_order)
|
||||
@ -145,16 +121,12 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
foreach ($purchase_order->line_items as $item) {
|
||||
$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.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "purchase_order", $key);
|
||||
|
||||
if($key == 'type_id') {
|
||||
$keyval = 'type';
|
||||
}
|
||||
@ -164,29 +136,17 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
}
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
$item_array[$key] = $item->{$key};
|
||||
} 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);
|
||||
$entity = $this->decorateAdvancedFields($purchase_order, $transformed_items);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
$this->storage_array[] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,22 +157,18 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
$parts = explode('.', $key);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
||||
if(is_array($parts) && $parts[0] == 'item') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $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];
|
||||
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
|
||||
$entity[$key] = $transformed_purchase_order[$parts[1]];
|
||||
} elseif (array_key_exists($key, $transformed_purchase_order)) {
|
||||
$entity[$key] = $transformed_purchase_order[$key];
|
||||
} 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\Quote;
|
||||
use App\Transformers\QuoteTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -28,43 +29,6 @@ class QuoteExport extends BaseExport
|
||||
|
||||
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 = [
|
||||
'client',
|
||||
'currency',
|
||||
@ -78,24 +42,20 @@ class QuoteExport extends BaseExport
|
||||
$this->quote_transformer = new QuoteTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
@ -104,6 +64,41 @@ class QuoteExport extends BaseExport
|
||||
|
||||
$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()
|
||||
->each(function ($quote) {
|
||||
$this->csv->insertOne($this->buildRow($quote));
|
||||
@ -114,50 +109,42 @@ class QuoteExport extends BaseExport
|
||||
|
||||
private function buildRow(Quote $quote) :array
|
||||
{
|
||||
$transformed_entity = $this->quote_transformer->transform($quote);
|
||||
$transformed_invoice = $this->quote_transformer->transform($quote);
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
$parts = explode('.', $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);
|
||||
}
|
||||
|
||||
|
||||
private function decorateAdvancedFields(Quote $quote, array $entity) :array
|
||||
{
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
$entity['currency'] = $quote->client->currency()->code;
|
||||
if (in_array('quote.currency_id', $this->input['report_keys'])) {
|
||||
$entity['quote.currency'] = $quote->client->currency()->code;
|
||||
}
|
||||
|
||||
if (in_array('client_id', $this->input['report_keys'])) {
|
||||
$entity['client'] = $quote->client->present()->name();
|
||||
if (in_array('quote.client_id', $this->input['report_keys'])) {
|
||||
$entity['quote.client'] = $quote->client->present()->name();
|
||||
}
|
||||
|
||||
if (in_array('status_id', $this->input['report_keys'])) {
|
||||
$entity['status'] = $quote->stringStatus($quote->status_id);
|
||||
if (in_array('quote.status', $this->input['report_keys'])) {
|
||||
$entity['quote.status'] = $quote->stringStatus($quote->status_id);
|
||||
}
|
||||
|
||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
||||
$entity['invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
||||
if (in_array('quote.invoice_id', $this->input['report_keys'])) {
|
||||
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\Quote;
|
||||
use App\Transformers\QuoteTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -28,63 +29,8 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
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' => '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 $storage_array = [];
|
||||
private array $storage_item_array = [];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
@ -98,24 +44,19 @@ class QuoteItemExport extends BaseExport
|
||||
$this->quote_transformer = new QuoteTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public 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));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->with('client')->where('company_id', $this->company->id)
|
||||
@ -123,12 +64,58 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
$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()
|
||||
->each(function ($quote) {
|
||||
$this->iterateItems($quote);
|
||||
});
|
||||
|
||||
$this->csv->insertAll($this->storage_array);
|
||||
|
||||
return $this->csv->toString();
|
||||
|
||||
}
|
||||
|
||||
private function iterateItems(Quote $quote)
|
||||
@ -137,51 +124,34 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
$transformed_items = [];
|
||||
|
||||
$transformed_items = [];
|
||||
|
||||
foreach ($quote->line_items as $item) {
|
||||
$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.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "quote", $key);
|
||||
|
||||
if($key == 'type_id')
|
||||
$keyval = 'type';
|
||||
$key = 'type';
|
||||
|
||||
if($key == 'tax_id')
|
||||
$keyval = 'tax_category';
|
||||
$key = 'tax_category';
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
} else {
|
||||
$item_array[$keyval] = '';
|
||||
$item_array[$key] = $item->{$key};
|
||||
}
|
||||
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);
|
||||
$entity = $this->decorateAdvancedFields($quote, $transformed_items);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
$this->storage_array[] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,25 +162,22 @@ class QuoteItemExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("quote.", "", $key), $this->entity_keys) ?? $key;
|
||||
$parts = explode('.', $key);
|
||||
|
||||
if(is_array($parts) && $parts[0] == 'item') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_quote)) {
|
||||
$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);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Company;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Transformers\RecurringInvoiceTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -28,56 +29,6 @@ class RecurringInvoiceExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -85,7 +36,7 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$this->invoice_transformer = new RecurringInvoiceTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public function init(): Builder
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
@ -93,23 +44,33 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$t = app('translator');
|
||||
$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) {
|
||||
$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()
|
||||
->withTrashed()
|
||||
->with('client')->where('company_id', $this->company->id)
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$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 ($invoice) {
|
||||
$this->csv->insertOne($this->buildRow($invoice));
|
||||
@ -118,6 +79,27 @@ class RecurringInvoiceExport extends BaseExport
|
||||
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
|
||||
{
|
||||
$transformed_invoice = $this->invoice_transformer->transform($invoice);
|
||||
@ -125,22 +107,13 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("recurring_invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
$parts = explode('.', $key);
|
||||
|
||||
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];
|
||||
if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||
} 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'])) {
|
||||
$entity['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||
$entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Task;
|
||||
use App\Models\Timezone;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
@ -33,30 +34,9 @@ class TaskExport extends BaseExport
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
public array $entity_keys = [
|
||||
'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 $storage_array = [];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'status',
|
||||
'project',
|
||||
'client',
|
||||
'invoice',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'duration',
|
||||
];
|
||||
private array $storage_item_array = [];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
@ -65,7 +45,7 @@ class TaskExport extends BaseExport
|
||||
$this->entity_transformer = new TaskTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public function init(): Builder
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
@ -74,19 +54,12 @@ class TaskExport extends BaseExport
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
|
||||
$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);
|
||||
|
||||
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()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
@ -94,52 +67,87 @@ class TaskExport extends BaseExport
|
||||
|
||||
$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);
|
||||
});
|
||||
|
||||
$this->csv->insertAll($this->storage_array);
|
||||
|
||||
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)
|
||||
{
|
||||
$entity = [];
|
||||
$transformed_entity = $this->entity_transformer->transform($task);
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
|
||||
$parts = explode('.', $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[$keyval] = $transformed_entity[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $task, $this->entity_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
$entity['start_date'] = '';
|
||||
$entity['end_date'] = '';
|
||||
$entity['duration'] = '';
|
||||
|
||||
$entity['task.start_date'] = '';
|
||||
$entity['task.end_date'] = '';
|
||||
$entity['task.duration'] = '';
|
||||
|
||||
if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
|
||||
$this->csv->insertOne($entity);
|
||||
$this->storage_array[] = $entity;
|
||||
} else {
|
||||
$this->iterateLogs($task, $entity);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function iterateLogs(Task $task, array $entity)
|
||||
@ -163,39 +171,40 @@ class TaskExport extends BaseExport
|
||||
|
||||
foreach ($logs as $key => $item) {
|
||||
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) {
|
||||
$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) {
|
||||
$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'])) {
|
||||
$entity['duration'] = $task->calcDuration();
|
||||
$entity['task.duration'] = $task->calcDuration();
|
||||
}
|
||||
|
||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
$this->storage_array[] = $entity;
|
||||
|
||||
unset($entity['start_date']);
|
||||
unset($entity['end_date']);
|
||||
unset($entity['duration']);
|
||||
unset($entity['task.start_date']);
|
||||
unset($entity['task.end_date']);
|
||||
unset($entity['task.duration']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(Task $task, array $entity) :array
|
||||
{
|
||||
if (in_array('status_id', $this->input['report_keys'])) {
|
||||
$entity['status'] = $task->status()->exists() ? $task->status->name : '';
|
||||
if (in_array('task.status_id', $this->input['report_keys'])) {
|
||||
$entity['task.status_id'] = $task->status()->exists() ? $task->status->name : '';
|
||||
}
|
||||
|
||||
if (in_array('project_id', $this->input['report_keys'])) {
|
||||
$entity['project'] = $task->project()->exists() ? $task->project->name : '';
|
||||
if (in_array('task.project_id', $this->input['report_keys'])) {
|
||||
$entity['task.project_id'] = $task->project()->exists() ? $task->project->name : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
|
@ -17,6 +17,7 @@ use App\Models\Company;
|
||||
use App\Transformers\VendorContactTransformer;
|
||||
use App\Transformers\VendorTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
@ -31,46 +32,6 @@ class VendorExport extends BaseExport
|
||||
|
||||
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)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -79,8 +40,9 @@ class VendorExport extends BaseExport
|
||||
$this->contact_transformer = new VendorContactTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
public function init(): Builder
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
@ -91,12 +53,9 @@ class VendorExport extends BaseExport
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
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')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
@ -104,6 +63,37 @@ class VendorExport extends BaseExport
|
||||
|
||||
$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()
|
||||
->each(function ($vendor) {
|
||||
$this->csv->insertOne($this->buildRow($vendor));
|
||||
@ -114,7 +104,7 @@ class VendorExport extends BaseExport
|
||||
|
||||
private function buildRow(Vendor $vendor) :array
|
||||
{
|
||||
$transformed_contact = [];
|
||||
$transformed_contact = false;
|
||||
|
||||
$transformed_vendor = $this->vendor_transformer->transform($vendor);
|
||||
|
||||
@ -127,14 +117,12 @@ class VendorExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $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)) {
|
||||
$entity[$keyval] = $transformed_vendor[$parts[1]];
|
||||
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
||||
$entity[$key] = $transformed_vendor[$parts[1]];
|
||||
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
|
||||
$entity[$key] = $transformed_contact[$parts[1]];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ class ClientFactory
|
||||
$client->is_deleted = 0;
|
||||
$client->client_hash = Str::random(40);
|
||||
$client->settings = ClientSettings::defaults();
|
||||
$client->classification = '';
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
@ -34,7 +34,9 @@ class RecurringExpenseFactory
|
||||
$recurring_expense->tax_amount1 = 0;
|
||||
$recurring_expense->tax_amount2 = 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->amount = 0;
|
||||
$recurring_expense->foreign_amount = 0;
|
||||
@ -47,6 +49,7 @@ class RecurringExpenseFactory
|
||||
$recurring_expense->custom_value4 = '';
|
||||
$recurring_expense->uses_inclusive_taxes = true;
|
||||
$recurring_expense->calculate_tax_by_amount = true;
|
||||
$recurring_expense->remaining_cycles = -1;
|
||||
|
||||
return $recurring_expense;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ class RecurringExpenseToExpenseFactory
|
||||
$expense->tax_amount3 = $recurring_expense->tax_amount3 ?: 0;
|
||||
$expense->uses_inclusive_taxes = $recurring_expense->uses_inclusive_taxes;
|
||||
$expense->calculate_tax_by_amount = $recurring_expense->calculate_tax_by_amount;
|
||||
$expense->invoice_currency_id = $recurring_expense->invoice_currency_id;
|
||||
|
||||
return $expense;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class VendorFactory
|
||||
$vendor->country_id = 4;
|
||||
$vendor->is_deleted = 0;
|
||||
$vendor->vendor_hash = Str::random(40);
|
||||
$vendor->classification = '';
|
||||
|
||||
return $vendor;
|
||||
}
|
||||
|
@ -88,6 +88,11 @@ class CreditFilters extends QueryFilters
|
||||
->orWhere('credits.custom_value4', 'like', '%'.$filter.'%')
|
||||
->orWhereHas('client', function ($q) use ($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_value2', '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;
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'client_id') {
|
||||
return $this->builder->orderBy(\App\Models\Client::select('name')
|
||||
if ($sort_col[0] == 'client_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||
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]);
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'vendor_id') {
|
||||
return $this->builder->orderBy(\App\Models\Vendor::select('name')
|
||||
if ($sort_col[0] == 'vendor_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||
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]);
|
||||
|
||||
}
|
||||
|
||||
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'])) {
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
|
@ -116,6 +116,11 @@ class InvoiceFilters extends QueryFilters
|
||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||
->orWhereHas('client', function ($q) use ($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);
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -12,7 +12,9 @@
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
|
||||
|
||||
/**
|
||||
* PaymentFilters.
|
||||
@ -43,6 +45,11 @@ class PaymentFilters extends QueryFilters
|
||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||
->orWhereHas('client', function ($q) use ($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
|
||||
* @param ?string $value
|
||||
* @return Builder
|
||||
*/
|
||||
public function match_transactions($value = 'true'): Builder
|
||||
{
|
||||
@ -124,7 +133,7 @@ class PaymentFilters extends QueryFilters
|
||||
if ($value == 'true') {
|
||||
return $this->builder
|
||||
->where('is_deleted', 0)
|
||||
->where(function ($query) {
|
||||
->where(function (Builder $query) {
|
||||
$query->whereNull('transaction_id')
|
||||
->orWhere("transaction_id", "")
|
||||
->company();
|
||||
@ -169,6 +178,33 @@ class PaymentFilters extends QueryFilters
|
||||
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.
|
||||
*
|
||||
|
@ -72,8 +72,8 @@ abstract class QueryFilters
|
||||
/**
|
||||
* Apply the filters to the builder.
|
||||
*
|
||||
* @param Builder $builder
|
||||
* @return Builder
|
||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||
* @return \Illuminate\Database\Eloquent\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')
|
||||
{
|
||||
if ($value == 'true') {
|
||||
@ -294,7 +298,7 @@ abstract class QueryFilters
|
||||
{
|
||||
return $this->builder->where(function ($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);
|
||||
});
|
||||
}
|
||||
@ -306,7 +310,7 @@ abstract class QueryFilters
|
||||
{
|
||||
return $this->builder->where(function ($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);
|
||||
});
|
||||
}
|
||||
|
@ -40,6 +40,11 @@ class QuoteFilters extends QueryFilters
|
||||
->orWhere('custom_value4', 'like', '%'.$filter.'%')
|
||||
->orWhereHas('client', function ($q) use ($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.'%')
|
||||
->orWhereHas('client', function ($q) use ($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) {
|
||||
$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));
|
||||
|
||||
return $this->builder->where(function ($query) use ($user_array) {
|
||||
$query->whereNotIn('id', $user_array)
|
||||
->where('account_id', auth()->user()->account_id);
|
||||
$query->whereNotIn('id', $user_array);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
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
|
||||
{
|
||||
|
||||
public function transform($yodlee_account)
|
||||
{
|
||||
$data = [];
|
||||
@ -93,13 +94,54 @@ class AccountTransformer implements AccountTransformerInterface
|
||||
$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 [
|
||||
'id' => $account->id,
|
||||
'account_type' => $account->CONTAINER,
|
||||
// 'account_name' => $account->accountName,
|
||||
'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) : '',
|
||||
'provider_account_id' => $account->providerAccountId,
|
||||
'provider_id' => $account->providerId,
|
||||
|
@ -297,4 +297,71 @@ class Yodlee
|
||||
'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
|
||||
{
|
||||
$this->sub_total += $this->getLineTotal();
|
||||
$this->sub_total += round($this->getLineTotal(), $this->currency->precision);
|
||||
|
||||
$this->gross_sub_total += $this->getGrossLineTotal();
|
||||
|
||||
@ -391,15 +391,15 @@ class InvoiceItemSum
|
||||
{
|
||||
$this->setGroupedTaxes(collect([]));
|
||||
|
||||
$item_tax = 0;
|
||||
|
||||
foreach ($this->line_items as $this->item) {
|
||||
foreach ($this->line_items as $key => $this->item) {
|
||||
if ($this->item->line_total == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item_tax = 0;
|
||||
|
||||
//$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);
|
||||
|
||||
@ -424,9 +424,19 @@ class InvoiceItemSum
|
||||
if ($item_tax_rate3_total != 0) {
|
||||
$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;
|
||||
|
||||
private $currency;
|
||||
private \App\Models\Currency $currency;
|
||||
|
||||
private $total_taxes;
|
||||
|
||||
@ -226,8 +226,10 @@ class InvoiceItemSumInclusive
|
||||
|
||||
$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);
|
||||
|
||||
/** @var float $item_tax */
|
||||
$item_tax += $this->formatValue($item_tax_rate1_total, $this->currency->precision);
|
||||
|
||||
if (strlen($this->item->tax_name1) > 1) {
|
||||
@ -347,15 +349,17 @@ class InvoiceItemSumInclusive
|
||||
{
|
||||
$this->setGroupedTaxes(collect([]));
|
||||
|
||||
$item_tax = 0;
|
||||
|
||||
foreach ($this->line_items as $this->item) {
|
||||
if ($this->sub_total == 0) {
|
||||
$amount = $this->item->line_total;
|
||||
} 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 += $item_tax_rate1_total;
|
||||
@ -379,9 +383,17 @@ class InvoiceItemSumInclusive
|
||||
if ($item_tax_rate3_total != 0) {
|
||||
$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
|
||||
{
|
||||
if ($this->invoice->is_amount_discount == true) {
|
||||
if ($this->invoice->is_amount_discount) {
|
||||
$this->invoice_items->calcTaxesWithAmountDiscount();
|
||||
$this->invoice->line_items = $this->invoice_items->getLineItems();
|
||||
}
|
||||
|
||||
$this->tax_map = collect();
|
||||
@ -327,8 +328,6 @@ class InvoiceSum
|
||||
return $value['key'] == $key;
|
||||
})->sum('total');
|
||||
|
||||
//$total_line_tax -= $this->discount($total_line_tax);
|
||||
|
||||
$this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
|
||||
|
||||
$this->total_taxes += $total_line_tax;
|
||||
@ -377,16 +376,6 @@ class InvoiceSum
|
||||
|
||||
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);
|
||||
|
||||
|
@ -315,8 +315,9 @@ class InvoiceSumInclusive
|
||||
|
||||
public function setTaxMap()
|
||||
{
|
||||
if ($this->invoice->is_amount_discount == true) {
|
||||
if ($this->invoice->is_amount_discount) {
|
||||
$this->invoice_items->calcTaxesWithAmountDiscount();
|
||||
$this->invoice->line_items = $this->invoice_items->getLineItems();
|
||||
}
|
||||
|
||||
$this->tax_map = collect();
|
||||
|
@ -33,6 +33,7 @@ class GmailTransport extends AbstractTransport
|
||||
nlog("In Do Send");
|
||||
$message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$token = $message->getHeaders()->get('gmailtoken')->getValue();
|
||||
$message->getHeaders()->remove('gmailtoken');
|
||||
|
||||
@ -52,6 +53,8 @@ class GmailTransport extends AbstractTransport
|
||||
if ($bccs) {
|
||||
$bcc_list = 'Bcc: ';
|
||||
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
$bcc_list .= $address->getAddress() .',';
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ class Office365MailTransport extends AbstractTransport
|
||||
$symfony_message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||
|
||||
$graph = new Graph();
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$token = $symfony_message->getHeaders()->get('gmailtoken')->getValue();
|
||||
$symfony_message->getHeaders()->remove('gmailtoken');
|
||||
|
||||
@ -38,6 +40,8 @@ class Office365MailTransport extends AbstractTransport
|
||||
$bcc_list = '';
|
||||
|
||||
if ($bccs) {
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
$bcc_list .= 'Bcc: "'.$address->getAddress().'" <'.$address->getAddress().'>\r\n';
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class SubscriptionCalculator
|
||||
*/
|
||||
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('client_id', $this->invoice->client_id)
|
||||
->where('balance', '>', 0)
|
||||
|
@ -72,7 +72,7 @@ class AccountController extends BaseController
|
||||
|
||||
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();
|
||||
|
||||
|
@ -418,10 +418,12 @@ class LoginController extends BaseController
|
||||
->setReturnType(Model\User::class)
|
||||
->execute();
|
||||
|
||||
nlog($user);
|
||||
|
||||
if ($user) {
|
||||
$account = request()->input('account');
|
||||
|
||||
$email = $user->getMail() ?: $user->getUserPrincipalName();
|
||||
$email = $user->getUserPrincipalName() ?? false;
|
||||
|
||||
$query = [
|
||||
'oauth_user_id' => $user->getId(),
|
||||
@ -437,7 +439,7 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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');
|
||||
}
|
||||
|
||||
|
||||
// Signup!
|
||||
if (request()->has('create') && request()->input('create') == 'true') {
|
||||
$new_account = [
|
||||
|
@ -11,12 +11,14 @@
|
||||
|
||||
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\Http\Controllers\BaseController;
|
||||
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
||||
use App\Jobs\Bank\ProcessBankTransactions;
|
||||
use App\Models\BankIntegration;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\Yodlee\YodleeAuthRequest;
|
||||
use App\Http\Requests\Yodlee\YodleeAdminRequest;
|
||||
|
||||
class YodleeController extends BaseController
|
||||
{
|
||||
@ -277,4 +279,27 @@ class YodleeController extends BaseController
|
||||
|
||||
// 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)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
|
||||
public function store(StoreBankTransactionRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
//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);
|
||||
}
|
||||
|
@ -12,9 +12,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Models\BankTransactionRule;
|
||||
use App\Filters\BankTransactionFilters;
|
||||
use App\Factory\BankTransactionRuleFactory;
|
||||
use App\Filters\BankTransactionRuleFilters;
|
||||
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\UpdateBankTransactionRuleRequest;
|
||||
use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest;
|
||||
use App\Services\Bank\BankMatchingService;
|
||||
|
||||
class BankTransactionRuleController extends BaseController
|
||||
{
|
||||
@ -256,8 +255,12 @@ class BankTransactionRuleController extends BaseController
|
||||
*/
|
||||
public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule)
|
||||
{
|
||||
//stubs for updating the model
|
||||
$bank_transaction = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule);
|
||||
/** @var \App\Models\User $user */
|
||||
$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());
|
||||
}
|
||||
@ -304,6 +307,7 @@ class BankTransactionRuleController extends BaseController
|
||||
{
|
||||
/** @var \App\Models\User $user **/
|
||||
$user = auth()->user();
|
||||
|
||||
$bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id);
|
||||
|
||||
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));
|
||||
|
||||
BankMatchingService::dispatch($user->company()->id, $user->company()->db);
|
||||
|
||||
return $this->itemResponse($bank_transaction_rule);
|
||||
}
|
||||
|
||||
|
@ -530,9 +530,8 @@ class BaseController extends Controller
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
$query = $paginator->getCollection(); /** @phpstan-ignore-line */
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$query = $paginator->getCollection();
|
||||
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
|
||||
@ -636,7 +635,7 @@ class BaseController extends Controller
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$query = $paginator->getCollection();
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
@ -885,7 +884,7 @@ class BaseController extends Controller
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$query = $paginator->getCollection();
|
||||
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
@ -1066,7 +1065,7 @@ class BaseController extends Controller
|
||||
$data = $this->first_load;
|
||||
}
|
||||
} else {
|
||||
$included = request()->input('include');
|
||||
$included = request()->input('include', '');
|
||||
$included = explode(',', $included);
|
||||
|
||||
foreach ($included as $include) {
|
||||
|
@ -11,30 +11,31 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Events\Client\ClientWasCreated;
|
||||
use App\Events\Client\ClientWasUpdated;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Client;
|
||||
use App\Models\Account;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Factory\ClientFactory;
|
||||
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\CreateClientRequest;
|
||||
use App\Http\Requests\Client\DestroyClientRequest;
|
||||
use App\Http\Requests\Client\EditClientRequest;
|
||||
use App\Http\Requests\Client\PurgeClientRequest;
|
||||
use App\Http\Requests\Client\ShowClientRequest;
|
||||
use App\Http\Requests\Client\PurgeClientRequest;
|
||||
use App\Http\Requests\Client\StoreClientRequest;
|
||||
use App\Http\Requests\Client\CreateClientRequest;
|
||||
use App\Http\Requests\Client\UpdateClientRequest;
|
||||
use App\Http\Requests\Client\UploadClientRequest;
|
||||
use App\Models\Account;
|
||||
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;
|
||||
use App\Http\Requests\Client\DestroyClientRequest;
|
||||
|
||||
/**
|
||||
* Class ClientController.
|
||||
@ -227,7 +228,7 @@ class ClientController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
@ -285,4 +286,18 @@ class ClientController extends BaseController
|
||||
|
||||
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 */
|
||||
|
||||
if (Ninja::isSelfHost()) {
|
||||
$cgs = CompanyGateway::whereIn('gateway_key', $this->stripe_keys)
|
||||
$cgs = CompanyGateway::query()
|
||||
->whereIn('gateway_key', $this->stripe_keys)
|
||||
->where('is_deleted', false)
|
||||
->get();
|
||||
|
||||
|
@ -30,7 +30,8 @@ class CreditController extends Controller
|
||||
{
|
||||
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 = [
|
||||
'credit' => $credit,
|
||||
|
@ -71,7 +71,7 @@ class DocumentController extends Controller
|
||||
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
|
||||
{
|
||||
/** @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)
|
||||
->get();
|
||||
|
||||
|
@ -17,6 +17,10 @@ use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* EntityViewController
|
||||
* @deprecated 5.7 ?
|
||||
*/
|
||||
class EntityViewController extends Controller
|
||||
{
|
||||
use MakesHash;
|
||||
|
@ -11,26 +11,27 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Events\Credit\CreditWasViewed;
|
||||
use App\Events\Invoice\InvoiceWasViewed;
|
||||
use App\Events\Misc\InvitationWasViewed;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Client;
|
||||
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\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\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.
|
||||
@ -94,6 +95,7 @@ class InvitationController extends Controller
|
||||
}
|
||||
|
||||
$client_contact = $invitation->contact;
|
||||
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars()));
|
||||
|
||||
if (empty($client_contact->email)) {
|
||||
$client_contact->email = Str::random(15) . "@example.com";
|
||||
|
@ -87,14 +87,19 @@ class InvoiceController extends Controller
|
||||
public function showBlob($hash)
|
||||
{
|
||||
$data = Cache::get($hash);
|
||||
$invitation = false;
|
||||
|
||||
match($data['entity_type']){
|
||||
match($data['entity_type'] ?? false){
|
||||
'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
||||
'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
|
||||
'credit' => $invitation = CreditInvitation::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();
|
||||
|
||||
$headers = ['Content-Type' => 'application/pdf'];
|
||||
@ -128,7 +133,8 @@ class InvoiceController extends Controller
|
||||
|
||||
public function downloadInvoices($ids)
|
||||
{
|
||||
$data['invoices'] = Invoice::whereIn('id', $ids)
|
||||
$data['invoices'] = Invoice::query()
|
||||
->whereIn('id', $ids)
|
||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||
->withTrashed()
|
||||
->get();
|
||||
@ -153,7 +159,8 @@ class InvoiceController extends Controller
|
||||
*/
|
||||
private function makePayment(array $ids)
|
||||
{
|
||||
$invoices = Invoice::whereIn('id', $ids)
|
||||
$invoices = Invoice::query()
|
||||
->whereIn('id', $ids)
|
||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||
->withTrashed()
|
||||
->get();
|
||||
@ -215,7 +222,8 @@ class InvoiceController extends Controller
|
||||
*/
|
||||
private function downloadInvoicePDF(array $ids)
|
||||
{
|
||||
$invoices = Invoice::whereIn('id', $ids)
|
||||
$invoices = Invoice::query()
|
||||
->whereIn('id', $ids)
|
||||
->withTrashed()
|
||||
->whereClientId(auth()->guard('contact')->user()->client->id)
|
||||
->get();
|
||||
@ -244,11 +252,20 @@ class InvoiceController extends Controller
|
||||
// create new archive
|
||||
$zipFile = new \PhpZip\ZipFile();
|
||||
try {
|
||||
|
||||
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';
|
||||
$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)
|
||||
{
|
||||
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) {
|
||||
MultiDB::findAndSetDbByAccountKey($account_or_company_key);
|
||||
|
||||
/** @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 {
|
||||
$account = $company->account;
|
||||
}
|
||||
@ -157,6 +157,8 @@ class NinjaPlanController extends Controller
|
||||
|
||||
//create recurring invoice
|
||||
$subscription_repo = new SubscriptionRepository();
|
||||
|
||||
/** @var \App\Models\Subscription $subscription **/
|
||||
$subscription = Subscription::find(6);
|
||||
|
||||
$recurring_invoice = RecurringInvoiceFactory::create($subscription->company_id, $subscription->user_id);
|
||||
@ -181,7 +183,7 @@ class NinjaPlanController extends Controller
|
||||
->increment()
|
||||
->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('id', '!=', $recurring_invoice->id)
|
||||
->first();
|
||||
@ -215,7 +217,7 @@ class NinjaPlanController extends Controller
|
||||
$data['late_invoice'] = false;
|
||||
|
||||
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) {
|
||||
//offer the option to have a free trial
|
||||
|
@ -169,7 +169,7 @@ class PaymentController extends Controller
|
||||
$payment = $payment->service()->applyCredits($payment_hash)->save();
|
||||
|
||||
/** @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) {
|
||||
/** @var \App\Models\Invoice $invoice **/
|
||||
|
@ -12,21 +12,22 @@
|
||||
|
||||
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\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\ShowQuotesRequest;
|
||||
use App\Jobs\Invoice\InjectSignature;
|
||||
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;
|
||||
use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
|
||||
|
||||
class QuoteController extends Controller
|
||||
{
|
||||
@ -53,7 +54,7 @@ class QuoteController extends Controller
|
||||
{
|
||||
/* 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 = [
|
||||
'quote' => $quote,
|
||||
@ -95,8 +96,9 @@ class QuoteController extends Controller
|
||||
/** @var \App\Models\ClientContact $client_contact **/
|
||||
$client_contact = auth()->user();
|
||||
|
||||
$data['quotes'] = Quote::whereIn('id', $ids)
|
||||
->whereClientId($client_contact->client->id)
|
||||
$data['quotes'] = Quote::query()
|
||||
->whereIn('id', $ids)
|
||||
->where('client_id', $client_contact->client_id)
|
||||
->withTrashed()
|
||||
->get();
|
||||
|
||||
@ -120,36 +122,38 @@ class QuoteController extends Controller
|
||||
/** @var \App\Models\ClientContact $client_contact **/
|
||||
$client_contact = auth()->user();
|
||||
|
||||
$quotes = Quote::whereIn('id', $ids)
|
||||
->whereClientId($client_contact->client_id)
|
||||
$quote_invitations = QuoteInvitation::query()
|
||||
->with('quote','company')
|
||||
->whereIn('quote_id', $ids)
|
||||
->where('client_contact_id', $client_contact->id)
|
||||
->withTrashed()
|
||||
->get();
|
||||
|
||||
if (! $quotes || $quotes->count() == 0) {
|
||||
if (! $quote_invitations || $quote_invitations->count() == 0) {
|
||||
return redirect()
|
||||
->route('client.quotes.index')
|
||||
->with('message', ctrans('texts.no_quotes_available_for_download'));
|
||||
}
|
||||
|
||||
if ($quotes->count() == 1) {
|
||||
$file = $quotes->first()->service()->getQuotePdf();
|
||||
// return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
if ($quote_invitations->count() == 1) {
|
||||
$invitation = $quote_invitations->first();
|
||||
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||
return response()->streamDownload(function () use ($file) {
|
||||
echo Storage::get($file);
|
||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||
echo $file;
|
||||
}, $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
|
||||
$zipFile = new \PhpZip\ZipFile();
|
||||
try {
|
||||
foreach ($quotes as $quote) {
|
||||
//add it to the zip
|
||||
$zipFile->addFromString(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true)));
|
||||
foreach ($quote_invitations as $invitation) {
|
||||
$file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||
$zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file);
|
||||
}
|
||||
|
||||
$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);
|
||||
} catch (\PhpZip\Exception\ZipException $e) {
|
||||
// handle exception
|
||||
} finally {
|
||||
$zipFile->close();
|
||||
}
|
||||
@ -168,7 +171,8 @@ class QuoteController extends Controller
|
||||
|
||||
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('company_id', auth()->guard('contact')->user()->client->company_id)
|
||||
->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
|
||||
if ($quote->invoice()->exists()) {
|
||||
return redirect()->route('client.invoice.show', $quote->invoice->hashed_id);
|
||||
if ($quotes->first()->invoice()->exists()) {
|
||||
return redirect()->route('client.invoice.show', $quotes->first()->invoice->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)
|
||||
{
|
||||
$client_contact = ClientContact::where('email', auth()->user()->email)
|
||||
$client_contact = ClientContact::query()
|
||||
->where('email', auth()->user()->email)
|
||||
->where('id', $this->transformKeys($contact))
|
||||
->first();
|
||||
->firstOrFail();
|
||||
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
|
@ -34,7 +34,7 @@ class UploadController extends Controller
|
||||
/** @var \App\Models\ClientContact $client_contact **/
|
||||
$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);
|
||||
}
|
||||
|
@ -11,38 +11,39 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\DataMapper\Analytics\AccountDeleted;
|
||||
use App\DataMapper\CompanySettings;
|
||||
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 Str;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
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\Support\Facades\Storage;
|
||||
use Str;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
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 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.
|
||||
@ -423,7 +424,7 @@ class CompanyController extends BaseController
|
||||
$company = $this->company_repo->save($request->all(), $company);
|
||||
|
||||
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"))){
|
||||
@ -615,7 +616,7 @@ class CompanyController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
@ -679,4 +680,36 @@ class CompanyController extends BaseController
|
||||
|
||||
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)
|
||||
{
|
||||
/** @var \App\Models\User $auth_user */
|
||||
$auth_user = auth()->user();
|
||||
$company = $auth_user->company();
|
||||
|
||||
$company = auth()->user()->company();
|
||||
|
||||
$company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
|
||||
$company_user = CompanyUser::query()->where('user_id', $user->id)->where('company_id',$company->id)->first();
|
||||
|
||||
if (! $company_user) {
|
||||
throw new ModelNotFoundException(ctrans('texts.company_user_not_found'));
|
||||
@ -122,11 +123,16 @@ class CompanyUserController extends BaseController
|
||||
return;
|
||||
}
|
||||
|
||||
if (auth()->user()->isAdmin()) {
|
||||
if ($auth_user->isAdmin()) {
|
||||
$company_user->fill($request->input('company_user'));
|
||||
} else {
|
||||
$company_user->settings = $request->input('company_user')['settings'];
|
||||
$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();
|
||||
@ -136,8 +142,11 @@ class CompanyUserController extends BaseController
|
||||
|
||||
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();
|
||||
|
||||
|
@ -105,7 +105,7 @@ class ConnectedAccountController extends BaseController
|
||||
->execute();
|
||||
|
||||
if ($user) {
|
||||
$email = $user->getMail() ?: $user->getUserPrincipalName();
|
||||
$email = $user->getUserPrincipalName() ?? false;
|
||||
|
||||
nlog("microsoft");
|
||||
nlog($email);
|
||||
|
@ -151,7 +151,7 @@ class CreditController extends BaseController
|
||||
/** @var \App\Models\User $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);
|
||||
}
|
||||
@ -200,8 +200,6 @@ class CreditController extends BaseController
|
||||
/** @var \App\Models\User $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 = $credit->service()
|
||||
@ -387,8 +385,8 @@ class CreditController extends BaseController
|
||||
$credit = $this->credit_repository->save($request->all(), $credit);
|
||||
|
||||
$credit->service()
|
||||
->triggeredActions($request)
|
||||
->deletePdf();
|
||||
->triggeredActions($request);
|
||||
// ->deletePdf();
|
||||
|
||||
/** @var \App\Models\User $user**/
|
||||
$user = auth()->user();
|
||||
@ -531,20 +529,18 @@ class CreditController extends BaseController
|
||||
if ($action == 'bulk_download' && $credits->count() > 1) {
|
||||
$credits->each(function ($credit) use($user){
|
||||
if ($user->cannot('view', $credit)) {
|
||||
nlog('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);
|
||||
}
|
||||
|
||||
if ($action == 'bulk_print' && $user->can('view', $credits->first())) {
|
||||
$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();
|
||||
@ -594,11 +590,8 @@ class CreditController extends BaseController
|
||||
}
|
||||
break;
|
||||
case 'download':
|
||||
// $file = $credit->pdf_file_path();
|
||||
$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) {
|
||||
echo Storage::get($file);
|
||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||
@ -725,7 +718,7 @@ class CreditController extends BaseController
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param UploadCreditRequest $request
|
||||
* @param Credit $client
|
||||
* @param Credit $credit
|
||||
* @return Response
|
||||
*
|
||||
*
|
||||
@ -778,7 +771,7 @@ class CreditController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -128,7 +128,7 @@ class DocumentController extends BaseController
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param EditDocumentRegquest $request
|
||||
* @param EditDocumentRequest $request
|
||||
* @param Document $document
|
||||
* @return Response
|
||||
*/
|
||||
|
@ -78,6 +78,8 @@ class EmailController extends BaseController
|
||||
$entity_obj->service()->markSent()->save();
|
||||
|
||||
$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);
|
||||
}
|
||||
@ -125,7 +127,6 @@ class EmailController extends BaseController
|
||||
$this->entity_transformer = PurchaseOrderTransformer::class;
|
||||
}
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
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')) {
|
||||
$this->saveDocuments($request->file('documents'), $expense);
|
||||
$this->saveDocuments($request->file('documents'), $expense, $request->input('is_public', true));
|
||||
}
|
||||
|
||||
return $this->itemResponse($expense->fresh());
|
||||
|
@ -139,12 +139,14 @@ class GroupSettingController extends BaseController
|
||||
*/
|
||||
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);
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $group_setting->company, $group_setting);
|
||||
|
||||
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);
|
||||
@ -217,7 +219,7 @@ class GroupSettingController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -92,15 +92,82 @@ class ImportController extends Controller
|
||||
|
||||
$class_map = $this->getEntityMap($entityType);
|
||||
|
||||
$hints = $this->setImportHints($entityType, $class_map::importable(), $csv_array[0]);
|
||||
|
||||
$data['mappings'][$entityType] = [
|
||||
'available' => $class_map::importable(),
|
||||
'headers' => array_slice($csv_array, 0, 2),
|
||||
'hints' => $hints,
|
||||
];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@ -115,6 +182,9 @@ class ImportController extends Controller
|
||||
|
||||
public function import(ImportRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$data = $request->all();
|
||||
|
||||
if (empty($data['hash'])) {
|
||||
@ -130,7 +200,7 @@ class ImportController extends Controller
|
||||
}
|
||||
|
||||
unset($data['files']);
|
||||
CSVIngest::dispatch($data, auth()->user()->company());
|
||||
CSVIngest::dispatch($data, $user->company());
|
||||
|
||||
return response()->json(['message' => ctrans('texts.import_started')], 200);
|
||||
}
|
||||
|
@ -162,7 +162,9 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@ -211,7 +213,11 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
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()
|
||||
->fillDefaults()
|
||||
@ -219,7 +225,7 @@ class InvoiceController extends BaseController
|
||||
->adjustInventory()
|
||||
->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 = [
|
||||
'invoice' => $invoice->transaction_event(),
|
||||
@ -409,7 +415,7 @@ class InvoiceController extends BaseController
|
||||
|
||||
$invoice->service()
|
||||
->triggeredActions($request)
|
||||
->deletePdf()
|
||||
// ->deletePdf()
|
||||
->adjustInventory($old_invoice);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$action = $request->input('action');
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -543,8 +504,8 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
|
||||
if ($action == 'bulk_download' && $invoices->count() > 1) {
|
||||
$invoices->each(function ($invoice) {
|
||||
if (auth()->user()->cannot('view', $invoice)) {
|
||||
$invoices->each(function ($invoice) use($user) {
|
||||
if ($user->cannot('view', $invoice)) {
|
||||
nlog('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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
return response()->streamDownload(function () use ($file) {
|
||||
@ -564,9 +525,9 @@ class InvoiceController extends BaseController
|
||||
}, 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) {
|
||||
return $invoice->service()->getInvoicePdf();
|
||||
return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first(), $invoice->company->db))->handle();
|
||||
});
|
||||
|
||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||
@ -579,15 +540,15 @@ class InvoiceController extends BaseController
|
||||
/*
|
||||
* Send the other actions to the switch
|
||||
*/
|
||||
$invoices->each(function ($invoice, $key) use ($action) {
|
||||
if (auth()->user()->can('edit', $invoice)) {
|
||||
$invoices->each(function ($invoice, $key) use ($action, $user) {
|
||||
if ($user->can('edit', $invoice)) {
|
||||
$this->performAction($invoice, $action, true);
|
||||
}
|
||||
});
|
||||
|
||||
/* 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;
|
||||
case 'cancel':
|
||||
$invoice = $invoice->service()->handleCancellation()->deletePdf()->save();
|
||||
$invoice = $invoice->service()->handleCancellation()->save();
|
||||
if (! $bulk) {
|
||||
$this->itemResponse($invoice);
|
||||
}
|
||||
@ -889,6 +850,7 @@ class InvoiceController extends BaseController
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
$file = $invoice->service()->getEInvoice($contact);
|
||||
$file_name = $invoice->getFileName("xml");
|
||||
|
||||
$headers = ['Content-Type' => 'application/xml'];
|
||||
|
||||
@ -897,8 +859,8 @@ class InvoiceController extends BaseController
|
||||
}
|
||||
|
||||
return response()->streamDownload(function () use ($file) {
|
||||
echo Storage::get($file);
|
||||
}, basename($file), $headers);
|
||||
echo $file;
|
||||
}, $file_name, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1005,16 +967,17 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
public function upload(UploadInvoiceRequest $request, Invoice $invoice)
|
||||
{
|
||||
|
||||
if (! $this->checkFeature(Account::FEATURE_DOCUMENTS)) {
|
||||
return $this->featureFailure();
|
||||
}
|
||||
|
||||
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')) {
|
||||
$this->saveDocuments($request->file('documents'), $invoice);
|
||||
$this->saveDocuments($request->file('file'), $invoice, $request->input('is_public', true));
|
||||
}
|
||||
|
||||
return $this->itemResponse($invoice->fresh());
|
||||
@ -1022,7 +985,10 @@ class InvoiceController extends BaseController
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -301,6 +301,7 @@ class MigrationController extends BaseController
|
||||
$user = auth()->user();
|
||||
|
||||
$company_count = $user->account->companies()->count();
|
||||
$fresh_company = false;
|
||||
|
||||
// Look for possible existing company (based on company keys).
|
||||
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first();
|
||||
|
@ -74,6 +74,7 @@ class OneTimeTokenController extends BaseController
|
||||
'user_id' => $user->id,
|
||||
'company_key'=> $user->company()->company_key,
|
||||
'context' => $request->input('context'),
|
||||
'is_react' => $request->request()->hasHeader('X-REACT') ? true : false,
|
||||
];
|
||||
|
||||
Cache::put($hash, $data, 3600);
|
||||
|
@ -749,7 +749,7 @@ class PaymentController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -95,7 +95,7 @@ class PreviewPurchaseOrderController extends BaseController
|
||||
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) {
|
||||
return $this->blankEntity();
|
||||
@ -181,7 +181,8 @@ class PreviewPurchaseOrderController extends BaseController
|
||||
DB::connection(config('database.default'))->beginTransaction();
|
||||
|
||||
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')
|
||||
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
|
||||
->where('company_id', $company->id)
|
||||
|
@ -541,7 +541,7 @@ class ProductController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -264,7 +264,7 @@ class ProjectController extends BaseController
|
||||
$project->saveQuietly();
|
||||
|
||||
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);
|
||||
@ -373,7 +373,7 @@ class ProjectController extends BaseController
|
||||
}
|
||||
|
||||
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);
|
||||
@ -565,7 +565,7 @@ class ProjectController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -139,7 +139,10 @@ class PurchaseOrderController extends BaseController
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@ -183,7 +186,10 @@ class PurchaseOrderController extends BaseController
|
||||
*/
|
||||
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()
|
||||
->fillDefaults()
|
||||
@ -361,7 +367,7 @@ class PurchaseOrderController extends BaseController
|
||||
|
||||
$purchase_order = $purchase_order->service()
|
||||
->triggeredActions($request)
|
||||
->touchPdf()
|
||||
// ->touchPdf()
|
||||
->save();
|
||||
|
||||
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)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$action = $request->input('action');
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -493,20 +502,20 @@ class PurchaseOrderController extends BaseController
|
||||
* Download Purchase Order/s
|
||||
*/
|
||||
if ($action == 'bulk_download' && $purchase_orders->count() >= 1) {
|
||||
$purchase_orders->each(function ($purchase_order) {
|
||||
if (auth()->user()->cannot('view', $purchase_order)) {
|
||||
$purchase_orders->each(function ($purchase_order) use ($user){
|
||||
if ($user->cannot('view', $purchase_order)) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return $purchase_order->service()->getPurchaseOrderPdf();
|
||||
return (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($purchase_order->invitations->first()))->rawPdf();
|
||||
});
|
||||
|
||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
||||
@ -519,8 +528,8 @@ class PurchaseOrderController extends BaseController
|
||||
/*
|
||||
* Send the other actions to the switch
|
||||
*/
|
||||
$purchase_orders->each(function ($purchase_order, $key) use ($action) {
|
||||
if (auth()->user()->can('edit', $purchase_order)) {
|
||||
$purchase_orders->each(function ($purchase_order, $key) use ($action, $user) {
|
||||
if ($user->can('edit', $purchase_order)) {
|
||||
$this->performAction($purchase_order, $action, true);
|
||||
}
|
||||
});
|
||||
@ -751,7 +760,7 @@ class PurchaseOrderController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -16,6 +16,7 @@ use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\Account;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Factory\QuoteFactory;
|
||||
use App\Filters\QuoteFilters;
|
||||
@ -33,6 +34,7 @@ use App\Transformers\QuoteTransformer;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Transformers\InvoiceTransformer;
|
||||
use App\Transformers\ProjectTransformer;
|
||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||
use App\Factory\CloneQuoteToProjectFactory;
|
||||
use App\Http\Requests\Quote\EditQuoteRequest;
|
||||
@ -395,8 +397,8 @@ class QuoteController extends BaseController
|
||||
$quote = $this->quote_repo->save($request->all(), $quote);
|
||||
|
||||
$quote->service()
|
||||
->triggeredActions($request)
|
||||
->deletePdf();
|
||||
->triggeredActions($request);
|
||||
// ->deletePdf();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$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) {
|
||||
return response()->json(['message' => ctrans('texts.quote_not_found')]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Download Invoice/s
|
||||
* Download Quote/s
|
||||
*/
|
||||
|
||||
if ($action == 'bulk_download' && $quotes->count() >= 1) {
|
||||
$quotes->each(function ($quote) use($user){
|
||||
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);
|
||||
}
|
||||
@ -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())) {
|
||||
$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();
|
||||
@ -575,18 +576,13 @@ class QuoteController extends BaseController
|
||||
if ($action == 'convert_to_project') {
|
||||
$quotes->each(function ($quote, $key) use ($user) {
|
||||
if ($user->can('edit', $quote)) {
|
||||
$project = CloneQuoteToProjectFactory::create($quote, $user->id);
|
||||
|
||||
if (empty($project->number)) {
|
||||
$project->number = $this->getNextProjectNumber($project);
|
||||
}
|
||||
$project->save();
|
||||
$quote->project_id = $project->id;
|
||||
$quote->save();
|
||||
$quote->service()->convertToProject();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
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)
|
||||
{
|
||||
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_to_invoice':
|
||||
|
||||
@ -692,8 +695,6 @@ class QuoteController extends BaseController
|
||||
|
||||
return $this->itemResponse($quote->service()->convertToInvoice());
|
||||
|
||||
break;
|
||||
|
||||
case 'clone_to_invoice':
|
||||
|
||||
$this->entity_type = Invoice::class;
|
||||
@ -702,41 +703,38 @@ class QuoteController extends BaseController
|
||||
$invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
break;
|
||||
|
||||
case 'clone_to_quote':
|
||||
$quote = CloneQuoteFactory::create($quote, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($quote);
|
||||
break;
|
||||
|
||||
case 'approve':
|
||||
if (! in_array($quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
|
||||
return response()->json(['message' => ctrans('texts.quote_unapprovable')], 400);
|
||||
}
|
||||
|
||||
return $this->itemResponse($quote->service()->approveWithNoCoversion()->save());
|
||||
break;
|
||||
|
||||
case 'history':
|
||||
// code...
|
||||
break;
|
||||
case 'download':
|
||||
|
||||
//$file = $quote->pdf_file_path();
|
||||
$file = $quote->service()->getQuotePdf();
|
||||
|
||||
return response()->streamDownload(function () use ($file) {
|
||||
echo Storage::get($file);
|
||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
||||
|
||||
|
||||
break;
|
||||
case 'restore':
|
||||
$this->quote_repo->restore($quote);
|
||||
|
||||
if (! $bulk) {
|
||||
return $this->itemResponse($quote);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'archive':
|
||||
$this->quote_repo->archive($quote);
|
||||
|
||||
@ -754,16 +752,11 @@ class QuoteController extends BaseController
|
||||
|
||||
break;
|
||||
case 'email':
|
||||
$quote->service()->sendEmail();
|
||||
|
||||
return response()->json(['message'=> ctrans('texts.sent_message')], 200);
|
||||
break;
|
||||
|
||||
case 'send_email':
|
||||
|
||||
$quote->service()->sendEmail();
|
||||
|
||||
return response()->json(['message'=> ctrans('texts.sent_message')], 200);
|
||||
break;
|
||||
|
||||
case 'mark_sent':
|
||||
$quote->service()->markSent()->save();
|
||||
@ -905,7 +898,7 @@ class QuoteController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -609,7 +609,7 @@ class RecurringExpenseController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -153,7 +153,10 @@ class RecurringInvoiceController extends BaseController
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@ -199,7 +202,10 @@ class RecurringInvoiceController extends BaseController
|
||||
*/
|
||||
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()
|
||||
->triggeredActions($request)
|
||||
@ -380,7 +386,7 @@ class RecurringInvoiceController extends BaseController
|
||||
|
||||
$recurring_invoice->service()
|
||||
->triggeredActions($request)
|
||||
->deletePdf()
|
||||
// ->deletePdf()
|
||||
->save();
|
||||
|
||||
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)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
|
||||
|
||||
$recurring_invoices->each(function ($recurring_invoice, $key) use ($request) {
|
||||
if (auth()->user()->can('edit', $recurring_invoice)) {
|
||||
$recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) {
|
||||
if ($user->can('edit', $recurring_invoice)) {
|
||||
$this->performAction($recurring_invoice, $request->action, true);
|
||||
}
|
||||
});
|
||||
@ -550,7 +559,7 @@ class RecurringInvoiceController extends BaseController
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -14,6 +14,7 @@ namespace App\Http\Controllers\Reports;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Jobs\Report\SendToAdmin;
|
||||
use App\Export\CSV\ActivityExport;
|
||||
use App\Jobs\Report\PreviewReport;
|
||||
use App\Http\Controllers\BaseController;
|
||||
use App\Http\Requests\Report\GenericReportRequest;
|
||||
|
||||
@ -31,14 +32,27 @@ class ActivityReportController extends BaseController
|
||||
|
||||
public function __invoke(GenericReportRequest $request)
|
||||
{
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
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);
|
||||
}
|
||||
// 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();
|
||||
|
||||
|
@ -11,12 +11,13 @@
|
||||
|
||||
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\Jobs\Report\PreviewReport;
|
||||
use App\Http\Controllers\BaseController;
|
||||
use App\Http\Requests\Report\GenericReportRequest;
|
||||
use App\Jobs\Report\SendToAdmin;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class ClientContactReportController extends BaseController
|
||||
{
|
||||
@ -62,13 +63,29 @@ class ClientContactReportController extends BaseController
|
||||
*/
|
||||
public function __invoke(GenericReportRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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();
|
||||
|
||||
|
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