mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 23:57:33 -05:00 
			
		
		
		
	Merge branch 'v5-develop' into vite-migration
This commit is contained in:
		
						commit
						99b1aab2a2
					
				
							
								
								
									
										6
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							@ -46,7 +46,11 @@ jobs:
 | 
				
			|||||||
          git checkout main
 | 
					          git checkout main
 | 
				
			||||||
          npm i
 | 
					          npm i
 | 
				
			||||||
          npm run build
 | 
					          npm run build
 | 
				
			||||||
          cp -r dist/react/* ../public/react 
 | 
					          
 | 
				
			||||||
 | 
					          mkdir -p ../public/react/${{ github.event.release.tag_name }}/
 | 
				
			||||||
 | 
					          cp -r dist/react/* ../public/react/${{ github.event.release.tag_name }}/
 | 
				
			||||||
 | 
					          cp -r dist/react/* ../public/react/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          mkdir -p ../public/tinymce_6.4.2/tinymce/js/
 | 
					          mkdir -p ../public/tinymce_6.4.2/tinymce/js/
 | 
				
			||||||
          cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
 | 
					          cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
 | 
				
			||||||
          cd ..
 | 
					          cd ..
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
5.7.7
 | 
					5.7.22
 | 
				
			||||||
@ -862,7 +862,7 @@ class CheckData extends Command
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                $records = DB::table($table)
 | 
					                $records = DB::table($table)
 | 
				
			||||||
                                ->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id")
 | 
					                                ->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id")
 | 
				
			||||||
                                ->where("{$table}.{$company_id}", '!=', "{$tableName}.company_id")
 | 
					                                ->whereRaw("{$table}.{$company_id} != {$tableName}.company_id")
 | 
				
			||||||
                                ->get(["{$table}.id"]);
 | 
					                                ->get(["{$table}.id"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ($records->count()) {
 | 
					                if ($records->count()) {
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,8 @@ class CreateTestData extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    protected $invoice_repo;
 | 
					    protected $invoice_repo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $count;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Execute the console command.
 | 
					     * Execute the console command.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,7 @@ class ReactBuilder extends Command
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $includes = '';
 | 
					        $includes = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
					        $directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
 | 
					        foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
 | 
				
			||||||
            if ($file->getExtension() == 'js') {
 | 
					            if ($file->getExtension() == 'js') {
 | 
				
			||||||
 | 
				
			|||||||
@ -173,7 +173,7 @@ class SendRemindersCron extends Command
 | 
				
			|||||||
        /**Refresh Invoice values*/
 | 
					        /**Refresh Invoice values*/
 | 
				
			||||||
        $invoice->calc()->getInvoice()->save();
 | 
					        $invoice->calc()->getInvoice()->save();
 | 
				
			||||||
        $invoice->fresh();
 | 
					        $invoice->fresh();
 | 
				
			||||||
        $invoice->service()->deletePdf()->save();
 | 
					        // $invoice->service()->deletePdf()->save();
 | 
				
			||||||
        if ($invoice->client->getSetting('enable_e_invoice')){
 | 
					        if ($invoice->client->getSetting('enable_e_invoice')){
 | 
				
			||||||
            $invoice->service()->deleteEInvoice()->save();
 | 
					            $invoice->service()->deleteEInvoice()->save();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,28 +11,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Console;
 | 
					namespace App\Console;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Jobs\Cron\AutoBillCron;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Jobs\Cron\RecurringExpensesCron;
 | 
					use App\Models\Account;
 | 
				
			||||||
use App\Jobs\Cron\RecurringInvoicesCron;
 | 
					 | 
				
			||||||
use App\Jobs\Cron\SubscriptionCron;
 | 
					 | 
				
			||||||
use App\Jobs\Cron\UpdateCalculatedFields;
 | 
					 | 
				
			||||||
use App\Jobs\Invoice\InvoiceCheckLateWebhook;
 | 
					 | 
				
			||||||
use App\Jobs\Ninja\AdjustEmailQuota;
 | 
					 | 
				
			||||||
use App\Jobs\Ninja\BankTransactionSync;
 | 
					 | 
				
			||||||
use App\Jobs\Ninja\CompanySizeCheck;
 | 
					 | 
				
			||||||
use App\Jobs\Ninja\QueueSize;
 | 
					use App\Jobs\Ninja\QueueSize;
 | 
				
			||||||
use App\Jobs\Ninja\SystemMaintenance;
 | 
					 | 
				
			||||||
use App\Jobs\Ninja\TaskScheduler;
 | 
					 | 
				
			||||||
use App\Jobs\Quote\QuoteCheckExpired;
 | 
					 | 
				
			||||||
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
 | 
					 | 
				
			||||||
use App\Jobs\Util\DiskCleanup;
 | 
					use App\Jobs\Util\DiskCleanup;
 | 
				
			||||||
use App\Jobs\Util\ReminderJob;
 | 
					use App\Jobs\Util\ReminderJob;
 | 
				
			||||||
use App\Jobs\Util\SchedulerCheck;
 | 
					use App\Jobs\Cron\AutoBillCron;
 | 
				
			||||||
use App\Jobs\Util\UpdateExchangeRates;
 | 
					 | 
				
			||||||
use App\Jobs\Util\VersionCheck;
 | 
					use App\Jobs\Util\VersionCheck;
 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Jobs\Ninja\TaskScheduler;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Jobs\Util\SchedulerCheck;
 | 
				
			||||||
 | 
					use App\Jobs\Ninja\CheckACHStatus;
 | 
				
			||||||
 | 
					use App\Jobs\Cron\SubscriptionCron;
 | 
				
			||||||
 | 
					use App\Jobs\Ninja\AdjustEmailQuota;
 | 
				
			||||||
 | 
					use App\Jobs\Ninja\CompanySizeCheck;
 | 
				
			||||||
 | 
					use App\Jobs\Ninja\SystemMaintenance;
 | 
				
			||||||
 | 
					use App\Jobs\Quote\QuoteCheckExpired;
 | 
				
			||||||
 | 
					use App\Jobs\Util\UpdateExchangeRates;
 | 
				
			||||||
 | 
					use App\Jobs\Ninja\BankTransactionSync;
 | 
				
			||||||
 | 
					use App\Jobs\Cron\RecurringExpensesCron;
 | 
				
			||||||
 | 
					use App\Jobs\Cron\RecurringInvoicesCron;
 | 
				
			||||||
 | 
					use App\Jobs\Cron\UpdateCalculatedFields;
 | 
				
			||||||
use Illuminate\Console\Scheduling\Schedule;
 | 
					use Illuminate\Console\Scheduling\Schedule;
 | 
				
			||||||
 | 
					use App\Jobs\Invoice\InvoiceCheckLateWebhook;
 | 
				
			||||||
 | 
					use App\Jobs\Subscription\CleanStaleInvoiceOrder;
 | 
				
			||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
 | 
					use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Kernel extends ConsoleKernel
 | 
					class Kernel extends ConsoleKernel
 | 
				
			||||||
@ -107,7 +108,10 @@ class Kernel extends ConsoleKernel
 | 
				
			|||||||
            $schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping();
 | 
					            $schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Pulls in bank transactions from third party services */
 | 
					            /* Pulls in bank transactions from third party services */
 | 
				
			||||||
            $schedule->job(new BankTransactionSync)->dailyAt('04:10')->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
 | 
					            $schedule->job(new BankTransactionSync)->everyFourHours()->withoutOverlapping()->name('bank-trans-sync-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Checks ACH verification status and updates state to authorize when verified */
 | 
				
			||||||
 | 
					            $schedule->job(new CheckACHStatus)->everySixHours()->withoutOverlapping()->name('ach-status-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $schedule->command('ninja:check-data --database=db-ninja-01')->dailyAt('02:10')->withoutOverlapping()->name('check-data-db-1-job')->onOneServer();
 | 
					            $schedule->command('ninja:check-data --database=db-ninja-01')->dailyAt('02:10')->withoutOverlapping()->name('check-data-db-1-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -481,8 +481,11 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public $enable_e_invoice = false;
 | 
					    public $enable_e_invoice = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $classification = ''; // individual, company, partnership, trust, charity, government, other
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static $casts = [
 | 
					    public static $casts = [
 | 
				
			||||||
        'enable_e_invoice'                   => 'bool', 
 | 
					        'enable_e_invoice'                   => 'bool', 
 | 
				
			||||||
 | 
					        'classification'                     => 'string',
 | 
				
			||||||
        'default_expense_payment_type_id'    => 'string',
 | 
					        'default_expense_payment_type_id'    => 'string',
 | 
				
			||||||
        'e_invoice_type'                     => 'string',    
 | 
					        'e_invoice_type'                     => 'string',    
 | 
				
			||||||
        'mailgun_endpoint'                   => 'string',    
 | 
					        'mailgun_endpoint'                   => 'string',    
 | 
				
			||||||
@ -843,6 +846,23 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
        return $notification;
 | 
					        return $notification;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Stubs the notification defaults
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return stdClass
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function notificationAdminDefaults() :stdClass
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $notification = new stdClass;
 | 
				
			||||||
 | 
					        $notification->email = [];
 | 
				
			||||||
 | 
					        $notification->email = ['invoice_sent_all'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $notification;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Defines entity variables for PDF generation
 | 
					     * Defines entity variables for PDF generation
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -363,7 +363,15 @@ class BaseRule implements RuleInterface
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function override($item): self
 | 
					    public function override($item): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->tax_rate1 = $item->tax_rate1;
 | 
				
			||||||
 | 
					        $this->tax_name1 = $item->tax_name1;
 | 
				
			||||||
 | 
					        $this->tax_rate2 = $item->tax_rate2;
 | 
				
			||||||
 | 
					        $this->tax_name2 = $item->tax_name2;
 | 
				
			||||||
 | 
					        $this->tax_rate3 = $item->tax_rate3;
 | 
				
			||||||
 | 
					        $this->tax_name3 = $item->tax_name3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function calculateRates(): self
 | 
					    public function calculateRates(): self
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,10 @@ class Rule extends BaseRule implements RuleInterface
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        $this->tax_rate1 = $item->tax_rate1;
 | 
					        $this->tax_rate1 = $item->tax_rate1;
 | 
				
			||||||
        $this->tax_name1 = $item->tax_name1;
 | 
					        $this->tax_name1 = $item->tax_name1;
 | 
				
			||||||
 | 
					        $this->tax_rate2 = $item->tax_rate2;
 | 
				
			||||||
 | 
					        $this->tax_name2 = $item->tax_name2;
 | 
				
			||||||
 | 
					        $this->tax_rate3 = $item->tax_rate3;
 | 
				
			||||||
 | 
					        $this->tax_name3 = $item->tax_name3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -57,9 +57,11 @@ class ActivityExport extends BaseExport
 | 
				
			|||||||
                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
					                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
            })->toArray();
 | 
					            })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					            
 | 
				
			||||||
                ->map(function ($credit) {
 | 
					            $report = $query->cursor()
 | 
				
			||||||
                    return $this->buildActivityRow($credit);
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
 | 
					                    $row = $this->buildActivityRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
@ -70,6 +72,8 @@ class ActivityExport extends BaseExport
 | 
				
			|||||||
            return [
 | 
					            return [
 | 
				
			||||||
            Carbon::parse($activity->created_at)->format($this->date_format),
 | 
					            Carbon::parse($activity->created_at)->format($this->date_format),
 | 
				
			||||||
            ctrans("texts.activity_{$activity->activity_type_id}",[
 | 
					            ctrans("texts.activity_{$activity->activity_type_id}",[
 | 
				
			||||||
 | 
					                'payment_amount' => $activity->payment ? $activity->payment->amount : '',
 | 
				
			||||||
 | 
					                'adjustment' => $activity->payment ? $activity->payment->refunded : '',
 | 
				
			||||||
                'client' => $activity->client ? $activity->client->present()->name() : '',
 | 
					                'client' => $activity->client ? $activity->client->present()->name() : '',
 | 
				
			||||||
                'contact' => $activity->contact ? $activity->contact->present()->name() : '',
 | 
					                'contact' => $activity->contact ? $activity->contact->present()->name() : '',
 | 
				
			||||||
                'quote' => $activity->quote ? $activity->quote->number : '',
 | 
					                'quote' => $activity->quote ? $activity->quote->number : '',
 | 
				
			||||||
@ -101,7 +105,7 @@ class ActivityExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
 | 
					        $this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ksort($this->entity_keys);
 | 
					        // ksort($this->entity_keys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
					            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
				
			||||||
@ -146,4 +150,27 @@ class ActivityExport extends BaseExport
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processMetaData(array $row, $resource): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $clean_row = [];
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            nlog("key: {$key}, value: {$value}");
 | 
				
			||||||
 | 
					            nlog($row);
 | 
				
			||||||
 | 
					            $clean_row[$key]['entity'] = 'activity';
 | 
				
			||||||
 | 
					            $clean_row[$key]['id'] = $key;
 | 
				
			||||||
 | 
					            $clean_row[$key]['hashed_id'] = null;
 | 
				
			||||||
 | 
					            $clean_row[$key]['value'] = $row[$key];
 | 
				
			||||||
 | 
					            $clean_row[$key]['identifier'] = $value;
 | 
				
			||||||
 | 
					            $clean_row[$key]['display_value'] = $row[$key];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $clean_row;
 | 
				
			||||||
 | 
					    }   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,20 +11,30 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Export\CSV;
 | 
					namespace App\Export\CSV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Utils\Number;
 | 
					use App\Utils\Number;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Credit;
 | 
				
			||||||
use App\Utils\Helpers;
 | 
					use App\Utils\Helpers;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Expense;
 | 
					use App\Models\Expense;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
 | 
					use App\Models\Document;
 | 
				
			||||||
use League\Fractal\Manager;
 | 
					use League\Fractal\Manager;
 | 
				
			||||||
 | 
					use App\Models\ClientContact;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Transformers\TaskTransformer;
 | 
					use App\Transformers\TaskTransformer;
 | 
				
			||||||
use App\Transformers\PaymentTransformer;
 | 
					use App\Transformers\PaymentTransformer;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use League\Fractal\Serializer\ArraySerializer;
 | 
					use League\Fractal\Serializer\ArraySerializer;
 | 
				
			||||||
 | 
					use App\Models\Product;
 | 
				
			||||||
 | 
					use App\Models\Task;
 | 
				
			||||||
 | 
					use App\Models\Vendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseExport
 | 
					class BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -56,7 +66,7 @@ class BaseExport
 | 
				
			|||||||
        'id_number' => 'vendor.id_number',
 | 
					        'id_number' => 'vendor.id_number',
 | 
				
			||||||
        'name' => 'vendor.name',
 | 
					        'name' => 'vendor.name',
 | 
				
			||||||
        'number' => 'vendor.number',
 | 
					        'number' => 'vendor.number',
 | 
				
			||||||
        'client_phone' => 'vendor.phone',
 | 
					        'phone' => 'vendor.phone',
 | 
				
			||||||
        'postal_code' => 'vendor.postal_code',
 | 
					        'postal_code' => 'vendor.postal_code',
 | 
				
			||||||
        'private_notes' => 'vendor.private_notes',
 | 
					        'private_notes' => 'vendor.private_notes',
 | 
				
			||||||
        'public_notes' => 'vendor.public_notes',
 | 
					        'public_notes' => 'vendor.public_notes',
 | 
				
			||||||
@ -229,8 +239,8 @@ class BaseExport
 | 
				
			|||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected array $product_report_keys  = [
 | 
					    protected array $product_report_keys  = [
 | 
				
			||||||
        'project' => 'project_id',
 | 
					        // 'project' => 'project_id',
 | 
				
			||||||
        'vendor' => 'vendor_id',
 | 
					        // 'vendor' => 'vendor_id',
 | 
				
			||||||
        'custom_value1' => 'custom_value1',
 | 
					        'custom_value1' => 'custom_value1',
 | 
				
			||||||
        'custom_value2' => 'custom_value2',
 | 
					        'custom_value2' => 'custom_value2',
 | 
				
			||||||
        'custom_value3' => 'custom_value3',
 | 
					        'custom_value3' => 'custom_value3',
 | 
				
			||||||
@ -246,6 +256,10 @@ class BaseExport
 | 
				
			|||||||
        'tax_name1' => 'tax_name1',
 | 
					        'tax_name1' => 'tax_name1',
 | 
				
			||||||
        'tax_name2' => 'tax_name2',
 | 
					        'tax_name2' => 'tax_name2',
 | 
				
			||||||
        'tax_name3' => 'tax_name3',
 | 
					        'tax_name3' => 'tax_name3',
 | 
				
			||||||
 | 
					        'image' => 'product_image',
 | 
				
			||||||
 | 
					        'tax_category' => 'tax_id',
 | 
				
			||||||
 | 
					        'max_quantity' => 'max_quantity',
 | 
				
			||||||
 | 
					        'in_stock_quantity' => 'in_stock_quantity',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected array $item_report_keys = [
 | 
					    protected array $item_report_keys = [
 | 
				
			||||||
@ -364,7 +378,7 @@ class BaseExport
 | 
				
			|||||||
    protected array $expense_report_keys = [
 | 
					    protected array $expense_report_keys = [
 | 
				
			||||||
        'amount' => 'expense.amount',
 | 
					        'amount' => 'expense.amount',
 | 
				
			||||||
        'category' => 'expense.category_id',
 | 
					        'category' => 'expense.category_id',
 | 
				
			||||||
        'client' => 'expense.client_id',
 | 
					        // 'client' => 'expense.client_id',
 | 
				
			||||||
        'custom_value1' => 'expense.custom_value1',
 | 
					        'custom_value1' => 'expense.custom_value1',
 | 
				
			||||||
        'custom_value2' => 'expense.custom_value2',
 | 
					        'custom_value2' => 'expense.custom_value2',
 | 
				
			||||||
        'custom_value3' => 'expense.custom_value3',
 | 
					        'custom_value3' => 'expense.custom_value3',
 | 
				
			||||||
@ -578,31 +592,33 @@ class BaseExport
 | 
				
			|||||||
        $manager->setSerializer(new ArraySerializer());
 | 
					        $manager->setSerializer(new ArraySerializer());
 | 
				
			||||||
        $transformed_client = $manager->createData($transformed_client)->toArray();
 | 
					        $transformed_client = $manager->createData($transformed_client)->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($column == 'name')
 | 
					        if(in_array($column, ['client.name', 'name']))
 | 
				
			||||||
            return $transformed_client['display_name'];
 | 
					            return $transformed_client['display_name'];
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if($column == 'user_id')
 | 
					        if(in_array($column, ['client.user_id', 'user_id']))
 | 
				
			||||||
            return $entity->client->user->present()->name();
 | 
					            return $entity->client->user->present()->name();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($column == 'country_id')
 | 
					        if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) 
 | 
				
			||||||
 | 
					            return $entity->client->assigned_user->present()->name();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(in_array($column, ['client.country_id', 'country_id']))
 | 
				
			||||||
            return $entity->client->country ? ctrans("texts.country_{$entity->client->country->name}") : '';
 | 
					            return $entity->client->country ? ctrans("texts.country_{$entity->client->country->name}") : '';
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if($column == 'shipping_country_id')
 | 
					        if(in_array($column, ['client.shipping_country_id', 'shipping_country_id']))
 | 
				
			||||||
            return $entity->client->shipping_country ? ctrans("texts.country_{$entity->client->shipping_country->name}") : '';
 | 
					            return $entity->client->shipping_country ? ctrans("texts.country_{$entity->client->shipping_country->name}") : '';
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if($column == 'size_id')
 | 
					        if(in_array($column, ['client.size_id', 'size_id']))
 | 
				
			||||||
            return $entity->client->size?->name ?? '';
 | 
					            return $entity->client->size?->name ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($column == 'industry_id')
 | 
					        if(in_array($column, ['client.industry_id', 'industry_id']))
 | 
				
			||||||
            return $entity->client->industry?->name ?? '';
 | 
					            return $entity->client->industry?->name ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($column == 'currency_id') {
 | 
					        if (in_array($column, ['client.currency_id', 'currency_id']))
 | 
				
			||||||
            return $entity->client->currency() ? $entity->client->currency()->code : $entity->company->currency()->code;
 | 
					            return $entity->client->currency() ? $entity->client->currency()->code : $entity->company->currency()->code;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if($column == 'client.payment_terms') {
 | 
					        if(in_array($column, ['payment_terms', 'client.payment_terms']))
 | 
				
			||||||
            return $entity->client->getSetting('payment_terms');
 | 
					            return $entity->client->getSetting('payment_terms');
 | 
				
			||||||
        }
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(array_key_exists($column, $transformed_client))
 | 
					        if(array_key_exists($column, $transformed_client))
 | 
				
			||||||
            return $transformed_client[$column];
 | 
					            return $transformed_client[$column];
 | 
				
			||||||
@ -644,7 +660,7 @@ class BaseExport
 | 
				
			|||||||
        // nlog("searching for {$column}");
 | 
					        // nlog("searching for {$column}");
 | 
				
			||||||
        $transformed_invoice = false;
 | 
					        $transformed_invoice = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($transformer instanceof PaymentTransformer) {
 | 
					        if($transformer instanceof PaymentTransformer && ($entity->invoices ?? false)) {
 | 
				
			||||||
            $transformed_invoices = $transformer->includeInvoices($entity);
 | 
					            $transformed_invoices = $transformer->includeInvoices($entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $manager = new Manager();
 | 
					            $manager = new Manager();
 | 
				
			||||||
@ -666,7 +682,7 @@ class BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($transformer instanceof TaskTransformer) {
 | 
					        if($transformer instanceof TaskTransformer && ($entity->invoice ?? false)) {
 | 
				
			||||||
            $transformed_invoice = $transformer->includeInvoice($entity);
 | 
					            $transformed_invoice = $transformer->includeInvoice($entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$transformed_invoice)
 | 
					            if(!$transformed_invoice)
 | 
				
			||||||
@ -900,7 +916,7 @@ class BaseExport
 | 
				
			|||||||
        $helper = new Helpers();
 | 
					        $helper = new Helpers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $header = [];
 | 
					        $header = [];
 | 
				
			||||||
 | 
					        // nlog("header");
 | 
				
			||||||
        foreach ($this->input['report_keys'] as $value) {
 | 
					        foreach ($this->input['report_keys'] as $value) {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            $key = array_search($value, $this->entity_keys);
 | 
					            $key = array_search($value, $this->entity_keys);
 | 
				
			||||||
@ -947,6 +963,9 @@ class BaseExport
 | 
				
			|||||||
            if(!$key) {
 | 
					            if(!$key) {
 | 
				
			||||||
                $prefix = ctrans('texts.expense')." ";
 | 
					                $prefix = ctrans('texts.expense')." ";
 | 
				
			||||||
                $key = array_search($value, $this->expense_report_keys);
 | 
					                $key = array_search($value, $this->expense_report_keys);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                    if(!$key && $value == 'expense.category')
 | 
				
			||||||
 | 
					                        $key = 'category';
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$key) {
 | 
					            if(!$key) {
 | 
				
			||||||
@ -973,6 +992,8 @@ class BaseExport
 | 
				
			|||||||
                $prefix = '';
 | 
					                $prefix = '';
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // nlog("key => {$key}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $key = str_replace('item.', '', $key);
 | 
					            $key = str_replace('item.', '', $key);
 | 
				
			||||||
            $key = str_replace('recurring_invoice.', '', $key);
 | 
					            $key = str_replace('recurring_invoice.', '', $key);
 | 
				
			||||||
            $key = str_replace('purchase_order.', '', $key);
 | 
					            $key = str_replace('purchase_order.', '', $key);
 | 
				
			||||||
@ -986,6 +1007,7 @@ class BaseExport
 | 
				
			|||||||
            $key = str_replace('payment.', '', $key);
 | 
					            $key = str_replace('payment.', '', $key);
 | 
				
			||||||
            $key = str_replace('expense.', '', $key);
 | 
					            $key = str_replace('expense.', '', $key);
 | 
				
			||||||
            $key = str_replace('product.', '', $key);
 | 
					            $key = str_replace('product.', '', $key);
 | 
				
			||||||
 | 
					            $key = str_replace('task.', '', $key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(stripos($value, 'custom_value') !== false)
 | 
					            if(stripos($value, 'custom_value') !== false)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -1004,12 +1026,15 @@ class BaseExport
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                elseif(count($parts) == 2 && stripos($parts[0], 'contact') !== false) {
 | 
					                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);
 | 
					                    $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]}");
 | 
					                    $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;
 | 
					                    $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'])){
 | 
					                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]}");
 | 
					                    $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;
 | 
					                    $header[] = ctrans("texts.{$parts[0]}") . " " . $custom_field_string;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -1028,4 +1053,100 @@ class BaseExport
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        return $header;
 | 
					        return $header;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processMetaData(array $row, $resource): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $class = get_class($resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $entity = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        match ($class) {
 | 
				
			||||||
 | 
					            Invoice::class => $entity = 'invoice',
 | 
				
			||||||
 | 
					            RecurringInvoice::class => $entity = 'recurring_invoice',
 | 
				
			||||||
 | 
					            Quote::class => $entity = 'quote',
 | 
				
			||||||
 | 
					            Credit::class => $entity = 'credit',
 | 
				
			||||||
 | 
					            Expense::class => $entity = 'expense',
 | 
				
			||||||
 | 
					            Document::class => $entity = 'document',
 | 
				
			||||||
 | 
					            ClientContact::class => $entity = 'contact',
 | 
				
			||||||
 | 
					            PurchaseOrder::class => $entity = 'purchase_order',
 | 
				
			||||||
 | 
					            Payment::class => $entity = 'payment',
 | 
				
			||||||
 | 
					            Product::class => $entity = 'product',
 | 
				
			||||||
 | 
					            Task::class => $entity = 'task',
 | 
				
			||||||
 | 
					            Vendor::class => $entity = 'vendor',
 | 
				
			||||||
 | 
					            default => $entity = 'invoice',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $clean_row = [];
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            $report_keys = explode(".", $value);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $column_key = $value;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if($value == 'product_image') {
 | 
				
			||||||
 | 
					                $column_key = 'image';
 | 
				
			||||||
 | 
					                $value = 'image';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($value == 'tax_id') {         
 | 
				
			||||||
 | 
					                $column_key = 'tax_category';
 | 
				
			||||||
 | 
					                $value = 'tax_category';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $clean_row[$key]['entity'] = $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
 | 
				
			||||||
 | 
					            $clean_row[$key]['value'] = $row[$column_key];
 | 
				
			||||||
 | 
					            $clean_row[$key]['identifier'] = $value;
 | 
				
			||||||
 | 
					            $clean_row[$key]['display_value'] = $row[$column_key];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $clean_row;
 | 
				
			||||||
 | 
					    }   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processItemMetaData(array $row, $resource): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $class = get_class($resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $entity = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        match ($class) {
 | 
				
			||||||
 | 
					            Invoice::class => $entity = 'invoice',
 | 
				
			||||||
 | 
					            Quote::class => $entity = 'quote',
 | 
				
			||||||
 | 
					            Credit::class => $entity = 'credit',
 | 
				
			||||||
 | 
					            Expense::class => $entity = 'expense',
 | 
				
			||||||
 | 
					            Document::class => $entity = 'document',
 | 
				
			||||||
 | 
					            ClientContact::class => $entity = 'contact',
 | 
				
			||||||
 | 
					            PurchaseOrder::class => $entity = 'purchase_order',
 | 
				
			||||||
 | 
					            default => $entity = 'invoice',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $clean_row = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            $report_keys = explode(".", $value);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $column_key = $value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($value == 'type_id' || $value == 'item.type_id')
 | 
				
			||||||
 | 
					                $column_key = 'type';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($value == 'tax_id' || $value == 'item.tax_id')
 | 
				
			||||||
 | 
					                $column_key = 'tax_category';
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            $clean_row[$key]['entity'] = $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
 | 
				
			||||||
 | 
					            $clean_row[$key]['value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
 | 
				
			||||||
 | 
					            $clean_row[$key]['identifier'] = $value;
 | 
				
			||||||
 | 
					            $clean_row[$key]['display_value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $clean_row;
 | 
				
			||||||
 | 
					    }   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,15 +11,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Export\CSV;
 | 
					namespace App\Export\CSV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Transformers\ClientContactTransformer;
 | 
					 | 
				
			||||||
use App\Transformers\ClientTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use App\Utils\Number;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use App\Models\Client;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
 | 
					use App\Transformers\ClientTransformer;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use App\Transformers\ClientContactTransformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClientExport extends BaseExport
 | 
					class ClientExport extends BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -93,7 +94,8 @@ class ClientExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($client) {
 | 
					                ->map(function ($client) {
 | 
				
			||||||
                    return $this->buildRow($client);
 | 
					                    $row = $this->buildRow($client);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $client);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
@ -171,6 +173,30 @@ class ClientExport extends BaseExport
 | 
				
			|||||||
        return $this->decorateAdvancedFields($client, $entity);
 | 
					        return $this->decorateAdvancedFields($client, $entity);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processMetaData(array $row, $resource): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $clean_row = [];
 | 
				
			||||||
 | 
					        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            $report_keys = explode(".", $value);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $column_key = $value;
 | 
				
			||||||
 | 
					            $clean_row[$key]['entity'] = $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
 | 
				
			||||||
 | 
					            $clean_row[$key]['hashed_id'] = $report_keys[0] == 'client' ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
 | 
				
			||||||
 | 
					            $clean_row[$key]['value'] = $row[$column_key];
 | 
				
			||||||
 | 
					            $clean_row[$key]['identifier'] = $key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(in_array($clean_row[$key]['id'], ['paid_to_date', 'balance', 'credit_balance','payment_balance']))
 | 
				
			||||||
 | 
					                $clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $resource);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                $clean_row[$key]['display_value'] = $row[$column_key];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $clean_row;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function decorateAdvancedFields(Client $client, array $entity) :array
 | 
					    private function decorateAdvancedFields(Client $client, array $entity) :array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (in_array('client.user', $this->input['report_keys'])) {
 | 
					        if (in_array('client.user', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -94,7 +94,8 @@ class ContactExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($contact) {
 | 
					                ->map(function ($contact) {
 | 
				
			||||||
                    return $this->buildRow($contact);
 | 
					                    $row = $this->buildRow($contact);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $contact);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use App\Transformers\CreditTransformer;
 | 
					use App\Transformers\CreditTransformer;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CreditExport extends BaseExport
 | 
					class CreditExport extends BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -56,7 +56,7 @@ class CreditExport extends BaseExport
 | 
				
			|||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function processMetaData(array $row, Credit $credit): array
 | 
					    public function processMetaData(array $row, $resource): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $clean_row = [];
 | 
					        $clean_row = [];
 | 
				
			||||||
        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
					        foreach (array_values($this->input['report_keys']) as $key => $value) {
 | 
				
			||||||
@ -66,12 +66,12 @@ class CreditExport extends BaseExport
 | 
				
			|||||||
            $column_key = $value;
 | 
					            $column_key = $value;
 | 
				
			||||||
            $clean_row[$key]['entity'] = $report_keys[0];
 | 
					            $clean_row[$key]['entity'] = $report_keys[0];
 | 
				
			||||||
            $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
 | 
					            $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
 | 
				
			||||||
            $clean_row[$key]['hashed_id'] = $report_keys[0] == 'credit' ? null : $credit->{$report_keys[0]}->hashed_id ?? null;
 | 
					            $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]['value'] = $row[$column_key];
 | 
				
			||||||
            $clean_row[$key]['identifier'] = $value;
 | 
					            $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']))
 | 
					            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], $credit->client);
 | 
					                $clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $resource->client);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                $clean_row[$key]['display_value'] = $row[$column_key];
 | 
					                $clean_row[$key]['display_value'] = $row[$column_key];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Document;
 | 
					use App\Models\Document;
 | 
				
			||||||
use App\Transformers\DocumentTransformer;
 | 
					use App\Transformers\DocumentTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -56,6 +56,7 @@ class DocumentExport extends BaseExport
 | 
				
			|||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($document) {
 | 
					                ->map(function ($document) {
 | 
				
			||||||
                    $row = $this->buildRow($document);
 | 
					                    $row = $this->buildRow($document);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $document);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
				
			|||||||
@ -49,7 +49,8 @@ class ExpenseExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
@ -158,6 +159,10 @@ class ExpenseExport extends BaseExport
 | 
				
			|||||||
            $entity['expense.assigned_user'] = $expense->assigned_user ? $expense->assigned_user->present()->name() : '';
 | 
					            $entity['expense.assigned_user'] = $expense->assigned_user ? $expense->assigned_user->present()->name() : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('expense.category_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['expense.category_id'] = $expense->category ? $expense->category->name : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ use App\Libraries\MultiDB;
 | 
				
			|||||||
use App\Export\CSV\BaseExport;
 | 
					use App\Export\CSV\BaseExport;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use App\Transformers\InvoiceTransformer;
 | 
					use App\Transformers\InvoiceTransformer;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InvoiceExport extends BaseExport
 | 
					class InvoiceExport extends BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -78,7 +78,8 @@ class InvoiceExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
@ -94,7 +95,6 @@ class InvoiceExport extends BaseExport
 | 
				
			|||||||
        //insert the header
 | 
					        //insert the header
 | 
				
			||||||
        $this->csv->insertOne($this->buildHeader());
 | 
					        $this->csv->insertOne($this->buildHeader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query->cursor()
 | 
					        $query->cursor()
 | 
				
			||||||
            ->each(function ($invoice) {
 | 
					            ->each(function ($invoice) {
 | 
				
			||||||
                $this->csv->insertOne($this->buildRow($invoice));
 | 
					                $this->csv->insertOne($this->buildRow($invoice));
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Transformers\InvoiceTransformer;
 | 
					use App\Transformers\InvoiceTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -33,6 +33,8 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private array $storage_array = [];
 | 
					    private array $storage_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private array $storage_item_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private array $decorate_keys = [
 | 
					    private array $decorate_keys = [
 | 
				
			||||||
        'client',
 | 
					        'client',
 | 
				
			||||||
        'currency_id',
 | 
					        'currency_id',
 | 
				
			||||||
@ -62,7 +64,8 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $query = Invoice::query()
 | 
					        $query = Invoice::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')->where('company_id', $this->company->id)
 | 
					                        ->with('client')
 | 
				
			||||||
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
                        ->where('is_deleted', 0);
 | 
					                        ->where('is_deleted', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = $this->addDateRange($query);
 | 
					        $query = $this->addDateRange($query);
 | 
				
			||||||
@ -81,12 +84,21 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
					                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
            })->toArray();
 | 
					            })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query->cursor()
 | 
					 | 
				
			||||||
              ->each(function ($resource) {
 | 
					 | 
				
			||||||
                $this->iterateItems($resource);
 | 
					 | 
				
			||||||
               });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return array_merge(['columns' => $header], $this->storage_array);
 | 
					        $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);
 | 
				
			||||||
 | 
					               
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -188,13 +200,7 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
            $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
 | 
					            $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // if($this->force_keys) {
 | 
					 | 
				
			||||||
        //     $entity['client'] = $invoice->client->present()->name();
 | 
					 | 
				
			||||||
        //     $entity['client_id_number'] = $invoice->client->id_number;
 | 
					 | 
				
			||||||
        //     $entity['client_number'] = $invoice->client->number;
 | 
					 | 
				
			||||||
        //     $entity['status'] = $invoice->stringStatus($invoice->status_id);
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Transformers\PaymentTransformer;
 | 
					use App\Transformers\PaymentTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,40 +28,6 @@ class PaymentExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public Writer $csv;
 | 
					    public Writer $csv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // public array $entity_keys = [
 | 
					 | 
				
			||||||
    //     'amount' => 'amount',
 | 
					 | 
				
			||||||
    //     'applied' => 'applied',
 | 
					 | 
				
			||||||
    //     'client' => 'client_id',
 | 
					 | 
				
			||||||
    //     'currency' => 'currency_id',
 | 
					 | 
				
			||||||
    //     'custom_value1' => 'custom_value1',
 | 
					 | 
				
			||||||
    //     'custom_value2' => 'custom_value2',
 | 
					 | 
				
			||||||
    //     'custom_value3' => 'custom_value3',
 | 
					 | 
				
			||||||
    //     'custom_value4' => 'custom_value4',
 | 
					 | 
				
			||||||
    //     'date' => 'date',
 | 
					 | 
				
			||||||
    //     'exchange_currency' => 'exchange_currency_id',
 | 
					 | 
				
			||||||
    //     'gateway' => 'gateway_type_id',
 | 
					 | 
				
			||||||
    //     'number' => 'number',
 | 
					 | 
				
			||||||
    //     'private_notes' => 'private_notes',
 | 
					 | 
				
			||||||
    //     'project' => 'project_id',
 | 
					 | 
				
			||||||
    //     'refunded' => 'refunded',
 | 
					 | 
				
			||||||
    //     'status' => 'status_id',
 | 
					 | 
				
			||||||
    //     'transaction_reference' => 'transaction_reference',
 | 
					 | 
				
			||||||
    //     'type' => 'type_id',
 | 
					 | 
				
			||||||
    //     'vendor' => 'vendor_id',
 | 
					 | 
				
			||||||
    //     'invoices' => 'invoices',
 | 
					 | 
				
			||||||
    // ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // private array $decorate_keys = [
 | 
					 | 
				
			||||||
    //     'vendor',
 | 
					 | 
				
			||||||
    //     'status',
 | 
					 | 
				
			||||||
    //     'project',
 | 
					 | 
				
			||||||
    //     'client',
 | 
					 | 
				
			||||||
    //     'currency',
 | 
					 | 
				
			||||||
    //     'exchange_currency',
 | 
					 | 
				
			||||||
    //     'type',
 | 
					 | 
				
			||||||
    //     'invoices',
 | 
					 | 
				
			||||||
    // ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct(Company $company, array $input)
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->company = $company;
 | 
					        $this->company = $company;
 | 
				
			||||||
@ -105,12 +71,12 @@ class PaymentExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function run()
 | 
				
			||||||
 | 
				
			|||||||
@ -13,11 +13,10 @@ namespace App\Export\CSV;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Document;
 | 
					 | 
				
			||||||
use App\Models\Product;
 | 
					use App\Models\Product;
 | 
				
			||||||
use App\Transformers\ProductTransformer;
 | 
					use App\Transformers\ProductTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -48,7 +47,8 @@ class ProductExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);    
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ use App\Libraries\MultiDB;
 | 
				
			|||||||
use App\Models\PurchaseOrder;
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use App\Transformers\PurchaseOrderTransformer;
 | 
					use App\Transformers\PurchaseOrderTransformer;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderExport extends BaseExport
 | 
					class PurchaseOrderExport extends BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -119,7 +119,8 @@ class PurchaseOrderExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,14 +11,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Export\CSV;
 | 
					namespace App\Export\CSV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					 | 
				
			||||||
use App\Transformers\PurchaseOrderTransformer;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use App\Transformers\PurchaseOrderTransformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderItemExport extends BaseExport
 | 
					class PurchaseOrderItemExport extends BaseExport
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -33,6 +33,8 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private array $storage_array = [];
 | 
					    private array $storage_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private array $storage_item_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(Company $company, array $input)
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->company = $company;
 | 
					        $this->company = $company;
 | 
				
			||||||
@ -50,7 +52,6 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
					        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            // $this->force_keys = true;
 | 
					 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
 | 
					            $this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,9 +79,16 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
        $query->cursor()
 | 
					        $query->cursor()
 | 
				
			||||||
              ->each(function ($resource) {
 | 
					              ->each(function ($resource) {
 | 
				
			||||||
                $this->iterateItems($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_array);
 | 
					        return array_merge(['columns' => $header], $this->storage_item_array);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function run()
 | 
				
			||||||
@ -113,7 +121,7 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
        foreach ($purchase_order->line_items as $item) {
 | 
					        foreach ($purchase_order->line_items as $item) {
 | 
				
			||||||
            $item_array = [];
 | 
					            $item_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
 | 
					            foreach (array_values(array_intersect($this->input['report_keys'], $this->item_report_keys)) as $key) { //items iterator produces item array
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (str_contains($key, "item.")) {
 | 
					                if (str_contains($key, "item.")) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -190,4 +198,5 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Transformers\QuoteTransformer;
 | 
					use App\Transformers\QuoteTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,7 +80,8 @@ class QuoteExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    return $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
                })->toArray();
 | 
					                })->toArray();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
        return array_merge(['columns' => $header], $report);
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Transformers\QuoteTransformer;
 | 
					use App\Transformers\QuoteTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29,7 +29,8 @@ class QuoteItemExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public Writer $csv;
 | 
					    public Writer $csv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private array $storage_array;
 | 
					    private array $storage_array = [];
 | 
				
			||||||
 | 
					    private array $storage_item_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private array $decorate_keys = [
 | 
					    private array $decorate_keys = [
 | 
				
			||||||
        'client',
 | 
					        'client',
 | 
				
			||||||
@ -77,12 +78,20 @@ class QuoteItemExport extends BaseExport
 | 
				
			|||||||
                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
					                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
            })->toArray();
 | 
					            })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query->cursor()
 | 
					            $query->cursor()
 | 
				
			||||||
              ->each(function ($resource) {
 | 
					                ->each(function ($resource) {
 | 
				
			||||||
                $this->iterateItems($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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return array_merge(['columns' => $header], $this->storage_array);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Transformers\RecurringInvoiceTransformer;
 | 
					use App\Transformers\RecurringInvoiceTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,55 +29,6 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public Writer $csv;
 | 
					    public Writer $csv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public array $entity_keys = [
 | 
					 | 
				
			||||||
        'amount' => 'amount',
 | 
					 | 
				
			||||||
        'balance' => 'balance',
 | 
					 | 
				
			||||||
        'client' => 'client_id',
 | 
					 | 
				
			||||||
        // 'custom_surcharge1' => 'custom_surcharge1',
 | 
					 | 
				
			||||||
        // 'custom_surcharge2' => 'custom_surcharge2',
 | 
					 | 
				
			||||||
        // 'custom_surcharge3' => 'custom_surcharge3',
 | 
					 | 
				
			||||||
        // 'custom_surcharge4' => 'custom_surcharge4',
 | 
					 | 
				
			||||||
        'custom_value1' => 'custom_value1',
 | 
					 | 
				
			||||||
        'custom_value2' => 'custom_value2',
 | 
					 | 
				
			||||||
        'custom_value3' => 'custom_value3',
 | 
					 | 
				
			||||||
        'custom_value4' => 'custom_value4',
 | 
					 | 
				
			||||||
        'date' => 'date',
 | 
					 | 
				
			||||||
        'discount' => 'discount',
 | 
					 | 
				
			||||||
        'due_date' => 'due_date',
 | 
					 | 
				
			||||||
        'exchange_rate' => 'exchange_rate',
 | 
					 | 
				
			||||||
        'footer' => 'footer',
 | 
					 | 
				
			||||||
        'number' => 'number',
 | 
					 | 
				
			||||||
        'paid_to_date' => 'paid_to_date',
 | 
					 | 
				
			||||||
        'partial' => 'partial',
 | 
					 | 
				
			||||||
        'partial_due_date' => 'partial_due_date',
 | 
					 | 
				
			||||||
        'po_number' => 'po_number',
 | 
					 | 
				
			||||||
        'private_notes' => 'private_notes',
 | 
					 | 
				
			||||||
        'public_notes' => 'public_notes',
 | 
					 | 
				
			||||||
        'next_send_date' => 'next_send_date',
 | 
					 | 
				
			||||||
        'status' => 'status_id',
 | 
					 | 
				
			||||||
        'tax_name1' => 'tax_name1',
 | 
					 | 
				
			||||||
        'tax_name2' => 'tax_name2',
 | 
					 | 
				
			||||||
        'tax_name3' => 'tax_name3',
 | 
					 | 
				
			||||||
        'tax_rate1' => 'tax_rate1',
 | 
					 | 
				
			||||||
        'tax_rate2' => 'tax_rate2',
 | 
					 | 
				
			||||||
        'tax_rate3' => 'tax_rate3',
 | 
					 | 
				
			||||||
        'terms' => 'terms',
 | 
					 | 
				
			||||||
        'total_taxes' => 'total_taxes',
 | 
					 | 
				
			||||||
        'currency' => 'currency_id',
 | 
					 | 
				
			||||||
        'vendor' => 'vendor_id',
 | 
					 | 
				
			||||||
        'project' => 'project_id',
 | 
					 | 
				
			||||||
        'frequency_id' => 'frequency_id',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private array $decorate_keys = [
 | 
					 | 
				
			||||||
        'country',
 | 
					 | 
				
			||||||
        'client',
 | 
					 | 
				
			||||||
        'currency',
 | 
					 | 
				
			||||||
        'status',
 | 
					 | 
				
			||||||
        'vendor',
 | 
					 | 
				
			||||||
        'project',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct(Company $company, array $input)
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->company = $company;
 | 
					        $this->company = $company;
 | 
				
			||||||
@ -84,7 +36,7 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
        $this->invoice_transformer = new RecurringInvoiceTransformer();
 | 
					        $this->invoice_transformer = new RecurringInvoiceTransformer();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function init(): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
        App::forgetInstance('translator');
 | 
					        App::forgetInstance('translator');
 | 
				
			||||||
@ -92,23 +44,33 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
        $t = app('translator');
 | 
					        $t = app('translator');
 | 
				
			||||||
        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
					        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //load the CSV document from a string
 | 
					 | 
				
			||||||
        $this->csv = Writer::createFromString();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
					            $this->input['report_keys'] = array_values($this->recurring_invoice_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //insert the header
 | 
					 | 
				
			||||||
        $this->csv->insertOne($this->buildHeader());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query = RecurringInvoice::query()
 | 
					        $query = RecurringInvoice::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')->where('company_id', $this->company->id)
 | 
					                        ->with('client')
 | 
				
			||||||
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
                        ->where('is_deleted', 0);
 | 
					                        ->where('is_deleted', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = $this->addDateRange($query);
 | 
					        $query = $this->addDateRange($query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query  = $this->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //load the CSV document from a string
 | 
				
			||||||
 | 
					        $this->csv = Writer::createFromString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //insert the header
 | 
				
			||||||
 | 
					        $this->csv->insertOne($this->buildHeader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query->cursor()
 | 
					        $query->cursor()
 | 
				
			||||||
            ->each(function ($invoice) {
 | 
					            ->each(function ($invoice) {
 | 
				
			||||||
                $this->csv->insertOne($this->buildRow($invoice));
 | 
					                $this->csv->insertOne($this->buildRow($invoice));
 | 
				
			||||||
@ -117,6 +79,27 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
        return $this->csv->toString();
 | 
					        return $this->csv->toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function returnJson()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = $this->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $headerdisplay = $this->buildHeader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
 | 
				
			||||||
 | 
					                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
 | 
					            })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $report = $query->cursor()
 | 
				
			||||||
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
					                    return $this->processMetaData($row, $resource);
 | 
				
			||||||
 | 
					                })->toArray();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return array_merge(['columns' => $header], $report);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function buildRow(RecurringInvoice $invoice) :array
 | 
					    private function buildRow(RecurringInvoice $invoice) :array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $transformed_invoice = $this->invoice_transformer->transform($invoice);
 | 
					        $transformed_invoice = $this->invoice_transformer->transform($invoice);
 | 
				
			||||||
@ -124,22 +107,13 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
        $entity = [];
 | 
					        $entity = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (array_values($this->input['report_keys']) as $key) {
 | 
					        foreach (array_values($this->input['report_keys']) as $key) {
 | 
				
			||||||
            $keyval = array_search($key, $this->entity_keys);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$keyval) {
 | 
					            $parts = explode('.', $key);
 | 
				
			||||||
                $keyval = array_search(str_replace("recurring_invoice.", "", $key), $this->entity_keys) ?? $key;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$keyval) {
 | 
					            if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
 | 
				
			||||||
                $keyval = $key;
 | 
					                $entity[$key] = $transformed_invoice[$parts[1]];
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (array_key_exists($key, $transformed_invoice)) {
 | 
					 | 
				
			||||||
                $entity[$keyval] = $transformed_invoice[$key];
 | 
					 | 
				
			||||||
            } elseif (array_key_exists($keyval, $transformed_invoice)) {
 | 
					 | 
				
			||||||
                $entity[$keyval] = $transformed_invoice[$keyval];
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
 | 
					                $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -174,7 +148,7 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) {
 | 
					        if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
 | 
					            $entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ use App\Models\Task;
 | 
				
			|||||||
use App\Models\Timezone;
 | 
					use App\Models\Timezone;
 | 
				
			||||||
use App\Transformers\TaskTransformer;
 | 
					use App\Transformers\TaskTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
@ -33,30 +34,9 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public Writer $csv;
 | 
					    public Writer $csv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public array $entity_keys = [
 | 
					    private array $storage_array = [];
 | 
				
			||||||
        'start_date' => 'start_date',
 | 
					 | 
				
			||||||
        'end_date' => 'end_date',
 | 
					 | 
				
			||||||
        'duration' => 'duration',
 | 
					 | 
				
			||||||
        'rate' => 'rate',
 | 
					 | 
				
			||||||
        'number' => 'number',
 | 
					 | 
				
			||||||
        'description' => 'description',
 | 
					 | 
				
			||||||
        'custom_value1' => 'custom_value1',
 | 
					 | 
				
			||||||
        'custom_value2' => 'custom_value2',
 | 
					 | 
				
			||||||
        'custom_value3' => 'custom_value3',
 | 
					 | 
				
			||||||
        'custom_value4' => 'custom_value4',
 | 
					 | 
				
			||||||
        'status' => 'status_id',
 | 
					 | 
				
			||||||
        'project' => 'project_id',
 | 
					 | 
				
			||||||
     ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private array $decorate_keys = [
 | 
					    private array $storage_item_array = [];
 | 
				
			||||||
        'status',
 | 
					 | 
				
			||||||
        'project',
 | 
					 | 
				
			||||||
        'client',
 | 
					 | 
				
			||||||
        'invoice',
 | 
					 | 
				
			||||||
        'start_date',
 | 
					 | 
				
			||||||
        'end_date',
 | 
					 | 
				
			||||||
        'duration',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(Company $company, array $input)
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -65,7 +45,7 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
        $this->entity_transformer = new TaskTransformer();
 | 
					        $this->entity_transformer = new TaskTransformer();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function init(): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
        App::forgetInstance('translator');
 | 
					        App::forgetInstance('translator');
 | 
				
			||||||
@ -74,19 +54,12 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
					        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
 | 
					        $this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        //load the CSV document from a string
 | 
					 | 
				
			||||||
        $this->csv = Writer::createFromString();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ksort($this->entity_keys);
 | 
					        ksort($this->entity_keys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
					            $this->input['report_keys'] = array_values($this->task_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //insert the header
 | 
					 | 
				
			||||||
        $this->csv->insertOne($this->buildHeader());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query = Task::query()
 | 
					        $query = Task::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->where('company_id', $this->company->id)
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
@ -94,52 +67,87 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $query = $this->addDateRange($query);
 | 
					        $query = $this->addDateRange($query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = $this->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //load the CSV document from a string
 | 
				
			||||||
 | 
					        $this->csv = Writer::createFromString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //insert the header
 | 
				
			||||||
 | 
					        $this->csv->insertOne($this->buildHeader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query->cursor()
 | 
					        $query->cursor()
 | 
				
			||||||
              ->each(function ($entity) {
 | 
					              ->each(function ($entity) {
 | 
				
			||||||
                  $this->buildRow($entity);
 | 
					                  $this->buildRow($entity);
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->csv->insertAll($this->storage_array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->csv->toString();
 | 
					        return $this->csv->toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function returnJson()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = $this->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $headerdisplay = $this->buildHeader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
 | 
				
			||||||
 | 
					                return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
 | 
					            })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query->cursor()
 | 
				
			||||||
 | 
					                ->each(function ($resource) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					                    $this->buildRow($resource);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					                    foreach($this->storage_array as $row)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        $this->storage_item_array[] = $this->processMetaData($row, $resource);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $this->storage_array = [];
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					        nlog($this->storage_item_array);
 | 
				
			||||||
 | 
					        return array_merge(['columns' => $header], $this->storage_item_array);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function buildRow(Task $task)
 | 
					    private function buildRow(Task $task)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $entity = [];
 | 
					        $entity = [];
 | 
				
			||||||
        $transformed_entity = $this->entity_transformer->transform($task);
 | 
					        $transformed_entity = $this->entity_transformer->transform($task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (array_values($this->input['report_keys']) as $key) {
 | 
					        foreach (array_values($this->input['report_keys']) as $key) {
 | 
				
			||||||
            $keyval = array_search($key, $this->entity_keys);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$keyval) {
 | 
					            $parts = explode('.', $key);
 | 
				
			||||||
                $keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
 | 
					
 | 
				
			||||||
 | 
					            if (is_array($parts) && $parts[0] == 'task' && array_key_exists($parts[1], $transformed_entity)) {
 | 
				
			||||||
 | 
					                $entity[$key] = $transformed_entity[$parts[1]];
 | 
				
			||||||
 | 
					            } elseif (array_key_exists($key, $transformed_entity)) {
 | 
				
			||||||
 | 
					                $entity[$key] = $transformed_entity[$key];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$keyval) {
 | 
					 | 
				
			||||||
                $keyval = $key;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (array_key_exists($key, $transformed_entity)) {
 | 
					 | 
				
			||||||
                $entity[$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['task.start_date'] = '';
 | 
				
			||||||
        $entity['end_date'] = '';
 | 
					        $entity['task.end_date'] = '';
 | 
				
			||||||
        $entity['duration'] = '';
 | 
					        $entity['task.duration'] = '';
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
 | 
					        if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
 | 
				
			||||||
            $this->csv->insertOne($entity);
 | 
					            $this->storage_array[] = $entity;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $this->iterateLogs($task, $entity);
 | 
					            $this->iterateLogs($task, $entity);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function iterateLogs(Task $task, array $entity)
 | 
					    private function iterateLogs(Task $task, array $entity)
 | 
				
			||||||
@ -163,39 +171,40 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        foreach ($logs as $key => $item) {
 | 
					        foreach ($logs as $key => $item) {
 | 
				
			||||||
            if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
 | 
					            if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
 | 
				
			||||||
                $entity['start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
 | 
					                $entity['task.start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
 | 
					            if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
 | 
				
			||||||
                $entity['end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
 | 
					                $entity['task.end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
 | 
					            if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
 | 
				
			||||||
                $entity['end_date'] = ctrans('texts.is_running');
 | 
					                $entity['task.end_date'] = ctrans('texts.is_running');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
 | 
					            if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
 | 
				
			||||||
                $entity['duration'] = $task->calcDuration();
 | 
					                $entity['task.duration'] = $task->calcDuration();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            $entity = $this->decorateAdvancedFields($task, $entity);
 | 
					            $entity = $this->decorateAdvancedFields($task, $entity);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            $this->csv->insertOne($entity);
 | 
					            $this->storage_array[] = $entity;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            unset($entity['start_date']);
 | 
					            unset($entity['task.start_date']);
 | 
				
			||||||
            unset($entity['end_date']);
 | 
					            unset($entity['task.end_date']);
 | 
				
			||||||
            unset($entity['duration']);
 | 
					            unset($entity['task.duration']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function decorateAdvancedFields(Task $task, array $entity) :array
 | 
					    private function decorateAdvancedFields(Task $task, array $entity) :array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (in_array('status_id', $this->input['report_keys'])) {
 | 
					        if (in_array('task.status_id', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['status'] = $task->status()->exists() ? $task->status->name : '';
 | 
					            $entity['task.status_id'] = $task->status()->exists() ? $task->status->name : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('project_id', $this->input['report_keys'])) {
 | 
					        if (in_array('task.project_id', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['project'] = $task->project()->exists() ? $task->project->name : '';
 | 
					            $entity['task.project_id'] = $task->project()->exists() ? $task->project->name : '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Transformers\VendorContactTransformer;
 | 
					use App\Transformers\VendorContactTransformer;
 | 
				
			||||||
use App\Transformers\VendorTransformer;
 | 
					use App\Transformers\VendorTransformer;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Facades\App;
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
use League\Csv\Writer;
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -31,42 +32,6 @@ class VendorExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public string $date_key = 'created_at';
 | 
					    public string $date_key = 'created_at';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public array $entity_keys = [
 | 
					 | 
				
			||||||
        'address1' => 'vendor.address1',
 | 
					 | 
				
			||||||
        'address2' => 'vendor.address2',
 | 
					 | 
				
			||||||
        'city' => 'vendor.city',
 | 
					 | 
				
			||||||
        'country' => 'vendor.country_id',
 | 
					 | 
				
			||||||
        'custom_value1' => 'vendor.custom_value1',
 | 
					 | 
				
			||||||
        'custom_value2' => 'vendor.custom_value2',
 | 
					 | 
				
			||||||
        'custom_value3' => 'vendor.custom_value3',
 | 
					 | 
				
			||||||
        'custom_value4' => 'vendor.custom_value4',
 | 
					 | 
				
			||||||
        'id_number' => 'vendor.id_number',
 | 
					 | 
				
			||||||
        'name' => 'vendor.name',
 | 
					 | 
				
			||||||
        'number' => 'vendor.number',
 | 
					 | 
				
			||||||
        'phone' => 'vendor.phone',
 | 
					 | 
				
			||||||
        'postal_code' => 'vendor.postal_code',
 | 
					 | 
				
			||||||
        'private_notes' => 'vendor.private_notes',
 | 
					 | 
				
			||||||
        'public_notes' => 'vendor.public_notes',
 | 
					 | 
				
			||||||
        'state' => 'vendor.state',
 | 
					 | 
				
			||||||
        'vat_number' => 'vendor.vat_number',
 | 
					 | 
				
			||||||
        'website' => 'vendor.website',
 | 
					 | 
				
			||||||
        'currency' => 'vendor.currency',
 | 
					 | 
				
			||||||
        'first_name' => 'vendor_contact.first_name',
 | 
					 | 
				
			||||||
        'last_name' => 'vendor_contact.last_name',
 | 
					 | 
				
			||||||
        'contact_phone' => 'vendor_contact.phone',
 | 
					 | 
				
			||||||
        'contact_custom_value1' => 'vendor_contact.custom_value1',
 | 
					 | 
				
			||||||
        'contact_custom_value2' => 'vendor_contact.custom_value2',
 | 
					 | 
				
			||||||
        'contact_custom_value3' => 'vendor_contact.custom_value3',
 | 
					 | 
				
			||||||
        'contact_custom_value4' => 'vendor_contact.custom_value4',
 | 
					 | 
				
			||||||
        'email' => 'vendor_contact.email',
 | 
					 | 
				
			||||||
        'status' => 'vendor.status'
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private array $decorate_keys = [
 | 
					 | 
				
			||||||
        'vendor.country_id',
 | 
					 | 
				
			||||||
        'vendor.currency',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct(Company $company, array $input)
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->company = $company;
 | 
					        $this->company = $company;
 | 
				
			||||||
@ -75,8 +40,9 @@ class VendorExport extends BaseExport
 | 
				
			|||||||
        $this->contact_transformer = new VendorContactTransformer();
 | 
					        $this->contact_transformer = new VendorContactTransformer();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function init(): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
        App::forgetInstance('translator');
 | 
					        App::forgetInstance('translator');
 | 
				
			||||||
        App::setLocale($this->company->locale());
 | 
					        App::setLocale($this->company->locale());
 | 
				
			||||||
@ -87,19 +53,47 @@ class VendorExport extends BaseExport
 | 
				
			|||||||
        $this->csv = Writer::createFromString();
 | 
					        $this->csv = Writer::createFromString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
					            $this->input['report_keys'] = array_values($this->vendor_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        $query = Vendor::query()->with('contacts')
 | 
				
			||||||
 | 
					                        ->withTrashed()
 | 
				
			||||||
 | 
					                        ->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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $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
 | 
					        //insert the header
 | 
				
			||||||
        $this->csv->insertOne($this->buildHeader());
 | 
					        $this->csv->insertOne($this->buildHeader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Vendor::query()->with('contacts')
 | 
					 | 
				
			||||||
                                ->withTrashed()
 | 
					 | 
				
			||||||
                                ->where('company_id', $this->company->id)
 | 
					 | 
				
			||||||
                                ->where('is_deleted', 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query = $this->addDateRange($query);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query->cursor()
 | 
					        $query->cursor()
 | 
				
			||||||
              ->each(function ($vendor) {
 | 
					              ->each(function ($vendor) {
 | 
				
			||||||
                  $this->csv->insertOne($this->buildRow($vendor));
 | 
					                  $this->csv->insertOne($this->buildRow($vendor));
 | 
				
			||||||
@ -110,7 +104,7 @@ class VendorExport extends BaseExport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function buildRow(Vendor $vendor) :array
 | 
					    private function buildRow(Vendor $vendor) :array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $transformed_contact = [];
 | 
					        $transformed_contact = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $transformed_vendor = $this->vendor_transformer->transform($vendor);
 | 
					        $transformed_vendor = $this->vendor_transformer->transform($vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,14 +117,12 @@ class VendorExport extends BaseExport
 | 
				
			|||||||
        foreach (array_values($this->input['report_keys']) as $key) {
 | 
					        foreach (array_values($this->input['report_keys']) as $key) {
 | 
				
			||||||
            $parts = explode('.', $key);
 | 
					            $parts = explode('.', $key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $keyval = array_search($key, $this->entity_keys);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
 | 
					            if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
 | 
				
			||||||
                $entity[$keyval] = $transformed_vendor[$parts[1]];
 | 
					                $entity[$key] = $transformed_vendor[$parts[1]];
 | 
				
			||||||
            } elseif (is_array($parts) && $parts[0] == 'vendor_contact' && array_key_exists($parts[1], $transformed_contact)) {
 | 
					            } elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
 | 
				
			||||||
                $entity[$keyval] = $transformed_contact[$parts[1]];
 | 
					                $entity[$key] = $transformed_contact[$parts[1]];
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $entity[$keyval] = '';
 | 
					                $entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ class ClientFactory
 | 
				
			|||||||
        $client->is_deleted = 0;
 | 
					        $client->is_deleted = 0;
 | 
				
			||||||
        $client->client_hash = Str::random(40);
 | 
					        $client->client_hash = Str::random(40);
 | 
				
			||||||
        $client->settings = ClientSettings::defaults();
 | 
					        $client->settings = ClientSettings::defaults();
 | 
				
			||||||
 | 
					        $client->classification = '';
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $client;
 | 
					        return $client;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,9 @@ class RecurringExpenseFactory
 | 
				
			|||||||
        $recurring_expense->tax_amount1 = 0;
 | 
					        $recurring_expense->tax_amount1 = 0;
 | 
				
			||||||
        $recurring_expense->tax_amount2 = 0;
 | 
					        $recurring_expense->tax_amount2 = 0;
 | 
				
			||||||
        $recurring_expense->tax_amount3 = 0;
 | 
					        $recurring_expense->tax_amount3 = 0;
 | 
				
			||||||
        $recurring_expense->date = null;
 | 
					        $recurring_expense->date = now()->format('Y-m-d');
 | 
				
			||||||
 | 
					        $recurring_expense->next_send_date = now()->format('Y-m-d');
 | 
				
			||||||
 | 
					        $recurring_expense->next_send_date_client = now()->format('Y-m-d');
 | 
				
			||||||
        $recurring_expense->payment_date = null;
 | 
					        $recurring_expense->payment_date = null;
 | 
				
			||||||
        $recurring_expense->amount = 0;
 | 
					        $recurring_expense->amount = 0;
 | 
				
			||||||
        $recurring_expense->foreign_amount = 0;
 | 
					        $recurring_expense->foreign_amount = 0;
 | 
				
			||||||
@ -47,6 +49,7 @@ class RecurringExpenseFactory
 | 
				
			|||||||
        $recurring_expense->custom_value4 = '';
 | 
					        $recurring_expense->custom_value4 = '';
 | 
				
			||||||
        $recurring_expense->uses_inclusive_taxes = true;
 | 
					        $recurring_expense->uses_inclusive_taxes = true;
 | 
				
			||||||
        $recurring_expense->calculate_tax_by_amount = true;
 | 
					        $recurring_expense->calculate_tax_by_amount = true;
 | 
				
			||||||
 | 
					        $recurring_expense->remaining_cycles = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $recurring_expense;
 | 
					        return $recurring_expense;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,7 @@ class VendorFactory
 | 
				
			|||||||
        $vendor->country_id = 4;
 | 
					        $vendor->country_id = 4;
 | 
				
			||||||
        $vendor->is_deleted = 0;
 | 
					        $vendor->is_deleted = 0;
 | 
				
			||||||
        $vendor->vendor_hash = Str::random(40);
 | 
					        $vendor->vendor_hash = Str::random(40);
 | 
				
			||||||
 | 
					        $vendor->classification = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $vendor;
 | 
					        return $vendor;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,10 @@ class ExpenseFilters extends QueryFilters
 | 
				
			|||||||
                ->orWhere('custom_value1', 'like', '%'.$filter.'%')
 | 
					                ->orWhere('custom_value1', 'like', '%'.$filter.'%')
 | 
				
			||||||
                ->orWhere('custom_value2', 'like', '%'.$filter.'%')
 | 
					                ->orWhere('custom_value2', 'like', '%'.$filter.'%')
 | 
				
			||||||
                ->orWhere('custom_value3', 'like', '%'.$filter.'%')
 | 
					                ->orWhere('custom_value3', 'like', '%'.$filter.'%')
 | 
				
			||||||
                ->orWhere('custom_value4', 'like', '%'.$filter.'%');
 | 
					                ->orWhere('custom_value4', 'like', '%'.$filter.'%')
 | 
				
			||||||
 | 
					                ->orWhereHas('category', function ($q) use ($filter) {
 | 
				
			||||||
 | 
					                              $q->where('name', 'like', '%'.$filter.'%');
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -166,16 +169,27 @@ class ExpenseFilters extends QueryFilters
 | 
				
			|||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($sort_col[0] == 'client_id') {
 | 
					        if ($sort_col[0] == 'client_id' && in_array($sort_col[1], ['asc', 'desc'])) {
 | 
				
			||||||
            return $this->builder->orderBy(\App\Models\Client::select('name')
 | 
					            return $this->builder
 | 
				
			||||||
 | 
					                    ->orderByRaw('ISNULL(client_id), client_id '. $sort_col[1])
 | 
				
			||||||
 | 
					                    ->orderBy(\App\Models\Client::select('name')
 | 
				
			||||||
                    ->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
 | 
					                    ->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($sort_col[0] == 'vendor_id') {
 | 
					        if ($sort_col[0] == 'vendor_id' && in_array($sort_col[1], ['asc', 'desc'])) {
 | 
				
			||||||
            return $this->builder->orderBy(\App\Models\Vendor::select('name')
 | 
					            return $this->builder
 | 
				
			||||||
 | 
					                    ->orderByRaw('ISNULL(vendor_id), vendor_id '. $sort_col[1])
 | 
				
			||||||
 | 
					                    ->orderBy(\App\Models\Vendor::select('name')
 | 
				
			||||||
                    ->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
 | 
					                    ->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($sort_col[0] == 'category_id' && in_array($sort_col[1], ['asc', 'desc'])) {
 | 
				
			||||||
 | 
					            return $this->builder
 | 
				
			||||||
 | 
					                    ->orderByRaw('ISNULL(category_id), category_id '. $sort_col[1])
 | 
				
			||||||
 | 
					                    ->orderBy(\App\Models\ExpenseCategory::select('name')
 | 
				
			||||||
 | 
					                    ->whereColumn('expense_categories.id', 'expenses.category_id'), $sort_col[1]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
 | 
					        if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
 | 
				
			||||||
            return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
					            return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
				
			||||||
 | 
				
			|||||||
@ -229,6 +229,32 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
        return $this->builder->where('due_date', '>=', $date);
 | 
					        return $this->builder->where('due_date', '>=', $date);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function date_range(string $date_range = ''): Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $parts = explode(",", $date_range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($parts) != 3) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!in_array($parts[0], ['date','due_date'])) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $start_date = Carbon::parse($parts[1]);
 | 
				
			||||||
 | 
					            $end_date = Carbon::parse($parts[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->builder->whereBetween($parts[0], [$start_date, $end_date]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        catch(\Exception $e){
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Sorts the list based on $sort.
 | 
					     * Sorts the list based on $sort.
 | 
				
			||||||
 | 
				
			|||||||
@ -12,8 +12,9 @@
 | 
				
			|||||||
namespace App\Filters;
 | 
					namespace App\Filters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * PaymentFilters.
 | 
					 * PaymentFilters.
 | 
				
			||||||
@ -177,6 +178,33 @@ class PaymentFilters extends QueryFilters
 | 
				
			|||||||
        return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
					        return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function date_range(string $date_range = ''): Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $parts = explode(",", $date_range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($parts) != 3) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!in_array($parts[0], ['date'])) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $start_date = Carbon::parse($parts[1]);
 | 
				
			||||||
 | 
					            $end_date = Carbon::parse($parts[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->builder->whereBetween($parts[0], [$start_date, $end_date]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        catch(\Exception $e){
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Filters the query by the users company ID.
 | 
					     * Filters the query by the users company ID.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -391,15 +391,15 @@ class InvoiceItemSum
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->setGroupedTaxes(collect([]));
 | 
					        $this->setGroupedTaxes(collect([]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $item_tax = 0;
 | 
					        foreach ($this->line_items as $key => $this->item) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach ($this->line_items as $this->item) {
 | 
					 | 
				
			||||||
            if ($this->item->line_total == 0) {
 | 
					            if ($this->item->line_total == 0) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            $item_tax = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
					            //$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
				
			||||||
            $amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total)) : 0;
 | 
					            $amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->invoice->discount * ( $this->item->line_total / $this->sub_total)) : 0;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            $item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
 | 
					            $item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -424,9 +424,19 @@ class InvoiceItemSum
 | 
				
			|||||||
            if ($item_tax_rate3_total != 0) {
 | 
					            if ($item_tax_rate3_total != 0) {
 | 
				
			||||||
                $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
					                $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->item->gross_line_total = $this->getLineTotal() + $item_tax;
 | 
				
			||||||
 | 
					            $this->item->tax_amount = $item_tax;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->line_items[$key] = $this->item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->setTotalTaxes($this->getTotalTaxes() + $item_tax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->setTotalTaxes($item_tax);
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -349,15 +349,17 @@ class InvoiceItemSumInclusive
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->setGroupedTaxes(collect([]));
 | 
					        $this->setGroupedTaxes(collect([]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $item_tax = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($this->line_items as $this->item) {
 | 
					        foreach ($this->line_items as $this->item) {
 | 
				
			||||||
            if ($this->sub_total == 0) {
 | 
					            if ($this->sub_total == 0) {
 | 
				
			||||||
                $amount = $this->item->line_total;
 | 
					                $amount = $this->item->line_total;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
					                $amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->invoice->discount * ($this->item->line_total / $this->sub_total)) : 0;
 | 
				
			||||||
 | 
					                // $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            $item_tax = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
 | 
					            $item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $item_tax += $item_tax_rate1_total;
 | 
					            $item_tax += $item_tax_rate1_total;
 | 
				
			||||||
@ -381,9 +383,17 @@ class InvoiceItemSumInclusive
 | 
				
			|||||||
            if ($item_tax_rate3_total != 0) {
 | 
					            if ($item_tax_rate3_total != 0) {
 | 
				
			||||||
                $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
					                $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->setTotalTaxes($this->getTotalTaxes() + $item_tax);
 | 
				
			||||||
 | 
					            $this->item->gross_line_total = $this->getLineTotal();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $this->item->tax_amount = $item_tax;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->setTotalTaxes($item_tax);
 | 
					        return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $this->setTotalTaxes($item_tax);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -308,8 +308,9 @@ class InvoiceSum
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function setTaxMap(): self
 | 
					    public function setTaxMap(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->invoice->is_amount_discount == true) {
 | 
					        if ($this->invoice->is_amount_discount) {
 | 
				
			||||||
            $this->invoice_items->calcTaxesWithAmountDiscount();
 | 
					            $this->invoice_items->calcTaxesWithAmountDiscount();
 | 
				
			||||||
 | 
					            $this->invoice->line_items = $this->invoice_items->getLineItems();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->tax_map = collect();
 | 
					        $this->tax_map = collect();
 | 
				
			||||||
@ -327,8 +328,6 @@ class InvoiceSum
 | 
				
			|||||||
                return $value['key'] == $key;
 | 
					                return $value['key'] == $key;
 | 
				
			||||||
            })->sum('total');
 | 
					            })->sum('total');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //$total_line_tax -= $this->discount($total_line_tax);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
 | 
					            $this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->total_taxes += $total_line_tax;
 | 
					            $this->total_taxes += $total_line_tax;
 | 
				
			||||||
@ -377,16 +376,6 @@ class InvoiceSum
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function purgeTaxes(): self
 | 
					    public function purgeTaxes(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // $this->tax_rate1 = 0;
 | 
					 | 
				
			||||||
        // $this->tax_name1 = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $this->tax_rate2 = 0;
 | 
					 | 
				
			||||||
        // $this->tax_name2 = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $this->tax_rate3 = 0;
 | 
					 | 
				
			||||||
        // $this->tax_name3 = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $this->discount = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $line_items = collect($this->invoice->line_items);
 | 
					        $line_items = collect($this->invoice->line_items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -315,8 +315,9 @@ class InvoiceSumInclusive
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function setTaxMap()
 | 
					    public function setTaxMap()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->invoice->is_amount_discount == true) {
 | 
					        if ($this->invoice->is_amount_discount) {
 | 
				
			||||||
            $this->invoice_items->calcTaxesWithAmountDiscount();
 | 
					            $this->invoice_items->calcTaxesWithAmountDiscount();
 | 
				
			||||||
 | 
					            $this->invoice->line_items = $this->invoice_items->getLineItems();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->tax_map = collect();
 | 
					        $this->tax_map = collect();
 | 
				
			||||||
 | 
				
			|||||||
@ -12,37 +12,37 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Auth;
 | 
					namespace App\Http\Controllers\Auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Google_Client;
 | 
					 | 
				
			||||||
use App\Models\User;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Models\Account;
 | 
					 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					 | 
				
			||||||
use App\Utils\TruthSource;
 | 
					 | 
				
			||||||
use Microsoft\Graph\Model;
 | 
					 | 
				
			||||||
use App\Models\CompanyUser;
 | 
					 | 
				
			||||||
use App\Models\CompanyToken;
 | 
					 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					 | 
				
			||||||
use App\Libraries\OAuth\OAuth;
 | 
					 | 
				
			||||||
use App\Events\User\UserLoggedIn;
 | 
					 | 
				
			||||||
use Illuminate\Http\JsonResponse;
 | 
					 | 
				
			||||||
use PragmaRX\Google2FA\Google2FA;
 | 
					 | 
				
			||||||
use App\Jobs\Account\CreateAccount;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Auth;
 | 
					 | 
				
			||||||
use App\Utils\Traits\User\LoginCache;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Cache;
 | 
					 | 
				
			||||||
use Turbo124\Beacon\Facades\LightLogs;
 | 
					 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					 | 
				
			||||||
use App\Jobs\Company\CreateCompanyToken;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Response;
 | 
					 | 
				
			||||||
use Laravel\Socialite\Facades\Socialite;
 | 
					 | 
				
			||||||
use App\Http\Requests\Login\LoginRequest;
 | 
					 | 
				
			||||||
use App\Libraries\OAuth\Providers\Google;
 | 
					 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					 | 
				
			||||||
use App\DataMapper\Analytics\LoginFailure;
 | 
					use App\DataMapper\Analytics\LoginFailure;
 | 
				
			||||||
use App\DataMapper\Analytics\LoginSuccess;
 | 
					use App\DataMapper\Analytics\LoginSuccess;
 | 
				
			||||||
use App\Utils\Traits\UserSessionAttributes;
 | 
					use App\Events\User\UserLoggedIn;
 | 
				
			||||||
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
 | 
					use App\Http\Requests\Login\LoginRequest;
 | 
				
			||||||
 | 
					use App\Jobs\Account\CreateAccount;
 | 
				
			||||||
 | 
					use App\Jobs\Company\CreateCompanyToken;
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Libraries\OAuth\OAuth;
 | 
				
			||||||
 | 
					use App\Libraries\OAuth\Providers\Google;
 | 
				
			||||||
 | 
					use App\Models\Account;
 | 
				
			||||||
 | 
					use App\Models\CompanyToken;
 | 
				
			||||||
 | 
					use App\Models\CompanyUser;
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
use App\Transformers\CompanyUserTransformer;
 | 
					use App\Transformers\CompanyUserTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Utils\Traits\User\LoginCache;
 | 
				
			||||||
 | 
					use App\Utils\Traits\UserSessionAttributes;
 | 
				
			||||||
 | 
					use App\Utils\TruthSource;
 | 
				
			||||||
 | 
					use Google_Client;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
 | 
					use Illuminate\Foundation\Auth\AuthenticatesUsers;
 | 
				
			||||||
 | 
					use Illuminate\Http\JsonResponse;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Auth;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Response;
 | 
				
			||||||
 | 
					use Laravel\Socialite\Facades\Socialite;
 | 
				
			||||||
 | 
					use Microsoft\Graph\Model;
 | 
				
			||||||
 | 
					use PragmaRX\Google2FA\Google2FA;
 | 
				
			||||||
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LoginController extends BaseController
 | 
					class LoginController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -418,10 +418,12 @@ class LoginController extends BaseController
 | 
				
			|||||||
            ->setReturnType(Model\User::class)
 | 
					            ->setReturnType(Model\User::class)
 | 
				
			||||||
            ->execute();
 | 
					            ->execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nlog($user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($user) {
 | 
					        if ($user) {
 | 
				
			||||||
            $account = request()->input('account');
 | 
					            $account = request()->input('account');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $email = $user->getMail() ?: $user->getUserPrincipalName();
 | 
					            $email = $user->getUserPrincipalName() ?? false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $query = [
 | 
					            $query = [
 | 
				
			||||||
                'oauth_user_id' => $user->getId(),
 | 
					                'oauth_user_id' => $user->getId(),
 | 
				
			||||||
@ -436,8 +438,8 @@ class LoginController extends BaseController
 | 
				
			|||||||
                return $this->existingOauthUser($existing_user);
 | 
					                return $this->existingOauthUser($existing_user);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //If this is a result user/email combo - lets add their OAuth details details
 | 
					            // If this is a result user/email combo - lets add their OAuth details details
 | 
				
			||||||
            if ($existing_login_user = MultiDB::hasUser(['email' => $email])) {
 | 
					            if ($email && $existing_login_user = MultiDB::hasUser(['email' => $email])) {
 | 
				
			||||||
                if (!$existing_login_user->account) {
 | 
					                if (!$existing_login_user->account) {
 | 
				
			||||||
                    return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
 | 
					                    return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -447,7 +449,6 @@ class LoginController extends BaseController
 | 
				
			|||||||
                return $this->existingLoginUser($user->getId(), 'microsoft');
 | 
					                return $this->existingLoginUser($user->getId(), 'microsoft');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Signup!
 | 
					            // Signup!
 | 
				
			||||||
            if (request()->has('create') && request()->input('create') == 'true') {
 | 
					            if (request()->has('create') && request()->input('create') == 'true') {
 | 
				
			||||||
                $new_account = [
 | 
					                $new_account = [
 | 
				
			||||||
@ -640,8 +641,9 @@ class LoginController extends BaseController
 | 
				
			|||||||
            $parameters = ['response_type' => 'code', 'redirect_uri' => config('ninja.app_url') . "/auth/microsoft"];
 | 
					            $parameters = ['response_type' => 'code', 'redirect_uri' => config('ninja.app_url') . "/auth/microsoft"];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(request()->hasHeader('X-REACT') || request()->query('react'))
 | 
					        if(request()->hasHeader('X-REACT') || request()->query('react')) {
 | 
				
			||||||
            Cache::put("react_redir:".auth()->user()?->account->key, 'true', 300);
 | 
					            Cache::put("react_redir:".auth()->user()?->account->key, 'true', 300);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (request()->has('code')) {
 | 
					        if (request()->has('code')) {
 | 
				
			||||||
            return $this->handleProviderCallback($provider);
 | 
					            return $this->handleProviderCallback($provider);
 | 
				
			||||||
@ -698,7 +700,7 @@ class LoginController extends BaseController
 | 
				
			|||||||
        $request_from_react = Cache::pull("react_redir:".auth()->user()?->account?->key);
 | 
					        $request_from_react = Cache::pull("react_redir:".auth()->user()?->account?->key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // if($request_from_react)
 | 
					        // if($request_from_react)
 | 
				
			||||||
            $redirect_url = config('ninja.react_url')."/#/settings/user_details/connect";
 | 
					        $redirect_url = config('ninja.react_url')."/#/settings/user_details/connect";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect($redirect_url);
 | 
					        return redirect($redirect_url);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,7 @@
 | 
				
			|||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					 | 
				
			||||||
use App\Models\BankTransactionRule;
 | 
					use App\Models\BankTransactionRule;
 | 
				
			||||||
use App\Filters\BankTransactionFilters;
 | 
					 | 
				
			||||||
use App\Factory\BankTransactionRuleFactory;
 | 
					use App\Factory\BankTransactionRuleFactory;
 | 
				
			||||||
use App\Filters\BankTransactionRuleFilters;
 | 
					use App\Filters\BankTransactionRuleFilters;
 | 
				
			||||||
use App\Repositories\BankTransactionRuleRepository;
 | 
					use App\Repositories\BankTransactionRuleRepository;
 | 
				
			||||||
@ -26,6 +24,7 @@ use App\Http\Requests\BankTransactionRule\StoreBankTransactionRuleRequest;
 | 
				
			|||||||
use App\Http\Requests\BankTransactionRule\CreateBankTransactionRuleRequest;
 | 
					use App\Http\Requests\BankTransactionRule\CreateBankTransactionRuleRequest;
 | 
				
			||||||
use App\Http\Requests\BankTransactionRule\UpdateBankTransactionRuleRequest;
 | 
					use App\Http\Requests\BankTransactionRule\UpdateBankTransactionRuleRequest;
 | 
				
			||||||
use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest;
 | 
					use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest;
 | 
				
			||||||
 | 
					use App\Services\Bank\BankMatchingService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BankTransactionRuleController extends BaseController
 | 
					class BankTransactionRuleController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -256,8 +255,12 @@ class BankTransactionRuleController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule)
 | 
					    public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //stubs for updating the model
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $bank_transaction = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule);
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BankMatchingService::dispatch($user->company()->id, $user->company()->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($bank_transaction_rule->fresh());
 | 
					        return $this->itemResponse($bank_transaction_rule->fresh());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -304,6 +307,7 @@ class BankTransactionRuleController extends BaseController
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var \App\Models\User $user **/
 | 
					        /** @var \App\Models\User $user **/
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id);
 | 
					        $bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($bank_transaction_rule);
 | 
					        return $this->itemResponse($bank_transaction_rule);
 | 
				
			||||||
@ -355,6 +359,8 @@ class BankTransactionRuleController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), BankTransactionRuleFactory::create($user->company()->id, $user->id));
 | 
					        $bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), BankTransactionRuleFactory::create($user->company()->id, $user->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BankMatchingService::dispatch($user->company()->id, $user->company()->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($bank_transaction_rule);
 | 
					        return $this->itemResponse($bank_transaction_rule);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,10 @@ use Illuminate\Support\Facades\Hash;
 | 
				
			|||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
use Illuminate\View\View;
 | 
					use Illuminate\View\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EntityViewController
 | 
				
			||||||
 | 
					 * @deprecated 5.7 ?
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class EntityViewController extends Controller
 | 
					class EntityViewController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use MakesHash;
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
				
			|||||||
@ -89,11 +89,12 @@ class InvoiceController extends Controller
 | 
				
			|||||||
        $data = Cache::get($hash);
 | 
					        $data = Cache::get($hash);
 | 
				
			||||||
        $invitation = false;
 | 
					        $invitation = false;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        match($data['entity_type']){
 | 
					        match($data['entity_type'] ?? false){
 | 
				
			||||||
            'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
 | 
					            'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
 | 
				
			||||||
            'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
 | 
					            'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
 | 
				
			||||||
            'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']),
 | 
					            'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']),
 | 
				
			||||||
            'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']),
 | 
					            'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']),
 | 
				
			||||||
 | 
					            false => $invitation = false,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $invitation) {
 | 
					        if (! $invitation) {
 | 
				
			||||||
 | 
				
			|||||||
@ -12,21 +12,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\ClientPortal;
 | 
					namespace App\Http\Controllers\ClientPortal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Misc\InvitationWasViewed;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Models\Quote;
 | 
				
			||||||
 | 
					use Illuminate\View\View;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					use App\Models\QuoteInvitation;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Events\Quote\QuoteWasViewed;
 | 
					use App\Events\Quote\QuoteWasViewed;
 | 
				
			||||||
use App\Http\Controllers\Controller;
 | 
					use App\Http\Controllers\Controller;
 | 
				
			||||||
use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
 | 
					use App\Jobs\Invoice\InjectSignature;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\View\Factory;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Events\Misc\InvitationWasViewed;
 | 
				
			||||||
 | 
					use Symfony\Component\HttpFoundation\BinaryFileResponse;
 | 
				
			||||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest;
 | 
					use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest;
 | 
				
			||||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
 | 
					use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
 | 
				
			||||||
use App\Jobs\Invoice\InjectSignature;
 | 
					use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
 | 
				
			||||||
use App\Models\Quote;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Illuminate\Contracts\View\Factory;
 | 
					 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
use Illuminate\View\View;
 | 
					 | 
				
			||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class QuoteController extends Controller
 | 
					class QuoteController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -121,37 +122,38 @@ class QuoteController extends Controller
 | 
				
			|||||||
        /** @var \App\Models\ClientContact $client_contact **/
 | 
					        /** @var \App\Models\ClientContact $client_contact **/
 | 
				
			||||||
        $client_contact = auth()->user();
 | 
					        $client_contact = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $quotes = Quote::query()
 | 
					        $quote_invitations = QuoteInvitation::query()
 | 
				
			||||||
            ->whereIn('id', $ids)
 | 
					            ->with('quote','company')
 | 
				
			||||||
            ->whereClientId($client_contact->client_id)
 | 
					            ->whereIn('quote_id', $ids)
 | 
				
			||||||
 | 
					            ->where('client_contact_id', $client_contact->id)
 | 
				
			||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
            ->get();
 | 
					            ->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $quotes || $quotes->count() == 0) {
 | 
					        if (! $quote_invitations || $quote_invitations->count() == 0) {
 | 
				
			||||||
            return redirect()
 | 
					            return redirect()
 | 
				
			||||||
                ->route('client.quotes.index')
 | 
					                ->route('client.quotes.index')
 | 
				
			||||||
                ->with('message', ctrans('texts.no_quotes_available_for_download'));
 | 
					                ->with('message', ctrans('texts.no_quotes_available_for_download'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($quotes->count() == 1) {
 | 
					        if ($quote_invitations->count() == 1) {
 | 
				
			||||||
            $file = $quotes->first()->service()->getQuotePdf();
 | 
					            $invitation = $quote_invitations->first();
 | 
				
			||||||
            // return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
 | 
					            $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
 | 
				
			||||||
            return response()->streamDownload(function () use ($file) {
 | 
					            return response()->streamDownload(function () use ($file) {
 | 
				
			||||||
                echo Storage::get($file);
 | 
					                echo $file;
 | 
				
			||||||
            }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
					            }, $invitation->quote->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->buildZip($quotes);
 | 
					        return $this->buildZip($quote_invitations);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function buildZip($quotes)
 | 
					    private function buildZip($quote_invitations)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // create new archive
 | 
					        // create new archive
 | 
				
			||||||
        $zipFile = new \PhpZip\ZipFile();
 | 
					        $zipFile = new \PhpZip\ZipFile();
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            foreach ($quotes as $quote) {
 | 
					            foreach ($quote_invitations as $invitation) {
 | 
				
			||||||
                //add it to the zip
 | 
					                $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle();
 | 
				
			||||||
                $zipFile->addFromString(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true)));
 | 
					                $zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
 | 
					            $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
 | 
				
			||||||
@ -162,7 +164,6 @@ class QuoteController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return response()->download($filepath, $filename)->deleteFileAfterSend(true);
 | 
					            return response()->download($filepath, $filename)->deleteFileAfterSend(true);
 | 
				
			||||||
        } catch (\PhpZip\Exception\ZipException $e) {
 | 
					        } catch (\PhpZip\Exception\ZipException $e) {
 | 
				
			||||||
            // handle exception
 | 
					 | 
				
			||||||
        } finally {
 | 
					        } finally {
 | 
				
			||||||
            $zipFile->close();
 | 
					            $zipFile->close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -22,9 +22,10 @@ class SwitchCompanyController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function __invoke(string $contact)
 | 
					    public function __invoke(string $contact)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $client_contact = ClientContact::where('email', auth()->user()->email)
 | 
					        $client_contact = ClientContact::query()
 | 
				
			||||||
            ->where('id', $this->transformKeys($contact))
 | 
					                                       ->where('email', auth()->user()->email)
 | 
				
			||||||
            ->first();
 | 
					                                       ->where('id', $this->transformKeys($contact))
 | 
				
			||||||
 | 
					                                       ->firstOrFail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auth()->guard('contact')->loginUsingId($client_contact->id, true);
 | 
					        auth()->guard('contact')->loginUsingId($client_contact->id, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -697,4 +697,19 @@ class CompanyController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($company->fresh());
 | 
					        return $this->itemResponse($company->fresh());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function logo()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					        $company = $user->company();
 | 
				
			||||||
 | 
					        $logo = strlen($company->settings->company_logo) > 5 ? $company->settings->company_logo : 'https://pdf.invoicing.co/favicon-v2.png';
 | 
				
			||||||
 | 
					        $headers = ['Content-Disposition' => 'inline'];
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					        return response()->streamDownload(function () use ($logo){
 | 
				
			||||||
 | 
					            echo @file_get_contents($logo);
 | 
				
			||||||
 | 
					        }, 'logo.png', $headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -111,10 +111,11 @@ class CompanyUserController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function update(UpdateCompanyUserRequest $request, User $user)
 | 
					    public function update(UpdateCompanyUserRequest $request, User $user)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $auth_user */
 | 
				
			||||||
 | 
					        $auth_user = auth()->user();
 | 
				
			||||||
 | 
					        $company = $auth_user->company();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $company = auth()->user()->company();
 | 
					        $company_user = CompanyUser::query()->where('user_id', $user->id)->where('company_id',$company->id)->first();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $company_user) {
 | 
					        if (! $company_user) {
 | 
				
			||||||
            throw new ModelNotFoundException(ctrans('texts.company_user_not_found'));
 | 
					            throw new ModelNotFoundException(ctrans('texts.company_user_not_found'));
 | 
				
			||||||
@ -122,11 +123,16 @@ class CompanyUserController extends BaseController
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (auth()->user()->isAdmin()) {
 | 
					        if ($auth_user->isAdmin()) {
 | 
				
			||||||
            $company_user->fill($request->input('company_user'));
 | 
					            $company_user->fill($request->input('company_user'));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $company_user->settings = $request->input('company_user')['settings'];
 | 
					            $company_user->settings = $request->input('company_user')['settings'];
 | 
				
			||||||
            $company_user->notifications = $request->input('company_user')['notifications'];
 | 
					            $company_user->notifications = $request->input('company_user')['notifications'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(isset($request->input('company_user')['react_settings'])) {
 | 
				
			||||||
 | 
					                $company_user->react_settings = $request->input('company_user')['react_settings'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $company_user->save();
 | 
					        $company_user->save();
 | 
				
			||||||
@ -136,8 +142,11 @@ class CompanyUserController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function updatePreferences(UpdateCompanyUserPreferencesRequest $request, User $user)
 | 
					    public function updatePreferences(UpdateCompanyUserPreferencesRequest $request, User $user)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $auth_user */
 | 
				
			||||||
 | 
					        $auth_user = auth()->user();
 | 
				
			||||||
 | 
					        $company = $auth_user->company();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $company = auth()->user()->company();
 | 
					        $company = $auth_user->company();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
 | 
					        $company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,7 @@ class ConnectedAccountController extends BaseController
 | 
				
			|||||||
                      ->execute();
 | 
					                      ->execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($user) {
 | 
					        if ($user) {
 | 
				
			||||||
            $email = $user->getMail() ?: $user->getUserPrincipalName();
 | 
					            $email = $user->getUserPrincipalName() ?? false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nlog("microsoft");
 | 
					            nlog("microsoft");
 | 
				
			||||||
            nlog($email);
 | 
					            nlog($email);
 | 
				
			||||||
 | 
				
			|||||||
@ -385,8 +385,8 @@ class CreditController extends BaseController
 | 
				
			|||||||
        $credit = $this->credit_repository->save($request->all(), $credit);
 | 
					        $credit = $this->credit_repository->save($request->all(), $credit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $credit->service()
 | 
					        $credit->service()
 | 
				
			||||||
               ->triggeredActions($request)
 | 
					               ->triggeredActions($request);
 | 
				
			||||||
               ->deletePdf();
 | 
					            //    ->deletePdf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /** @var \App\Models\User $user**/
 | 
					        /** @var \App\Models\User $user**/
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
@ -529,20 +529,18 @@ class CreditController extends BaseController
 | 
				
			|||||||
        if ($action == 'bulk_download' && $credits->count() > 1) {
 | 
					        if ($action == 'bulk_download' && $credits->count() > 1) {
 | 
				
			||||||
            $credits->each(function ($credit) use($user){
 | 
					            $credits->each(function ($credit) use($user){
 | 
				
			||||||
                if ($user->cannot('view', $credit)) {
 | 
					                if ($user->cannot('view', $credit)) {
 | 
				
			||||||
                    nlog('access denied');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    return response()->json(['message' => ctrans('text.access_denied')]);
 | 
					                    return response()->json(['message' => ctrans('text.access_denied')]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ZipCredits::dispatch($credits, $credits->first()->company, $user);
 | 
					            ZipCredits::dispatch($credits->pluck('id')->toArray(), $credits->first()->company, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
					            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($action == 'bulk_print' && $user->can('view', $credits->first())) {
 | 
					        if ($action == 'bulk_print' && $user->can('view', $credits->first())) {
 | 
				
			||||||
            $paths = $credits->map(function ($credit) {
 | 
					            $paths = $credits->map(function ($credit) {
 | 
				
			||||||
                return $credit->service()->getCreditPdf($credit->invitations->first());
 | 
					                return (new \App\Jobs\Entity\CreateRawPdf($credit->invitations->first(), $credit->company->db))->handle();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
					            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
				
			||||||
@ -592,11 +590,8 @@ class CreditController extends BaseController
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'download':
 | 
					            case 'download':
 | 
				
			||||||
                // $file = $credit->pdf_file_path();
 | 
					 | 
				
			||||||
                $file = $credit->service()->getCreditPdf($credit->invitations->first());
 | 
					                $file = $credit->service()->getCreditPdf($credit->invitations->first());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return response()->streamDownload(function () use ($file) {
 | 
					                return response()->streamDownload(function () use ($file) {
 | 
				
			||||||
                    echo Storage::get($file);
 | 
					                    echo Storage::get($file);
 | 
				
			||||||
                }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
					                }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,6 @@ class EmailHistoryController extends BaseController
 | 
				
			|||||||
                 ->map(function ($system_log) {
 | 
					                 ->map(function ($system_log) {
 | 
				
			||||||
                     if($system_log->log['history'] ?? false) {
 | 
					                     if($system_log->log['history'] ?? false) {
 | 
				
			||||||
                        return $system_log->log['history'];
 | 
					                        return $system_log->log['history'];
 | 
				
			||||||
                        //  return json_decode($system_log->log['history'], true);
 | 
					 | 
				
			||||||
                     }
 | 
					                     }
 | 
				
			||||||
                 });
 | 
					                 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,7 +59,6 @@ class EmailHistoryController extends BaseController
 | 
				
			|||||||
                ->map(function ($system_log) {
 | 
					                ->map(function ($system_log) {
 | 
				
			||||||
                    if($system_log->log['history'] ?? false) {
 | 
					                    if($system_log->log['history'] ?? false) {
 | 
				
			||||||
                        return $system_log->log['history'];
 | 
					                        return $system_log->log['history'];
 | 
				
			||||||
                        // return json_decode($system_log->log['history'], true);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -92,15 +92,82 @@ class ImportController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            $class_map = $this->getEntityMap($entityType);
 | 
					            $class_map = $this->getEntityMap($entityType);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            $hints = $this->setImportHints($entityType, $class_map::importable(), $csv_array[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $data['mappings'][$entityType] = [
 | 
					            $data['mappings'][$entityType] = [
 | 
				
			||||||
                'available' => $class_map::importable(),
 | 
					                'available' => $class_map::importable(),
 | 
				
			||||||
                'headers'   => array_slice($csv_array, 0, 2),
 | 
					                'headers'   => array_slice($csv_array, 0, 2),
 | 
				
			||||||
 | 
					                'hints' => $hints,
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json($data);
 | 
					        return response()->json($data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function setImportHints($entity_type, $available_keys, $headers): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $hints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $translated_keys = collect($available_keys)->map(function ($value,$key){
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $parts = explode(".", $value);
 | 
				
			||||||
 | 
					            $index = $parts[0];
 | 
				
			||||||
 | 
					            $label = $parts[1] ?? $parts[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ['key' => $key, 'index' => ctrans("texts.{$index}"), 'label' => ctrans("texts.{$label}")];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach($headers as $key => $value) {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            foreach($translated_keys as $tkey => $tvalue)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if($this->testMatch($value, $tvalue['label'])) {
 | 
				
			||||||
 | 
					                    $hit = $tvalue['key'];
 | 
				
			||||||
 | 
					                    $hints[$key] = $hit;
 | 
				
			||||||
 | 
					                    unset($translated_keys[$tkey]);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    $hints[$key] = null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					             
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //second pass using the index of the translation here
 | 
				
			||||||
 | 
					        foreach($headers as $key => $value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(isset($hints[$key])) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach($translated_keys as $tkey => $tvalue) 
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if($this->testMatch($value, $tvalue['index'])) {
 | 
				
			||||||
 | 
					                    $hit = $tvalue['key'];
 | 
				
			||||||
 | 
					                    $hints[$key] = $hit;
 | 
				
			||||||
 | 
					                    unset($translated_keys[$tkey]);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $hints[$key] = null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $hints;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function testMatch($haystack, $needle): bool
 | 
				
			||||||
 | 
					    {  
 | 
				
			||||||
 | 
					        return stripos($haystack, $needle) !== false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function convertEncoding($data)
 | 
					    private function convertEncoding($data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -115,6 +182,9 @@ class ImportController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function import(ImportRequest $request)
 | 
					    public function import(ImportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = $request->all();
 | 
					        $data = $request->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (empty($data['hash'])) {
 | 
					        if (empty($data['hash'])) {
 | 
				
			||||||
@ -130,7 +200,7 @@ class ImportController extends Controller
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unset($data['files']);
 | 
					        unset($data['files']);
 | 
				
			||||||
        CSVIngest::dispatch($data, auth()->user()->company());
 | 
					        CSVIngest::dispatch($data, $user->company());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['message' => ctrans('texts.import_started')], 200);
 | 
					        return response()->json(['message' => ctrans('texts.import_started')], 200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -415,7 +415,7 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $invoice->service()
 | 
					        $invoice->service()
 | 
				
			||||||
                ->triggeredActions($request)
 | 
					                ->triggeredActions($request)
 | 
				
			||||||
                ->deletePdf()
 | 
					                // ->deletePdf()
 | 
				
			||||||
                ->adjustInventory($old_invoice);
 | 
					                ->adjustInventory($old_invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
@ -527,7 +527,7 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if ($action == 'bulk_print' && $user->can('view', $invoices->first())) {
 | 
					        if ($action == 'bulk_print' && $user->can('view', $invoices->first())) {
 | 
				
			||||||
            $paths = $invoices->map(function ($invoice) {
 | 
					            $paths = $invoices->map(function ($invoice) {
 | 
				
			||||||
                return $invoice->service()->getInvoicePdf();
 | 
					                return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first(), $invoice->company->db))->handle();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
					            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
				
			||||||
@ -700,7 +700,7 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'cancel':
 | 
					            case 'cancel':
 | 
				
			||||||
                $invoice = $invoice->service()->handleCancellation()->deletePdf()->save();
 | 
					                $invoice = $invoice->service()->handleCancellation()->save();
 | 
				
			||||||
                if (! $bulk) {
 | 
					                if (! $bulk) {
 | 
				
			||||||
                    $this->itemResponse($invoice);
 | 
					                    $this->itemResponse($invoice);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ class OneTimeTokenController extends BaseController
 | 
				
			|||||||
            'user_id' => $user->id,
 | 
					            'user_id' => $user->id,
 | 
				
			||||||
            'company_key'=> $user->company()->company_key,
 | 
					            'company_key'=> $user->company()->company_key,
 | 
				
			||||||
            'context' => $request->input('context'),
 | 
					            'context' => $request->input('context'),
 | 
				
			||||||
            'is_react' => $request->has('react') && $request->query('react') == 'true' ? true : false,
 | 
					            'is_react' => $request->hasHeader('X-REACT') ? true : false,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cache::put($hash, $data, 3600);
 | 
					        Cache::put($hash, $data, 3600);
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,10 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function create(CreatePurchaseOrderRequest $request)
 | 
					    public function create(CreatePurchaseOrderRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $purchase_order = PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id);
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $purchase_order = PurchaseOrderFactory::create($user->company()->id, $user->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($purchase_order);
 | 
					        return $this->itemResponse($purchase_order);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -183,7 +186,10 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store(StorePurchaseOrderRequest $request)
 | 
					    public function store(StorePurchaseOrderRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id));
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create($user->company()->id, $user->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $purchase_order = $purchase_order->service()
 | 
					        $purchase_order = $purchase_order->service()
 | 
				
			||||||
            ->fillDefaults()
 | 
					            ->fillDefaults()
 | 
				
			||||||
@ -361,7 +367,7 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $purchase_order = $purchase_order->service()
 | 
					        $purchase_order = $purchase_order->service()
 | 
				
			||||||
            ->triggeredActions($request)
 | 
					            ->triggeredActions($request)
 | 
				
			||||||
            ->touchPdf()
 | 
					            // ->touchPdf()
 | 
				
			||||||
            ->save();
 | 
					            ->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new PurchaseOrderWasUpdated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new PurchaseOrderWasUpdated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
@ -475,11 +481,14 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function bulk(BulkPurchaseOrderRequest $request)
 | 
					    public function bulk(BulkPurchaseOrderRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $action = $request->input('action');
 | 
					        $action = $request->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ids = $request->input('ids');
 | 
					        $ids = $request->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !auth()->user()->company()->account->account_sms_verified) {
 | 
					        if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) {
 | 
				
			||||||
            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
					            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -493,20 +502,20 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
         * Download Purchase Order/s
 | 
					         * Download Purchase Order/s
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if ($action == 'bulk_download' && $purchase_orders->count() >= 1) {
 | 
					        if ($action == 'bulk_download' && $purchase_orders->count() >= 1) {
 | 
				
			||||||
            $purchase_orders->each(function ($purchase_order) {
 | 
					            $purchase_orders->each(function ($purchase_order) use ($user){
 | 
				
			||||||
                if (auth()->user()->cannot('view', $purchase_order)) {
 | 
					                if ($user->cannot('view', $purchase_order)) {
 | 
				
			||||||
                    return response()->json(['message' => ctrans('text.access_denied')]);
 | 
					                    return response()->json(['message' => ctrans('text.access_denied')]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ZipPurchaseOrders::dispatch($purchase_orders, $purchase_orders->first()->company, auth()->user());
 | 
					            ZipPurchaseOrders::dispatch($purchase_orders->pluck("id")->toArray(), $purchase_orders->first()->company, auth()->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
					            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($action == 'bulk_print' && auth()->user()->can('view', $purchase_orders->first())) {
 | 
					        if ($action == 'bulk_print' && $user->can('view', $purchase_orders->first())) {
 | 
				
			||||||
            $paths = $purchase_orders->map(function ($purchase_order) {
 | 
					            $paths = $purchase_orders->map(function ($purchase_order) {
 | 
				
			||||||
                return $purchase_order->service()->getPurchaseOrderPdf();
 | 
					                return (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($purchase_order->invitations->first()))->rawPdf();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
					            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
				
			||||||
@ -519,8 +528,8 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Send the other actions to the switch
 | 
					         * Send the other actions to the switch
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        $purchase_orders->each(function ($purchase_order, $key) use ($action) {
 | 
					        $purchase_orders->each(function ($purchase_order, $key) use ($action, $user) {
 | 
				
			||||||
            if (auth()->user()->can('edit', $purchase_order)) {
 | 
					            if ($user->can('edit', $purchase_order)) {
 | 
				
			||||||
                $this->performAction($purchase_order, $action, true);
 | 
					                $this->performAction($purchase_order, $action, true);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ use App\Models\Quote;
 | 
				
			|||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\Account;
 | 
					use App\Models\Account;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use App\Factory\QuoteFactory;
 | 
					use App\Factory\QuoteFactory;
 | 
				
			||||||
use App\Filters\QuoteFilters;
 | 
					use App\Filters\QuoteFilters;
 | 
				
			||||||
@ -33,6 +34,7 @@ use App\Transformers\QuoteTransformer;
 | 
				
			|||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
use App\Transformers\InvoiceTransformer;
 | 
					use App\Transformers\InvoiceTransformer;
 | 
				
			||||||
 | 
					use App\Transformers\ProjectTransformer;
 | 
				
			||||||
use App\Factory\CloneQuoteToInvoiceFactory;
 | 
					use App\Factory\CloneQuoteToInvoiceFactory;
 | 
				
			||||||
use App\Factory\CloneQuoteToProjectFactory;
 | 
					use App\Factory\CloneQuoteToProjectFactory;
 | 
				
			||||||
use App\Http\Requests\Quote\EditQuoteRequest;
 | 
					use App\Http\Requests\Quote\EditQuoteRequest;
 | 
				
			||||||
@ -395,8 +397,8 @@ class QuoteController extends BaseController
 | 
				
			|||||||
        $quote = $this->quote_repo->save($request->all(), $quote);
 | 
					        $quote = $this->quote_repo->save($request->all(), $quote);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $quote->service()
 | 
					        $quote->service()
 | 
				
			||||||
              ->triggeredActions($request)
 | 
					              ->triggeredActions($request);
 | 
				
			||||||
              ->deletePdf();
 | 
					            //   ->deletePdf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -524,16 +526,15 @@ class QuoteController extends BaseController
 | 
				
			|||||||
            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
					            return response(['message' => 'Please verify your account to send emails.'], 400);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $quotes = Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
					        $quotes = Quote::query()->with('invitations')->withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $quotes) {
 | 
					        if (! $quotes) {
 | 
				
			||||||
            return response()->json(['message' => ctrans('texts.quote_not_found')]);
 | 
					            return response()->json(['message' => ctrans('texts.quote_not_found')]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Download Invoice/s
 | 
					         * Download Quote/s
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($action == 'bulk_download' && $quotes->count() >= 1) {
 | 
					        if ($action == 'bulk_download' && $quotes->count() >= 1) {
 | 
				
			||||||
            $quotes->each(function ($quote) use($user){
 | 
					            $quotes->each(function ($quote) use($user){
 | 
				
			||||||
                if ($user->cannot('view', $quote)) {
 | 
					                if ($user->cannot('view', $quote)) {
 | 
				
			||||||
@ -541,7 +542,7 @@ class QuoteController extends BaseController
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ZipQuotes::dispatch($quotes, $quotes->first()->company, auth()->user());
 | 
					            ZipQuotes::dispatch($quotes->pluck('id')->toArray(), $quotes->first()->company, auth()->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
					            return response()->json(['message' => ctrans('texts.sent_message')], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -556,12 +557,12 @@ class QuoteController extends BaseController
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
					            return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($action == 'bulk_print' && $user->can('view', $quotes->first())) {
 | 
					        if ($action == 'bulk_print' && $user->can('view', $quotes->first())) {
 | 
				
			||||||
            $paths = $quotes->map(function ($quote) {
 | 
					            $paths = $quotes->map(function ($quote) {
 | 
				
			||||||
                return $quote->service()->getQuotePdf();
 | 
					                return (new \App\Jobs\Entity\CreateRawPdf($quote->invitations->first(), $quote->company->db))->handle();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
					            $merge = (new PdfMerge($paths->toArray()))->run();
 | 
				
			||||||
@ -575,18 +576,13 @@ class QuoteController extends BaseController
 | 
				
			|||||||
        if ($action == 'convert_to_project') {
 | 
					        if ($action == 'convert_to_project') {
 | 
				
			||||||
            $quotes->each(function ($quote, $key) use ($user) {
 | 
					            $quotes->each(function ($quote, $key) use ($user) {
 | 
				
			||||||
                if ($user->can('edit', $quote)) {
 | 
					                if ($user->can('edit', $quote)) {
 | 
				
			||||||
                    $project = CloneQuoteToProjectFactory::create($quote, $user->id);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (empty($project->number)) {
 | 
					                    $quote->service()->convertToProject();
 | 
				
			||||||
                        $project->number = $this->getNextProjectNumber($project);
 | 
					
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    $project->save();
 | 
					 | 
				
			||||||
                    $quote->project_id = $project->id;
 | 
					 | 
				
			||||||
                    $quote->save();
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
					            return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
@ -684,7 +680,14 @@ class QuoteController extends BaseController
 | 
				
			|||||||
    private function performAction(Quote $quote, $action, $bulk = false)
 | 
					    private function performAction(Quote $quote, $action, $bulk = false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        switch ($action) {
 | 
					        switch ($action) {
 | 
				
			||||||
            case 'convert':
 | 
					            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':
 | 
					            case 'convert_to_invoice':
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $this->entity_type = Invoice::class;
 | 
					                $this->entity_type = Invoice::class;
 | 
				
			||||||
@ -692,8 +695,6 @@ class QuoteController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return $this->itemResponse($quote->service()->convertToInvoice());
 | 
					                return $this->itemResponse($quote->service()->convertToInvoice());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case 'clone_to_invoice':
 | 
					            case 'clone_to_invoice':
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $this->entity_type = Invoice::class;
 | 
					                $this->entity_type = Invoice::class;
 | 
				
			||||||
@ -702,41 +703,38 @@ class QuoteController extends BaseController
 | 
				
			|||||||
                $invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
 | 
					                $invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return $this->itemResponse($invoice);
 | 
					                return $this->itemResponse($invoice);
 | 
				
			||||||
                break;
 | 
					
 | 
				
			||||||
            case 'clone_to_quote':
 | 
					            case 'clone_to_quote':
 | 
				
			||||||
                $quote = CloneQuoteFactory::create($quote, auth()->user()->id);
 | 
					                $quote = CloneQuoteFactory::create($quote, auth()->user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return $this->itemResponse($quote);
 | 
					                return $this->itemResponse($quote);
 | 
				
			||||||
                break;
 | 
					
 | 
				
			||||||
            case 'approve':
 | 
					            case 'approve':
 | 
				
			||||||
                if (! in_array($quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
 | 
					                if (! in_array($quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
 | 
				
			||||||
                    return response()->json(['message' => ctrans('texts.quote_unapprovable')], 400);
 | 
					                    return response()->json(['message' => ctrans('texts.quote_unapprovable')], 400);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return $this->itemResponse($quote->service()->approveWithNoCoversion()->save());
 | 
					                return $this->itemResponse($quote->service()->approveWithNoCoversion()->save());
 | 
				
			||||||
                break;
 | 
					
 | 
				
			||||||
            case 'history':
 | 
					            case 'history':
 | 
				
			||||||
                // code...
 | 
					                // code...
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'download':
 | 
					            case 'download':
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                //$file = $quote->pdf_file_path();
 | 
					 | 
				
			||||||
                $file = $quote->service()->getQuotePdf();
 | 
					                $file = $quote->service()->getQuotePdf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return response()->streamDownload(function () use ($file) {
 | 
					                return response()->streamDownload(function () use ($file) {
 | 
				
			||||||
                    echo Storage::get($file);
 | 
					                    echo Storage::get($file);
 | 
				
			||||||
                }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
					                }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 'restore':
 | 
					            case 'restore':
 | 
				
			||||||
                $this->quote_repo->restore($quote);
 | 
					                $this->quote_repo->restore($quote);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (! $bulk) {
 | 
					                if (! $bulk) {
 | 
				
			||||||
                    return $this->itemResponse($quote);
 | 
					                    return $this->itemResponse($quote);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'archive':
 | 
					            case 'archive':
 | 
				
			||||||
                $this->quote_repo->archive($quote);
 | 
					                $this->quote_repo->archive($quote);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -754,16 +752,11 @@ class QuoteController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'email':
 | 
					            case 'email':
 | 
				
			||||||
                $quote->service()->sendEmail();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return response()->json(['message'=> ctrans('texts.sent_message')], 200);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case 'send_email':
 | 
					            case 'send_email':
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $quote->service()->sendEmail();
 | 
					                $quote->service()->sendEmail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return response()->json(['message'=> ctrans('texts.sent_message')], 200);
 | 
					                return response()->json(['message'=> ctrans('texts.sent_message')], 200);
 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'mark_sent':
 | 
					            case 'mark_sent':
 | 
				
			||||||
                $quote->service()->markSent()->save();
 | 
					                $quote->service()->markSent()->save();
 | 
				
			||||||
 | 
				
			|||||||
@ -153,7 +153,10 @@ class RecurringInvoiceController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function create(CreateRecurringInvoiceRequest $request)
 | 
					    public function create(CreateRecurringInvoiceRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $recurring_invoice = RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $recurring_invoice = RecurringInvoiceFactory::create($user->company()->id, $user->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($recurring_invoice);
 | 
					        return $this->itemResponse($recurring_invoice);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -199,7 +202,10 @@ class RecurringInvoiceController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store(StoreRecurringInvoiceRequest $request)
 | 
					    public function store(StoreRecurringInvoiceRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create($user->company()->id, $user->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->service()
 | 
					        $recurring_invoice->service()
 | 
				
			||||||
                          ->triggeredActions($request)
 | 
					                          ->triggeredActions($request)
 | 
				
			||||||
@ -380,7 +386,7 @@ class RecurringInvoiceController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice->service()
 | 
					        $recurring_invoice->service()
 | 
				
			||||||
                          ->triggeredActions($request)
 | 
					                          ->triggeredActions($request)
 | 
				
			||||||
                          ->deletePdf()
 | 
					                        //   ->deletePdf()
 | 
				
			||||||
                          ->save();
 | 
					                          ->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
@ -405,18 +411,21 @@ class RecurringInvoiceController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function bulk(BulkRecurringInvoiceRequest $request)
 | 
					    public function bulk(BulkRecurringInvoiceRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0;
 | 
					        $percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array($request->action, ['increase_prices', 'update_prices'])) {
 | 
					        if (in_array($request->action, ['increase_prices', 'update_prices'])) {
 | 
				
			||||||
            UpdateRecurring::dispatch($request->ids, auth()->user()->company(), auth()->user(), $request->action, $percentage_increase);
 | 
					            UpdateRecurring::dispatch($request->ids, $user->company(), $user, $request->action, $percentage_increase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'Update in progress.'], 200);
 | 
					            return response()->json(['message' => 'Update in progress.'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
 | 
					        $recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoices->each(function ($recurring_invoice, $key) use ($request) {
 | 
					        $recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) {
 | 
				
			||||||
            if (auth()->user()->can('edit', $recurring_invoice)) {
 | 
					            if ($user->can('edit', $recurring_invoice)) {
 | 
				
			||||||
                $this->performAction($recurring_invoice, $request->action, true);
 | 
					                $this->performAction($recurring_invoice, $request->action, true);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Reports;
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
use App\Export\CSV\DocumentExport;
 | 
					use App\Export\CSV\DocumentExport;
 | 
				
			||||||
 | 
					use App\Jobs\Report\PreviewReport;
 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
use App\Http\Requests\Report\GenericReportRequest;
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
use App\Jobs\Report\SendToAdmin;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DocumentReportController extends BaseController
 | 
					class DocumentReportController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -62,14 +63,27 @@ class DocumentReportController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __invoke(GenericReportRequest $request)
 | 
					    public function __invoke(GenericReportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('send_email') && $request->get('send_email')) {
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), DocumentExport::class, $this->filename);
 | 
					            SendToAdmin::dispatch($user->company(), $request->all(), DocumentExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'working...'], 200);
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // expect a list of visible fields, or use the default
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $export = new DocumentExport(auth()->user()->company(), $request->all());
 | 
					        if($request->has('output') && $request->input('output') == 'json') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash = \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            PreviewReport::dispatch($user->company(), $request->all(), DocumentExport::class, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new DocumentExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,6 @@ class InvoiceItemReportController extends BaseController
 | 
				
			|||||||
            return response()->json(['message' => $hash], 200);
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        $export = new InvoiceItemExport($user->company(), $request->all());
 | 
					        $export = new InvoiceItemExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Reports;
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
 | 
					use App\Jobs\Report\PreviewReport;
 | 
				
			||||||
use App\Export\CSV\QuoteItemExport;
 | 
					use App\Export\CSV\QuoteItemExport;
 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
use App\Http\Requests\Report\GenericReportRequest;
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
use App\Jobs\Report\SendToAdmin;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class QuoteItemReportController extends BaseController
 | 
					class QuoteItemReportController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -62,14 +63,26 @@ class QuoteItemReportController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __invoke(GenericReportRequest $request)
 | 
					    public function __invoke(GenericReportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('send_email') && $request->get('send_email')) {
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), QuoteItemExport::class, $this->filename);
 | 
					            SendToAdmin::dispatch($user->company(), $request->all(), QuoteItemExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'working...'], 200);
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // expect a list of visible fields, or use the default
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $export = new QuoteItemExport(auth()->user()->company(), $request->all());
 | 
					        if($request->has('output') && $request->input('output') == 'json') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash = \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            PreviewReport::dispatch($user->company(), $request->all(), QuoteItemExport::class, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new QuoteItemExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Reports;
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Export\CSV\RecurringInvoiceExport;
 | 
					 | 
				
			||||||
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;
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
 | 
					use App\Jobs\Report\PreviewReport;
 | 
				
			||||||
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
 | 
					use App\Export\CSV\RecurringInvoiceExport;
 | 
				
			||||||
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RecurringInvoiceReportController extends BaseController
 | 
					class RecurringInvoiceReportController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -31,14 +32,26 @@ class RecurringInvoiceReportController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function __invoke(GenericReportRequest $request)
 | 
					    public function __invoke(GenericReportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('send_email') && $request->get('send_email')) {
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), RecurringInvoiceExport::class, $this->filename);
 | 
					            SendToAdmin::dispatch($user->company(), $request->all(), RecurringInvoiceExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'working...'], 200);
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // expect a list of visible fields, or use the default
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $export = new RecurringInvoiceExport(auth()->user()->company(), $request->all());
 | 
					        if($request->has('output') && $request->input('output') == 'json') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash = \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            PreviewReport::dispatch($user->company(), $request->all(), RecurringInvoiceExport::class, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new RecurringInvoiceExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Reports;
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use App\Export\CSV\TaskExport;
 | 
					use App\Export\CSV\TaskExport;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
 | 
					use App\Jobs\Report\PreviewReport;
 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
use App\Http\Requests\Report\GenericReportRequest;
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
use App\Jobs\Report\SendToAdmin;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TaskReportController extends BaseController
 | 
					class TaskReportController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -62,14 +63,26 @@ class TaskReportController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function __invoke(GenericReportRequest $request)
 | 
					    public function __invoke(GenericReportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('send_email') && $request->get('send_email')) {
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), TaskExport::class, $this->filename);
 | 
					            SendToAdmin::dispatch($user->company(), $request->all(), TaskExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'working...'], 200);
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // expect a list of visible fields, or use the default
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $export = new TaskExport(auth()->user()->company(), $request->all());
 | 
					        if($request->has('output') && $request->input('output') == 'json') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash = \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            PreviewReport::dispatch($user->company(), $request->all(), TaskExport::class, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new TaskExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,11 +11,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Reports;
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Export\CSV\VendorExport;
 | 
					use App\Export\CSV\VendorExport;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
 | 
					use App\Jobs\Report\PreviewReport;
 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
use App\Http\Requests\Report\GenericReportRequest;
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
use App\Jobs\Report\SendToAdmin;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VendorReportController extends BaseController
 | 
					class VendorReportController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -30,14 +31,26 @@ class VendorReportController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function __invoke(GenericReportRequest $request)
 | 
					    public function __invoke(GenericReportRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->has('send_email') && $request->get('send_email')) {
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), VendorExport::class, $this->filename);
 | 
					            SendToAdmin::dispatch($user->company(), $request->all(), VendorExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'working...'], 200);
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // expect a list of visible fields, or use the default
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $export = new VendorExport(auth()->user()->company(), $request->all());
 | 
					        if($request->has('output') && $request->input('output') == 'json') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $hash = \Illuminate\Support\Str::uuid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            PreviewReport::dispatch($user->company(), $request->all(), VendorExport::class, $hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => $hash], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new VendorExport($user->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $csv = $export->run();
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,85 +11,102 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\User;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\ClientContact;
 | 
					 | 
				
			||||||
use App\Http\Requests\Search\GenericSearchRequest;
 | 
					use App\Http\Requests\Search\GenericSearchRequest;
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SearchController extends Controller
 | 
					class SearchController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    private array $clients = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private array $client_contacts = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private array $invoices = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __invoke(GenericSearchRequest $request)
 | 
					    public function __invoke(GenericSearchRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->clientMap($user);
 | 
				
			||||||
 | 
					        $this->invoiceMap($user);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return response()->json([
 | 
					        return response()->json([
 | 
				
			||||||
            'clients' => $this->clientMap($user),
 | 
					            'clients' => $this->clients,
 | 
				
			||||||
            'client_contacts' => $this->clientContactMap($user),
 | 
					            'client_contacts' => $this->client_contacts,
 | 
				
			||||||
            'invoices' => $this->invoiceMap($user),
 | 
					            'invoices' => $this->invoices,
 | 
				
			||||||
            'settings' => $this->settingsMap(),
 | 
					            'settings' => $this->settingsMap(),
 | 
				
			||||||
        ], 200);
 | 
					        ], 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function clientMap(User $user) {
 | 
					    private function clientMap(User $user)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Client::query()
 | 
					        $clients =  Client::query()
 | 
				
			||||||
                     ->company()
 | 
					                     ->company()
 | 
				
			||||||
                     ->when($user->cannot('view_all') || $user->cannot('view_client'), function ($query) use($user) {
 | 
					                     ->where('is_deleted', 0)
 | 
				
			||||||
 | 
					                     ->when(!$user->hasPermission('view_all') || !$user->hasPermission('view_client'), function ($query) use ($user) {
 | 
				
			||||||
                         $query->where('user_id', $user->id);
 | 
					                         $query->where('user_id', $user->id);
 | 
				
			||||||
                     })
 | 
					                     })
 | 
				
			||||||
                     ->cursor()
 | 
					                     ->orderBy('id', 'desc')
 | 
				
			||||||
                     ->map(function ($client){
 | 
					                     ->take(1000)
 | 
				
			||||||
                        return [
 | 
					                     ->get();
 | 
				
			||||||
                            'name' => $client->present()->name(), 
 | 
					
 | 
				
			||||||
                            'type' => '/client', 
 | 
					                        foreach($clients as $client) {
 | 
				
			||||||
                            'id' => $client->hashed_id,
 | 
					                            $this->clients[] = [
 | 
				
			||||||
                            'path' => "/clients/{$client->hashed_id}/edit"
 | 
					                                'name' => $client->present()->name(),
 | 
				
			||||||
                        ];
 | 
					                                'type' => '/client',
 | 
				
			||||||
                     });
 | 
					                                'id' => $client->hashed_id,
 | 
				
			||||||
 | 
					                                'path' => "/clients/{$client->hashed_id}/edit"
 | 
				
			||||||
 | 
					                            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            $client->contacts->each(function ($contact) {
 | 
				
			||||||
 | 
					                                $this->client_contacts[] = [
 | 
				
			||||||
 | 
					                                    'name' => $contact->present()->search_display(),
 | 
				
			||||||
 | 
					                                    'type' => '/client_contact',
 | 
				
			||||||
 | 
					                                    'id' => $contact->hashed_id,
 | 
				
			||||||
 | 
					                                    'path' => "/clients/{$contact->hashed_id}"
 | 
				
			||||||
 | 
					                                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                                
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                         
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function clientContactMap(User $user) {
 | 
					    private function invoiceMap(User $user)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return ClientContact::query()
 | 
					        $invoices = Invoice::query()
 | 
				
			||||||
                     ->company()
 | 
					                     ->company()
 | 
				
			||||||
                     ->with('client')
 | 
					                     ->with('client')
 | 
				
			||||||
                     ->when($user->cannot('view_all') || $user->cannot('view_client'), function ($query) use($user) {
 | 
					                     ->where('is_deleted', 0)
 | 
				
			||||||
 | 
					                     ->whereHas('client', function ($q) {
 | 
				
			||||||
 | 
					                         $q->where('is_deleted', 0);
 | 
				
			||||||
 | 
					                     })
 | 
				
			||||||
 | 
					                     ->when(!$user->hasPermission('view_all') || !$user->hasPermission('view_invoice'), function ($query) use ($user) {
 | 
				
			||||||
                         $query->where('user_id', $user->id);
 | 
					                         $query->where('user_id', $user->id);
 | 
				
			||||||
                     })
 | 
					                     })
 | 
				
			||||||
                     ->cursor()
 | 
					                     ->orderBy('id', 'desc')
 | 
				
			||||||
                     ->map(function ($contact){
 | 
					                    ->take(3000)
 | 
				
			||||||
                        return [
 | 
					                    ->get(); 
 | 
				
			||||||
                            'name' => $contact->present()->search_display(), 
 | 
					                    
 | 
				
			||||||
                            'type' => '/client_contact', 
 | 
					                    foreach($invoices as $invoice) {
 | 
				
			||||||
                            'id' => $contact->client->hashed_id,
 | 
					                            $this->invoices[] = [
 | 
				
			||||||
                            'path' => "/clients/{$contact->client->hashed_id}"
 | 
					                                'name' => $invoice->client->present()->name() . ' - ' . $invoice->number,
 | 
				
			||||||
                        ];
 | 
					                                'type' => '/invoice',
 | 
				
			||||||
                     });
 | 
					                                'id' => $invoice->hashed_id,
 | 
				
			||||||
 | 
					                                'path' => "/clients/{$invoice->hashed_id}/edit"
 | 
				
			||||||
 | 
					                            ];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function invoiceMap(User $user) {
 | 
					    private function settingsMap()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        return Invoice::query()
 | 
					 | 
				
			||||||
                     ->company()
 | 
					 | 
				
			||||||
                     ->with('client')
 | 
					 | 
				
			||||||
                     ->when($user->cannot('view_all') || $user->cannot('view_invoice'), function ($query) use($user) {
 | 
					 | 
				
			||||||
                         $query->where('user_id', $user->id);
 | 
					 | 
				
			||||||
                     })
 | 
					 | 
				
			||||||
                     ->cursor()
 | 
					 | 
				
			||||||
                     ->map(function ($invoice){
 | 
					 | 
				
			||||||
                        return [
 | 
					 | 
				
			||||||
                            'name' => $invoice->client->present()->name() . ' - ' . $invoice->number, 
 | 
					 | 
				
			||||||
                            'type' => '/invoice', 
 | 
					 | 
				
			||||||
                            'id' => $invoice->hashed_id,
 | 
					 | 
				
			||||||
                            'path' => "/clients/{$invoice->hashed_id}/edit"
 | 
					 | 
				
			||||||
                        ];
 | 
					 | 
				
			||||||
                     });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private function settingsMap() {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $paths = [
 | 
					        $paths = [
 | 
				
			||||||
            'user_details' => '/settings/user_details',
 | 
					            'user_details' => '/settings/user_details',
 | 
				
			||||||
 | 
				
			|||||||
@ -11,13 +11,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Exceptions\FilePermissionsFailure;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Utils\Traits\AppSetup;
 | 
					use App\Utils\Traits\AppSetup;
 | 
				
			||||||
use App\Utils\Traits\ClientGroupSettingsSaver;
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Artisan;
 | 
					use Illuminate\Support\Facades\Artisan;
 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use App\Exceptions\FilePermissionsFailure;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Bus\DispatchesJobs;
 | 
				
			||||||
 | 
					use App\Utils\Traits\ClientGroupSettingsSaver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelfUpdateController extends BaseController
 | 
					class SelfUpdateController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -109,11 +110,33 @@ class SelfUpdateController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->buildCache(true);
 | 
					        $this->buildCache(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->runModelChecks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        nlog('Called Artisan commands');
 | 
					        nlog('Called Artisan commands');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['message' => 'Update completed'], 200);
 | 
					        return response()->json(['message' => 'Update completed'], 200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function runModelChecks()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Company::query()
 | 
				
			||||||
 | 
					               ->cursor()
 | 
				
			||||||
 | 
					               ->each(function ($company){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $settings = $company->settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(property_exists($settings->pdf_variables, 'purchase_order_details'))
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $pdf_variables = $settings->pdf_variables;
 | 
				
			||||||
 | 
					                    $pdf_variables->purchase_order_details = [];
 | 
				
			||||||
 | 
					                    $settings->pdf_variables = $pdf_variables;
 | 
				
			||||||
 | 
					                    $company->settings = $settings;
 | 
				
			||||||
 | 
					                    $company->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					               });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function clearCacheDir()
 | 
					    private function clearCacheDir()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $directoryIterator = new \RecursiveDirectoryIterator(base_path('bootstrap/cache'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
					        $directoryIterator = new \RecursiveDirectoryIterator(base_path('bootstrap/cache'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
				
			||||||
 | 
				
			|||||||
@ -15,11 +15,9 @@ use App\DataMapper\FeesAndLimits;
 | 
				
			|||||||
use App\Factory\CompanyGatewayFactory;
 | 
					use App\Factory\CompanyGatewayFactory;
 | 
				
			||||||
use App\Http\Requests\StripeConnect\InitializeStripeConnectRequest;
 | 
					use App\Http\Requests\StripeConnect\InitializeStripeConnectRequest;
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					use App\Models\CompanyGateway;
 | 
				
			||||||
use App\Models\GatewayType;
 | 
					use App\Models\GatewayType;
 | 
				
			||||||
use App\PaymentDrivers\Stripe\Jobs\StripeWebhook;
 | 
					 | 
				
			||||||
use Stripe\Exception\ApiErrorException;
 | 
					use Stripe\Exception\ApiErrorException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StripeConnectController extends BaseController
 | 
					class StripeConnectController extends BaseController
 | 
				
			||||||
@ -124,12 +122,27 @@ class StripeConnectController extends BaseController
 | 
				
			|||||||
        $company_gateway->setConfig($payload);
 | 
					        $company_gateway->setConfig($payload);
 | 
				
			||||||
        $company_gateway->save();
 | 
					        $company_gateway->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					            $stripe = $company_gateway->driver()->init();
 | 
				
			||||||
 | 
					            $a = \Stripe\Account::retrieve($response->stripe_user_id, $stripe->stripe_connect_auth);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if($a->business_name ?? false) {
 | 
				
			||||||
 | 
					                $company_gateway->label = substr("Stripe - {$a->business_name}", 0, 250);
 | 
				
			||||||
 | 
					                $company_gateway->save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch(\Exception $e){
 | 
				
			||||||
 | 
					            nlog("could not harvest stripe company name");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // nlog("Stripe Connect Redirect URI = {$redirect_uri}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // StripeWebhook::dispatch($company->company_key, $company_gateway->id);
 | 
					        // StripeWebhook::dispatch($company->company_key, $company_gateway->id);
 | 
				
			||||||
        // if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
 | 
					        if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
 | 
				
			||||||
            $redirect_uri = 'https://app.invoicing.co/#/settings/online_payments';
 | 
					            $redirect_uri = 'https://app.invoicing.co/#/settings/online_payments';
 | 
				
			||||||
        // } else {
 | 
					        } else {
 | 
				
			||||||
        //     $redirect_uri = 'https://invoicing.co/stripe/completed';
 | 
					            $redirect_uri = 'https://invoicing.co/stripe/completed';
 | 
				
			||||||
        // }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //response here
 | 
					        //response here
 | 
				
			||||||
        return view('auth.connect.completed', ['url' => $redirect_uri]);
 | 
					        return view('auth.connect.completed', ['url' => $redirect_uri]);
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,6 @@ use App\Jobs\Invoice\InjectSignature;
 | 
				
			|||||||
use Illuminate\Support\Facades\Cache;
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
use Illuminate\Contracts\View\Factory;
 | 
					use Illuminate\Contracts\View\Factory;
 | 
				
			||||||
use App\Models\PurchaseOrderInvitation;
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					 | 
				
			||||||
use App\Events\Misc\InvitationWasViewed;
 | 
					use App\Events\Misc\InvitationWasViewed;
 | 
				
			||||||
use App\Jobs\Vendor\CreatePurchaseOrderPdf;
 | 
					use App\Jobs\Vendor\CreatePurchaseOrderPdf;
 | 
				
			||||||
use App\Events\PurchaseOrder\PurchaseOrderWasViewed;
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasViewed;
 | 
				
			||||||
@ -119,14 +118,8 @@ class PurchaseOrderController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf();
 | 
					        $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // $headers = ['Content-Type' => 'application/pdf'];
 | 
					 | 
				
			||||||
        // $entity_string = $data['entity_type'];
 | 
					 | 
				
			||||||
        // $file_name = $invitation->{$entity_string}->numberFormatter().'.pdf';
 | 
					 | 
				
			||||||
        // return response()->streamDownload(function () use ($file) {
 | 
					 | 
				
			||||||
        //     echo $file;
 | 
					 | 
				
			||||||
        // }, $file_name, $headers);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $headers = ['Content-Type' => 'application/pdf'];
 | 
					        $headers = ['Content-Type' => 'application/pdf'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->make($file, 200, $headers);
 | 
					        return response()->make($file, 200, $headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -156,7 +149,7 @@ class PurchaseOrderController extends Controller
 | 
				
			|||||||
        $transformed_ids = $this->transformKeys($request->purchase_orders);
 | 
					        $transformed_ids = $this->transformKeys($request->purchase_orders);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->input('action') == 'download') {
 | 
					        if ($request->input('action') == 'download') {
 | 
				
			||||||
            return $this->downloadInvoices((array) $transformed_ids);
 | 
					            return $this->downloadPurchaseOrders((array) $transformed_ids);
 | 
				
			||||||
        } elseif ($request->input('action') == 'accept') {
 | 
					        } elseif ($request->input('action') == 'accept') {
 | 
				
			||||||
            return $this->acceptPurchaseOrder($request->all());
 | 
					            return $this->acceptPurchaseOrder($request->all());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -177,7 +170,8 @@ class PurchaseOrderController extends Controller
 | 
				
			|||||||
        $purchase_count_query = clone $purchase_orders;
 | 
					        $purchase_count_query = clone $purchase_orders;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $purchase_orders->whereIn('status_id', [PurchaseOrder::STATUS_DRAFT, PurchaseOrder::STATUS_SENT])
 | 
					        $purchase_orders->whereIn('status_id', [PurchaseOrder::STATUS_DRAFT, PurchaseOrder::STATUS_SENT])
 | 
				
			||||||
                        ->cursor()->each(function ($purchase_order) {
 | 
					                        ->cursor()
 | 
				
			||||||
 | 
					                        ->each(function ($purchase_order) {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
                            $purchase_order->service()
 | 
					                            $purchase_order->service()
 | 
				
			||||||
                                        ->markSent()
 | 
					                                        ->markSent()
 | 
				
			||||||
@ -201,39 +195,39 @@ class PurchaseOrderController extends Controller
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function downloadInvoices($ids)
 | 
					    public function downloadPurchaseOrders($ids)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $purchase_orders = PurchaseOrder::query()
 | 
					        $purchase_order_invitations = PurchaseOrderInvitation::query()
 | 
				
			||||||
                            ->whereIn('id', $ids)
 | 
					                            ->with('purchase_order', 'company')
 | 
				
			||||||
                            ->where('vendor_id', auth()->guard('vendor')->user()->vendor_id)
 | 
					                            ->whereIn('purchase_order_id', $ids)
 | 
				
			||||||
 | 
					                            ->where('vendor_contact_id', auth()->guard('vendor')->user()->id)
 | 
				
			||||||
                            ->withTrashed()
 | 
					                            ->withTrashed()
 | 
				
			||||||
                            ->get();
 | 
					                            ->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($purchase_orders) == 0) {
 | 
					        if (count($purchase_order_invitations) == 0) {
 | 
				
			||||||
            return back()->with(['message' => ctrans('texts.no_items_selected')]);
 | 
					            return back()->with(['message' => ctrans('texts.no_items_selected')]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($purchase_orders) == 1) {
 | 
					        if (count($purchase_order_invitations) == 1) {
 | 
				
			||||||
            $purchase_order = $purchase_orders->first();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $file = $purchase_order->service()->getPurchaseOrderPdf(auth()->guard('vendor')->user());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $invitation = $purchase_order_invitations->first();
 | 
				
			||||||
 | 
					            $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf();
 | 
				
			||||||
            return response()->streamDownload(function () use ($file) {
 | 
					            return response()->streamDownload(function () use ($file) {
 | 
				
			||||||
                echo Storage::get($file);
 | 
					                echo $file;
 | 
				
			||||||
            }, basename($file), ['Content-Type' => 'application/pdf']);
 | 
					            }, $invitation->purchase_order->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->buildZip($purchase_orders);
 | 
					        return $this->buildZip($purchase_order_invitations);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function buildZip($purchase_orders)
 | 
					    private function buildZip($invitations)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // create new archive
 | 
					        // create new archive
 | 
				
			||||||
        $zipFile = new \PhpZip\ZipFile();
 | 
					        $zipFile = new \PhpZip\ZipFile();
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            foreach ($purchase_orders as $purchase_order) {
 | 
					            foreach ($invitations as $invitation) {
 | 
				
			||||||
                //add it to the zip
 | 
					                $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf();
 | 
				
			||||||
                $zipFile->addFromString(basename($purchase_order->pdf_file_path()), file_get_contents($purchase_order->pdf_file_path(null, 'url', true)));
 | 
					                $zipFile->addFromString($invitation->purchase_order->numberFormatter().".pdf", $file);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip';
 | 
					            $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip';
 | 
				
			||||||
 | 
				
			|||||||
@ -195,15 +195,15 @@ class PdfSlot extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elseif($this->entity_type == 'quote'){
 | 
					        elseif($this->entity_type == 'quote'){
 | 
				
			||||||
            foreach($this->settings->pdf_variables->quote_details as $variable)
 | 
					            foreach($this->settings->pdf_variables->quote_details ?? [] as $variable)
 | 
				
			||||||
                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
					                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elseif($this->entity_type == 'credit') {
 | 
					        elseif($this->entity_type == 'credit') {
 | 
				
			||||||
            foreach($this->settings->pdf_variables->credit_details as $variable)
 | 
					            foreach($this->settings->pdf_variables->credit_details ?? [] as $variable)
 | 
				
			||||||
                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
					                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elseif($this->entity_type == 'purchase_order'){
 | 
					        elseif($this->entity_type == 'purchase_order'){
 | 
				
			||||||
            foreach($this->settings->pdf_variables->purchase_order_details as $variable)
 | 
					            foreach($this->settings->pdf_variables->purchase_order_details ?? [] as $variable)
 | 
				
			||||||
                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
					                $entity_details .= "<div class='flex px-5 block'><p class= w-36 block'>{$variable}_label</p><p class='pl-5 w-36 block entity-field'>{$variable}</p></div>";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,10 @@ class BulkBankTransactionRuleRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->isAdmin();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,7 @@ class StoreClientRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $rules['number'] = ['bail', 'nullable', Rule::unique('clients')->where('company_id', $user->company()->id)];
 | 
					        $rules['number'] = ['bail', 'nullable', Rule::unique('clients')->where('company_id', $user->company()->id)];
 | 
				
			||||||
        $rules['id_number'] = ['bail', 'nullable', Rule::unique('clients')->where('company_id', $user->company()->id)];
 | 
					        $rules['id_number'] = ['bail', 'nullable', Rule::unique('clients')->where('company_id', $user->company()->id)];
 | 
				
			||||||
 | 
					        $rules['classification'] = 'bail|sometimes|nullable|in:individual,company,partnership,trust,charity,government,other';
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $rules;
 | 
					        return $rules;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ class UpdateClientRequest extends Request
 | 
				
			|||||||
        $rules['size_id'] = 'integer|nullable';
 | 
					        $rules['size_id'] = 'integer|nullable';
 | 
				
			||||||
        $rules['country_id'] = 'integer|nullable';
 | 
					        $rules['country_id'] = 'integer|nullable';
 | 
				
			||||||
        $rules['shipping_country_id'] = 'integer|nullable';
 | 
					        $rules['shipping_country_id'] = 'integer|nullable';
 | 
				
			||||||
 | 
					        $rules['classification'] = 'bail|sometimes|nullable|in:individual,company,partnership,trust,charity,government,other';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->id_number) {
 | 
					        if ($this->id_number) {
 | 
				
			||||||
            $rules['id_number'] = Rule::unique('clients')->where('company_id', $user->company()->id)->ignore($this->client->id);
 | 
					            $rules['id_number'] = Rule::unique('clients')->where('company_id', $user->company()->id)->ignore($this->client->id);
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,10 @@ class UpdateCompanyUserRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->isAdmin() || (auth()->user()->id == $this->user->id);
 | 
					        /** @var \App\Models\User $auth_user */
 | 
				
			||||||
 | 
					        $auth_user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $auth_user->isAdmin() || ($auth_user->id == $this->user->id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
 | 
				
			|||||||
@ -24,16 +24,19 @@ class UpdateGroupSettingRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->can('edit', $this->group_setting);
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->can('edit', $this->group_setting);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $rules['settings'] = new ValidClientGroupSettingsRule();
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
//        $rules['name'] = 'unique:group_settings,name,'.$this->id.',id,company_id,'.$this->group_setting->company_id;
 | 
					        return [
 | 
				
			||||||
 | 
					            'settings' => [new ValidClientGroupSettingsRule()],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $rules;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					    public function prepareForValidation()
 | 
				
			||||||
 | 
				
			|||||||
@ -30,18 +30,25 @@ class UpdatePaymentRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->can('edit', $this->payment);
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->can('edit', $this->payment);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules = [
 | 
					        $rules = [
 | 
				
			||||||
            'invoices' => ['array', new PaymentAppliedValidAmount($this->all()), new ValidCreditsPresentRule($this->all())],
 | 
					            'invoices' => ['array', new PaymentAppliedValidAmount($this->all()), new ValidCreditsPresentRule($this->all())],
 | 
				
			||||||
            'invoices.*.invoice_id' => 'distinct',
 | 
					            'invoices.*.invoice_id' => 'distinct',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->number) {
 | 
					        if ($this->number) {
 | 
				
			||||||
            $rules['number'] = Rule::unique('payments')->where('company_id', auth()->user()->company()->id)->ignore($this->payment->id);
 | 
					            $rules['number'] = Rule::unique('payments')->where('company_id', $user->company()->id)->ignore($this->payment->id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->file('documents') && is_array($this->file('documents'))) {
 | 
					        if ($this->file('documents') && is_array($this->file('documents'))) {
 | 
				
			||||||
@ -75,7 +82,8 @@ class UpdatePaymentRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (isset($input['invoices']) && is_array($input['invoices']) !== false) {
 | 
					        if (isset($input['invoices']) && is_array($input['invoices']) !== false) {
 | 
				
			||||||
            foreach ($input['invoices'] as $key => $value) {
 | 
					            foreach ($input['invoices'] as $key => $value) {
 | 
				
			||||||
                if (array_key_exists('invoice_id', $input['invoices'][$key])) {
 | 
					                if(isset($input['invoices'][$key]['invoice_id'])){
 | 
				
			||||||
 | 
					                // if (array_key_exists('invoice_id', $input['invoices'][$key])) {
 | 
				
			||||||
                    $input['invoices'][$key]['invoice_id'] = $this->decodePrimaryKey($value['invoice_id']);
 | 
					                    $input['invoices'][$key]['invoice_id'] = $this->decodePrimaryKey($value['invoice_id']);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -83,7 +91,8 @@ class UpdatePaymentRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (isset($input['credits']) && is_array($input['credits']) !== false) {
 | 
					        if (isset($input['credits']) && is_array($input['credits']) !== false) {
 | 
				
			||||||
            foreach ($input['credits'] as $key => $value) {
 | 
					            foreach ($input['credits'] as $key => $value) {
 | 
				
			||||||
                if (array_key_exists('credits', $input['credits'][$key])) {
 | 
					                // if (array_key_exists('credits', $input['credits'][$key])) {
 | 
				
			||||||
 | 
					                if (isset($input['credits'][$key]['credit_id'])) {
 | 
				
			||||||
                    $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']);
 | 
					                    $input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -30,9 +30,11 @@ class BulkActionQuoteRequest extends Request
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules = [];
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'action' => 'sometimes|in:convert_to_invoice,convert_to_project,email,bulk_download,bulk_print,clone_to_invoice,approve,download,restore,archive,delete,send_email,mark_sent',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($input['action'] == 'convert_to_invoice') {
 | 
					        if (in_array($input['action'], ['convert,convert_to_invoice']) ) {
 | 
				
			||||||
            $rules['action'] = [new ConvertableQuoteRule()];
 | 
					            $rules['action'] = [new ConvertableQuoteRule()];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -75,6 +75,9 @@ class UpdateRecurringExpenseRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					    public function prepareForValidation()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user*/
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $input = $this->decodePrimaryKeys($input);
 | 
					        $input = $this->decodePrimaryKeys($input);
 | 
				
			||||||
@ -88,7 +91,7 @@ class UpdateRecurringExpenseRequest extends Request
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
 | 
					        if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
 | 
				
			||||||
            $input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
 | 
					            $input['currency_id'] = (string) $user->company()->settings->currency_id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->replace($input);
 | 
					        $this->replace($input);
 | 
				
			||||||
 | 
				
			|||||||
@ -28,23 +28,30 @@ class StoreTaskRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->can('create', Task::class);
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->can('create', Task::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules = [];
 | 
					        $rules = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isset($this->number)) {
 | 
					        if (isset($this->number)) {
 | 
				
			||||||
            $rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id);
 | 
					            $rules['number'] = Rule::unique('tasks')->where('company_id', $user->company()->id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isset($this->client_id)) {
 | 
					        if (isset($this->client_id)) {
 | 
				
			||||||
            $rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
					            $rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.$user->company()->id.',is_deleted,0';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isset($this->project_id)) {
 | 
					        if (isset($this->project_id)) {
 | 
				
			||||||
            $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
					            $rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) {
 | 
					        $rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) {
 | 
				
			||||||
@ -77,7 +84,7 @@ class StoreTaskRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					    public function prepareForValidation()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $input = $this->all();
 | 
					
 | 
				
			||||||
        $input = $this->decodePrimaryKeys($this->all());
 | 
					        $input = $this->decodePrimaryKeys($this->all());
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (array_key_exists('status_id', $input) && is_string($input['status_id'])) {
 | 
					        if (array_key_exists('status_id', $input) && is_string($input['status_id'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -22,14 +22,20 @@ class StoreTaxRateRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->isAdmin();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            //'name' => 'required',
 | 
					            'name' => 'required|unique:tax_rates,name,null,null,company_id,'.$user->companyId().',deleted_at,NULL',
 | 
				
			||||||
            'name' => 'required|unique:tax_rates,name,null,null,company_id,'.auth()->user()->companyId().',deleted_at,NULL',
 | 
					 | 
				
			||||||
            'rate' => 'required|numeric',
 | 
					            'rate' => 'required|numeric',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -23,17 +23,25 @@ class UpdateTaxRateRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function authorize() : bool
 | 
					    public function authorize() : bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $user->isAdmin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules = [];
 | 
					        $rules = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules['rate'] = 'numeric';
 | 
					        $rules['rate'] = 'sometimes|numeric';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->number) {
 | 
					        if ($this->name) {
 | 
				
			||||||
            $rules['number'] = Rule::unique('tax_rates')->where('company_id', auth()->user()->company()->id)->ignore($this->tax_rate->id);
 | 
					            $rules['name'] = Rule::unique('tax_rates')->where('company_id', $user->company()->id)->ignore($this->tax_rate->id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $rules;
 | 
					        return $rules;
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ class StoreVendorRequest extends Request
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
 | 
					        $rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
 | 
				
			||||||
 | 
					        $rules['classification'] = 'bail|sometimes|nullable|in:individual,company,partnership,trust,charity,government,other';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $rules;
 | 
					        return $rules;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,7 @@ class UpdateVendorRequest extends Request
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
 | 
					        $rules['language_id'] = 'bail|nullable|sometimes|exists:languages,id';
 | 
				
			||||||
 | 
					        $rules['classification'] = 'bail|sometimes|nullable|in:individual,company,partnership,trust,charity,government,other';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $rules;
 | 
					        return $rules;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -90,6 +90,12 @@ class PaymentAppliedValidAmount implements Rule
 | 
				
			|||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(count($this->input['invoices']) >=1 && $payment->status_id == Payment::STATUS_PENDING){
 | 
				
			||||||
 | 
					                $this->message = 'Cannot apply a payment until the status is completed.';
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (round($payment_amounts, 3) >= round($invoice_amounts, 3)) {
 | 
					        if (round($payment_amounts, 3) >= round($invoice_amounts, 3)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ use App\Jobs\Util\UnlinkFile;
 | 
				
			|||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Mail\DownloadCredits;
 | 
					use App\Mail\DownloadCredits;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\CreditInvitation;
 | 
				
			||||||
use App\Models\User;
 | 
					use App\Models\User;
 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
@ -30,32 +31,12 @@ class ZipCredits implements ShouldQueue
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $credits;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public $settings;
 | 
					    public $settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $tries = 1;
 | 
					    public $tries = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function __construct(protected array $credit_ids, protected Company $company, protected User $user)
 | 
				
			||||||
     * @param $invoices
 | 
					 | 
				
			||||||
     * @param Company $company
 | 
					 | 
				
			||||||
     * @param $email
 | 
					 | 
				
			||||||
     * @deprecated confirm to be deleted
 | 
					 | 
				
			||||||
     * Create a new job instance.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function __construct($credits, Company $company, User $user)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->credits = $credits;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->company = $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->user = $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->settings = $company->settings;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -67,21 +48,18 @@ class ZipCredits implements ShouldQueue
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // create new zip object
 | 
					        $this->settings = $this->company->settings;
 | 
				
			||||||
        $zipFile = new \PhpZip\ZipFile();
 | 
					        $zipFile = new \PhpZip\ZipFile();
 | 
				
			||||||
        $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.credits')).'.zip';
 | 
					        $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.credits')).'.zip';
 | 
				
			||||||
        $invitation = $this->credits->first()->invitations->first();
 | 
					 | 
				
			||||||
        $path = $this->credits->first()->client->quote_filepath($invitation);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->credits->each(function ($credit) {
 | 
					        $invitations = CreditInvitation::query()->with('credit')->whereIn('credit_id', $this->credit_ids)->get();
 | 
				
			||||||
            (new CreateEntityPdf($credit->invitations()->first()))->handle();
 | 
					        $invitation = $invitations->first();
 | 
				
			||||||
        });
 | 
					        $path = $invitation->contact->client->credit_filepath($invitation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            foreach ($this->credits as $credit) {
 | 
					            foreach ($invitations as $invitation) {
 | 
				
			||||||
                $file = $credit->service()->getCreditPdf($credit->invitations()->first());
 | 
					                $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $this->company->db))->handle();
 | 
				
			||||||
                $zip_file_name = basename($file);
 | 
					                $zipFile->addFromString($invitation->credit->numberFormatter() . '.pdf', $file);
 | 
				
			||||||
                $zipFile->addFromString($zip_file_name, Storage::get($file));
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
					            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\Cron;
 | 
					namespace App\Jobs\Cron;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use App\Models\RecurringExpense;
 | 
					use App\Models\RecurringExpense;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use Illuminate\Support\Facades\Auth;
 | 
					use Illuminate\Support\Facades\Auth;
 | 
				
			||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
 | 
					use App\Events\Expense\ExpenseWasCreated;
 | 
				
			||||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
use App\Factory\RecurringExpenseToExpenseFactory;
 | 
					use App\Factory\RecurringExpenseToExpenseFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -109,6 +111,9 @@ class RecurringExpensesCron
 | 
				
			|||||||
        $expense->number = $this->getNextExpenseNumber($expense);
 | 
					        $expense->number = $this->getNextExpenseNumber($expense);
 | 
				
			||||||
        $expense->saveQuietly();
 | 
					        $expense->saveQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null)));
 | 
				
			||||||
 | 
					        event('eloquent.created: App\Models\Expense', $expense);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_expense->next_send_date = $recurring_expense->nextSendDate();
 | 
					        $recurring_expense->next_send_date = $recurring_expense->nextSendDate();
 | 
				
			||||||
        $recurring_expense->next_send_date_client = $recurring_expense->next_send_date;
 | 
					        $recurring_expense->next_send_date_client = $recurring_expense->next_send_date;
 | 
				
			||||||
        $recurring_expense->last_sent_date = now();
 | 
					        $recurring_expense->last_sent_date = now();
 | 
				
			||||||
 | 
				
			|||||||
@ -80,8 +80,8 @@ class UpdateCalculatedFields
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $project->tasks->each(function ($task) use (&$duration) {
 | 
					        $project->tasks->each(function ($task) use (&$duration) {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        
 | 
					        if(is_iterable($task->time_log)) {
 | 
				
			||||||
            foreach(json_decode($task->time_log) as $log){
 | 
					            foreach(json_decode($task->time_log) as $log) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $start_time = $log[0];
 | 
					                $start_time = $log[0];
 | 
				
			||||||
                $end_time = $log[1] == 0 ? time() : $log[1];
 | 
					                $end_time = $log[1] == 0 ? time() : $log[1];
 | 
				
			||||||
@ -89,6 +89,7 @@ class UpdateCalculatedFields
 | 
				
			|||||||
                $duration += $end_time - $start_time;
 | 
					                $duration += $end_time - $start_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -220,7 +220,7 @@ class CreateRawPdf implements ShouldQueue
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private function checkEInvoice(string $pdf): string
 | 
					    private function checkEInvoice(string $pdf): string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(!$this->entity instanceof Invoice)
 | 
					        if(!$this->entity instanceof Invoice || !$this->company->getSetting('enable_e_invoice'))
 | 
				
			||||||
            return $pdf;
 | 
					            return $pdf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $e_invoice_type = $this->entity->client->getSetting('e_invoice_type');
 | 
					        $e_invoice_type = $this->entity->client->getSetting('e_invoice_type');
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										79
									
								
								app/Jobs/Ninja/CheckACHStatus.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								app/Jobs/Ninja/CheckACHStatus.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					<?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\Jobs\Ninja;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
 | 
					use App\Models\ClientGatewayToken;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CheckACHStatus implements ShouldQueue
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new job instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Execute the job.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function handle()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //multiDB environment, need to
 | 
				
			||||||
 | 
					        foreach (MultiDB::$dbs as $db) {
 | 
				
			||||||
 | 
					            MultiDB::setDB($db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            nlog("Checking ACH status");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ClientGatewayToken::query()
 | 
				
			||||||
 | 
					            ->where('created_at', '>', now()->subMonths(2))
 | 
				
			||||||
 | 
					            ->where('gateway_type_id', 2)
 | 
				
			||||||
 | 
					            ->whereHas('gateway', function ($q) {
 | 
				
			||||||
 | 
					                $q->whereIn('gateway_key', ['d14dd26a37cecc30fdd65700bfb55b23','d14dd26a47cecc30fdd65700bfb67b34']);
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            ->whereJsonContains('meta', ['state' => 'unauthorized'])
 | 
				
			||||||
 | 
					            ->cursor()
 | 
				
			||||||
 | 
					            ->each(function ($token) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    $stripe = $token->gateway->driver($token->client)->init();
 | 
				
			||||||
 | 
					                    $pm =  $stripe->getStripePaymentMethod($token->token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if($pm) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        $meta = $token->meta;
 | 
				
			||||||
 | 
					                        $meta->state = 'authorized';
 | 
				
			||||||
 | 
					                        $token->meta = $meta;
 | 
				
			||||||
 | 
					                        $token->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                } catch (\Exception $e) {
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -18,6 +18,7 @@ use App\Jobs\Vendor\CreatePurchaseOrderPdf;
 | 
				
			|||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Mail\DownloadPurchaseOrders;
 | 
					use App\Mail\DownloadPurchaseOrders;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Models\User;
 | 
					use App\Models\User;
 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
@ -30,32 +31,12 @@ class ZipPurchaseOrders implements ShouldQueue
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $purchase_orders;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public $settings;
 | 
					    public $settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $tries = 1;
 | 
					    public $tries = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function __construct(protected array $purchase_order_ids, protected Company $company, protected User $user)
 | 
				
			||||||
     * @param $purchase_orders
 | 
					 | 
				
			||||||
     * @param Company $company
 | 
					 | 
				
			||||||
     * @param $email
 | 
					 | 
				
			||||||
     * @deprecated confirm to be deleted
 | 
					 | 
				
			||||||
     * Create a new job instance.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function __construct($purchase_orders, Company $company, User $user)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->purchase_orders = $purchase_orders;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->company = $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->user = $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->settings = $company->settings;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -67,21 +48,23 @@ class ZipPurchaseOrders implements ShouldQueue
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->settings = $this->company->settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // create new zip object
 | 
					        // create new zip object
 | 
				
			||||||
        $zipFile = new \PhpZip\ZipFile();
 | 
					        $zipFile = new \PhpZip\ZipFile();
 | 
				
			||||||
        $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip';
 | 
					        $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip';
 | 
				
			||||||
        $invitation = $this->purchase_orders->first()->invitations->first();
 | 
					 | 
				
			||||||
        $path = $this->purchase_orders->first()->vendor->purchase_order_filepath($invitation);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->purchase_orders->each(function ($purchase_order) {
 | 
					        $invitations = PurchaseOrderInvitation::query()
 | 
				
			||||||
            (new CreatePurchaseOrderPdf($purchase_order->invitations()->first()))->handle();
 | 
					                                            ->with('purchase_order')
 | 
				
			||||||
        });
 | 
					                                            ->whereIn('purchase_order_id', $this->purchase_order_ids)
 | 
				
			||||||
 | 
					                                            ->get();
 | 
				
			||||||
 | 
					        $invitation = $invitations->first();
 | 
				
			||||||
 | 
					        $path = $invitation->contact->vendor->purchase_order_filepath($invitation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            foreach ($this->purchase_orders as $purchase_order) {
 | 
					            foreach ($invitations as $invitation) {
 | 
				
			||||||
                $file = $purchase_order->service()->getPurchaseOrderPdf();
 | 
					                $file = (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($invitation))->rawPdf();
 | 
				
			||||||
                $zip_file_name = basename($file);
 | 
					                $zipFile->addFromString($invitation->purchase_order->numberFormatter().".pdf", $file);
 | 
				
			||||||
                $zipFile->addFromString($zip_file_name, Storage::get($file));
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
					            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
				
			||||||
 | 
				
			|||||||
@ -11,51 +11,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\Quote;
 | 
					namespace App\Jobs\Quote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Jobs\Entity\CreateEntityPdf;
 | 
					use App\Models\User;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
					 | 
				
			||||||
use App\Jobs\Util\UnlinkFile;
 | 
					 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Mail\DownloadQuotes;
 | 
					use App\Mail\DownloadQuotes;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Jobs\Util\UnlinkFile;
 | 
				
			||||||
use App\Models\User;
 | 
					 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use App\Models\QuoteInvitation;
 | 
				
			||||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
					use App\Jobs\Mail\NinjaMailerJob;
 | 
				
			||||||
use Illuminate\Queue\InteractsWithQueue;
 | 
					use App\Jobs\Mail\NinjaMailerObject;
 | 
				
			||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Illuminate\Support\Facades\Storage;
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ZipQuotes implements ShouldQueue
 | 
					class ZipQuotes implements ShouldQueue
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $quotes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public $settings;
 | 
					    public $settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $tries = 1;
 | 
					    public $tries = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function __construct(protected array $quote_ids, protected Company $company, protected User $user)
 | 
				
			||||||
     * @param $invoices
 | 
					 | 
				
			||||||
     * @param Company $company
 | 
					 | 
				
			||||||
     * @param $email
 | 
					 | 
				
			||||||
     * @deprecated confirm to be deleted
 | 
					 | 
				
			||||||
     * Create a new job instance.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function __construct($quotes, Company $company, User $user)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->quotes = $quotes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->company = $company;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->user = $user;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->settings = $company->settings;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -67,26 +47,21 @@ class ZipQuotes implements ShouldQueue
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        $this->settings = $this->company->settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // create new zip object
 | 
					        // create new zip object
 | 
				
			||||||
        $zipFile = new \PhpZip\ZipFile();
 | 
					        $zipFile = new \PhpZip\ZipFile();
 | 
				
			||||||
        $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
 | 
					        $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
 | 
				
			||||||
        $invitation = $this->quotes->first()->invitations->first();
 | 
					 | 
				
			||||||
        $path = $this->quotes->first()->client->quote_filepath($invitation);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->quotes->each(function ($quote) {
 | 
					        $invitations = QuoteInvitation::query()->with('quote')->whereIn('quote_id', $this->quote_ids)->get();
 | 
				
			||||||
            $quote->service()->createInvitations();
 | 
					        $invitation = $invitations->first();
 | 
				
			||||||
 | 
					        $path = $invitation->contact->client->quote_filepath($invitation);
 | 
				
			||||||
            (new CreateEntityPdf($quote->invitations()->first()))->handle();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            foreach ($this->quotes as $quote) {
 | 
					 | 
				
			||||||
                $file = $quote->service()->getQuotePdf();
 | 
					 | 
				
			||||||
                $zip_file_name = basename($file);
 | 
					 | 
				
			||||||
                $zipFile->addFromString($zip_file_name, Storage::get($file));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // $download_file = file_get_contents($quote->pdf_file_path($invitation, 'url', true));
 | 
					            foreach ($invitations as $invitation) {
 | 
				
			||||||
                // $zipFile->addFromString(basename($quote->pdf_file_path($invitation)), $download_file);
 | 
					                $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $this->company->db))->handle();
 | 
				
			||||||
 | 
					                $zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
					            Storage::put($path.$file_name, $zipFile->outputAsString());
 | 
				
			||||||
@ -100,8 +75,9 @@ class ZipQuotes implements ShouldQueue
 | 
				
			|||||||
            NinjaMailerJob::dispatch($nmo);
 | 
					            NinjaMailerJob::dispatch($nmo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1));
 | 
					            UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch (\PhpZip\Exception\ZipException $e) {
 | 
					        } catch (\PhpZip\Exception\ZipException $e) {
 | 
				
			||||||
            // handle exception
 | 
					            nlog("zip build failed: ".$e->getMessage());
 | 
				
			||||||
        } finally {
 | 
					        } finally {
 | 
				
			||||||
            $zipFile->close();
 | 
					            $zipFile->close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,22 +11,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Jobs\RecurringInvoice;
 | 
					namespace App\Jobs\RecurringInvoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\DataMapper\Analytics\SendRecurringFailure;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use App\Factory\InvoiceInvitationFactory;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Factory\RecurringInvoiceToInvoiceFactory;
 | 
					 | 
				
			||||||
use App\Jobs\Cron\AutoBill;
 | 
					 | 
				
			||||||
use App\Jobs\Entity\EmailEntity;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Jobs\Cron\AutoBill;
 | 
				
			||||||
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Jobs\Entity\EmailEntity;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Carbon\Carbon;
 | 
					 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
					 | 
				
			||||||
use Illuminate\Queue\InteractsWithQueue;
 | 
					 | 
				
			||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Turbo124\Beacon\Facades\LightLogs;
 | 
					use Turbo124\Beacon\Facades\LightLogs;
 | 
				
			||||||
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceWasCreated;
 | 
				
			||||||
 | 
					use App\Factory\InvoiceInvitationFactory;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
 | 
					use App\Factory\RecurringInvoiceToInvoiceFactory;
 | 
				
			||||||
 | 
					use App\DataMapper\Analytics\SendRecurringFailure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SendRecurring implements ShouldQueue
 | 
					class SendRecurring implements ShouldQueue
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -105,6 +107,7 @@ class SendRecurring implements ShouldQueue
 | 
				
			|||||||
        $this->recurring_invoice->save();
 | 
					        $this->recurring_invoice->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event('eloquent.created: App\Models\Invoice', $invoice);
 | 
					        event('eloquent.created: App\Models\Invoice', $invoice);
 | 
				
			||||||
 | 
					        event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //auto bill, BUT NOT DRAFTS!!
 | 
					        //auto bill, BUT NOT DRAFTS!!
 | 
				
			||||||
        if ($invoice->auto_bill_enabled && $invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->client->getSetting('auto_email_invoice')) {
 | 
					        if ($invoice->auto_bill_enabled && $invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->client->getSetting('auto_email_invoice')) {
 | 
				
			||||||
 | 
				
			|||||||
@ -39,8 +39,8 @@ class PreviewReport implements ShouldQueue
 | 
				
			|||||||
        /** @var \App\Export\CSV\CreditExport $export */
 | 
					        /** @var \App\Export\CSV\CreditExport $export */
 | 
				
			||||||
        $export = new $this->report_class($this->company, $this->request);
 | 
					        $export = new $this->report_class($this->company, $this->request);
 | 
				
			||||||
        $report = $export->returnJson();
 | 
					        $report = $export->returnJson();
 | 
				
			||||||
        nlog($report);
 | 
					        // nlog($report);
 | 
				
			||||||
        nlog($this->report_class);
 | 
					        // nlog($this->report_class);
 | 
				
			||||||
        // nlog($report);
 | 
					        // nlog($report);
 | 
				
			||||||
        Cache::put($this->hash, $report, 60 * 60);
 | 
					        Cache::put($this->hash, $report, 60 * 60);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ class CreateUser
 | 
				
			|||||||
            'is_admin' => 1,
 | 
					            'is_admin' => 1,
 | 
				
			||||||
            'is_locked' => 0,
 | 
					            'is_locked' => 0,
 | 
				
			||||||
            'permissions' => '',
 | 
					            'permissions' => '',
 | 
				
			||||||
            'notifications' => CompanySettings::notificationDefaults(),
 | 
					            'notifications' => CompanySettings::notificationAdminDefaults(),
 | 
				
			||||||
            'settings' => null,
 | 
					            'settings' => null,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,7 @@ class CreatedExpenseActivity implements ShouldQueue
 | 
				
			|||||||
        $fields->user_id = $user_id;
 | 
					        $fields->user_id = $user_id;
 | 
				
			||||||
        $fields->company_id = $event->expense->company_id;
 | 
					        $fields->company_id = $event->expense->company_id;
 | 
				
			||||||
        $fields->activity_type_id = Activity::CREATE_EXPENSE;
 | 
					        $fields->activity_type_id = Activity::CREATE_EXPENSE;
 | 
				
			||||||
 | 
					        $fields->recurring_expense_id = $event->expense->recurring_expense_id ?? null;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $this->activity_repo->save($fields, $event->expense, $event->event_vars);
 | 
					        $this->activity_repo->save($fields, $event->expense, $event->event_vars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ class CreateInvoiceActivity implements ShouldQueue
 | 
				
			|||||||
        $fields->client_id = $event->invoice->client_id;
 | 
					        $fields->client_id = $event->invoice->client_id;
 | 
				
			||||||
        $fields->company_id = $event->invoice->company_id;
 | 
					        $fields->company_id = $event->invoice->company_id;
 | 
				
			||||||
        $fields->activity_type_id = Activity::CREATE_INVOICE;
 | 
					        $fields->activity_type_id = Activity::CREATE_INVOICE;
 | 
				
			||||||
 | 
					        $fields->recurring_invoice_id = $event->invoice->recurring_id;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
					        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,7 @@ class EntitySentObject
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
            $mail_obj->data = [
 | 
					            $mail_obj->data = [
 | 
				
			||||||
                'title' => $mail_obj->subject,
 | 
					                'title' => $mail_obj->subject,
 | 
				
			||||||
                'message' => ctrans(
 | 
					                'content' => ctrans(
 | 
				
			||||||
                    $this->template_body,
 | 
					                    $this->template_body,
 | 
				
			||||||
                    [
 | 
					                    [
 | 
				
			||||||
                        'amount' => $mail_obj->amount,
 | 
					                        'amount' => $mail_obj->amount,
 | 
				
			||||||
@ -98,7 +98,7 @@ class EntitySentObject
 | 
				
			|||||||
            $mail_obj->markdown = 'email.admin.generic';
 | 
					            $mail_obj->markdown = 'email.admin.generic';
 | 
				
			||||||
            $mail_obj->tag = $this->company->company_key;
 | 
					            $mail_obj->tag = $this->company->company_key;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        // nlog($mail_obj);
 | 
				
			||||||
        return $mail_obj;
 | 
					        return $mail_obj;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -186,7 +186,7 @@ class EntitySentObject
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'title' => $this->getSubject(),
 | 
					            'title' => $this->getSubject(),
 | 
				
			||||||
            'message' => $this->getMessage(),
 | 
					            'content' => $this->getMessage(),
 | 
				
			||||||
            'url' => $this->invitation->getAdminLink($this->use_react_url),
 | 
					            'url' => $this->invitation->getAdminLink($this->use_react_url),
 | 
				
			||||||
            'button' => ctrans("texts.view_{$this->entity_type}"),
 | 
					            'button' => ctrans("texts.view_{$this->entity_type}"),
 | 
				
			||||||
            'signature' => $settings->email_signature,
 | 
					            'signature' => $settings->email_signature,
 | 
				
			||||||
 | 
				
			|||||||
@ -114,11 +114,6 @@ class CreditEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
            ->setTextBody($text_body);
 | 
					            ->setTextBody($text_body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->client->getSetting('pdf_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
 | 
					        if ($this->client->getSetting('pdf_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
 | 
				
			||||||
            // if (Ninja::isHosted()) {
 | 
					 | 
				
			||||||
            //     $this->setAttachments([$this->credit->pdf_file_path($this->invitation, 'url', true)]);
 | 
					 | 
				
			||||||
            // } else {
 | 
					 | 
				
			||||||
            //     $this->setAttachments([$this->credit->pdf_file_path($this->invitation)]);
 | 
					 | 
				
			||||||
            // }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle());
 | 
					            $pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -128,21 +123,21 @@ class CreditEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
        //attach third party documents
 | 
					        //attach third party documents
 | 
				
			||||||
        if ($this->client->getSetting('document_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
					        if ($this->client->getSetting('document_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
				
			||||||
            // Storage::url
 | 
					            // Storage::url
 | 
				
			||||||
            foreach ($this->credit->documents as $document) {
 | 
					            $this->credit->documents()->where('is_public',true)->cursor()->each(function($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, 'file' => base64_encode($document->getFile())]]);
 | 
					                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, 'file' => base64_encode($document->getFile())]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach ($this->credit->company->documents as $document) {
 | 
					            $this->credit->company->documents()->where('is_public',true)->cursor()->each(function($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, 'file' => base64_encode($document->getFile())]]);
 | 
					                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, 'file' => base64_encode($document->getFile())]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
				
			|||||||
@ -135,31 +135,31 @@ class InvoiceEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
        //attach third party documents
 | 
					        //attach third party documents
 | 
				
			||||||
        if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
					        if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
				
			||||||
            if ($this->invoice->recurring_invoice()->exists()) {
 | 
					            if ($this->invoice->recurring_invoice()->exists()) {
 | 
				
			||||||
                foreach ($this->invoice->recurring_invoice->documents as $document) {
 | 
					                $this->invoice->recurring_invoice->documents()->where('is_public',true)->cursor()->each(function ($document) {
 | 
				
			||||||
                    if ($document->size > $this->max_attachment_size) {
 | 
					                    if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                        $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                        $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                        $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Storage::url
 | 
					            // Storage::url
 | 
				
			||||||
            foreach ($this->invoice->documents as $document) {
 | 
					            $this->invoice->documents()->where('is_public',true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach ($this->invoice->company->documents as $document) {
 | 
					            $this->invoice->company->documents()->where('is_public',true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $line_items = $this->invoice->line_items;
 | 
					            $line_items = $this->invoice->line_items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -175,13 +175,13 @@ class InvoiceEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
                                       ->where('invoice_documents', 1)
 | 
					                                       ->where('invoice_documents', 1)
 | 
				
			||||||
                                       ->cursor()
 | 
					                                       ->cursor()
 | 
				
			||||||
                                       ->each(function ($expense) {
 | 
					                                       ->each(function ($expense) {
 | 
				
			||||||
                                           foreach ($expense->documents as $document) {
 | 
					                                           $expense->documents()->where('is_public',true)->cursor()->each(function ($document) {
 | 
				
			||||||
                                               if ($document->size > $this->max_attachment_size) {
 | 
					                                               if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                                                   $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                                                   $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                                               } else {
 | 
					                                               } else {
 | 
				
			||||||
                                                   $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                                                   $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                                               }
 | 
					                                               }
 | 
				
			||||||
                                           }
 | 
					                                           });
 | 
				
			||||||
                                       });
 | 
					                                       });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -195,13 +195,13 @@ class InvoiceEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
                    $tasks = Task::query()->whereIn('id', $this->transformKeys($task_ids))
 | 
					                    $tasks = Task::query()->whereIn('id', $this->transformKeys($task_ids))
 | 
				
			||||||
                                       ->cursor()
 | 
					                                       ->cursor()
 | 
				
			||||||
                                       ->each(function ($task) {
 | 
					                                       ->each(function ($task) {
 | 
				
			||||||
                                           foreach ($task->documents as $document) {
 | 
					                                           $task->documents()->where('is_public', true)->cursor()->each(function ($document) {
 | 
				
			||||||
                                               if ($document->size > $this->max_attachment_size) {
 | 
					                                               if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                                                   $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                                                   $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                                               } else {
 | 
					                                               } else {
 | 
				
			||||||
                                                   $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                                                   $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                                               }
 | 
					                                               }
 | 
				
			||||||
                                           }
 | 
					                                           });
 | 
				
			||||||
                                       });
 | 
					                                       });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -98,13 +98,13 @@ class PaymentEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                //attach invoice documents also to payments
 | 
					                //attach invoice documents also to payments
 | 
				
			||||||
                if ($this->client->getSetting('document_email_attachment') !== false) {
 | 
					                if ($this->client->getSetting('document_email_attachment') !== false) {
 | 
				
			||||||
                    foreach ($invoice->documents as $document) {
 | 
					                    $invoice->documents()->where('is_public', true)->cursor()->each(function ($document){
 | 
				
			||||||
                        if ($document->size > $this->max_attachment_size) {
 | 
					                        if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                            $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                            $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                            $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if($this->client->getSetting('enable_e_invoice'))
 | 
					                if($this->client->getSetting('enable_e_invoice'))
 | 
				
			||||||
 | 
				
			|||||||
@ -127,21 +127,21 @@ class PurchaseOrderEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
        //attach third party documents
 | 
					        //attach third party documents
 | 
				
			||||||
        if ($this->vendor->getSetting('document_email_attachment') !== false && $this->purchase_order->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
					        if ($this->vendor->getSetting('document_email_attachment') !== false && $this->purchase_order->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
				
			||||||
            // Storage::url
 | 
					            // Storage::url
 | 
				
			||||||
            foreach ($this->purchase_order->documents as $document) {
 | 
					            $this->purchase_order->documents()->where('is_public', true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
 | 
					                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach ($this->purchase_order->company->documents as $document) {
 | 
					            $this->purchase_order->company->documents()->where('is_public', true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
 | 
					                    $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
				
			|||||||
@ -121,21 +121,21 @@ class QuoteEmailEngine extends BaseEmailEngine
 | 
				
			|||||||
        //attach third party documents
 | 
					        //attach third party documents
 | 
				
			||||||
        if ($this->client->getSetting('document_email_attachment') !== false && $this->quote->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
					        if ($this->client->getSetting('document_email_attachment') !== false && $this->quote->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
 | 
				
			||||||
            // Storage::url
 | 
					            // Storage::url
 | 
				
			||||||
            foreach ($this->quote->documents as $document) {
 | 
					            $this->quote->documents()->where('is_public', true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach ($this->quote->company->documents as $document) {
 | 
					            $this->quote->company->documents()->where('is_public', true)->cursor()->each(function ($document) {
 | 
				
			||||||
                if ($document->size > $this->max_attachment_size) {
 | 
					                if ($document->size > $this->max_attachment_size) {
 | 
				
			||||||
                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
					                    $this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
					                    $this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => null, ]]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
				
			|||||||
@ -416,6 +416,9 @@ class Activity extends StaticModel
 | 
				
			|||||||
        if($this->vendor)
 | 
					        if($this->vendor)
 | 
				
			||||||
            $replacements['vendor'] = ['label' => $this?->vendor?->present()->name() ?? '', 'hashed_id' => $this->vendor->hashed_id ?? ''];
 | 
					            $replacements['vendor'] = ['label' => $this?->vendor?->present()->name() ?? '', 'hashed_id' => $this->vendor->hashed_id ?? ''];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($this->activity_type_id == 4 && $this->recurring_invoice)
 | 
				
			||||||
 | 
					            $replacements['recurring_invoice'] = ['label' => $this?->recurring_invoice?->number ?? '', 'hashed_id' => $this->recurring_invoice->hashed_id ?? ''];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $replacements['activity_type_id'] = $this->activity_type_id;
 | 
					        $replacements['activity_type_id'] = $this->activity_type_id;
 | 
				
			||||||
        $replacements['id'] = $this->id;
 | 
					        $replacements['id'] = $this->id;
 | 
				
			||||||
        $replacements['hashed_id'] = $this->hashed_id;
 | 
					        $replacements['hashed_id'] = $this->hashed_id;
 | 
				
			||||||
 | 
				
			|||||||
@ -105,22 +105,22 @@ class BaseModel extends Model
 | 
				
			|||||||
        return $value;
 | 
					        return $value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __call($method, $params)
 | 
					    // public function __call($method, $params)
 | 
				
			||||||
    {
 | 
					    // {
 | 
				
			||||||
        $entity = strtolower(class_basename($this));
 | 
					    //     $entity = strtolower(class_basename($this));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($entity) {
 | 
					    //     if ($entity) {
 | 
				
			||||||
            $configPath = "modules.relations.$entity.$method";
 | 
					    //         $configPath = "modules.relations.$entity.$method";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (config()->has($configPath)) {
 | 
					    //         if (config()->has($configPath)) {
 | 
				
			||||||
                $function = config()->get($configPath);
 | 
					    //             $function = config()->get($configPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return call_user_func_array([$this, $function[0]], $function[1]);
 | 
					    //             return call_user_func_array([$this, $function[0]], $function[1]);
 | 
				
			||||||
            }
 | 
					    //         }
 | 
				
			||||||
        }
 | 
					    //     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return parent::__call($method, $params);
 | 
					    //     return parent::__call($method, $params);
 | 
				
			||||||
    }
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * @param  \Illuminate\Database\Eloquent\Builder  $query
 | 
					    * @param  \Illuminate\Database\Eloquent\Builder  $query
 | 
				
			||||||
 | 
				
			|||||||
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