mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 04:48:40 -05:00 
			
		
		
		
	Merge remote-tracking branch 'origin/v5-develop' into v5-develop
This commit is contained in:
		
						commit
						c908819348
					
				
							
								
								
									
										41
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Bug report
 | 
				
			||||||
 | 
					about: Create a report to help us improve
 | 
				
			||||||
 | 
					title: ''
 | 
				
			||||||
 | 
					labels: triage
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**What version of Invoice Ninja are you running? ie v4.5.25 / v5.0.30**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**What environment are you running?**
 | 
				
			||||||
 | 
					Docker
 | 
				
			||||||
 | 
					Shared Hosting
 | 
				
			||||||
 | 
					ZIP
 | 
				
			||||||
 | 
					Other
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Have you checked log files (storage/logs/) Please provide redacted output**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Have you searched existing issues?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Have you reported this to Slack/forum before posting?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe the bug**
 | 
				
			||||||
 | 
					A clear and concise description of what the bug is.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Steps To Reproduce**
 | 
				
			||||||
 | 
					Please list the steps to reproduce the issue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Expected behavior**
 | 
				
			||||||
 | 
					A clear and concise description of what you expected to happen.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Screenshots**
 | 
				
			||||||
 | 
					If applicable, add screenshots to help explain your problem.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Additional context**
 | 
				
			||||||
 | 
					Add any other context about the problem here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Note: Before posting don't forget to check our "Troubleshooting" category in the [docs](https://invoiceninja.github.io/docs/self-host-troubleshooting/) (https://invoiceninja.github.io/docs/self-host-troubleshooting/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**(v5) Can you replicate the issue on our demo site? https://demo.invoiceninja.com**
 | 
				
			||||||
							
								
								
									
										24
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Feature request
 | 
				
			||||||
 | 
					about: Suggest an idea for this project
 | 
				
			||||||
 | 
					title: ''
 | 
				
			||||||
 | 
					labels: feature request
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**What version of Invoice Ninja are you running? ie v4.5 / v5**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**What environment are you running?**
 | 
				
			||||||
 | 
					Docker
 | 
				
			||||||
 | 
					Shared Hosting
 | 
				
			||||||
 | 
					ZIP
 | 
				
			||||||
 | 
					Other
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Have you searched existing issues/requests?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Screenshots**
 | 
				
			||||||
 | 
					If applicable, add screenshots to help explain your request/question.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Additional context**
 | 
				
			||||||
 | 
					Add any other context about the request/question here.
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
5.5.48
 | 
					5.5.55
 | 
				
			||||||
@ -119,6 +119,7 @@ class CheckData extends Command
 | 
				
			|||||||
        $this->checkDuplicateRecurringInvoices();
 | 
					        $this->checkDuplicateRecurringInvoices();
 | 
				
			||||||
        $this->checkOauthSanity();
 | 
					        $this->checkOauthSanity();
 | 
				
			||||||
        $this->checkVendorSettings();
 | 
					        $this->checkVendorSettings();
 | 
				
			||||||
 | 
					        $this->checkClientSettings();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if(Ninja::isHosted()){
 | 
					        if(Ninja::isHosted()){
 | 
				
			||||||
            $this->checkAccountStatuses();
 | 
					            $this->checkAccountStatuses();
 | 
				
			||||||
@ -952,24 +953,24 @@ class CheckData extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if ($this->option('fix') == 'true') {
 | 
					        if ($this->option('fix') == 'true') {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Client::query()->whereNull('settings->currency_id')->cursor()->each(function ($client){
 | 
					            // Client::query()->whereNull('settings->currency_id')->cursor()->each(function ($client){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(is_array($client->settings) && count($client->settings) == 0)
 | 
					            //     if(is_array($client->settings) && count($client->settings) == 0)
 | 
				
			||||||
                {
 | 
					            //     {
 | 
				
			||||||
                    $settings = ClientSettings::defaults();
 | 
					            //         $settings = ClientSettings::defaults();
 | 
				
			||||||
                    $settings->currency_id = $client->company->settings->currency_id;
 | 
					            //         $settings->currency_id = $client->company->settings->currency_id;
 | 
				
			||||||
                }
 | 
					            //     }
 | 
				
			||||||
                else {
 | 
					            //     else {
 | 
				
			||||||
                    $settings = $client->settings;
 | 
					            //         $settings = $client->settings;
 | 
				
			||||||
                    $settings->currency_id = $client->company->settings->currency_id;
 | 
					            //         $settings->currency_id = $client->company->settings->currency_id;
 | 
				
			||||||
                }
 | 
					            //     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $client->settings = $settings;
 | 
					            //     $client->settings = $settings;
 | 
				
			||||||
                $client->save();
 | 
					            //     $client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $this->logMessage("Fixing currency for # {$client->id}");
 | 
					            //     $this->logMessage("Fixing currency for # {$client->id}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            });
 | 
					            // });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Client::query()->whereNull('country_id')->cursor()->each(function ($client){
 | 
					            Client::query()->whereNull('country_id')->cursor()->each(function ($client){
 | 
				
			||||||
 | 
				
			|||||||
@ -306,8 +306,8 @@ class CreateSingleAccount extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $webhook_config = [
 | 
					        $webhook_config = [
 | 
				
			||||||
            'post_purchase_url' => 'http://ninja.test:8000/api/admin/plan',
 | 
					            'post_purchase_url' => 'http://ninja.test:8000/api/admin/plan',
 | 
				
			||||||
            'post_purchase_rest_method' => 'POST',
 | 
					            'post_purchase_rest_method' => 'post',
 | 
				
			||||||
            'post_purchase_headers' => [],
 | 
					            'post_purchase_headers' => [config('ninja.ninja_hosted_header') => config('ninja.ninja_hosted_secret')],
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $sub = SubscriptionFactory::create($company->id, $user->id);
 | 
					        $sub = SubscriptionFactory::create($company->id, $user->id);
 | 
				
			||||||
 | 
				
			|||||||
@ -437,7 +437,7 @@ class CreateTestData extends Command
 | 
				
			|||||||
            'company_id' => $client->company->id,
 | 
					            'company_id' => $client->company->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Document::factory()->count(5)->create([
 | 
					        Document::factory()->count(1)->create([
 | 
				
			||||||
            'user_id' => $client->user->id,
 | 
					            'user_id' => $client->user->id,
 | 
				
			||||||
            'company_id' => $client->company_id,
 | 
					            'company_id' => $client->company_id,
 | 
				
			||||||
            'documentable_type' => Vendor::class,
 | 
					            'documentable_type' => Vendor::class,
 | 
				
			||||||
 | 
				
			|||||||
@ -56,7 +56,7 @@ class ReactBuilder extends Command
 | 
				
			|||||||
        $directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
					        $directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
 | 
					        foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
 | 
				
			||||||
            if (str_contains($file->getFileName(), '.js')) {
 | 
					            if (str_contains($file->getFileName(), '.js') && !strpos($file->getFileName(), '.json')) {
 | 
				
			||||||
                if (str_contains($file->getFileName(), 'index.')) {
 | 
					                if (str_contains($file->getFileName(), 'index.')) {
 | 
				
			||||||
                    $includes .= '<script type="module" crossorigin src="/react/'.$file->getFileName().'"></script>'."\n";
 | 
					                    $includes .= '<script type="module" crossorigin src="/react/'.$file->getFileName().'"></script>'."\n";
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ class TranslationsExport extends Command
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @var string
 | 
					     * @var string
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected $signature = 'ninja:translations';
 | 
					    protected $signature = 'ninja:translations {--type=} {--path=}';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The console command description.
 | 
					     * The console command description.
 | 
				
			||||||
@ -36,8 +36,11 @@ class TranslationsExport extends Command
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    protected $description = 'Transform translations to json';
 | 
					    protected $description = 'Transform translations to json';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $log = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private array $langs = [
 | 
					    private array $langs = [
 | 
				
			||||||
        'ar',
 | 
					        'ar',
 | 
				
			||||||
 | 
					        'bg',
 | 
				
			||||||
        'ca',
 | 
					        'ca',
 | 
				
			||||||
        'cs',
 | 
					        'cs',
 | 
				
			||||||
        'da',
 | 
					        'da',
 | 
				
			||||||
@ -47,10 +50,12 @@ class TranslationsExport extends Command
 | 
				
			|||||||
        'en_GB',
 | 
					        'en_GB',
 | 
				
			||||||
        'es',
 | 
					        'es',
 | 
				
			||||||
        'es_ES',
 | 
					        'es_ES',
 | 
				
			||||||
 | 
					        'et',
 | 
				
			||||||
        'fa',
 | 
					        'fa',
 | 
				
			||||||
        'fi',
 | 
					        'fi',
 | 
				
			||||||
        'fr',
 | 
					        'fr',
 | 
				
			||||||
        'fr_CA',
 | 
					        'fr_CA',
 | 
				
			||||||
 | 
					        'he',
 | 
				
			||||||
        'hr',
 | 
					        'hr',
 | 
				
			||||||
        'it',
 | 
					        'it',
 | 
				
			||||||
        'ja',
 | 
					        'ja',
 | 
				
			||||||
@ -65,7 +70,9 @@ class TranslationsExport extends Command
 | 
				
			|||||||
        'ro',
 | 
					        'ro',
 | 
				
			||||||
        'ru_RU',
 | 
					        'ru_RU',
 | 
				
			||||||
        'sl',
 | 
					        'sl',
 | 
				
			||||||
 | 
					        'sk',
 | 
				
			||||||
        'sq',
 | 
					        'sq',
 | 
				
			||||||
 | 
					        'sr',
 | 
				
			||||||
        'sv',
 | 
					        'sv',
 | 
				
			||||||
        'th',
 | 
					        'th',
 | 
				
			||||||
        'tr_TR',
 | 
					        'tr_TR',
 | 
				
			||||||
@ -88,6 +95,49 @@ class TranslationsExport extends Command
 | 
				
			|||||||
     * @return mixed
 | 
					     * @return mixed
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function handle()
 | 
					    public function handle()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $type =$this->option('type') ?? 'export';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($type == 'import')
 | 
				
			||||||
 | 
					            $this->import();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($type == 'export')
 | 
				
			||||||
 | 
					            $this->export();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function import()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //loop and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach($this->langs as $lang)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $import_file = "textsphp_{$lang}.php";
 | 
				
			||||||
 | 
					            $dir = $this->option('path') ?? storage_path('lang_import/');
 | 
				
			||||||
 | 
					            $path = $dir.$import_file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(file_exists($path)){
 | 
				
			||||||
 | 
					                $this->logMessage($path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $trans = file_get_contents($path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                file_put_contents(lang_path("/{$lang}/texts.php"), $trans);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->logMessage("Could not open file");
 | 
				
			||||||
 | 
					                $this->logMessage($path);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function export()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Storage::disk('local')->makeDirectory('lang');
 | 
					        Storage::disk('local')->makeDirectory('lang');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -99,4 +149,12 @@ class TranslationsExport extends Command
 | 
				
			|||||||
            Storage::disk('local')->put("lang/{$lang}/{$lang}.json", json_encode(Arr::dot($translations), JSON_UNESCAPED_UNICODE));
 | 
					            Storage::disk('local')->put("lang/{$lang}/{$lang}.json", json_encode(Arr::dot($translations), JSON_UNESCAPED_UNICODE));
 | 
				
			||||||
        } 
 | 
					        } 
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function logMessage($str)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $str = date('Y-m-d h:i:s').' '.$str;
 | 
				
			||||||
 | 
					        $this->info($str);
 | 
				
			||||||
 | 
					        $this->log .= $str."\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,9 @@ use App\Jobs\Ninja\CompanySizeCheck;
 | 
				
			|||||||
use App\Jobs\Ninja\QueueSize;
 | 
					use App\Jobs\Ninja\QueueSize;
 | 
				
			||||||
use App\Jobs\Ninja\SystemMaintenance;
 | 
					use App\Jobs\Ninja\SystemMaintenance;
 | 
				
			||||||
use App\Jobs\Ninja\TaskScheduler;
 | 
					use App\Jobs\Ninja\TaskScheduler;
 | 
				
			||||||
 | 
					use App\Jobs\Invoice\InvoiceCheckLateWebhook;
 | 
				
			||||||
use App\Jobs\Quote\QuoteCheckExpired;
 | 
					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\Util\SchedulerCheck;
 | 
				
			||||||
@ -68,12 +70,18 @@ class Kernel extends ConsoleKernel
 | 
				
			|||||||
        /* Sends recurring invoices*/
 | 
					        /* Sends recurring invoices*/
 | 
				
			||||||
        $schedule->job(new RecurringInvoicesCron)->hourly()->withoutOverlapping()->name('recurring-invoice-job')->onOneServer();
 | 
					        $schedule->job(new RecurringInvoicesCron)->hourly()->withoutOverlapping()->name('recurring-invoice-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Stale Invoice Cleanup*/
 | 
				
			||||||
 | 
					        $schedule->job(new CleanStaleInvoiceOrder)->hourlyAt(30)->withoutOverlapping()->name('stale-invoice-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Sends recurring invoices*/
 | 
					        /* Sends recurring invoices*/
 | 
				
			||||||
        $schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
 | 
					        $schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Fires notifications for expired Quotes */
 | 
					        /* Fires notifications for expired Quotes */
 | 
				
			||||||
        $schedule->job(new QuoteCheckExpired)->dailyAt('05:10')->withoutOverlapping()->name('quote-expired-job')->onOneServer();
 | 
					        $schedule->job(new QuoteCheckExpired)->dailyAt('05:10')->withoutOverlapping()->name('quote-expired-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Fires webhooks for overdue Invoice */
 | 
				
			||||||
 | 
					        $schedule->job(new InvoiceCheckLateWebhook)->dailyAt('07:00')->withoutOverlapping()->name('invoice-overdue-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Performs auto billing */
 | 
					        /* Performs auto billing */
 | 
				
			||||||
        $schedule->job(new AutoBillCron)->dailyAt('06:20')->withoutOverlapping()->name('auto-bill-job')->onOneServer();
 | 
					        $schedule->job(new AutoBillCron)->dailyAt('06:20')->withoutOverlapping()->name('auto-bill-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -81,7 +89,7 @@ class Kernel extends ConsoleKernel
 | 
				
			|||||||
        $schedule->job(new SchedulerCheck)->dailyAt('01:10')->withoutOverlapping();
 | 
					        $schedule->job(new SchedulerCheck)->dailyAt('01:10')->withoutOverlapping();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Checks for scheduled tasks */
 | 
					        /* Checks for scheduled tasks */
 | 
				
			||||||
        $schedule->job(new TaskScheduler())->dailyAt('06:50')->withoutOverlapping()->name('task-scheduler-job')->onOneServer();
 | 
					        $schedule->job(new TaskScheduler())->hourlyAt(10)->withoutOverlapping()->name('task-scheduler-job')->onOneServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Performs system maintenance such as pruning the backup table */
 | 
					        /* Performs system maintenance such as pruning the backup table */
 | 
				
			||||||
        $schedule->job(new SystemMaintenance)->sundays()->at('02:30')->withoutOverlapping()->name('system-maintenance-job')->onOneServer();
 | 
					        $schedule->job(new SystemMaintenance)->sundays()->at('02:30')->withoutOverlapping()->name('system-maintenance-job')->onOneServer();
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,10 @@ class ClientRegistrationFields
 | 
				
			|||||||
                'key' => 'vat_number',
 | 
					                'key' => 'vat_number',
 | 
				
			||||||
                'required' => false,
 | 
					                'required' => false,
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'key' => 'currency_id',
 | 
				
			||||||
 | 
					                'required' => false,
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $data;
 | 
					        return $data;
 | 
				
			||||||
 | 
				
			|||||||
@ -441,7 +441,22 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public $send_email_on_mark_paid = false;
 | 
					    public $send_email_on_mark_paid = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $postmark_secret = '';
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public $mailgun_secret = '';
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public $mailgun_domain = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $auto_bill_standard_invoices = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $email_alignment = 'center'; // center , left, right
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static $casts = [
 | 
					    public static $casts = [
 | 
				
			||||||
 | 
					        'email_alignment'                    => 'string',
 | 
				
			||||||
 | 
					        'auto_bill_standard_invoices'        => 'bool',
 | 
				
			||||||
 | 
					        'postmark_secret'                    => 'string',
 | 
				
			||||||
 | 
					        'mailgun_secret'                     => 'string',
 | 
				
			||||||
 | 
					        'mailgun_domain'                     => 'string',
 | 
				
			||||||
        'send_email_on_mark_paid'            => 'bool',
 | 
					        'send_email_on_mark_paid'            => 'bool',
 | 
				
			||||||
        'vendor_portal_enable_uploads'       => 'bool',
 | 
					        'vendor_portal_enable_uploads'       => 'bool',
 | 
				
			||||||
        'besr_id'                            => 'string',
 | 
					        'besr_id'                            => 'string',
 | 
				
			||||||
 | 
				
			|||||||
@ -235,12 +235,17 @@ class EmailTemplateDefaults
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static function emailStatementSubject()
 | 
					    public static function emailStatementSubject()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return '';
 | 
					        return ctrans('texts.your_statement');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function emailStatementTemplate()
 | 
					    public static function emailStatementTemplate()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return '';
 | 
					
 | 
				
			||||||
 | 
					        $statement_message = '<p>$client<br><br>'.self::transformText('client_statement_body').'<br></p>';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $statement_message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // return ctrans('texts.client_statement_body', ['start_date' => '$start_date', 'end_date' => '$end_date']);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static function transformText($string)
 | 
					    private static function transformText($string)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										96
									
								
								app/DataMapper/Schedule/ClientStatement.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/DataMapper/Schedule/ClientStatement.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\DataMapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ClientStatement
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Defines the template name
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $template = 'client_statement';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * An array of clients hashed_ids
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Leave blank if this action should apply to all clients
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public array $clients = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The consts to be used to define the date_range variable of the statement
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public const THIS_MONTH = 'this_month';
 | 
				
			||||||
 | 
					    public const THIS_QUARTER = 'this_quarter';
 | 
				
			||||||
 | 
					    public const THIS_YEAR = 'this_year';
 | 
				
			||||||
 | 
					    public const PREVIOUS_MONTH = 'previous_month';
 | 
				
			||||||
 | 
					    public const PREVIOUS_QUARTER = 'previous_quarter';
 | 
				
			||||||
 | 
					    public const PREVIOUS_YEAR = 'previous_year';
 | 
				
			||||||
 | 
					    public const CUSTOM_RANGE = "custom_range";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The date range the statement should include
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $date_range = 'this_month';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * If a custom range is select for the date range then
 | 
				
			||||||
 | 
					     * the start_date should be supplied in Y-m-d format
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $start_date = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * If a custom range is select for the date range then
 | 
				
			||||||
 | 
					     * the end_date should be supplied in Y-m-d format
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $end_date = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Flag which allows the payment table
 | 
				
			||||||
 | 
					     * to be shown
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var boolean
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public bool $show_payments_table = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Flag which allows the aging table
 | 
				
			||||||
 | 
					     * to be shown
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var boolean
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public bool $show_aging_table = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * String const which defines whether
 | 
				
			||||||
 | 
					     * the invoices to be shown are either
 | 
				
			||||||
 | 
					     * paid or unpaid
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $status = 'paid'; // paid | unpaid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										138
									
								
								app/Export/CSV/ProductSalesExport.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								app/Export/CSV/ProductSalesExport.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Export\CSV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\Credit;
 | 
				
			||||||
 | 
					use App\Models\Document;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\Product;
 | 
				
			||||||
 | 
					use App\Transformers\ProductTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\App;
 | 
				
			||||||
 | 
					use League\Csv\Writer;
 | 
				
			||||||
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProductSalesExport extends BaseExport
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected array $input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $date_key = 'created_at';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected array $entity_keys = [
 | 
				
			||||||
 | 
					        'custom_value1' => 'custom_value1',
 | 
				
			||||||
 | 
					        'custom_value2' => 'custom_value2',
 | 
				
			||||||
 | 
					        'custom_value3' => 'custom_value3',
 | 
				
			||||||
 | 
					        'custom_value4' => 'custom_value4',
 | 
				
			||||||
 | 
					        'product_key' => 'product_key',
 | 
				
			||||||
 | 
					        'notes' => 'notes',
 | 
				
			||||||
 | 
					        'cost' => 'cost',
 | 
				
			||||||
 | 
					        'price' => 'price',
 | 
				
			||||||
 | 
					        'quantity' => 'quantity',
 | 
				
			||||||
 | 
					        'tax_rate1' => 'tax_rate1',
 | 
				
			||||||
 | 
					        'tax_rate2' => 'tax_rate2',
 | 
				
			||||||
 | 
					        'tax_rate3' => 'tax_rate3',
 | 
				
			||||||
 | 
					        'tax_name1' => 'tax_name1',
 | 
				
			||||||
 | 
					        'tax_name2' => 'tax_name2',
 | 
				
			||||||
 | 
					        'tax_name3' => 'tax_name3',
 | 
				
			||||||
 | 
					        'is_amount_discount' => 'is_amount_discount',
 | 
				
			||||||
 | 
					        'discount' => 'discount',
 | 
				
			||||||
 | 
					        'line_total' => 'line_total',
 | 
				
			||||||
 | 
					        'gross_line_total' => 'gross_line_total',
 | 
				
			||||||
 | 
					        'status' => 'status',
 | 
				
			||||||
 | 
					        'date' => 'date',
 | 
				
			||||||
 | 
					        'currency' => 'currency',
 | 
				
			||||||
 | 
					        'client' => 'client',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private array $decorate_keys = [
 | 
				
			||||||
 | 
					        'client',
 | 
				
			||||||
 | 
					        'currency',
 | 
				
			||||||
 | 
					        'date',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(Company $company, array $input)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->company = $company;
 | 
				
			||||||
 | 
					        $this->input = $input;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
 | 
					        App::forgetInstance('translator');
 | 
				
			||||||
 | 
					        App::setLocale($this->company->locale());
 | 
				
			||||||
 | 
					        $t = app('translator');
 | 
				
			||||||
 | 
					        $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //load the CSV document from a string
 | 
				
			||||||
 | 
					        $this->csv = Writer::createFromString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
 | 
					            $this->input['report_keys'] = array_values($this->entity_keys);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //insert the header
 | 
				
			||||||
 | 
					        $this->csv->insertOne($this->buildHeader());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = Invoice::query()
 | 
				
			||||||
 | 
					                        ->withTrashed()
 | 
				
			||||||
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					                        ->where('is_deleted', 0)
 | 
				
			||||||
 | 
					                        ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query = $this->addDateRange($query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query->cursor()
 | 
				
			||||||
 | 
					              ->each(function ($invoice) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  foreach($invoice->line_items as $item)
 | 
				
			||||||
 | 
					                    $this->csv->insertOne($this->buildRow($invoice, $item));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->csv->toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function buildRow($invoice, $invoice_item) :array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $transformed_entity = (array)$invoice_item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $entity = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (array_values($this->input['report_keys']) as $key) {
 | 
				
			||||||
 | 
					            $keyval = array_search($key, $this->entity_keys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (array_key_exists($key, $transformed_entity)) {
 | 
				
			||||||
 | 
					                $entity[$keyval] = $transformed_entity[$key];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $entity[$keyval] = '';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->decorateAdvancedFields($invoice, $entity);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function decorateAdvancedFields(Invoice $invoice, $entity) :array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $entity['client'] = $invoice->client->present()->name();
 | 
				
			||||||
 | 
					        $entity['currency'] = $invoice->client->currency()->code;
 | 
				
			||||||
 | 
					        $entity['status'] = $invoice->stringStatus($invoice->status_id);
 | 
				
			||||||
 | 
					        $entity['date'] = Carbon::parse($invoice->date)->format($this->company->date_format());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $entity;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										32
									
								
								app/Factory/SchedulerFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Factory/SchedulerFactory.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Scheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SchedulerFactory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static function create($company_id, $user_id) :Scheduler
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $scheduler = new Scheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $scheduler->name = '';
 | 
				
			||||||
 | 
					        $scheduler->company_id = $company_id;
 | 
				
			||||||
 | 
					        $scheduler->user_id = $user_id;
 | 
				
			||||||
 | 
					        $scheduler->parameters = [];
 | 
				
			||||||
 | 
					        $scheduler->is_paused = false;
 | 
				
			||||||
 | 
					        $scheduler->is_deleted = false;
 | 
				
			||||||
 | 
					        $scheduler->template = '';
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $scheduler;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -77,28 +77,45 @@ class BankTransactionFilters extends QueryFilters
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $status_parameters = explode(',', $value);
 | 
					        $status_parameters = explode(',', $value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $status_array = [];
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $debit_or_withdrawal_array = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('all', $status_parameters)) {
 | 
					        if (in_array('all', $status_parameters)) {
 | 
				
			||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('unmatched', $status_parameters)) {
 | 
					        if (in_array('unmatched', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', BankTransaction::STATUS_UNMATCHED);
 | 
					            $status_array[] = BankTransaction::STATUS_UNMATCHED;
 | 
				
			||||||
 | 
					            // $this->builder->orWhere('status_id', BankTransaction::STATUS_UNMATCHED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('matched', $status_parameters)) {
 | 
					        if (in_array('matched', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', BankTransaction::STATUS_MATCHED);
 | 
					            $status_array[] = BankTransaction::STATUS_MATCHED;
 | 
				
			||||||
 | 
					            // $this->builder->where('status_id', BankTransaction::STATUS_MATCHED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('converted', $status_parameters)) {
 | 
					        if (in_array('converted', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', BankTransaction::STATUS_CONVERTED);
 | 
					            $status_array[] = BankTransaction::STATUS_CONVERTED;
 | 
				
			||||||
 | 
					            // $this->builder->where('status_id', BankTransaction::STATUS_CONVERTED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('deposits', $status_parameters)) {
 | 
					        if (in_array('deposits', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('base_type', 'CREDIT');
 | 
					            $debit_or_withdrawal_array[] = 'CREDIT';
 | 
				
			||||||
 | 
					            // $this->builder->where('base_type', 'CREDIT');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('withdrawals', $status_parameters)) {
 | 
					        if (in_array('withdrawals', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('base_type', 'DEBIT');
 | 
					            $debit_or_withdrawal_array[] = 'DEBIT';
 | 
				
			||||||
 | 
					            // $this->builder->where('base_type', 'DEBIT');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(count($status_array) >=1) {
 | 
				
			||||||
 | 
					            $this->builder->whereIn('status_id', $status_array);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(count($debit_or_withdrawal_array) >=1) {
 | 
				
			||||||
 | 
					            $this->builder->orWhereIn('base_type', $debit_or_withdrawal_array);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
				
			|||||||
@ -193,9 +193,7 @@ class ClientFilters extends QueryFilters
 | 
				
			|||||||
            ->where('clients.company_id', '=', $company_id)
 | 
					            ->where('clients.company_id', '=', $company_id)
 | 
				
			||||||
            ->where('client_contacts.is_primary', '=', true)
 | 
					            ->where('client_contacts.is_primary', '=', true)
 | 
				
			||||||
            ->where('client_contacts.deleted_at', '=', null)
 | 
					            ->where('client_contacts.deleted_at', '=', null)
 | 
				
			||||||
            //->whereRaw('(clients.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
               // DB::raw('COALESCE(clients.currency_id, companies.currency_id) currency_id'),
 | 
					 | 
				
			||||||
                DB::raw('COALESCE(clients.country_id, companies.country_id) country_id'),
 | 
					                DB::raw('COALESCE(clients.country_id, companies.country_id) country_id'),
 | 
				
			||||||
                DB::raw("CONCAT(COALESCE(client_contacts.first_name, ''), ' ', COALESCE(client_contacts.last_name, '')) contact"),
 | 
					                DB::raw("CONCAT(COALESCE(client_contacts.first_name, ''), ' ', COALESCE(client_contacts.last_name, '')) contact"),
 | 
				
			||||||
                'clients.id',
 | 
					                'clients.id',
 | 
				
			||||||
@ -238,7 +236,6 @@ class ClientFilters extends QueryFilters
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function entityFilter()
 | 
					    public function entityFilter()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //return $this->builder->whereCompanyId(auth()->user()->company()->id);
 | 
					 | 
				
			||||||
        return $this->builder->company();
 | 
					        return $this->builder->company();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,6 @@ class DesignFilters extends QueryFilters
 | 
				
			|||||||
        $query = DB::table('designs')
 | 
					        $query = DB::table('designs')
 | 
				
			||||||
            ->join('companies', 'companies.id', '=', 'designs.company_id')
 | 
					            ->join('companies', 'companies.id', '=', 'designs.company_id')
 | 
				
			||||||
            ->where('designs.company_id', '=', $company_id)
 | 
					            ->where('designs.company_id', '=', $company_id)
 | 
				
			||||||
            //->whereRaw('(designs.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
                'designs.id',
 | 
					                'designs.id',
 | 
				
			||||||
                'designs.name',
 | 
					                'designs.name',
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										124
									
								
								app/Filters/ExpenseCategoryFilters.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								app/Filters/ExpenseCategoryFilters.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Filters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Expense;
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Gate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ExpenseCategoryFilters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ExpenseCategoryFilters extends QueryFilters
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filter based on search text.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string query filter
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function filter(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return  $this->builder->where('expense_categories.name', 'like', '%'.$filter.'%');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the list based on the status
 | 
				
			||||||
 | 
					     * archived, active, deleted.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string filter
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function status(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $table = 'expense_categories';
 | 
				
			||||||
 | 
					        $filters = explode(',', $filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->where(function ($query) use ($filters, $table) {
 | 
				
			||||||
 | 
					            $query->whereNull($table.'.id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ACTIVE, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhereNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ARCHIVED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query) use ($table) {
 | 
				
			||||||
 | 
					                    $query->whereNotNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (! in_array($table, ['users'])) {
 | 
				
			||||||
 | 
					                        $query->where($table.'.is_deleted', '=', 0);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_DELETED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere($table.'.is_deleted', '=', 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Sorts the list based on $sort.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string sort formatted as column|asc
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sort(string $sort) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $sort_col = explode('|', $sort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['name'])) {
 | 
				
			||||||
 | 
					            return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the base query.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param int company_id
 | 
				
			||||||
 | 
					     * @param User $user
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function baseQuery(int $company_id, User $user) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the query by the users company ID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function entityFilter()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //return $this->builder->whereCompanyId(auth()->user()->company()->id);
 | 
				
			||||||
 | 
					        return $this->builder->company();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -69,26 +69,55 @@ class ExpenseFilters extends QueryFilters
 | 
				
			|||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->builder->whereNested(function ($query) use($status_parameters){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('logged', $status_parameters)) {
 | 
					            if (in_array('logged', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('amount', '>', 0);
 | 
					
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query){
 | 
				
			||||||
 | 
					                    $query->where('amount', '>', 0)
 | 
				
			||||||
 | 
					                          ->whereNull('invoice_id')
 | 
				
			||||||
 | 
					                          ->whereNull('payment_date');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('pending', $status_parameters)) {
 | 
					            if (in_array('pending', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereNull('invoice_id')->whereNotNull('payment_date');
 | 
					
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query){
 | 
				
			||||||
 | 
					                    $query->where('should_be_invoiced',true)
 | 
				
			||||||
 | 
					                          ->whereNull('invoice_id');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('invoiced', $status_parameters)) {
 | 
					            if (in_array('invoiced', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereNotNull('invoice_id');
 | 
					
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query){
 | 
				
			||||||
 | 
					                    $query->whereNotNull('invoice_id');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('paid', $status_parameters)) {
 | 
					            if (in_array('paid', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereNotNull('payment_date');
 | 
					
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query){
 | 
				
			||||||
 | 
					                    $query->whereNotNull('payment_date');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (in_array('unpaid', $status_parameters)) {
 | 
					            if (in_array('unpaid', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereNull('payment_date');
 | 
					
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query){
 | 
				
			||||||
 | 
					                    $query->whereNull('payment_date');
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // nlog($this->builder->toSql());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,9 +205,7 @@ class ExpenseFilters extends QueryFilters
 | 
				
			|||||||
        $query = DB::table('expenses')
 | 
					        $query = DB::table('expenses')
 | 
				
			||||||
            ->join('companies', 'companies.id', '=', 'expenses.company_id')
 | 
					            ->join('companies', 'companies.id', '=', 'expenses.company_id')
 | 
				
			||||||
            ->where('expenses.company_id', '=', $company_id)
 | 
					            ->where('expenses.company_id', '=', $company_id)
 | 
				
			||||||
            //->whereRaw('(expenses.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
               // DB::raw('COALESCE(expenses.currency_id, companies.currency_id) currency_id'),
 | 
					 | 
				
			||||||
                DB::raw('COALESCE(expenses.country_id, companies.country_id) country_id'),
 | 
					                DB::raw('COALESCE(expenses.country_id, companies.country_id) country_id'),
 | 
				
			||||||
                DB::raw("CONCAT(COALESCE(expense_contacts.first_name, ''), ' ', COALESCE(expense_contacts.last_name, '')) contact"),
 | 
					                DB::raw("CONCAT(COALESCE(expense_contacts.first_name, ''), ' ', COALESCE(expense_contacts.last_name, '')) contact"),
 | 
				
			||||||
                'expenses.id',
 | 
					                'expenses.id',
 | 
				
			||||||
@ -212,8 +239,6 @@ class ExpenseFilters extends QueryFilters
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function entityFilter()
 | 
					    public function entityFilter()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        //return $this->builder->whereCompanyId(auth()->user()->company()->id);
 | 
					 | 
				
			||||||
        return $this->builder->company();
 | 
					        return $this->builder->company();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,8 @@ use App\Models\User;
 | 
				
			|||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					use InvalidArgumentException;
 | 
				
			||||||
 | 
					use RuntimeException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * InvoiceFilters.
 | 
					 * InvoiceFilters.
 | 
				
			||||||
@ -45,20 +47,27 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $status_parameters = explode(',', $value);
 | 
					        $status_parameters = explode(',', $value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoice_filters = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('all', $status_parameters)) {
 | 
					        if (in_array('all', $status_parameters)) {
 | 
				
			||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('paid', $status_parameters)) {
 | 
					        if (in_array('paid', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Invoice::STATUS_PAID);
 | 
					            $invoice_filters[] = Invoice::STATUS_PAID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('unpaid', $status_parameters)) {
 | 
					        if (in_array('unpaid', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]);
 | 
					            $invoice_filters[] = Invoice::STATUS_SENT;
 | 
				
			||||||
 | 
					            $invoice_filters[] = Invoice::STATUS_PARTIAL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(count($invoice_filters) >0){
 | 
				
			||||||
 | 
					            $this->builder->whereIn('status_id', $invoice_filters);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (in_array('overdue', $status_parameters)) {
 | 
					        if (in_array('overdue', $status_parameters)) {
 | 
				
			||||||
            $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
					            $this->builder->orWhereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
				
			||||||
                            ->where('due_date', '<', Carbon::now())
 | 
					                            ->where('due_date', '<', Carbon::now())
 | 
				
			||||||
                            ->orWhere('partial_due_date', '<', Carbon::now());
 | 
					                            ->orWhere('partial_due_date', '<', Carbon::now());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -136,6 +145,10 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return Builder 
 | 
				
			||||||
 | 
					     * @throws RuntimeException 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function without_deleted_clients()
 | 
					    public function without_deleted_clients()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -144,6 +157,10 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
                       });
 | 
					                       });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return Builder 
 | 
				
			||||||
 | 
					     * @throws InvalidArgumentException 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function upcoming()
 | 
					    public function upcoming()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->builder
 | 
					        return $this->builder
 | 
				
			||||||
@ -154,6 +171,10 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
                    ->orderBy('due_date', 'ASC');
 | 
					                    ->orderBy('due_date', 'ASC');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return void 
 | 
				
			||||||
 | 
					     * @throws InvalidArgumentException 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function overdue()
 | 
					    public function overdue()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
					        $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
				
			||||||
@ -165,6 +186,11 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
                ->orderBy('due_date', 'ASC');
 | 
					                ->orderBy('due_date', 'ASC');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param string $client_id 
 | 
				
			||||||
 | 
					     * @return Builder 
 | 
				
			||||||
 | 
					     * @throws InvalidArgumentException 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function payable(string $client_id = '')
 | 
					    public function payable(string $client_id = '')
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (strlen($client_id) == 0) {
 | 
					        if (strlen($client_id) == 0) {
 | 
				
			||||||
@ -222,8 +248,20 @@ class InvoiceFilters extends QueryFilters
 | 
				
			|||||||
        } else {            
 | 
					        } else {            
 | 
				
			||||||
            return $this->builder->company()->with(['invitations.company'], ['documents.company']);
 | 
					            return $this->builder->company()->with(['invitations.company'], ['documents.company']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//            return $this->builder->whereCompanyId(auth()->user()->company()->id);
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param string $filter 
 | 
				
			||||||
 | 
					     * @return Builder 
 | 
				
			||||||
 | 
					     * @throws InvalidArgumentException 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function private_notes($filter = '') :Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->where('private_notes', 'LIKE', '%'.$filter.'%');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -84,12 +84,17 @@ class PaymentFilters extends QueryFilters
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a list of payments that can be matched to bank transactions
 | 
					     * Returns a list of payments that can be matched to bank transactions
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function match_transactions($value = '')
 | 
					    public function match_transactions($value = 'true') :Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($value == 'true')
 | 
					        if($value == 'true'){
 | 
				
			||||||
        {
 | 
					            return $this->builder
 | 
				
			||||||
            return $this->builder->where('is_deleted',0)->whereNull('transaction_id');
 | 
					                        ->where('is_deleted',0)
 | 
				
			||||||
 | 
					                        ->where(function ($query){
 | 
				
			||||||
 | 
					                            $query->whereNull('transaction_id')
 | 
				
			||||||
 | 
					                            ->orWhere("transaction_id","");
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
				
			|||||||
@ -42,20 +42,26 @@ class PurchaseOrderFilters extends QueryFilters
 | 
				
			|||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $po_status = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('draft', $status_parameters)) {
 | 
					        if (in_array('draft', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', PurchaseOrder::STATUS_DRAFT);
 | 
					            $po_status[] = PurchaseOrder::STATUS_DRAFT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('sent', $status_parameters)) {
 | 
					        if (in_array('sent', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', PurchaseOrder::STATUS_SENT);
 | 
					            $po_status[] = PurchaseOrder::STATUS_SENT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('accepted', $status_parameters)) {
 | 
					        if (in_array('accepted', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', PurchaseOrder::STATUS_ACCEPTED);
 | 
					            $po_status[] = PurchaseOrder::STATUS_ACCEPTED;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('cancelled', $status_parameters)) {
 | 
					        if (in_array('cancelled', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', PurchaseOrder::STATUS_CANCELLED);
 | 
					            $po_status[] = PurchaseOrder::STATUS_CANCELLED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(count($status_parameters) >=1) {
 | 
				
			||||||
 | 
					            $this->builder->whereIn('status_id', $status_parameters);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ namespace App\Filters;
 | 
				
			|||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class QueryFilters.
 | 
					 * Class QueryFilters.
 | 
				
			||||||
@ -173,22 +174,30 @@ abstract class QueryFilters
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function created_at($value)
 | 
					    public function created_at($value = '')
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $created_at = $value ? (int) $value : 0;
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $created_at = date('Y-m-d H:i:s', $value);
 | 
					        if($value == '')
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(is_string($created_at)){
 | 
					        try{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $created_at = strtotime(str_replace("/","-",$created_at));
 | 
					            if(is_numeric($value)){
 | 
				
			||||||
 | 
					                $created_at = Carbon::createFromTimestamp((int)$value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					                $created_at = Carbon::parse($value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this->builder->where('created_at', '>=', $created_at);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch(\Exception $e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!$created_at)
 | 
					 | 
				
			||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $this->builder->where('created_at', '>=', $created_at);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function is_deleted($value)
 | 
					    public function is_deleted($value)
 | 
				
			||||||
@ -209,6 +218,15 @@ abstract class QueryFilters
 | 
				
			|||||||
        return $this->builder->where('client_id', $this->decodePrimaryKey($client_id));
 | 
					        return $this->builder->where('client_id', $this->decodePrimaryKey($client_id));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function vendor_id(string $vendor_id = '') :Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($vendor_id) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->where('vendor_id', $this->decodePrimaryKey($vendor_id));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function filter_deleted_clients($value)
 | 
					    public function filter_deleted_clients($value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($value == 'true') {
 | 
					        if ($value == 'true') {
 | 
				
			||||||
@ -226,12 +244,6 @@ abstract class QueryFilters
 | 
				
			|||||||
            return $this->builder->where('is_deleted', 0);
 | 
					            return $this->builder->where('is_deleted', 0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // if($value == 'true'){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //     $this->builder->withTrashed();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -239,6 +251,7 @@ abstract class QueryFilters
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->builder
 | 
					        return $this->builder
 | 
				
			||||||
            ->orWhere($this->with_property, $value)
 | 
					            ->orWhere($this->with_property, $value)
 | 
				
			||||||
            ->orderByRaw("{$this->with_property} = ? DESC", [$value]);
 | 
					            ->orderByRaw("{$this->with_property} = ? DESC", [$value])
 | 
				
			||||||
 | 
					            ->company();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -66,27 +66,40 @@ class QuoteFilters extends QueryFilters
 | 
				
			|||||||
            return $this->builder;
 | 
					            return $this->builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $quote_filters = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('draft', $status_parameters)) {
 | 
					        if (in_array('draft', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Quote::STATUS_DRAFT);
 | 
					            $quote_filters[] = Quote::STATUS_DRAFT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('sent', $status_parameters)) {
 | 
					        if (in_array('sent', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Quote::STATUS_SENT);
 | 
					            $quote_filters[] = Quote::STATUS_SENT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('approved', $status_parameters)) {
 | 
					        if (in_array('approved', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Quote::STATUS_APPROVED);
 | 
					            $quote_filters[] = Quote::STATUS_APPROVED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(count($quote_filters) >=1){
 | 
				
			||||||
 | 
					            $this->builder->whereIn('status_id', $quote_filters);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('expired', $status_parameters)) {
 | 
					        if (in_array('expired', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Quote::STATUS_SENT)
 | 
					            $this->builder->orWhere(function ($query){
 | 
				
			||||||
                          ->where('due_date', '>=', now()->toDateString());
 | 
					                          $query->where('status_id', Quote::STATUS_SENT)
 | 
				
			||||||
 | 
					                          ->company()
 | 
				
			||||||
 | 
					                          ->whereNotNull('due_date')
 | 
				
			||||||
 | 
					                          ->where('due_date', '<=', now()->toDateString());
 | 
				
			||||||
 | 
					                      });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('upcoming', $status_parameters)) {
 | 
					        if (in_array('upcoming', $status_parameters)) {
 | 
				
			||||||
            $this->builder->where('status_id', Quote::STATUS_SENT)
 | 
					            $this->builder->orWhere(function ($query){
 | 
				
			||||||
                          ->where('due_date', '<=', now()->toDateString())
 | 
					                        $query->where('status_id', Quote::STATUS_SENT)
 | 
				
			||||||
 | 
					                          ->company()
 | 
				
			||||||
 | 
					                          ->where('due_date', '>=', now()->toDateString())
 | 
				
			||||||
                          ->orderBy('due_date', 'DESC');
 | 
					                          ->orderBy('due_date', 'DESC');
 | 
				
			||||||
 | 
					                      });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->builder;
 | 
					        return $this->builder;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										129
									
								
								app/Filters/SubscriptionFilters.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								app/Filters/SubscriptionFilters.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Filters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use App\Models\Webhook;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Gate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SubscriptionFilters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class SubscriptionFilters extends QueryFilters
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filter based on search text.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string query filter
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function filter(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return  $this->builder->where(function ($query) use ($filter) {
 | 
				
			||||||
 | 
					            $query->where('name', 'like', '%'.$filter.'%');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the list based on the status
 | 
				
			||||||
 | 
					     * archived, active, deleted.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string filter
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function status(string $filter = '') : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (strlen($filter) == 0) {
 | 
				
			||||||
 | 
					            return $this->builder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $table = 'subscriptions';
 | 
				
			||||||
 | 
					        $filters = explode(',', $filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->where(function ($query) use ($filters, $table) {
 | 
				
			||||||
 | 
					            $query->whereNull($table.'.id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ACTIVE, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhereNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_ARCHIVED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere(function ($query) use ($table) {
 | 
				
			||||||
 | 
					                    $query->whereNotNull($table.'.deleted_at');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (! in_array($table, ['users'])) {
 | 
				
			||||||
 | 
					                        $query->where($table.'.is_deleted', '=', 0);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (in_array(parent::STATUS_DELETED, $filters)) {
 | 
				
			||||||
 | 
					                $query->orWhere($table.'.is_deleted', '=', 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Sorts the list based on $sort.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string sort formatted as column|asc
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sort(string $sort) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $sort_col = explode('|', $sort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->builder->orderBy($sort_col[0], $sort_col[1]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the base query.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param int company_id
 | 
				
			||||||
 | 
					     * @param User $user
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     * @deprecated
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function baseQuery(int $company_id, User $user) : Builder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = DB::table('subscriptions')
 | 
				
			||||||
 | 
					            ->join('companies', 'companies.id', '=', 'subscriptions.company_id')
 | 
				
			||||||
 | 
					            ->where('subscriptions.company_id', '=', $company_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * If the user does not have permissions to view all invoices
 | 
				
			||||||
 | 
					         * limit the user to only the invoices they have created
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (Gate::denies('view-list', Webhook::class)) {
 | 
				
			||||||
 | 
					            $query->where('subscriptions.user_id', '=', $user->id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filters the query by the users company ID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Illuminate\Database\Query\Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function entityFilter()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->builder->company();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -104,7 +104,6 @@ class TokenFilters extends QueryFilters
 | 
				
			|||||||
        $query = DB::table('company_tokens')
 | 
					        $query = DB::table('company_tokens')
 | 
				
			||||||
            ->join('companies', 'companies.id', '=', 'company_tokens.company_id')
 | 
					            ->join('companies', 'companies.id', '=', 'company_tokens.company_id')
 | 
				
			||||||
            ->where('company_tokens.company_id', '=', $company_id)
 | 
					            ->where('company_tokens.company_id', '=', $company_id)
 | 
				
			||||||
            //->whereRaw('(designs.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
                'company_tokens.id',
 | 
					                'company_tokens.id',
 | 
				
			||||||
                'company_tokens.name',
 | 
					                'company_tokens.name',
 | 
				
			||||||
 | 
				
			|||||||
@ -118,7 +118,6 @@ class VendorFilters extends QueryFilters
 | 
				
			|||||||
            ->where('vendors.company_id', '=', $company_id)
 | 
					            ->where('vendors.company_id', '=', $company_id)
 | 
				
			||||||
            ->where('vendor_contacts.is_primary', '=', true)
 | 
					            ->where('vendor_contacts.is_primary', '=', true)
 | 
				
			||||||
            ->where('vendor_contacts.deleted_at', '=', null)
 | 
					            ->where('vendor_contacts.deleted_at', '=', null)
 | 
				
			||||||
            //->whereRaw('(vendors.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
               // DB::raw('COALESCE(vendors.currency_id, companies.currency_id) currency_id'),
 | 
					               // DB::raw('COALESCE(vendors.currency_id, companies.currency_id) currency_id'),
 | 
				
			||||||
                DB::raw('COALESCE(vendors.country_id, companies.country_id) country_id'),
 | 
					                DB::raw('COALESCE(vendors.country_id, companies.country_id) country_id'),
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,6 @@ class WebhookFilters extends QueryFilters
 | 
				
			|||||||
        $query = DB::table('webhooks')
 | 
					        $query = DB::table('webhooks')
 | 
				
			||||||
            ->join('companies', 'companies.id', '=', 'webhooks.company_id')
 | 
					            ->join('companies', 'companies.id', '=', 'webhooks.company_id')
 | 
				
			||||||
            ->where('webhooks.company_id', '=', $company_id)
 | 
					            ->where('webhooks.company_id', '=', $company_id)
 | 
				
			||||||
            //->whereRaw('(designs.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
 | 
					 | 
				
			||||||
            ->select(
 | 
					            ->select(
 | 
				
			||||||
                'webhooks.id',
 | 
					                'webhooks.id',
 | 
				
			||||||
                'webhooks.target_url',
 | 
					                'webhooks.target_url',
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ namespace App\Helpers\Epc;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use BaconQrCode\Renderer\ImageRenderer;
 | 
					use BaconQrCode\Renderer\ImageRenderer;
 | 
				
			||||||
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
 | 
					use BaconQrCode\Renderer\Image\SvgImageBackEnd;
 | 
				
			||||||
@ -35,7 +36,7 @@ class EpcQrGenerator
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(protected Company $company, protected Invoice $invoice, protected float $amount){}
 | 
					    public function __construct(protected Company $company, protected Invoice|RecurringInvoice $invoice, protected float $amount){}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getQrCode()
 | 
					    public function getQrCode()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -87,10 +87,10 @@ class SwissQrGenerator
 | 
				
			|||||||
    $qrBill->setUltimateDebtor(
 | 
					    $qrBill->setUltimateDebtor(
 | 
				
			||||||
        QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
 | 
					        QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
 | 
				
			||||||
            substr($this->client->present()->name(), 0 , 70),
 | 
					            substr($this->client->present()->name(), 0 , 70),
 | 
				
			||||||
            $this->client->address1 ? substr($this->client->address1, 0 , 70) : '_',
 | 
					            $this->client->address1 ? substr($this->client->address1, 0 , 70) : ' ',
 | 
				
			||||||
            $this->client->address2 ? substr($this->client->address2, 0 , 16) : '_',
 | 
					            $this->client->address2 ? substr($this->client->address2, 0 , 16) : ' ',
 | 
				
			||||||
            $this->client->postal_code ? substr($this->client->postal_code, 0, 16) : '_',
 | 
					            $this->client->postal_code ? substr($this->client->postal_code, 0, 16) : ' ',
 | 
				
			||||||
            $this->client->city ? substr($this->client->city, 0, 35) : '_',
 | 
					            $this->client->city ? substr($this->client->city, 0, 35) : ' ',
 | 
				
			||||||
            'CH'
 | 
					            'CH'
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -112,6 +112,7 @@ class ActivityController extends BaseController
 | 
				
			|||||||
                    'purchase_order' => $activity->purchase_order ? $activity->purchase_order : '',
 | 
					                    'purchase_order' => $activity->purchase_order ? $activity->purchase_order : '',
 | 
				
			||||||
                    'subscription' => $activity->subscription ? $activity->subscription : '',
 | 
					                    'subscription' => $activity->subscription ? $activity->subscription : '',
 | 
				
			||||||
                    'vendor_contact' => $activity->vendor_contact ? $activity->vendor_contact : '',
 | 
					                    'vendor_contact' => $activity->vendor_contact ? $activity->vendor_contact : '',
 | 
				
			||||||
 | 
					                    'recurring_expense' => $activity->recurring_expense ? $activity->recurring_expense : '',
 | 
				
			||||||
                ];
 | 
					                ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return array_merge($arr, $activity->toArray());
 | 
					                return array_merge($arr, $activity->toArray());
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ class ContactRegisterController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function register(RegisterRequest $request)
 | 
					    public function register(RegisterRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $request->merge(['company' => $request->company()]);
 | 
					        $request->merge(['company' => $request->company()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client = $this->getClient($request->all());
 | 
					        $client = $this->getClient($request->all());
 | 
				
			||||||
@ -58,7 +59,7 @@ class ContactRegisterController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Auth::guard('contact')->loginUsingId($client_contact->id, true);
 | 
					        Auth::guard('contact')->loginUsingId($client_contact->id, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()->route('client.dashboard');
 | 
					        return redirect()->intended(route('client.dashboard'));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function getClient(array $data)
 | 
					    private function getClient(array $data)
 | 
				
			||||||
@ -66,7 +67,15 @@ class ContactRegisterController extends Controller
 | 
				
			|||||||
        $client = ClientFactory::create($data['company']->id, $data['company']->owner()->id);
 | 
					        $client = ClientFactory::create($data['company']->id, $data['company']->owner()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client->fill($data);
 | 
					        $client->fill($data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client->save();
 | 
					        $client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(isset($data['currency_id'])) {
 | 
				
			||||||
 | 
					            $settings = $client->settings;
 | 
				
			||||||
 | 
					            $settings->currency_id = isset($data['currency_id']) ? $data['currency_id'] : $data['company']->settings->currency_id;
 | 
				
			||||||
 | 
					            $client->settings = $settings;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client->number = $this->getNextClientNumber($client);
 | 
					        $client->number = $this->getNextClientNumber($client);
 | 
				
			||||||
        $client->save();
 | 
					        $client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -984,6 +984,9 @@ class BaseController extends Controller
 | 
				
			|||||||
            //pass report errors bool to front end
 | 
					            //pass report errors bool to front end
 | 
				
			||||||
            $data['report_errors'] = Ninja::isSelfHost() ? $account->report_errors : true;
 | 
					            $data['report_errors'] = Ninja::isSelfHost() ? $account->report_errors : true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //pass whitelabel bool to front end
 | 
				
			||||||
 | 
					            $data['white_label'] = Ninja::isSelfHost() ? $account->isPaid() : false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //pass referral code to front end
 | 
					            //pass referral code to front end
 | 
				
			||||||
            $data['rc'] = request()->has('rc') ? request()->input('rc') : '';
 | 
					            $data['rc'] = request()->has('rc') ? request()->input('rc') : '';
 | 
				
			||||||
            $data['build'] = request()->has('build') ? request()->input('build') : '';
 | 
					            $data['build'] = request()->has('build') ? request()->input('build') : '';
 | 
				
			||||||
 | 
				
			|||||||
@ -52,7 +52,7 @@ class InvoiceController extends Controller
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return Factory|View
 | 
					     * @return Factory|View
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function show(ShowInvoiceRequest $request, Invoice $invoice)
 | 
					    public function show(ShowInvoiceRequest $request, Invoice $invoice, ?string $hash = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        set_time_limit(0);
 | 
					        set_time_limit(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -69,6 +69,7 @@ class InvoiceController extends Controller
 | 
				
			|||||||
            'invoice' => $invoice,
 | 
					            'invoice' => $invoice,
 | 
				
			||||||
            'invitation' => $invitation ?: $invoice->invitations->first(),
 | 
					            'invitation' => $invitation ?: $invoice->invitations->first(),
 | 
				
			||||||
            'key' => $invitation ? $invitation->key : false,
 | 
					            'key' => $invitation ? $invitation->key : false,
 | 
				
			||||||
 | 
					            'hash' => $hash,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($request->query('mode') === 'fullscreen') {
 | 
					        if ($request->query('mode') === 'fullscreen') {
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@ use App\Models\Invoice;
 | 
				
			|||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Models\Subscription;
 | 
					use App\Models\Subscription;
 | 
				
			||||||
use App\Notifications\Ninja\NewAccountNotification;
 | 
					use App\Notifications\Ninja\NewAccountNotification;
 | 
				
			||||||
 | 
					use App\Repositories\RecurringInvoiceRepository;
 | 
				
			||||||
use App\Repositories\SubscriptionRepository;
 | 
					use App\Repositories\SubscriptionRepository;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
@ -147,6 +148,7 @@ class NinjaPlanController extends Controller
 | 
				
			|||||||
            $account->plan_term = 'month';
 | 
					            $account->plan_term = 'month';
 | 
				
			||||||
            $account->plan_started = now();
 | 
					            $account->plan_started = now();
 | 
				
			||||||
            $account->plan_expires = now()->addDays(14);
 | 
					            $account->plan_expires = now()->addDays(14);
 | 
				
			||||||
 | 
					            $account->is_trial=true;
 | 
				
			||||||
            $account->save();
 | 
					            $account->save();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -178,6 +180,15 @@ class NinjaPlanController extends Controller
 | 
				
			|||||||
                 ->increment()
 | 
					                 ->increment()
 | 
				
			||||||
                 ->queue();
 | 
					                 ->queue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $old_recurring = RecurringInvoice::where('company_id', config('ninja.ninja_default_company_id'))->where('client_id', $client->id)->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($old_recurring) {
 | 
				
			||||||
 | 
					            $old_recurring->service()->stop()->save();
 | 
				
			||||||
 | 
					            $old_recurring_repo = new RecurringInvoiceRepository();
 | 
				
			||||||
 | 
					            $old_recurring_repo->archive($old_recurring);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
 | 
					        $ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
 | 
				
			||||||
        $ninja_company->notification(new NewAccountNotification($subscription->company->account, $client))->ninja();
 | 
					        $ninja_company->notification(new NewAccountNotification($subscription->company->account, $client))->ninja();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -206,7 +217,7 @@ class NinjaPlanController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if ($account) {
 | 
					            if ($account) {
 | 
				
			||||||
                //offer the option to have a free trial
 | 
					                //offer the option to have a free trial
 | 
				
			||||||
                if (! $account->trial_started && ! $account->plan) {
 | 
					                if (!$account->is_trial) {
 | 
				
			||||||
                    return $this->trial();
 | 
					                    return $this->trial();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -148,8 +148,17 @@ class PaymentController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $payment = $payment->service()->applyCredits($payment_hash)->save();
 | 
					        $payment = $payment->service()->applyCredits($payment_hash)->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event('eloquent.created: App\Models\Payment', $payment);
 | 
					        event('eloquent.created: App\Models\Payment', $payment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($invoices->sum('balance') > 0){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $invoice = $invoices->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return redirect()->route('client.invoice.show', ['invoice' => $invoice->hashed_id, 'hash' => $request->input('hash')]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (property_exists($payment_hash->data, 'billing_context')) {
 | 
					        if (property_exists($payment_hash->data, 'billing_context')) {
 | 
				
			||||||
            $billing_subscription = \App\Models\Subscription::find($payment_hash->data->billing_context->subscription_id);
 | 
					            $billing_subscription = \App\Models\Subscription::find($payment_hash->data->billing_context->subscription_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
namespace App\Http\Controllers\ClientPortal;
 | 
					namespace App\Http\Controllers\ClientPortal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Http\Controllers\Controller;
 | 
					use App\Http\Controllers\Controller;
 | 
				
			||||||
 | 
					use App\Http\Requests\ClientPortal\RecurringInvoices\ShowRecurringInvoiceRequest;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
@ -38,4 +39,20 @@ class SubscriptionController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return render('subscriptions.index');
 | 
					        return render('subscriptions.index');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Display the recurring invoice.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ShowRecurringInvoiceRequest $request
 | 
				
			||||||
 | 
					     * @param RecurringInvoice $recurring_invoice
 | 
				
			||||||
 | 
					     * @return Factory|View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function show(ShowRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->render('subscriptions.show', [
 | 
				
			||||||
 | 
					            'invoice' => $recurring_invoice->load('invoices','subscription'),
 | 
				
			||||||
 | 
					            'subscription' => $recurring_invoice->subscription
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -31,9 +31,12 @@ class SubscriptionPlanSwitchController extends Controller
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index(ShowPlanSwitchRequest $request, RecurringInvoice $recurring_invoice, Subscription $target)
 | 
					    public function index(ShowPlanSwitchRequest $request, RecurringInvoice $recurring_invoice, Subscription $target)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $amount = $recurring_invoice->subscription
 | 
					        $amount = $recurring_invoice->subscription
 | 
				
			||||||
                                    ->service()
 | 
					                                    ->service()
 | 
				
			||||||
                                    ->calculateUpgradePrice($recurring_invoice, $target);
 | 
					                                    ->calculateUpgradePriceV2($recurring_invoice, $target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nlog("payment amount = {$amount}");
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * Null value here is a proxy for
 | 
					         * Null value here is a proxy for
 | 
				
			||||||
         * denying the user a change plan option
 | 
					         * denying the user a change plan option
 | 
				
			||||||
@ -42,11 +45,14 @@ class SubscriptionPlanSwitchController extends Controller
 | 
				
			|||||||
            render('subscriptions.denied');
 | 
					            render('subscriptions.denied');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $amount = max(0,$amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return render('subscriptions.switch', [
 | 
					        return render('subscriptions.switch', [
 | 
				
			||||||
            'subscription' => $recurring_invoice->subscription,
 | 
					            'subscription' => $recurring_invoice->subscription,
 | 
				
			||||||
            'recurring_invoice' => $recurring_invoice,
 | 
					            'recurring_invoice' => $recurring_invoice,
 | 
				
			||||||
            'target' => $target,
 | 
					            'target' => $target,
 | 
				
			||||||
            'amount' => $amount,
 | 
					            'amount' => $amount,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -53,6 +53,16 @@ class SubscriptionPurchaseController extends Controller
 | 
				
			|||||||
            $this->setLocale($request->query('locale'));
 | 
					            $this->setLocale($request->query('locale'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!auth()->guard('contact')->check() && $subscription->registration_required && $subscription->company->client_can_register) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            session()->put('url.intended', route('client.subscription.upgrade',['subscription' => $subscription->hashed_id]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return redirect()->route('client.register', ['company_key' => $subscription->company->company_key]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        elseif(!auth()->guard('contact')->check() && $subscription->registration_required && ! $subscription->company->client_can_register) {
 | 
				
			||||||
 | 
					            return render('generic.subscription_blocked', ['account' => $subscription->company->account, 'company' => $subscription->company]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return view('billing-portal.purchasev2', [
 | 
					        return view('billing-portal.purchasev2', [
 | 
				
			||||||
            'subscription' => $subscription,
 | 
					            'subscription' => $subscription,
 | 
				
			||||||
            'hash' => Str::uuid()->toString(),
 | 
					            'hash' => Str::uuid()->toString(),
 | 
				
			||||||
 | 
				
			|||||||
@ -521,7 +521,7 @@ class CompanyController extends BaseController
 | 
				
			|||||||
            $nmo->company = $other_company;
 | 
					            $nmo->company = $other_company;
 | 
				
			||||||
            $nmo->settings = $other_company->settings;
 | 
					            $nmo->settings = $other_company->settings;
 | 
				
			||||||
            $nmo->to_user = auth()->user();
 | 
					            $nmo->to_user = auth()->user();
 | 
				
			||||||
            NinjaMailerJob::dispatch($nmo, true);
 | 
					            (new NinjaMailerJob($nmo, true))->handle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $company->delete();
 | 
					            $company->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,12 +12,14 @@
 | 
				
			|||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Factory\ExpenseCategoryFactory;
 | 
					use App\Factory\ExpenseCategoryFactory;
 | 
				
			||||||
 | 
					use App\Filters\ExpenseCategoryFilters;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\CreateExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\CreateExpenseCategoryRequest;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\DestroyExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\DestroyExpenseCategoryRequest;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\EditExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\EditExpenseCategoryRequest;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\ShowExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\ShowExpenseCategoryRequest;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\StoreExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\StoreExpenseCategoryRequest;
 | 
				
			||||||
use App\Http\Requests\ExpenseCategory\UpdateExpenseCategoryRequest;
 | 
					use App\Http\Requests\ExpenseCategory\UpdateExpenseCategoryRequest;
 | 
				
			||||||
 | 
					use App\Models\Expense;
 | 
				
			||||||
use App\Models\ExpenseCategory;
 | 
					use App\Models\ExpenseCategory;
 | 
				
			||||||
use App\Repositories\BaseRepository;
 | 
					use App\Repositories\BaseRepository;
 | 
				
			||||||
use App\Transformers\ExpenseCategoryTransformer;
 | 
					use App\Transformers\ExpenseCategoryTransformer;
 | 
				
			||||||
@ -79,13 +81,15 @@ class ExpenseCategoryController extends BaseController
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return Response
 | 
					     * @return Response
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index()
 | 
					    public function index(ExpenseCategoryFilters $filters)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $expense_categories = ExpenseCategory::scope();
 | 
					        $expense_categories = ExpenseCategory::filter($filters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->listResponse($expense_categories);
 | 
					        return $this->listResponse($expense_categories);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Show the form for creating a new resource.
 | 
					     * Show the form for creating a new resource.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -131,11 +135,45 @@ class ExpenseCategoryController extends BaseController
 | 
				
			|||||||
        return $this->itemResponse($expense_category);
 | 
					        return $this->itemResponse($expense_category);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Store a newly created resource in storage.
 | 
					     * Store a newly created resource in storage.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param StoreExpenseCategoryRequest $request
 | 
					     * @param StoreInvoiceRequest $request  The request
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
     * @return Response
 | 
					     * @return Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/expense_categories",
 | 
				
			||||||
 | 
					     *      operationId="storeExpenseCategory",
 | 
				
			||||||
 | 
					     *      tags={"expense_categories"},
 | 
				
			||||||
 | 
					     *      summary="Adds a expense category",
 | 
				
			||||||
 | 
					     *      description="Adds an expense category to the system",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns the saved invoice object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ExpenseCategory"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store(StoreExpenseCategoryRequest $request)
 | 
					    public function store(StoreExpenseCategoryRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,6 @@ namespace App\Http\Controllers;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Http\Requests\Import\ImportRequest;
 | 
					use App\Http\Requests\Import\ImportRequest;
 | 
				
			||||||
use App\Http\Requests\Import\PreImportRequest;
 | 
					use App\Http\Requests\Import\PreImportRequest;
 | 
				
			||||||
use App\Jobs\Import\CSVImport;
 | 
					 | 
				
			||||||
use App\Jobs\Import\CSVIngest;
 | 
					use App\Jobs\Import\CSVIngest;
 | 
				
			||||||
use Illuminate\Http\UploadedFile;
 | 
					use Illuminate\Http\UploadedFile;
 | 
				
			||||||
use Illuminate\Support\Facades\Cache;
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
@ -162,7 +161,7 @@ class ImportController extends Controller
 | 
				
			|||||||
    public function detectDelimiter($csvfile)
 | 
					    public function detectDelimiter($csvfile)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $delimiters = array(',', '.', ';');
 | 
					        $delimiters = array(',', '.', ';');
 | 
				
			||||||
        $bestDelimiter = false;
 | 
					        $bestDelimiter = ' ';
 | 
				
			||||||
        $count = 0;
 | 
					        $count = 0;
 | 
				
			||||||
        foreach ($delimiters as $delimiter)
 | 
					        foreach ($delimiters as $delimiter)
 | 
				
			||||||
            if (substr_count($csvfile, $delimiter) > $count) {
 | 
					            if (substr_count($csvfile, $delimiter) > $count) {
 | 
				
			||||||
 | 
				
			|||||||
@ -781,7 +781,8 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
            case 'email':
 | 
					            case 'email':
 | 
				
			||||||
                //check query parameter for email_type and set the template else use calculateTemplate
 | 
					                //check query parameter for email_type and set the template else use calculateTemplate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (request()->has('email_type') && in_array(request()->input('email_type'), ['reminder1', 'reminder2', 'reminder3', 'reminder_endless', 'custom1', 'custom2', 'custom3'])) {
 | 
					                // if (request()->has('email_type') && in_array(request()->input('email_type'), ['reminder1', 'reminder2', 'reminder3', 'reminder_endless', 'custom1', 'custom2', 'custom3'])) {
 | 
				
			||||||
 | 
					                if (request()->has('email_type') && property_exists($invoice->company->settings, request()->input('email_type'))) {
 | 
				
			||||||
                    $this->reminder_template = $invoice->client->getSetting(request()->input('email_type'));
 | 
					                    $this->reminder_template = $invoice->client->getSetting(request()->input('email_type'));
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->reminder_template = $invoice->calculateTemplate('invoice');
 | 
					                    $this->reminder_template = $invoice->calculateTemplate('invoice');
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,10 @@ class PaymentWebhookController extends Controller
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public function __invoke(PaymentWebhookRequest $request)
 | 
					    public function __invoke(PaymentWebhookRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        //return early if we cannot resolve the company gateway
 | 
				
			||||||
 | 
					        if(!$request->getCompanyGateway())
 | 
				
			||||||
 | 
					            return response()->json([], 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $request
 | 
					        return $request
 | 
				
			||||||
            ->getCompanyGateway()
 | 
					            ->getCompanyGateway()
 | 
				
			||||||
            ->driver()
 | 
					            ->driver()
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ class PostMarkController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function webhook(Request $request)
 | 
					    public function webhook(Request $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('postmark.secret')) {
 | 
					        if ($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('services.postmark.token')) {
 | 
				
			||||||
            ProcessPostmarkWebhook::dispatch($request->all());
 | 
					            ProcessPostmarkWebhook::dispatch($request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json(['message' => 'Success'], 200);
 | 
					            return response()->json(['message' => 'Success'], 200);
 | 
				
			||||||
 | 
				
			|||||||
@ -198,7 +198,7 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
        event(new PurchaseOrderWasCreated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
					        event(new PurchaseOrderWasCreated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($purchase_order);
 | 
					        return $this->itemResponse($purchase_order->fresh());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Display the specified resource.
 | 
					     * Display the specified resource.
 | 
				
			||||||
@ -502,7 +502,6 @@ 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) {
 | 
				
			||||||
                if (auth()->user()->cannot('view', $purchase_order)) {
 | 
					                if (auth()->user()->cannot('view', $purchase_order)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Controllers\Reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Export\CSV\ProductExport;
 | 
				
			||||||
 | 
					use App\Export\CSV\ProductSalesExport;
 | 
				
			||||||
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
 | 
					use App\Http\Requests\Report\GenericReportRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Report\ProductSalesReportRequest;
 | 
				
			||||||
 | 
					use App\Jobs\Report\SendToAdmin;
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProductSalesReportController extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private string $filename = 'product_sales.csv';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::__construct();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/reports/product_sales",
 | 
				
			||||||
 | 
					     *      operationId="getProductSalesReport",
 | 
				
			||||||
 | 
					     *      tags={"reports"},
 | 
				
			||||||
 | 
					     *      summary="Product Salesreports",
 | 
				
			||||||
 | 
					     *      description="Export product sales reports",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\RequestBody(
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/GenericReportSchema")
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="success",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __invoke(ProductSalesReportRequest $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($request->has('send_email') && $request->get('send_email')) {
 | 
				
			||||||
 | 
					            SendToAdmin::dispatch(auth()->user()->company(), $request->all(), ProductSalesExport::class, $this->filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response()->json(['message' => 'working...'], 200);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // expect a list of visible fields, or use the default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $export = new ProductSalesExport(auth()->user()->company(), $request->all());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $csv = $export->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $headers = [
 | 
				
			||||||
 | 
					            'Content-Disposition' => 'attachment',
 | 
				
			||||||
 | 
					            'Content-Type' => 'text/csv',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response()->streamDownload(function () use ($csv) {
 | 
				
			||||||
 | 
					            echo $csv;
 | 
				
			||||||
 | 
					        }, $this->filename, $headers);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,4 +1,13 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ namespace App\Http\Controllers;
 | 
				
			|||||||
use App\Events\Subscription\SubscriptionWasCreated;
 | 
					use App\Events\Subscription\SubscriptionWasCreated;
 | 
				
			||||||
use App\Events\Subscription\SubscriptionWasUpdated;
 | 
					use App\Events\Subscription\SubscriptionWasUpdated;
 | 
				
			||||||
use App\Factory\SubscriptionFactory;
 | 
					use App\Factory\SubscriptionFactory;
 | 
				
			||||||
 | 
					use App\Filters\SubscriptionFilters;
 | 
				
			||||||
use App\Http\Requests\Subscription\CreateSubscriptionRequest;
 | 
					use App\Http\Requests\Subscription\CreateSubscriptionRequest;
 | 
				
			||||||
use App\Http\Requests\Subscription\DestroySubscriptionRequest;
 | 
					use App\Http\Requests\Subscription\DestroySubscriptionRequest;
 | 
				
			||||||
use App\Http\Requests\Subscription\EditSubscriptionRequest;
 | 
					use App\Http\Requests\Subscription\EditSubscriptionRequest;
 | 
				
			||||||
@ -80,9 +81,9 @@ class SubscriptionController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index(): \Illuminate\Http\Response
 | 
					    public function index(SubscriptionFilters $filters): \Illuminate\Http\Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $subscriptions = Subscription::query()->company();
 | 
					        $subscriptions = Subscription::filter($filters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->listResponse($subscriptions);
 | 
					        return $this->listResponse($subscriptions);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,37 +11,40 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Http\Requests\TaskScheduler\CreateScheduledTaskRequest;
 | 
					use App\Factory\SchedulerFactory;
 | 
				
			||||||
use App\Http\Requests\TaskScheduler\UpdateScheduleRequest;
 | 
					use App\Http\Requests\TaskScheduler\CreateSchedulerRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\TaskScheduler\ShowSchedulerRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\TaskScheduler\StoreSchedulerRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\TaskScheduler\UpdateSchedulerRequest;
 | 
				
			||||||
 | 
					use App\Http\Requests\Task\DestroySchedulerRequest;
 | 
				
			||||||
use App\Jobs\Ninja\TaskScheduler;
 | 
					use App\Jobs\Ninja\TaskScheduler;
 | 
				
			||||||
use App\Jobs\Report\ProfitAndLoss;
 | 
					use App\Jobs\Report\ProfitAndLoss;
 | 
				
			||||||
use App\Models\Scheduler;
 | 
					use App\Models\Scheduler;
 | 
				
			||||||
use App\Repositories\TaskSchedulerRepository;
 | 
					use App\Repositories\SchedulerRepository;
 | 
				
			||||||
use App\Transformers\TaskSchedulerTransformer;
 | 
					use App\Transformers\SchedulerTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Model;
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
use Symfony\Component\HttpFoundation\Request;
 | 
					use Symfony\Component\HttpFoundation\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TaskSchedulerController extends BaseController
 | 
					class TaskSchedulerController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $entity_type = Scheduler::class;
 | 
					    protected $entity_type = Scheduler::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $entity_transformer = TaskSchedulerTransformer::class;
 | 
					    protected $entity_transformer = SchedulerTransformer::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected TaskSchedulerRepository $scheduler_repository;
 | 
					    public function __construct(protected SchedulerRepository $scheduler_repository)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct(TaskSchedulerRepository $scheduler_repository)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::__construct();
 | 
					        parent::__construct();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->scheduler_repository = $scheduler_repository;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @OA\GET(
 | 
					     * @OA\GET(
 | 
				
			||||||
     *      path="/api/v1/task_scheduler/",
 | 
					     *      path="/api/v1/task_schedulers/",
 | 
				
			||||||
     *      operationId="getTaskSchedulers",
 | 
					     *      operationId="getTaskSchedulers",
 | 
				
			||||||
     *      tags={"task_scheduler"},
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
     *      summary="Task Scheduler Index",
 | 
					     *      summary="Task Scheduler Index",
 | 
				
			||||||
     *      description="Get all schedulers with associated jobs",
 | 
					     *      description="Get all schedulers with associated jobs",
 | 
				
			||||||
     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
@ -67,11 +70,57 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
        return $this->listResponse($schedulers);
 | 
					        return $this->listResponse($schedulers);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Show the form for creating a new resource.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param CreateSchedulerRequest $request  The request
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/invoices/task_schedulers",
 | 
				
			||||||
 | 
					     *      operationId="getTaskScheduler",
 | 
				
			||||||
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
 | 
					     *      summary="Gets a new blank scheduler object",
 | 
				
			||||||
 | 
					     *      description="Returns a blank object with default values",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/include"),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="A blank scheduler object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/TaskSchedulerSchema"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function create(CreateSchedulerRequest $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $scheduler = SchedulerFactory::create(auth()->user()->company()->id, auth()->user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->itemResponse($scheduler);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @OA\Post(
 | 
					     * @OA\Post(
 | 
				
			||||||
     *      path="/api/v1/task_scheduler/",
 | 
					     *      path="/api/v1/task_schedulers/",
 | 
				
			||||||
     *      operationId="createTaskScheduler",
 | 
					     *      operationId="createTaskScheduler",
 | 
				
			||||||
     *      tags={"task_scheduler"},
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
     *      summary="Create task scheduler with job ",
 | 
					     *      summary="Create task scheduler with job ",
 | 
				
			||||||
     *      description="Create task scheduler with a job (action(job) request should be sent via request also. Example: We want client report to be job which will be run
 | 
					     *      description="Create task scheduler with a job (action(job) request should be sent via request also. Example: We want client report to be job which will be run
 | 
				
			||||||
     * multiple times, we should send the same parameters in the request as we would send if we wanted to get report, see example",
 | 
					     * multiple times, we should send the same parameters in the request as we would send if we wanted to get report, see example",
 | 
				
			||||||
@ -100,19 +149,18 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store(CreateScheduledTaskRequest $request)
 | 
					    public function store(StoreSchedulerRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $scheduler = new Scheduler();
 | 
					        $scheduler = $this->scheduler_repository->save($request->all(), SchedulerFactory::create(auth()->user()->company()->id, auth()->user()->id));
 | 
				
			||||||
        $scheduler->service()->store($scheduler, $request);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($scheduler);
 | 
					        return $this->itemResponse($scheduler);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @OA\GET(
 | 
					     * @OA\GET(
 | 
				
			||||||
     *      path="/api/v1/task_scheduler/{id}",
 | 
					     *      path="/api/v1/task_schedulers/{id}",
 | 
				
			||||||
     *      operationId="showTaskScheduler",
 | 
					     *      operationId="showTaskScheduler",
 | 
				
			||||||
     *      tags={"task_scheduler"},
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
     *      summary="Show given scheduler",
 | 
					     *      summary="Show given scheduler",
 | 
				
			||||||
     *      description="Get scheduler with associated job",
 | 
					     *      description="Get scheduler with associated job",
 | 
				
			||||||
     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
@ -142,16 +190,16 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function show(Scheduler $scheduler)
 | 
					    public function show(ShowSchedulerRequest $request, Scheduler $scheduler)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->itemResponse($scheduler);
 | 
					        return $this->itemResponse($scheduler);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @OA\PUT(
 | 
					     * @OA\PUT(
 | 
				
			||||||
     *      path="/api/v1/task_scheduler/{id}",
 | 
					     *      path="/api/v1/task_schedulers/{id}",
 | 
				
			||||||
     *      operationId="updateTaskScheduler",
 | 
					     *      operationId="updateTaskScheduler",
 | 
				
			||||||
     *      tags={"task_scheduler"},
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
     *      summary="Update task scheduler ",
 | 
					     *      summary="Update task scheduler ",
 | 
				
			||||||
     *      description="Update task scheduler",
 | 
					     *      description="Update task scheduler",
 | 
				
			||||||
     * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
					     * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
@ -168,7 +216,7 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
     *          ),
 | 
					     *          ),
 | 
				
			||||||
     *      ),     * @OA\RequestBody(
 | 
					     *      ),     * @OA\RequestBody(
 | 
				
			||||||
     *          required=true,
 | 
					     *          required=true,
 | 
				
			||||||
     *          @OA\JsonContent(ref="#/components/schemas/UpdateTaskSchedulerSchema")
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/TaskSchedulerSchema")
 | 
				
			||||||
     *      ),
 | 
					     *      ),
 | 
				
			||||||
     * @OA\Response(
 | 
					     * @OA\Response(
 | 
				
			||||||
     *          response=200,
 | 
					     *          response=200,
 | 
				
			||||||
@ -189,18 +237,18 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function update(Scheduler $scheduler, UpdateScheduleRequest $request)
 | 
					    public function update(UpdateSchedulerRequest $request, Scheduler $scheduler)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $scheduler->service()->update($scheduler, $request);
 | 
					        $this->scheduler_repository->save($request->all(), $scheduler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($scheduler);
 | 
					        return $this->itemResponse($scheduler);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @OA\DELETE(
 | 
					     * @OA\DELETE(
 | 
				
			||||||
     *      path="/api/v1/task_scheduler/{id}",
 | 
					     *      path="/api/v1/task_schedulers/{id}",
 | 
				
			||||||
     *      operationId="destroyTaskScheduler",
 | 
					     *      operationId="destroyTaskScheduler",
 | 
				
			||||||
     *      tags={"task_scheduler"},
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
     *      summary="Destroy Task Scheduler",
 | 
					     *      summary="Destroy Task Scheduler",
 | 
				
			||||||
     *      description="Destroy task scheduler and its associated job",
 | 
					     *      description="Destroy task scheduler and its associated job",
 | 
				
			||||||
     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
@ -230,10 +278,83 @@ class TaskSchedulerController extends BaseController
 | 
				
			|||||||
     *       ),
 | 
					     *       ),
 | 
				
			||||||
     *     )
 | 
					     *     )
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function destroy(Scheduler $scheduler)
 | 
					    public function destroy(DestroySchedulerRequest $request, Scheduler $scheduler)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->scheduler_repository->delete($scheduler);
 | 
					        $this->scheduler_repository->delete($scheduler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($scheduler->fresh());
 | 
					        return $this->itemResponse($scheduler->fresh());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Perform bulk actions on the list view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Response
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/task_schedulers/bulk",
 | 
				
			||||||
 | 
					     *      operationId="bulkTaskSchedulerActions",
 | 
				
			||||||
 | 
					     *      tags={"task_schedulers"},
 | 
				
			||||||
 | 
					     *      summary="Performs bulk actions on an array of task_schedulers",
 | 
				
			||||||
 | 
					     *      description="",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/index"),
 | 
				
			||||||
 | 
					     *      @OA\RequestBody(
 | 
				
			||||||
 | 
					     *         description="array of ids",
 | 
				
			||||||
 | 
					     *         required=true,
 | 
				
			||||||
 | 
					     *         @OA\MediaType(
 | 
				
			||||||
 | 
					     *             mediaType="application/json",
 | 
				
			||||||
 | 
					     *             @OA\Schema(
 | 
				
			||||||
 | 
					     *                 type="array",
 | 
				
			||||||
 | 
					     *                 @OA\Items(
 | 
				
			||||||
 | 
					     *                     type="integer",
 | 
				
			||||||
 | 
					     *                     description="Array of hashed IDs to be bulk 'actioned",
 | 
				
			||||||
 | 
					     *                     example="[0,1,2,3]",
 | 
				
			||||||
 | 
					     *                 ),
 | 
				
			||||||
 | 
					     *             )
 | 
				
			||||||
 | 
					     *         )
 | 
				
			||||||
 | 
					     *     ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="The TaskSchedule response",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/TaskScheduleSchema"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function bulk()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $action = request()->input('action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!in_array($action, ['archive', 'restore', 'delete']))
 | 
				
			||||||
 | 
					            return response()->json(['message' => 'Bulk action does not exist'], 400);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ids = request()->input('ids');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $task_schedulers = Scheduler::withTrashed()->find($this->transformKeys($ids));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $task_schedulers->each(function ($task_scheduler, $key) use ($action) {
 | 
				
			||||||
 | 
					            if (auth()->user()->can('edit', $task_scheduler)) {
 | 
				
			||||||
 | 
					                $this->scheduler_repository->{$action}($task_scheduler);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->listResponse(Scheduler::withTrashed()->whereIn('id', $this->transformKeys($ids)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -174,6 +174,8 @@ class BillingPortalPurchase extends Component
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public $company;
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Campaign reference.
 | 
					     * Campaign reference.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -183,7 +185,11 @@ class BillingPortalPurchase extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->subscription = Subscription::with('company')->find($this->subscription);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = $this->subscription->company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->quantity = 1;
 | 
					        $this->quantity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -196,6 +202,12 @@ class BillingPortalPurchase extends Component
 | 
				
			|||||||
        elseif(strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
 | 
					        elseif(strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
 | 
				
			||||||
            $this->price = $this->subscription->promo_price;
 | 
					            $this->price = $this->subscription->promo_price;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Leave this here, otherwise a logged in user will need to reauth... painfully */
 | 
				
			||||||
 | 
					        if(Auth::guard('contact')->check()){
 | 
				
			||||||
 | 
					            return $this->getPaymentMethods(auth()->guard('contact')->user());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -225,10 +237,10 @@ class BillingPortalPurchase extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->steps['existing_user'] = false;
 | 
					        $this->steps['existing_user'] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $contact = $this->createBlankClient();
 | 
					        $this->contact = $this->createBlankClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($contact && $contact instanceof ClientContact) {
 | 
					        if ($this->contact && $this->contact instanceof ClientContact) {
 | 
				
			||||||
            $this->getPaymentMethods($contact);
 | 
					            $this->getPaymentMethods($this->contact);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -265,9 +277,6 @@ class BillingPortalPurchase extends Component
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// nlog($this->subscription->group_settings->settings);
 | 
					 | 
				
			||||||
// nlog($this->subscription->group_settings->settings->currency_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(array_key_exists('currency_id', $this->request_data)) {
 | 
					        if(array_key_exists('currency_id', $this->request_data)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $currency = Cache::get('currencies')->filter(function ($item){
 | 
					            $currency = Cache::get('currencies')->filter(function ($item){
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ use App\DataMapper\ClientSettings;
 | 
				
			|||||||
use App\Factory\ClientFactory;
 | 
					use App\Factory\ClientFactory;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
					use App\Jobs\Mail\NinjaMailerJob;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
					use App\Jobs\Mail\NinjaMailerObject;
 | 
				
			||||||
 | 
					use App\Jobs\Subscription\CleanStaleInvoiceOrder;
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Mail\ContactPasswordlessLogin;
 | 
					use App\Mail\ContactPasswordlessLogin;
 | 
				
			||||||
use App\Mail\Subscription\OtpCode;
 | 
					use App\Mail\Subscription\OtpCode;
 | 
				
			||||||
@ -120,7 +121,7 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @var array
 | 
					     * @var array
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public $request_data;
 | 
					    public $request_data = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Instance of company.
 | 
					     * Instance of company.
 | 
				
			||||||
@ -129,6 +130,14 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public $company;
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Instance of company.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Campaign reference.
 | 
					     * Campaign reference.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -151,10 +160,23 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
    public $valid_coupon = false;
 | 
					    public $valid_coupon = false;
 | 
				
			||||||
    public $payable_invoices = [];
 | 
					    public $payable_invoices = [];
 | 
				
			||||||
    public $payment_confirmed = false;
 | 
					    public $payment_confirmed = false;
 | 
				
			||||||
 | 
					    public $is_eligible = true;
 | 
				
			||||||
 | 
					    public $not_eligible_message = '';
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->subscription = Subscription::with('company')->find($this->subscription);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = $this->subscription->company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(auth()->guard('contact')->check()){
 | 
				
			||||||
 | 
					            $this->email = auth()->guard('contact')->user()->email;
 | 
				
			||||||
 | 
					            $this->contact = auth()->guard('contact')->user();
 | 
				
			||||||
 | 
					            $this->authenticated = true;
 | 
				
			||||||
 | 
					            $this->payment_started = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->discount = 0;
 | 
					        $this->discount = 0;
 | 
				
			||||||
        $this->sub_total = 0;
 | 
					        $this->sub_total = 0;
 | 
				
			||||||
@ -177,7 +199,7 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
            $this->coupon = request()->query('coupon');
 | 
					            $this->coupon = request()->query('coupon');
 | 
				
			||||||
            $this->handleCoupon();
 | 
					            $this->handleCoupon();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elseif(strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
 | 
					        elseif(isset($this->subscription->promo_code) && strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
 | 
				
			||||||
            $this->price = $this->subscription->promo_price; 
 | 
					            $this->price = $this->subscription->promo_price; 
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -224,6 +246,8 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function resetEmail()
 | 
					    public function resetEmail()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->resetErrorBag('login');
 | 
				
			||||||
 | 
					        $this->resetValidation('login');  
 | 
				
			||||||
        $this->email = null;
 | 
					        $this->email = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -402,7 +426,6 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -488,9 +511,20 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return void
 | 
					     * @return void
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function handleBeforePaymentEvents() :void
 | 
					    public function handleBeforePaymentEvents() :self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $eligibility_check = $this->subscription->service()->isEligible($this->contact);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(is_array($eligibility_check) && $eligibility_check['message'] != 'Success'){
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $this->is_eligible = false;
 | 
				
			||||||
 | 
					            $this->not_eligible_message = $eligibility_check['message'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'client_id' => $this->contact->client->id,
 | 
					            'client_id' => $this->contact->client->id,
 | 
				
			||||||
            'date' => now()->format('Y-m-d'),
 | 
					            'date' => now()->format('Y-m-d'),
 | 
				
			||||||
@ -500,19 +534,9 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
            ]],
 | 
					            ]],
 | 
				
			||||||
            'user_input_promo_code' => $this->coupon,
 | 
					            'user_input_promo_code' => $this->coupon,
 | 
				
			||||||
            'coupon' => empty($this->subscription->promo_code) ? '' : $this->coupon,
 | 
					            'coupon' => empty($this->subscription->promo_code) ? '' : $this->coupon,
 | 
				
			||||||
            // 'quantity' => $this->quantity,
 | 
					
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $is_eligible = $this->subscription->service()->isEligible($this->contact);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // if (is_array($is_eligible) && $is_eligible['message'] != 'Success') {
 | 
					 | 
				
			||||||
        //     $this->steps['not_eligible'] = true;
 | 
					 | 
				
			||||||
        //     $this->steps['not_eligible_message'] = $is_eligible['message'];
 | 
					 | 
				
			||||||
        //     $this->steps['show_loading_bar'] = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //     return;
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->invoice = $this->subscription
 | 
					        $this->invoice = $this->subscription
 | 
				
			||||||
            ->service()
 | 
					            ->service()
 | 
				
			||||||
            ->createInvoiceV2($this->bundle, $this->contact->client_id, $this->valid_coupon)
 | 
					            ->createInvoiceV2($this->bundle, $this->contact->client_id, $this->valid_coupon)
 | 
				
			||||||
@ -533,9 +557,21 @@ class BillingPortalPurchasev2 extends Component
 | 
				
			|||||||
        ], now()->addMinutes(60));
 | 
					        ], now()->addMinutes(60));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->emit('beforePaymentEventsCompleted');
 | 
					        $this->emit('beforePaymentEventsCompleted');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function handleTrial()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->subscription->service()->startTrial([
 | 
				
			||||||
 | 
					            'email' => $this->email ?? $this->contact->email,
 | 
				
			||||||
 | 
					            'quantity' => $this->quantity,
 | 
				
			||||||
 | 
					            'contact_id' => $this->contact->id,
 | 
				
			||||||
 | 
					            'client_id' => $this->contact->client->id,
 | 
				
			||||||
 | 
					            'bundle' => $this->bundle,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
namespace App\Http\Livewire;
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Credit;
 | 
					use App\Models\Credit;
 | 
				
			||||||
use App\Utils\Traits\WithSorting;
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
@ -23,26 +24,31 @@ class CreditsTable extends Component
 | 
				
			|||||||
    use WithPagination;
 | 
					    use WithPagination;
 | 
				
			||||||
    use WithSorting;
 | 
					    use WithSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int $company_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = Company::find($this->company_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $query = Credit::query()
 | 
					        $query = Credit::query()
 | 
				
			||||||
            ->where('client_id', auth()->guard('contact')->user()->client_id)
 | 
					 | 
				
			||||||
            ->where('company_id', $this->company->id)
 | 
					            ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					            ->where('client_id', auth()->guard('contact')->user()->client_id)
 | 
				
			||||||
            ->where('status_id', '<>', Credit::STATUS_DRAFT)
 | 
					            ->where('status_id', '<>', Credit::STATUS_DRAFT)
 | 
				
			||||||
            ->where('is_deleted', 0)
 | 
					            ->where('is_deleted', 0)
 | 
				
			||||||
            ->where(function ($query) {
 | 
					            ->where(function ($query) {
 | 
				
			||||||
                $query->whereDate('due_date', '>=', now())
 | 
					                $query->whereDate('due_date', '>=', now())
 | 
				
			||||||
                      ->orWhereNull('due_date');
 | 
					                      ->orWhereNull('due_date');
 | 
				
			||||||
                //->orWhere('due_date', '=', '');
 | 
					 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
 | 
					            ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
 | 
				
			||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@ namespace App\Http\Livewire;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Credit;
 | 
					use App\Models\Credit;
 | 
				
			||||||
use App\Models\Document;
 | 
					use App\Models\Document;
 | 
				
			||||||
use App\Models\Expense;
 | 
					use App\Models\Expense;
 | 
				
			||||||
@ -31,21 +32,27 @@ class DocumentsTable extends Component
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use WithPagination, WithSorting;
 | 
					    use WithPagination, WithSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $client;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public Client $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public int $client_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public string $tab = 'documents';
 | 
					    public string $tab = 'documents';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $query;
 | 
					    protected $query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount($client)
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->client = $client;
 | 
					        $this->client = Client::with('company')->find($this->client_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = $this->client->company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->query = $this->documents();
 | 
					        $this->query = $this->documents();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
namespace App\Http\Livewire;
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Utils\Traits\WithSorting;
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					use Carbon\Carbon;
 | 
				
			||||||
@ -23,15 +24,21 @@ class InvoicesTable extends Component
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use WithPagination, WithSorting;
 | 
					    use WithPagination, WithSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $status = [];
 | 
					    public array $status = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int $company_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = Company::find($this->company_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->sort_asc = false;
 | 
					        $this->sort_asc = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,11 @@ class PayNowDropdown extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount(int $total)
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->total = $total;
 | 
					        $this->methods = auth()->guard('contact')->user()->client->service()->getPaymentMethods($this->total);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->methods = auth()->guard('contact')->user()->client->service()->getPaymentMethods($total);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,9 @@
 | 
				
			|||||||
namespace App\Http\Livewire;
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\ClientGatewayToken;
 | 
					use App\Models\ClientGatewayToken;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Utils\Traits\WithSorting;
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
use Livewire\WithPagination;
 | 
					use Livewire\WithPagination;
 | 
				
			||||||
@ -13,17 +15,23 @@ class PaymentMethodsTable extends Component
 | 
				
			|||||||
    use WithPagination;
 | 
					    use WithPagination;
 | 
				
			||||||
    use WithSorting;
 | 
					    use WithSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $client;
 | 
					    public Client $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount($client)
 | 
					    public int $client_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->client = $client;
 | 
					        $this->client = Client::with('company')->find($this->client_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = $this->client->company;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
namespace App\Http\Livewire;
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Utils\Traits\WithSorting;
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
@ -23,17 +24,19 @@ class PaymentsTable extends Component
 | 
				
			|||||||
    use WithSorting;
 | 
					    use WithSorting;
 | 
				
			||||||
    use WithPagination;
 | 
					    use WithPagination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $user;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public int $company_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->user = auth()->user();
 | 
					        $this->company = Company::find($this->company_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
@ -43,7 +46,7 @@ class PaymentsTable extends Component
 | 
				
			|||||||
            ->where('company_id', $this->company->id)
 | 
					            ->where('company_id', $this->company->id)
 | 
				
			||||||
            ->where('client_id', auth()->guard('contact')->user()->client_id)
 | 
					            ->where('client_id', auth()->guard('contact')->user()->client_id)
 | 
				
			||||||
            ->whereIn('status_id', [Payment::STATUS_FAILED, Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_REFUNDED, Payment::STATUS_PARTIALLY_REFUNDED])
 | 
					            ->whereIn('status_id', [Payment::STATUS_FAILED, Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_REFUNDED, Payment::STATUS_PARTIALLY_REFUNDED])
 | 
				
			||||||
            ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
 | 
					            ->orderBy($this->sort_field, $this->sort_asc ? 'desc' : 'asc')
 | 
				
			||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
            ->paginate($this->per_page);
 | 
					            ->paginate($this->per_page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
namespace App\Http\Livewire;
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Utils\Traits\WithSorting;
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
@ -22,15 +23,27 @@ class QuotesTable extends Component
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use WithPagination;
 | 
					    use WithPagination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $per_page = 10;
 | 
					    public int $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $status = [];
 | 
					    public array $status = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $company;
 | 
					    public Company $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $sort = 'status_id'; // Default sortBy. Feel free to change or pull from client/company settings.
 | 
					    public string $sort = 'status_id'; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool $sort_asc = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int $company_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public string $db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->company = Company::find($this->company_id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $sort_asc = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function sortBy($field)
 | 
					    public function sortBy($field)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -41,16 +54,11 @@ class QuotesTable extends Component
 | 
				
			|||||||
        $this->sort = $field;
 | 
					        $this->sort = $field;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        MultiDB::setDb($this->company->db);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Quote::query()
 | 
					        $query = Quote::query()
 | 
				
			||||||
            ->with('client.gateway_tokens', 'company', 'client.contacts')
 | 
					            ->with('client.contacts', 'company')
 | 
				
			||||||
            ->orderBy($this->sort, $this->sort_asc ? 'asc' : 'desc');
 | 
					            ->orderBy($this->sort, $this->sort_asc ? 'asc' : 'desc');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($this->status) > 0) {
 | 
					        if (count($this->status) > 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -142,7 +142,7 @@ class SubscriptionPlanSwitch extends Component
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->hide_button = true;
 | 
					        $this->hide_button = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response =  $this->target->service()->createChangePlanCredit([
 | 
					        $response =  $this->target->service()->createChangePlanCreditV2([
 | 
				
			||||||
            'recurring_invoice' => $this->recurring_invoice,
 | 
					            'recurring_invoice' => $this->recurring_invoice,
 | 
				
			||||||
            'subscription' => $this->subscription,
 | 
					            'subscription' => $this->subscription,
 | 
				
			||||||
            'target' => $this->target,
 | 
					            'target' => $this->target,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										51
									
								
								app/Http/Livewire/SubscriptionsTable.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/Http/Livewire/SubscriptionsTable.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Livewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
 | 
					use App\Utils\Traits\WithSorting;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					use Livewire\WithPagination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SubscriptionsTable extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use WithPagination;
 | 
				
			||||||
 | 
					    use WithSorting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $per_page = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDb($this->company->db);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = RecurringInvoice::query()
 | 
				
			||||||
 | 
					            ->where('client_id', auth()->guard('contact')->user()->client->id)
 | 
				
			||||||
 | 
					            ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					            ->whereNotNull('subscription_id')
 | 
				
			||||||
 | 
					            ->where('is_deleted', false)
 | 
				
			||||||
 | 
					            ->where('status_id', RecurringInvoice::STATUS_ACTIVE)
 | 
				
			||||||
 | 
					            ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
 | 
				
			||||||
 | 
					            ->withTrashed()
 | 
				
			||||||
 | 
					            ->paginate($this->per_page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return render('components.livewire.subscriptions-table', [
 | 
				
			||||||
 | 
					            'recurring_invoices' => $query,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -18,6 +18,7 @@ use Illuminate\Http\Request;
 | 
				
			|||||||
use Illuminate\Support\Facades\Cache;
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
use Illuminate\Support\Facades\Hash;
 | 
					use Illuminate\Support\Facades\Hash;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					use Laravel\Socialite\Facades\Socialite;
 | 
				
			||||||
use stdClass;
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PasswordProtection
 | 
					class PasswordProtection
 | 
				
			||||||
@ -111,7 +112,18 @@ class PasswordProtection
 | 
				
			|||||||
                    return $next($request);
 | 
					                    return $next($request);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            elseif(auth()->user()->oauth_provider_id == 'apple')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 | 
					                $user = Socialite::driver('apple')->userFromToken($request->header('X-API-OAUTH-PASSWORD'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if($user && ($user->email == auth()->user()->email)){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
 | 
				
			||||||
 | 
					                    return $next($request);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return response()->json($error, 412);
 | 
					            return response()->json($error, 412);
 | 
				
			||||||
 | 
				
			|||||||
@ -64,21 +64,22 @@ class MatchBankTransactionRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if(array_key_exists('payment_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['payment_id']) >= 1){
 | 
					            if(array_key_exists('payment_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['payment_id']) >= 1){
 | 
				
			||||||
                $inputs['transactions'][$key]['payment_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['payment_id']);
 | 
					                $inputs['transactions'][$key]['payment_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['payment_id']);
 | 
				
			||||||
                $p = Payment::withTrashed()->find($inputs['transactions'][$key]['payment_id']);
 | 
					                $p = Payment::withTrashed()->where('company_id', auth()->user()->company()->id)->where('id', $inputs['transactions'][$key]['payment_id'])->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /*Ensure we don't relink an existing payment*/
 | 
					                /*Ensure we don't relink an existing payment*/
 | 
				
			||||||
                if(!$p || $p->transaction_id)
 | 
					                if(!$p || is_numeric($p->transaction_id)){
 | 
				
			||||||
                    $inputs['transactions'][$key]['payment_id'] = null;
 | 
					                    unset($inputs['transactions'][$key]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(array_key_exists('expense_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['expense_id']) >= 1){
 | 
					            if(array_key_exists('expense_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['expense_id']) >= 1){
 | 
				
			||||||
                $inputs['transactions'][$key]['expense_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['expense_id']);
 | 
					                $inputs['transactions'][$key]['expense_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['expense_id']);
 | 
				
			||||||
                $e = Expense::withTrashed()->find($inputs['transactions'][$key]['expense_id']);
 | 
					                $e = Expense::withTrashed()->where('company_id', auth()->user()->company()->id)->where('id', $inputs['transactions'][$key]['expense_id'])->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /*Ensure we don't relink an existing expense*/
 | 
					                /*Ensure we don't relink an existing expense*/
 | 
				
			||||||
                if(!$e || $e->transaction_id)
 | 
					                if(!$e || is_numeric($e->transaction_id))
 | 
				
			||||||
                    $inputs['transactions'][$key]['expense_id'] = null;
 | 
					                    unset($inputs['transactions'][$key]['expense_id']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ class RegisterRequest extends FormRequest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        foreach ($rules as $field => $properties) {
 | 
					        foreach ($rules as $field => $properties) {
 | 
				
			||||||
            if ($field === 'email') {
 | 
					            if ($field === 'email') {
 | 
				
			||||||
                $rules[$field] = array_merge($rules[$field], ['email:rfc,dns', 'max:255', Rule::unique('client_contacts')->where('company_id', $this->company()->id)]);
 | 
					                $rules[$field] = array_merge($rules[$field], ['email:rfc,dns', 'max:191', Rule::unique('client_contacts')->where('company_id', $this->company()->id)]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ($field === 'current_password') {
 | 
					            if ($field === 'current_password') {
 | 
				
			||||||
 | 
				
			|||||||
@ -40,8 +40,6 @@ class UpdateCompanyRequest extends Request
 | 
				
			|||||||
        return auth()->user()->can('edit', $this->company);
 | 
					        return auth()->user()->can('edit', $this->company);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
@ -110,6 +108,7 @@ class UpdateCompanyRequest extends Request
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(isset($settings['email_style_custom']))
 | 
				
			||||||
            $settings['email_style_custom'] = str_replace(['{{','}}'], ['',''], $settings['email_style_custom']);
 | 
					            $settings['email_style_custom'] = str_replace(['{{','}}'], ['',''], $settings['email_style_custom']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $account->isFreeHostedClient()) {
 | 
					        if (! $account->isFreeHostedClient()) {
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ class StoreExpenseRequest extends Request
 | 
				
			|||||||
            $rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
 | 
					            $rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! empty($this->client_id)) {
 | 
					        if ($this->client_id) {
 | 
				
			||||||
            $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
					            $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,10 @@ class UpdateExpenseRequest extends Request
 | 
				
			|||||||
            $rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->expense->id);
 | 
					            $rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->expense->id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->client_id) {
 | 
				
			||||||
 | 
					            $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $rules['category_id'] = 'bail|sometimes|nullable|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
					        $rules['category_id'] = 'bail|sometimes|nullable|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->globalRules($rules);
 | 
					        return $this->globalRules($rules);
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,8 @@ class PaymentWebhookRequest extends Request
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::findAndSetDbByCompanyKey($this->company_key);
 | 
					        MultiDB::findAndSetDbByCompanyKey($this->company_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return CompanyGateway::withTrashed()->findOrFail($this->decodePrimaryKey($this->company_gateway_id));
 | 
					        return CompanyGateway::withTrashed()->find($this->decodePrimaryKey($this->company_gateway_id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@ class StoreRecurringExpenseRequest extends Request
 | 
				
			|||||||
            $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
					            $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
				
			||||||
        $rules['frequency_id'] = 'required|integer|digits_between:1,12';
 | 
					        $rules['frequency_id'] = 'required|integer|digits_between:1,12';
 | 
				
			||||||
        $rules['tax_amount1'] = 'numeric';
 | 
					        $rules['tax_amount1'] = 'numeric';
 | 
				
			||||||
        $rules['tax_amount2'] = 'numeric';
 | 
					        $rules['tax_amount2'] = 'numeric';
 | 
				
			||||||
@ -61,10 +62,6 @@ class StoreRecurringExpenseRequest extends Request
 | 
				
			|||||||
            $input['next_send_date_client'] = $input['next_send_date'];
 | 
					            $input['next_send_date_client'] = $input['next_send_date'];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (array_key_exists('category_id', $input) && is_string($input['category_id'])) {
 | 
					 | 
				
			||||||
            $input['category_id'] = $this->decodePrimaryKey($input['category_id']);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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) auth()->user()->company()->settings->currency_id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -46,6 +46,7 @@ class UpdateRecurringExpenseRequest extends Request
 | 
				
			|||||||
        $rules['tax_amount1'] = 'numeric';
 | 
					        $rules['tax_amount1'] = 'numeric';
 | 
				
			||||||
        $rules['tax_amount2'] = 'numeric';
 | 
					        $rules['tax_amount2'] = 'numeric';
 | 
				
			||||||
        $rules['tax_amount3'] = 'numeric';
 | 
					        $rules['tax_amount3'] = 'numeric';
 | 
				
			||||||
 | 
					        $rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->globalRules($rules);
 | 
					        return $this->globalRules($rules);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -70,10 +71,6 @@ class UpdateRecurringExpenseRequest extends Request
 | 
				
			|||||||
            $input['next_send_date_client'] = $input['next_send_date'];
 | 
					            $input['next_send_date_client'] = $input['next_send_date'];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (array_key_exists('category_id', $input) && is_string($input['category_id'])) {
 | 
					 | 
				
			||||||
            $input['category_id'] = $this->decodePrimaryKey($input['category_id']);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (array_key_exists('documents', $input)) {
 | 
					        if (array_key_exists('documents', $input)) {
 | 
				
			||||||
            unset($input['documents']);
 | 
					            unset($input['documents']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										71
									
								
								app/Http/Requests/Report/ProductSalesReportRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/Http/Requests/Report/ProductSalesReportRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Report;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Validation\Rule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProductSalesReportRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'date_range' => 'bail|required|string',
 | 
				
			||||||
 | 
					            'end_date' => 'bail|required_if:date_range,custom|nullable|date',
 | 
				
			||||||
 | 
					            'start_date' => 'bail|required_if:date_range,custom|nullable|date',
 | 
				
			||||||
 | 
					            'report_keys' => 'bail|present|array',
 | 
				
			||||||
 | 
					            'send_email' => 'bail|required|bool',
 | 
				
			||||||
 | 
					            'client_id' => 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function prepareForValidation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (! array_key_exists('date_range', $input)) {
 | 
				
			||||||
 | 
					            $input['date_range'] = 'all';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (! array_key_exists('report_keys', $input)) {
 | 
				
			||||||
 | 
					            $input['report_keys'] = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (! array_key_exists('send_email', $input)) {
 | 
				
			||||||
 | 
					            $input['send_email'] = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (array_key_exists('date_range', $input) && $input['date_range'] != 'custom') {
 | 
				
			||||||
 | 
					            $input['start_date'] = null;
 | 
				
			||||||
 | 
					            $input['end_date'] = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(array_key_exists('client_id', $input) && strlen($input['client_id']) >=1)
 | 
				
			||||||
 | 
					            $input['client_id'] = $this->decodePrimaryKey($input['client_id']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->replace($input);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -32,8 +32,6 @@ class CheckMailRequest extends Request
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function rules()
 | 
					    public function rules()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        nlog($this->driver);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'mail_driver' => 'required',
 | 
					            'mail_driver' => 'required',
 | 
				
			||||||
            'encryption' => 'required_unless:mail_driver,log',
 | 
					            'encryption' => 'required_unless:mail_driver,log',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,39 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Http\Requests\TaskScheduler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreateScheduledTaskRequest extends Request
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determine if the user is authorized to make this request.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function authorize(): bool
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function rules()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'paused' => 'sometimes|bool',
 | 
					 | 
				
			||||||
            'repeat_every' => 'required|string|in:DAY,WEEK,MONTH,3MONTHS,YEAR',
 | 
					 | 
				
			||||||
            'start_from' => 'sometimes|string',
 | 
					 | 
				
			||||||
            'job' => 'required',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function prepareForValidation()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $input = $this->all();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! array_key_exists('start_from', $input)) {
 | 
					 | 
				
			||||||
            $input['start_from'] = now();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->replace($input);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								app/Http/Requests/TaskScheduler/CreateSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Http/Requests/TaskScheduler/CreateSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\TaskScheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateSchedulerRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/Http/Requests/TaskScheduler/DestroySchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/Http/Requests/TaskScheduler/DestroySchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\Task;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DestroySchedulerRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/Http/Requests/TaskScheduler/ShowSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/Http/Requests/TaskScheduler/ShowSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\TaskScheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShowSchedulerRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->can('view', $this->scheduler);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Requests\TaskScheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use Illuminate\Validation\Rule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StoreSchedulerRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->isAdmin();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rules()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $rules = [
 | 
				
			||||||
 | 
					            'name' => ['bail', 'required', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)],
 | 
				
			||||||
 | 
					            'is_paused' => 'bail|sometimes|boolean',
 | 
				
			||||||
 | 
					            'frequency_id' => 'bail|required|integer|digits_between:1,12',
 | 
				
			||||||
 | 
					            'next_run' => 'bail|required|date:Y-m-d',
 | 
				
			||||||
 | 
					            'template' => 'bail|required|string',
 | 
				
			||||||
 | 
					            'parameters' => 'bail|array',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $rules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,25 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Http\Requests\TaskScheduler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UpdateScheduledJobRequest extends Request
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determine if the user is authorized to make this request.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function authorize(): bool
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return auth()->user()->isAdmin();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function rules(): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'action_name' => 'sometimes|string',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -8,14 +8,12 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Http\Requests\TaskScheduler;
 | 
					namespace App\Http\Requests\TaskScheduler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
use Carbon\Carbon;
 | 
					 | 
				
			||||||
use Illuminate\Validation\Rule;
 | 
					use Illuminate\Validation\Rule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UpdateScheduleRequest extends Request
 | 
					class UpdateSchedulerRequest extends Request
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Determine if the user is authorized to make this request.
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
@ -29,23 +27,17 @@ class UpdateScheduleRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function rules(): array
 | 
					    public function rules(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					
 | 
				
			||||||
            'paused' => 'sometimes|bool',
 | 
					        $rules = [
 | 
				
			||||||
            'repeat_every' => 'sometimes|string|in:DAY,WEEK,BIWEEKLY,MONTH,3MONTHS,YEAR',
 | 
					            'name' => ['bail', 'sometimes', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)->ignore($this->task_scheduler->id)],
 | 
				
			||||||
            'start_from' => 'sometimes',
 | 
					            'is_paused' => 'bail|sometimes|boolean',
 | 
				
			||||||
            'scheduled_run'=>'sometimes',
 | 
					            'frequency_id' => 'bail|required|integer|digits_between:1,12',
 | 
				
			||||||
 | 
					            'next_run' => 'bail|required|date:Y-m-d',
 | 
				
			||||||
 | 
					            'template' => 'bail|required|string',
 | 
				
			||||||
 | 
					            'parameters' => 'bail|array',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function prepareForValidation()
 | 
					        return $rules;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $input = $this->all();
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (isset($input['start_from'])) {
 | 
					 | 
				
			||||||
            $input['scheduled_run'] = Carbon::parse((int) $input['start_from']);
 | 
					 | 
				
			||||||
            $input['start_from'] = Carbon::parse((int) $input['start_from']);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->replace($input);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -29,6 +29,7 @@ class BlackListRule implements Rule
 | 
				
			|||||||
        'dataservices.space',
 | 
					        'dataservices.space',
 | 
				
			||||||
        'karenkey.com',
 | 
					        'karenkey.com',
 | 
				
			||||||
        'sharklasers.com',
 | 
					        'sharklasers.com',
 | 
				
			||||||
 | 
					        '100072641.help'
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ use App\Http\Requests\Quote\StoreQuoteRequest;
 | 
				
			|||||||
use App\Import\ImportException;
 | 
					use App\Import\ImportException;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
					use App\Jobs\Mail\NinjaMailerJob;
 | 
				
			||||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
					use App\Jobs\Mail\NinjaMailerObject;
 | 
				
			||||||
use App\Mail\Import\ImportCompleted;
 | 
					use App\Mail\Import\CsvImportCompleted;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
@ -187,6 +187,10 @@ class BaseImport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                $entity = $this->transformer->transform($record);
 | 
					                $entity = $this->transformer->transform($record);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(!$entity)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $validator = $this->runValidation($entity);
 | 
					                $validator = $this->runValidation($entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ($validator->fails()) {
 | 
					                if ($validator->fails()) {
 | 
				
			||||||
@ -282,6 +286,8 @@ class BaseImport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function ingestInvoices($invoices, $invoice_number_key)
 | 
					    public function ingestInvoices($invoices, $invoice_number_key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoice_transformer = $this->transformer;
 | 
					        $invoice_transformer = $this->transformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /** @var PaymentRepository $payment_repository */
 | 
					        /** @var PaymentRepository $payment_repository */
 | 
				
			||||||
@ -343,6 +349,7 @@ class BaseImport
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $invoice_repository->save($invoice_data, $invoice);
 | 
					                    $invoice_repository->save($invoice_data, $invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $count++;
 | 
				
			||||||
                    // If we're doing a generic CSV import, only import payment data if we're not importing a payment CSV.
 | 
					                    // If we're doing a generic CSV import, only import payment data if we're not importing a payment CSV.
 | 
				
			||||||
                    // If we're doing a platform-specific import, trust the platform to only return payment info if there's not a separate payment CSV.
 | 
					                    // If we're doing a platform-specific import, trust the platform to only return payment info if there's not a separate payment CSV.
 | 
				
			||||||
                    if (
 | 
					                    if (
 | 
				
			||||||
@ -404,6 +411,9 @@ class BaseImport
 | 
				
			|||||||
                ];
 | 
					                ];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function actionInvoiceStatus(
 | 
					    private function actionInvoiceStatus(
 | 
				
			||||||
@ -475,6 +485,8 @@ class BaseImport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function ingestQuotes($quotes, $quote_number_key)
 | 
					    public function ingestQuotes($quotes, $quote_number_key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $quote_transformer = $this->transformer;
 | 
					        $quote_transformer = $this->transformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /** @var ClientRepository $client_repository */
 | 
					        /** @var ClientRepository $client_repository */
 | 
				
			||||||
@ -533,6 +545,8 @@ class BaseImport
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $quote_repository->save($quote_data, $quote);
 | 
					                    $quote_repository->save($quote_data, $quote);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
 | 
					                    $count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    $this->actionQuoteStatus(
 | 
					                    $this->actionQuoteStatus(
 | 
				
			||||||
                        $quote,
 | 
					                        $quote,
 | 
				
			||||||
                        $quote_data,
 | 
					                        $quote_data,
 | 
				
			||||||
@ -552,7 +566,11 @@ class BaseImport
 | 
				
			|||||||
                    'error' => $message,
 | 
					                    'error' => $message,
 | 
				
			||||||
                ];
 | 
					                ];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function getUserIDForRecord($record)
 | 
					    protected function getUserIDForRecord($record)
 | 
				
			||||||
@ -586,10 +604,11 @@ class BaseImport
 | 
				
			|||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'errors'  => $this->error_array,
 | 
					            'errors'  => $this->error_array,
 | 
				
			||||||
            'company' => $this->company,
 | 
					            'company' => $this->company,
 | 
				
			||||||
 | 
					            'entity_count' => $this->entity_count
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $nmo = new NinjaMailerObject;
 | 
					        $nmo = new NinjaMailerObject;
 | 
				
			||||||
        $nmo->mailable = new ImportCompleted($this->company, $data);
 | 
					        $nmo->mailable = new CsvImportCompleted($this->company, $data);
 | 
				
			||||||
        $nmo->company = $this->company;
 | 
					        $nmo->company = $this->company;
 | 
				
			||||||
        $nmo->settings = $this->company->settings;
 | 
					        $nmo->settings = $this->company->settings;
 | 
				
			||||||
        $nmo->to_user = $this->company->owner();
 | 
					        $nmo->to_user = $this->company->owner();
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@ use App\Import\Transformer\Csv\PaymentTransformer;
 | 
				
			|||||||
use App\Import\Transformer\Csv\ProductTransformer;
 | 
					use App\Import\Transformer\Csv\ProductTransformer;
 | 
				
			||||||
use App\Import\Transformer\Csv\QuoteTransformer;
 | 
					use App\Import\Transformer\Csv\QuoteTransformer;
 | 
				
			||||||
use App\Import\Transformer\Csv\VendorTransformer;
 | 
					use App\Import\Transformer\Csv\VendorTransformer;
 | 
				
			||||||
use App\Import\Transformers\Bank\BankTransformer;
 | 
					use App\Import\Transformer\Bank\BankTransformer;
 | 
				
			||||||
use App\Repositories\BankTransactionRepository;
 | 
					use App\Repositories\BankTransactionRepository;
 | 
				
			||||||
use App\Repositories\ClientRepository;
 | 
					use App\Repositories\ClientRepository;
 | 
				
			||||||
use App\Repositories\ExpenseRepository;
 | 
					use App\Repositories\ExpenseRepository;
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,6 @@ class Wave extends BaseImport implements ImportInterface
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (empty($data)) {
 | 
					        if (empty($data)) {
 | 
				
			||||||
            $this->entity_count['clients'] = 0;
 | 
					            $this->entity_count['clients'] = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -170,11 +169,16 @@ class Wave extends BaseImport implements ImportInterface
 | 
				
			|||||||
        $entity_type = 'expense';
 | 
					        $entity_type = 'expense';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = $this->getCsvData($entity_type);
 | 
					        $data = $this->getCsvData($entity_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!$data){
 | 
				
			||||||
 | 
					            $this->entity_count['expense'] = 0;
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = $this->preTransform($data, $entity_type);
 | 
					        $data = $this->preTransform($data, $entity_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (empty($data)) {
 | 
					        if (empty($data)) {
 | 
				
			||||||
            $this->entity_count['expense'] = 0;
 | 
					            $this->entity_count['expense'] = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -212,6 +216,8 @@ class Wave extends BaseImport implements ImportInterface
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function ingestExpenses($data)
 | 
					    public function ingestExpenses($data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $key = 'Transaction ID';
 | 
					        $key = 'Transaction ID';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $expense_transformer = $this->transformer;
 | 
					        $expense_transformer = $this->transformer;
 | 
				
			||||||
@ -255,6 +261,7 @@ class Wave extends BaseImport implements ImportInterface
 | 
				
			|||||||
                    );
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    $expense_repository->save($expense_data, $expense);
 | 
					                    $expense_repository->save($expense_data, $expense);
 | 
				
			||||||
 | 
					                    $count++;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } catch (\Exception $ex) {
 | 
					            } catch (\Exception $ex) {
 | 
				
			||||||
                if ($ex instanceof ImportException) {
 | 
					                if ($ex instanceof ImportException) {
 | 
				
			||||||
@ -270,5 +277,8 @@ class Wave extends BaseImport implements ImportInterface
 | 
				
			|||||||
                ];
 | 
					                ];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@
 | 
				
			|||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Import\Transformers\Bank;
 | 
					namespace App\Import\Transformer\Bank;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Import\ImportException;
 | 
					use App\Import\ImportException;
 | 
				
			||||||
use App\Import\Transformer\BaseTransformer;
 | 
					use App\Import\Transformer\BaseTransformer;
 | 
				
			||||||
@ -61,9 +61,9 @@ class InvoiceTransformer extends BaseTransformer
 | 
				
			|||||||
                'discount'           => $this->getFreshbookQuantityFloat($record, 'Discount Percentage'),
 | 
					                'discount'           => $this->getFreshbookQuantityFloat($record, 'Discount Percentage'),
 | 
				
			||||||
                'is_amount_discount' => false,
 | 
					                'is_amount_discount' => false,
 | 
				
			||||||
                'tax_name1'          => $this->getString($record, 'Tax 1 Type'),
 | 
					                'tax_name1'          => $this->getString($record, 'Tax 1 Type'),
 | 
				
			||||||
                'tax_rate1'          => $this->getFreshbookQuantityFloat($record, 'Tax 1 Amount'),
 | 
					                'tax_rate1'          => $this->calcTaxRate($record, 'Tax 1 Amount'),
 | 
				
			||||||
                'tax_name2'          => $this->getString($record, 'Tax 2 Type'),
 | 
					                'tax_name2'          => $this->getString($record, 'Tax 2 Type'),
 | 
				
			||||||
                'tax_rate2'          => $this->getFreshbookQuantityFloat($record, 'Tax 2 Amount'),
 | 
					                'tax_rate2'          => $this->calcTaxRate($record, 'Tax 2 Amount'),
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
            $transformed['amount'] += $this->getFreshbookQuantityFloat($record, 'Line Total');
 | 
					            $transformed['amount'] += $this->getFreshbookQuantityFloat($record, 'Line Total');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -79,6 +79,27 @@ class InvoiceTransformer extends BaseTransformer
 | 
				
			|||||||
        return $transformed;
 | 
					        return $transformed;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Line Subtotal
 | 
				
			||||||
 | 
					    public function calcTaxRate($record, $field)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(isset($record['Line Subtotal']) && $record['Line Subtotal'] > 0)
 | 
				
			||||||
 | 
					            return ($record[$field] / $record['Line Subtotal']) * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $tax_amount1 = isset($record['Tax 1 Amount']) ? $record['Tax 1 Amount'] : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $tax_amount2 = isset($record['Tax 2 Amount']) ? $record['Tax 2 Amount'] : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $line_total = isset($record['Line Total']) ? $record['Line Total'] : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $subtotal = $line_total - $tax_amount2 - $tax_amount1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($subtotal > 0)
 | 
				
			||||||
 | 
					            return $record[$field] / $subtotal * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** @return float  */
 | 
					    /** @return float  */
 | 
				
			||||||
    public function getFreshbookQuantityFloat($data, $field)
 | 
					    public function getFreshbookQuantityFloat($data, $field)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,11 @@ class InvoiceTransformer extends BaseTransformer
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function transform($invoice_data)
 | 
					    public function transform($invoice_data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isset($invoice_data['DocumentNumber'])) {
 | 
				
			||||||
 | 
					            throw new ImportException('DocumentNumber key not found in this import file.');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->hasInvoice($invoice_data['DocumentNumber'])) {
 | 
					        if ($this->hasInvoice($invoice_data['DocumentNumber'])) {
 | 
				
			||||||
            throw new ImportException('Invoice number already exists');
 | 
					            throw new ImportException('Invoice number already exists');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,8 @@ class ClientTransformer extends BaseTransformer
 | 
				
			|||||||
    public function transform($data)
 | 
					    public function transform($data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($data['customer_name']) && $this->hasClient($data['customer_name'])) {
 | 
					        if (isset($data['customer_name']) && $this->hasClient($data['customer_name'])) {
 | 
				
			||||||
            throw new ImportException('Client already exists');
 | 
					            return false;
 | 
				
			||||||
 | 
					            // throw new ImportException('Client already exists');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $settings = new \stdClass;
 | 
					        $settings = new \stdClass;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,430 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\ClientContact;
 | 
					 | 
				
			||||||
use App\Utils\Number;
 | 
					 | 
				
			||||||
use Carbon;
 | 
					 | 
				
			||||||
use Exception;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class BaseTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @var
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected $maps;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * BaseTransformer constructor.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param $maps
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function __construct($maps)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->maps = $maps;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     * @param $field
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getString($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (isset($data[$field]) && $data[$field]) ? $data[$field] : '';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getInvoiceTypeId($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (isset($data[$field]) && $data[$field]) ? $data[$field] : '1';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getCurrencyByCode($data, $key = 'client.currency_id')
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $code = array_key_exists($key, $data) ? $data[$key] : false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['currencies'][$code] ?? $this->maps['company']->settings->currency_id;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getClient($client_name, $client_email)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $clients = $this->maps['company']->clients;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client_id_search = $clients->where('id_number', $client_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($client_id_search->count() >= 1) {
 | 
					 | 
				
			||||||
            return $client_id_search->first()->id;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client_name_search = $clients->where('name', $client_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($client_name_search->count() >= 1) {
 | 
					 | 
				
			||||||
            return $client_name_search->first()->id;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! empty($client_email)) {
 | 
					 | 
				
			||||||
            $contacts = ClientContact::where('company_id', $this->maps['company']->id)
 | 
					 | 
				
			||||||
                                     ->where('email', $client_email);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ($contacts->count() >= 1) {
 | 
					 | 
				
			||||||
                return $contacts->first()->client_id;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function hasClient($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = trim(strtolower($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['client'][$name]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function hasVendor($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = trim(strtolower($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['vendor'][$name]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $key
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function hasProduct($key)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $key = trim(strtolower($key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['product'][$key]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     * @param $field
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return int
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getNumber($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (isset($data->$field) && $data->$field) ? $data->$field : 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     * @param $field
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return float
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getFloat($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (array_key_exists($field, $data)) {
 | 
					 | 
				
			||||||
            $number = preg_replace('/[^0-9-.]+/', '', $data[$field]);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $number = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return Number::parseFloat($number);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getFloatWithSamePrecision($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $precision = (int) strpos(strrev($data[$field]), ".");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return round($data[$field], $precision);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getClientId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['client'][$name]) ? $this->maps['client'][$name] : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getProduct($data, $key, $field, $default = false)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $productKey = trim(strtolower($data->$key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! isset($this->maps['product'][$productKey])) {
 | 
					 | 
				
			||||||
            return $default;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $product = $this->maps['product'][$productKey];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $product->$field ?: $default;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getContact($email)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $email = trim(strtolower($email));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! isset($this->maps['contact'][$email])) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['contact'][$email];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getCustomer($key)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $key = trim($key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! isset($this->maps['customer'][$key])) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['customer'][$key];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getCountryId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (strlen($name) == 2) {
 | 
					 | 
				
			||||||
            return $this->getCountryIdBy2($name);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['countries'][$name]) ? $this->maps['countries'][$name] : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getCountryIdBy2($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['countries2'][$name]) ? $this->maps['countries2'][$name] : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getTaxRate($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['tax_rates'][$name]) ? $this->maps['tax_rates'][$name] : 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getTaxName($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['tax_names'][$name]) ? $this->maps['tax_names'][$name] : '';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return mixed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getFirstName($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = Utils::splitName($name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $name[0];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $date
 | 
					 | 
				
			||||||
     * @param string $format
 | 
					 | 
				
			||||||
     * @param mixed  $data
 | 
					 | 
				
			||||||
     * @param mixed  $field
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getDate($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if ($date = data_get($data, $field)) {
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                $date = new Carbon($date);
 | 
					 | 
				
			||||||
            } catch (Exception $e) {
 | 
					 | 
				
			||||||
                // if we fail to parse return blank
 | 
					 | 
				
			||||||
                $date = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $date ? $date->format('Y-m-d') : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return mixed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getLastName($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = Utils::splitName($name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $name[1];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $number
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getInvoiceNumber($number)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $number ? ltrim(trim($number), '0') : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $invoiceNumber
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getInvoiceId($invoiceNumber)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
 | 
					 | 
				
			||||||
        $invoiceNumber = strtolower($invoiceNumber);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['invoice'][$invoiceNumber]) ? $this->maps['invoice'][$invoiceNumber] : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $invoiceNumber
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getInvoicePublicId($invoiceNumber)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
 | 
					 | 
				
			||||||
        $invoiceNumber = strtolower($invoiceNumber);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return isset($this->maps['invoice'][$invoiceNumber]) ? $this->maps['invoices'][$invoiceNumber]->public_id : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $invoiceNumber
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function hasInvoice($invoiceNumber)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
 | 
					 | 
				
			||||||
        $invoiceNumber = strtolower($invoiceNumber);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['invoice'][$invoiceNumber] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $invoiceNumber
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getInvoiceClientId($invoiceNumber)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
 | 
					 | 
				
			||||||
        $invoiceNumber = strtolower($invoiceNumber);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['invoice_client'][$invoiceNumber] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getVendorId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['vendor'][$name] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getExpenseCategoryId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['expense_category'][$name] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getProjectId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['project'][$name] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $name
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getPaymentTypeId($name)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $name = strtolower(trim($name));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->maps['payment_type'][$name] ?? null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,78 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class ClientTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ClientTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|Item
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (isset($data->name) && $this->hasClient($data->name)) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $settings = new \stdClass;
 | 
					 | 
				
			||||||
        $settings->currency_id = (string) $this->getCurrencyByCode($data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id' => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'name' => $this->getString($data, 'client.name'),
 | 
					 | 
				
			||||||
            'phone' => $this->getString($data, 'client.phone'),
 | 
					 | 
				
			||||||
            'address1' => $this->getString($data, 'client.address1'),
 | 
					 | 
				
			||||||
            'address2' => $this->getString($data, 'client.address2'),
 | 
					 | 
				
			||||||
            'city' => $this->getString($data, 'client.city'),
 | 
					 | 
				
			||||||
            'state' => $this->getString($data, 'client.state'),
 | 
					 | 
				
			||||||
            'shipping_address1' => $this->getString($data, 'client.shipping_address1'),
 | 
					 | 
				
			||||||
            'shipping_address2' => $this->getString($data, 'client.shipping_address2'),
 | 
					 | 
				
			||||||
            'shipping_city' => $this->getString($data, 'client.shipping_city'),
 | 
					 | 
				
			||||||
            'shipping_state' => $this->getString($data, 'client.shipping_state'),
 | 
					 | 
				
			||||||
            'shipping_postal_code' => $this->getString($data, 'client.shipping_postal_code'),
 | 
					 | 
				
			||||||
            'public_notes' => $this->getString($data, 'client.public_notes'),
 | 
					 | 
				
			||||||
            'private_notes' => $this->getString($data, 'client.private_notes'),
 | 
					 | 
				
			||||||
            'website' => $this->getString($data, 'client.website'),
 | 
					 | 
				
			||||||
            'vat_number' => $this->getString($data, 'client.vat_number'),
 | 
					 | 
				
			||||||
            'id_number' => $this->getString($data, 'client.id_number'),
 | 
					 | 
				
			||||||
            'custom_value1' => $this->getString($data, 'client.custom1'),
 | 
					 | 
				
			||||||
            'custom_value2' => $this->getString($data, 'client.custom2'),
 | 
					 | 
				
			||||||
            'custom_value3' => $this->getString($data, 'client.custom3'),
 | 
					 | 
				
			||||||
            'custom_value4' => $this->getString($data, 'client.custom4'),
 | 
					 | 
				
			||||||
            'balance' => $this->getFloat($data, 'client.balance'),
 | 
					 | 
				
			||||||
            'paid_to_date' => $this->getFloat($data, 'client.paid_to_date'),
 | 
					 | 
				
			||||||
            'credit_balance' => 0,
 | 
					 | 
				
			||||||
            'settings' => $settings,
 | 
					 | 
				
			||||||
            'client_hash' => Str::random(40),
 | 
					 | 
				
			||||||
            'contacts' => [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'first_name' => $this->getString($data, 'contact.first_name'),
 | 
					 | 
				
			||||||
                    'last_name' => $this->getString($data, 'contact.last_name'),
 | 
					 | 
				
			||||||
                    'email' => $this->getString($data, 'contact.email'),
 | 
					 | 
				
			||||||
                    'phone' => $this->getString($data, 'contact.phone'),
 | 
					 | 
				
			||||||
                    'custom_value1' => $this->getString($data, 'contact.custom1'),
 | 
					 | 
				
			||||||
                    'custom_value2' => $this->getString($data, 'contact.custom2'),
 | 
					 | 
				
			||||||
                    'custom_value3' => $this->getString($data, 'contact.custom3'),
 | 
					 | 
				
			||||||
                    'custom_value4' => $this->getString($data, 'contact.custom4'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            'country_id' => isset($data->country_id) ? $this->getCountryId($data->country_id) : null,
 | 
					 | 
				
			||||||
            'shipping_country_id' => isset($data->shipping_country_id) ? $this->getCountryId($data->shipping_country_id) : null,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,120 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * client Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class ClientTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ClientTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array|bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (isset($data->name) && $this->hasClient($data->name)) {
 | 
					 | 
				
			||||||
            throw new ImportException('Client already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $settings = new \stdClass();
 | 
					 | 
				
			||||||
        $settings->currency_id = (string) $this->getCurrencyByCode($data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id' => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'name' => $this->getString($data, 'client.name'),
 | 
					 | 
				
			||||||
            'phone' => $this->getString($data, 'client.phone'),
 | 
					 | 
				
			||||||
            'address1' => $this->getString($data, 'client.address1'),
 | 
					 | 
				
			||||||
            'address2' => $this->getString($data, 'client.address2'),
 | 
					 | 
				
			||||||
            'postal_code' => $this->getString($data, 'client.postal_code'),
 | 
					 | 
				
			||||||
            'city' => $this->getString($data, 'client.city'),
 | 
					 | 
				
			||||||
            'state' => $this->getString($data, 'client.state'),
 | 
					 | 
				
			||||||
            'shipping_address1' => $this->getString(
 | 
					 | 
				
			||||||
                $data,
 | 
					 | 
				
			||||||
                'client.shipping_address1'
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'shipping_address2' => $this->getString(
 | 
					 | 
				
			||||||
                $data,
 | 
					 | 
				
			||||||
                'client.shipping_address2'
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'shipping_city' => $this->getString($data, 'client.shipping_city'),
 | 
					 | 
				
			||||||
            'shipping_state' => $this->getString(
 | 
					 | 
				
			||||||
                $data,
 | 
					 | 
				
			||||||
                'client.shipping_state'
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'shipping_postal_code' => $this->getString(
 | 
					 | 
				
			||||||
                $data,
 | 
					 | 
				
			||||||
                'client.shipping_postal_code'
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'public_notes' => $this->getString($data, 'client.public_notes'),
 | 
					 | 
				
			||||||
            'private_notes' => $this->getString($data, 'client.private_notes'),
 | 
					 | 
				
			||||||
            'website' => $this->getString($data, 'client.website'),
 | 
					 | 
				
			||||||
            'vat_number' => $this->getString($data, 'client.vat_number'),
 | 
					 | 
				
			||||||
            'id_number' => $this->getString($data, 'client.id_number'),
 | 
					 | 
				
			||||||
            'custom_value1' => $this->getString($data, 'client.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2' => $this->getString($data, 'client.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3' => $this->getString($data, 'client.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4' => $this->getString($data, 'client.custom_value4'),
 | 
					 | 
				
			||||||
            'balance' => preg_replace(
 | 
					 | 
				
			||||||
                '/[^0-9,.]+/',
 | 
					 | 
				
			||||||
                '',
 | 
					 | 
				
			||||||
                $this->getFloat($data, 'client.balance')
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'paid_to_date' => preg_replace(
 | 
					 | 
				
			||||||
                '/[^0-9,.]+/',
 | 
					 | 
				
			||||||
                '',
 | 
					 | 
				
			||||||
                $this->getFloat($data, 'client.paid_to_date')
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            'credit_balance' => 0,
 | 
					 | 
				
			||||||
            'settings' => $settings,
 | 
					 | 
				
			||||||
            'client_hash' => Str::random(40),
 | 
					 | 
				
			||||||
            'contacts' => [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'first_name' => $this->getString(
 | 
					 | 
				
			||||||
                        $data,
 | 
					 | 
				
			||||||
                        'contact.first_name'
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                    'last_name' => $this->getString($data, 'contact.last_name'),
 | 
					 | 
				
			||||||
                    'email' => $this->getString($data, 'contact.email'),
 | 
					 | 
				
			||||||
                    'phone' => $this->getString($data, 'contact.phone'),
 | 
					 | 
				
			||||||
                    'custom_value1' => $this->getString(
 | 
					 | 
				
			||||||
                        $data,
 | 
					 | 
				
			||||||
                        'contact.custom_value1'
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                    'custom_value2' => $this->getString(
 | 
					 | 
				
			||||||
                        $data,
 | 
					 | 
				
			||||||
                        'contact.custom_value2'
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                    'custom_value3' => $this->getString(
 | 
					 | 
				
			||||||
                        $data,
 | 
					 | 
				
			||||||
                        'contact.custom_value3'
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                    'custom_value4' => $this->getString(
 | 
					 | 
				
			||||||
                        $data,
 | 
					 | 
				
			||||||
                        'contact.custom_value4'
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            'country_id' => isset($data['client.country'])
 | 
					 | 
				
			||||||
                ? $this->getCountryId($data['client.country'])
 | 
					 | 
				
			||||||
                : null,
 | 
					 | 
				
			||||||
            'shipping_country_id' => isset($data['client.shipping_country'])
 | 
					 | 
				
			||||||
                ? $this->getCountryId($data['client.shipping_country'])
 | 
					 | 
				
			||||||
                : null,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class InvoiceTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ExpenseTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $clientId = isset($data['expense.client']) ? $this->getClientId($data['expense.client']) : null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id'            => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'amount'                => $this->getFloat($data, 'expense.amount'),
 | 
					 | 
				
			||||||
            'currency_id'           => $this->getCurrencyByCode($data, 'expense.currency_id'),
 | 
					 | 
				
			||||||
            'vendor_id'             => isset($data['expense.vendor']) ? $this->getVendorId($data['expense.vendor']) : null,
 | 
					 | 
				
			||||||
            'client_id'             => isset($data['expense.client']) ? $this->getClientId($data['expense.client']) : null,
 | 
					 | 
				
			||||||
            'date'		            => isset($data['expense.date']) ? date('Y-m-d', strtotime($data['expense.date'])) : null,
 | 
					 | 
				
			||||||
            'public_notes'          => $this->getString($data, 'expense.public_notes'),
 | 
					 | 
				
			||||||
            'private_notes'         => $this->getString($data, 'expense.private_notes'),
 | 
					 | 
				
			||||||
            'category_id'   		=> isset($data['expense.category']) ? $this->getExpenseCategoryId($data['expense.category']) : null,
 | 
					 | 
				
			||||||
            'project_id'            => isset($data['expense.project']) ? $this->getProjectId($data['expense.project']) : null,
 | 
					 | 
				
			||||||
            'payment_type_id'       => isset($data['expense.payment_type']) ? $this->getPaymentTypeId($data['expense.payment_type']) : null,
 | 
					 | 
				
			||||||
            'payment_date'          => isset($data['expense.payment_date']) ? date('Y-m-d', strtotime($data['expense.payment_date'])) : null,
 | 
					 | 
				
			||||||
            'custom_value1'        => $this->getString($data, 'expense.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2'        => $this->getString($data, 'expense.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3'        => $this->getString($data, 'expense.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4'        => $this->getString($data, 'expense.custom_value4'),
 | 
					 | 
				
			||||||
            'transaction_reference' => $this->getString($data, 'expense.transaction_reference'),
 | 
					 | 
				
			||||||
            'should_be_invoiced'    => $clientId ? true : false,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,133 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * client Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class InvoiceTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class InvoiceTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($line_items_data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoice_data = reset($line_items_data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($this->hasInvoice($invoice_data['invoice.number'])) {
 | 
					 | 
				
			||||||
            throw new ImportException('Invoice number already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $invoiceStatusMap = [
 | 
					 | 
				
			||||||
            'sent'  => Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
            'draft' => Invoice::STATUS_DRAFT,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $transformed = [
 | 
					 | 
				
			||||||
            'company_id'        => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'number'            => $this->getString($invoice_data, 'invoice.number'),
 | 
					 | 
				
			||||||
            'user_id'           => $this->getString($invoice_data, 'invoice.user_id'),
 | 
					 | 
				
			||||||
            'amount'            => $amount = $this->getFloat($invoice_data, 'invoice.amount'),
 | 
					 | 
				
			||||||
            'balance'           => isset($invoice_data['invoice.balance']) ? $this->getFloat($invoice_data, 'invoice.balance') : $amount,
 | 
					 | 
				
			||||||
            'client_id'         => $this->getClient($this->getString($invoice_data, 'client.name'), $this->getString($invoice_data, 'client.email')),
 | 
					 | 
				
			||||||
            'discount'          => $this->getFloat($invoice_data, 'invoice.discount'),
 | 
					 | 
				
			||||||
            'po_number'         => $this->getString($invoice_data, 'invoice.po_number'),
 | 
					 | 
				
			||||||
            'date'              => isset($invoice_data['invoice.date']) ? date('Y-m-d', strtotime($invoice_data['invoice.date'])) : now()->format('Y-m-d'),
 | 
					 | 
				
			||||||
            'due_date'          => isset($invoice_data['invoice.due_date']) ? date('Y-m-d', strtotime($invoice_data['invoice.due_date'])) : null,
 | 
					 | 
				
			||||||
            'terms'             => $this->getString($invoice_data, 'invoice.terms'),
 | 
					 | 
				
			||||||
            'public_notes'      => $this->getString($invoice_data, 'invoice.public_notes'),
 | 
					 | 
				
			||||||
            // 'is_sent'           => $this->getString( $invoice_data, 'invoice.is_sent' ),
 | 
					 | 
				
			||||||
            'private_notes'     => $this->getString($invoice_data, 'invoice.private_notes'),
 | 
					 | 
				
			||||||
            'tax_name1'         => $this->getString($invoice_data, 'invoice.tax_name1'),
 | 
					 | 
				
			||||||
            'tax_rate1'         => $this->getFloat($invoice_data, 'invoice.tax_rate1'),
 | 
					 | 
				
			||||||
            'tax_name2'         => $this->getString($invoice_data, 'invoice.tax_name2'),
 | 
					 | 
				
			||||||
            'tax_rate2'         => $this->getFloat($invoice_data, 'invoice.tax_rate2'),
 | 
					 | 
				
			||||||
            'tax_name3'         => $this->getString($invoice_data, 'invoice.tax_name3'),
 | 
					 | 
				
			||||||
            'tax_rate3'         => $this->getFloat($invoice_data, 'invoice.tax_rate3'),
 | 
					 | 
				
			||||||
            'custom_value1'     => $this->getString($invoice_data, 'invoice.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2'     => $this->getString($invoice_data, 'invoice.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3'     => $this->getString($invoice_data, 'invoice.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4'     => $this->getString($invoice_data, 'invoice.custom_value4'),
 | 
					 | 
				
			||||||
            'footer'            => $this->getString($invoice_data, 'invoice.footer'),
 | 
					 | 
				
			||||||
            'partial'           => $this->getFloat($invoice_data, 'invoice.partial'),
 | 
					 | 
				
			||||||
            'partial_due_date'  => $this->getString($invoice_data, 'invoice.partial_due_date'),
 | 
					 | 
				
			||||||
            'custom_surcharge1' => $this->getString($invoice_data, 'invoice.custom_surcharge1'),
 | 
					 | 
				
			||||||
            'custom_surcharge2' => $this->getString($invoice_data, 'invoice.custom_surcharge2'),
 | 
					 | 
				
			||||||
            'custom_surcharge3' => $this->getString($invoice_data, 'invoice.custom_surcharge3'),
 | 
					 | 
				
			||||||
            'custom_surcharge4' => $this->getString($invoice_data, 'invoice.custom_surcharge4'),
 | 
					 | 
				
			||||||
            'exchange_rate'     => $this->getString($invoice_data, 'invoice.exchange_rate'),
 | 
					 | 
				
			||||||
            'status_id'         => $invoiceStatusMap[$status =
 | 
					 | 
				
			||||||
                    strtolower($this->getString($invoice_data, 'invoice.status'))] ??
 | 
					 | 
				
			||||||
                Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
            // 'viewed'            => $status === 'viewed',
 | 
					 | 
				
			||||||
            'archived'          => $status === 'archived',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (isset($invoice_data['payment.amount'])) {
 | 
					 | 
				
			||||||
            $transformed['payments'] = [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'date'                  => isset($invoice_data['payment.date']) ? date('Y-m-d', strtotime($invoice_data['payment.date'])) : date('y-m-d'),
 | 
					 | 
				
			||||||
                    'transaction_reference' => $this->getString($invoice_data, 'payment.transaction_reference'),
 | 
					 | 
				
			||||||
                    'amount'                => $this->getFloat($invoice_data, 'payment.amount'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        } elseif ($status === 'paid') {
 | 
					 | 
				
			||||||
            $transformed['payments'] = [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'date'                  => isset($invoice_data['payment.date']) ? date('Y-m-d', strtotime($invoice_data['payment.date'])) : date('y-m-d'),
 | 
					 | 
				
			||||||
                    'transaction_reference' => $this->getString($invoice_data, 'payment.transaction_reference'),
 | 
					 | 
				
			||||||
                    'amount'                => $this->getFloat($invoice_data, 'invoice.amount'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        } elseif (isset($transformed['amount']) && isset($transformed['balance']) && ($transformed['amount'] != $transformed['balance'])) {
 | 
					 | 
				
			||||||
            $transformed['payments'] = [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'date'                  => isset($invoice_data['payment.date']) ? date('Y-m-d', strtotime($invoice_data['payment.date'])) : date('y-m-d'),
 | 
					 | 
				
			||||||
                    'transaction_reference' => $this->getString($invoice_data, 'payment.transaction_reference'),
 | 
					 | 
				
			||||||
                    'amount'                => $transformed['amount'] - $transformed['balance'],
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $line_items = [];
 | 
					 | 
				
			||||||
        foreach ($line_items_data as $record) {
 | 
					 | 
				
			||||||
            $line_items[] = [
 | 
					 | 
				
			||||||
                'quantity'           => $this->getFloat($record, 'item.quantity'),
 | 
					 | 
				
			||||||
                'cost'               => $this->getFloat($record, 'item.cost'),
 | 
					 | 
				
			||||||
                'product_key'        => $this->getString($record, 'item.product_key'),
 | 
					 | 
				
			||||||
                'notes'              => $this->getString($record, 'item.notes'),
 | 
					 | 
				
			||||||
                'discount'           => $this->getFloat($record, 'item.discount'),
 | 
					 | 
				
			||||||
                'is_amount_discount' => filter_var($this->getString($record, 'item.is_amount_discount'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
 | 
					 | 
				
			||||||
                'tax_name1'          => $this->getString($record, 'item.tax_name1'),
 | 
					 | 
				
			||||||
                'tax_rate1'          => $this->getFloat($record, 'item.tax_rate1'),
 | 
					 | 
				
			||||||
                'tax_name2'          => $this->getString($record, 'item.tax_name2'),
 | 
					 | 
				
			||||||
                'tax_rate2'          => $this->getFloat($record, 'item.tax_rate2'),
 | 
					 | 
				
			||||||
                'tax_name3'          => $this->getString($record, 'item.tax_name3'),
 | 
					 | 
				
			||||||
                'tax_rate3'          => $this->getFloat($record, 'item.tax_rate3'),
 | 
					 | 
				
			||||||
                'custom_value1'      => $this->getString($record, 'item.custom_value1'),
 | 
					 | 
				
			||||||
                'custom_value2'      => $this->getString($record, 'item.custom_value2'),
 | 
					 | 
				
			||||||
                'custom_value3'      => $this->getString($record, 'item.custom_value3'),
 | 
					 | 
				
			||||||
                'custom_value4'      => $this->getString($record, 'item.custom_value4'),
 | 
					 | 
				
			||||||
                'type_id'            => $this->getInvoiceTypeId($record, 'item.type_id'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $transformed['line_items'] = $line_items;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $transformed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,65 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * client Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class PaymentTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class PaymentTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $client_id =
 | 
					 | 
				
			||||||
            $this->getClient($this->getString($data, 'payment.client_id'), $this->getString($data, 'payment.client_id'));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (empty($client_id)) {
 | 
					 | 
				
			||||||
            throw new ImportException('Could not find client.');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $transformed = [
 | 
					 | 
				
			||||||
            'company_id'            => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'number'                => $this->getString($data, 'payment.number'),
 | 
					 | 
				
			||||||
            'user_id'               => $this->getString($data, 'payment.user_id'),
 | 
					 | 
				
			||||||
            'amount'                => $this->getFloat($data, 'payment.amount'),
 | 
					 | 
				
			||||||
            'refunded'              => $this->getFloat($data, 'payment.refunded'),
 | 
					 | 
				
			||||||
            'applied'               => $this->getFloat($data, 'payment.applied'),
 | 
					 | 
				
			||||||
            'transaction_reference' => $this->getString($data, 'payment.transaction_reference '),
 | 
					 | 
				
			||||||
            'date'                  => $this->getString($data, 'payment.date'),
 | 
					 | 
				
			||||||
            'private_notes'         => $this->getString($data, 'payment.private_notes'),
 | 
					 | 
				
			||||||
            'custom_value1'         => $this->getString($data, 'payment.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2'         => $this->getString($data, 'payment.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3'         => $this->getString($data, 'payment.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4'         => $this->getString($data, 'payment.custom_value4'),
 | 
					 | 
				
			||||||
            'client_id'             => $client_id,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (isset($data['payment.invoice_number']) &&
 | 
					 | 
				
			||||||
            $invoice_id = $this->getInvoiceId($data['payment.invoice_number'])) {
 | 
					 | 
				
			||||||
            $transformed['invoices'] = [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'invoice_id' => $invoice_id,
 | 
					 | 
				
			||||||
                    'amount'     => $transformed['amount'] ?? null,
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $transformed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,47 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class ProductTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ProductTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id' => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'product_key' => $this->getString($data, 'product.product_key'),
 | 
					 | 
				
			||||||
            'notes' => $this->getString($data, 'product.notes'),
 | 
					 | 
				
			||||||
            'cost' => $this->getFloat($data, 'product.cost'),
 | 
					 | 
				
			||||||
            'price' => $this->getFloat($data, 'product.price'),
 | 
					 | 
				
			||||||
            'quantity' => $this->getFloat($data, 'product.quantity'),
 | 
					 | 
				
			||||||
            'tax_name1' => $this->getString($data, 'product.tax_name1'),
 | 
					 | 
				
			||||||
            'tax_rate1' => $this->getFloat($data, 'product.tax_rate1'),
 | 
					 | 
				
			||||||
            'tax_name2' => $this->getString($data, 'product.tax_name2'),
 | 
					 | 
				
			||||||
            'tax_rate2' => $this->getFloat($data, 'product.tax_rate2'),
 | 
					 | 
				
			||||||
            'tax_name3' => $this->getString($data, 'product.tax_name3'),
 | 
					 | 
				
			||||||
            'tax_rate3' => $this->getFloat($data, 'product.tax_rate3'),
 | 
					 | 
				
			||||||
            'custom_value1' => $this->getString($data, 'product.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2' => $this->getString($data, 'product.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3' => $this->getString($data, 'product.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4' => $this->getString($data, 'product.custom_value4'),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,54 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Csv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class VendorTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class VendorTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array|bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (isset($data->name) && $this->hasVendor($data->name)) {
 | 
					 | 
				
			||||||
            throw new ImportException('Vendor already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id' => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'name'            => $this->getString($data, 'vendor.name'),
 | 
					 | 
				
			||||||
            'phone'           => $this->getString($data, 'vendor.phone'),
 | 
					 | 
				
			||||||
            'id_number'       => $this->getString($data, 'vendor.id_number'),
 | 
					 | 
				
			||||||
            'vat_number'      => $this->getString($data, 'vendor.vat_number'),
 | 
					 | 
				
			||||||
            'website'         => $this->getString($data, 'vendor.website'),
 | 
					 | 
				
			||||||
            'currency_id'     => $this->getCurrencyByCode($data, 'vendor.currency_id'),
 | 
					 | 
				
			||||||
            'public_notes'    => $this->getString($data, 'vendor.public_notes'),
 | 
					 | 
				
			||||||
            'private_notes'   => $this->getString($data, 'vendor.private_notes'),
 | 
					 | 
				
			||||||
            'address1'        => $this->getString($data, 'vendor.address1'),
 | 
					 | 
				
			||||||
            'address2'        => $this->getString($data, 'vendor.address2'),
 | 
					 | 
				
			||||||
            'city'            => $this->getString($data, 'vendor.city'),
 | 
					 | 
				
			||||||
            'state'           => $this->getString($data, 'vendor.state'),
 | 
					 | 
				
			||||||
            'postal_code'     => $this->getString($data, 'vendor.postal_code'),
 | 
					 | 
				
			||||||
            'custom_value1'        => $this->getString($data, 'vendor.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2'        => $this->getString($data, 'vendor.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3'        => $this->getString($data, 'vendor.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4'        => $this->getString($data, 'vendor.custom_value4'),
 | 
					 | 
				
			||||||
            'vendor_contacts' => [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'first_name' => $this->getString($data, 'vendor.first_name'),
 | 
					 | 
				
			||||||
                    'last_name'  => $this->getString($data, 'vendor.last_name'),
 | 
					 | 
				
			||||||
                    'email'      => $this->getString($data, 'vendor.email'),
 | 
					 | 
				
			||||||
                    'phone'      => $this->getString($data, 'vendor.phone'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            'country_id'      => isset($data['vendor.country_id']) ? $this->getCountryId($data['vendor.country_id']) : null,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,57 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Freshbooks;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class ClientTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ClientTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array|bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (isset($data['Organization']) && $this->hasClient($data['Organization'])) {
 | 
					 | 
				
			||||||
            throw new ImportException('Client already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'company_id'     => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'name'           => $this->getString($data, 'Organization'),
 | 
					 | 
				
			||||||
            'phone'     => $this->getString($data, 'Phone'),
 | 
					 | 
				
			||||||
            'address1'       => $this->getString($data, 'Street'),
 | 
					 | 
				
			||||||
            'city'           => $this->getString($data, 'City'),
 | 
					 | 
				
			||||||
            'state'          => $this->getString($data, 'Province/State'),
 | 
					 | 
				
			||||||
            'postal_code'    => $this->getString($data, 'Postal Code'),
 | 
					 | 
				
			||||||
            'country_id'     => isset($data['Country']) ? $this->getCountryId($data['Country']) : null,
 | 
					 | 
				
			||||||
            'private_notes'   => $this->getString($data, 'Notes'),
 | 
					 | 
				
			||||||
            'credit_balance' => 0,
 | 
					 | 
				
			||||||
            'settings'       => new \stdClass,
 | 
					 | 
				
			||||||
            'client_hash'    => Str::random(40),
 | 
					 | 
				
			||||||
            'contacts'       => [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'first_name'    => $this->getString($data, 'First Name'),
 | 
					 | 
				
			||||||
                    'last_name'     => $this->getString($data, 'Last Name'),
 | 
					 | 
				
			||||||
                    'email'         => $this->getString($data, 'Email'),
 | 
					 | 
				
			||||||
                    'phone'         => $this->getString($data, 'Phone'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,87 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * client Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Freshbooks;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
use App\Utils\Number;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class InvoiceTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class InvoiceTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $line_items_data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($line_items_data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoice_data = reset($line_items_data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($this->hasInvoice($invoice_data['Invoice #'])) {
 | 
					 | 
				
			||||||
            throw new ImportException('Invoice number already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $invoiceStatusMap = [
 | 
					 | 
				
			||||||
            'sent'  => Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
            'draft' => Invoice::STATUS_DRAFT,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $transformed = [
 | 
					 | 
				
			||||||
            'company_id'  => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'client_id'   => $this->getClient($this->getString($invoice_data, 'Client Name'), null),
 | 
					 | 
				
			||||||
            'number'      => $this->getString($invoice_data, 'Invoice #'),
 | 
					 | 
				
			||||||
            'date'        => isset($invoice_data['Date Issued']) ? date('Y-m-d', strtotime($invoice_data['Date Issued'])) : null,
 | 
					 | 
				
			||||||
            'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'),
 | 
					 | 
				
			||||||
            'amount'      => 0,
 | 
					 | 
				
			||||||
            'status_id'   => $invoiceStatusMap[$status =
 | 
					 | 
				
			||||||
                    strtolower($this->getString($invoice_data, 'Invoice Status'))] ?? Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
            // 'viewed'      => $status === 'viewed',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $line_items = [];
 | 
					 | 
				
			||||||
        foreach ($line_items_data as $record) {
 | 
					 | 
				
			||||||
            $line_items[] = [
 | 
					 | 
				
			||||||
                'product_key'        => $this->getString($record, 'Item Name'),
 | 
					 | 
				
			||||||
                'notes'              => $this->getString($record, 'Item Description'),
 | 
					 | 
				
			||||||
                'cost'               => $this->getFreshbookQuantityFloat($record, 'Rate'),
 | 
					 | 
				
			||||||
                'quantity'           => $this->getFreshbookQuantityFloat($record, 'Quantity'),
 | 
					 | 
				
			||||||
                'discount'           => $this->getFreshbookQuantityFloat($record, 'Discount Percentage'),
 | 
					 | 
				
			||||||
                'is_amount_discount' => false,
 | 
					 | 
				
			||||||
                'tax_name1'          => $this->getString($record, 'Tax 1 Type'),
 | 
					 | 
				
			||||||
                'tax_rate1'          => $this->getFreshbookQuantityFloat($record, 'Tax 1 Amount'),
 | 
					 | 
				
			||||||
                'tax_name2'          => $this->getString($record, 'Tax 2 Type'),
 | 
					 | 
				
			||||||
                'tax_rate2'          => $this->getFreshbookQuantityFloat($record, 'Tax 2 Amount'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
            $transformed['amount'] += $this->getFreshbookQuantityFloat($record, 'Line Total');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $transformed['line_items'] = $line_items;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! empty($invoice_data['Date Paid'])) {
 | 
					 | 
				
			||||||
            $transformed['payments'] = [[
 | 
					 | 
				
			||||||
                'date'   => date('Y-m-d', strtotime($invoice_data['Date Paid'])),
 | 
					 | 
				
			||||||
                'amount' => $transformed['amount'],
 | 
					 | 
				
			||||||
            ]];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $transformed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** @return float  */
 | 
					 | 
				
			||||||
    public function getFreshbookQuantityFloat($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $data[$field];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,91 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * client Ninja (https://clientninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/clientninja/clientninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers\Invoice2Go;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Import\Transformers\BaseTransformer;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class InvoiceTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class InvoiceTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $line_items_data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($invoice_data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if ($this->hasInvoice($invoice_data['DocumentNumber'])) {
 | 
					 | 
				
			||||||
            throw new ImportException('Invoice number already exists');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $invoiceStatusMap = [
 | 
					 | 
				
			||||||
            'unsent' => Invoice::STATUS_DRAFT,
 | 
					 | 
				
			||||||
            'sent'   => Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $transformed = [
 | 
					 | 
				
			||||||
            'company_id'  => $this->maps['company']->id,
 | 
					 | 
				
			||||||
            'number'      => $this->getString($invoice_data, 'DocumentNumber'),
 | 
					 | 
				
			||||||
            'notes'       => $this->getString($invoice_data, 'Comment'),
 | 
					 | 
				
			||||||
            'date'        => isset($invoice_data['DocumentDate']) ? date('Y-m-d', strtotime($invoice_data['DocumentDate'])) : null,
 | 
					 | 
				
			||||||
            'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'),
 | 
					 | 
				
			||||||
            'amount'      => 0,
 | 
					 | 
				
			||||||
            'status_id'   => $invoiceStatusMap[$status =
 | 
					 | 
				
			||||||
                    strtolower($this->getString($invoice_data, 'DocumentStatus'))] ?? Invoice::STATUS_SENT,
 | 
					 | 
				
			||||||
            // 'viewed'      => $status === 'viewed',
 | 
					 | 
				
			||||||
            'line_items'  => [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'amount'             => $amount = $this->getFloat($invoice_data, 'TotalAmount'),
 | 
					 | 
				
			||||||
                    'quantity'           => 1,
 | 
					 | 
				
			||||||
                    'discount'           => $this->getFloat($invoice_data, 'DiscountValue'),
 | 
					 | 
				
			||||||
                    'is_amount_discount' => false,
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client_id =
 | 
					 | 
				
			||||||
            $this->getClient($this->getString($invoice_data, 'Name'), $this->getString($invoice_data, 'EmailRecipient'));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($client_id) {
 | 
					 | 
				
			||||||
            $transformed['client_id'] = $client_id;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $transformed['client'] = [
 | 
					 | 
				
			||||||
                'name'              => $this->getString($invoice_data, 'Name'),
 | 
					 | 
				
			||||||
                'address1'          => $this->getString($invoice_data, 'DocumentRecipientAddress'),
 | 
					 | 
				
			||||||
                'shipping_address1' => $this->getString($invoice_data, 'ShipAddress'),
 | 
					 | 
				
			||||||
                'credit_balance'    => 0,
 | 
					 | 
				
			||||||
                'settings'          => new \stdClass,
 | 
					 | 
				
			||||||
                'client_hash'       => Str::random(40),
 | 
					 | 
				
			||||||
                'contacts'          => [
 | 
					 | 
				
			||||||
                    [
 | 
					 | 
				
			||||||
                        'email' => $this->getString($invoice_data, 'Email'),
 | 
					 | 
				
			||||||
                    ],
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (! empty($invoice_data['Date Paid'])) {
 | 
					 | 
				
			||||||
            $transformed['payments'] = [
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'date'   => date('Y-m-d', strtotime($invoice_data['DatePaid'])),
 | 
					 | 
				
			||||||
                    'amount' => $this->getFloat($invoice_data, 'Payments'),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $transformed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,46 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Import\Transformers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class InvoiceItemTransformer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class InvoiceItemTransformer extends BaseTransformer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param $data
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|Item
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function transform($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            'quantity' => $this->getFloat($data, 'item.quantity'),
 | 
					 | 
				
			||||||
            'cost' => $this->getFloat($data, 'item.cost'),
 | 
					 | 
				
			||||||
            'product_key' => $this->getString($data, 'item.product_key'),
 | 
					 | 
				
			||||||
            'notes' => $this->getString($data, 'item.notes'),
 | 
					 | 
				
			||||||
            'discount' => $this->getFloat($data, 'item.discount'),
 | 
					 | 
				
			||||||
            'is_amount_discount' => $this->getString($data, 'item.is_amount_discount'),
 | 
					 | 
				
			||||||
            'tax_name1' => $this->getString($data, 'item.tax_name1'),
 | 
					 | 
				
			||||||
            'tax_rate1' => $this->getFloat($data, 'item.tax_rate1'),
 | 
					 | 
				
			||||||
            'tax_name2' => $this->getString($data, 'item.tax_name2'),
 | 
					 | 
				
			||||||
            'tax_rate2' => $this->getFloat($data, 'item.tax_rate2'),
 | 
					 | 
				
			||||||
            'tax_name3' => $this->getString($data, 'item.tax_name3'),
 | 
					 | 
				
			||||||
            'tax_rate3' => $this->getFloat($data, 'item.tax_rate3'),
 | 
					 | 
				
			||||||
            'custom_value1' => $this->getString($data, 'item.custom_value1'),
 | 
					 | 
				
			||||||
            'custom_value2' => $this->getString($data, 'item.custom_value2'),
 | 
					 | 
				
			||||||
            'custom_value3' => $this->getString($data, 'item.custom_value3'),
 | 
					 | 
				
			||||||
            'custom_value4' => $this->getString($data, 'item.custom_value4'),
 | 
					 | 
				
			||||||
            'type_id' => $this->getInvoiceTypeId($data, 'item.type_id'),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
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